diff --git a/.travis.yml b/.travis.yml index cea5f854c91..09cefa27b32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,13 +4,10 @@ language: c env: global: - BASENAME="vorestation" # $BASENAME.dmb, $BASENAME.dme, etc. - - BYOND_MAJOR="513" - - BYOND_MINOR="1520" - - MACRO_COUNT=4 cache: directories: - - $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR} + - $HOME/BYOND addons: apt: @@ -37,13 +34,17 @@ jobs: include: - stage: "File Tests" #This is the odd man out, with specific installs and stuff. name: "Validate Files" - install: #Need python for some of the tag matching stuff - - pip install --user PyYaml -q - - pip install --user beautifulsoup4 -q - script: ./tools/travis/validate_files.sh addons: apt: - packages: ~ # Don't need any packages for this + packages: + - python3 + - python3-pip + - python3-setuptools + install: #Need python for some of the tag matching stuff + - tools/travis/install_build_deps.sh + script: + - tools/travis/validate_files.sh + - tools/travis/build_tgui.sh - stage: "Unit Tests" env: TEST_DEFINE="UNIT_TEST" TEST_FILE="code/_unit_tests.dm" RUN="1" name: "Compile normally (unit tests)" diff --git a/_build_dependencies.sh b/_build_dependencies.sh new file mode 100644 index 00000000000..b33548a58a0 --- /dev/null +++ b/_build_dependencies.sh @@ -0,0 +1,13 @@ +# This file has all the information on what versions of libraries are thrown into the code +# For dreamchecker +export SPACEMANDMM_TAG=suite-1.4 +# For NanoUI + TGUI +export NODE_VERSION=12 +# For the scripts in tools +export PHP_VERSION=5.6 +# Byond Major +export BYOND_MAJOR=513 +# Byond Minor +export BYOND_MINOR=1526 +# Macro Count +export MACRO_COUNT=4 \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm index 1c308a0e0ba..fb686820eea 100644 --- a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm +++ b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm @@ -140,7 +140,7 @@ /obj/machinery/atmospherics/binary/algae_farm/attack_hand(mob/user) if(..()) return 1 - ui_interact(user) + tgui_interact(user) /obj/machinery/atmospherics/binary/algae_farm/RefreshParts() ..() @@ -165,7 +165,13 @@ moles_per_tick = initial(moles_per_tick) + (manip_rating**2 - 1) -/obj/machinery/atmospherics/binary/algae_farm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/state = default_state) +/obj/machinery/atmospherics/binary/algae_farm/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AlgaeFarm", name) + ui.open() + +/obj/machinery/atmospherics/binary/algae_farm/tgui_data(mob/user) var/data[0] data["panelOpen"] = panel_open @@ -198,41 +204,28 @@ "percent" = air2.total_moles ? round((air2.gas[output_gas] / air2.total_moles) * 100) : 0, "moles" = round(air2.gas[output_gas], 0.01)) - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "algae_farm_vr.tmpl", "Algae Farm Control Panel", 500, 600) - ui.set_initial_data(data) - ui.set_auto_update(TRUE) - ui.open() + return data -/obj/machinery/atmospherics/binary/algae_farm/Topic(href, href_list) +/obj/machinery/atmospherics/binary/algae_farm/tgui_act(action, params) if(..()) - return 1 - usr.set_machine(src) + return TRUE add_fingerprint(usr) - // Queue management can be done even while busy - if(href_list["activate"]) - update_use_power(USE_POWER_ACTIVE) - update_icon() - updateUsrDialog() - return - - if(href_list["deactivate"]) - update_use_power(USE_POWER_IDLE) - update_icon() - updateUsrDialog() - return - - if(href_list["ejectMaterial"]) - var/matName = href_list["ejectMaterial"] - if(!(matName in stored_material)) - return - eject_materials(matName, 0) - updateUsrDialog() - return + switch(action) + if("toggle") + if(use_power == USE_POWER_IDLE) + update_use_power(USE_POWER_ACTIVE) + else + update_use_power(USE_POWER_IDLE) + update_icon() + . = TRUE + if("ejectMaterial") + var/matName = params["mat"] + if(!(matName in stored_material)) + return + eject_materials(matName, 0) + . = TRUE // TODO - These should be replaced with materials datum. diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 1c501e87f0f..dd38dae3ca9 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -209,18 +209,21 @@ /obj/machinery/atmospherics/binary/passive_gate/attack_hand(user as mob) if(..()) return - src.add_fingerprint(usr) - if(!src.allowed(user)) + add_fingerprint(usr) + if(!allowed(user)) to_chat(user, "Access denied.") return - usr.set_machine(src) - ui_interact(user) - return + tgui_interact(user) -/obj/machinery/atmospherics/binary/passive_gate/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/atmospherics/binary/passive_gate/tgui_interact(mob/user, datum/tgui/ui) if(stat & (BROKEN|NOPOWER)) - return + return FALSE + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PressureRegulator", name) + ui.open() +/obj/machinery/atmospherics/binary/passive_gate/tgui_data(mob/user) // this is the data which will be sent to the ui var/data[0] @@ -235,51 +238,48 @@ "last_flow_rate" = round(last_flow_rate*10), ) - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "pressure_regulator.tmpl", name, 470, 370) - ui.set_initial_data(data) // when the ui is first opened this is the data it will use - ui.open() // open the new ui window - ui.set_auto_update(1) // auto update every Master Controller tick + return data -/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list) - if(..()) return 1 +/obj/machinery/atmospherics/binary/passive_gate/tgui_act(action, params) + if(..()) + return TRUE - if(href_list["toggle_valve"]) - unlocked = !unlocked + switch(action) + if("toggle_valve") + . = TRUE + unlocked = !unlocked + if("regulate_mode") + . = TRUE + switch(params["mode"]) + if("off") regulate_mode = REGULATE_NONE + if("input") regulate_mode = REGULATE_INPUT + if("output") regulate_mode = REGULATE_OUTPUT - if(href_list["regulate_mode"]) - switch(href_list["regulate_mode"]) - if ("off") regulate_mode = REGULATE_NONE - if ("input") regulate_mode = REGULATE_INPUT - if ("output") regulate_mode = REGULATE_OUTPUT + if("set_press") + . = TRUE + switch(params["press"]) + if("min") + target_pressure = 0 + if("max") + target_pressure = max_pressure_setting + if("set") + var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure Control",src.target_pressure) as num + src.target_pressure = between(0, new_pressure, max_pressure_setting) - switch(href_list["set_press"]) - if ("min") - target_pressure = 0 - if ("max") - target_pressure = max_pressure_setting - if ("set") - var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure Control",src.target_pressure) as num - src.target_pressure = between(0, new_pressure, max_pressure_setting) + if("set_flow_rate") + . = TRUE + switch(params["press"]) + if("min") + set_flow_rate = 0 + if("max") + set_flow_rate = air1.volume + if("set") + var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[air1.volume]L/s)","Flow Rate Control",src.set_flow_rate) as num + src.set_flow_rate = between(0, new_flow_rate, air1.volume) - switch(href_list["set_flow_rate"]) - if ("min") - set_flow_rate = 0 - if ("max") - set_flow_rate = air1.volume - if ("set") - var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[air1.volume]kPa)","Flow Rate Control",src.set_flow_rate) as num - src.set_flow_rate = between(0, new_flow_rate, air1.volume) - - usr.set_machine(src) //Is this even needed with NanoUI? - src.update_icon() - src.add_fingerprint(usr) - return + update_icon() + add_fingerprint(usr) /obj/machinery/atmospherics/binary/passive_gate/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) if (!W.is_wrench()) diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 0df02174976..54e034dc92a 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -143,10 +143,15 @@ Thus, the two variables affect pump operation are set in New(): return 1 -/obj/machinery/atmospherics/binary/pump/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/atmospherics/binary/pump/tgui_interact(mob/user, datum/tgui/ui) if(stat & (BROKEN|NOPOWER)) return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "GasPump", name) + ui.open() +/obj/machinery/atmospherics/binary/pump/tgui_data(mob/user) // this is the data which will be sent to the ui var/data[0] @@ -159,15 +164,7 @@ Thus, the two variables affect pump operation are set in New(): "max_power_draw" = power_rating, ) - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "gas_pump.tmpl", name, 470, 290) - ui.set_initial_data(data) // when the ui is first opened this is the data it will use - ui.open() // open the new ui window - ui.set_auto_update(1) // auto update every Master Controller tick + return data /obj/machinery/atmospherics/binary/pump/Initialize() . = ..() @@ -204,36 +201,40 @@ Thus, the two variables affect pump operation are set in New(): update_icon() return -/obj/machinery/atmospherics/binary/pump/attack_hand(user as mob) +/obj/machinery/atmospherics/binary/pump/attack_ghost(mob/user) + tgui_interact(user) + +/obj/machinery/atmospherics/binary/pump/attack_hand(mob/user) if(..()) return - src.add_fingerprint(usr) - if(!src.allowed(user)) + add_fingerprint(usr) + if(!allowed(user)) to_chat(user, "Access denied.") return - usr.set_machine(src) - ui_interact(user) - return + tgui_interact(user) -/obj/machinery/atmospherics/binary/pump/Topic(href,href_list) - if(..()) return 1 +/obj/machinery/atmospherics/binary/pump/tgui_act(action, params) + if(..()) + return TRUE - if(href_list["power"]) - update_use_power(!use_power) + switch(action) + if("power") + update_use_power(!use_power) + . = TRUE + if("set_press") + var/press = params["press"] + switch(press) + if("min") + target_pressure = 0 + if("max") + target_pressure = max_pressure_setting + if("set") + var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure control",src.target_pressure) as num + src.target_pressure = between(0, new_pressure, max_pressure_setting) + . = TRUE - switch(href_list["set_press"]) - if ("min") - target_pressure = 0 - if ("max") - target_pressure = max_pressure_setting - if ("set") - var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure control",src.target_pressure) as num - src.target_pressure = between(0, new_pressure, max_pressure_setting) - - usr.set_machine(src) - src.add_fingerprint(usr) - - src.update_icon() + add_fingerprint(usr) + update_icon() /obj/machinery/atmospherics/binary/pump/power_change() var/old_stat = stat diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm index 9f0862d8001..56171a0880d 100644 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ b/code/ATMOSPHERICS/components/omni_devices/filter.dm @@ -87,23 +87,14 @@ return 1 -/obj/machinery/atmospherics/omni/atmos_filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) - - var/list/data = new() - - data = build_uidata() - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - - if (!ui) - ui = new(user, src, ui_key, "omni_filter.tmpl", "Omni Filter Control", 330, 330) - ui.set_initial_data(data) - +/obj/machinery/atmospherics/omni/atmos_filter/tgui_interact(mob/user,datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OmniFilter", name) ui.open() -/obj/machinery/atmospherics/omni/atmos_filter/proc/build_uidata() - var/list/data = new() +/obj/machinery/atmospherics/omni/atmos_filter/tgui_data(mob/user) + var/list/data = list() data["power"] = use_power data["config"] = configuring @@ -156,34 +147,41 @@ else return null -/obj/machinery/atmospherics/omni/atmos_filter/Topic(href, href_list) - if(..()) return 1 - switch(href_list["command"]) +/obj/machinery/atmospherics/omni/atmos_filter/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) if("power") if(!configuring) update_use_power(!use_power) else update_use_power(USE_POWER_OFF) + . = TRUE if("configure") configuring = !configuring if(configuring) update_use_power(USE_POWER_OFF) - - //only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on - if(configuring && !use_power) - switch(href_list["command"]) - if("set_flow_rate") - var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num - set_flow_rate = between(0, new_flow_rate, max_flow_rate) - if("switch_mode") - switch_mode(dir_flag(href_list["dir"]), mode_return_switch(href_list["mode"])) - if("switch_filter") - var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Phoron", "Nitrous Oxide") - switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter)) + . = TRUE + if("set_flow_rate") + if(!configuring || use_power) + return + var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num + set_flow_rate = between(0, new_flow_rate, max_flow_rate) + . = TRUE + if("switch_mode") + if(!configuring || use_power) + return + switch_mode(dir_flag(params["dir"]), mode_return_switch(params["mode"])) + . = TRUE + if("switch_filter") + if(!configuring || use_power) + return + var/new_filter = input(usr,"Select filter mode:","Change filter",params["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Phoron", "Nitrous Oxide") + switch_filter(dir_flag(params["dir"]), mode_return_switch(new_filter)) + . = TRUE update_icon() - SSnanoui.update_uis(src) - return /obj/machinery/atmospherics/omni/atmos_filter/proc/mode_return_switch(var/mode) switch(mode) diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm index 0210d09e691..077be63b30b 100644 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/omni_devices/mixer.dm @@ -124,22 +124,13 @@ return 1 -/obj/machinery/atmospherics/omni/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - usr.set_machine(src) - - var/list/data = new() - - data = build_uidata() - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - - if (!ui) - ui = new(user, src, ui_key, "omni_mixer.tmpl", "Omni Mixer Control", 360, 330) - ui.set_initial_data(data) - +/obj/machinery/atmospherics/omni/mixer/tgui_interact(mob/user,datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OmniMixer", name) ui.open() -/obj/machinery/atmospherics/omni/mixer/proc/build_uidata() +/obj/machinery/atmospherics/omni/mixer/tgui_data(mob/user) var/list/data = new() data["power"] = use_power @@ -172,36 +163,45 @@ return data -/obj/machinery/atmospherics/omni/mixer/Topic(href, href_list) - if(..()) return 1 +/obj/machinery/atmospherics/omni/mixer/tgui_act(action, params) + if(..()) + return TRUE - switch(href_list["command"]) + switch(action) if("power") + . = TRUE if(!configuring) update_use_power(!use_power) else update_use_power(USE_POWER_OFF) if("configure") + . = TRUE configuring = !configuring if(configuring) update_use_power(USE_POWER_OFF) - - //only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on - if(configuring && !use_power) - switch(href_list["command"]) - if("set_flow_rate") - var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num - set_flow_rate = between(0, new_flow_rate, max_flow_rate) - if("switch_mode") - switch_mode(dir_flag(href_list["dir"]), href_list["mode"]) - if("switch_con") - change_concentration(dir_flag(href_list["dir"])) - if("switch_conlock") - con_lock(dir_flag(href_list["dir"])) + if("set_flow_rate") + . = TRUE + if(!configuring || use_power) + return + var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num + set_flow_rate = between(0, new_flow_rate, max_flow_rate) + if("switch_mode") + . = TRUE + if(!configuring || use_power) + return + switch_mode(dir_flag(params["dir"]), params["mode"]) + if("switch_con") + . = TRUE + if(!configuring || use_power) + return + change_concentration(dir_flag(params["dir"])) + if("switch_conlock") + . = TRUE + if(!configuring || use_power) + return + con_lock(dir_flag(params["dir"])) update_icon() - SSnanoui.update_uis(src) - return /obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/mode = ATM_NONE) if(mode != ATM_INPUT && mode != ATM_OUTPUT) diff --git a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm index 54acc3db99f..be7f905a77e 100644 --- a/code/ATMOSPHERICS/components/omni_devices/omni_base.dm +++ b/code/ATMOSPHERICS/components/omni_devices/omni_base.dm @@ -110,7 +110,7 @@ return src.add_fingerprint(usr) - ui_interact(user) + tgui_interact(user) return /obj/machinery/atmospherics/omni/proc/build_icons() diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index bde060a11a5..9e192afe1b2 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -111,7 +111,7 @@ if(frequency) set_frequency(frequency) -/obj/machinery/atmospherics/trinary/atmos_filter/attack_hand(user as mob) // -- TLE +/obj/machinery/atmospherics/trinary/atmos_filter/attack_hand(user) // -- TLE if(..()) return @@ -119,81 +119,107 @@ to_chat(user, "Access denied.") return - var/dat - var/current_filter_type - switch(filter_type) - if(0) - current_filter_type = "Phoron" - if(1) - current_filter_type = "Oxygen" - if(2) - current_filter_type = "Nitrogen" - if(3) - current_filter_type = "Carbon Dioxide" - if(4) - current_filter_type = "Nitrous Oxide" - if(-1) - current_filter_type = "Nothing" - else - current_filter_type = "ERROR - Report this bug to the admin, please!" + tgui_interact(user) - dat += {" - Power: [use_power?"On":"Off"]
- Filtering: [current_filter_type]

-

Set Filter Type:

- Phoron
- Oxygen
- Nitrogen
- Carbon Dioxide
- Nitrous Oxide
- Nothing
-
- Set Flow Rate Limit: - [src.set_flow_rate]L/s | Change
- Flow rate: [round(last_flow_rate, 0.1)]L/s - "} + // var/dat + // var/current_filter_type + // switch(filter_type) + // if(0) + // current_filter_type = "Phoron" + // if(1) + // current_filter_type = "Oxygen" + // if(2) + // current_filter_type = "Nitrogen" + // if(3) + // current_filter_type = "Carbon Dioxide" + // if(4) + // current_filter_type = "Nitrous Oxide" + // if(-1) + // current_filter_type = "Nothing" + // else + // current_filter_type = "ERROR - Report this bug to the admin, please!" - user << browse("[src.name] control[dat]", "window=atmos_filter") - onclose(user, "atmos_filter") - return + // dat += {" + // Power: [use_power?"On":"Off"]
+ // Filtering: [current_filter_type]

+ //

Set Filter Type:

+ // Phoron
+ // Oxygen
+ // Nitrogen
+ // Carbon Dioxide
+ // Nitrous Oxide
+ // Nothing
+ //
+ // Set Flow Rate Limit: + // [src.set_flow_rate]L/s | Change
+ // Flow rate: [round(last_flow_rate, 0.1)]L/s + // "} -/obj/machinery/atmospherics/trinary/atmos_filter/Topic(href, href_list) // -- TLE + // user << browse("[src.name] control[dat]", "window=atmos_filter") + // onclose(user, "atmos_filter") + + + +/obj/machinery/atmospherics/trinary/atmos_filter/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AtmosFilter", name) + ui.open() + +/obj/machinery/atmospherics/trinary/atmos_filter/tgui_data(mob/user) + var/list/data = list() + + data["on"] = use_power + data["rate"] = set_flow_rate + data["max_rate"] = air1.volume + data["last_flow_rate"] = round(last_flow_rate, 0.1) + + data["filter_types"] = list() + data["filter_types"] += list(list("name" = "Nothing", "f_type" = -1, "selected" = filter_type == -1)) + data["filter_types"] += list(list("name" = "Phoron", "f_type" = 0, "selected" = filter_type == 0)) + data["filter_types"] += list(list("name" = "Oxygen", "f_type" = 1, "selected" = filter_type == 1)) + data["filter_types"] += list(list("name" = "Nitrogen", "f_type" = 2, "selected" = filter_type == 2)) + data["filter_types"] += list(list("name" = "Carbon Dioxide", "f_type" = 3, "selected" = filter_type == 3)) + data["filter_types"] += list(list("name" = "Nitrous Oxide", "f_type" = 4, "selected" = filter_type == 4)) + + return data + +/obj/machinery/atmospherics/trinary/atmos_filter/tgui_act(action, params) if(..()) - return 1 - usr.set_machine(src) - src.add_fingerprint(usr) - if(href_list["filterset"]) - filter_type = text2num(href_list["filterset"]) + return TRUE - filtered_out.Cut() //no need to create new lists unnecessarily - switch(filter_type) - if(0) //removing hydrocarbons - filtered_out += "phoron" - filtered_out += "oxygen_agent_b" - if(1) //removing O2 - filtered_out += "oxygen" - if(2) //removing N2 - filtered_out += "nitrogen" - if(3) //removing CO2 - filtered_out += "carbon_dioxide" - if(4)//removing N2O - filtered_out += "sleeping_agent" + switch(action) + if("power") + update_use_power(!use_power) + if("rate") + var/rate = params["rate"] + if(rate == "max") + rate = air1.volume + . = TRUE + else if(text2num(rate) != null) + rate = text2num(rate) + . = TRUE + if(.) + set_flow_rate = clamp(rate, 0, air1.volume) + if("filter") + . = TRUE + filter_type = text2num(params["filterset"]) + filtered_out.Cut() //no need to create new lists unnecessarily + switch(filter_type) + if(0) //removing hydrocarbons + filtered_out += "phoron" + filtered_out += "oxygen_agent_b" + if(1) //removing O2 + filtered_out += "oxygen" + if(2) //removing N2 + filtered_out += "nitrogen" + if(3) //removing CO2 + filtered_out += "carbon_dioxide" + if(4)//removing N2O + filtered_out += "sleeping_agent" - if (href_list["temp"]) - src.temp = null - if(href_list["set_flow_rate"]) - var/new_flow_rate = input(usr,"Enter new flow rate (0-[air1.volume]L/s)","Flow Rate Control",src.set_flow_rate) as num - src.set_flow_rate = max(0, min(air1.volume, new_flow_rate)) - if(href_list["power"]) - update_use_power(!use_power) - src.update_icon() - src.updateUsrDialog() -/* - for(var/mob/M in viewers(1, src)) - if ((M.client && M.machine == src)) - src.attack_hand(M) -*/ - return + add_fingerprint(usr) + update_icon() // // Mirrored Orientation - Flips the output dir to opposite side from normal. diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index 62b4b763b83..ef2a4c1a8ac 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -77,59 +77,88 @@ return 1 +/obj/machinery/atmospherics/trinary/mixer/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AtmosMixer", name) + ui.open() + +/obj/machinery/atmospherics/trinary/mixer/tgui_data(mob/user) + var/list/data = list() + data["on"] = use_power + data["set_pressure"] = round(set_flow_rate) + data["max_pressure"] = min(air1.volume, air2.volume) + data["node1_concentration"] = round(mixing_inputs[air1]*100, 1) + data["node2_concentration"] = round(mixing_inputs[air2]*100, 1) + var/list/node_connects = get_node_connect_dirs() + data["node1_dir"] = dir_name(node_connects[1],TRUE) + data["node2_dir"] = dir_name(node_connects[2],TRUE) + return data + /obj/machinery/atmospherics/trinary/mixer/attack_hand(user as mob) if(..()) return - src.add_fingerprint(usr) - if(!src.allowed(user)) - to_chat(user, "Access denied.") - return - usr.set_machine(src) - var/list/node_connects = get_node_connect_dirs() - var/dat = {"Power: [use_power?"On":"Off"]
- Set Flow Rate Limit: - [set_flow_rate]L/s | Change -
- Flow Rate: [round(last_flow_rate, 0.1)]L/s -

- Node 1 ([dir_name(node_connects[1],TRUE)]) Concentration: - - - - - [mixing_inputs[air1]]([mixing_inputs[air1]*100]%) - + - + -
- Node 2 ([dir_name(node_connects[2],TRUE)]) Concentration: - - - - - [mixing_inputs[air2]]([mixing_inputs[air2]*100]%) - + - + - "} + tgui_interact(user) + // src.add_fingerprint(usr) + // if(!src.allowed(user)) + // to_chat(user, "Access denied.") + // return + // usr.set_machine(src) + // var/list/node_connects = get_node_connect_dirs() + // var/dat = {"Power: [use_power?"On":"Off"]
+ // Set Flow Rate Limit: + // [set_flow_rate]L/s | Change + //
+ // Flow Rate: [round(last_flow_rate, 0.1)]L/s + //

+ // Node 1 ([dir_name(node_connects[1],TRUE)]) Concentration: + // - + // - + // [mixing_inputs[air1]]([mixing_inputs[air1]*100]%) + // + + // + + //
+ // Node 2 ([dir_name(node_connects[2],TRUE)]) Concentration: + // - + // - + // [mixing_inputs[air2]]([mixing_inputs[air2]*100]%) + // + + // + + // "} - user << browse("[src.name] control[dat]", "window=atmo_mixer") - onclose(user, "atmo_mixer") - return + // user << browse("[src.name] control[dat]", "window=atmo_mixer") + // onclose(user, "atmo_mixer") + // return -/obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list) - if(..()) return 1 - if(href_list["power"]) - update_use_power(!use_power) - if(href_list["set_press"]) - var/max_flow_rate = min(air1.volume, air2.volume) - var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",src.set_flow_rate) as num - src.set_flow_rate = max(0, min(max_flow_rate, new_flow_rate)) - if(href_list["node1_c"]) - var/value = text2num(href_list["node1_c"]) - src.mixing_inputs[air1] = max(0, min(1, src.mixing_inputs[air1] + value)) - src.mixing_inputs[air2] = 1.0 - mixing_inputs[air1] - if(href_list["node2_c"]) - var/value = text2num(href_list["node2_c"]) - src.mixing_inputs[air2] = max(0, min(1, src.mixing_inputs[air2] + value)) - src.mixing_inputs[air1] = 1.0 - mixing_inputs[air2] - src.update_icon() - src.updateUsrDialog() - return +/obj/machinery/atmospherics/trinary/mixer/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("power") + update_use_power(!use_power) + . = TRUE + if("pressure") + var/pressure = params["pressure"] + if(pressure == "max") + pressure = min(air1.volume, air2.volume) + . = TRUE + else if(text2num(pressure) != null) + pressure = text2num(pressure) + . = TRUE + if(.) + set_flow_rate = clamp(pressure, 0, min(air1.volume, air2.volume)) + if("node1") + var/value = text2num(params["concentration"]) + mixing_inputs[air1] = max(0, min(1, value / 100)) + mixing_inputs[air2] = 1.0 - mixing_inputs[air1] + . = TRUE + if("node2") + var/value = text2num(params["concentration"]) + mixing_inputs[air2] = max(0, min(1, value / 100)) + mixing_inputs[air1] = 1.0 - mixing_inputs[air2] + . = TRUE + update_icon() // // "T" Orientation - Inputs are on oposite sides instead of adjacent diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm index 2c53c47583d..3568a87a425 100644 --- a/code/ATMOSPHERICS/components/unary/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm @@ -53,12 +53,18 @@ return /obj/machinery/atmospherics/unary/freezer/attack_ai(mob/user as mob) - ui_interact(user) + tgui_interact(user) /obj/machinery/atmospherics/unary/freezer/attack_hand(mob/user as mob) - ui_interact(user) + tgui_interact(user) -/obj/machinery/atmospherics/unary/freezer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/atmospherics/unary/freezer/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "GasTemperatureSystem", name) + ui.open() + +/obj/machinery/atmospherics/unary/freezer/tgui_data(mob/user) // this is the data which will be sent to the ui var/data[0] data["on"] = use_power ? 1 : 0 @@ -76,34 +82,26 @@ temp_class = "average" data["gasTemperatureClass"] = temp_class - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "freezer.tmpl", "Gas Cooling System", 440, 300) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) + return data -/obj/machinery/atmospherics/unary/freezer/Topic(href, href_list) +/obj/machinery/atmospherics/unary/freezer/tgui_act(action, params) if(..()) - return 1 - if(href_list["toggleStatus"]) - update_use_power(!use_power) - update_icon() - if(href_list["temp"]) - var/amount = text2num(href_list["temp"]) - if(amount > 0) - set_temperature = min(set_temperature + amount, 1000) - else - set_temperature = max(set_temperature + amount, 0) - if(href_list["setPower"]) //setting power to 0 is redundant anyways - var/new_setting = between(0, text2num(href_list["setPower"]), 100) - set_power_level(new_setting) + return TRUE + + . = TRUE + switch(action) + if("toggleStatus") + update_use_power(!use_power) + update_icon() + if("setGasTemperature") + var/amount = text2num(params["temp"]) + if(amount > 0) + set_temperature = min(amount, 1000) + else + set_temperature = max(amount, 0) + if("setPower") //setting power to 0 is redundant anyways + var/new_setting = between(0, text2num(params["value"]), 100) + set_power_level(new_setting) add_fingerprint(usr) diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm index ad852affdc2..365be85b704 100644 --- a/code/ATMOSPHERICS/components/unary/heat_source.dm +++ b/code/ATMOSPHERICS/components/unary/heat_source.dm @@ -75,12 +75,18 @@ update_icon() /obj/machinery/atmospherics/unary/heater/attack_ai(mob/user as mob) - ui_interact(user) + tgui_interact(user) /obj/machinery/atmospherics/unary/heater/attack_hand(mob/user as mob) - ui_interact(user) + tgui_interact(user) -/obj/machinery/atmospherics/unary/heater/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/atmospherics/unary/heater/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "GasTemperatureSystem", name) + ui.open() + +/obj/machinery/atmospherics/unary/heater/tgui_data(mob/user) // this is the data which will be sent to the ui var/data[0] data["on"] = use_power ? 1 : 0 @@ -91,39 +97,31 @@ data["targetGasTemperature"] = round(set_temperature) data["powerSetting"] = power_setting - var/temp_class = "normal" + var/temp_class = "average" if(air_contents.temperature > (T20C+40)) temp_class = "bad" data["gasTemperatureClass"] = temp_class - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "freezer.tmpl", "Gas Heating System", 440, 300) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) + return data -/obj/machinery/atmospherics/unary/heater/Topic(href, href_list) +/obj/machinery/atmospherics/unary/heater/tgui_act(action, params) if(..()) - return 1 - if(href_list["toggleStatus"]) - update_use_power(!use_power) - update_icon() - if(href_list["temp"]) - var/amount = text2num(href_list["temp"]) - if(amount > 0) - set_temperature = min(set_temperature + amount, max_temperature) - else - set_temperature = max(set_temperature + amount, 0) - if(href_list["setPower"]) //setting power to 0 is redundant anyways - var/new_setting = between(0, text2num(href_list["setPower"]), 100) - set_power_level(new_setting) + return TRUE + + . = TRUE + switch(action) + if("toggleStatus") + update_use_power(!use_power) + update_icon() + if("setGasTemperature") + var/amount = text2num(params["temp"]) + if(amount > 0) + set_temperature = min(amount, max_temperature) + else + set_temperature = max(amount, 0) + if("setPower") //setting power to 0 is redundant anyways + var/new_setting = between(0, text2num(params["value"]), 100) + set_power_level(new_setting) add_fingerprint(usr) diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 593d3cbd8b2..792d53d65d9 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -374,6 +374,12 @@ ONE_ATMOSPHERE*50 ) + if("reset_external_pressure" in signal.data) + external_pressure_bound = ONE_ATMOSPHERE + + if("reset_internal_pressure" in signal.data) + internal_pressure_bound = 0 + if(signal.data["init"] != null) name = signal.data["init"] return diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index 586a87cd4e4..4e9d7fd6ad7 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -116,6 +116,8 @@ What is the naming convention for planes or layers? #define HUD_LAYER 20 // Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots) #define SCREEN_LAYER 22 // Mob HUD/effects layer +#define PLANE_STATUS 2 //Status Indicators that show over mobs' heads when certain things like stuns affect them. + #define PLANE_ADMIN1 3 //Purely for shenanigans (below lighting) #define PLANE_PLANETLIGHTING 4 //Lighting on planets #define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives diff --git a/code/__defines/chemistry_vr.dm b/code/__defines/chemistry_vr.dm index f15ebd4a564..0058985adcb 100644 --- a/code/__defines/chemistry_vr.dm +++ b/code/__defines/chemistry_vr.dm @@ -1,3 +1,4 @@ // More for our custom races #define IS_CHIMERA 12 -#define IS_SHADEKIN 13 \ No newline at end of file +#define IS_SHADEKIN 13 +#define IS_ALRAUNE 14 \ No newline at end of file diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index 53e47d9acfe..b8afc5cb720 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -163,3 +163,8 @@ if (!(DATUM.datum_flags & DF_ISPROCESSING)) {\ #define START_PROCESSING_POWER_OBJECT(Datum) START_PROCESSING_IN_LIST(Datum, global.processing_power_items) #define STOP_PROCESSING_POWER_OBJECT(Datum) STOP_PROCESSING_IN_LIST(Datum, global.processing_power_items) + +// Computer login types +#define LOGIN_TYPE_NORMAL 1 +#define LOGIN_TYPE_AI 2 +#define LOGIN_TYPE_ROBOT 3 \ No newline at end of file diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index c81bcd4c0cf..8cdcf651bec 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -46,6 +46,10 @@ #define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (isclient(I) ? I : null)) + +//Persistence +#define AREA_FLAG_IS_NOT_PERSISTENT 8 // SSpersistence will not track values from this area. + // Shuttles. // These define the time taken for the shuttle to get to the space station, and the time before it leaves again. @@ -111,7 +115,7 @@ #define CUSTOM_ITEM_MOB 'icons/mob/custom_items_mob.dmi' #endif #ifndef CUSTOM_ITEM_SYNTH -#define CUSTOM_ITEM_SYNTH 'icons/mob/custom_synthetic.dmi' +#define CUSTOM_ITEM_SYNTH 'icons/mob/custom_synthetic_vr.dmi' //Vorestation edit #endif #define WALL_CAN_OPEN 1 @@ -349,3 +353,112 @@ var/global/list/##LIST_NAME = list();\ #define JOB_SILICON_ROBOT 0x2 #define JOB_SILICON_AI 0x4 #define JOB_SILICON 0x6 // 2|4, probably don't set jobs to this, but good for checking + +#define DEFAULT_OVERMAP_RANGE 0 // Makes general computers and devices be able to connect to other overmap z-levels on the same tile. + +/* + Used for wire name appearances. Replaces the color name on the left with the one on the right. + The color on the left is the one used as the actual color of the wire, but it doesn't look good when written. + So, we need to replace the name to something that looks better. +*/ +#define LIST_COLOR_RENAME \ + list( \ + "rebeccapurple" = "dark purple",\ + "darkslategrey" = "dark grey", \ + "darkolivegreen"= "dark green", \ + "darkslateblue" = "dark blue", \ + "darkkhaki" = "khaki", \ + "darkseagreen" = "light green",\ + "midnightblue" = "blue", \ + "lightgrey" = "light grey", \ + "darkgrey" = "dark grey", \ + "darkmagenta" = "dark magenta",\ + "steelblue" = "blue", \ + "goldenrod" = "gold" \ + ) + +/// Pure Black and white colorblindness. Every species except Vulpkanins and Tajarans will have this. +#define GREYSCALE_COLOR_REPLACE \ + list( \ + "red" = "grey", \ + "blue" = "grey", \ + "green" = "grey", \ + "orange" = "light grey", \ + "brown" = "grey", \ + "gold" = "light grey", \ + "cyan" = "silver", \ + "magenta" = "grey", \ + "purple" = "grey", \ + "pink" = "light grey" \ + ) + +/// Red colorblindness. Vulpkanins/Wolpins have this. +#define PROTANOPIA_COLOR_REPLACE \ + list( \ + "red" = "darkolivegreen", \ + "darkred" = "darkolivegreen", \ + "green" = "yellow", \ + "orange" = "goldenrod", \ + "gold" = "goldenrod", \ + "brown" = "darkolivegreen", \ + "cyan" = "steelblue", \ + "magenta" = "blue", \ + "purple" = "darkslategrey", \ + "pink" = "beige" \ + ) + +/// Green colorblindness. +#define DEUTERANOPIA_COLOR_REPLACE \ + list( \ + "red" = "goldenrod", \ + "green" = "tan", \ + "yellow" = "tan", \ + "orange" = "goldenrod", \ + "gold" = "burlywood", \ + "brown" = "saddlebrown",\ + "cyan" = "lavender", \ + "magenta" = "blue", \ + "darkmagenta" = "darkslateblue", \ + "purple" = "slateblue", \ + "pink" = "thistle" \ + ) + +/// Yellow-Blue colorblindness. Tajarans/Farwas have this. +#define TRITANOPIA_COLOR_REPLACE \ + list( \ + "red" = "rebeccapurple", \ + "blue" = "darkslateblue", \ + "green" = "darkolivegreen", \ + "orange" = "darkkhaki", \ + "gold" = "darkkhaki", \ + "brown" = "rebeccapurple", \ + "cyan" = "darkseagreen", \ + "magenta" = "darkslateblue", \ + "navy" = "darkslateblue", \ + "purple" = "darkslateblue", \ + "pink" = "lightgrey" \ + ) + +//Various stuff used in Persistence + +#define send_output(target, msg, control) target << output(msg, control) + +#define send_link(target, url) target << link(url) + +#define SPAN_NOTICE(X) "[X]" + +#define SPAN_WARNING(X) "[X]" + +#define SPAN_DANGER(X) "[X]" + +#define SPAN_OCCULT(X) "[X]" + +#define FONT_SMALL(X) "[X]" + +#define FONT_NORMAL(X) "[X]" + +#define FONT_LARGE(X) "[X]" + +#define FONT_HUGE(X) "[X]" + +#define FONT_GIANT(X) "[X]" diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index c7b1c0eb800..da9220b3af8 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -399,7 +399,9 @@ #define VIS_CLOAKED 23 -#define VIS_COUNT 23 //Must be highest number from above. +#define VIS_STATUS 24 + +#define VIS_COUNT 24 //Must be highest number from above. //Some mob icon layering defines #define BODY_LAYER -100 @@ -429,4 +431,6 @@ #define EXAMINE_SKIPLEGS 0x0080 #define EXAMINE_SKIPFEET 0x0100 -#define MAX_NUTRITION 5000 //VOREStation Edit \ No newline at end of file +#define MAX_NUTRITION 5000 //VOREStation Edit + +#define FAKE_INVIS_ALPHA_THRESHOLD 127 // If something's alpha var is at or below this number, certain things will pretend it is invisible. diff --git a/code/__defines/objects.dm b/code/__defines/objects.dm index 3d2891a3c5f..d6530fecff3 100644 --- a/code/__defines/objects.dm +++ b/code/__defines/objects.dm @@ -40,4 +40,12 @@ #define CATALOGUER_REWARD_SUPERHARD 2560 // Very difficult and dangerous, such as scanning the Advanced Dark Gygax. // 5 10 20 40 80 160 -// 10 40 160 640 2560 \ No newline at end of file +// 10 40 160 640 2560 + +// Defines for Exosuit components. + +#define MECH_HULL "Hull" +#define MECH_ACTUATOR "Actuator" +#define MECH_ARMOR "Plating" +#define MECH_GAS "Life Support" +#define MECH_ELECTRIC "Firmware" diff --git a/code/__defines/sound.dm b/code/__defines/sound.dm index d954d34b2a0..bd225bde451 100644 --- a/code/__defines/sound.dm +++ b/code/__defines/sound.dm @@ -124,8 +124,7 @@ 'sound/ambience/maintenance/maintenance2.ogg',\ 'sound/ambience/maintenance/maintenance3.ogg',\ 'sound/ambience/maintenance/maintenance4.ogg',\ - 'sound/ambience/maintenance/maintenance5.ogg',\ - 'sound/ambience/maintenance/maintenance6.ogg'\ + 'sound/ambience/maintenance/maintenance5.ogg'\ ) // Life support machinery at work, keeping everyone breathing. @@ -155,7 +154,11 @@ // Concerning sounds, for when one discovers something horrible happened in a PoI. #define AMBIENCE_FOREBODING list(\ 'sound/ambience/foreboding/foreboding1.ogg',\ - 'sound/ambience/foreboding/foreboding2.ogg'\ + 'sound/ambience/foreboding/foreboding2.ogg',\ + 'sound/ambience/foreboding/foreboding3.ogg',\ + 'sound/ambience/foreboding/foreboding4.ogg',\ + 'sound/ambience/foreboding/foreboding5.ogg',\ + 'sound/ambience/foreboding/foreboding6.ogg'\ ) // Ambience heard when aboveground on Sif and not in a Point of Interest. diff --git a/code/__defines/species_languages_vr.dm b/code/__defines/species_languages_vr.dm index 831df5253dd..54362278d4d 100644 --- a/code/__defines/species_languages_vr.dm +++ b/code/__defines/species_languages_vr.dm @@ -1,5 +1,6 @@ #define SPECIES_WHITELIST_SELECTABLE 0x20 // Can select and customize, but not join as +#define LANGUAGE_DRUDAKAR "D'Rudak'Ar" #define LANGUAGE_SLAVIC "Pan-Slavic" #define LANGUAGE_BIRDSONG "Birdsong" #define LANGUAGE_SAGARU "Sagaru" diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 0fa2532bf9b..4e333dac062 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -58,6 +58,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_MAPPING 25 #define INIT_ORDER_DECALS 20 #define INIT_ORDER_JOB 17 +#define INIT_ORDER_ALARM 16 // Must initialize before atoms. #define INIT_ORDER_ATOMS 15 #define INIT_ORDER_MACHINES 10 #define INIT_ORDER_SHUTTLES 3 @@ -70,13 +71,13 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_HOLOMAPS -5 #define INIT_ORDER_NIGHTSHIFT -6 #define INIT_ORDER_OVERLAY -7 -#define INIT_ORDER_ALARM -8 #define INIT_ORDER_OPENSPACE -10 #define INIT_ORDER_XENOARCH -20 #define INIT_ORDER_CIRCUIT -21 #define INIT_ORDER_AI -22 #define INIT_ORDER_AI_FAST -23 #define INIT_ORDER_GAME_MASTER -24 +#define INIT_ORDER_PERSISTENCE -25 #define INIT_ORDER_TICKER -50 #define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init. @@ -100,6 +101,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define FIRE_PRIORITY_TICKER 60 #define FIRE_PRIORITY_PLANETS 75 #define FIRE_PRIORITY_MACHINES 100 +#define FIRE_PRIORITY_TGUI 110 #define FIRE_PRIORITY_PROJECTILES 150 #define FIRE_PRIORITY_CHAT 400 #define FIRE_PRIORITY_OVERLAYS 500 diff --git a/code/__defines/tgui.dm b/code/__defines/tgui.dm new file mode 100644 index 00000000000..3d706a4e0fa --- /dev/null +++ b/code/__defines/tgui.dm @@ -0,0 +1,29 @@ +/// Maximum number of windows that can be suspended/reused +#define TGUI_WINDOW_SOFT_LIMIT 5 +/// Maximum number of open windows +#define TGUI_WINDOW_HARD_LIMIT 9 + +/// Maximum ping timeout allowed to detect zombie windows +#define TGUI_PING_TIMEOUT 4 SECONDS + +/// Window does not exist +#define TGUI_WINDOW_CLOSED 0 +/// Window was just opened, but is still not ready to be sent data +#define TGUI_WINDOW_LOADING 1 +/// Window is free and ready to receive data +#define TGUI_WINDOW_READY 2 + +/// Get a window id based on the provided pool index +#define TGUI_WINDOW_ID(index) "tgui-window-[index]" +/// Get a pool index of the provided window id +#define TGUI_WINDOW_INDEX(window_id) text2num(copytext(window_id, 13)) + +/// Max length for Modal Input +#define TGUI_MODAL_INPUT_MAX_LENGTH 1024 +/// Max length for Modal Input for names +#define TGUI_MODAL_INPUT_MAX_LENGTH_NAME 64 // Names for generally anything don't go past 32, let alone 64. + +#define TGUI_MODAL_OPEN 1 +#define TGUI_MODAL_DELEGATE 2 +#define TGUI_MODAL_ANSWER 3 +#define TGUI_MODAL_CLOSE 4 \ No newline at end of file diff --git a/code/__defines/wires.dm b/code/__defines/wires.dm new file mode 100644 index 00000000000..9fce2e8b870 --- /dev/null +++ b/code/__defines/wires.dm @@ -0,0 +1,122 @@ +// Wire defines for all machines/items. + +// Miscellaneous +#define WIRE_DUD_PREFIX "__dud" + +// General +#define WIRE_IDSCAN "ID Scan" +#define WIRE_MAIN_POWER1 "Primary Power" +#define WIRE_MAIN_POWER2 "Secondary Power" +#define WIRE_AI_CONTROL "AI Control" +#define WIRE_ELECTRIFY "Electrification" +#define WIRE_SAFETY "Safety" + +// Vendors and smartfridges +#define WIRE_THROW_ITEM "Item Throw" +#define WIRE_CONTRABAND "Contraband" + +// Airlock +#define WIRE_DOOR_BOLTS "Door Bolts" +#define WIRE_BACKUP_POWER1 "Primary Backup Power" +#define WIRE_BACKUP_POWER2 "Secondary Backup Power" +#define WIRE_OPEN_DOOR "Door State" +#define WIRE_SPEED "Door Timing" +#define WIRE_BOLT_LIGHT "Bolt Lights" + +// Air alarm +#define WIRE_SYPHON "Siphon" +#define WIRE_AALARM "Atmospherics Alarm" + +// Camera +#define WIRE_FOCUS "Focus" +#define WIRE_CAM_LIGHT "Camera Light" +#define WIRE_CAM_ALARM "Camera Alarm" + +// Grid Check +#define WIRE_REBOOT "Reboot" +#define WIRE_LOCKOUT "Lockout" +#define WIRE_ALLOW_MANUAL1 "Manual Override 1" +#define WIRE_ALLOW_MANUAL2 "Manual Override 2" +#define WIRE_ALLOW_MANUAL3 "Manual Override 3" + +// Jukebox +#define WIRE_POWER "Power" +#define WIRE_JUKEBOX_HACK "Hack" +#define WIRE_SPEEDUP "Speedup" +#define WIRE_SPEEDDOWN "Speeddown" +#define WIRE_REVERSE "Reverse" +#define WIRE_START "Start" +#define WIRE_STOP "Stop" +#define WIRE_PREV "Prev" +#define WIRE_NEXT "Next" + +// Mulebot +#define WIRE_MOB_AVOIDANCE "Mob Avoidance" +#define WIRE_LOADCHECK "Load Checking" +#define WIRE_MOTOR1 "Primary Motor" +#define WIRE_MOTOR2 "Secondary Motor" +#define WIRE_REMOTE_RX "Signal Receiver" +#define WIRE_REMOTE_TX "Signal Sender" +#define WIRE_BEACON_RX "Beacon Receiver" + +// Explosives, bombs +#define WIRE_EXPLODE "Explode" // Explodes if pulsed or cut while active, defuses a bomb that isn't active on cut. +#define WIRE_EXPLODE_DELAY "Explode Delay" // Explodes immediately if cut, explodes 3 seconds later if pulsed. +#define WIRE_DISARM "Disarm" // Explicit "disarming" wire. +#define WIRE_BADDISARM "Bad Disarm" // Disarming wire, except it blows up anyways. +#define WIRE_BOMB_UNBOLT "Unbolt" // Unbolts the bomb if cut, hint on pulsed. +#define WIRE_BOMB_DELAY "Delay" // Raises the timer on pulse, does nothing on cut. +#define WIRE_BOMB_PROCEED "Proceed" // Lowers the timer, explodes if cut while the bomb is active. +#define WIRE_BOMB_ACTIVATE "Activate" // Will start a bombs timer if pulsed, will hint if pulsed while already active, will stop a timer a bomb on cut. + +// Nuclear bomb +#define WIRE_BOMB_LIGHT "Bomb Light" +#define WIRE_BOMB_TIMING "Bomb Timing" +#define WIRE_BOMB_SAFETY "Bomb Safety" + +// Particle accelerator +#define WIRE_PARTICLE_POWER "Power Toggle" // Toggles whether the PA is on or not. +#define WIRE_PARTICLE_STRENGTH "Strength" // Determines the strength of the PA. +#define WIRE_PARTICLE_INTERFACE "Interface" // Determines the interface showing up. +#define WIRE_PARTICLE_POWER_LIMIT "Maximum Power" // Determines how strong the PA can be. + +// Autolathe +#define WIRE_AUTOLATHE_HACK "Hack" +#define WIRE_AUTOLATHE_DISABLE "Disable" + +// Radio +#define WIRE_RADIO_SIGNAL "Signal" +#define WIRE_RADIO_RECEIVER "Receiver" +#define WIRE_RADIO_TRANSMIT "Transmitter" + +// Cyborg +#define WIRE_BORG_LOCKED "Lockdown" +#define WIRE_BORG_CAMERA "Camera" +#define WIRE_BORG_LAWCHECK "Law Check" + +// Seed Storage +#define WIRE_SEED_SMART "Smart" +#define WIRE_SEED_LOCKDOWN "Lockdown" + +// Shield Generator +#define WIRE_SHIELD_CONTROL "Shield Controls" // Cut to lock most shield controls. Mend to unlock them. Pulse does nothing. + +// SMES +#define WIRE_SMES_RCON "RCon" // Remote control (AI and consoles), cut to disable +#define WIRE_SMES_INPUT "Input" // Input wire, cut to disable input, pulse to disable for 60s +#define WIRE_SMES_OUTPUT "Output" // Output wire, cut to disable output, pulse to disable for 60s +#define WIRE_SMES_GROUNDING "Grounding" // Cut to quickly discharge causing sparks, pulse to only create few sparks +#define WIRE_SMES_FAILSAFES "Failsafes" // Cut to disable failsafes, mend to reenable + +// Suit storage unit +#define WIRE_SSU_UV "UV wire" + +// Tesla coil +#define WIRE_TESLACOIL_ZAP "Zap" + +// RIGsuits +#define WIRE_RIG_SECURITY "Security" +#define WIRE_RIG_AI_OVERRIDE "AI Override" +#define WIRE_RIG_SYSTEM_CONTROL "System Control" +#define WIRE_RIG_INTERFACE_LOCK "Interface Lock" +#define WIRE_RIG_INTERFACE_SHOCK "Interface Shock" diff --git a/code/_global_vars/lists/misc.dm b/code/_global_vars/lists/misc.dm index c10fcba5303..adec2bf824f 100644 --- a/code/_global_vars/lists/misc.dm +++ b/code/_global_vars/lists/misc.dm @@ -1,2 +1,5 @@ GLOBAL_LIST_INIT(speech_toppings, list("|" = "i", "+" = "b", "_" = "u")) GLOBAL_LIST_EMPTY(meteor_list) + +/// List of wire colors for each object type of that round. One for airlocks, one for vendors, etc. +GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value. \ No newline at end of file diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index 6ec3ccb9662..40dbaf49cbe 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -615,4 +615,83 @@ datum/projectile_data /proc/window_flash(var/client_or_usr) if (!client_or_usr) return - winset(client_or_usr, "mainwindow", "flash=5") \ No newline at end of file + winset(client_or_usr, "mainwindow", "flash=5") + +/** + * Get a bounding box of a list of atoms. + * + * Arguments: + * - atoms - List of atoms. Can accept output of view() and range() procs. + * + * Returns: list(x1, y1, x2, y2) + */ +/proc/get_bbox_of_atoms(list/atoms) + var/list/list_x = list() + var/list/list_y = list() + for(var/_a in atoms) + var/atom/a = _a + list_x += a.x + list_y += a.y + return list( + min(list_x), + min(list_y), + max(list_x), + max(list_y)) + +// Will recursively loop through an atom's contents and check for mobs, then it will loop through every atom in that atom's contents. +// It will keep doing this until it checks every content possible. This will fix any problems with mobs, that are inside objects, +// being unable to hear people due to being in a box within a bag. + +/proc/recursive_mob_check(var/atom/O, var/list/L = list(), var/recursion_limit = 3, var/client_check = 1, var/sight_check = 1, var/include_radio = 1) + + //GLOB.debug_mob += O.contents.len + if(!recursion_limit) + return L + for(var/atom/A in O.contents) + + if(ismob(A)) + var/mob/M = A + if(client_check && !M.client) + L |= recursive_mob_check(A, L, recursion_limit - 1, client_check, sight_check, include_radio) + continue + if(sight_check && !isInSight(A, O)) + continue + L |= M + //log_world("[recursion_limit] = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])") + + else if(include_radio && istype(A, /obj/item/radio)) + if(sight_check && !isInSight(A, O)) + continue + L |= A + + if(isobj(A) || ismob(A)) + L |= recursive_mob_check(A, L, recursion_limit - 1, client_check, sight_check, include_radio) + return L + +// The old system would loop through lists for a total of 5000 per function call, in an empty server. +// This new system will loop at around 1000 in an empty server. + +/proc/get_mobs_in_view(var/R, var/atom/source, var/include_clientless = FALSE) + // Returns a list of mobs in range of R from source. Used in radio and say code. + + var/turf/T = get_turf(source) + var/list/hear = list() + + if(!T) + return hear + + var/list/range = hear(R, T) + + for(var/atom/A in range) + if(ismob(A)) + var/mob/M = A + if(M.client || include_clientless) + hear += M + //log_world("Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])") + else if(istype(A, /obj/item/radio)) + hear += A + + if(isobj(A) || ismob(A)) + hear |= recursive_mob_check(A, hear, 3, 1, 0, 1) + + return hear \ No newline at end of file diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm index 498f497a7c8..b2dfae05444 100644 --- a/code/_helpers/global_lists_vr.dm +++ b/code/_helpers/global_lists_vr.dm @@ -154,7 +154,7 @@ var/global/list/edible_trash = list(/obj/item/broken_device, /obj/item/weapon/bone, /obj/item/weapon/broken_bottle, /obj/item/weapon/card/emag_broken, - /obj/item/weapon/cigbutt, + /obj/item/trash/cigbutt, /obj/item/weapon/circuitboard/broken, /obj/item/weapon/clipboard, /obj/item/weapon/corncob, diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index d27abcbf7e2..757555f0375 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -176,6 +176,22 @@ /proc/log_unit_test(text) to_world_log("## UNIT_TEST: [text]") +/proc/log_tgui(user_or_client, text) + var/entry = "" + if(!user_or_client) + entry += "no user" + else if(istype(user_or_client, /mob)) + var/mob/user = user_or_client + entry += "[user.ckey] (as [user])" + else if(istype(user_or_client, /client)) + var/client/client = user_or_client + entry += "[client.ckey]" + entry += ":\n[text]" + WRITE_LOG(diary, entry) + +/proc/log_asset(text) + WRITE_LOG(diary, "ASSET: [text]") + /proc/report_progress(var/progress_message) admin_notice("[progress_message]", R_DEBUG) to_world_log(progress_message) diff --git a/code/_helpers/sorts/comparators.dm b/code/_helpers/sorts/comparators.dm index a9ca5748b77..f4a8c575c98 100644 --- a/code/_helpers/sorts/comparators.dm +++ b/code/_helpers/sorts/comparators.dm @@ -56,3 +56,9 @@ . = B[STAT_ENTRY_TIME] - A[STAT_ENTRY_TIME] if (!.) . = B[STAT_ENTRY_COUNT] - A[STAT_ENTRY_COUNT] + +// Compares complexity of recipes for use in cooking, etc. This is for telling which recipe to make, not for showing things to the player. +/proc/cmp_recipe_complexity_dsc(datum/recipe/A, datum/recipe/B) + var/a_score = LAZYLEN(A.items) + LAZYLEN(A.reagents) + LAZYLEN(A.fruit) + var/b_score = LAZYLEN(B.items) + LAZYLEN(B.reagents) + LAZYLEN(B.fruit) + return b_score - a_score \ No newline at end of file diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm index 67844cf4a2d..1b028e117b7 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -138,6 +138,19 @@ /proc/sanitize_old(var/t,var/list/repl_chars = list("\n"="#","\t"="#")) return html_encode(replace_characters(t,repl_chars)) + +//Removes a few problematic characters +/proc/sanitize_simple(t,list/repl_chars = list("\n"="#","\t"="#")) + for(var/char in repl_chars) + var/index = findtext(t, char) + while(index) + t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index + length(char)) + index = findtext(t, char, index + length(char)) + return t + +/proc/sanitize_filename(t) + return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"="")) + /* * Text searches */ diff --git a/code/_helpers/type2type.dm b/code/_helpers/type2type.dm index 18a94a501d0..77019ab7b9f 100644 --- a/code/_helpers/type2type.dm +++ b/code/_helpers/type2type.dm @@ -281,3 +281,103 @@ return strtype return copytext(strtype, delim_pos) +// Concatenates a list of strings into a single string. A seperator may optionally be provided. +/proc/list2text(list/ls, sep) + if (ls.len <= 1) // Early-out code for empty or singleton lists. + return ls.len ? ls[1] : "" + + var/l = ls.len // Made local for sanic speed. + var/i = 0 // Incremented every time a list index is accessed. + + if (sep != null) + // Macros expand to long argument lists like so: sep, ls[++i], sep, ls[++i], sep, ls[++i], etc... + #define S1 sep, ls[++i] + #define S4 S1, S1, S1, S1 + #define S16 S4, S4, S4, S4 + #define S64 S16, S16, S16, S16 + + . = "[ls[++i]]" // Make sure the initial element is converted to text. + + // Having the small concatenations come before the large ones boosted speed by an average of at least 5%. + if (l-1 & 0x01) // 'i' will always be 1 here. + . = text("[][][]", ., S1) // Append 1 element if the remaining elements are not a multiple of 2. + if (l-i & 0x02) + . = text("[][][][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4. + if (l-i & 0x04) + . = text("[][][][][][][][][]", ., S4) // And so on.... + if (l-i & 0x08) + . = text("[][][][][][][][][][][][][][][][][]", ., S4, S4) + if (l-i & 0x10) + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16) + if (l-i & 0x20) + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16) + if (l-i & 0x40) + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64) + while (l > i) // Chomp through the rest of the list, 128 elements at a time. + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64) + + #undef S64 + #undef S16 + #undef S4 + #undef S1 + else + // Macros expand to long argument lists like so: ls[++i], ls[++i], ls[++i], etc... + #define S1 ls[++i] + #define S4 S1, S1, S1, S1 + #define S16 S4, S4, S4, S4 + #define S64 S16, S16, S16, S16 + + . = "[ls[++i]]" // Make sure the initial element is converted to text. + + if (l-1 & 0x01) // 'i' will always be 1 here. + . += S1 // Append 1 element if the remaining elements are not a multiple of 2. + if (l-i & 0x02) + . = text("[][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4. + if (l-i & 0x04) + . = text("[][][][][]", ., S4) // And so on... + if (l-i & 0x08) + . = text("[][][][][][][][][]", ., S4, S4) + if (l-i & 0x10) + . = text("[][][][][][][][][][][][][][][][][]", ., S16) + if (l-i & 0x20) + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16) + if (l-i & 0x40) + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64) + while (l > i) // Chomp through the rest of the list, 128 elements at a time. + . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64) + + #undef S64 + #undef S16 + #undef S4 + #undef S1 + +// Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator) +/proc/text2list(text, delimiter="\n") + var/delim_len = length(delimiter) + if (delim_len < 1) + return list(text) + + . = list() + var/last_found = 1 + var/found + + do + found = findtext(text, delimiter, last_found, 0) + . += copytext(text, last_found, found) + last_found = found + delim_len + while (found) diff --git a/code/_helpers/type2type_vr.dm b/code/_helpers/type2type_vr.dm deleted file mode 100644 index e6df5318061..00000000000 --- a/code/_helpers/type2type_vr.dm +++ /dev/null @@ -1,107 +0,0 @@ -/* -// Contains VOREStation type2type functions -// list2text - takes delimiter and returns text -// text2list - takes delimiter, and creates list -// -*/ - -// Concatenates a list of strings into a single string. A seperator may optionally be provided. -/proc/list2text(list/ls, sep) - if (ls.len <= 1) // Early-out code for empty or singleton lists. - return ls.len ? ls[1] : "" - - var/l = ls.len // Made local for sanic speed. - var/i = 0 // Incremented every time a list index is accessed. - - if (sep <> null) - // Macros expand to long argument lists like so: sep, ls[++i], sep, ls[++i], sep, ls[++i], etc... - #define S1 sep, ls[++i] - #define S4 S1, S1, S1, S1 - #define S16 S4, S4, S4, S4 - #define S64 S16, S16, S16, S16 - - . = "[ls[++i]]" // Make sure the initial element is converted to text. - - // Having the small concatenations come before the large ones boosted speed by an average of at least 5%. - if (l-1 & 0x01) // 'i' will always be 1 here. - . = text("[][][]", ., S1) // Append 1 element if the remaining elements are not a multiple of 2. - if (l-i & 0x02) - . = text("[][][][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4. - if (l-i & 0x04) - . = text("[][][][][][][][][]", ., S4) // And so on.... - if (l-i & 0x08) - . = text("[][][][][][][][][][][][][][][][][]", ., S4, S4) - if (l-i & 0x10) - . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16) - if (l-i & 0x20) - . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16) - if (l-i & 0x40) - . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64) - while (l > i) // Chomp through the rest of the list, 128 elements at a time. - . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64) - - #undef S64 - #undef S16 - #undef S4 - #undef S1 - else - // Macros expand to long argument lists like so: ls[++i], ls[++i], ls[++i], etc... - #define S1 ls[++i] - #define S4 S1, S1, S1, S1 - #define S16 S4, S4, S4, S4 - #define S64 S16, S16, S16, S16 - - . = "[ls[++i]]" // Make sure the initial element is converted to text. - - if (l-1 & 0x01) // 'i' will always be 1 here. - . += S1 // Append 1 element if the remaining elements are not a multiple of 2. - if (l-i & 0x02) - . = text("[][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4. - if (l-i & 0x04) - . = text("[][][][][]", ., S4) // And so on... - if (l-i & 0x08) - . = text("[][][][][][][][][]", ., S4, S4) - if (l-i & 0x10) - . = text("[][][][][][][][][][][][][][][][][]", ., S16) - if (l-i & 0x20) - . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16) - if (l-i & 0x40) - . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64) - while (l > i) // Chomp through the rest of the list, 128 elements at a time. - . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64) - - #undef S64 - #undef S16 - #undef S4 - #undef S1 - -// Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator) -/proc/text2list(text, delimiter="\n") - var/delim_len = length(delimiter) - if (delim_len < 1) - return list(text) - - . = list() - var/last_found = 1 - var/found - - do - found = findtext(text, delimiter, last_found, 0) - . += copytext(text, last_found, found) - last_found = found + delim_len - while (found) diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index e218727049b..eba949e02d7 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -289,6 +289,11 @@ Turf and target are seperate in case you want to teleport some distance from a t /proc/format_frequency(var/f) return "[round(f / 10)].[f % 10]" +//Opposite of format, returns as a number +/proc/unformat_frequency(frequency) + frequency = text2num(frequency) + return frequency * 10 + //This will update a mob's name, real_name, mind.name, data_core records, pda and id @@ -1571,6 +1576,14 @@ var/mob/dview/dview_mob = new /datum/proc/stack_trace(msg) CRASH(msg) +GLOBAL_REAL_VAR(list/stack_trace_storage) +/proc/gib_stack_trace() + stack_trace_storage = list() + stack_trace() + stack_trace_storage.Cut(1, min(3,stack_trace_storage.len)) + . = stack_trace_storage + stack_trace_storage = null + // \ref behaviour got changed in 512 so this is necesary to replicate old behaviour. // If it ever becomes necesary to get a more performant REF(), this lies here in wait // #define REF(thing) (thing && istype(thing, /datum) && (thing:datum_flags & DF_USE_TAG) && thing:tag ? "[thing:tag]" : "\ref[thing]") diff --git a/code/_helpers/visual_filters.dm b/code/_helpers/visual_filters.dm new file mode 100644 index 00000000000..6cafa5a04d2 --- /dev/null +++ b/code/_helpers/visual_filters.dm @@ -0,0 +1,36 @@ +// These involve BYOND's built in filters that do visual effects, and not stuff that distinguishes between things. + +// All of this ported from TG. +/atom/movable + var/list/filter_data // For handling persistent filters + +/proc/cmp_filter_data_priority(list/A, list/B) + return A["priority"] - B["priority"] + +/atom/movable/proc/add_filter(filter_name, priority, list/params) + LAZYINITLIST(filter_data) + var/list/p = params.Copy() + p["priority"] = priority + filter_data[filter_name] = p + update_filters() + +/atom/movable/proc/update_filters() + filters = null + filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, TRUE) + for(var/f in filter_data) + var/list/data = filter_data[f] + var/list/arguments = data.Copy() + arguments -= "priority" + filters += filter(arglist(arguments)) + +/atom/movable/proc/get_filter(filter_name) + if(filter_data && filter_data[filter_name]) + return filters[filter_data.Find(filter_name)] + +// Polaris Extensions +/atom/movable/proc/remove_filter(filter_name) + var/thing = get_filter(filter_name) + if(thing) + LAZYREMOVE(filter_data, filter_name) + filters -= thing + update_filters() \ No newline at end of file diff --git a/code/_macros.dm b/code/_macros.dm index 5b7fb379d30..4796f93b472 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -37,4 +37,4 @@ #define random_id(key,min_id,max_id) uniqueness_repository.Generate(/datum/uniqueness_generator/id_random, key, min_id, max_id) -#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") } +#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") } \ No newline at end of file diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index b431ac12986..859884a8b7c 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -122,25 +122,22 @@ /atom/proc/AIShiftClick() return -/obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors! - if(density) - Topic(src, list("command"="open", "activate" = "1")) - else - Topic(src, list("command"="open", "activate" = "0")) +/obj/machinery/door/airlock/AIShiftClick(mob/user) // Opens and closes doors! + add_fingerprint(user) + user_toggle_open(user) return 1 -/atom/proc/AICtrlClick() +/atom/proc/AICtrlClick(mob/user) return -/obj/machinery/door/airlock/AICtrlClick() // Bolts doors - if(locked) - Topic(src, list("command"="bolts", "activate" = "0")) - else - Topic(src, list("command"="bolts", "activate" = "1")) +/obj/machinery/door/airlock/AICtrlClick(mob/user) // Bolts doors + add_fingerprint(user) + toggle_bolt(user) return 1 -/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs. - Topic(src, list("breaker"="1")) +/obj/machinery/power/apc/AICtrlClick(mob/user) // turns off/on APCs. + add_fingerprint(user) + toggle_breaker() return 1 /obj/machinery/turretid/AICtrlClick() //turns off/on Turrets @@ -150,13 +147,12 @@ /atom/proc/AIAltClick(var/atom/A) return AltClick(A) -/obj/machinery/door/airlock/AIAltClick() // Electrifies doors. - if(!electrified_until) - // permanent shock - Topic(src, list("command"="electrify_permanently", "activate" = "1")) +/obj/machinery/door/airlock/AIAltClick(mob/user) // Electrifies doors. + add_fingerprint(user) + if(electrified_until) + electrify(0, 1) else - // disable/6 is not in Topic; disable/5 disables both temporary and permanent shock - Topic(src, list("command"="electrify_permanently", "activate" = "0")) + electrify(-1, 1) return 1 /obj/machinery/turretid/AIAltClick() //toggles lethal on turrets @@ -166,16 +162,17 @@ /atom/proc/AIMiddleClick(var/mob/living/silicon/user) return 0 -/obj/machinery/door/airlock/AIMiddleClick() // Toggles door bolt lights. - +/obj/machinery/door/airlock/AIMiddleClick(mob/user) // Toggles door bolt lights. if(..()) return - - if(!src.lights) - Topic(src, list("command"="lights", "activate" = "1")) - else - Topic(src, list("command"="lights", "activate" = "0")) - return 1 + add_fingerprint(user) + if(wires.is_cut(WIRE_BOLT_LIGHT)) + to_chat(user, "The bolt lights wire is cut - The door bolt lights are permanently disabled.") + return + lights = !lights + to_chat(user, "Lights are now [lights ? "on." : "off."]") + update_icon() + return TRUE // // Override AdjacentQuick for AltClicking diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 0c994251478..ab56dc6032d 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -117,37 +117,36 @@ /atom/proc/BorgCtrlShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden CtrlShiftClick(user) -/obj/machinery/door/airlock/BorgCtrlShiftClick() - AICtrlShiftClick() +/obj/machinery/door/airlock/BorgCtrlShiftClick(mob/user) + AICtrlShiftClick(user) /atom/proc/BorgShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden ShiftClick(user) -/obj/machinery/door/airlock/BorgShiftClick() // Opens and closes doors! Forwards to AI code. - AIShiftClick() - +/obj/machinery/door/airlock/BorgShiftClick(mob/user) // Opens and closes doors! Forwards to AI code. + AIShiftClick(user) /atom/proc/BorgCtrlClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden CtrlClick(user) -/obj/machinery/door/airlock/BorgCtrlClick() // Bolts doors. Forwards to AI code. - AICtrlClick() +/obj/machinery/door/airlock/BorgCtrlClick(mob/user) // Bolts doors. Forwards to AI code. + AICtrlClick(user) -/obj/machinery/power/apc/BorgCtrlClick() // turns off/on APCs. Forwards to AI code. - AICtrlClick() +/obj/machinery/power/apc/BorgCtrlClick(mob/user) // turns off/on APCs. Forwards to AI code. + AICtrlClick(user) -/obj/machinery/turretid/BorgCtrlClick() //turret control on/off. Forwards to AI code. - AICtrlClick() +/obj/machinery/turretid/BorgCtrlClick(mob/user) //turret control on/off. Forwards to AI code. + AICtrlClick(user) /atom/proc/BorgAltClick(var/mob/living/silicon/robot/user) AltClick(user) return -/obj/machinery/door/airlock/BorgAltClick() // Eletrifies doors. Forwards to AI code. - AIAltClick() +/obj/machinery/door/airlock/BorgAltClick(mob/user) // Eletrifies doors. Forwards to AI code. + AIAltClick(user) -/obj/machinery/turretid/BorgAltClick() //turret lethal on/off. Forwards to AI code. - AIAltClick() +/obj/machinery/turretid/BorgAltClick(mob/user) //turret lethal on/off. Forwards to AI code. + AIAltClick(user) /* As with AI, these are not used in click code, diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index c123790b51c..160413135b0 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -222,4 +222,8 @@ #undef AB_WEST_OFFSET #undef AB_NORTH_OFFSET -#undef AB_MAX_COLUMNS \ No newline at end of file +#undef AB_MAX_COLUMNS + + +/datum/action/innate/ + action_type = AB_INNATE \ No newline at end of file diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 7060451b275..f0a959c6a7b 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -123,8 +123,3 @@ /obj/screen/fullscreen/fishbed icon_state = "fishbed" - -#undef FULLSCREEN_LAYER -#undef BLIND_LAYER -#undef DAMAGE_LAYER -#undef CRIT_LAYER \ No newline at end of file diff --git a/code/_onclick/hud/map_popups.dm b/code/_onclick/hud/map_popups.dm new file mode 100644 index 00000000000..aae5c808c97 --- /dev/null +++ b/code/_onclick/hud/map_popups.dm @@ -0,0 +1,171 @@ +/client + /** + * Assoc list with all the active maps - when a screen obj is added to + * a map, it's put in here as well. + * + * Format: list( = list(/obj/screen)) + */ + var/list/screen_maps = list() + +/obj/screen + /** + * Map name assigned to this object. + * Automatically set by /client/proc/register_map_obj. + */ + var/assigned_map + /** + * Mark this object as garbage-collectible after you clean the map + * it was registered on. + * + * This could probably be changed to be a proc, for conditional removal. + * But for now, this works. + */ + var/del_on_map_removal = TRUE + +/** + * A screen object, which acts as a container for turfs and other things + * you want to show on the map, which you usually attach to "vis_contents". + */ +/obj/screen/map_view + icon_state = "blank" + // Map view has to be on the lowest plane to enable proper lighting + layer = SPACE_PLANE + plane = SPACE_PLANE + +/** + * A generic background object. + * It is also implicitly used to allocate a rectangle on the map, which will + * be used for auto-scaling the map. + */ +/obj/screen/background + name = "background" + icon = 'icons/mob/map_backgrounds.dmi' + icon_state = "clear" + layer = SPACE_PLANE + plane = SPACE_PLANE + +/** + * Sets screen_loc of this screen object, in form of point coordinates, + * with optional pixel offset (px, py). + * + * If applicable, "assigned_map" has to be assigned before this proc call. + */ +/obj/screen/proc/set_position(x, y, px = 0, py = 0) + if(assigned_map) + screen_loc = "[assigned_map]:[x]:[px],[y]:[py]" + else + screen_loc = "[x]:[px],[y]:[py]" + +/** + * Sets screen_loc to fill a rectangular area of the map. + * + * If applicable, "assigned_map" has to be assigned before this proc call. + */ +/obj/screen/proc/fill_rect(x1, y1, x2, y2) + if(assigned_map) + screen_loc = "[assigned_map]:[x1],[y1] to [x2],[y2]" + else + screen_loc = "[x1],[y1] to [x2],[y2]" + +/** + * Registers screen obj with the client, which makes it visible on the + * assigned map, and becomes a part of the assigned map's lifecycle. + */ +/client/proc/register_map_obj(obj/screen/screen_obj) + if(!screen_obj.assigned_map) + CRASH("Can't register [screen_obj] without 'assigned_map' property.") + if(!screen_maps[screen_obj.assigned_map]) + screen_maps[screen_obj.assigned_map] = list() + // NOTE: Possibly an expensive operation + var/list/screen_map = screen_maps[screen_obj.assigned_map] + if(!screen_map.Find(screen_obj)) + screen_map += screen_obj + if(!screen.Find(screen_obj)) + screen += screen_obj + +/** + * Clears the map of registered screen objects. + * + * Not really needed most of the time, as the client's screen list gets reset + * on relog. any of the buttons are going to get caught by garbage collection + * anyway. they're effectively qdel'd. + */ +/client/proc/clear_map(map_name) + if(!map_name || !(map_name in screen_maps)) + return FALSE + for(var/obj/screen/screen_obj in screen_maps[map_name]) + screen_maps[map_name] -= screen_obj + if(screen_obj.del_on_map_removal) + qdel(screen_obj) + screen_maps -= map_name + +/** + * Clears all the maps of registered screen objects. + */ +/client/proc/clear_all_maps() + for(var/map_name in screen_maps) + clear_map(map_name) + +/** + * Creates a popup window with a basic map element in it, without any + * further initialization. + * + * Ratio is how many pixels by how many pixels (keep it simple). + * + * Returns a map name. + */ +/client/proc/create_popup(name, ratiox = 100, ratioy = 100) + winclone(src, "popupwindow", name) + var/list/winparams = list() + winparams["size"] = "[ratiox]x[ratioy]" + winparams["on-close"] = "handle-popup-close [name]" + winset(src, "[name]", list2params(winparams)) + winshow(src, "[name]", 1) + + var/list/params = list() + params["parent"] = "[name]" + params["type"] = "map" + params["size"] = "[ratiox]x[ratioy]" + params["anchor1"] = "0,0" + params["anchor2"] = "[ratiox],[ratioy]" + winset(src, "[name]_map", list2params(params)) + + return "[name]_map" + +/** + * Create the popup, and get it ready for generic use by giving + * it a background. + * + * Width and height are multiplied by 64 by default. + */ +/client/proc/setup_popup(popup_name, width = 9, height = 9, \ + tilesize = 2, bg_icon) + if(!popup_name) + return + clear_map("[popup_name]_map") + var/x_value = world.icon_size * tilesize * width + var/y_value = world.icon_size * tilesize * height + var/map_name = create_popup(popup_name, x_value, y_value) + + var/obj/screen/background/background = new + background.assigned_map = map_name + background.fill_rect(1, 1, width, height) + if(bg_icon) + background.icon_state = bg_icon + register_map_obj(background) + + return map_name + +/** + * Closes a popup. + */ +/client/proc/close_popup(popup) + winshow(src, popup, 0) + handle_popup_close(popup) + +/** + * When the popup closes in any way (player or proc call) it calls this. + */ +/client/verb/handle_popup_close(window_id as text) + set hidden = TRUE + clear_map("[window_id]_map") diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 64535b174aa..e393248c6e4 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -470,7 +470,6 @@ var/mob/living/silicon/robot/R = usr if(R.module) R.uneq_active() - R.hud_used.update_robot_modules_display() else to_chat(R, "You haven't selected a module yet.") diff --git a/code/_onclick/hud/skybox.dm b/code/_onclick/hud/skybox.dm index f055ea86936..efd11798915 100644 --- a/code/_onclick/hud/skybox.dm +++ b/code/_onclick/hud/skybox.dm @@ -3,17 +3,20 @@ #define SKYBOX_TURFS (SKYBOX_PIXELS/WORLD_ICON_SIZE) // Skybox screen object. -/obj/skybox +/obj/screen/skybox name = "skybox" + icon = null + appearance_flags = TILE_BOUND|PIXEL_SCALE mouse_opacity = 0 anchored = TRUE simulated = FALSE screen_loc = "CENTER,CENTER" + layer = OBJ_LAYER plane = SKYBOX_PLANE blend_mode = BLEND_MULTIPLY // You actually need to do it this way or you see it in occlusion. // Adjust transform property to scale for client's view var. We assume the skybox is 736x736 px -/obj/skybox/proc/scale_to_view(var/view) +/obj/screen/skybox/proc/scale_to_view(var/view) var/matrix/M = matrix() // Translate to center the icon over us! M.Translate(-(SKYBOX_PIXELS - WORLD_ICON_SIZE) / 2) @@ -23,7 +26,7 @@ src.transform = M /client - var/obj/skybox/skybox + var/obj/screen/skybox/skybox /client/proc/update_skybox(rebuild) if(!skybox) diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm index b99ab68064b..c1d87d7ef35 100644 --- a/code/controllers/communications.dm +++ b/code/controllers/communications.dm @@ -148,6 +148,41 @@ var/list/radiochannels = list( "Talon" = TALON_FREQ //VOREStation Add ) +// Hey, if anyone ever needs to update tgui/packages/tgui/constants.js with new radio channels +// I've kept this around just for you. +/* /client/verb/generate_tgui_radio_constants() + set name = "Generate TGUI Radio Constants" + set category = "Generate TGUI Radio Constants" + + var/list/channel_info = list() + + for(var/i in RADIO_LOW_FREQ to RADIO_HIGH_FREQ) + for(var/key in radiochannels) + if(i == radiochannels[key]) + channel_info.Add(list(list("name" = key, "freq" = i, "color" = frequency_span_class(i)))) + + for(var/list/channel in channel_info) + switch(channel["color"]) + if("deadsay") channel["color"] = "#530FAD" + if("radio") channel["color"] = "#008000" + if("deptradio") channel["color"] = "#ff00ff" + if("newscaster") channel["color"] = "#750000" + if("comradio") channel["color"] = "#193A7A" + if("syndradio") channel["color"] = "#6D3F40" + if("centradio") channel["color"] = "#5C5C8A" + if("airadio") channel["color"] = "#FF00FF" + if("entradio") channel["color"] = "#339966" + if("secradio") channel["color"] = "#A30000" + if("engradio") channel["color"] = "#A66300" + if("medradio") channel["color"] = "#008160" + if("sciradio") channel["color"] = "#993399" + if("supradio") channel["color"] = "#5F4519" + if("srvradio") channel["color"] = "#6eaa2c" + if("expradio") channel["color"] = "#555555" + + to_chat(src, json_encode(channel_info)) */ + + // central command channels, i.e deathsquid & response teams var/list/CENT_FREQS = list(ERT_FREQ, DTH_FREQ) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 3a649b4ad49..ed77065e19f 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -236,6 +236,8 @@ var/list/gamemode_cache = list() var/static/dooc_allowed = 1 var/static/dsay_allowed = 1 + var/persistence_enabled = 1 + var/allow_byond_links = 0 var/allow_discord_links = 0 var/allow_url_links = 0 // honestly if I were you i'd leave this one off, only use in dire situations @@ -434,15 +436,15 @@ var/list/gamemode_cache = list() if ("allow_admin_spawning") config.allow_admin_spawning = 1 - + if ("allow_byond_links") allow_byond_links = 1 if ("allow_discord_links") - allow_discord_links = 1 + allow_discord_links = 1 if ("allow_url_links") - allow_url_links = 1 + allow_url_links = 1 if ("no_dead_vote") config.vote_no_dead = 1 @@ -577,6 +579,9 @@ var/list/gamemode_cache = list() if("protect_roles_from_antagonist") config.protect_roles_from_antagonist = 1 + if ("persistence_enabled") + config.persistence_enabled = 1 + if ("probability") var/prob_pos = findtext(value, " ") var/prob_name = null diff --git a/code/controllers/subsystems/ai.dm b/code/controllers/subsystems/ai.dm index 0641453f2ba..4ed43a34811 100644 --- a/code/controllers/subsystems/ai.dm +++ b/code/controllers/subsystems/ai.dm @@ -32,7 +32,7 @@ SUBSYSTEM_DEF(ai) while(currentrun.len) var/datum/ai_holder/A = currentrun[currentrun.len] --currentrun.len - if(!A || QDELETED(A) || A.busy) // Doesn't exist or won't exist soon or not doing it this tick + if(!A || QDELETED(A) || !A.holder?.loc || A.busy) // Doesn't exist or won't exist soon or not doing it this tick continue if(process_z[get_z(A.holder)]) diff --git a/code/controllers/subsystems/mobs.dm b/code/controllers/subsystems/mobs.dm index 8fb2bf3f891..1ae1d647579 100644 --- a/code/controllers/subsystems/mobs.dm +++ b/code/controllers/subsystems/mobs.dm @@ -43,7 +43,7 @@ SUBSYSTEM_DEF(mobs) if(!M || QDELETED(M)) mob_list -= M continue - else if(M.low_priority && !(process_z[get_z(M)])) + else if(M.low_priority && !(M.loc && process_z[get_z(M)])) slept_mobs++ continue diff --git a/code/controllers/subsystems/persistence.dm b/code/controllers/subsystems/persistence.dm new file mode 100644 index 00000000000..49f3d601fee --- /dev/null +++ b/code/controllers/subsystems/persistence.dm @@ -0,0 +1,59 @@ +SUBSYSTEM_DEF(persistence) + name = "Persistence" + init_order = INIT_ORDER_PERSISTENCE + flags = SS_NO_FIRE + var/list/tracking_values = list() + var/list/persistence_datums = list() + +/datum/controller/subsystem/persistence/Initialize() + . = ..() + for(var/thing in subtypesof(/datum/persistent)) + var/datum/persistent/P = new thing + persistence_datums[thing] = P + P.Initialize() + +/datum/controller/subsystem/persistence/Shutdown() + for(var/thing in persistence_datums) + var/datum/persistent/P = persistence_datums[thing] + P.Shutdown() + +/datum/controller/subsystem/persistence/proc/track_value(var/atom/value, var/track_type) + + if(config.persistence_enabled == 0) //if the config is not set to persistent nothing will save or load. + return + + var/turf/T = get_turf(value) + if(!T) + return + + var/area/A = get_area(T) + if(!A || (A.flags & AREA_FLAG_IS_NOT_PERSISTENT)) + return + +// if((!T.z in GLOB.using_map.station_levels) || !initialized) + if(!T.z in using_map.station_levels) + return + + if(!tracking_values[track_type]) + tracking_values[track_type] = list() + tracking_values[track_type] += value + +/datum/controller/subsystem/persistence/proc/forget_value(var/atom/value, var/track_type) + if(tracking_values[track_type]) + tracking_values[track_type] -= value + + +/datum/controller/subsystem/persistence/proc/show_info(var/mob/user) + if(!user.client.holder) + return + + var/list/dat = list("") + var/can_modify = check_rights(R_ADMIN, 0, user) + for(var/thing in persistence_datums) + var/datum/persistent/P = persistence_datums[thing] + if(P.has_admin_data) + dat += P.GetAdminSummary(user, can_modify) + dat += "
" + var/datum/browser/popup = new(user, "admin_persistence", "Persistence Data") + popup.set_content(jointext(dat, null)) + popup.open() \ No newline at end of file diff --git a/code/controllers/subsystems/skybox.dm b/code/controllers/subsystems/skybox.dm index 03f41f0f33d..6befac0b605 100644 --- a/code/controllers/subsystems/skybox.dm +++ b/code/controllers/subsystems/skybox.dm @@ -132,7 +132,7 @@ SUBSYSTEM_DEF(skybox) for(var/z in zlevels) skybox_cache["[z]"] = generate_skybox(z) - for(var/client/C) + for(var/client/C in GLOB.clients) var/their_z = get_z(C.mob) if(!their_z) //Nullspace continue diff --git a/code/controllers/subsystems/tgui.dm b/code/controllers/subsystems/tgui.dm new file mode 100644 index 00000000000..e94830a5f03 --- /dev/null +++ b/code/controllers/subsystems/tgui.dm @@ -0,0 +1,343 @@ + /** + * tgui subsystem + * + * Contains all tgui state and subsystem code. + **/ + + +SUBSYSTEM_DEF(tgui) + name = "TGUI" + wait = 9 + flags = SS_NO_INIT + priority = FIRE_PRIORITY_TGUI + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + + /// A list of UIs scheduled to process + var/list/current_run = list() + /// A list of open UIs + var/list/open_uis = list() + /// A list of open UIs, grouped by src_object and ui_key. + var/list/open_uis_by_src = list() + /// The HTML base used for all UIs. + var/basehtml + +/datum/controller/subsystem/tgui/PreInit() + basehtml = file2text('tgui/packages/tgui/public/tgui.html') + +/datum/controller/subsystem/tgui/Shutdown() + close_all_uis() + +/datum/controller/subsystem/tgui/stat_entry() + ..("P:[open_uis.len]") + +/datum/controller/subsystem/tgui/fire(resumed = 0) + if(!resumed) + src.current_run = open_uis.Copy() + // Cache for sanic speed (lists are references anyways) + var/list/current_run = src.current_run + while(current_run.len) + var/datum/tgui/ui = current_run[current_run.len] + current_run.len-- + // TODO: Move user/src_object check to process() + if(ui && ui.user && ui.src_object) + ui.process() + else + open_uis.Remove(ui) + if(MC_TICK_CHECK) + return + +/** + * public + * + * Requests a usable tgui window from the pool. + * Returns null if pool was exhausted. + * + * required user mob + * return datum/tgui + */ +/datum/controller/subsystem/tgui/proc/request_pooled_window(mob/user) + if(!user.client) + return null + var/list/windows = user.client.tgui_windows + var/window_id + var/datum/tgui_window/window + var/window_found = FALSE + // Find a usable window + for(var/i in 1 to TGUI_WINDOW_HARD_LIMIT) + window_id = TGUI_WINDOW_ID(i) + window = windows[window_id] + // As we are looping, create missing window datums + if(!window) + window = new(user.client, window_id, pooled = TRUE) + // Skip windows with acquired locks + if(window.locked) + continue + if(window.status == TGUI_WINDOW_READY) + return window + if(window.status == TGUI_WINDOW_CLOSED) + window.status = TGUI_WINDOW_LOADING + window_found = TRUE + break + if(!window_found) + return null + return window + +/** + * public + * + * Force closes all tgui windows. + * + * required user mob + */ +/datum/controller/subsystem/tgui/proc/force_close_all_windows(mob/user) + if(user.client) + user.client.tgui_windows = list() + for(var/i in 1 to TGUI_WINDOW_HARD_LIMIT) + var/window_id = TGUI_WINDOW_ID(i) + user << browse(null, "window=[window_id]") + +/** + * public + * + * Force closes the tgui window by window_id. + * + * required user mob + * required window_id string + */ +/datum/controller/subsystem/tgui/proc/force_close_window(mob/user, window_id) + // Close all tgui datums based on window_id. + for(var/datum/tgui/ui in user.tgui_open_uis) + if(ui.window && ui.window.id == window_id) + ui.close(can_be_suspended = FALSE) + // Unset machine just to be sure. + user.unset_machine() + // Close window directly just to be sure. + user << browse(null, "window=[window_id]") + + /** + * public + * + * Get a open UI given a user, src_object, and ui_key and try to update it with data. + * + * required user mob The mob who opened/is using the UI. + * required src_object datum The object/datum which owns the UI. + * required ui_key string The ui_key of the UI. + * + * return datum/tgui The found UI. + **/ +/datum/controller/subsystem/tgui/proc/try_update_ui( + mob/user, + datum/src_object, + datum/tgui/ui) + // Look up a UI if it wasn't passed. + if(isnull(ui)) + ui = get_open_ui(user, src_object) + // Couldn't find a UI. + if(isnull(ui)) + return null + ui.process_status() + // UI ended up with the closed status + // or is actively trying to close itself. + // FIXME: Doesn't actually fix the paper bug. + if(ui.status <= STATUS_CLOSE) + ui.close() + return null + ui.send_update() + return ui + + /** + * private + * + * Get a open UI given a user, src_object, and ui_key. + * + * required user mob The mob who opened/is using the UI. + * required src_object datum The object/datum which owns the UI. + * required ui_key string The ui_key of the UI. + * + * return datum/tgui The found UI. + **/ +/datum/controller/subsystem/tgui/proc/get_open_ui(mob/user, datum/src_object) + var/key = "[REF(src_object)]" + // No UIs opened for this src_object + if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list)) + return null // No UIs open. + for(var/datum/tgui/ui in open_uis_by_src[key]) // Find UIs for this object. + // Make sure we have the right user + if(ui.user == user) + return ui + return null // Couldn't find a UI! + + /** + * private + * + * Update all UIs attached to src_object. + * + * required src_object datum The object/datum which owns the UIs. + * + * return int The number of UIs updated. + **/ +/datum/controller/subsystem/tgui/proc/update_uis(datum/src_object) + var/count = 0 + var/key = "[REF(src_object)]" + if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list)) + return count // Couldn't find any UIs for this object. + for(var/datum/tgui/ui in open_uis_by_src[key]) + // Check the UI is valid. + if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) + ui.process(force = 1) // Update the UI. + count++ // Count each UI we update. + return count + + /** + * private + * + * Close all UIs attached to src_object. + * + * required src_object datum The object/datum which owns the UIs. + * + * return int The number of UIs closed. + **/ +/datum/controller/subsystem/tgui/proc/close_uis(datum/src_object) + var/count = 0 + var/key = "[REF(src_object)]" + // No UIs opened for this src_object + if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list)) + return count + for(var/datum/tgui/ui in open_uis_by_src[key]) + if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid. + ui.close() // Close the UI. + count++ // Count each UI we close. + return count + + /** + * private + * + * Close all UIs regardless of their attachment to src_object. + * + * return int The number of UIs closed. + **/ +/datum/controller/subsystem/tgui/proc/close_all_uis() + var/count = 0 + for(var/key in open_uis_by_src) + for(var/datum/tgui/ui in open_uis_by_src[key]) + if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid. + ui.close() // Close the UI. + count++ // Count each UI we close. + return count + + /** + * private + * + * Update all UIs belonging to a user. + * + * required user mob The mob who opened/is using the UI. + * optional src_object datum If provided, only update UIs belonging this src_object. + * + * return int The number of UIs updated. + **/ +/datum/controller/subsystem/tgui/proc/update_user_uis(mob/user, datum/src_object) + var/count = 0 + if(length(user?.tgui_open_uis) == 0) + return count + for(var/datum/tgui/ui in user.tgui_open_uis) + if(isnull(src_object) || ui.src_object == src_object) + ui.process(force = 1) + count++ + return count + + /** + * private + * + * Close all UIs belonging to a user. + * + * required user mob The mob who opened/is using the UI. + * optional src_object datum If provided, only close UIs belonging this src_object. + * + * return int The number of UIs closed. + **/ +/datum/controller/subsystem/tgui/proc/close_user_uis(mob/user, datum/src_object, logout = FALSE) + var/count = 0 + if(length(user?.tgui_open_uis) == 0) + return count + for(var/datum/tgui/ui in user.tgui_open_uis) + if(isnull(src_object) || ui.src_object == src_object) + ui.close(logout = logout) + count++ + return count + + /** + * private + * + * Add a UI to the list of open UIs. + * + * required ui datum/tgui The UI to be added. + **/ +/datum/controller/subsystem/tgui/proc/on_open(datum/tgui/ui) + var/key = "[REF(ui.src_object)]" + if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list)) + open_uis_by_src[key] = list() + ui.user.tgui_open_uis |= ui + var/list/uis = open_uis_by_src[key] + uis |= ui + open_uis |= ui + + /** + * private + * + * Remove a UI from the list of open UIs. + * + * required ui datum/tgui The UI to be removed. + * + * return bool If the UI was removed or not. + **/ +/datum/controller/subsystem/tgui/proc/on_close(datum/tgui/ui) + var/key = "[REF(ui.src_object)]" + if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list)) + return FALSE + // Remove it from the list of processing UIs. + open_uis.Remove(ui) + // If the user exists, remove it from them too. + if(ui.user) + ui.user.tgui_open_uis.Remove(ui) + var/list/uis = open_uis_by_src[key] + uis.Remove(ui) + if(length(uis) == 0) + open_uis_by_src.Remove(key) + return TRUE + + /** + * private + * + * Handle client logout, by closing all their UIs. + * + * required user mob The mob which logged out. + * + * return int The number of UIs closed. + **/ +/datum/controller/subsystem/tgui/proc/on_logout(mob/user) + return close_user_uis(user, logout = TRUE) + + /** + * private + * + * Handle clients switching mobs, by transferring their UIs. + * + * required user source The client's original mob. + * required user target The client's new mob. + * + * return bool If the UIs were transferred. + **/ +/datum/controller/subsystem/tgui/proc/on_transfer(mob/source, mob/target) + // The old mob had no open UIs. + if(length(source?.tgui_open_uis) == 0) + return FALSE + if(isnull(target.tgui_open_uis) || !istype(target.tgui_open_uis, /list)) + target.tgui_open_uis = list() + // Transfer all the UIs. + for(var/datum/tgui/ui in source.tgui_open_uis) + // Inform the UIs of their new owner. + ui.user = target + target.tgui_open_uis.Add(ui) + // Clear the old list. + source.tgui_open_uis.Cut() + return TRUE \ No newline at end of file diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm index 2d77a744e37..cc498385a39 100644 --- a/code/controllers/subsystems/ticker.dm +++ b/code/controllers/subsystems/ticker.dm @@ -261,6 +261,8 @@ var/global/datum/controller/subsystem/ticker/ticker to_world("An admin has delayed the round end.") end_game_state = END_GAME_DELAYED else if(restart_timeleft <= 0) + to_world("Restarting world!") + sleep(5) world.Reboot() else if (world.time - last_restart_notify >= 1 MINUTE) to_world("Restarting in [round(restart_timeleft/600, 1)] minute\s.") diff --git a/code/datums/autolathe/arms.dm b/code/datums/autolathe/arms.dm index e170d8c885b..53a2f14fac1 100644 --- a/code/datums/autolathe/arms.dm +++ b/code/datums/autolathe/arms.dm @@ -33,6 +33,12 @@ path =/obj/item/ammo_casing/a12g/stunshell hidden = 1 +/datum/category_item/autolathe/arms/flechetteshell + name = "ammunition (flechette cartridge, shotgun)" + path =/obj/item/ammo_casing/a12g/flechette + hidden = 1 + man_rating = 2 + ////////////////// /*Ammo magazines*/ ////////////////// @@ -64,6 +70,18 @@ name = "pistol magazine (.45 flash)" path =/obj/item/ammo_magazine/m45/flash +/datum/category_item/autolathe/arms/pistol_45ap + name = "pistol magazine (.45 armor piercing)" + path =/obj/item/ammo_magazine/m45/ap + hidden = 1 + resources = list(DEFAULT_WALL_MATERIAL = 500, MAT_PLASTEEL = 300) + +/datum/category_item/autolathe/arms/pistol_45hp + name = "pistol magazine (.45 hollowpoint)" + path =/obj/item/ammo_magazine/m45/hp + hidden = 1 + resources = list(DEFAULT_WALL_MATERIAL = 500, MAT_PLASTIC = 200) + /datum/category_item/autolathe/arms/pistol_45uzi name = "uzi magazine (.45)" path =/obj/item/ammo_magazine/m45uzi @@ -138,6 +156,12 @@ name = "top-mounted SMG magazine (9mm flash)" path =/obj/item/ammo_magazine/m9mmt/flash +/datum/category_item/autolathe/arms/smg_9mmap + name = "top-mounted SMG magazine (9mm armor piercing)" + path =/obj/item/ammo_magazine/m9mmt/ap + hidden = 1 + man_rating = 2 + /////// 10mm /datum/category_item/autolathe/arms/smg_10mm name = "SMG magazine (10mm)" diff --git a/code/datums/autolathe/autolathe.dm b/code/datums/autolathe/autolathe.dm index 91c9ec37b7a..003212fe75b 100644 --- a/code/datums/autolathe/autolathe.dm +++ b/code/datums/autolathe/autolathe.dm @@ -71,6 +71,7 @@ var/datum/category_collection/autolathe/autolathe_recipes var/is_stack // Creates multiple of an item if applied to non-stack items var/max_stack var/no_scale + var/man_rating = 0 /datum/category_item/autolathe/dd_SortValue() return name \ No newline at end of file diff --git a/code/datums/autolathe/general.dm b/code/datums/autolathe/general.dm index 6ec648d388c..a2dcd047c9c 100644 --- a/code/datums/autolathe/general.dm +++ b/code/datums/autolathe/general.dm @@ -54,6 +54,10 @@ name = "jar" path =/obj/item/glass_jar +/datum/category_item/autolathe/general/fishtank + name = "fish tank" + path =/obj/item/glass_jar + /datum/category_item/autolathe/general/radio_headset name = "radio headset" path =/obj/item/device/radio/headset @@ -94,6 +98,20 @@ is_stack = TRUE no_scale = TRUE //prevents material duplication exploits +/datum/category_item/autolathe/general/plasteel + name = "plasteel sheets" + path =/obj/item/stack/material/plasteel + is_stack = TRUE + no_scale = TRUE //prevents material duplication exploits + resources = list(MAT_PLASTEEL = 2000) + +/datum/category_item/autolathe/general/plastic + name = "plastic sheets" + path =/obj/item/stack/material/plastic + is_stack = TRUE + no_scale = TRUE //prevents material duplication exploits + resources = list(MAT_PLASTIC = 2000) + //TFF 24/12/19 - Let people print more spray bottles if needed. /datum/category_item/autolathe/general/spraybottle name = "spray bottle" @@ -129,6 +147,12 @@ name = "maglight" path =/obj/item/device/flashlight/maglight +/datum/category_item/autolathe/general/idcard + name = "ID Card" + path = /obj/item/weapon/card/id + resources = list(DEFAULT_WALL_MATERIAL = 100, MAT_GLASS = 100, MAT_PLASTIC = 300) + man_rating = 2 + /datum/category_item/autolathe/general/handcuffs name = "handcuffs" path =/obj/item/weapon/handcuffs diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index be5f6b33db3..bb9372749af 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -332,6 +332,19 @@ var/global/list/PDA_Manifest = list() var/datum/job/J = SSjob.get_job(assignment) hidden = J?.offmap_spawn + /* Note: Due to cached_character_icon, a number of emergent properties occur due to the initialization + * order of readied-up vs latejoiners. Namely, latejoiners will get a uniform in their datacore picture, but readied-up will + * not. This is due to the fact that SSticker calls data_core.manifest_inject() inside of ticker/proc/create_characters(), + * but does not equip them until ticker/proc/equip_characters(), which is called later. So, this proc is literally called before + * they ever get their equipment, and so it can't get a picture of them in their equipment. + * Latejoiners do not have this problem, because /mob/new_player/proc/AttemptLateSpawn calls EquipRank() before it calls + * this proc, which means that they're already clothed by the time they get their picture taken here. + * The COMPILE_OVERLAYS() here is just to bypass SSoverlays taking for-fucking-ever to update the mob, since we're about to + * take a picture of them, we want all the overlays. + */ + COMPILE_OVERLAYS(H) + SSoverlays.queue -= H + var/id = generate_record_id() //General Record var/datum/data/record/G = CreateGeneralRecord(H, id, hidden) @@ -418,8 +431,8 @@ var/global/list/PDA_Manifest = list() var/icon/side if(H) var/icon/charicon = cached_character_icon(H) - front = icon(charicon, dir = SOUTH) - side = icon(charicon, dir = WEST) + front = icon(charicon, dir = SOUTH, frame = 1) + side = icon(charicon, dir = WEST, frame = 1) else // Sending null things through browse_rsc() makes a runtime and breaks the console trying to view the record. front = icon('html/images/no_image32.png') side = icon('html/images/no_image32.png') @@ -445,6 +458,8 @@ var/global/list/PDA_Manifest = list() G.fields["religion"] = "Unknown" G.fields["photo_front"] = front G.fields["photo_side"] = side + G.fields["photo-south"] = "'data:image/png;base64,[icon2base64(front)]'" + G.fields["photo-west"] = "'data:image/png;base64,[icon2base64(side)]'" G.fields["notes"] = "No notes found." if(hidden) hidden_general += G diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 65576a52a72..abc7ade225f 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -202,7 +202,9 @@ var/obj/belly/destination_belly = destination.loc var/mob/living/telenommer = destination_belly.owner if(istype(telenommer)) - if(!isliving(teleatom)) + if(istype(teleatom, /obj/machinery) || istype(teleatom, /obj/structure)) + return 0 + else if(!isliving(teleatom)) return 1 else var/mob/living/telemob = teleatom diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index 3a9a0610a57..e8b0c2aa789 100644 --- a/code/datums/looping_sounds/machinery_sounds.dm +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -4,7 +4,7 @@ mid_sounds = list('sound/machines/shower/shower_mid1.ogg'=1,'sound/machines/shower/shower_mid2.ogg'=1,'sound/machines/shower/shower_mid3.ogg'=1) mid_length = 10 end_sound = 'sound/machines/shower/shower_end.ogg' - volume = 20 + volume = 15 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm index 846b519f772..a2d3e9b728c 100644 --- a/code/datums/outfits/outfit.dm +++ b/code/datums/outfits/outfit.dm @@ -101,6 +101,7 @@ var/list/outfits_decls_by_type_ H.equip_to_slot_or_del(new path(H), slot_in_backpack) post_equip(H) + if(W) // We set ID info last to ensure the ID photo is as correct as possible. H.set_id_info(W) return 1 diff --git a/code/datums/outfits/spec_op.dm b/code/datums/outfits/spec_op.dm index 8c6a3f3c1b3..bb43b4cb9bd 100644 --- a/code/datums/outfits/spec_op.dm +++ b/code/datums/outfits/spec_op.dm @@ -6,7 +6,7 @@ glasses = /obj/item/clothing/glasses/thermal/plain/eyepatch mask = /obj/item/clothing/mask/smokable/cigarette/cigar/havana head = /obj/item/clothing/head/beret //deathsquad - belt = /obj/item/weapon/gun/energy/pulse_rifle/M1911 + belt = /obj/item/weapon/gun/energy/pulse_rifle/compact/admin back = /obj/item/weapon/storage/backpack/satchel shoes = /obj/item/clothing/shoes/boots/combat gloves = /obj/item/clothing/gloves/combat diff --git a/code/datums/recipe.dm b/code/datums/recipe.dm deleted file mode 100644 index a70199887cd..00000000000 --- a/code/datums/recipe.dm +++ /dev/null @@ -1,166 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * - * /datum/recipe by rastaf0 13 apr 2011 * - * * * * * * * * * * * * * * * * * * * * * * * * * * - * This is powerful and flexible recipe system. - * It exists not only for food. - * supports both reagents and objects as prerequisites. - * In order to use this system you have to define a deriative from /datum/recipe - * * reagents are reagents. Acid, milc, booze, etc. - * * items are objects. Fruits, tools, circuit boards. - * * result is type to create as new object - * * time is optional parameter, you shall use in in your machine, - default /datum/recipe/ procs does not rely on this parameter. - * - * Functions you need: - * /datum/recipe/proc/make(var/obj/container as obj) - * Creates result inside container, - * deletes prerequisite reagents, - * transfers reagents from prerequisite objects, - * deletes all prerequisite objects (even not needed for recipe at the moment). - * - * /proc/select_recipe(list/datum/recipe/avaiable_recipes, obj/obj as obj, exact = 1) - * Wonderful function that select suitable recipe for you. - * obj is a machine (or magik hat) with prerequisites, - * exact = 0 forces algorithm to ignore superfluous stuff. - * - * - * Functions you do not need to call directly but could: - * /datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents) - * /datum/recipe/proc/check_items(var/obj/container as obj) - * - * */ - -/datum/recipe - var/list/reagents // example: = list("berryjuice" = 5) // do not list same reagent twice - var/list/items // example: = list(/obj/item/weapon/tool/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo - var/list/fruit // example: = list("fruit" = 3) - var/result // example: = /obj/item/weapon/reagent_containers/food/snacks/donut/normal - var/time = 100 // 1/10 part of second - -/datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents) - . = 1 - for (var/r_r in reagents) - var/aval_r_amnt = avail_reagents.get_reagent_amount(r_r) - if (!(abs(aval_r_amnt - reagents[r_r])<0.5)) //if NOT equals - if (aval_r_amnt>reagents[r_r]) - . = 0 - else - return -1 - if ((reagents?(reagents.len):(0)) < avail_reagents.reagent_list.len) - return 0 - return . - -/datum/recipe/proc/check_fruit(var/obj/container) - . = 1 - if(fruit && fruit.len) - var/list/checklist = list() - // You should trust Copy(). - checklist = fruit.Copy() - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in container) - if(!G.seed || !G.seed.kitchen_tag || isnull(checklist[G.seed.kitchen_tag])) - continue - checklist[G.seed.kitchen_tag]-- - for(var/ktag in checklist) - if(!isnull(checklist[ktag])) - if(checklist[ktag] < 0) - . = 0 - else if(checklist[ktag] > 0) - . = -1 - break - return . - -/datum/recipe/proc/check_items(var/obj/container as obj) - . = 1 - if (items && items.len) - var/list/checklist = list() - checklist = items.Copy() // You should really trust Copy - if(istype(container, /obj/machinery)) - var/obj/machinery/machine = container - for(var/obj/O in ((machine.contents - machine.component_parts) - machine.circuit)) - if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown)) - continue // Fruit is handled in check_fruit(). - var/found = 0 - for(var/i = 1; i < checklist.len+1; i++) - var/item_type = checklist[i] - if (istype(O,item_type)) - checklist.Cut(i, i+1) - found = 1 - break - if (!found) - . = 0 - else - for(var/obj/O in container.contents) - if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown)) - continue // Fruit is handled in check_fruit(). - var/found = 0 - for(var/i = 1; i < checklist.len+1; i++) - var/item_type = checklist[i] - if (istype(O,item_type)) - checklist.Cut(i, i+1) - found = 1 - break - if (!found) - . = 0 - if (checklist.len) - . = -1 - return . - -//general version -/datum/recipe/proc/make(var/obj/container as obj) - var/obj/result_obj = new result(container) - if(istype(container, /obj/machinery)) - var/obj/machinery/machine = container - for (var/obj/O in ((machine.contents-result_obj - machine.component_parts) - machine.circuit)) - O.reagents.trans_to_obj(result_obj, O.reagents.total_volume) - qdel(O) - else - for (var/obj/O in (container.contents-result_obj)) - O.reagents.trans_to_obj(result_obj, O.reagents.total_volume) - qdel(O) - container.reagents.clear_reagents() - return result_obj - -// food-related -/datum/recipe/proc/make_food(var/obj/container as obj) - if(!result) - to_world("Recipe [type] is defined without a result, please bug report this.") - return - var/obj/result_obj = new result(container) - if(istype(container, /obj/machinery)) - var/obj/machinery/machine = container - for (var/obj/O in ((machine.contents-result_obj - machine.component_parts) - machine.circuit)) - if (O.reagents) - O.reagents.del_reagent("nutriment") - O.reagents.update_total() - O.reagents.trans_to_obj(result_obj, O.reagents.total_volume) - qdel(O) - else - for (var/obj/O in (container.contents-result_obj)) - if (O.reagents) - O.reagents.del_reagent("nutriment") - O.reagents.update_total() - O.reagents.trans_to_obj(result_obj, O.reagents.total_volume) - qdel(O) - container.reagents.clear_reagents() - return result_obj - -/proc/select_recipe(var/list/datum/recipe/avaiable_recipes, var/obj/obj as obj, var/exact) - var/list/datum/recipe/possible_recipes = new - var/target = exact ? 0 : 1 - for (var/datum/recipe/recipe in avaiable_recipes) - if((recipe.check_reagents(obj.reagents) < target) || (recipe.check_items(obj) < target) || (recipe.check_fruit(obj) < target)) - continue - possible_recipes |= recipe - if (possible_recipes.len==0) - return null - else if (possible_recipes.len==1) - return possible_recipes[1] - else //okay, let's select the most complicated recipe - var/highest_count = 0 - . = possible_recipes[1] - for (var/datum/recipe/recipe in possible_recipes) - var/count = ((recipe.items)?(recipe.items.len):0) + ((recipe.reagents)?(recipe.reagents.len):0) + ((recipe.fruit)?(recipe.fruit.len):0) - if (count >= highest_count) - highest_count = count - . = recipe - return . diff --git a/code/datums/repositories/cameras.dm b/code/datums/repositories/cameras.dm index d5161133948..e69de29bb2d 100644 --- a/code/datums/repositories/cameras.dm +++ b/code/datums/repositories/cameras.dm @@ -1,49 +0,0 @@ -var/global/datum/repository/cameras/camera_repository = new() - -/proc/invalidateCameraCache() - camera_repository.networks.Cut() - camera_repository.invalidated = 1 - camera_repository.camera_cache_id = (++camera_repository.camera_cache_id % 999999) - -/datum/repository/cameras - var/list/networks - var/invalidated = 1 - var/camera_cache_id = 1 - -/datum/repository/cameras/New() - networks = list() - ..() - -/datum/repository/cameras/proc/cameras_in_network(var/network, var/list/zlevels) - setup_cache() - var/list/network_list = networks[network] - if(LAZYLEN(zlevels)) - var/list/filtered_cameras = list() - for(var/list/C in network_list) - //Camera is marked as always-visible - if(C["omni"]) - filtered_cameras[++filtered_cameras.len] = C - continue - //Camera might be in an adjacent zlevel - var/camz = C["z"] - if(!camz) //It's inside something (helmet, communicator, etc) or nullspace or who knows - camz = get_z(locate(C["camera"]) in cameranet.cameras) - if(camz in zlevels) - filtered_cameras[++filtered_cameras.len] = C //Can't add lists to lists with += - return filtered_cameras - else - return network_list - -/datum/repository/cameras/proc/setup_cache() - if(!invalidated) - return - invalidated = 0 - - cameranet.process_sort() - for(var/obj/machinery/camera/C in cameranet.cameras) - var/cam = C.nano_structure() - for(var/network in C.network) - if(!networks[network]) - networks[network] = list() - var/list/netlist = networks[network] - netlist[++netlist.len] = cam diff --git a/code/datums/repositories/crew.dm b/code/datums/repositories/crew.dm index f67a17ca75b..7a748049bc2 100644 --- a/code/datums/repositories/crew.dm +++ b/code/datums/repositories/crew.dm @@ -51,6 +51,7 @@ var/global/datum/repository/crew/crew_repository = new() crewmemberData["area"] = sanitize(A.get_name()) crewmemberData["x"] = pos.x crewmemberData["y"] = pos.y + crewmemberData["realZ"] = pos.z crewmemberData["z"] = using_map.get_zlevel_name(pos.z) crewmembers[++crewmembers.len] = crewmemberData diff --git a/code/datums/supplypacks/atmospherics.dm b/code/datums/supplypacks/atmospherics.dm index cf102f129db..fb5d4a0e597 100644 --- a/code/datums/supplypacks/atmospherics.dm +++ b/code/datums/supplypacks/atmospherics.dm @@ -11,42 +11,42 @@ name = "Inflatable barriers" contains = list(/obj/item/weapon/storage/briefcase/inflatable = 3) cost = 20 - containertype = /obj/structure/closet/crate/engineering + containertype = /obj/structure/closet/crate/aether containername = "Inflatable Barrier Crate" /datum/supply_pack/atmos/canister_empty name = "Empty gas canister" cost = 7 containername = "Empty gas canister crate" - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/aether contains = list(/obj/machinery/portable_atmospherics/canister) /datum/supply_pack/atmos/canister_air name = "Air canister" cost = 10 containername = "Air canister crate" - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/aether contains = list(/obj/machinery/portable_atmospherics/canister/air) /datum/supply_pack/atmos/canister_oxygen name = "Oxygen canister" cost = 15 containername = "Oxygen canister crate" - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/aether contains = list(/obj/machinery/portable_atmospherics/canister/oxygen) /datum/supply_pack/atmos/canister_nitrogen name = "Nitrogen canister" cost = 10 containername = "Nitrogen canister crate" - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/aether contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen) /datum/supply_pack/atmos/canister_phoron name = "Phoron gas canister" cost = 60 containername = "Phoron gas canister crate" - containertype = /obj/structure/closet/crate/secure/large + containertype = /obj/structure/closet/crate/secure/large/aether access = access_atmospherics contains = list(/obj/machinery/portable_atmospherics/canister/phoron) @@ -54,7 +54,7 @@ name = "N2O gas canister" cost = 15 containername = "N2O gas canister crate" - containertype = /obj/structure/closet/crate/secure/large + containertype = /obj/structure/closet/crate/secure/large/aether access = access_atmospherics contains = list(/obj/machinery/portable_atmospherics/canister/sleeping_agent) @@ -62,7 +62,7 @@ name = "Carbon dioxide gas canister" cost = 15 containername = "CO2 canister crate" - containertype = /obj/structure/closet/crate/secure/large + containertype = /obj/structure/closet/crate/secure/large/aether access = access_atmospherics contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide) @@ -70,7 +70,7 @@ contains = list(/obj/machinery/pipedispenser/orderable) name = "Pipe Dispenser" cost = 25 - containertype = /obj/structure/closet/crate/secure/large + containertype = /obj/structure/closet/crate/secure/large/aether containername = "Pipe Dispenser Crate" access = access_atmospherics @@ -78,7 +78,7 @@ contains = list(/obj/machinery/pipedispenser/disposal/orderable) name = "Disposals Pipe Dispenser" cost = 25 - containertype = /obj/structure/closet/crate/secure/large + containertype = /obj/structure/closet/crate/secure/large/aether containername = "Disposal Dispenser Crate" access = access_atmospherics @@ -89,7 +89,7 @@ /obj/item/weapon/tank/air = 3 ) cost = 10 - containertype = /obj/structure/closet/crate/internals + containertype = /obj/structure/closet/crate/aether containername = "Internals crate" /datum/supply_pack/atmos/evacuation @@ -104,5 +104,5 @@ /obj/item/clothing/mask/gas = 4 ) cost = 35 - containertype = /obj/structure/closet/crate/internals + containertype = /obj/structure/closet/crate/aether containername = "Emergency crate" diff --git a/code/datums/supplypacks/contraband.dm b/code/datums/supplypacks/contraband.dm index 7b266b2a76f..7d8616a8ad0 100644 --- a/code/datums/supplypacks/contraband.dm +++ b/code/datums/supplypacks/contraband.dm @@ -28,7 +28,7 @@ /obj/item/weapon/grenade/chem_grenade/incendiary ) cost = 25 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/weapon containername = "Special Ops crate" contraband = 1 @@ -39,7 +39,7 @@ /obj/item/weapon/reagent_containers/food/snacks/unajerky = 4 ) cost = 25 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/unathi containername = "Moghes imports crate" contraband = 1 @@ -51,7 +51,7 @@ ) cost = 50 contraband = 1 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/hedberg containername = "Ballistic weapons crate" /datum/supply_pack/randomised/misc/telecrate //you get something awesome, a couple of decent things, and a few weak/filler things @@ -103,5 +103,5 @@ ) cost = 250 //more than a hat crate!, contraband = 1 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large containername = "Suspicious crate" diff --git a/code/datums/supplypacks/costumes.dm b/code/datums/supplypacks/costumes.dm index 879d5accd0c..f9b61d95723 100644 --- a/code/datums/supplypacks/costumes.dm +++ b/code/datums/supplypacks/costumes.dm @@ -1,6 +1,6 @@ /* * Here is where any supply packs -* related to weapons live. +* related to costumes live. */ @@ -19,7 +19,7 @@ /obj/item/clothing/head/wizard/fake ) cost = 20 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/nanothreads containername = "Wizard costume crate" /datum/supply_pack/randomised/costumes/hats @@ -48,8 +48,8 @@ ) name = "Collectable hat crate!" cost = 200 - containertype = /obj/structure/closet/crate - containername = "Collectable hats crate! Brought to you by Bass.inc!" + containertype = /obj/structure/closet/crate/nanothreads + containername = "Collectable hats crate" /datum/supply_pack/randomised/costumes/costume num_contained = 3 @@ -84,7 +84,7 @@ ) name = "Costumes crate" cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/nanothreads containername = "Actor Costumes" /datum/supply_pack/costumes/formal_wear @@ -104,15 +104,15 @@ /obj/item/clothing/shoes/leather, /obj/item/clothing/accessory/wcoat ) - name = "Formalwear closet" + name = "Formalwear (Suits)" cost = 30 - containertype = /obj/structure/closet - containername = "Formalwear for the best occasions." + containertype = /obj/structure/closet/crate/gilthari + containername = "Formal suit crate" datum/supply_pack/costumes/witch name = "Witch costume" containername = "Witch costume" - containertype = /obj/structure/closet + containertype = /obj/structure/closet/crate/nanothreads cost = 20 contains = list( /obj/item/clothing/suit/wizrobe/marisa/fake, @@ -124,7 +124,7 @@ datum/supply_pack/costumes/witch /datum/supply_pack/randomised/costumes/costume_hats name = "Costume hats" containername = "Actor hats crate" - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/nanothreads cost = 10 num_contained = 3 contains = list( @@ -147,9 +147,9 @@ datum/supply_pack/costumes/witch ) /datum/supply_pack/randomised/costumes/dresses - name = "Womens formal dress locker" - containername = "Pretty dress locker" - containertype = /obj/structure/closet + name = "Formalwear (Dresses)" + containername = "Formal dress crate" + containertype = /obj/structure/closet/crate/gilthari cost = 15 num_contained = 3 contains = list( diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm index 5ffa26d7117..5d2bc99089a 100644 --- a/code/datums/supplypacks/engineering.dm +++ b/code/datums/supplypacks/engineering.dm @@ -11,30 +11,72 @@ name = "Replacement lights" contains = list(/obj/item/weapon/storage/box/lights/mixed = 3) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/galaksi containername = "Replacement lights" /datum/supply_pack/eng/smescoil name = "Superconducting Magnetic Coil" contains = list(/obj/item/weapon/smes_coil) cost = 75 - containertype = /obj/structure/closet/crate/engineering + containertype = /obj/structure/closet/crate/focalpoint containername = "Superconducting Magnetic Coil crate" /datum/supply_pack/eng/smescoil/super_capacity name = "Superconducting Capacitance Coil" contains = list(/obj/item/weapon/smes_coil/super_capacity) cost = 90 - containertype = /obj/structure/closet/crate/engineering + containertype = /obj/structure/closet/crate/focalpoint containername = "Superconducting Capacitance Coil crate" /datum/supply_pack/eng/smescoil/super_io name = "Superconducting Transmission Coil" contains = list(/obj/item/weapon/smes_coil/super_io) cost = 90 - containertype = /obj/structure/closet/crate/engineering + containertype = /obj/structure/closet/crate/focalpoint containername = "Superconducting Transmission Coil crate" +/datum/supply_pack/eng/shield_capacitor + name = "Shield Capacitor" + contains = list(/obj/machinery/shield_capacitor) + cost = 20 + containertype = /obj/structure/closet/crate/focalpoint + containername = "shield capacitor crate" + +/datum/supply_pack/eng/shield_capacitor/advanced + name = "Advanced Shield Capacitor" + contains = list(/obj/machinery/shield_capacitor/advanced) + cost = 30 + containertype = /obj/structure/closet/crate/focalpoint + containername = "advanced shield capacitor crate" + +/datum/supply_pack/eng/bubble_shield + name = "Bubble Shield Generator" + contains = list(/obj/machinery/shield_gen) + cost = 40 + containertype =/obj/structure/closet/crate/focalpoint + containername = "shield bubble generator crate" + +/datum/supply_pack/eng/bubble_shield/advanced + name = "Advanced Bubble Shield Generator" + contains = list(/obj/machinery/shield_gen/advanced) + cost = 60 + containertype = /obj/structure/closet/crate/focalpoint + containername = "advanced bubble shield generator crate" + +/datum/supply_pack/eng/hull_shield + name = "Hull Shield Generator" + contains = list(/obj/machinery/shield_gen/external) + cost = 80 + containertype = /obj/structure/closet/crate/focalpoint + containername = "shield hull generator crate" + +/datum/supply_pack/eng/hull_shield/advanced + name = "Advanced Hull Shield Generator" + contains = list(/obj/machinery/shield_gen/external/advanced) + cost = 120 + containertype = /obj/structure/closet/crate/focalpoint + containername = "advanced hull shield generator crate" + /datum/supply_pack/eng/electrical name = "Electrical maintenance crate" contains = list( @@ -44,7 +86,7 @@ /obj/item/weapon/cell/high = 2 ) cost = 10 - containertype = /obj/structure/closet/crate/engineering/electrical + containertype = /obj/structure/closet/crate/ward containername = "Electrical maintenance crate" /datum/supply_pack/eng/e_welders @@ -53,7 +95,7 @@ /obj/item/weapon/weldingtool/electric = 3 ) cost = 15 - containertype = /obj/structure/closet/crate/engineering/electrical + containertype = /obj/structure/closet/crate/ward containername = "Electric welder crate" /datum/supply_pack/eng/mechanical @@ -65,14 +107,14 @@ /obj/item/clothing/head/hardhat ) cost = 10 - containertype = /obj/structure/closet/crate/engineering + containertype = /obj/structure/closet/crate/xion containername = "Mechanical maintenance crate" /datum/supply_pack/eng/fueltank name = "Fuel tank crate" contains = list(/obj/structure/reagent_dispensers/fueltank) cost = 10 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/nanotrasen containername = "fuel tank crate" /datum/supply_pack/eng/solar @@ -84,35 +126,35 @@ /obj/item/weapon/paper/solar ) cost = 20 - containertype = /obj/structure/closet/crate/engineering + containertype = /obj/structure/closet/crate/einstein containername = "Solar pack crate" /datum/supply_pack/eng/engine name = "Emitter crate" contains = list(/obj/machinery/power/emitter = 2) cost = 10 - containertype = /obj/structure/closet/crate/secure/engineering + containertype = /obj/structure/closet/crate/secure/einstein containername = "Emitter crate" access = access_ce /datum/supply_pack/eng/engine/field_gen name = "Field Generator crate" contains = list(/obj/machinery/field_generator = 2) - containertype = /obj/structure/closet/crate/secure/engineering + containertype = /obj/structure/closet/crate/secure/xion containername = "Field Generator crate" access = access_ce /datum/supply_pack/eng/engine/sing_gen name = "Singularity Generator crate" contains = list(/obj/machinery/the_singularitygen) - containertype = /obj/structure/closet/crate/secure/engineering + containertype = /obj/structure/closet/crate/secure/einstein containername = "Singularity Generator crate" access = access_ce /datum/supply_pack/eng/engine/collector name = "Collector crate" contains = list(/obj/machinery/power/rad_collector = 3) - containertype = /obj/structure/closet/crate/secure/engineering + containertype = /obj/structure/closet/crate/secure/einstein containername = "Collector crate" /datum/supply_pack/eng/engine/PA @@ -127,23 +169,33 @@ /obj/structure/particle_accelerator/power_box, /obj/structure/particle_accelerator/end_cap ) - containertype = /obj/structure/closet/crate/secure/engineering + containertype = /obj/structure/closet/crate/secure/einstein containername = "Particle Accelerator crate" access = access_ce -/datum/supply_pack/eng/shield_generator - name = "Shield Generator Construction Kit" - contains = list( - /obj/item/weapon/circuitboard/shield_generator, - /obj/item/weapon/stock_parts/capacitor, - /obj/item/weapon/stock_parts/micro_laser, - /obj/item/weapon/smes_coil, - /obj/item/weapon/stock_parts/console_screen, - /obj/item/weapon/stock_parts/subspace/amplifier - ) - cost = 80 - containertype = /obj/structure/closet/crate/engineering - containername = "shield generator construction kit crate" +/datum/supply_pack/eng/shield_gen + contains = list(/obj/item/weapon/circuitboard/shield_gen) + name = "Bubble shield generator circuitry" + cost = 30 + containertype = /obj/structure/closet/crate/secure/focalpoint + containername = "bubble shield generator circuitry crate" + access = access_ce + +/datum/supply_pack/eng/shield_gen_ex + contains = list(/obj/item/weapon/circuitboard/shield_gen_ex) + name = "Hull shield generator circuitry" + cost = 30 + containertype = /obj/structure/closet/crate/secure/focalpoint + containername = "hull shield generator circuitry crate" + access = access_ce + +/datum/supply_pack/eng/shield_cap + contains = list(/obj/item/weapon/circuitboard/shield_cap) + name = "Bubble shield capacitor circuitry" + cost = 30 + containertype = /obj/structure/closet/crate/secure/focalpoint + containername = "shield capacitor circuitry crate" + access = access_ce /datum/supply_pack/eng/smbig name = "Supermatter Core" @@ -157,7 +209,7 @@ contains = list(/obj/machinery/power/generator) name = "Mark I Thermoelectric Generator" cost = 40 - containertype = /obj/structure/closet/crate/secure/large + containertype = /obj/structure/closet/crate/secure/large/einstein containername = "Mk1 TEG crate" access = access_engine @@ -165,7 +217,7 @@ contains = list(/obj/machinery/atmospherics/binary/circulator) name = "Binary atmospheric circulator" cost = 20 - containertype = /obj/structure/closet/crate/secure/large + containertype = /obj/structure/closet/crate/secure/large/einstein containername = "Atmospheric circulator crate" access = access_engine @@ -183,7 +235,7 @@ name = "P.A.C.M.A.N. portable generator parts" cost = 25 containername = "P.A.C.M.A.N. Portable Generator Construction Kit" - containertype = /obj/structure/closet/crate/secure/engineering + containertype = /obj/structure/closet/crate/secure/focalpoint access = access_tech_storage contains = list( /obj/item/weapon/stock_parts/micro_laser, @@ -196,7 +248,7 @@ name = "Super P.A.C.M.A.N. portable generator parts" cost = 35 containername = "Super P.A.C.M.A.N. portable generator construction kit" - containertype = /obj/structure/closet/crate/secure/engineering + containertype = /obj/structure/closet/crate/secure/focalpoint access = access_tech_storage contains = list( /obj/item/weapon/stock_parts/micro_laser, @@ -209,7 +261,7 @@ name = "R-UST Mk. 8 Tokamak fusion core crate" cost = 50 containername = "R-UST Mk. 8 Tokamak Fusion Core crate" - containertype = /obj/structure/closet/crate/secure/engineering + containertype = /obj/structure/closet/crate/secure/einstein access = access_engine contains = list( /obj/item/weapon/book/manual/rust_engine, @@ -221,7 +273,7 @@ name = "R-UST Mk. 8 fuel injector crate" cost = 30 containername = "R-UST Mk. 8 fuel injector crate" - containertype = /obj/structure/closet/crate/secure/engineering + containertype = /obj/structure/closet/crate/secure/einstein access = access_engine contains = list( /obj/machinery/fusion_fuel_injector, @@ -233,7 +285,7 @@ name = "Gyrotron crate" cost = 15 containername = "Gyrotron Crate" - containertype = /obj/structure/closet/crate/secure/engineering + containertype = /obj/structure/closet/crate/secure/einstein access = access_engine contains = list( /obj/machinery/power/emitter/gyrotron, @@ -244,12 +296,12 @@ name = "Fusion Fuel Compressor circuitry crate" cost = 10 containername = "Fusion Fuel Compressor circuitry crate" - containertype = /obj/structure/closet/crate/engineering + containertype = /obj/structure/closet/crate/einstein contains = list(/obj/item/weapon/circuitboard/fusion_fuel_compressor) /datum/supply_pack/eng/tritium name = "Tritium crate" cost = 75 containername = "Tritium crate" - containertype = /obj/structure/closet/crate/engineering + containertype = /obj/structure/closet/crate/einstein contains = list(/obj/fiftyspawner/tritium) diff --git a/code/datums/supplypacks/engineering_vr.dm b/code/datums/supplypacks/engineering_vr.dm index 273d3f65585..61c0f0e1803 100644 --- a/code/datums/supplypacks/engineering_vr.dm +++ b/code/datums/supplypacks/engineering_vr.dm @@ -1,3 +1,17 @@ +/datum/supply_pack/eng/modern_shield + name = "Modern Shield Construction Kit" + contains = list( + /obj/item/weapon/circuitboard/shield_generator, + /obj/item/weapon/stock_parts/capacitor, + /obj/item/weapon/stock_parts/micro_laser, + /obj/item/weapon/smes_coil, + /obj/item/weapon/stock_parts/console_screen, + /obj/item/weapon/stock_parts/subspace/amplifier + ) + cost = 80 + containertype = /obj/structure/closet/crate/focalpoint + containername = "shield generator construction kit crate" + /datum/supply_pack/eng/thermoregulator contains = list(/obj/machinery/power/thermoregulator) name = "Thermal Regulator" diff --git a/code/datums/supplypacks/hospitality.dm b/code/datums/supplypacks/hospitality.dm index 6547b25e702..2c9bbbce518 100644 --- a/code/datums/supplypacks/hospitality.dm +++ b/code/datums/supplypacks/hospitality.dm @@ -23,7 +23,7 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer = 4, ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/gilthari containername = "Party equipment" /datum/supply_pack/hospitality/barsupplies @@ -43,8 +43,15 @@ /obj/item/weapon/storage/box/glass_extras/sticks ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/gilthari containername = "crate of bar supplies" + +/datum/supply_pack/hospitality/cookingoil + name = "Cooking oil tank crate" + contains = list(/obj/structure/reagent_dispensers/cookingoil) + cost = 10 + containertype = /obj/structure/largecrate + containername = "cooking oil tank crate" /datum/supply_pack/randomised/hospitality/ group = "Hospitality" @@ -60,7 +67,7 @@ ) name = "Surprise pack of five pizzas" cost = 15 - containertype = /obj/structure/closet/crate/freezer + containertype = /obj/structure/closet/crate/freezer/centauri containername = "Pizza crate" /datum/supply_pack/hospitality/gifts @@ -74,5 +81,5 @@ /obj/item/weapon/paper/card/flower ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/allico containername = "crate of gifts" \ No newline at end of file diff --git a/code/datums/supplypacks/hydroponics.dm b/code/datums/supplypacks/hydroponics.dm index 4341a696ad9..069911606e5 100644 --- a/code/datums/supplypacks/hydroponics.dm +++ b/code/datums/supplypacks/hydroponics.dm @@ -11,7 +11,7 @@ name = "Monkey crate" contains = list (/obj/item/weapon/storage/box/monkeycubes) cost = 20 - containertype = /obj/structure/closet/crate/freezer + containertype = /obj/structure/closet/crate/freezer/nanotrasen containername = "Monkey crate" /datum/supply_pack/hydro/farwa @@ -110,7 +110,7 @@ /obj/item/seeds/sugarcaneseed ) cost = 10 - containertype = /obj/structure/closet/crate/hydroponics + containertype = /obj/structure/closet/crate/carp containername = "Seeds crate" access = access_hydroponics @@ -124,7 +124,7 @@ /obj/item/weapon/material/twohanded/fireaxe/scythe ) cost = 45 - containertype = /obj/structure/closet/crate/hydroponics + containertype = /obj/structure/closet/crate/grayson containername = "Weed control crate" access = access_hydroponics @@ -132,7 +132,7 @@ name = "Water tank crate" contains = list(/obj/structure/reagent_dispensers/watertank) cost = 10 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/aether containername = "water tank crate" /datum/supply_pack/hydro/bee_keeper @@ -144,14 +144,14 @@ /obj/item/bee_pack ) cost = 40 - containertype = /obj/structure/closet/crate/hydroponics + containertype = /obj/structure/closet/crate/carp containername = "Beekeeping crate" access = access_hydroponics /datum/supply_pack/hydro/tray name = "Empty hydroponics trays" cost = 50 - containertype = /obj/structure/closet/crate/hydroponics + containertype = /obj/structure/closet/crate/aether containername = "Hydroponics tray crate" contains = list(/obj/machinery/portable_atmospherics/hydroponics{anchored = 0} = 3) access = access_hydroponics diff --git a/code/datums/supplypacks/materials.dm b/code/datums/supplypacks/materials.dm index cd799a235b1..95f15caa6d1 100644 --- a/code/datums/supplypacks/materials.dm +++ b/code/datums/supplypacks/materials.dm @@ -11,40 +11,40 @@ name = "50 metal sheets" contains = list(/obj/fiftyspawner/steel) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/grayson containername = "Metal sheets crate" /datum/supply_pack/materials/glass50 name = "50 glass sheets" contains = list(/obj/fiftyspawner/glass) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/grayson containername = "Glass sheets crate" /datum/supply_pack/materials/wood50 name = "50 wooden planks" contains = list(/obj/fiftyspawner/wood) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/grayson containername = "Wooden planks crate" /datum/supply_pack/materials/plastic50 name = "50 plastic sheets" contains = list(/obj/fiftyspawner/plastic) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/grayson containername = "Plastic sheets crate" /datum/supply_pack/materials/cardboard_sheets contains = list(/obj/fiftyspawner/cardboard) name = "50 cardboard sheets" cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/grayson containername = "Cardboard sheets crate" /datum/supply_pack/materials/carpet name = "Imported carpet" - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/grayson containername = "Imported carpet crate" cost = 15 contains = list( @@ -55,7 +55,7 @@ /datum/supply_pack/misc/linoleum name = "Linoleum" - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/grayson containername = "Linoleum crate" cost = 15 contains = list(/obj/fiftyspawner/linoleum) \ No newline at end of file diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm index 1b164a2cdf3..3edcbed2008 100644 --- a/code/datums/supplypacks/medical.dm +++ b/code/datums/supplypacks/medical.dm @@ -22,28 +22,28 @@ /obj/item/weapon/storage/box/autoinjectors ) cost = 10 - containertype = /obj/structure/closet/crate/medical + containertype = /obj/structure/closet/crate/zenghu containername = "Medical crate" /datum/supply_pack/med/bloodpack name = "BloodPack crate" contains = list(/obj/item/weapon/storage/box/bloodpacks = 3) cost = 10 - containertype = /obj/structure/closet/crate/medical + containertype = /obj/structure/closet/crate/nanocare containername = "BloodPack crate" /datum/supply_pack/med/bodybag name = "Body bag crate" contains = list(/obj/item/weapon/storage/box/bodybags = 3) cost = 10 - containertype = /obj/structure/closet/crate/medical + containertype = /obj/structure/closet/crate/nanocare containername = "Body bag crate" /datum/supply_pack/med/cryobag name = "Stasis bag crate" contains = list(/obj/item/bodybag/cryobag = 3) cost = 40 - containertype = /obj/structure/closet/crate/medical + containertype = /obj/structure/closet/crate/nanocare containername = "Stasis bag crate" /datum/supply_pack/med/surgery @@ -62,7 +62,7 @@ /obj/item/weapon/surgical/circular_saw ) cost = 25 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/veymed containername = "Surgery crate" access = access_medical @@ -73,7 +73,7 @@ /obj/item/weapon/storage/box/cdeathalarm_kit ) cost = 40 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/ward containername = "Death Alarm crate" access = access_medical @@ -83,7 +83,7 @@ /obj/item/weapon/storage/firstaid/clotting ) cost = 100 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/zenghu containername = "Clotting Medicine crate" access = access_medical @@ -97,7 +97,7 @@ /obj/item/weapon/storage/belt/medical = 3 ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/veymed containername = "Sterile equipment crate" /datum/supply_pack/med/extragear @@ -109,7 +109,7 @@ /obj/item/clothing/suit/storage/hooded/wintercoat/medical = 3 ) cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanocare containername = "Medical surplus equipment" access = access_medical @@ -133,7 +133,7 @@ /obj/item/weapon/reagent_containers/syringe ) cost = 50 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanocare containername = "Chief medical officer equipment" access = access_cmo @@ -156,7 +156,7 @@ /obj/item/weapon/reagent_containers/syringe ) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanocare containername = "Medical Doctor equipment" access = access_medical_equip @@ -179,7 +179,7 @@ /obj/item/weapon/reagent_containers/syringe ) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanocare containername = "Chemist equipment" access = access_chemistry @@ -207,7 +207,7 @@ /obj/item/clothing/accessory/storage/white_vest ) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanocare containername = "Paramedic equipment" access = access_medical_equip @@ -226,7 +226,7 @@ /obj/item/weapon/cartridge/medical ) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanocare containername = "Psychiatrist equipment" access = access_psychiatrist @@ -247,7 +247,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanocare containername = "Medical scrubs crate" access = access_medical_equip @@ -264,7 +264,7 @@ /obj/item/weapon/pen ) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/veymed containername = "Autopsy equipment crate" access = access_morgue @@ -291,7 +291,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanocare containername = "Medical uniform crate" access = access_medical_equip @@ -309,7 +309,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 50 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanocare containername = "Medical biohazard equipment" access = access_medical_equip @@ -317,7 +317,7 @@ name = "Portable freezers crate" contains = list(/obj/item/weapon/storage/box/freezer = 7) cost = 25 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/veymed containername = "Portable freezers" access = access_medical_equip @@ -325,7 +325,7 @@ name = "Virus sample crate" contains = list(/obj/item/weapon/virusdish/random = 4) cost = 25 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/zenghu containername = "Virus sample crate" access = access_cmo @@ -333,40 +333,40 @@ name = "Defibrillator crate" contains = list(/obj/item/device/defib_kit = 2) cost = 30 - containertype = /obj/structure/closet/crate/medical + containertype = /obj/structure/closet/crate/veymed containername = "Defibrillator crate" /datum/supply_pack/med/distillery name = "Chemical distiller crate" contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery = 1) cost = 50 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/nanotrasen containername = "Chemical distiller crate" /datum/supply_pack/med/advdistillery name = "Industrial Chemical distiller crate" contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial = 1) cost = 150 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/xion containername = "Industrial Chemical distiller crate" /datum/supply_pack/med/oxypump name = "Oxygen pump crate" contains = list(/obj/machinery/oxygen_pump/mobile = 1) cost = 125 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/xion containername = "Oxygen pump crate" /datum/supply_pack/med/anestheticpump name = "Anesthetic pump crate" contains = list(/obj/machinery/oxygen_pump/mobile/anesthetic = 1) cost = 130 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/nanotrasen containername = "Anesthetic pump crate" /datum/supply_pack/med/stablepump name = "Portable stabilizer crate" contains = list(/obj/machinery/oxygen_pump/mobile/stabilizer = 1) cost = 175 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/nanotrasen containername = "Portable stabilizer crate" diff --git a/code/datums/supplypacks/misc.dm b/code/datums/supplypacks/misc.dm index 1e5890f0c8b..db46de1e047 100644 --- a/code/datums/supplypacks/misc.dm +++ b/code/datums/supplypacks/misc.dm @@ -20,7 +20,7 @@ ) name = "Trading Card Crate" cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/oculum containername = "cards crate" /datum/supply_pack/randomised/misc/dnd @@ -36,7 +36,7 @@ ) name = "Miniatures Crate" cost = 200 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/oculum containername = "Miniature Crate" /datum/supply_pack/randomised/misc/plushies @@ -88,14 +88,14 @@ //VOREStation Add End name = "Plushies Crate" cost = 15 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/allico containername = "Plushies Crate" /datum/supply_pack/misc/eftpos contains = list(/obj/item/device/eftpos) name = "EFTPOS scanner" cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/nanotrasen containername = "EFTPOS crate" /datum/supply_pack/misc/chaplaingear @@ -113,7 +113,7 @@ /obj/item/weapon/storage/fancy/candle_box = 3 ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/gilthari containername = "Chaplain equipment crate" /datum/supply_pack/misc/hoverpod @@ -136,14 +136,14 @@ /obj/item/clothing/accessory/storage/webbing ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/nanothreads containername = "Webbing crate" /datum/supply_pack/misc/holoplant name = "Holoplant Pot" contains = list(/obj/machinery/holoplant/shipped) cost = 15 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/thinktronic containername = "Holoplant crate" /datum/supply_pack/misc/glucose_hypos @@ -152,7 +152,7 @@ /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5 ) cost = 25 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/zenghu containername = "Glucose Hypo Crate" /datum/supply_pack/misc/mre_rations @@ -169,7 +169,7 @@ /obj/item/weapon/storage/mre/menu9, /obj/item/weapon/storage/mre/menu10) cost = 50 - containertype = /obj/structure/closet/crate/freezer + containertype = /obj/structure/closet/crate/centauri containername = "ready to eat rations" /datum/supply_pack/misc/paste_rations @@ -178,7 +178,7 @@ /obj/item/weapon/storage/mre/menu11 = 2 ) cost = 25 - containertype = /obj/structure/closet/crate/freezer + containertype = /obj/structure/closet/crate/freezer/centauri containername = "emergency rations" /datum/supply_pack/misc/medical_rations @@ -187,5 +187,5 @@ /obj/item/weapon/storage/mre/menu13 = 2 ) cost = 40 - containertype = /obj/structure/closet/crate/freezer + containertype = /obj/structure/closet/crate/zenghu containername = "emergency rations" diff --git a/code/datums/supplypacks/munitions.dm b/code/datums/supplypacks/munitions.dm index 45fa6ae3f4a..f7b8eeebad9 100644 --- a/code/datums/supplypacks/munitions.dm +++ b/code/datums/supplypacks/munitions.dm @@ -20,15 +20,15 @@ /obj/item/weapon/storage/box/flashbangs = 2 ) cost = 40 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/lawson containername = "Security equipment crate" access = access_security*/ /datum/supply_pack/munitions/egunpistol name = "Weapons - Energy sidearms" contains = list(/obj/item/weapon/gun/energy/gun = 2) - cost = 50 - containertype = /obj/structure/closet/crate/secure/weapon + cost = 40 + containertype = /obj/structure/closet/crate/secure/lawson containername = "Energy sidearms crate" access = access_armory //VOREStation Edit - Guns are for the armory. @@ -59,7 +59,7 @@ name = "Weapons - Laser rifle crate" contains = list(/obj/item/weapon/gun/energy/laser = 2) //VOREStation Edit - Made to be consistent with the energy guns crate. cost = 50 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/heph containername = "Energy weapons crate" access = access_armory @@ -79,7 +79,7 @@ name = "Weapons - Energy marksman" contains = list(/obj/item/weapon/gun/energy/sniperrifle = 2) cost = 100 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/heph containername = "Energy marksman crate" access = access_armory @@ -87,7 +87,7 @@ name = "Weapons - Burst laser" contains = list(/obj/item/weapon/gun/energy/gun/burst = 2) cost = 50 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/lawson containername = "Burst laser crate" access = access_armory */ @@ -98,7 +98,7 @@ /obj/item/weapon/storage/box/empslite ) cost = 50 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/ward containername = "Electromagnetic weapons crate" access = access_armory @@ -109,7 +109,7 @@ /obj/item/weapon/storage/box/empslite ) cost = 30 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/ward containername = "Electromagnetic weapons crate" access = access_armory @@ -117,7 +117,7 @@ name = "Weapons - Ballistic SMGs" contains = list(/obj/item/weapon/gun/projectile/automatic/wt550 = 2) cost = 50 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/ward containername = "Ballistic weapon crate" access = access_armory @@ -144,11 +144,22 @@ containername = "Ballistic Weapons crate" access = access_armory //VOREStation Edit - Guns are for the armory. +/datum/supply_pack/munitions/caseless + name = "Weapons - Prototype Caseless Rifle" + contains = list( + /obj/item/weapon/gun/projectile/caseless/prototype, + /obj/item/ammo_magazine/m5mmcaseless = 3 + ) + cost = 60 + containertype = /obj/structure/closet/crate/secure/gilthari + containername = "Caseless rifle crate" + access = access_security + /datum/supply_pack/munitions/mrifle name = "Weapons - Magnetic Rifles" contains = list(/obj/item/weapon/gun/magnetic/railgun/heater = 2) cost = 120 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/heph containername = "Magnetic weapon crate" access = access_armory @@ -156,7 +167,7 @@ name = "Weapons - Magnetic Pistols" contains = list(/obj/item/weapon/gun/magnetic/railgun/heater/pistol = 2) cost = 200 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/heph containername = "Magnetic weapon crate" access = access_armory @@ -164,7 +175,7 @@ name = "Weapons - Magnetic Carbines" contains = list(/obj/item/weapon/gun/magnetic/railgun/flechette/sif = 2) cost = 130 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/lawson containername = "Magnetic weapon crate" access = access_security @@ -183,7 +194,7 @@ /obj/item/weapon/storage/box/shotgunshells = 2 ) cost = 25 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/weapon containername = "Ballistic ammunition crate" access = access_armory @@ -199,7 +210,7 @@ name = "Ammunition - 9mm top mounted lethal" contains = list(/obj/item/ammo_magazine/m9mmt = 6) cost = 25 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/weapon containername = "Ballistic ammunition crate" access = access_armory @@ -207,7 +218,7 @@ name = "Ammunition - 9mm top mounted rubber" contains = list(/obj/item/ammo_magazine/m9mmt/rubber = 6) cost = 25 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/weapon containername = "Ballistic ammunition crate" access = access_security @@ -215,7 +226,7 @@ name = "Ammunition - 7.62mm lethal" contains = list(/obj/item/ammo_magazine/m762 = 6) cost = 25 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/weapon containername = "Ballistic ammunition crate" access = access_armory @@ -223,6 +234,6 @@ name = "Ammunition - Power cell" contains = list(/obj/item/weapon/cell/device/weapon = 3) cost = 50 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/weapon containername = "Energy ammunition crate" access = access_security diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm index 134ae76e303..9bb6b1a4429 100644 --- a/code/datums/supplypacks/recreation.dm +++ b/code/datums/supplypacks/recreation.dm @@ -20,7 +20,7 @@ /obj/item/weapon/material/twohanded/fireaxe/foam = 2 ) cost = 50 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/allico containername = "foam weapon crate" /datum/supply_pack/recreation/lasertag @@ -31,8 +31,8 @@ /obj/item/weapon/gun/energy/lasertag/blue, /obj/item/clothing/suit/bluetag ) - containertype = /obj/structure/closet - containername = "Lasertag Closet" + containertype = /obj/structure/closet/crate/ward + containername = "Lasertag Supplies" cost = 10 /datum/supply_pack/recreation/artscrafts @@ -55,14 +55,14 @@ /obj/item/weapon/wrapping_paper = 3 ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/allico containername = "Arts and Crafts crate" /datum/supply_pack/recreation/painters name = "Station Painting Supplies" cost = 10 containername = "station painting supplies crate" - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/grayson contains = list( /obj/item/device/pipe_painter = 2, /obj/item/device/floor_painter = 2, @@ -82,7 +82,7 @@ name = "Deluxe Fishing Bait" cost = 40 containername = "deluxe bait crate" - containertype = /obj/structure/closet/crate/freezer + containertype = /obj/structure/closet/crate/carp num_contained = 8 contains = list( /obj/item/weapon/storage/box/wormcan, @@ -93,7 +93,7 @@ name = "Laser Tag Turrets" cost = 40 containername = "laser tag turret crate" - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/ward contains = list( /obj/machinery/porta_turret/lasertag/blue, /obj/machinery/porta_turret/lasertag/red diff --git a/code/datums/supplypacks/robotics.dm b/code/datums/supplypacks/robotics.dm index 757d38b9535..5f8cf6337c8 100644 --- a/code/datums/supplypacks/robotics.dm +++ b/code/datums/supplypacks/robotics.dm @@ -20,7 +20,7 @@ /obj/item/weapon/cell/high = 2 ) cost = 10 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Robotics assembly" access = access_robotics @@ -56,7 +56,7 @@ name = "Morpheus robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/morpheus) cost = 20 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/morpheus containername = "Robolimb blueprints (Morpheus)" access = access_robotics @@ -64,7 +64,7 @@ name = "Cyber Solutions robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/cybersolutions) cost = 20 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/cybersolutions containername = "Robolimb blueprints (Cyber Solutions)" access = access_robotics @@ -72,7 +72,7 @@ name = "Xion robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/xion) cost = 20 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/xion containername = "Robolimb blueprints (Xion)" access = access_robotics @@ -80,7 +80,7 @@ name = "Grayson robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/grayson) cost = 30 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/grayson containername = "Robolimb blueprints (Grayson)" access = access_robotics @@ -88,7 +88,7 @@ name = "Hephaestus robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/hephaestus) cost = 35 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/heph containername = "Robolimb blueprints (Hephaestus)" access = access_robotics @@ -96,7 +96,7 @@ name = "Ward-Takahashi robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/wardtakahashi) cost = 35 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/ward containername = "Robolimb blueprints (Ward-Takahashi)" access = access_robotics @@ -104,7 +104,7 @@ name = "Zeng Hu robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/zenghu) cost = 35 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/zenghu containername = "Robolimb blueprints (Zeng Hu)" access = access_robotics @@ -112,7 +112,7 @@ name = "Bishop robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/bishop) cost = 70 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/bishop containername = "Robolimb blueprints (Bishop)" access = access_robotics @@ -133,7 +133,7 @@ /obj/item/weapon/circuitboard/mecha/ripley/peripherals ) cost = 25 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/xion containername = "APLU \"Ripley\" Circuit Crate" access = access_robotics @@ -144,7 +144,7 @@ /obj/item/weapon/circuitboard/mecha/odysseus/main ) cost = 25 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/veymed containername = "\"Odysseus\" Circuit Crate" access = access_robotics @@ -158,7 +158,7 @@ ) name = "Random APLU modkit" cost = 200 - containertype = /obj/structure/closet/crate/science + containertype = /obj/structure/closet/crate/xion containername = "heavy crate" /datum/supply_pack/randomised/robotics/exosuit_mod/durand @@ -168,6 +168,7 @@ /obj/item/device/kit/paint/durand/phazon ) name = "Random Durand exosuit modkit" + containertype = /obj/structure/closet/crate/heph /datum/supply_pack/randomised/robotics/exosuit_mod/gygax contains = list( @@ -176,6 +177,7 @@ /obj/item/device/kit/paint/gygax/recitence ) name = "Random Gygax exosuit modkit" + containertype = /obj/structure/closet/crate/heph /datum/supply_pack/robotics/jumper_cables name = "Jumper kit crate" @@ -183,7 +185,7 @@ /obj/item/device/defib_kit/jumper_kit = 2 ) cost = 30 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/einstein containername = "Jumper kit crate" access = access_robotics diff --git a/code/datums/supplypacks/science.dm b/code/datums/supplypacks/science.dm index ab55b8571e8..c4c03ffd047 100644 --- a/code/datums/supplypacks/science.dm +++ b/code/datums/supplypacks/science.dm @@ -9,7 +9,7 @@ name = "Coolant tank crate" contains = list(/obj/structure/reagent_dispensers/coolanttank) cost = 15 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/aether containername = "coolant tank crate" /datum/supply_pack/sci/phoron @@ -39,7 +39,7 @@ /obj/item/seeds/kudzuseed ) cost = 15 - containertype = /obj/structure/closet/crate/hydroponics + containertype = /obj/structure/closet/crate/carp containername = "Exotic Seeds crate" access = access_hydroponics @@ -47,14 +47,14 @@ name = "Integrated circuit printer" contains = list(/obj/item/device/integrated_circuit_printer = 2) cost = 15 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/ward containername = "Integrated circuit crate" /datum/supply_pack/sci/integrated_circuit_printer_upgrade name = "Integrated circuit printer upgrade - advanced designs" contains = list(/obj/item/weapon/disk/integrated_circuit/upgrade/advanced) cost = 30 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/ward containername = "Integrated circuit crate" /datum/supply_pack/sci/xenoarch @@ -75,6 +75,6 @@ /obj/item/weapon/storage/bag/fossils, /obj/item/weapon/hand_labeler) cost = 100 - containertype = /obj/structure/closet/crate/secure/science + containertype = /obj/structure/closet/crate/secure/xion containername = "Xenoarchaeology Tech crate" access = access_research \ No newline at end of file diff --git a/code/datums/supplypacks/security.dm b/code/datums/supplypacks/security.dm index cd523475834..5fd24a473fe 100644 --- a/code/datums/supplypacks/security.dm +++ b/code/datums/supplypacks/security.dm @@ -53,11 +53,11 @@ /obj/item/clothing/accessory/storage/pouches/blue, ) cost = 30 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/heph containername = "Plate Carrier crate" /datum/supply_pack/security/carriersgreen - name = "Armor - Blue modular armor" + name = "Armor - Green modular armor" contains = list( /obj/item/clothing/suit/armor/pcarrier/green, /obj/item/clothing/accessory/armor/armguards/green, @@ -65,7 +65,7 @@ /obj/item/clothing/accessory/storage/pouches/green, ) cost = 30 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/heph containername = "Plate Carrier crate" /datum/supply_pack/security/carriersnavy @@ -77,7 +77,7 @@ /obj/item/clothing/accessory/storage/pouches/navy, ) cost = 30 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/heph containername = "Plate Carrier crate" /datum/supply_pack/security/carrierstan @@ -89,7 +89,7 @@ /obj/item/clothing/accessory/storage/pouches/tan, ) cost = 30 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/heph containername = "Plate Carrier crate" /datum/supply_pack/security/armorplate @@ -98,7 +98,7 @@ /obj/item/clothing/accessory/armor/armorplate, ) cost = 5 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/lawson containername = "Armor plate crate" /datum/supply_pack/security/armorplatestab @@ -107,7 +107,7 @@ /obj/item/clothing/accessory/armor/armorplate/stab, ) cost = 10 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/lawson containername = "Armor plate crate" /datum/supply_pack/security/armorplatemedium @@ -116,7 +116,7 @@ /obj/item/clothing/accessory/armor/armorplate/medium, ) cost = 10 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/lawson containername = "Armor plate crate" /datum/supply_pack/security/armorplatetac @@ -125,7 +125,7 @@ /obj/item/clothing/accessory/armor/armorplate/tactical, ) cost = 15 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/heph containername = "Armor plate crate" /datum/supply_pack/randomised/security/carriers @@ -140,7 +140,7 @@ /obj/item/clothing/suit/armor/pcarrier/press ) cost = 10 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/scg containername = "Plate Carrier crate" /datum/supply_pack/security/carriertags @@ -158,7 +158,7 @@ /obj/item/clothing/accessory/armor/tag/abneg ) cost = 20 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/scg containername = "Plate Carrier crate" /datum/supply_pack/security/helmcovers @@ -174,7 +174,7 @@ /obj/item/clothing/accessory/armor/helmcover/tan ) cost = 20 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/scg containername = "Helmet Covers crate" /datum/supply_pack/randomised/security/armorplates @@ -193,7 +193,7 @@ /obj/item/clothing/accessory/armor/armorplate/bulletproof ) cost = 40 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/scg containername = "Armor plate crate" /datum/supply_pack/randomised/security/carrierarms @@ -210,7 +210,7 @@ /obj/item/clothing/accessory/armor/armguards/bulletproof ) cost = 40 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/scg containername = "Armor plate crate" /datum/supply_pack/randomised/security/carrierlegs @@ -227,7 +227,7 @@ /obj/item/clothing/accessory/armor/legguards/bulletproof ) cost = 40 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/scg containername = "Armor plate crate" /datum/supply_pack/randomised/security/carrierbags @@ -246,7 +246,7 @@ /obj/item/clothing/accessory/storage/pouches/large/tan ) cost = 50 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/scg containername = "Armor plate crate" /datum/supply_pack/security/riot_gear @@ -260,7 +260,7 @@ /obj/item/weapon/storage/box/handcuffs ) cost = 40 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/lawson containername = "Riot gear crate" access = access_armory @@ -273,7 +273,7 @@ /obj/item/clothing/shoes/leg_guard/riot ) cost = 30 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/lawson containername = "Riot armor crate" access = access_armory @@ -287,7 +287,7 @@ /obj/item/clothing/accessory/armor/legguards/riot ) cost = 40 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/lawson containername = "Riot armor crate" access = access_armory @@ -300,7 +300,7 @@ /obj/item/clothing/shoes/leg_guard/laserproof ) cost = 40 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/lawson containername = "Ablative armor crate" access = access_armory @@ -314,7 +314,7 @@ /obj/item/clothing/accessory/armor/legguards/laserproof ) cost = 50 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/lawson containername = "Ablative armor crate" access = access_armory @@ -327,7 +327,7 @@ /obj/item/clothing/shoes/leg_guard/bulletproof ) cost = 40 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/heph containername = "Ballistic armor crate" access = access_armory /* VOREStation Removal - Howabout no ERT armor being orderable? @@ -342,7 +342,7 @@ /obj/item/clothing/accessory/armor/legguards/bulletproof ) cost = 50 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/heph containername = "Ballistic armor crate" access = access_armory @@ -355,13 +355,13 @@ /obj/item/clothing/shoes/leg_guard/combat ) cost = 40 - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/saare containername = "Combat armor crate" access = access_armory /datum/supply_pack/security/tactical name = "Armor - Tactical" - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/saare containername = "Tactical armor crate" cost = 40 access = access_armory @@ -387,7 +387,7 @@ /datum/supply_pack/security/flexitac name = "Armor - Tactical Light" - containertype = /obj/structure/closet/crate/secure/gear + containertype = /obj/structure/closet/crate/secure/saare containername = "Tactical Light armor crate" cost = 75 access = access_armory @@ -412,15 +412,14 @@ name = "Misc - Security Barriers" contains = list(/obj/machinery/deployable/barrier = 4) cost = 20 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/secure/heph containername = "Security barrier crate" - access = null /datum/supply_pack/security/securityshieldgen name = "Misc - Wall shield generators" contains = list(/obj/machinery/shieldwallgen = 4) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/heph containername = "Wall shield generators crate" access = access_teleporter @@ -434,7 +433,7 @@ /obj/item/clothing/accessory/holster/hip ) cost = 15 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/hedberg containername = "Holster crate" /datum/supply_pack/security/extragear @@ -446,7 +445,7 @@ /obj/item/clothing/suit/storage/hooded/wintercoat/security = 3 ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/nanothreads containername = "Security surplus equipment" /datum/supply_pack/security/detectivegear @@ -473,7 +472,7 @@ /obj/item/weapon/storage/bag/detective ) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Forensic equipment" access = access_forensics_lockers @@ -486,7 +485,7 @@ /obj/item/device/detective_scanner ) cost = 60 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/ward containername = "Forensic equipment" access = access_forensics_lockers @@ -508,7 +507,7 @@ /obj/item/clothing/gloves/black = 2 ) cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Investigation clothing" access = access_forensics_lockers @@ -538,7 +537,7 @@ /obj/item/device/flashlight/maglight ) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Officer equipment" access = access_brig @@ -567,7 +566,7 @@ /obj/item/device/flashlight/maglight ) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Warden equipment" access = access_armory @@ -594,7 +593,7 @@ /obj/item/device/flashlight/maglight ) cost = 50 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Head of security equipment" access = access_hos @@ -613,7 +612,7 @@ /obj/item/weapon/storage/box/holobadge ) cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Security uniform crate" /datum/supply_pack/security/navybluesecurityclothing @@ -634,7 +633,7 @@ /obj/item/weapon/storage/box/holobadge ) cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Navy blue security uniform crate" /datum/supply_pack/security/corporatesecurityclothing @@ -654,7 +653,7 @@ /obj/item/weapon/storage/box/holobadge ) cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Corporate security uniform crate" /datum/supply_pack/security/biosuit @@ -670,7 +669,7 @@ /obj/item/weapon/storage/box/gloves ) cost = 25 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Security biohazard gear" access = access_security @@ -680,6 +679,6 @@ /obj/item/weapon/contraband/poster/nanotrasen = 6 ) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanotrasen containername = "Morale Posters" access = access_maint_tunnels diff --git a/code/datums/supplypacks/supply.dm b/code/datums/supplypacks/supply.dm index b58c5960457..e9fa3f2d998 100644 --- a/code/datums/supplypacks/supply.dm +++ b/code/datums/supplypacks/supply.dm @@ -18,14 +18,14 @@ /obj/item/weapon/reagent_containers/food/condiment/yeast = 3 ) cost = 10 - containertype = /obj/structure/closet/crate/freezer + containertype = /obj/structure/closet/crate/freezer/centauri containername = "Food crate" /datum/supply_pack/supply/toner name = "Toner cartridges" contains = list(/obj/item/device/toner = 6) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/ummarcar containername = "Toner cartridges" /datum/supply_pack/supply/janitor @@ -48,7 +48,7 @@ /obj/structure/mopbucket ) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/galaksi containername = "Janitorial supplies" /datum/supply_pack/supply/shipping @@ -62,7 +62,7 @@ /obj/item/weapon/tool/wirecutters, /obj/item/weapon/tape_roll = 2) cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/ummarcar containername = "Shipping supplies crate" /datum/supply_pack/supply/bureaucracy @@ -82,13 +82,20 @@ ) name = "Office supplies" cost = 15 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/ummarcar containername = "Office supplies crate" +/datum/supply_pack/supply/sticky_notes + name = "Stationery - sticky notes (50)" + contains = list(/obj/item/sticky_pad/random) + cost = 10 + containertype = /obj/structure/closet/crate/ummarcar + containername = "\improper Sticky notes crate" + /datum/supply_pack/supply/spare_pda name = "Spare PDAs" cost = 10 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/thinktronic containername = "Spare PDA crate" contains = list(/obj/item/device/pda = 3) @@ -112,7 +119,7 @@ /obj/item/clothing/glasses/meson ) cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/xion containername = "Shaft miner equipment" access = access_mining /* //VOREStation Edit - Pointless on Tether. @@ -127,12 +134,12 @@ name = "Cargo Train Tug" contains = list(/obj/vehicle/train/engine) cost = 35 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/xion containername = "Cargo Train Tug Crate" /datum/supply_pack/supply/cargotrailer name = "Cargo Train Trolley" contains = list(/obj/vehicle/train/trolley) cost = 15 - containertype = /obj/structure/largecrate + containertype = /obj/structure/closet/crate/large/xion containername = "Cargo Train Trolley Crate" diff --git a/code/datums/supplypacks/voidsuits.dm b/code/datums/supplypacks/voidsuits.dm index ed4640c91e0..a867b20255a 100644 --- a/code/datums/supplypacks/voidsuits.dm +++ b/code/datums/supplypacks/voidsuits.dm @@ -17,7 +17,7 @@ /obj/item/weapon/tank/oxygen = 2, ) cost = 40 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/aether containername = "Atmospheric voidsuit crate" access = access_atmospherics @@ -31,7 +31,7 @@ /obj/item/weapon/tank/oxygen = 2, ) cost = 50 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/aether containername = "Heavy Duty Atmospheric voidsuit crate" access = access_atmospherics @@ -45,7 +45,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/xion containername = "Engineering voidsuit crate" access = access_engine_equip @@ -59,7 +59,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/xion containername = "Engineering Construction voidsuit crate" access = access_engine_equip @@ -73,7 +73,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 45 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/xion containername = "Engineering Hazmat voidsuit crate" access = access_engine_equip @@ -87,7 +87,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 50 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/xion containername = "Reinforced Engineering voidsuit crate" access = access_engine_equip @@ -101,7 +101,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/veymed containername = "Medical voidsuit crate" access = access_medical_equip @@ -115,7 +115,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/veymed containername = "Medical EMT voidsuit crate" access = access_medical_equip @@ -129,12 +129,12 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 45 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/nanocare containername = "Medical Biohazard voidsuit crate" access = access_medical_equip /datum/supply_pack/voidsuits/medical/alt - name = "Vey-Med Medical voidsuits" + name = "Vey-Med Autoadaptive voidsuits (humanoid)" contains = list( /obj/item/clothing/suit/space/void/medical/alt = 2, /obj/item/clothing/head/helmet/space/void/medical/alt = 2, @@ -143,10 +143,21 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 60 - containertype = /obj/structure/closet/crate/secure - containername = "Vey-Med Medical voidsuit crate" + containertype = /obj/structure/closet/crate/secure/veymed + containername = "Vey-Med Autoadaptive voidsuit (humanoid) crate" access = access_medical_equip +/datum/supply_pack/voidsuits/medical/alt/tesh + name = "Vey-Med Autoadaptive voidsuits (teshari)" + contains = list( + /obj/item/clothing/suit/space/void/medical/alt/tesh = 2, + /obj/item/clothing/head/helmet/space/void/medical/alt/tesh = 2, + /obj/item/clothing/mask/breath = 2, + /obj/item/clothing/shoes/magboots = 2, + /obj/item/weapon/tank/oxygen = 2 + ) + containername = "Vey-Med Autoadaptive voidsuit (teshari) crate" + /datum/supply_pack/voidsuits/security name = "Security voidsuits" contains = list( @@ -157,7 +168,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/heph containername = "Security voidsuit crate" /datum/supply_pack/voidsuits/security/crowd @@ -170,7 +181,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 60 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/heph containername = "Security Crowd Control voidsuit crate" access = access_armory @@ -184,7 +195,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 60 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/heph containername = "Security EVA voidsuit crate" access = access_armory @@ -197,7 +208,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 40 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/xion containername = "Mining voidsuit crate" access = access_mining @@ -210,7 +221,7 @@ /obj/item/weapon/tank/oxygen = 2 ) cost = 50 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/grayson containername = "Frontier Mining voidsuit crate" access = access_mining @@ -221,6 +232,6 @@ /obj/item/clothing/mask/gas/zaddat = 1 ) cost = 30 - containertype = /obj/structure/closet/crate + containertype = /obj/structure/closet/crate/nanotrasen containername = "Zaddat Shroud crate" access = null \ No newline at end of file diff --git a/code/datums/uplink/visible_weapons.dm b/code/datums/uplink/visible_weapons.dm index 0ed9b262265..d3ed1dcec34 100644 --- a/code/datums/uplink/visible_weapons.dm +++ b/code/datums/uplink/visible_weapons.dm @@ -90,7 +90,7 @@ path = /obj/item/weapon/gun/projectile/p92x/large /datum/uplink_item/item/visible_weapons/lemat - name = "LeMat" + name = "Mako Revolver" item_cost = 60 path = /obj/item/weapon/gun/projectile/revolver/lemat @@ -145,9 +145,9 @@ path = /obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever /datum/uplink_item/item/visible_weapons/egun - name = "Energy Gun" + name = "Compact Energy Gun" item_cost = 30 - path = /obj/item/weapon/gun/energy/gun + path = /obj/item/weapon/gun/energy/gun/compact /datum/uplink_item/item/visible_weapons/lasercannon name = "Laser Cannon" diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index f018a8e5944..229412e93f0 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -1,61 +1,53 @@ // Wires for airlocks /datum/wires/airlock/secure - random = 1 + randomize = 1 wire_count = 14 - window_y = 680 /datum/wires/airlock holder_type = /obj/machinery/door/airlock wire_count = 12 - window_y = 570 + proper_name = "Airlock" -var/const/AIRLOCK_WIRE_IDSCAN = 1 -var/const/AIRLOCK_WIRE_MAIN_POWER1 = 2 -var/const/AIRLOCK_WIRE_MAIN_POWER2 = 4 -var/const/AIRLOCK_WIRE_DOOR_BOLTS = 8 -var/const/AIRLOCK_WIRE_BACKUP_POWER1 = 16 -var/const/AIRLOCK_WIRE_BACKUP_POWER2 = 32 -var/const/AIRLOCK_WIRE_OPEN_DOOR = 64 -var/const/AIRLOCK_WIRE_AI_CONTROL = 128 -var/const/AIRLOCK_WIRE_ELECTRIFY = 256 -var/const/AIRLOCK_WIRE_SAFETY = 512 -var/const/AIRLOCK_WIRE_SPEED = 1024 -var/const/AIRLOCK_WIRE_LIGHT = 2048 - -/datum/wires/airlock/CanUse(var/mob/living/L) +/datum/wires/airlock/interactable(mob/user) var/obj/machinery/door/airlock/A = holder - if(!istype(L, /mob/living/silicon)) + if(!issilicon(user)) if(A.isElectrified()) - if(A.shock(L, 100)) - return 0 + if(A.shock(user, 100)) + return FALSE if(A.p_open) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/airlock/GetInteractWindow() +/datum/wires/airlock/New(atom/_holder) + wires = list( + WIRE_IDSCAN, WIRE_MAIN_POWER1, WIRE_MAIN_POWER2, WIRE_DOOR_BOLTS, + WIRE_BACKUP_POWER1, WIRE_BACKUP_POWER2, WIRE_OPEN_DOOR, WIRE_AI_CONTROL, + WIRE_ELECTRIFY, WIRE_SAFETY, WIRE_SPEED, WIRE_BOLT_LIGHT + ) + return ..() + +/datum/wires/airlock/get_status() + . = ..() var/obj/machinery/door/airlock/A = holder var/haspower = A.arePowerSystemsOn() //If there's no power, then no lights will be on. - . += ..() - . += show_hint(0x01, A.locked, "The door bolts have fallen!", "The door bolts look up.") - . += show_hint(0x02, A.lights && haspower, "The door bolt lights are on.", "The door bolt lights are off!") - . += show_hint(0x04, haspower, "The test light is on.", "The test light is off!") - . += show_hint(0x08, A.backup_power_lost_until, "The backup power light is off!", "The backup power light is on.") - . += show_hint(0x10, A.aiControlDisabled == 0 && !A.emagged && haspower, "The 'AI control allowed' light is on.", "The 'AI control allowed' light is off.") - . += show_hint(0x20, A.safe == 0 && haspower, "The 'Check Wiring' light is on.", "The 'Check Wiring' light is off.") - . += show_hint(0x40, A.normalspeed == 0 && haspower, "The 'Check Timing Mechanism' light is on.", "The 'Check Timing Mechanism' light is off.") - . += show_hint(0x80, A.aiDisabledIdScanner == 0 && haspower, "The IDScan light is on.", "The IDScan light is off.") - -/datum/wires/airlock/UpdateCut(var/index, var/mended) + . += "The door bolts [A.locked ? "have fallen!" : "look up."]" + . += "The door bolt lights are [(A.lights && haspower) ? "on." : "off!"]" + . += "The test light is [haspower ? "on." : "off!"]" + . += "The backup power light is [A.backup_power_lost_until ? "off!" : "on."]" + . += "The 'AI control allowed' light is [(A.aiControlDisabled == 0 && !A.emagged && haspower) ? "on" : "off"]." + . += "The 'Check Wiring' light is [(A.safe == 0 && haspower) ? "on" : "off"]." + . += "The 'Check Timing Mechanism' light is [(A.normalspeed == 0 && haspower) ? "on" : "off"]." + . += "The IDScan light is [(A.aiDisabledIdScanner == 0 && haspower) ? "on" : "off."]" +/datum/wires/airlock/on_cut(wire, mend) var/obj/machinery/door/airlock/A = holder - switch(index) - if(AIRLOCK_WIRE_IDSCAN) - A.aiDisabledIdScanner = !mended - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - - if(!mended) + switch(wire) + if(WIRE_IDSCAN) + A.aiDisabledIdScanner = !mend + if(WIRE_MAIN_POWER1, WIRE_MAIN_POWER2) + if(!mend) //Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. A.loseMainPower() A.shock(usr, 50) @@ -63,9 +55,8 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 A.regainMainPower() A.shock(usr, 50) - if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - - if(!mended) + if(WIRE_BACKUP_POWER1, WIRE_BACKUP_POWER2) + if(!mend) //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. A.loseBackupPower() A.shock(usr, 50) @@ -73,16 +64,14 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 A.regainBackupPower() A.shock(usr, 50) - if(AIRLOCK_WIRE_DOOR_BOLTS) - - if(!mended) + if(WIRE_DOOR_BOLTS) + if(!mend) //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) A.lock(1) A.update_icon() - if(AIRLOCK_WIRE_AI_CONTROL) - - if(!mended) + if(WIRE_AI_CONTROL) + if(!mend) //one wire for AI control. Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all. //aiControlDisabled: If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. if(A.aiControlDisabled == 0) @@ -95,40 +84,41 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 else if(A.aiControlDisabled == 2) A.aiControlDisabled = -1 - if(AIRLOCK_WIRE_ELECTRIFY) - if(!mended) + if(WIRE_ELECTRIFY) + if(!mend) //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. A.electrify(-1) else A.electrify(0) return // Don't update the dialog. - if (AIRLOCK_WIRE_SAFETY) - A.safe = mended + if (WIRE_SAFETY) + A.safe = mend - if(AIRLOCK_WIRE_SPEED) - A.autoclose = mended - if(mended) + if(WIRE_SPEED) + A.autoclose = mend + if(mend) if(!A.density) A.close() - if(AIRLOCK_WIRE_LIGHT) - A.lights = mended + if(WIRE_BOLT_LIGHT) + A.lights = mend A.update_icon() -/datum/wires/airlock/UpdatePulsed(var/index) - +/datum/wires/airlock/on_pulse(wire) var/obj/machinery/door/airlock/A = holder - switch(index) - if(AIRLOCK_WIRE_IDSCAN) + switch(wire) + if(WIRE_IDSCAN) //Sending a pulse through flashes the red light on the door (if the door has power). if(A.arePowerSystemsOn() && A.density) A.do_animate("deny") - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + + if(WIRE_MAIN_POWER1, WIRE_MAIN_POWER2) //Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). A.loseMainPower() - if(AIRLOCK_WIRE_DOOR_BOLTS) + + if(WIRE_DOOR_BOLTS) //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), //raises them if they are down (only if power's on) if(!A.locked) @@ -136,10 +126,11 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 else A.unlock() - if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + if(WIRE_BACKUP_POWER1, WIRE_BACKUP_POWER2) //two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). A.loseBackupPower() - if(AIRLOCK_WIRE_AI_CONTROL) + + if(WIRE_AI_CONTROL) if(A.aiControlDisabled == 0) A.aiControlDisabled = 1 else if(A.aiControlDisabled == -1) @@ -152,24 +143,26 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 else if(A.aiControlDisabled == 2) A.aiControlDisabled = -1 - if(AIRLOCK_WIRE_ELECTRIFY) + if(WIRE_ELECTRIFY) //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. A.electrify(30) - if(AIRLOCK_WIRE_OPEN_DOOR) + + if(WIRE_OPEN_DOOR) //tries to open the door without ID //will succeed only if the ID wire is cut or the door requires no access and it's not emagged if(A.emagged) return if(!A.requiresID() || A.check_access(null)) if(A.density) A.open() else A.close() - if(AIRLOCK_WIRE_SAFETY) + + if(WIRE_SAFETY) A.safe = !A.safe if(!A.density) A.close() - if(AIRLOCK_WIRE_SPEED) + if(WIRE_SPEED) A.normalspeed = !A.normalspeed - if(AIRLOCK_WIRE_LIGHT) + if(WIRE_BOLT_LIGHT) A.lights = !A.lights A.update_icon() diff --git a/code/datums/wires/alarm.dm b/code/datums/wires/alarm.dm index 7c56bd4e525..ed8477042bb 100644 --- a/code/datums/wires/alarm.dm +++ b/code/datums/wires/alarm.dm @@ -1,94 +1,86 @@ /datum/wires/alarm holder_type = /obj/machinery/alarm wire_count = 5 + proper_name = "Air alarm" -var/const/AALARM_WIRE_IDSCAN = 1 -var/const/AALARM_WIRE_POWER = 2 -var/const/AALARM_WIRE_SYPHON = 4 -var/const/AALARM_WIRE_AI_CONTROL = 8 -var/const/AALARM_WIRE_AALARM = 16 +/datum/wires/alarm/New(atom/_holder) + wires = list( + WIRE_IDSCAN, WIRE_MAIN_POWER1, WIRE_SYPHON, + WIRE_AI_CONTROL, WIRE_AALARM + ) + return ..() -/datum/wires/alarm/CanUse(var/mob/living/L) +/datum/wires/alarm/interactable(mob/user) var/obj/machinery/alarm/A = holder if(A.panel_open) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/alarm/GetInteractWindow() +/datum/wires/alarm/get_status() var/obj/machinery/alarm/A = holder - . += ..() - . += show_hint(0x1, A.locked, "The Air Alarm is locked.", "The Air Alarm is unlocked.") - . += show_hint(0x2, A.shorted || (A.stat & (NOPOWER|BROKEN)), "The Air Alarm is offline.", "The Air Alarm is working properly!") - . += show_hint(0x4, A.aidisabled, "The 'AI control allowed' light is off.", "The 'AI control allowed' light is on.") + . = ..() + . += "The Air Alarm is [A.locked ? "locked." : "unlocked."]" + . += "The Air Alarm is [(A.shorted || (A.stat & (NOPOWER|BROKEN))) ? "offline." : "working properly!"]" + . += "The 'AI control allowed' light is [A.aidisabled ? "off" : "on"]." -/datum/wires/alarm/UpdateCut(var/index, var/mended) +/datum/wires/alarm/on_cut(wire, mend) var/obj/machinery/alarm/A = holder - switch(index) - if(AALARM_WIRE_IDSCAN) - if(!mended) - A.locked = 1 - //to_world("Idscan wire cut") + switch(wire) + if(WIRE_IDSCAN) + if(!mend) + A.locked = TRUE - if(AALARM_WIRE_POWER) + if(WIRE_MAIN_POWER1) A.shock(usr, 50) - A.shorted = !mended + A.shorted = !mend A.update_icon() - //to_world("Power wire cut") - if (AALARM_WIRE_AI_CONTROL) - if (A.aidisabled == !mended) - A.aidisabled = mended - //to_world("AI Control Wire Cut") + if(WIRE_AI_CONTROL) + A.aidisabled = !mend - if(AALARM_WIRE_SYPHON) - if(!mended) - A.mode = 3 // AALARM_MODE_PANIC + if(WIRE_SYPHON) + if(!mend) + A.mode = 3 // MODE_PANIC A.apply_mode() - //to_world("Syphon Wire Cut") - if(AALARM_WIRE_AALARM) - if (A.alarm_area.atmosalert(2, A)) + if(WIRE_AALARM) + if(A.alarm_area.atmosalert(2, A)) A.post_alert(2) A.update_icon() + ..() -/datum/wires/alarm/UpdatePulsed(var/index) +/datum/wires/alarm/on_pulse(wire) var/obj/machinery/alarm/A = holder - switch(index) - if(AALARM_WIRE_IDSCAN) + switch(wire) + if(WIRE_IDSCAN) A.locked = !A.locked - // to_world("Idscan wire pulsed") - if (AALARM_WIRE_POWER) - // to_world("Power wire pulsed") - if(A.shorted == 0) - A.shorted = 1 + if(WIRE_MAIN_POWER1) + if(!A.shorted) + A.shorted = TRUE A.update_icon() spawn(12000) - if(A.shorted == 1) - A.shorted = 0 + if(A.shorted) + A.shorted = FALSE A.update_icon() - - if (AALARM_WIRE_AI_CONTROL) - // to_world("AI Control wire pulsed") - if (A.aidisabled == 0) - A.aidisabled = 1 + if(WIRE_AI_CONTROL) + if(!A.aidisabled) + A.aidisabled = TRUE A.updateDialog() spawn(100) - if (A.aidisabled == 1) - A.aidisabled = 0 + if(A.aidisabled) + A.aidisabled = FALSE - if(AALARM_WIRE_SYPHON) - // to_world("Syphon wire pulsed") - if(A.mode == 1) // AALARM_MODE_SCRUB - A.mode = 3 // AALARM_MODE_PANIC + if(WIRE_SYPHON) + if(A.mode == 1) // MODE_SCRUB + A.mode = 3 // MODE_PANIC else - A.mode = 1 // AALARM_MODE_SCRUB + A.mode = 1 // MODE_SCRUB A.apply_mode() - if(AALARM_WIRE_AALARM) - // to_world("Aalarm wire pulsed") - if (A.alarm_area.atmosalert(0, A)) + if(WIRE_AALARM) + if(A.alarm_area.atmosalert(0, A)) A.post_alert(0) A.update_icon() diff --git a/code/datums/wires/apc.dm b/code/datums/wires/apc.dm index 1b7f43d21fe..15e96298ad5 100644 --- a/code/datums/wires/apc.dm +++ b/code/datums/wires/apc.dm @@ -1,76 +1,66 @@ /datum/wires/apc holder_type = /obj/machinery/power/apc wire_count = 4 + proper_name = "APC" -#define APC_WIRE_IDSCAN 1 -#define APC_WIRE_MAIN_POWER1 2 -#define APC_WIRE_MAIN_POWER2 4 -#define APC_WIRE_AI_CONTROL 8 +/datum/wires/apc/New(atom/_holder) + wires = list(WIRE_IDSCAN, WIRE_MAIN_POWER1, WIRE_MAIN_POWER2, WIRE_AI_CONTROL) + return ..() -/datum/wires/apc/GetInteractWindow() +/datum/wires/apc/get_status() + . = ..() var/obj/machinery/power/apc/A = holder - . += ..() - . += show_hint(0x1, A.locked, "The APC is locked.", "The APC is unlocked.") - . += show_hint(0x2, A.shorted, "The APCs power has been shorted.", "The APC is working properly!") - . += show_hint(0x4, A.aidisabled, "The 'AI control allowed' light is off.", "The 'AI control allowed' light is on.") + . += "The APC is [A.locked ? "" : "un"]locked." + . += A.shorted ? "The APCs power has been shorted." : "The APC is working properly!" + . += "The 'AI control allowed' light is [A.aidisabled ? "off" : "on"]." - -/datum/wires/apc/CanUse(var/mob/living/L) +/datum/wires/apc/interactable(mob/user) var/obj/machinery/power/apc/A = holder if(A.wiresexposed) return 1 return 0 -/datum/wires/apc/UpdatePulsed(var/index) - +/datum/wires/apc/on_pulse(wire) var/obj/machinery/power/apc/A = holder - switch(index) - - if(APC_WIRE_IDSCAN) - A.locked = 0 + switch(wire) + if(WIRE_IDSCAN) + A.locked = FALSE spawn(300) if(A) - A.locked = 1 + A.locked = TRUE - if (APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2) - if(A.shorted == 0) - A.shorted = 1 + if(WIRE_MAIN_POWER1, WIRE_MAIN_POWER2) + if(!A.shorted) + A.shorted = TRUE spawn(1200) - if(A && !IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2)) - A.shorted = 0 + if(A && !is_cut(WIRE_MAIN_POWER1) && !is_cut(WIRE_MAIN_POWER2)) + A.shorted = FALSE - if (APC_WIRE_AI_CONTROL) - if (A.aidisabled == 0) - A.aidisabled = 1 + if(WIRE_AI_CONTROL) + if(!A.aidisabled) + A.aidisabled = TRUE spawn(10) - if(A && !IsIndexCut(APC_WIRE_AI_CONTROL)) - A.aidisabled = 0 + if(A && !is_cut(WIRE_AI_CONTROL)) + A.aidisabled = FALSE -/datum/wires/apc/UpdateCut(var/index, var/mended) +/datum/wires/apc/on_cut(wire, mend) var/obj/machinery/power/apc/A = holder - switch(index) - if(APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2) - - if(!mended) - if(istype(usr, /mob/living)) + switch(wire) + if(WIRE_MAIN_POWER1, WIRE_MAIN_POWER2) + if(!mend) + if(isliving(usr)) A.shock(usr, 50) - A.shorted = 1 + A.shorted = TRUE - else if(!IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2)) - A.shorted = 0 - if(istype(usr, /mob/living)) + else if(!is_cut(WIRE_MAIN_POWER1) && !is_cut(WIRE_MAIN_POWER2)) + A.shorted = FALSE + if(isliving(usr)) A.shock(usr, 50) - if(APC_WIRE_AI_CONTROL) - - if(!mended) - if (A.aidisabled == 0) - A.aidisabled = 1 - else - if (A.aidisabled == 1) - A.aidisabled = 0 + if(WIRE_AI_CONTROL) + A.aidisabled = !mend diff --git a/code/datums/wires/autolathe.dm b/code/datums/wires/autolathe.dm index df625351b8a..92f5f7facb8 100644 --- a/code/datums/wires/autolathe.dm +++ b/code/datums/wires/autolathe.dm @@ -1,61 +1,54 @@ /datum/wires/autolathe - holder_type = /obj/machinery/autolathe wire_count = 6 + proper_name = "Autolathe" -var/const/AUTOLATHE_HACK_WIRE = 1 -var/const/AUTOLATHE_SHOCK_WIRE = 2 -var/const/AUTOLATHE_DISABLE_WIRE = 4 +/datum/wires/autolathe/New(atom/_holder) + wires = list(WIRE_AUTOLATHE_HACK, WIRE_ELECTRIFY, WIRE_AUTOLATHE_DISABLE) + return ..() -/datum/wires/autolathe/GetInteractWindow() +/datum/wires/autolathe/get_status() + . = ..() var/obj/machinery/autolathe/A = holder - . += ..() - . += show_hint(0x1, A.disabled, "The red light is off.", "The red light is on.") - . += show_hint(0x2, A.shocked, "The green light is off.", "The green light is on.") - . += show_hint(0x4, A.hacked, "The blue light is off.", "The blue light is on.") + . += "The red light is [A.disabled ? "off" : "on"]." + . += "The green light is [A.shocked ? "off" : "on"]." + . += "The blue light is [A.hacked ? "off" : "on"]." -/datum/wires/autolathe/CanUse() +/datum/wires/autolathe/interactable(mob/user) var/obj/machinery/autolathe/A = holder if(A.panel_open) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/autolathe/proc/update_autolathe_ui(mob/living/user) - if(CanUse(user)) - var/obj/machinery/autolathe/A = holder - A.interact(user) - -/datum/wires/autolathe/UpdateCut(index, mended) +/datum/wires/autolathe/on_cut(wire, mend) var/obj/machinery/autolathe/A = holder - switch(index) - if(AUTOLATHE_HACK_WIRE) - A.hacked = !mended - if(AUTOLATHE_SHOCK_WIRE) - A.shocked = !mended - if(AUTOLATHE_DISABLE_WIRE) - A.disabled = !mended - update_autolathe_ui(usr) + switch(wire) + if(WIRE_AUTOLATHE_HACK) + A.hacked = !mend + if(WIRE_ELECTRIFY) + A.shocked = !mend + if(WIRE_AUTOLATHE_DISABLE) + A.disabled = !mend + ..() -/datum/wires/autolathe/UpdatePulsed(index) - if(IsIndexCut(index)) +/datum/wires/autolathe/on_pulse(wire) + if(is_cut(wire)) return var/obj/machinery/autolathe/A = holder - switch(index) - if(AUTOLATHE_HACK_WIRE) + switch(wire) + if(WIRE_AUTOLATHE_HACK) A.hacked = !A.hacked spawn(50) - if(A && !IsIndexCut(index)) + if(A && !is_cut(wire)) A.hacked = 0 - update_autolathe_ui(usr) - if(AUTOLATHE_SHOCK_WIRE) + if(WIRE_ELECTRIFY) A.shocked = !A.shocked spawn(50) - if(A && !IsIndexCut(index)) + if(A && !is_cut(wire)) A.shocked = 0 - if(AUTOLATHE_DISABLE_WIRE) + if(WIRE_AUTOLATHE_DISABLE) A.disabled = !A.disabled spawn(50) - if(A && !IsIndexCut(index)) + if(A && !is_cut(wire)) A.disabled = 0 - update_autolathe_ui(usr) - update_autolathe_ui(usr) + ..() \ No newline at end of file diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm index 67210e21796..571e2a22e6c 100644 --- a/code/datums/wires/camera.dm +++ b/code/datums/wires/camera.dm @@ -1,70 +1,64 @@ // Wires for cameras. /datum/wires/camera - random = 1 + randomize = TRUE holder_type = /obj/machinery/camera wire_count = 6 + proper_name = "Camera" -/datum/wires/camera/GetInteractWindow() +/datum/wires/camera/New(atom/_holder) + wires = list(WIRE_FOCUS, WIRE_MAIN_POWER1, WIRE_CAM_LIGHT, WIRE_CAM_ALARM) + return ..() + +/datum/wires/camera/get_status() . = ..() var/obj/machinery/camera/C = holder - . += show_hint(0x1, C.view_range == initial(C.view_range), "The focus light is on.", "The focus light is off.") - . += show_hint(0x2, C.can_use(), "The power link light is on.", "The power link light is off.") - . += show_hint(0x4, C.light_disabled, "The camera light is off.", "The camera light is on.") - . += show_hint(0x8, C.alarm_on, "The alarm light is on.", "The alarm light is off.") - return . + . += "The focus light is [(C.view_range == initial(C.view_range)) ? "on" : "off"]." + . += "The power link light is [C.can_use() ? "on" : "off"]." + . += "The camera light is [C.light_disabled ? "off" : "on"]." + . += "The alarm light is [C.alarm_on ? "on" : "off"]." -/datum/wires/camera/CanUse(var/mob/living/L) +/datum/wires/camera/interactable(mob/user) var/obj/machinery/camera/C = holder return C.panel_open -var/const/CAMERA_WIRE_FOCUS = 1 -var/const/CAMERA_WIRE_POWER = 2 -var/const/CAMERA_WIRE_LIGHT = 4 -var/const/CAMERA_WIRE_ALARM = 8 -var/const/CAMERA_WIRE_NOTHING1 = 16 -var/const/CAMERA_WIRE_NOTHING2 = 32 - -/datum/wires/camera/UpdateCut(var/index, var/mended) +/datum/wires/camera/on_cut(wire, mend) var/obj/machinery/camera/C = holder - switch(index) - if(CAMERA_WIRE_FOCUS) - var/range = (mended ? initial(C.view_range) : C.short_range) + switch(wire) + if(WIRE_FOCUS) + var/range = (mend ? initial(C.view_range) : C.short_range) C.setViewRange(range) - if(CAMERA_WIRE_POWER) - if(C.status && !mended || !C.status && mended) + if(WIRE_MAIN_POWER1) + if(C.status && !mend || !C.status && mend) C.deactivate(usr, 1) - if(CAMERA_WIRE_LIGHT) - C.light_disabled = !mended + if(WIRE_CAM_LIGHT) + C.light_disabled = !mend - if(CAMERA_WIRE_ALARM) - if(!mended) + if(WIRE_CAM_ALARM) + if(!mend) C.triggerCameraAlarm() else C.cancelCameraAlarm() - return + ..() -/datum/wires/camera/UpdatePulsed(var/index) +/datum/wires/camera/on_pulse(wire) var/obj/machinery/camera/C = holder - if(IsIndexCut(index)) + if(is_cut(wire)) return - switch(index) - if(CAMERA_WIRE_FOCUS) + switch(wire) + if(WIRE_FOCUS) var/new_range = (C.view_range == initial(C.view_range) ? C.short_range : initial(C.view_range)) C.setViewRange(new_range) - if(CAMERA_WIRE_LIGHT) + if(WIRE_CAM_LIGHT) C.light_disabled = !C.light_disabled - if(CAMERA_WIRE_ALARM) + if(WIRE_CAM_ALARM) C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*") - return + ..() /datum/wires/camera/proc/CanDeconstruct() - if(IsIndexCut(CAMERA_WIRE_POWER) && IsIndexCut(CAMERA_WIRE_FOCUS) && IsIndexCut(CAMERA_WIRE_LIGHT) && IsIndexCut(CAMERA_WIRE_NOTHING1) && IsIndexCut(CAMERA_WIRE_NOTHING2)) - return 1 - else - return 0 + return is_all_cut() diff --git a/code/datums/wires/explosive.dm b/code/datums/wires/explosive.dm index 6dc8e988ac0..52b0150b661 100644 --- a/code/datums/wires/explosive.dm +++ b/code/datums/wires/explosive.dm @@ -1,30 +1,33 @@ /datum/wires/explosive wire_count = 1 + proper_name = "Explosive wires" -var/const/WIRE_EXPLODE = 1 +/datum/wires/explosive/New(atom/_holder) + wires = list(WIRE_EXPLODE) + return ..() /datum/wires/explosive/proc/explode() return -/datum/wires/explosive/UpdatePulsed(var/index) - switch(index) +/datum/wires/explosive/on_pulse(wire) + switch(wire) if(WIRE_EXPLODE) explode() -/datum/wires/explosive/UpdateCut(var/index, var/mended) - switch(index) +/datum/wires/explosive/on_cut(wire, mend) + switch(wire) if(WIRE_EXPLODE) - if(!mended) + if(!mend) explode() /datum/wires/explosive/c4 holder_type = /obj/item/weapon/plastique -/datum/wires/explosive/c4/CanUse(var/mob/living/L) +/datum/wires/explosive/c4/interactable(mob/user) var/obj/item/weapon/plastique/P = holder if(P.open_panel) - return 1 - return 0 + return TRUE + return FALSE /datum/wires/explosive/c4/explode() var/obj/item/weapon/plastique/P = holder diff --git a/code/datums/wires/grid_checker.dm b/code/datums/wires/grid_checker.dm index 355f39ec189..42bc470e052 100644 --- a/code/datums/wires/grid_checker.dm +++ b/code/datums/wires/grid_checker.dm @@ -1,66 +1,64 @@ /datum/wires/grid_checker holder_type = /obj/machinery/power/grid_checker wire_count = 8 + proper_name = "Grid Checker" -var/const/GRID_CHECKER_WIRE_REBOOT = 1 // This wire causes the grid-check to end, if pulsed. -var/const/GRID_CHECKER_WIRE_LOCKOUT = 2 // If cut or pulsed, locks the user out for half a minute. -var/const/GRID_CHECKER_WIRE_ALLOW_MANUAL_1 = 4 // Needs to be cut for REBOOT to be possible. -var/const/GRID_CHECKER_WIRE_ALLOW_MANUAL_2 = 8 // Needs to be cut for REBOOT to be possible. -var/const/GRID_CHECKER_WIRE_ALLOW_MANUAL_3 = 16 // Needs to be cut for REBOOT to be possible. -var/const/GRID_CHECKER_WIRE_SHOCK = 32 // Shocks the user if not wearing gloves. -var/const/GRID_CHECKER_WIRE_NOTHING_1 = 64 // Does nothing, but makes it a bit harder. -var/const/GRID_CHECKER_WIRE_NOTHING_2 = 128 // Does nothing, but makes it a bit harder. +/datum/wires/grid_checker/New(atom/_holder) + wires = list( + WIRE_REBOOT, WIRE_LOCKOUT, WIRE_ALLOW_MANUAL1, + WIRE_ALLOW_MANUAL2, WIRE_ALLOW_MANUAL3, WIRE_ELECTRIFY + ) + return ..() - -/datum/wires/grid_checker/CanUse(var/mob/living/L) +/datum/wires/grid_checker/interactable(mob/user) var/obj/machinery/power/grid_checker/G = holder if(G.opened) return TRUE return FALSE - -/datum/wires/grid_checker/GetInteractWindow() +/datum/wires/grid_checker/get_status() var/obj/machinery/power/grid_checker/G = holder - . += ..() - . += show_hint(0x1, G.power_failing, "The green light is off.", "The green light is on.") - . += show_hint(0x2, G.wire_locked_out, "The red light is on.", "The red light is off.") - . += show_hint(0x4, G.wire_allow_manual_1 && G.wire_allow_manual_2 && G.wire_allow_manual_3, "The blue light is on.", "The blue light is off.") + . = ..() + . += "The green light is [G.power_failing ? "off." : "on."]" + . += "The red light is [G.wire_locked_out ? "on." : "off."]" + . += "The blue light is [(G.wire_allow_manual_1 && G.wire_allow_manual_2 && G.wire_allow_manual_3) ? "on." : "off."]" - -/datum/wires/grid_checker/UpdateCut(var/index, var/mended) +/datum/wires/grid_checker/on_cut(wire, mend) var/obj/machinery/power/grid_checker/G = holder - switch(index) - if(GRID_CHECKER_WIRE_LOCKOUT) - G.wire_locked_out = !mended - if(GRID_CHECKER_WIRE_ALLOW_MANUAL_1) - G.wire_allow_manual_1 = !mended - if(GRID_CHECKER_WIRE_ALLOW_MANUAL_2) - G.wire_allow_manual_2 = !mended - if(GRID_CHECKER_WIRE_ALLOW_MANUAL_3) - G.wire_allow_manual_3 = !mended - if(GRID_CHECKER_WIRE_SHOCK) + switch(wire) + if(WIRE_LOCKOUT) + G.wire_locked_out = !mend + if(WIRE_ALLOW_MANUAL1) + G.wire_allow_manual_1 = !mend + if(WIRE_ALLOW_MANUAL2) + G.wire_allow_manual_2 = !mend + if(WIRE_ALLOW_MANUAL3) + G.wire_allow_manual_3 = !mend + if(WIRE_ELECTRIFY) if(G.wire_locked_out) return G.shock(usr, 70) + ..() - -/datum/wires/grid_checker/UpdatePulsed(var/index) +/datum/wires/grid_checker/on_pulse(wire) var/obj/machinery/power/grid_checker/G = holder - switch(index) - if(GRID_CHECKER_WIRE_REBOOT) + switch(wire) + if(WIRE_REBOOT) if(G.wire_locked_out) return - if(G.power_failing && G.wire_allow_manual_1 && G.wire_allow_manual_2 && G.wire_allow_manual_3) G.end_power_failure(TRUE) - if(GRID_CHECKER_WIRE_LOCKOUT) + + if(WIRE_LOCKOUT) if(G.wire_locked_out) return G.wire_locked_out = TRUE spawn(30 SECONDS) G.wire_locked_out = FALSE - if(GRID_CHECKER_WIRE_SHOCK) + + if(WIRE_ELECTRIFY) if(G.wire_locked_out) return - G.shock(usr, 70) \ No newline at end of file + G.shock(usr, 70) + ..() \ No newline at end of file diff --git a/code/datums/wires/jukebox.dm b/code/datums/wires/jukebox.dm index e207334ffd4..125bbd78ef8 100644 --- a/code/datums/wires/jukebox.dm +++ b/code/datums/wires/jukebox.dm @@ -1,42 +1,39 @@ /datum/wires/jukebox - random = 1 + randomize = TRUE holder_type = /obj/machinery/media/jukebox wire_count = 11 + proper_name = "Jukebox" -var/const/WIRE_POWER = 1 -var/const/WIRE_HACK = 2 -var/const/WIRE_SPEEDUP = 4 -var/const/WIRE_SPEEDDOWN = 8 -var/const/WIRE_REVERSE = 16 -var/const/WIRE_NOTHING1 = 32 -var/const/WIRE_NOTHING2 = 64 -var/const/WIRE_START = 128 -var/const/WIRE_STOP = 256 -var/const/WIRE_PREV = 512 -var/const/WIRE_NEXT = 1024 +/datum/wires/jukebox/New(atom/_holder) + wires = list( + WIRE_MAIN_POWER1, WIRE_JUKEBOX_HACK, + WIRE_SPEEDUP, WIRE_SPEEDDOWN, WIRE_REVERSE, + WIRE_START, WIRE_STOP, WIRE_PREV, WIRE_NEXT + ) + return ..() -/datum/wires/jukebox/CanUse(var/mob/living/L) +/datum/wires/jukebox/interactable(mob/user) var/obj/machinery/media/jukebox/A = holder if(A.panel_open) - return 1 - return 0 + return TRUE + return FALSE // Show the status of lights as a hint to the current state -/datum/wires/jukebox/GetInteractWindow() +/datum/wires/jukebox/get_status() var/obj/machinery/media/jukebox/A = holder - . += ..() - . += show_hint(0x1, A.stat & (BROKEN|NOPOWER), "The power light is off.", "The power light is on.") - . += show_hint(0x2, A.hacked, "The parental guidance light is off.", "The parental guidance light is on.") - . += show_hint(0x4, IsIndexCut(WIRE_REVERSE), "The data light is hauntingly dark.", "The data light is glowing softly.") + . = ..() + . += "The power light is [A.stat & (BROKEN|NOPOWER) ? "off." : "on."]" + . += "The parental guidance light is [A.hacked ? "off." : "on."]" + . += "The data light is [is_cut(WIRE_REVERSE) ? "hauntingly dark." : "glowing softly."]" // Give a hint as to what each wire does -/datum/wires/jukebox/UpdatePulsed(var/index) +/datum/wires/jukebox/on_pulse(wire) var/obj/machinery/media/jukebox/A = holder - switch(index) - if(WIRE_POWER) + switch(wire) + if(WIRE_MAIN_POWER1) holder.visible_message("[bicon(holder)] The power light flickers.") A.shock(usr, 90) - if(WIRE_HACK) + if(WIRE_JUKEBOX_HACK) holder.visible_message("[bicon(holder)] The parental guidance light flickers.") if(WIRE_REVERSE) holder.visible_message("[bicon(holder)] The data light blinks ominously.") @@ -55,24 +52,21 @@ var/const/WIRE_NEXT = 1024 else A.shock(usr, 10) // The nothing wires give a chance to shock just for fun -/datum/wires/jukebox/UpdateCut(var/index, var/mended) +/datum/wires/jukebox/on_cut(wire, mend) var/obj/machinery/media/jukebox/A = holder - switch(index) - if(WIRE_POWER) + switch(wire) + if(WIRE_MAIN_POWER1) // TODO - Actually make machine electrified or something. A.shock(usr, 90) - if(WIRE_HACK) - if(mended) - A.set_hacked(0) - else - A.set_hacked(1) + if(WIRE_JUKEBOX_HACK) + A.set_hacked(!mend) if(WIRE_SPEEDUP, WIRE_SPEEDDOWN, WIRE_REVERSE) - var/newfreq = IsIndexCut(WIRE_REVERSE) ? -1 : 1; - if (IsIndexCut(WIRE_SPEEDUP)) + var/newfreq = is_cut(WIRE_REVERSE) ? -1 : 1; + if(is_cut(WIRE_SPEEDUP)) newfreq *= 2 - if (IsIndexCut(WIRE_SPEEDDOWN)) + if(is_cut(WIRE_SPEEDDOWN)) newfreq *= 0.5 A.freq = newfreq diff --git a/code/datums/wires/mines.dm b/code/datums/wires/mines.dm index 372810988cc..209fcc4c307 100644 --- a/code/datums/wires/mines.dm +++ b/code/datums/wires/mines.dm @@ -1,32 +1,29 @@ /datum/wires/mines wire_count = 6 - random = 1 + randomize = TRUE holder_type = /obj/effect/mine + proper_name = "Explosive Wires" -#define WIRE_DETONATE 1 -#define WIRE_TIMED_DET 2 -#define WIRE_DISARM 4 -#define WIRE_DUMMY_1 8 -#define WIRE_DUMMY_2 16 -#define WIRE_BADDISARM 32 +/datum/wires/mines/New(atom/_holder) + wires = list(WIRE_EXPLODE, WIRE_EXPLODE_DELAY, WIRE_DISARM, WIRE_BADDISARM) + return ..() -/datum/wires/mines/GetInteractWindow() +/datum/wires/mines/get_status() . = ..() - . += "
\n["Warning: detonation may occur even with proper equipment."]" - return . + . += "\[Warning: detonation may occur even with proper equipment.]" /datum/wires/mines/proc/explode() return -/datum/wires/mines/UpdateCut(var/index, var/mended) +/datum/wires/mines/on_cut(wire, mend) var/obj/effect/mine/C = holder - switch(index) - if(WIRE_DETONATE) + switch(wire) + if(WIRE_EXPLODE) C.visible_message("[bicon(C)] *BEEE-*", "[bicon(C)] *BEEE-*") C.explode() - if(WIRE_TIMED_DET) + if(WIRE_EXPLODE_DELAY) C.visible_message("[bicon(C)] *BEEE-*", "[bicon(C)] *BEEE-*") C.explode() @@ -35,30 +32,22 @@ new C.mineitemtype(get_turf(C)) spawn(0) qdel(C) - return - - if(WIRE_DUMMY_1) - return - - - if(WIRE_DUMMY_2) - return if(WIRE_BADDISARM) C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*") spawn(20) C.explode() - return + ..() -/datum/wires/mines/UpdatePulsed(var/index) +/datum/wires/mines/on_pulse(wire) var/obj/effect/mine/C = holder - if(IsIndexCut(index)) + if(is_cut(wire)) return - switch(index) - if(WIRE_DETONATE) + switch(wire) + if(WIRE_EXPLODE) C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*") - if(WIRE_TIMED_DET) + if(WIRE_EXPLODE_DELAY) C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*") spawn(20) C.explode() @@ -66,16 +55,10 @@ if(WIRE_DISARM) C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*") - if(WIRE_DUMMY_1) - C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*") - - if(WIRE_DUMMY_2) - C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*") - if(WIRE_BADDISARM) C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*") - return + ..() -/datum/wires/mines/CanUse(var/mob/living/L) +/datum/wires/mines/interactable(mob/user) var/obj/effect/mine/M = holder return M.panel_open diff --git a/code/datums/wires/particle_accelerator.dm b/code/datums/wires/particle_accelerator.dm index 3d90236b462..e3fd198b3ba 100644 --- a/code/datums/wires/particle_accelerator.dm +++ b/code/datums/wires/particle_accelerator.dm @@ -1,52 +1,48 @@ /datum/wires/particle_acc/control_box wire_count = 5 holder_type = /obj/machinery/particle_accelerator/control_box + proper_name = "Particle accelerator control" -var/const/PARTICLE_TOGGLE_WIRE = 1 // Toggles whether the PA is on or not. -var/const/PARTICLE_STRENGTH_WIRE = 2 // Determines the strength of the PA. -var/const/PARTICLE_INTERFACE_WIRE = 4 // Determines the interface showing up. -var/const/PARTICLE_LIMIT_POWER_WIRE = 8 // Determines how strong the PA can be. -//var/const/PARTICLE_NOTHING_WIRE = 16 // Blank wire +/datum/wires/particle_acc/control_box/New(atom/_holder) + wires = list(WIRE_PARTICLE_POWER, WIRE_PARTICLE_STRENGTH, WIRE_PARTICLE_INTERFACE, WIRE_PARTICLE_POWER_LIMIT) + return ..() -/datum/wires/particle_acc/control_box/CanUse(var/mob/living/L) +/datum/wires/particle_acc/control_box/interactable(mob/user) var/obj/machinery/particle_accelerator/control_box/C = holder if(C.construction_state == 2) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/particle_acc/control_box/UpdatePulsed(var/index) +/datum/wires/particle_acc/control_box/on_pulse(wire) var/obj/machinery/particle_accelerator/control_box/C = holder - switch(index) - - if(PARTICLE_TOGGLE_WIRE) + switch(wire) + if(WIRE_PARTICLE_POWER) C.toggle_power() - if(PARTICLE_STRENGTH_WIRE) + if(WIRE_PARTICLE_STRENGTH) C.add_strength() - if(PARTICLE_INTERFACE_WIRE) + if(WIRE_PARTICLE_INTERFACE) C.interface_control = !C.interface_control - if(PARTICLE_LIMIT_POWER_WIRE) + if(WIRE_PARTICLE_POWER_LIMIT) C.visible_message("[bicon(C)][C] makes a large whirring noise.") -/datum/wires/particle_acc/control_box/UpdateCut(var/index, var/mended) +/datum/wires/particle_acc/control_box/on_cut(wire, mend) var/obj/machinery/particle_accelerator/control_box/C = holder - switch(index) - - if(PARTICLE_TOGGLE_WIRE) - if(C.active == !mended) + switch(wire) + if(WIRE_PARTICLE_POWER) + if(C.active == !mend) C.toggle_power() - if(PARTICLE_STRENGTH_WIRE) - + if(WIRE_PARTICLE_STRENGTH) for(var/i = 1; i < 3; i++) C.remove_strength() - if(PARTICLE_INTERFACE_WIRE) - C.interface_control = mended + if(WIRE_PARTICLE_INTERFACE) + C.interface_control = mend - if(PARTICLE_LIMIT_POWER_WIRE) - C.strength_upper_limit = (mended ? 2 : 3) + if(WIRE_PARTICLE_POWER_LIMIT) + C.strength_upper_limit = (mend ? 2 : 3) if(C.strength_upper_limit < C.strength) C.remove_strength() diff --git a/code/datums/wires/radio.dm b/code/datums/wires/radio.dm index d059a0b0919..ddc51108392 100644 --- a/code/datums/wires/radio.dm +++ b/code/datums/wires/radio.dm @@ -1,41 +1,42 @@ /datum/wires/radio holder_type = /obj/item/device/radio wire_count = 3 + proper_name = "Radio" -var/const/WIRE_SIGNAL = 1 -var/const/WIRE_RECEIVE = 2 -var/const/WIRE_TRANSMIT = 4 +/datum/wires/radio/New(atom/_holder) + wires = list(WIRE_RADIO_SIGNAL, WIRE_RADIO_RECEIVER, WIRE_RADIO_TRANSMIT) + return ..() -/datum/wires/radio/CanUse(var/mob/living/L) +/datum/wires/radio/interactable(mob/user) var/obj/item/device/radio/R = holder if(R.b_stat) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/radio/UpdatePulsed(var/index) +/datum/wires/radio/on_pulse(wire) var/obj/item/device/radio/R = holder - switch(index) - if(WIRE_SIGNAL) - R.listening = !R.listening && !IsIndexCut(WIRE_RECEIVE) - R.broadcasting = R.listening && !IsIndexCut(WIRE_TRANSMIT) + switch(wire) + if(WIRE_RADIO_SIGNAL) + R.listening = !R.listening && !is_cut(WIRE_RADIO_RECEIVER) + R.broadcasting = R.listening && !is_cut(WIRE_RADIO_TRANSMIT) - if(WIRE_RECEIVE) - R.listening = !R.listening && !IsIndexCut(WIRE_SIGNAL) + if(WIRE_RADIO_RECEIVER) + R.listening = !R.listening && !is_cut(WIRE_RADIO_SIGNAL) - if(WIRE_TRANSMIT) - R.broadcasting = !R.broadcasting && !IsIndexCut(WIRE_SIGNAL) - SSnanoui.update_uis(holder) + if(WIRE_RADIO_TRANSMIT) + R.broadcasting = !R.broadcasting && !is_cut(WIRE_RADIO_SIGNAL) + ..() -/datum/wires/radio/UpdateCut(var/index, var/mended) +/datum/wires/radio/on_cut(wire, mend) var/obj/item/device/radio/R = holder - switch(index) - if(WIRE_SIGNAL) - R.listening = mended && !IsIndexCut(WIRE_RECEIVE) - R.broadcasting = mended && !IsIndexCut(WIRE_TRANSMIT) + switch(wire) + if(WIRE_RADIO_SIGNAL) + R.listening = mend && !is_cut(WIRE_RADIO_RECEIVER) + R.broadcasting = mend && !is_cut(WIRE_RADIO_TRANSMIT) - if(WIRE_RECEIVE) - R.listening = mended && !IsIndexCut(WIRE_SIGNAL) + if(WIRE_RADIO_RECEIVER) + R.listening = mend && !is_cut(WIRE_RADIO_SIGNAL) - if(WIRE_TRANSMIT) - R.broadcasting = mended && !IsIndexCut(WIRE_SIGNAL) - SSnanoui.update_uis(holder) + if(WIRE_RADIO_TRANSMIT) + R.broadcasting = mend && !is_cut(WIRE_RADIO_SIGNAL) + ..() diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm index ed87a2b1fe6..7beb91437e4 100644 --- a/code/datums/wires/robot.dm +++ b/code/datums/wires/robot.dm @@ -1,76 +1,63 @@ /datum/wires/robot - random = 1 + randomize = TRUE holder_type = /mob/living/silicon/robot wire_count = 5 + proper_name = "Cyborg" -var/const/BORG_WIRE_LAWCHECK = 1 -var/const/BORG_WIRE_MAIN_POWER = 2 // The power wires do nothing whyyyyyyyyyyyyy -var/const/BORG_WIRE_LOCKED_DOWN = 4 -var/const/BORG_WIRE_AI_CONTROL = 8 -var/const/BORG_WIRE_CAMERA = 16 +/datum/wires/robot/New(atom/_holder) + wires = list(WIRE_AI_CONTROL, WIRE_BORG_CAMERA, WIRE_BORG_LAWCHECK, WIRE_BORG_LOCKED) + return ..() -/datum/wires/robot/GetInteractWindow() +/datum/wires/robot/get_status() . = ..() var/mob/living/silicon/robot/R = holder - . += show_hint(0x1, R.lawupdate, "The LawSync light is on.", "The LawSync light is off.") - . += show_hint(0x2, R.connected_ai, "The AI link light is on.", "The AI link light is off.") - . += show_hint(0x4, (!isnull(R.camera) && R.camera.status == 1), "The camera light is on.", "The camera light is off.") - . += show_hint(0x8, R.lockdown, "The lockdown light is on.", "The lockdown light is off.") - return . - -/datum/wires/robot/UpdateCut(var/index, var/mended) + . += "The LawSync light is [R.lawupdate ? "on" : "off"]." + . += "The AI link light is [R.connected_ai ? "on" : "off"]." + . += "The Camera light is [(R.camera && R.camera.status == 1) ? "on" : "off"]." + . += "The lockdown light is [R.lockcharge ? "on" : "off"]." +/datum/wires/robot/on_cut(wire, mend) var/mob/living/silicon/robot/R = holder - switch(index) - if(BORG_WIRE_LAWCHECK) //Cut the law wire, and the borg will no longer receive law updates from its AI - if(!mended) - if (R.lawupdate == 1) + switch(wire) + if(WIRE_BORG_LAWCHECK) //Cut the law wire, and the borg will no longer receive law updates from its AI + if(!mend) + if(R.lawupdate) to_chat(R, "LawSync protocol engaged.") + R.lawsync() R.show_laws() else - if (R.lawupdate == 0 && !R.emagged) - R.lawupdate = 1 + if(!R.lawupdate && !R.emagged) + R.lawupdate = TRUE - if (BORG_WIRE_AI_CONTROL) //Cut the AI wire to reset AI control - if(!mended) + if(WIRE_AI_CONTROL) //Cut the AI wire to reset AI control + if(!mend) R.disconnect_from_ai() - if (BORG_WIRE_CAMERA) + if(WIRE_BORG_CAMERA) if(!isnull(R.camera) && !R.scrambledcodes) - R.camera.status = mended + R.camera.status = mend - if(BORG_WIRE_LAWCHECK) //Forces a law update if the borg is set to receive them. Since an update would happen when the borg checks its laws anyway, not much use, but eh - if (R.lawupdate) - R.lawsync() + if(WIRE_BORG_LOCKED) + R.SetLockdown(!mend) + ..() - if(BORG_WIRE_LOCKED_DOWN) - R.SetLockdown(!mended) - - -/datum/wires/robot/UpdatePulsed(var/index) +/datum/wires/robot/on_pulse(wire) var/mob/living/silicon/robot/R = holder - switch(index) - if (BORG_WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI + switch(wire) + if(WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI if(!R.emagged) - var/mob/living/silicon/ai/new_ai = select_active_ai(R) - R.connect_to_ai(new_ai) + R.connect_to_ai(select_active_ai(R)) - if (BORG_WIRE_CAMERA) + if(WIRE_BORG_CAMERA) if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes) R.visible_message("[R]'s camera lense focuses loudly.") to_chat(R, "Your camera lense focuses loudly.") - if(BORG_WIRE_LOCKED_DOWN) + if(WIRE_BORG_LOCKED) R.SetLockdown(!R.lockdown) // Toggle -/datum/wires/robot/CanUse(var/mob/living/L) +/datum/wires/robot/interactable(mob/user) var/mob/living/silicon/robot/R = holder if(R.wiresexposed) - return 1 - return 0 - -/datum/wires/robot/proc/IsCameraCut() - return wires_status & BORG_WIRE_CAMERA - -/datum/wires/robot/proc/LockedCut() - return wires_status & BORG_WIRE_LOCKED_DOWN + return TRUE + return FALSE diff --git a/code/datums/wires/seedstorage.dm b/code/datums/wires/seedstorage.dm index 2a0e315a572..19414b67314 100644 --- a/code/datums/wires/seedstorage.dm +++ b/code/datums/wires/seedstorage.dm @@ -1,56 +1,58 @@ -#define SEED_WIRE_SMART 1 -#define SEED_WIRE_CONTRABAND 2 -#define SEED_WIRE_ELECTRIFY 4 -#define SEED_WIRE_LOCKDOWN 8 - /datum/wires/seedstorage holder_type = /obj/machinery/seed_storage wire_count = 4 - random = 1 + randomize = TRUE + proper_name = "Seed Storage" -/datum/wires/seedstorage/CanUse(var/mob/living/L) +/datum/wires/seedstorage/New(atom/_holder) + wires = list(WIRE_SEED_SMART, WIRE_CONTRABAND, WIRE_ELECTRIFY, WIRE_SEED_LOCKDOWN) + return ..() + +/datum/wires/seedstorage/interactable(mob/user) var/obj/machinery/seed_storage/V = holder if(V.panel_open) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/seedstorage/GetInteractWindow() +/datum/wires/seedstorage/get_status() var/obj/machinery/seed_storage/V = holder - . += ..() - . += show_hint(0x1, V.seconds_electrified, "The orange light is off.", "The orange light is on.") - . += show_hint(0x2, V.smart, "The red light is off.", "The red light is blinking.") - . += show_hint(0x4, V.hacked || V.emagged, "The green light is on.", "The green light is off.") - . += show_hint(0x8, V.lockdown, "The keypad lock is deployed.", "The keypad lock is retracted.") + . = ..() + . += "The orange light is [V.seconds_electrified ? "off." : "on."]" + . += "The red light is [V.smart ? "off." : "blinking."]" + . += "The green light is [(V.hacked || V.emagged) ? "on." : "off."]" + . += "The keypad lock light is [V.lockdown ? "deployed." : "retracted."]" -/datum/wires/seedstorage/UpdatePulsed(var/index) +/datum/wires/seedstorage/on_pulse(wire) var/obj/machinery/seed_storage/V = holder - switch(index) - if(SEED_WIRE_SMART) + switch(wire) + if(WIRE_SEED_SMART) V.smart = !V.smart - if(SEED_WIRE_CONTRABAND) + if(WIRE_CONTRABAND) V.hacked = !V.hacked - if(SEED_WIRE_ELECTRIFY) + if(WIRE_ELECTRIFY) V.seconds_electrified = 30 - if(SEED_WIRE_LOCKDOWN) + if(WIRE_SEED_LOCKDOWN) V.lockdown = !V.lockdown + ..() -/datum/wires/seedstorage/UpdateCut(var/index, var/mended) +/datum/wires/seedstorage/on_cut(wire, mend) var/obj/machinery/seed_storage/V = holder - switch(index) - if(SEED_WIRE_SMART) - V.smart = 0 - if(SEED_WIRE_CONTRABAND) - V.hacked = !mended - if(SEED_WIRE_ELECTRIFY) - if(mended) + switch(wire) + if(WIRE_SEED_SMART) + V.smart = FALSE + if(WIRE_CONTRABAND) + V.hacked = !mend + if(WIRE_ELECTRIFY) + if(mend) V.seconds_electrified = 0 else V.seconds_electrified = -1 - if(SEED_WIRE_LOCKDOWN) - if(mended) - V.lockdown = 1 + if(WIRE_SEED_LOCKDOWN) + if(mend) + V.lockdown = TRUE V.req_access = list() V.req_one_access = list() else V.req_access = initial(V.req_access) V.req_one_access = initial(V.req_one_access) + ..() \ No newline at end of file diff --git a/code/datums/wires/shield_generator.dm b/code/datums/wires/shield_generator.dm index 201109de359..9ba0293591c 100644 --- a/code/datums/wires/shield_generator.dm +++ b/code/datums/wires/shield_generator.dm @@ -1,46 +1,47 @@ /datum/wires/shield_generator holder_type = /obj/machinery/power/shield_generator wire_count = 5 + proper_name = "Shield Generator" -var/const/SHIELDGEN_WIRE_POWER = 1 // Cut to disable power input into the generator. Pulse does nothing. Mend to restore. -var/const/SHIELDGEN_WIRE_HACK = 2 // Pulse to hack the generator, enabling hacked modes. Cut to unhack. Mend does nothing. -var/const/SHIELDGEN_WIRE_CONTROL = 4 // Cut to lock most shield controls. Mend to unlock them. Pulse does nothing. -var/const/SHIELDGEN_WIRE_AICONTROL = 8 // Cut to disable AI control. Mend to restore. -var/const/SHIELDGEN_WIRE_NOTHING = 16 // A blank wire that doesn't have any specific function +/datum/wires/shield_generator/New(atom/_holder) + wires = list(WIRE_MAIN_POWER1, WIRE_CONTRABAND, WIRE_AI_CONTROL, WIRE_SHIELD_CONTROL) + return ..() -/datum/wires/shield_generator/CanUse(var/mob/living/L) +/datum/wires/shield_generator/interactable(mob/user) var/obj/machinery/power/shield_generator/S = holder if(S.panel_open) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/shield_generator/GetInteractWindow() +/datum/wires/shield_generator/get_status() var/obj/machinery/power/shield_generator/S = holder - . += ..() - . += show_hint(0x1, S.mode_changes_locked, "The orange light is on.", "The orange light is off.") - . += show_hint(0x2, S.ai_control_disabled, "The blue light is off.", "The blue light is blinking.") - . += show_hint(0x4, S.hacked, "The violet light is pulsing.", "The violet light is steady.") - . += show_hint(0x8, S.input_cut, "The red light is off.", "The red light is on.") + . = ..() + . += "The orange light is [S.mode_changes_locked ? "on." : "off."]" + . += "The blue light is [S.ai_control_disabled ? "off." : "blinking."]" + . += "The violet light is [S.hacked ? "pulsing." : "steady."]" + . += "The red light is [S.input_cut ? "off." : "on."]" -/datum/wires/shield_generator/UpdateCut(index, mended) +/datum/wires/shield_generator/on_cut(wire, mend) var/obj/machinery/power/shield_generator/S = holder - switch(index) - if(SHIELDGEN_WIRE_POWER) - S.input_cut = !mended - if(SHIELDGEN_WIRE_HACK) - if(!mended) - S.hacked = 0 + switch(wire) + if(WIRE_MAIN_POWER1) + S.input_cut = !mend + if(WIRE_CONTRABAND) + if(!mend) + S.hacked = FALSE if(S.check_flag(MODEFLAG_BYPASS)) S.toggle_flag(MODEFLAG_BYPASS) if(S.check_flag(MODEFLAG_OVERCHARGE)) S.toggle_flag(MODEFLAG_OVERCHARGE) - if(SHIELDGEN_WIRE_CONTROL) - S.mode_changes_locked = !mended - if(SHIELDGEN_WIRE_AICONTROL) - S.ai_control_disabled = !mended + if(WIRE_SHIELD_CONTROL) + S.mode_changes_locked = !mend + if(WIRE_AI_CONTROL) + S.ai_control_disabled = !mend + ..() -/datum/wires/shield_generator/UpdatePulsed(var/index) +/datum/wires/shield_generator/on_pulse(wire) var/obj/machinery/power/shield_generator/S = holder - switch(index) - if(SHIELDGEN_WIRE_HACK) - S.hacked = 1 \ No newline at end of file + switch(wire) + if(WIRE_CONTRABAND) + S.hacked = TRUE + ..() \ No newline at end of file diff --git a/code/datums/wires/smartfridge.dm b/code/datums/wires/smartfridge.dm index f69e153bbf6..78b82939e26 100644 --- a/code/datums/wires/smartfridge.dm +++ b/code/datums/wires/smartfridge.dm @@ -1,47 +1,52 @@ /datum/wires/smartfridge holder_type = /obj/machinery/smartfridge wire_count = 3 + proper_name = "Smartfridge" + +/datum/wires/smartfridge/New(atom/_holder) + wires = list(WIRE_ELECTRIFY, WIRE_IDSCAN, WIRE_THROW_ITEM) + return ..() /datum/wires/smartfridge/secure - random = 1 - wire_count = 4 + randomize = TRUE + wire_count = 4 // 3 actual, 1 dud. -var/const/SMARTFRIDGE_WIRE_ELECTRIFY = 1 -var/const/SMARTFRIDGE_WIRE_THROW = 2 -var/const/SMARTFRIDGE_WIRE_IDSCAN = 4 - -/datum/wires/smartfridge/CanUse(var/mob/living/L) +/datum/wires/smartfridge/interactable(mob/user) var/obj/machinery/smartfridge/S = holder + if(iscarbon(user) && S.Adjacent(user) && S.seconds_electrified && S.shock(user, 100)) + return FALSE if(S.panel_open) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/smartfridge/GetInteractWindow() +/datum/wires/smartfridge/get_status() + . = ..() var/obj/machinery/smartfridge/S = holder - . += ..() - . += show_hint(0x1, S.seconds_electrified, "The orange light is off.", "The orange light is on.") - . += show_hint(0x2, S.shoot_inventory, "The red light is off.", "The red light is blinking.") - . += show_hint(0x4, S.scan_id, "A purple light is on.", "A yellow light is on.") + . += "The orange light is [S.seconds_electrified ? "off" : "on"]." + . += "The red light is [S.shoot_inventory ? "off" : "blinking"]." + . += "A [S.scan_id ? "purple" : "yellow"] light is on." -/datum/wires/smartfridge/UpdatePulsed(var/index) +/datum/wires/smartfridge/on_pulse(wire) var/obj/machinery/smartfridge/S = holder - switch(index) - if(SMARTFRIDGE_WIRE_THROW) + switch(wire) + if(WIRE_THROW_ITEM) S.shoot_inventory = !S.shoot_inventory - if(SMARTFRIDGE_WIRE_ELECTRIFY) + if(WIRE_ELECTRIFY) S.seconds_electrified = 30 - if(SMARTFRIDGE_WIRE_IDSCAN) + if(WIRE_IDSCAN) S.scan_id = !S.scan_id + ..() -/datum/wires/smartfridge/UpdateCut(var/index, var/mended) +/datum/wires/smartfridge/on_cut(wire, mend) var/obj/machinery/smartfridge/S = holder - switch(index) - if(SMARTFRIDGE_WIRE_THROW) - S.shoot_inventory = !mended - if(SMARTFRIDGE_WIRE_ELECTRIFY) - if(mended) + switch(wire) + if(WIRE_THROW_ITEM) + S.shoot_inventory = !mend + if(WIRE_ELECTRIFY) + if(mend) S.seconds_electrified = 0 else S.seconds_electrified = -1 - if(SMARTFRIDGE_WIRE_IDSCAN) - S.scan_id = 1 + if(WIRE_IDSCAN) + S.scan_id = TRUE + ..() diff --git a/code/datums/wires/smes.dm b/code/datums/wires/smes.dm index 1751bb67602..ad63c125228 100644 --- a/code/datums/wires/smes.dm +++ b/code/datums/wires/smes.dm @@ -1,59 +1,57 @@ /datum/wires/smes holder_type = /obj/machinery/power/smes/buildable wire_count = 5 + proper_name = "SMES" -var/const/SMES_WIRE_RCON = 1 // Remote control (AI and consoles), cut to disable -var/const/SMES_WIRE_INPUT = 2 // Input wire, cut to disable input, pulse to disable for 60s -var/const/SMES_WIRE_OUTPUT = 4 // Output wire, cut to disable output, pulse to disable for 60s -var/const/SMES_WIRE_GROUNDING = 8 // Cut to quickly discharge causing sparks, pulse to only create few sparks -var/const/SMES_WIRE_FAILSAFES = 16 // Cut to disable failsafes, mend to reenable +/datum/wires/smes/New(atom/_holder) + wires = list(WIRE_SMES_RCON, WIRE_SMES_INPUT, WIRE_SMES_OUTPUT, WIRE_SMES_GROUNDING, WIRE_SMES_FAILSAFES) + return ..() - -/datum/wires/smes/CanUse(var/mob/living/L) +/datum/wires/smes/interactable(mob/user) var/obj/machinery/power/smes/buildable/S = holder if(S.panel_open) - return 1 - return 0 + return TRUE + return FALSE - -/datum/wires/smes/GetInteractWindow() +/datum/wires/smes/get_status() var/obj/machinery/power/smes/buildable/S = holder - . += ..() - . += show_hint(0x1, S.input_cut || S.input_pulsed || S.output_cut || S.output_pulsed, "The green light is off.", "The green light is on.") - . += show_hint(0x2, S.safeties_enabled || S.grounding, "The red light is off.", "The red light is blinking.") - . += show_hint(0x4, S.RCon, "The blue light is on.", "The blue light is off.") + . = ..() + . += "The green light is [(S.input_cut || S.input_pulsed || S.output_cut || S.output_pulsed) ? "off" : "on"]." + . += "The red light is [(S.safeties_enabled || S.grounding) ? "off" : "blinking"]." + . += "The blue light is [S.RCon ? "on" : "off"]." -/datum/wires/smes/UpdateCut(var/index, var/mended) +/datum/wires/smes/on_cut(wire, mend) var/obj/machinery/power/smes/buildable/S = holder - switch(index) - if(SMES_WIRE_RCON) - S.RCon = mended - if(SMES_WIRE_INPUT) - S.input_cut = !mended - if(SMES_WIRE_OUTPUT) - S.output_cut = !mended - if(SMES_WIRE_GROUNDING) - S.grounding = mended - if(SMES_WIRE_FAILSAFES) - S.safeties_enabled = mended + switch(wire) + if(WIRE_SMES_RCON) + S.RCon = mend + if(WIRE_SMES_INPUT) + S.input_cut = !mend + if(WIRE_SMES_OUTPUT) + S.output_cut = !mend + if(WIRE_SMES_GROUNDING) + S.grounding = mend + if(WIRE_SMES_FAILSAFES) + S.safeties_enabled = mend + ..() - -/datum/wires/smes/UpdatePulsed(var/index) +/datum/wires/smes/on_pulse(wire) var/obj/machinery/power/smes/buildable/S = holder - switch(index) - if(SMES_WIRE_RCON) + switch(wire) + if(WIRE_SMES_RCON) if(S.RCon) S.RCon = 0 spawn(10) S.RCon = 1 - if(SMES_WIRE_INPUT) + if(WIRE_SMES_INPUT) S.toggle_input() - if(SMES_WIRE_OUTPUT) + if(WIRE_SMES_OUTPUT) S.toggle_output() - if(SMES_WIRE_GROUNDING) + if(WIRE_SMES_GROUNDING) S.grounding = 0 - if(SMES_WIRE_FAILSAFES) + if(WIRE_SMES_FAILSAFES) if(S.safeties_enabled) S.safeties_enabled = 0 spawn(10) - S.safeties_enabled = 1 \ No newline at end of file + S.safeties_enabled = 1 + ..() \ No newline at end of file diff --git a/code/datums/wires/suit_storage_unit.dm b/code/datums/wires/suit_storage_unit.dm index fe694d271a3..97d3f98c841 100644 --- a/code/datums/wires/suit_storage_unit.dm +++ b/code/datums/wires/suit_storage_unit.dm @@ -1,47 +1,46 @@ /datum/wires/suit_storage_unit holder_type = /obj/machinery/suit_cycler wire_count = 3 + proper_name = "Suit storage unit" -var/const/SUIT_STORAGE_WIRE_ELECTRIFY = 1 -var/const/SUIT_STORAGE_WIRE_SAFETY = 2 -var/const/SUIT_STORAGE_WIRE_LOCKED = 4 +/datum/wires/suit_storage_unit/New(atom/_holder) + wires = list(WIRE_IDSCAN, WIRE_ELECTRIFY, WIRE_SAFETY) + return ..() -/datum/wires/suit_storage_unit/CanUse(var/mob/living/L) +/datum/wires/suit_storage_unit/interactable(mob/user) var/obj/machinery/suit_cycler/S = holder - if(!istype(L, /mob/living/silicon)) - if(S.electrified) - if(S.shock(L, 100)) - return 0 + if(iscarbon(user) && S.Adjacent(user) && S.electrified) + return !S.shock(user, 100) if(S.panel_open) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/suit_storage_unit/GetInteractWindow() - var/obj/machinery/suit_cycler/S = holder - . += ..() - . += show_hint(0x1, S.electrified, "The orange light is off.", "The orange light is on.") - . += show_hint(0x2, S.safeties, "The red light is off.", "The red light is blinking.") - . += show_hint(0x4, S.locked, "The yellow light is on.", "The yellow light is off.") +/datum/wires/suit_storage_unit/get_status() + . = ..() + var/obj/machinery/suit_cycler/A = holder + . += "The orange light is [A.electrified ? "off" : "on"]." + . += "The red light is [A.safeties ? "off" : "blinking"]." + . += "The yellow light is [A.locked ? "on" : "off"]." -/datum/wires/suit_storage_unit/UpdatePulsed(var/index) +/datum/wires/suit_storage_unit/on_pulse(wire) var/obj/machinery/suit_cycler/S = holder - switch(index) - if(SUIT_STORAGE_WIRE_SAFETY) + switch(wire) + if(WIRE_SAFETY) S.safeties = !S.safeties - if(SUIT_STORAGE_WIRE_ELECTRIFY) + if(WIRE_ELECTRIFY) S.electrified = 30 - if(SUIT_STORAGE_WIRE_LOCKED) + if(WIRE_IDSCAN) S.locked = !S.locked -/datum/wires/suit_storage_unit/UpdateCut(var/index, var/mended) +/datum/wires/suit_storage_unit/on_cut(wire, mend) var/obj/machinery/suit_cycler/S = holder - switch(index) - if(SUIT_STORAGE_WIRE_SAFETY) - S.safeties = mended - if(SUIT_STORAGE_WIRE_LOCKED) - S.locked = mended - if(SUIT_STORAGE_WIRE_ELECTRIFY) - if(mended) + switch(wire) + if(WIRE_SAFETY) + S.safeties = mend + if(WIRE_IDSCAN) + S.locked = mend + if(WIRE_ELECTRIFY) + if(mend) S.electrified = 0 else S.electrified = -1 diff --git a/code/datums/wires/tesla_coil.dm b/code/datums/wires/tesla_coil.dm index f176b8f1397..30f15539b7e 100644 --- a/code/datums/wires/tesla_coil.dm +++ b/code/datums/wires/tesla_coil.dm @@ -1,18 +1,21 @@ /datum/wires/tesla_coil wire_count = 1 holder_type = /obj/machinery/power/tesla_coil + proper_name = "Tesla coil" -var/const/WIRE_ZAP = 1 +/datum/wires/tesla_coil/New(atom/_holder) + wires = list(WIRE_TESLACOIL_ZAP) + return ..() -/datum/wires/tesla_coil/CanUse(mob/living/L) +/datum/wires/tesla_coil/interactable(mob/user) var/obj/machinery/power/tesla_coil/T = holder if(T && T.panel_open) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/tesla_coil/UpdatePulsed(index) +/datum/wires/tesla_coil/on_pulse(wire) var/obj/machinery/power/tesla_coil/T = holder - switch(index) - if(WIRE_ZAP) + switch(wire) + if(WIRE_TESLACOIL_ZAP) T.zap() ..() diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm index 61aadf4b1bc..33dc26f2415 100644 --- a/code/datums/wires/vending.dm +++ b/code/datums/wires/vending.dm @@ -1,49 +1,53 @@ /datum/wires/vending holder_type = /obj/machinery/vending wire_count = 4 + proper_name = "Vending machine" -var/const/VENDING_WIRE_THROW = 1 -var/const/VENDING_WIRE_CONTRABAND = 2 -var/const/VENDING_WIRE_ELECTRIFY = 4 -var/const/VENDING_WIRE_IDSCAN = 8 +/datum/wires/vending/New(atom/_holder) + wires = list(WIRE_THROW_ITEM, WIRE_IDSCAN, WIRE_ELECTRIFY, WIRE_CONTRABAND) + return ..() -/datum/wires/vending/CanUse(var/mob/living/L) +/datum/wires/vending/interactable(mob/user) var/obj/machinery/vending/V = holder + if(iscarbon(user) && V.seconds_electrified && V.shock(user, 100)) + return FALSE if(V.panel_open) - return 1 - return 0 + return TRUE + return FALSE -/datum/wires/vending/GetInteractWindow() +/datum/wires/vending/get_status() var/obj/machinery/vending/V = holder - . += ..() - . += show_hint(0x1, V.seconds_electrified, "The orange light is off.", "The orange light is on.") - . += show_hint(0x2, V.shoot_inventory, "The red light is off.", "The red light is blinking.") - . += show_hint(0x4, V.categories & CAT_HIDDEN, "A green light is on.", "A green light is off.") - . += show_hint(0x8, V.scan_id, "A purple light is on.", "A yellow light is on.") + . = ..() + . += "The orange light is [V.seconds_electrified ? "on" : "off"]." + . += "The red light is [V.shoot_inventory ? "off" : "blinking"]." + . += "The green light is [(V.categories & CAT_HIDDEN) ? "on" : "off"]." + . += "A [V.scan_id ? "purple" : "yellow"] light is on." -/datum/wires/vending/UpdatePulsed(var/index) +/datum/wires/vending/on_pulse(wire) var/obj/machinery/vending/V = holder - switch(index) - if(VENDING_WIRE_THROW) + switch(wire) + if(WIRE_THROW_ITEM) V.shoot_inventory = !V.shoot_inventory - if(VENDING_WIRE_CONTRABAND) + if(WIRE_CONTRABAND) V.categories ^= CAT_HIDDEN - if(VENDING_WIRE_ELECTRIFY) + if(WIRE_ELECTRIFY) V.seconds_electrified = 30 - if(VENDING_WIRE_IDSCAN) + if(WIRE_IDSCAN) V.scan_id = !V.scan_id + ..() -/datum/wires/vending/UpdateCut(var/index, var/mended) +/datum/wires/vending/on_cut(wire, mend) var/obj/machinery/vending/V = holder - switch(index) - if(VENDING_WIRE_THROW) - V.shoot_inventory = !mended - if(VENDING_WIRE_CONTRABAND) + switch(wire) + if(WIRE_THROW_ITEM) + V.shoot_inventory = !mend + if(WIRE_CONTRABAND) V.categories &= ~CAT_HIDDEN - if(VENDING_WIRE_ELECTRIFY) - if(mended) + if(WIRE_ELECTRIFY) + if(mend) V.seconds_electrified = 0 else V.seconds_electrified = -1 - if(VENDING_WIRE_IDSCAN) + if(WIRE_IDSCAN) V.scan_id = 1 + ..() \ No newline at end of file diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 645d7cc0435..83ebb65fa8f 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -1,340 +1,460 @@ -// Wire datums. Created by Giacomand. -// Was created to replace a horrible case of copy and pasted code with no care for maintability. -// Goodbye Door wires, Cyborg wires, Vending Machine wires, Autolathe wires -// Protolathe wires, APC wires and Camera wires! - -#define MAX_FLAG 65535 - -var/list/same_wires = list() -// 14 colours, if you're adding more than 14 wires then add more colours here -var/list/wireColours = list("red", "blue", "green", "darkred", "orange", "brown", "gold", "gray", "cyan", "navy", "purple", "pink", "black", "yellow") /datum/wires + /// TRUE if the wires will be different every time a new wire datum is created. + var/randomize = FALSE + /// The atom the wires belong too. For example: an airlock. + var/atom/holder + /// The holder type; used to make sure that the holder is the correct type. + var/holder_type + /// The display name for the TGUI window. For example, given the var is "APC"... + /// When the TGUI window is opened, "wires" will be appended to it's title, and it would become "APC wires". + var/proper_name = "Unknown" + /// The total number of wires that our holder atom has. + var/wire_count = NONE + /// A list of all wires. For a list of valid wires defines that can go here, see `code/__DEFINES/wires.dm` + var/list/wires + /// A list of all cut wires. The same values that can go into `wires` will get added and removed from this list. + var/list/cut_wires + /// An associative list with the wire color as the key, and the wire define as the value. + var/list/colors + /// An associative list of signalers attached to the wires. The wire color is the key, and the signaler object reference is the value. + var/list/assemblies - var/random = 0 // Will the wires be different for every single instance. - var/atom/holder = null // The holder - var/holder_type = null // The holder type; used to make sure that the holder is the correct type. - var/wire_count = 0 // Max is 16 - var/wires_status = 0 // BITFLAG OF WIRES - - var/hint_states = 0 // BITFLAG OF HINT STATES (For tracking if they changed for bolding in UI) - var/hint_states_initialized = FALSE // False until first time window is rendered. - - var/list/wires = list() - var/list/signallers = list() - - var/table_options = " align='center'" - var/row_options1 = " width='80px'" - var/row_options2 = " width='260px'" - var/window_x = 370 - var/window_y = 470 - -// Note: Its assumed states are boolean. If you ever have a multi-state hint, you must implement that yourself. -/datum/wires/proc/show_hint(flag, current_state, true_text, false_text) - var/state_changed = FALSE - if(hint_states_initialized) - if(!(hint_states & flag) != !current_state) // NOT-ing to convert to boolean - state_changed = TRUE - if(current_state) - hint_states |= flag - return state_changed ? "
[true_text]" : "
[true_text]" - else - hint_states &= ~flag - return state_changed ? "
[false_text]" : "
[false_text]" - -/datum/wires/New(var/atom/holder) +/datum/wires/New(atom/_holder) ..() - src.holder = holder - if(!istype(holder, holder_type)) + if(!istype(_holder, holder_type)) CRASH("Our holder is null/the wrong type!") + + holder = _holder + cut_wires = list() + colors = list() + assemblies = list() + + // Add in the appropriate amount of dud wires. + var/wire_len = length(wires) + if(wire_len < wire_count) // If the amount of "real" wires is less than the total we're suppose to have... + add_duds(wire_count - wire_len) // Add in the appropriate amount of duds to reach `wire_count`. + + // If the randomize is true, we need to generate a new set of wires and ignore any wire color directories. + if(randomize) + randomize() return - // Generate new wires - if(random) - GenerateWires() - // Get the same wires + if(!GLOB.wire_color_directory[holder_type]) + randomize() + GLOB.wire_color_directory[holder_type] = colors else - // We don't have any wires to copy yet, generate some and then copy it. - if(!same_wires[holder_type]) - GenerateWires() - same_wires[holder_type] = src.wires.Copy() - else - var/list/wires = same_wires[holder_type] - src.wires = wires // Reference the wires list. + colors = GLOB.wire_color_directory[holder_type] /datum/wires/Destroy() holder = null - signallers.Cut() + for(var/color in colors) + detach_assembly(color) return ..() -/datum/wires/proc/GenerateWires() - var/list/colours_to_pick = wireColours.Copy() // Get a copy, not a reference. - var/list/indexes_to_pick = list() - //Generate our indexes - for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i) - indexes_to_pick += i - colours_to_pick.len = wire_count // Downsize it to our specifications. +/** + * Randomly generates a new set of wires. and corresponding colors from the given pool. Assigns the information as an associative list, to `colors`. + * + * In the `colors` list, the name of the color is the key, and the wire is the value. + * For example: `colors["red"] = WIRE_ELECTRIFY`. This will look like `list("red" = WIRE_ELECTRIFY)` internally. + */ +/datum/wires/proc/randomize() + var/static/list/possible_colors = list("red", "blue", "green", "darkmagenta", "orange", "brown", "gold", "grey", "cyan", "white", "purple", "pink", "darkslategrey", "yellow") + var/list/my_possible_colors = possible_colors.Copy() - while(colours_to_pick.len && indexes_to_pick.len) - // Pick and remove a colour - var/colour = pick_n_take(colours_to_pick) + for(var/wire in shuffle(wires)) + colors[pick_n_take(my_possible_colors)] = wire - // Pick and remove an index - var/index = pick_n_take(indexes_to_pick) +/** + * Proc called when the user attempts to interact with wires UI. + * + * Checks if the user exists, is a mob, the wires are attached to something (`holder`) and makes sure `interactable(user)` returns TRUE. + * If all the checks succeed, open the TGUI interface for the user. + * + * Arugments: + * * user - the mob trying to interact with the wires. + */ +/datum/wires/proc/Interact(mob/user) + if(user && istype(user) && holder && interactable(user)) + tgui_interact(user) - src.wires[colour] = index - //wires = shuffle(wires) +/** + * Base proc, intended to be overriden. Wire datum specific checks you want to run before the TGUI is shown to the user should go here. + */ +/datum/wires/proc/interactable(mob/user) + return TRUE +/// Users will be interacting with our holder object and not the wire datum directly, therefore we need to return the holder. +/datum/wires/tgui_host() + return holder -/datum/wires/proc/Interact(var/mob/living/user) +/datum/wires/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Wires", "[proper_name] wires") + ui.open() - var/html = null - if(holder && CanUse(user)) - html = GetInteractWindow() - hint_states_initialized = TRUE - if(html) - user.set_machine(holder) - else - user.unset_machine() - // No content means no window. - user << browse(null, "window=wires") +/datum/wires/tgui_state(mob/user) + return GLOB.tgui_physical_state + +/datum/wires/tgui_data(mob/user) + var/list/data = list() + var/list/replace_colors + + if(isliving(user)) + var/mob/living/L = user + for(var/datum/modifier/M in L.modifiers) + if(!isnull(M.wire_colors_replace)) + replace_colors = M.wire_colors_replace + break + + var/list/wires_list = list() + + for(var/color in colors) + var/replaced_color = color + var/color_name = color + + if(color in replace_colors) // If this color is one that needs to be replaced using the colorblindness list. + replaced_color = replace_colors[color] + if(replaced_color in LIST_COLOR_RENAME) // If its an ugly written color name like "darkolivegreen", rename it to something like "dark green". + color_name = LIST_COLOR_RENAME[replaced_color] + else + color_name = replaced_color // Else just keep the normal color name + + if(color in LIST_COLOR_RENAME) + color_name = LIST_COLOR_RENAME[color] + + wires_list += list(list( + "seen_color" = replaced_color, // The color of the wire that the mob will see. This will be the same as `color` if the user is NOT colorblind. + "color_name" = color_name, // The wire's name. This will be the same as `color` if the user is NOT colorblind. + "color" = color, // The "real" color of the wire. No replacements. + "wire" = can_see_wire_info(user) && !is_dud_color(color) ? get_wire(color) : null, // Wire define information like "Contraband" or "Door Bolts". + "cut" = is_color_cut(color), // Whether the wire is cut or not. Used to display "cut" or "mend". + "attached" = is_attached(color) // Whether or not a signaler is attached to this wire. + )) + data["wires"] = wires_list + + // Get the information shown at the bottom of wire TGUI window, such as "The red light is blinking", etc. + // If the user is colorblind, we need to replace these colors as well. + var/list/status = get_status() + + if(replace_colors) + var/i + for(i in 1 to length(status)) + for(var/color in replace_colors) + var/new_color = replace_colors[color] + if(new_color in LIST_COLOR_RENAME) + new_color = LIST_COLOR_RENAME[new_color] + if(findtext(status[i], color)) + status[i] = replacetext(status[i], color, new_color) + break + + data["status"] = status + return data + +/datum/wires/tgui_act(action, list/params) + if(..()) + return TRUE + + var/mob/user = usr + if(!interactable(user)) return - var/datum/browser/popup = new(user, "wires", holder.name, window_x, window_y) - popup.set_content(html) - popup.set_title_image(user.browse_rsc_icon(holder.icon, holder.icon_state)) - popup.open() + var/obj/item/I = user.get_active_hand() + var/color = lowertext(params["wire"]) + holder.add_hiddenprint(user) -/datum/wires/proc/GetInteractWindow() - var/html = "
" - html += "

Exposed Wires

" - html += "" + switch(action) + // Toggles the cut/mend status. + if("cut") + // if(!I.is_wirecutter() && !user.can_admin_interact()) + if(!istype(I) || !I.is_wirecutter()) + to_chat(user, "You need wirecutters!") + return - for(var/colour in wires) - html += "" - html += "[capitalize(colour)]" - html += "" - html += "[IsColourCut(colour) ? "Mend" : "Cut"]" - html += " Pulse" - html += " [IsAttached(colour) ? "Detach" : "Attach"] Signaller" - html += "" - html += "
" + playsound(holder, I.usesound, 20, 1) + cut_color(color) + return TRUE - if (random) - html += "\The [holder] appears to have tamper-resistant electronics installed.

" //maybe this could be more generic? + // Pulse a wire. + if("pulse") + // if(!I.is_multitool() && !user.can_admin_interact()) + if(!istype(I) || !I.is_multitool()) + to_chat(user, "You need a multitool!") + return - return html + playsound(holder, 'sound/weapons/empty.ogg', 20, 1) + pulse_color(color) -/datum/wires/Topic(href, href_list) - ..() - if(in_range(holder, usr) && isliving(usr)) + // If they pulse the electrify wire, call interactable() and try to shock them. + if(get_wire(color) == WIRE_ELECTRIFY) + interactable(user) - var/mob/living/L = usr - if(CanUse(L) && href_list["action"]) - holder.add_hiddenprint(L) + return TRUE - var/list/items = L.get_all_held_items() - var/success = FALSE + // Attach a signaler to a wire. + if("attach") + if(is_attached(color)) + var/obj/item/O = detach_assembly(color) + if(O) + user.put_in_hands(O) + return TRUE - if(href_list["cut"]) // Toggles the cut/mend status - for(var/obj/item/I in items) // Paranoid about someone somehow grabbing a non-/obj/item, lets play it safe. - if(I.is_wirecutter()) - var/colour = href_list["cut"] - CutWireColour(colour) - playsound(holder, I.usesound, 20, 1) - success = TRUE - break - if(!success) - to_chat(L, span("warning", "You need wirecutters!")) + if(!istype(I, /obj/item/device/assembly/signaler)) + to_chat(user, "You need a remote signaller!") + return - else if(href_list["pulse"]) - for(var/obj/item/I in items) - if(I.is_multitool()) - var/colour = href_list["pulse"] - PulseColour(colour) - playsound(holder, 'sound/weapons/empty.ogg', 20, 1) - success = TRUE - break - if(!success) - to_chat(L, span("warning", "You need a multitool!")) + if(user.unEquip(I)) + attach_assembly(color, I) + return TRUE + else + to_chat(user, "[I] is stuck to your hand!") - else if(href_list["attach"]) - var/colour = href_list["attach"] - // Detach - if(IsAttached(colour)) - var/obj/item/O = Detach(colour) - if(O) - L.put_in_hands(O) +/** + * Proc called to determine if the user can see wire define information, such as "Contraband", "Door Bolts", etc. + * + * If the user is an admin, or has a multitool which reveals wire information in their active hand, the proc returns TRUE. + * + * Arguments: + * * user - the mob who is interacting with the wires. + */ +/datum/wires/proc/can_see_wire_info(mob/user) + // TODO: Reimplement this if we ever get Advanced Admin Interaction. + // if(user.can_admin_interact()) + // return TRUE + var/obj/item/I = user.get_active_hand() + if(istype(I, /obj/item/device/multitool/alien)) + return TRUE + return FALSE - // Attach - else - var/obj/item/device/assembly/signaler/S = L.is_holding_item_of_type(/obj/item/device/assembly/signaler) - if(istype(S)) - L.drop_from_inventory(S) - Attach(colour, S) - else - to_chat(L, span("warning", "You need a remote signaller!")) +/** + * Base proc, intended to be overwritten. Put wire information you'll see at the botton of the TGUI window here, such as "The red light is blinking". + */ +/datum/wires/proc/get_status() + return list() +/** + * Clears the `colors` list, and randomizes it to a new set of color-to-wire relations. + */ +/datum/wires/proc/shuffle_wires() + colors.Cut() + randomize() +/** + * Repairs all cut wires. + */ +/datum/wires/proc/repair() + cut_wires.Cut() +/** + * Adds in dud wires, which do nothing when cut/pulsed. + * + * Arguments: + * * duds - the amount of dud wires to generate. + */ +/datum/wires/proc/add_duds(duds) + while(duds) + var/dud = WIRE_DUD_PREFIX + "[--duds]" + if(dud in wires) + continue + wires += dud - // Update Window - Interact(usr) +/** + * Determines if the passed in wire is a dud or not. Returns TRUE if the wire is a dud, FALSE otherwise. + * + * Arugments: + * * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`. + */ +/datum/wires/proc/is_dud(wire) + return findtext(wire, WIRE_DUD_PREFIX, 1, length(WIRE_DUD_PREFIX) + 1) - if(href_list["close"]) - usr << browse(null, "window=wires") - usr.unset_machine(holder) +/** + * Returns TRUE if the wire that corresponds to the passed in color is a dud. FALSE otherwise. + * + * Arugments: + * * color - a wire color. + */ +/datum/wires/proc/is_dud_color(color) + return is_dud(get_wire(color)) -// -// Overridable Procs -// +/** + * Gets the wire associated with the color passed in. + * + * Arugments: + * * color - a wire color. + */ +/datum/wires/proc/get_wire(color) + return colors[color] -// Called when wires cut/mended. -/datum/wires/proc/UpdateCut(var/index, var/mended) - return +/** + * Determines if the passed in wire is cut or not. Returns TRUE if it's cut, FALSE otherwise. + * + * Arugments: + * * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`. + */ +/datum/wires/proc/is_cut(wire) + return (wire in cut_wires) -// Called when wire pulsed. Add code here. -/datum/wires/proc/UpdatePulsed(var/index) - return +/** + * Determines if the wire associated with the passed in color, is cut or not. Returns TRUE if it's cut, FALSE otherwise. + * + * Arugments: + * * wire - a wire color. + */ +/datum/wires/proc/is_color_cut(color) + return is_cut(get_wire(color)) -/datum/wires/proc/CanUse(var/mob/living/L) - return 1 +/** + * Determines if all of the wires are cut. Returns TRUE they're all cut, FALSE otherwise. + */ +/datum/wires/proc/is_all_cut() + return (length(cut_wires) == length(wires)) -// Example of use: -/* - -var/const/BOLTED= 1 -var/const/SHOCKED = 2 -var/const/SAFETY = 4 -var/const/POWER = 8 - -/datum/wires/door/UpdateCut(var/index, var/mended) - var/obj/machinery/door/airlock/A = holder - switch(index) - if(BOLTED) - if(!mended) - A.bolt() - if(SHOCKED) - A.shock() - if(SAFETY ) - A.safety() - -*/ - - -// -// Helper Procs -// - -/datum/wires/proc/PulseColour(var/colour) - PulseIndex(GetIndex(colour)) - -/datum/wires/proc/PulseIndex(var/index) - if(IsIndexCut(index)) - return - UpdatePulsed(index) - -/datum/wires/proc/GetIndex(var/colour) - if(wires[colour]) - var/index = wires[colour] - return index +/** + * Cut or mend a wire. Calls `on_cut()`. + * + * Arugments: + * * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`. + */ +/datum/wires/proc/cut(wire) + if(is_cut(wire)) + cut_wires -= wire + on_cut(wire, mend = TRUE) else - CRASH("[colour] is not a key in wires.") + cut_wires += wire + on_cut(wire, mend = FALSE) -// -// Is Index/Colour Cut procs -// +/** + * Cut the wire which corresponds with the passed in color. + * + * Arugments: + * * color - a wire color. + */ +/datum/wires/proc/cut_color(color) + cut(get_wire(color)) -/datum/wires/proc/IsColourCut(var/colour) - var/index = GetIndex(colour) - return IsIndexCut(index) +/** + * Cuts a random wire. + */ +/datum/wires/proc/cut_random() + cut(wires[rand(1, length(wires))]) -/datum/wires/proc/IsIndexCut(var/index) - return (index & wires_status) +/** + * Cuts all wires. + */ +/datum/wires/proc/cut_all() + for(var/wire in wires) + cut(wire) -// -// Signaller Procs -// +/** + * Proc called when any wire is cut. + * + * Base proc, intended to be overriden. + * Place an behavior you want to happen when certain wires are cut, into this proc. + * + * Arugments: + * * wire - a wire define, NOT color. For example 'WIRE_ELECTRIFY'. + * * mend - TRUE if we're mending the wire. FALSE if we're cutting. + */ +/datum/wires/proc/on_cut(wire, mend = FALSE) + return -/datum/wires/proc/IsAttached(var/colour) - if(signallers[colour]) - return 1 - return 0 +/** + * Pulses the given wire. Calls `on_pulse()`. + * + * Arugments: + * * wire - a wire define, NOT a color. For example `WIRE_ELECTRIFY`. + */ +/datum/wires/proc/pulse(wire) + if(is_cut(wire)) + return + on_pulse(wire) -/datum/wires/proc/GetAttached(var/colour) - if(signallers[colour]) - return signallers[colour] +/** + * Pulses the wire associated with the given color. + * + * Arugments: + * * wire - a wire color. + */ +/datum/wires/proc/pulse_color(color) + pulse(get_wire(color)) + +/** + * Proc called when any wire is pulsed. + * + * Base proc, intended to be overriden. + * Place behavior you want to happen when certain wires are pulsed, into this proc. + * + * Arugments: + * * wire - a wire define, NOT color. For example 'WIRE_ELECTRIFY'. + */ +/datum/wires/proc/on_pulse(wire) + return + +/** + * Proc called when an attached signaler receives a signal. + * + * Searches through the `assemblies` list for the wire that the signaler is attached to. Pulses the wire when it's found. + * + * Arugments: + * * S - the attached signaler receiving the signal. + */ +/datum/wires/proc/pulse_assembly(obj/item/device/assembly/signaler/S) + for(var/color in assemblies) + if(S == assemblies[color]) + pulse_color(color) + return TRUE + +/** + * Proc called when a mob tries to attach a signaler to a wire. + * + * Makes sure that `S` is actually a signaler and that something is not already attached to the wire. + * Adds the signaler to the `assemblies` list as a value, with the `color` as a the key. + * + * Arguments: + * * color - the wire color. + * * S - the signaler that a mob is trying to attach. + */ +/datum/wires/proc/attach_assembly(color, obj/item/device/assembly/signaler/S) + if(S && istype(S) && !is_attached(color)) + assemblies[color] = S + S.forceMove(holder) + S.connected = src + return S + +/** + * Proc called when a mob tries to detach a signaler from a wire. + * + * First checks if there is a signaler on the wire. If so, removes the signaler, and clears it from `assemblies` list. + * + * Arguments: + * * color - the wire color. + */ +/datum/wires/proc/detach_assembly(color) + var/obj/item/device/assembly/signaler/S = get_attached(color) + if(S && istype(S)) + assemblies -= color + S.connected = null + S.forceMove(holder.drop_location()) + return S + +/** + * Gets the signaler attached to the given wire color, if there is one. + * + * Arguments: + * * color - the wire color. + */ +/datum/wires/proc/get_attached(color) + if(assemblies[color]) + return assemblies[color] return null -/datum/wires/proc/Attach(var/colour, var/obj/item/device/assembly/signaler/S) - if(colour && S) - if(!IsAttached(colour)) - signallers[colour] = S - S.loc = holder - S.connected = src - return S - -/datum/wires/proc/Detach(var/colour) - if(colour) - var/obj/item/device/assembly/signaler/S = GetAttached(colour) - if(S) - signallers -= colour - S.connected = null - S.loc = holder.loc - return S - - -/datum/wires/proc/Pulse(var/obj/item/device/assembly/signaler/S) - - for(var/colour in signallers) - if(S == signallers[colour]) - PulseColour(colour) - break - - -// -// Cut Wire Colour/Index procs -// - -/datum/wires/proc/CutWireColour(var/colour) - var/index = GetIndex(colour) - CutWireIndex(index) - -/datum/wires/proc/CutWireIndex(var/index) - if(IsIndexCut(index)) - wires_status &= ~index - UpdateCut(index, 1) - else - wires_status |= index - UpdateCut(index, 0) - -/datum/wires/proc/RandomCut() - var/r = rand(1, wires.len) - CutWireIndex(r) - -/datum/wires/proc/RandomCutAll(var/probability = 10) - for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i) - if(prob(probability)) - CutWireIndex(i) - -/datum/wires/proc/CutAll() - for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i) - CutWireIndex(i) - -/datum/wires/proc/IsAllCut() - if(wires_status == (1 << wire_count) - 1) - return 1 - return 0 - -/datum/wires/proc/MendAll() - for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i) - if(IsIndexCut(i)) - CutWireIndex(i) - -// -//Shuffle and Mend -// - -/datum/wires/proc/Shuffle() - wires_status = 0 - GenerateWires() +/** + * Checks if the given wire has a signaler on it. + * + * Arguments: + * * color - the wire color. + */ +/datum/wires/proc/is_attached(color) + if(assemblies[color]) + return TRUE diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index d5202bafc2c..568eb0f743e 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -143,7 +143,7 @@ /proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message, var/channel = "Common", var/zlevel) if (ticker.current_state == GAME_STATE_PLAYING) - var/list/zlevels = zlevel ? using_map.get_map_levels(zlevel, TRUE) : null + var/list/zlevels = zlevel ? using_map.get_map_levels(zlevel, TRUE, om_range = DEFAULT_OVERMAP_RANGE) : null if(character.mind.role_alt_title) rank = character.mind.role_alt_title AnnounceArrivalSimple(character.real_name, rank, join_message, channel, zlevels) diff --git a/code/game/antagonist/antagonist_update.dm b/code/game/antagonist/antagonist_update.dm index 16c27f82c7e..b118cb91db8 100644 --- a/code/game/antagonist/antagonist_update.dm +++ b/code/game/antagonist/antagonist_update.dm @@ -15,7 +15,7 @@ spawn(3) var/mob/living/carbon/human/H = player.current if(istype(H)) - H.change_appearance(APPEARANCE_ALL, H.loc, H, species_whitelist = valid_species, state = z_state) + H.change_appearance(APPEARANCE_ALL, H, species_whitelist = valid_species, state = GLOB.tgui_self_state) return player.current /datum/antagonist/proc/update_access(var/mob/living/player) diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index d9c1ec53ea7..4d4533b4b31 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -31,6 +31,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station power_environ = 0 base_turf = /turf/space ambience = AMBIENCE_SPACE + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/space/atmosalert() return @@ -68,7 +69,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/shuttle requires_power = 0 - flags = RAD_SHIELDED + flags = RAD_SHIELDED | AREA_FLAG_IS_NOT_PERSISTENT sound_env = SMALL_ENCLOSED base_turf = /turf/space forbid_events = TRUE @@ -201,6 +202,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "\improper Alien base" icon_state = "yellow" requires_power = 0 + flags = AREA_FLAG_IS_NOT_PERSISTENT // CENTCOM @@ -209,6 +211,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "centcom" requires_power = 0 dynamic_lighting = 0 + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/centcom/control name = "\improper CentCom Control" @@ -286,6 +289,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station requires_power = 0 dynamic_lighting = 0 ambience = AMBIENCE_HIGHSEC + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/syndicate_mothership/control name = "\improper Mercenary Control Room" @@ -302,6 +306,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station icon_state = "asteroid" requires_power = 0 sound_env = ASTEROID + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/asteroid/cave // -- TLE name = "\improper Moon - Underground" @@ -325,6 +330,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station requires_power = 0 dynamic_lighting = 0 sound_env = ARENA + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/tdome/tdome1 name = "\improper Thunderdome (Team 1)" @@ -352,6 +358,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station flags = RAD_SHIELDED base_turf = /turf/space ambience = AMBIENCE_HIGHSEC + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/syndicate_station/start name = "\improper Mercenary Forward Operating Base" @@ -407,6 +414,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station requires_power = 0 dynamic_lighting = 0 ambience = AMBIENCE_OTHERWORLDLY + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/skipjack_station name = "\improper Skipjack" @@ -414,6 +422,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station requires_power = 0 base_turf = /turf/space ambience = AMBIENCE_HIGHSEC + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/skipjack_station/start name = "\improper Skipjack" @@ -448,6 +457,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "\improper Prison Station" icon_state = "brig" ambience = AMBIENCE_HIGHSEC + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/prison/arrival_airlock name = "\improper Prison Station Airlock" @@ -633,6 +643,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/maintenance/disposal name = "Waste Disposal" icon_state = "disposal" + flags = AREA_FLAG_IS_NOT_PERSISTENT //If trash items got this far, they can be safely deleted. /area/maintenance/engineering name = "Engineering Maintenance" @@ -946,10 +957,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/crew_quarters/heads/hop name = "\improper Command - HoP's Office" icon_state = "head_quarters" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/crew_quarters/heads/hor name = "\improper Research - RD's Office" icon_state = "head_quarters" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/crew_quarters/heads/chief name = "\improper Engineering - CE's Office" @@ -962,6 +975,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/crew_quarters/heads/cmo name = "\improper Medbay - CMO's Office" icon_state = "head_quarters" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/crew_quarters/courtroom name = "\improper Courtroom" @@ -1288,6 +1302,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station dynamic_lighting = 0 sound_env = LARGE_ENCLOSED forbid_events = TRUE + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/holodeck/alphadeck name = "\improper Holodeck Alpha" @@ -1648,10 +1663,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/medical/surgery name = "\improper Operating Theatre 1" icon_state = "surgery" + flags = AREA_FLAG_IS_NOT_PERSISTENT //This WOULD become a filth pit /area/medical/surgery2 name = "\improper Operating Theatre 2" icon_state = "surgery" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/medical/surgeryobs name = "\improper Operation Observation Room" @@ -1688,6 +1705,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/medical/sleeper name = "\improper Emergency Treatment Centre" icon_state = "exam_room" + flags = AREA_FLAG_IS_NOT_PERSISTENT //Trust me. /area/medical/first_aid_station_starboard name = "\improper Starboard First-Aid Station" @@ -1902,6 +1920,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/quartermaster/delivery name = "\improper Cargo - Delivery Office" icon_state = "quart" + flags = AREA_FLAG_IS_NOT_PERSISTENT //So trash doesn't pile up too hard. /area/quartermaster/miningdock name = "\improper Cargo Mining Dock" @@ -1941,6 +1960,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/rnd/rdoffice name = "\improper Research Director's Office" icon_state = "head_quarters" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/rnd/supermatter name = "\improper Supermatter Lab" @@ -2063,6 +2083,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "\improper Derelict Station" icon_state = "storage" ambience = AMBIENCE_RUINS + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/derelict/hallway/primary name = "\improper Derelict Primary Hallway" @@ -2163,6 +2184,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/constructionsite name = "\improper Construction Site" icon_state = "storage" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/constructionsite/storage name = "\improper Construction Site Storage Area" @@ -2348,6 +2370,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station /area/wreck ambience = AMBIENCE_RUINS + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/wreck/ai name = "\improper AI Chamber" @@ -2424,6 +2447,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "\improper Strange Location" icon_state = "away" ambience = AMBIENCE_FOREBODING + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/awaymission/gateway name = "\improper Gateway" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 49c481be157..e69ce8cfed5 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -49,6 +49,7 @@ var/sound_env = STANDARD_STATION var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf var/forbid_events = FALSE // If true, random events will not start inside this area. + var/no_spoilers = FALSE // If true, makes it much more difficult to see what is inside an area with things like mesons. /area/Initialize() . = ..() @@ -64,6 +65,8 @@ power_equip = 0 power_environ = 0 power_change() // all machines set to current power level, also updates lighting icon + if(no_spoilers) + set_spoiler_obfuscation(TRUE) return INITIALIZE_HINT_LATELOAD // Changes the area of T to A. Do not do this manually. @@ -367,18 +370,23 @@ var/list/mob/living/forced_ambiance_list = new L.update_floating( L.Check_Dense_Object() ) L.lastarea = newarea - play_ambience(L) + L.lastareachange = world.time + play_ambience(L, initial = TRUE) + if(no_spoilers) + L.disable_spoiler_vision() -/area/proc/play_ambience(var/mob/living/L) +/area/proc/play_ambience(var/mob/living/L, initial = TRUE) // Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch if(!(L && L.is_preference_enabled(/datum/client_preference/play_ambiance))) return // If we previously were in an area with force-played ambiance, stop it. - if(L in forced_ambiance_list) + if((L in forced_ambiance_list) && initial) L << sound(null, channel = CHANNEL_AMBIENCE_FORCED) forced_ambiance_list -= L if(forced_ambience) + if(L in forced_ambiance_list) + return if(forced_ambience.len) forced_ambiance_list |= L var/sound/chosen_ambiance = pick(forced_ambience) @@ -387,8 +395,9 @@ var/list/mob/living/forced_ambiance_list = new L << chosen_ambiance else L << sound(null, channel = CHANNEL_AMBIENCE_FORCED) - else if(src.ambience.len && prob(35)) - if((world.time >= L.client.time_last_ambience_played + 1 MINUTE)) + else if(src.ambience.len) + var/ambience_odds = L?.client.prefs.ambience_chance + if(prob(ambience_odds) && (world.time >= L.client.time_last_ambience_played + 1 MINUTE)) var/sound = pick(ambience) L << sound(sound, repeat = 0, wait = 0, volume = 50, channel = CHANNEL_AMBIENCE) L.client.time_last_ambience_played = world.time @@ -500,4 +509,16 @@ var/list/ghostteleportlocs = list() /area/proc/get_name() if(secret_name) return "Unknown Area" - return name \ No newline at end of file + return name + +GLOBAL_DATUM(spoiler_obfuscation_image, /image) + +/area/proc/set_spoiler_obfuscation(should_obfuscate) + if(!GLOB.spoiler_obfuscation_image) + GLOB.spoiler_obfuscation_image = image(icon = 'icons/misc/static.dmi') + GLOB.spoiler_obfuscation_image.plane = PLANE_MESONS + + if(should_obfuscate) + add_overlay(GLOB.spoiler_obfuscation_image) + else + cut_overlay(GLOB.spoiler_obfuscation_image) \ No newline at end of file diff --git a/code/game/area/asteroid_areas.dm b/code/game/area/asteroid_areas.dm index e5f22a77d76..85f3bffd2fa 100644 --- a/code/game/area/asteroid_areas.dm +++ b/code/game/area/asteroid_areas.dm @@ -3,6 +3,7 @@ /area/mine icon_state = "mining" sound_env = ASTEROID + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/mine/explored name = "Mine" @@ -27,18 +28,22 @@ /area/outpost/mining_north name = "North Mining Outpost" icon_state = "outpost_mine_north" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/outpost/mining_west name = "West Mining Outpost" icon_state = "outpost_mine_west" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/outpost/abandoned name = "Abandoned Outpost" icon_state = "dark" + flags = AREA_FLAG_IS_NOT_PERSISTENT // Main mining outpost /area/outpost/mining_main icon_state = "outpost_mine_main" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/outpost/mining_main/airlock name = "Mining Outpost Airlock" @@ -90,6 +95,7 @@ // Engineering Outpost /area/outpost/engineering icon_state = "outpost_engine" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/outpost/engineering/hallway name = "Engineering Outpost Hallway" @@ -163,6 +169,7 @@ // Research Outpost /area/outpost/research icon_state = "outpost_research" + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/outpost/research/hallway name = "Research Outpost Hallway" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index b1d994d3a36..1229a0a9cb6 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -12,6 +12,8 @@ var/throwpass = 0 var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom. var/simulated = 1 //filter for actions - used by lighting overlays + var/atom_say_verb = "says" + var/bubble_icon = "normal" ///what icon the atom uses for speechbubbles var/fluorescent // Shows up under a UV light. var/last_bumped = 0 @@ -610,3 +612,20 @@ "} var/turf/T = get_turf(src) . += "
[ADMIN_COORDJMP(T)]" + +/atom/proc/atom_say(message) + if(!message) + return + var/list/speech_bubble_hearers = list() + for(var/mob/M in get_mobs_in_view(7, src)) + M.show_message("[src] [atom_say_verb], \"[message]\"", 2, null, 1) + if(M.client) + speech_bubble_hearers += M.client + + if(length(speech_bubble_hearers)) + var/image/I = image('icons/mob/talk.dmi', src, "[bubble_icon][say_test(message)]", FLY_LAYER) + I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA + INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_hearers, 30) + +/atom/proc/speech_bubble(bubble_state = "", bubble_loc = src, list/bubble_recipients = list()) + return diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 01f5e687d87..bf5fc0ab18c 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1,6 +1,6 @@ /atom/movable layer = OBJ_LAYER - appearance_flags = TILE_BOUND|PIXEL_SCALE + appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER glide_size = 8 var/last_move = null //The direction the atom last moved var/anchored = 0 @@ -19,12 +19,14 @@ var/icon_scale_x = 1 // Used to scale icons up or down horizonally in update_transform(). var/icon_scale_y = 1 // Used to scale icons up or down vertically in update_transform(). var/icon_rotation = 0 // Used to rotate icons in update_transform() + var/icon_expected_height = 32 + var/icon_expected_width = 32 var/old_x = 0 var/old_y = 0 var/datum/riding/riding_datum = null var/does_spin = TRUE // Does the atom spin when thrown (of course it does :P) var/movement_type = NONE - + var/cloaked = FALSE //If we're cloaked or not var/image/cloaked_selfimage //The image we use for our client to let them see where we are @@ -107,7 +109,7 @@ glide_for(movetime) loc = newloc . = TRUE - + // So objects can be informed of z-level changes if (old_z != dest_z) onTransitZ(old_z, dest_z) @@ -133,7 +135,7 @@ var/atom/movable/thing = i // We don't call parent so we are calling this for byond thing.Crossed(src) - + // We're a multi-tile object (multiple locs) else if(. && newloc) . = doMove(newloc) @@ -282,7 +284,7 @@ glide_for(movetime) last_move = isnull(direction) ? 0 : direction loc = destination - + // Unset this in case it was set in some other proc. We're no longer moving diagonally for sure. moving_diagonally = 0 @@ -294,27 +296,27 @@ // If it's not the same area, Exited() it if(old_area && old_area != destarea) old_area.Exited(src, destination) - + // Uncross everything where we left for(var/i in oldloc) var/atom/movable/AM = i if(AM == src) continue AM.Uncrossed(src) - + // Information about turf and z-levels for source and dest collected var/turf/oldturf = get_turf(oldloc) var/turf/destturf = get_turf(destination) var/old_z = (oldturf ? oldturf.z : null) var/dest_z = (destturf ? destturf.z : null) - + // So objects can be informed of z-level changes if (old_z != dest_z) onTransitZ(old_z, dest_z) - + // Destination atom Entered destination.Entered(src, oldloc) - + // Entered() the new area if it's not the same area if(destarea && old_area != destarea) destarea.Entered(src, oldloc) @@ -366,7 +368,7 @@ glide_size = initial(glide_size) else glide_size = initial(glide_size) - + ///////////////////////////////////////////////////////////////// //called when src is thrown into hit_atom @@ -561,6 +563,14 @@ return null return text2num(pickweight(candidates)) +// Returns the current scaling of the sprite. +// Note this DOES NOT measure the height or width of the icon, but returns what number is being multiplied with to scale the icons, if any. +/atom/movable/proc/get_icon_scale_x() + return icon_scale_x + +/atom/movable/proc/get_icon_scale_y() + return icon_scale_y + /atom/movable/proc/update_transform() var/matrix/M = matrix() M.Scale(icon_scale_x, icon_scale_y) @@ -623,7 +633,7 @@ /atom/movable/proc/cloak_animation(var/length = 1 SECOND) //Save these var/initial_alpha = alpha - + //Animate alpha fade animate(src, alpha = 0, time = length) diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index 001e74ca59d..1d48349cb52 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -127,6 +127,7 @@ var/global/list/datum/dna/gene/dna_genes[0] new_dna.species=species new_dna.body_markings=body_markings.Copy() new_dna.base_species=base_species //VOREStation Edit + new_dna.custom_species=custom_species //VOREStaton Edit new_dna.species_traits=species_traits.Copy() //VOREStation Edit new_dna.blood_color=blood_color //VOREStation Edit for(var/b=1;b<=DNA_SE_LENGTH;b++) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index b9b8f6db8a9..eb0ad7000c9 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -5,6 +5,11 @@ #define DNA2_BUF_UE 2 #define DNA2_BUF_SE 4 +#define PAGE_UI "ui" +#define PAGE_SE "se" +#define PAGE_BUFFER "buffer" +#define PAGE_REJUVENATORS "rejuvenators" + //list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0), /datum/dna2/record var/datum/dna/dna = null @@ -38,6 +43,22 @@ ser["type"] = "se" return ser +/datum/dna2/record/proc/copy() + var/datum/dna2/record/newrecord = new /datum/dna2/record + newrecord.dna = dna.Clone() + newrecord.types = types + newrecord.name = name + newrecord.mind = mind + newrecord.ckey = ckey + newrecord.languages = languages + newrecord.implant = implant + newrecord.flavor = flavor + newrecord.gender = gender + newrecord.body_descriptors = body_descriptors.Copy() + newrecord.genetic_modifiers = genetic_modifiers.Copy() + return newrecord + + /////////////////////////// DNA MACHINES /obj/machinery/dna_scannernew name = "\improper DNA modifier" @@ -55,13 +76,28 @@ var/mob/living/carbon/occupant = null var/obj/item/weapon/reagent_containers/glass/beaker = null var/opened = 0 + var/damage_coeff + var/scan_level + var/precision_coeff /obj/machinery/dna_scannernew/Initialize() . = ..() default_apply_parts() + RefreshParts() + +/obj/machinery/dna_scannernew/RefreshParts() + scan_level = 0 + damage_coeff = 0 + precision_coeff = 0 + for(var/obj/item/weapon/stock_parts/scanning_module/P in component_parts) + scan_level += P.rating + for(var/obj/item/weapon/stock_parts/manipulator/P in component_parts) + precision_coeff = P.rating + for(var/obj/item/weapon/stock_parts/micro_laser/P in component_parts) + damage_coeff = P.rating /obj/machinery/dna_scannernew/relaymove(mob/user as mob) - if (user.stat) + if(user.stat) return src.go_out() return @@ -71,7 +107,7 @@ set category = "Object" set name = "Eject DNA Scanner" - if (usr.stat != 0) + if(usr.stat != 0) return eject_occupant() @@ -98,15 +134,15 @@ set category = "Object" set name = "Enter DNA Scanner" - if (usr.stat != 0) + if(usr.stat != 0) return - if (!ishuman(usr) && !issmall(usr)) //Make sure they're a mob that has dna + if(!ishuman(usr) && !issmall(usr)) //Make sure they're a mob that has dna to_chat(usr, "Try as you might, you can not climb up into the scanner.") return - if (src.occupant) + if(src.occupant) to_chat(usr, "The scanner is already occupied!") return - if (usr.abiotic()) + if(usr.abiotic()) to_chat(usr, "The subject cannot have abiotic items on.") return usr.stop_pulling() @@ -116,7 +152,7 @@ src.occupant = usr src.icon_state = "scanner_1" src.add_fingerprint(usr) - return + SStgui.update_uis(src) /obj/machinery/dna_scannernew/attackby(var/obj/item/weapon/item as obj, var/mob/user as mob) if(istype(item, /obj/item/weapon/reagent_containers/glass)) @@ -128,10 +164,11 @@ user.drop_item() item.loc = src user.visible_message("\The [user] adds \a [item] to \the [src]!", "You add \a [item] to \the [src]!") + SStgui.update_uis(src) return else if(istype(item, /obj/item/organ/internal/brain)) - if (src.occupant) + if(src.occupant) to_chat(user, "The scanner is already occupied!") return var/obj/item/organ/internal/brain/brain = item @@ -141,19 +178,20 @@ put_in(brain.brainmob) src.add_fingerprint(user) user.visible_message("\The [user] adds \a [item] to \the [src]!", "You add \a [item] to \the [src]!") + SStgui.update_uis(src) return else to_chat(user, "\The [brain] is not acceptable for genetic sampling!") - else if (!istype(item, /obj/item/weapon/grab)) + else if(!istype(item, /obj/item/weapon/grab)) return var/obj/item/weapon/grab/G = item - if (!ismob(G.affecting)) + if(!ismob(G.affecting)) return - if (src.occupant) + if(src.occupant) to_chat(user, "The scanner is already occupied!") return - if (G.affecting.abiotic()) + if(G.affecting.abiotic()) to_chat(user, "The subject cannot have abiotic items on.") return put_in(G.affecting) @@ -180,12 +218,12 @@ if(ghost.mind == M.mind) to_chat(ghost, "Your corpse has been placed into a cloning scanner. Return to your body if you want to be resurrected/cloned! (Verbs -> Ghost -> Re-enter corpse)") break - return + SStgui.update_uis(src) /obj/machinery/dna_scannernew/proc/go_out() - if ((!( src.occupant ) || src.locked)) + if((!( src.occupant ) || src.locked)) return - if (src.occupant.client) + if(src.occupant.client) src.occupant.client.eye = src.occupant.client.mob src.occupant.client.perspective = MOB_PERSPECTIVE if(istype(occupant,/mob/living/carbon/brain)) @@ -198,7 +236,7 @@ src.occupant.loc = src.loc src.occupant = null src.icon_state = "scanner_0" - return + SStgui.update_uis(src) /obj/machinery/dna_scannernew/ex_act(severity) switch(severity) @@ -211,7 +249,7 @@ qdel(src) return if(2.0) - if (prob(50)) + if(prob(50)) for(var/atom/movable/A as mob|obj in src) A.loc = src.loc ex_act(severity) @@ -220,7 +258,7 @@ qdel(src) return if(3.0) - if (prob(25)) + if(prob(25)) for(var/atom/movable/A as mob|obj in src) A.loc = src.loc ex_act(severity) @@ -251,21 +289,20 @@ var/injector_ready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete var/obj/machinery/dna_scannernew/connected = null var/obj/item/weapon/disk/data/disk = null - var/selected_menu_key = null + var/selected_menu_key = PAGE_UI anchored = 1 use_power = USE_POWER_IDLE idle_power_usage = 10 active_power_usage = 400 - var/waiting_for_user_input=0 // Fix for #274 (Mash create block injector without answering dialog to make unlimited injectors) - N3X /obj/machinery/computer/scan_consolenew/attackby(obj/item/I as obj, mob/user as mob) - if (istype(I, /obj/item/weapon/disk/data)) //INSERT SOME diskS - if (!src.disk) + if(istype(I, /obj/item/weapon/disk/data)) //INSERT SOME diskS + if(!src.disk) user.drop_item() I.loc = src src.disk = I to_chat(user, "You insert [I].") - SSnanoui.update_uis(src) // update all UIs attached to src + SStgui.update_uis(src) // update all UIs attached to src return else ..() @@ -279,7 +316,7 @@ qdel(src) return if(2.0) - if (prob(50)) + if(prob(50)) //SN src = null qdel(src) return @@ -315,35 +352,28 @@ /obj/machinery/computer/scan_consolenew/process() //not really used right now if(stat & (NOPOWER|BROKEN)) return - if (!( src.status )) //remove this + if(!( src.status )) //remove this return return */ /obj/machinery/computer/scan_consolenew/attack_ai(user as mob) src.add_hiddenprint(user) - ui_interact(user) + tgui_interact(user) /obj/machinery/computer/scan_consolenew/attack_hand(user as mob) if(!..()) - ui_interact(user) - - /** - * The ui_interact proc is used to open and update Nano UIs - * If ui_interact is not used then the UI will not update correctly - * ui_interact is currently defined for /atom/movable (which is inherited by /obj and /mob) - * - * @param user /mob The mob who is interacting with this ui - * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") - * @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui - * - * @return nothing - */ -/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + tgui_interact(user) +/obj/machinery/computer/scan_consolenew/tgui_interact(mob/user, datum/tgui/ui) if(!connected || user == connected.occupant || user.stat) return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "DNAModifier", name) + ui.open() +/obj/machinery/computer/scan_consolenew/tgui_data(mob/user) // this is the data which will be sent to the ui var/data[0] data["selectedMenuKey"] = selected_menu_key @@ -355,7 +385,7 @@ data["hasDisk"] = disk ? 1 : 0 var/diskData[0] - if (!disk || !disk.buf) + if(!disk || !disk.buf) diskData["data"] = null diskData["owner"] = null diskData["label"] = null @@ -383,7 +413,7 @@ data["selectedUITargetHex"] = selected_ui_target_hex var/occupantData[0] - if (!src.connected.occupant || !src.connected.occupant.dna) + if(!src.connected.occupant || !src.connected.occupant.dna) occupantData["name"] = null occupantData["stat"] = null occupantData["isViableSubject"] = null @@ -398,7 +428,7 @@ occupantData["name"] = connected.occupant.real_name occupantData["stat"] = connected.occupant.stat occupantData["isViableSubject"] = 1 - if (NOCLONE in connected.occupant.mutations || !src.connected.occupant.dna) + if(NOCLONE in connected.occupant.mutations || !src.connected.occupant.dna) occupantData["isViableSubject"] = 0 occupantData["health"] = connected.occupant.health occupantData["maxHealth"] = connected.occupant.maxHealth @@ -414,423 +444,357 @@ data["beakerVolume"] = 0 if(connected.beaker) data["beakerLabel"] = connected.beaker.label_text ? connected.beaker.label_text : null - if (connected.beaker.reagents && connected.beaker.reagents.reagent_list.len) + if(connected.beaker.reagents && connected.beaker.reagents.reagent_list.len) for(var/datum/reagent/R in connected.beaker.reagents.reagent_list) data["beakerVolume"] += R.volume - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "dna_modifier.tmpl", "DNA Modifier Console", 660, 700) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) + // Transfer modal information if there is one + data["modal"] = tgui_modal_data(src) -/obj/machinery/computer/scan_consolenew/Topic(href, href_list) + return data + +/obj/machinery/computer/scan_consolenew/tgui_act(action, params) if(..()) - return 0 // don't update uis + return TRUE if(!istype(usr.loc, /turf)) - return 0 // don't update uis + return TRUE if(!src || !src.connected) - return 0 // don't update uis + return TRUE if(irradiating) // Make sure that it isn't already irradiating someone... - return 0 // don't update uis + return TRUE add_fingerprint(usr) - if (href_list["selectMenuKey"]) - selected_menu_key = href_list["selectMenuKey"] - return 1 // return 1 forces an update to all Nano uis attached to src + if(tgui_act_modal(action, params)) + return TRUE - if (href_list["toggleLock"]) - if ((src.connected && src.connected.occupant)) - src.connected.locked = !( src.connected.locked ) - return 1 // return 1 forces an update to all Nano uis attached to src - - if (href_list["pulseRadiation"]) - irradiating = src.radiation_duration - var/lock_state = src.connected.locked - src.connected.locked = 1//lock it - SSnanoui.update_uis(src) // update all UIs attached to src - - sleep(10*src.radiation_duration) // sleep for radiation_duration seconds - - irradiating = 0 - - if (!src.connected.occupant) - return 1 // return 1 forces an update to all Nano uis attached to src - - if (prob(95)) - if(prob(75)) - randmutb(src.connected.occupant) - else - randmuti(src.connected.occupant) - else - if(prob(95)) - randmutg(src.connected.occupant) - else - randmuti(src.connected.occupant) - - src.connected.occupant.apply_effect(((src.radiation_intensity*3)+src.radiation_duration*3), IRRADIATE, check_protection = 0) - src.connected.locked = lock_state - return 1 // return 1 forces an update to all Nano uis attached to src - - if (href_list["radiationDuration"]) - if (text2num(href_list["radiationDuration"]) > 0) - if (src.radiation_duration < 20) - src.radiation_duration += 2 - else - if (src.radiation_duration > 2) - src.radiation_duration -= 2 - return 1 // return 1 forces an update to all Nano uis attached to src - - if (href_list["radiationIntensity"]) - if (text2num(href_list["radiationIntensity"]) > 0) - if (src.radiation_intensity < 10) - src.radiation_intensity++ - else - if (src.radiation_intensity > 1) - src.radiation_intensity-- - return 1 // return 1 forces an update to all Nano uis attached to src - - //////////////////////////////////////////////////////// - - if (href_list["changeUITarget"] && text2num(href_list["changeUITarget"]) > 0) - if (src.selected_ui_target < 15) - src.selected_ui_target++ - src.selected_ui_target_hex = src.selected_ui_target - switch(selected_ui_target) - if(10) - src.selected_ui_target_hex = "A" - if(11) - src.selected_ui_target_hex = "B" - if(12) - src.selected_ui_target_hex = "C" - if(13) - src.selected_ui_target_hex = "D" - if(14) - src.selected_ui_target_hex = "E" - if(15) - src.selected_ui_target_hex = "F" - else - src.selected_ui_target = 0 - src.selected_ui_target_hex = 0 - return 1 // return 1 forces an update to all Nano uis attached to src - - if (href_list["changeUITarget"] && text2num(href_list["changeUITarget"]) < 1) - if (src.selected_ui_target > 0) - src.selected_ui_target-- - src.selected_ui_target_hex = src.selected_ui_target - switch(selected_ui_target) - if(10) - src.selected_ui_target_hex = "A" - if(11) - src.selected_ui_target_hex = "B" - if(12) - src.selected_ui_target_hex = "C" - if(13) - src.selected_ui_target_hex = "D" - if(14) - src.selected_ui_target_hex = "E" - else - src.selected_ui_target = 15 - src.selected_ui_target_hex = "F" - return 1 // return 1 forces an update to all Nano uis attached to src - - if (href_list["selectUIBlock"] && href_list["selectUISubblock"]) // This chunk of code updates selected block / sub-block based on click - var/select_block = text2num(href_list["selectUIBlock"]) - var/select_subblock = text2num(href_list["selectUISubblock"]) - if ((select_block <= DNA_UI_LENGTH) && (select_block >= 1)) - src.selected_ui_block = select_block - if ((select_subblock <= DNA_BLOCK_SIZE) && (select_subblock >= 1)) - src.selected_ui_subblock = select_subblock - return 1 // return 1 forces an update to all Nano uis attached to src - - if (href_list["pulseUIRadiation"]) - var/block = src.connected.occupant.dna.GetUISubBlock(src.selected_ui_block,src.selected_ui_subblock) - - irradiating = src.radiation_duration - var/lock_state = src.connected.locked - src.connected.locked = 1//lock it - SSnanoui.update_uis(src) // update all UIs attached to src - - sleep(10*src.radiation_duration) // sleep for radiation_duration seconds - - irradiating = 0 - - if (!src.connected.occupant) - return 1 - - if (prob((80 + (src.radiation_duration / 2)))) - block = miniscrambletarget(num2text(selected_ui_target), src.radiation_intensity, src.radiation_duration) - src.connected.occupant.dna.SetUISubBlock(src.selected_ui_block,src.selected_ui_subblock,block) - src.connected.occupant.UpdateAppearance() - src.connected.occupant.apply_effect((src.radiation_intensity+src.radiation_duration), IRRADIATE, check_protection = 0) - else - if (prob(20+src.radiation_intensity)) - randmutb(src.connected.occupant) - domutcheck(src.connected.occupant,src.connected) - else - randmuti(src.connected.occupant) - src.connected.occupant.UpdateAppearance() - src.connected.occupant.apply_effect(((src.radiation_intensity*2)+src.radiation_duration), IRRADIATE, check_protection = 0) - src.connected.locked = lock_state - return 1 // return 1 forces an update to all Nano uis attached to src - - //////////////////////////////////////////////////////// - - if (href_list["injectRejuvenators"]) - if (!connected.occupant) - return 0 - var/inject_amount = round(text2num(href_list["injectRejuvenators"]), 5) // round to nearest 5 - if (inject_amount < 0) // Since the user can actually type the commands himself, some sanity checking - inject_amount = 0 - if (inject_amount > 50) - inject_amount = 50 - connected.beaker.reagents.trans_to_mob(connected.occupant, inject_amount, CHEM_BLOOD) - return 1 // return 1 forces an update to all Nano uis attached to src - - //////////////////////////////////////////////////////// - - if (href_list["selectSEBlock"] && href_list["selectSESubblock"]) // This chunk of code updates selected block / sub-block based on click (se stands for strutural enzymes) - var/select_block = text2num(href_list["selectSEBlock"]) - var/select_subblock = text2num(href_list["selectSESubblock"]) - if ((select_block <= DNA_SE_LENGTH) && (select_block >= 1)) - src.selected_se_block = select_block - if ((select_subblock <= DNA_BLOCK_SIZE) && (select_subblock >= 1)) - src.selected_se_subblock = select_subblock - //testing("User selected block [selected_se_block] (sent [select_block]), subblock [selected_se_subblock] (sent [select_block]).") - return 1 // return 1 forces an update to all Nano uis attached to src - - if (href_list["pulseSERadiation"]) - var/block = src.connected.occupant.dna.GetSESubBlock(src.selected_se_block,src.selected_se_subblock) - //var/original_block=block - //testing("Irradiating SE block [src.selected_se_block]:[src.selected_se_subblock] ([block])...") - - irradiating = src.radiation_duration - var/lock_state = src.connected.locked - src.connected.locked = 1 //lock it - SSnanoui.update_uis(src) // update all UIs attached to src - - sleep(10*src.radiation_duration) // sleep for radiation_duration seconds - - irradiating = 0 - - if(src.connected.occupant) - if (prob((80 + (src.radiation_duration / 2)))) - // FIXME: Find out what these corresponded to and change them to the WHATEVERBLOCK they need to be. - //if ((src.selected_se_block != 2 || src.selected_se_block != 12 || src.selected_se_block != 8 || src.selected_se_block || 10) && prob (20)) - var/real_SE_block=selected_se_block - block = miniscramble(block, src.radiation_intensity, src.radiation_duration) - if(prob(20)) - if (src.selected_se_block > 1 && src.selected_se_block < DNA_SE_LENGTH/2) - real_SE_block++ - else if (src.selected_se_block > DNA_SE_LENGTH/2 && src.selected_se_block < DNA_SE_LENGTH) - real_SE_block-- - - //testing("Irradiated SE block [real_SE_block]:[src.selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!") - connected.occupant.dna.SetSESubBlock(real_SE_block,selected_se_subblock,block) - src.connected.occupant.apply_effect((src.radiation_intensity+src.radiation_duration), IRRADIATE, check_protection = 0) - domutcheck(src.connected.occupant,src.connected) - else - src.connected.occupant.apply_effect(((src.radiation_intensity*2)+src.radiation_duration), IRRADIATE, check_protection = 0) - if (prob(80-src.radiation_duration)) - //testing("Random bad mut!") - randmutb(src.connected.occupant) - domutcheck(src.connected.occupant,src.connected) - else - randmuti(src.connected.occupant) - //testing("Random identity mut!") - src.connected.occupant.UpdateAppearance() - src.connected.locked = lock_state - return 1 // return 1 forces an update to all Nano uis attached to src - - if(href_list["ejectBeaker"]) - if(connected.beaker) - var/obj/item/weapon/reagent_containers/glass/B = connected.beaker - B.loc = connected.loc - connected.beaker = null - return 1 - - if(href_list["ejectOccupant"]) - connected.eject_occupant() - return 1 - - // Transfer Buffer Management - if(href_list["bufferOption"]) - var/bufferOption = href_list["bufferOption"] - - // These bufferOptions do not require a bufferId - if (bufferOption == "wipeDisk") - if ((isnull(src.disk)) || (src.disk.read_only)) - //src.temphtml = "Invalid disk. Please try again." - return 0 - - src.disk.buf=null - //src.temphtml = "Data saved." - return 1 - - if (bufferOption == "ejectDisk") - if (!src.disk) + . = TRUE + switch(action) + if("selectMenuKey") + var/key = params["key"] + if(!(key in list(PAGE_UI, PAGE_SE, PAGE_BUFFER, PAGE_REJUVENATORS))) return - src.disk.loc = get_turf(src) - src.disk = null - return 1 + selected_menu_key = key + if("toggleLock") + if(connected && connected.occupant) + connected.locked = !(connected.locked) - // All bufferOptions from here on require a bufferId - if (!href_list["bufferId"]) - return 0 + if("pulseRadiation") + irradiating = radiation_duration + var/lock_state = connected.locked + connected.locked = TRUE //lock it - var/bufferId = text2num(href_list["bufferId"]) - - if (bufferId < 1 || bufferId > 3) - return 0 // Not a valid buffer id - - if (bufferOption == "saveUI") - if(src.connected.occupant && src.connected.occupant.dna) - var/datum/dna2/record/databuf=new - databuf.types = DNA2_BUF_UE - databuf.dna = src.connected.occupant.dna.Clone() - if(ishuman(connected.occupant)) - var/mob/living/carbon/human/H = connected.occupant - databuf.dna.real_name = H.dna.real_name - databuf.gender = H.gender - databuf.body_descriptors = H.descriptors - databuf.name = "Unique Identifier" - src.buffers[bufferId] = databuf - return 1 - - if (bufferOption == "saveUIAndUE") - if(src.connected.occupant && src.connected.occupant.dna) - var/datum/dna2/record/databuf=new - databuf.types = DNA2_BUF_UI|DNA2_BUF_UE - databuf.dna = src.connected.occupant.dna.Clone() - if(ishuman(connected.occupant)) - var/mob/living/carbon/human/H = connected.occupant - databuf.dna.real_name = H.dna.real_name - databuf.gender = H.gender - databuf.body_descriptors = H.descriptors - databuf.name = "Unique Identifier + Unique Enzymes" - src.buffers[bufferId] = databuf - return 1 - - if (bufferOption == "saveSE") - if(src.connected.occupant && src.connected.occupant.dna) - var/datum/dna2/record/databuf=new - databuf.types = DNA2_BUF_SE - databuf.dna = src.connected.occupant.dna.Clone() - if(ishuman(connected.occupant)) - var/mob/living/carbon/human/H = connected.occupant - databuf.dna.real_name = H.dna.real_name - databuf.gender = H.gender - databuf.body_descriptors = H.descriptors - databuf.name = "Structural Enzymes" - src.buffers[bufferId] = databuf - return 1 - - if (bufferOption == "clear") - src.buffers[bufferId]=new /datum/dna2/record() - return 1 - - if (bufferOption == "changeLabel") - var/datum/dna2/record/buf = src.buffers[bufferId] - var/text = sanitize(input(usr, "New Label:", "Edit Label", buf.name) as text|null, MAX_NAME_LEN) - buf.name = text - src.buffers[bufferId] = buf - return 1 - - if (bufferOption == "transfer") - if (!src.connected.occupant || (NOCLONE in src.connected.occupant.mutations) || !src.connected.occupant.dna) - return - - irradiating = 2 - var/lock_state = src.connected.locked - src.connected.locked = 1//lock it - SSnanoui.update_uis(src) // update all UIs attached to src - - sleep(10*2) // sleep for 2 seconds + SStgui.update_uis(src) // update all UIs attached to src + sleep(10 * radiation_duration) // sleep for radiation_duration seconds irradiating = 0 - src.connected.locked = lock_state + connected.locked = lock_state - var/datum/dna2/record/buf = src.buffers[bufferId] + if(!connected.occupant) + return - if ((buf.types & DNA2_BUF_UI)) - if ((buf.types & DNA2_BUF_UE)) - src.connected.occupant.real_name = buf.dna.real_name - src.connected.occupant.name = buf.dna.real_name - if(ishuman(connected.occupant)) - var/mob/living/carbon/human/H = connected.occupant - H.gender = buf.gender - H.descriptors = buf.body_descriptors - src.connected.occupant.UpdateAppearance(buf.dna.UI.Copy()) - else if (buf.types & DNA2_BUF_SE) - src.connected.occupant.dna.SE = buf.dna.SE - src.connected.occupant.dna.UpdateSE() - if(ishuman(connected.occupant)) - var/mob/living/carbon/human/H = connected.occupant - H.gender = buf.gender - H.descriptors = buf.body_descriptors - domutcheck(src.connected.occupant,src.connected) - src.connected.occupant.apply_effect(rand(20,50), IRRADIATE, check_protection = 0) - return 1 - - if (bufferOption == "createInjector") - if (src.injector_ready || waiting_for_user_input) - - var/success = 1 - var/obj/item/weapon/dnainjector/I = new /obj/item/weapon/dnainjector - var/datum/dna2/record/buf = src.buffers[bufferId] - if(href_list["createBlockInjector"]) - waiting_for_user_input=1 - var/list/selectedbuf - if(buf.types & DNA2_BUF_SE) - selectedbuf=buf.dna.SE - else - selectedbuf=buf.dna.UI - var/blk = input(usr,"Select Block","Block") in all_dna_blocks(selectedbuf) - success = setInjectorBlock(I,blk,buf) + if(prob(95)) + if(prob(75)) + randmutb(connected.occupant) else - I.buf = buf - waiting_for_user_input=0 - if(success) - I.loc = src.loc - I.name += " ([buf.name])" - //src.temphtml = "Injector created." - src.injector_ready = 0 - spawn(300) - src.injector_ready = 1 - //else - //src.temphtml = "Error in injector creation." - //else - //src.temphtml = "Replicator not ready yet." - return 1 + randmuti(connected.occupant) + else + if(prob(95)) + randmutg(connected.occupant) + else + randmuti(connected.occupant) - if (bufferOption == "loadDisk") - if ((isnull(src.disk)) || (!src.disk.buf)) - //src.temphtml = "Invalid disk. Please try again." - return 0 + connected.occupant.apply_effect(((radiation_intensity*3)+radiation_duration*3), IRRADIATE, check_protection = 0) + if("radiationDuration") + radiation_duration = clamp(text2num(params["value"]), 1, 20) + if("radiationIntensity") + radiation_intensity = clamp(text2num(params["value"]), 1, 10) + //////////////////////////////////////////////////////// + if("changeUITarget") + selected_ui_target = clamp(text2num(params["value"]), 1, 15) + selected_ui_target_hex = num2text(selected_ui_target, 1, 16) + if("selectUIBlock") // This chunk of code updates selected block / sub-block based on click + var/select_block = text2num(params["block"]) + var/select_subblock = text2num(params["subblock"]) + if(!select_block || !select_subblock) + return - src.buffers[bufferId]=src.disk.buf - //src.temphtml = "Data loaded." - return 1 + selected_ui_block = clamp(select_block, 1, DNA_UI_LENGTH) + selected_ui_subblock = clamp(select_subblock, 1, DNA_BLOCK_SIZE) + if("pulseUIRadiation") + var/block = connected.occupant.dna.GetUISubBlock(selected_ui_block,selected_ui_subblock) - if (bufferOption == "saveDisk") - if ((isnull(src.disk)) || (src.disk.read_only)) - //src.temphtml = "Invalid disk. Please try again." - return 0 + irradiating = radiation_duration + var/lock_state = connected.locked + connected.locked = TRUE //lock it - var/datum/dna2/record/buf = src.buffers[bufferId] + SStgui.update_uis(src) // update all UIs attached to src + sleep(10 * radiation_duration) // sleep for radiation_duration seconds - src.disk.buf = buf - src.disk.name = "data disk - '[buf.dna.real_name]'" - //src.temphtml = "Data saved." - return 1 + irradiating = 0 + connected.locked = lock_state + + if(!connected.occupant) + return + + if(prob((80 + (radiation_duration / 2)))) + block = miniscrambletarget(num2text(selected_ui_target), radiation_intensity, radiation_duration) + connected.occupant.dna.SetUISubBlock(selected_ui_block,selected_ui_subblock,block) + connected.occupant.UpdateAppearance() + connected.occupant.apply_effect((radiation_intensity+radiation_duration), IRRADIATE, check_protection = 0) + else + if(prob(20 + radiation_intensity)) + randmutb(connected.occupant) + domutcheck(connected.occupant,connected) + else + randmuti(connected.occupant) + connected.occupant.UpdateAppearance() + connected.occupant.apply_effect(((radiation_intensity*2)+radiation_duration), IRRADIATE, check_protection = 0) + //////////////////////////////////////////////////////// + if("injectRejuvenators") + if(!connected.occupant || !connected.beaker) + return + var/inject_amount = clamp(round(text2num(params["amount"]), 5), 0, 50) // round to nearest 5 and clamp to 0-50 + if(!inject_amount) + return + connected.beaker.reagents.trans_to_mob(connected.occupant, inject_amount, CHEM_BLOOD) + //////////////////////////////////////////////////////// + if("selectSEBlock") // This chunk of code updates selected block / sub-block based on click (se stands for strutural enzymes) + var/select_block = text2num(params["block"]) + var/select_subblock = text2num(params["subblock"]) + if(!select_block || !select_subblock) + return + + selected_se_block = clamp(select_block, 1, DNA_SE_LENGTH) + selected_se_subblock = clamp(select_subblock, 1, DNA_BLOCK_SIZE) + if("pulseSERadiation") + var/block = connected.occupant.dna.GetSESubBlock(selected_se_block,selected_se_subblock) + //var/original_block=block + //testing("Irradiating SE block [selected_se_block]:[selected_se_subblock] ([block])...") + + irradiating = radiation_duration + var/lock_state = connected.locked + connected.locked = TRUE //lock it + + SStgui.update_uis(src) // update all UIs attached to src + sleep(10 * radiation_duration) // sleep for radiation_duration seconds + + irradiating = 0 + connected.locked = lock_state + + if(connected.occupant) + if(prob((80 + (radiation_duration / 2)))) + // FIXME: Find out what these corresponded to and change them to the WHATEVERBLOCK they need to be. + //if((selected_se_block != 2 || selected_se_block != 12 || selected_se_block != 8 || selected_se_block || 10) && prob (20)) + var/real_SE_block=selected_se_block + block = miniscramble(block, radiation_intensity, radiation_duration) + if(prob(20)) + if(selected_se_block > 1 && selected_se_block < DNA_SE_LENGTH/2) + real_SE_block++ + else if(selected_se_block > DNA_SE_LENGTH/2 && selected_se_block < DNA_SE_LENGTH) + real_SE_block-- + + //testing("Irradiated SE block [real_SE_block]:[selected_se_subblock] ([original_block] now [block]) [(real_SE_block!=selected_se_block) ? "(SHIFTED)":""]!") + connected.occupant.dna.SetSESubBlock(real_SE_block,selected_se_subblock,block) + connected.occupant.apply_effect((radiation_intensity+radiation_duration), IRRADIATE, check_protection = 0) + domutcheck(connected.occupant,connected) + else + connected.occupant.apply_effect(((radiation_intensity*2)+radiation_duration), IRRADIATE, check_protection = 0) + if (prob(80-radiation_duration)) + //testing("Random bad mut!") + randmutb(connected.occupant) + domutcheck(connected.occupant,connected) + else + randmuti(connected.occupant) + //testing("Random identity mut!") + connected.occupant.UpdateAppearance() + if("ejectBeaker") + if(connected.beaker) + var/obj/item/weapon/reagent_containers/glass/B = connected.beaker + B.loc = connected.loc + connected.beaker = null + if("ejectOccupant") + connected.eject_occupant() + // Transfer Buffer Management + if("bufferOption") + var/bufferOption = params["option"] + var/bufferId = text2num(params["id"]) + if(bufferId < 1 || bufferId > 3) // Not a valid buffer id + return + + var/datum/dna2/record/buffer = buffers[bufferId] + switch(bufferOption) + if("saveUI") + if(connected.occupant && connected.occupant.dna) + var/datum/dna2/record/databuf=new + databuf.types = DNA2_BUF_UI // DNA2_BUF_UE + databuf.dna = connected.occupant.dna.Clone() + if(ishuman(connected.occupant)) + var/mob/living/carbon/human/H = connected.occupant + databuf.dna.real_name = H.dna.real_name + databuf.gender = H.gender + databuf.body_descriptors = H.descriptors + databuf.name = "Unique Identifier" + buffers[bufferId] = databuf + if("saveUIAndUE") + if(connected.occupant && connected.occupant.dna) + var/datum/dna2/record/databuf=new + databuf.types = DNA2_BUF_UI|DNA2_BUF_UE + databuf.dna = connected.occupant.dna.Clone() + if(ishuman(connected.occupant)) + var/mob/living/carbon/human/H = connected.occupant + databuf.dna.real_name = H.dna.real_name + databuf.gender = H.gender + databuf.body_descriptors = H.descriptors + databuf.name = "Unique Identifier + Unique Enzymes" + buffers[bufferId] = databuf + if("saveSE") + if(connected.occupant && connected.occupant.dna) + var/datum/dna2/record/databuf=new + databuf.types = DNA2_BUF_SE + databuf.dna = connected.occupant.dna.Clone() + if(ishuman(connected.occupant)) + var/mob/living/carbon/human/H = connected.occupant + databuf.dna.real_name = H.dna.real_name + databuf.gender = H.gender + databuf.body_descriptors = H.descriptors + databuf.name = "Structural Enzymes" + buffers[bufferId] = databuf + if("clear") + buffers[bufferId] = new /datum/dna2/record() + if("changeLabel") + tgui_modal_input(src, "changeBufferLabel", "Please enter the new buffer label:", null, list("id" = bufferId), buffer.name, TGUI_MODAL_INPUT_MAX_LENGTH_NAME) + if("transfer") + if(!connected.occupant || (NOCLONE in connected.occupant.mutations) || !connected.occupant.dna) + return + + irradiating = 2 + var/lock_state = connected.locked + connected.locked = 1//lock it + + SStgui.update_uis(src) // update all UIs attached to src + sleep(2 SECONDS) // sleep for 2 seconds + + irradiating = 0 + connected.locked = lock_state + + var/datum/dna2/record/buf = buffers[bufferId] + + if((buf.types & DNA2_BUF_UI)) + if((buf.types & DNA2_BUF_UE)) + connected.occupant.real_name = buf.dna.real_name + connected.occupant.name = buf.dna.real_name + if(ishuman(connected.occupant)) + var/mob/living/carbon/human/H = connected.occupant + H.gender = buf.gender + H.descriptors = buf.body_descriptors + connected.occupant.UpdateAppearance(buf.dna.UI.Copy()) + else if(buf.types & DNA2_BUF_SE) + connected.occupant.dna.SE = buf.dna.SE + connected.occupant.dna.UpdateSE() + if(ishuman(connected.occupant)) + var/mob/living/carbon/human/H = connected.occupant + H.gender = buf.gender + H.descriptors = buf.body_descriptors + domutcheck(connected.occupant,connected) + connected.occupant.apply_effect(rand(20,50), IRRADIATE, check_protection = 0) + if("createInjector") + if(!injector_ready) + return + if(text2num(params["block"]) > 0) + var/list/choices = all_dna_blocks((buffer.types & DNA2_BUF_SE) ? buffer.dna.SE : buffer.dna.UI) + tgui_modal_choice(src, "createInjectorBlock", "Please select the block to create an injector from:", null, list("id" = bufferId), null, choices) + else + create_injector(bufferId, TRUE) + if("loadDisk") + if(isnull(disk) || disk.read_only) + return + buffers[bufferId] = disk.buf.copy() + if("saveDisk") + if(isnull(disk) || disk.read_only) + return + var/datum/dna2/record/buf = buffers[bufferId] + disk.buf = buf.copy() + disk.name = "data disk - '[buf.dna.real_name]'" + + if("wipeDisk") + if(isnull(disk) || disk.read_only) + return + disk.buf = null + if("ejectDisk") + if(!disk) + return + disk.forceMove(get_turf(src)) + disk = null + +/** + * Creates a blank injector with the name of the buffer at the given buffer_id + * + * Arguments: + * * buffer_id - The ID of the buffer + * * copy_buffer - Whether the injector should copy the buffer contents + */ +/obj/machinery/computer/scan_consolenew/proc/create_injector(buffer_id, copy_buffer = FALSE) + if(buffer_id < 1 || buffer_id > length(buffers)) + return + + // Cooldown + injector_ready = FALSE + addtimer(CALLBACK(src, .proc/injector_cooldown_finish), 30 SECONDS) + + // Create it + var/datum/dna2/record/buf = buffers[buffer_id] + var/obj/item/weapon/dnainjector/I = new() + I.forceMove(loc) + I.name += " ([buf.name])" + if(copy_buffer) + I.buf = buf.copy() + return I + +/** + * Called when the injector creation cooldown finishes + */ +/obj/machinery/computer/scan_consolenew/proc/injector_cooldown_finish() + injector_ready = TRUE + +/** + * Called in tgui_act() to process modal actions + * + * Arguments: + * * action - The action passed by tgui + * * params - The params passed by tgui + */ +/obj/machinery/computer/scan_consolenew/proc/tgui_act_modal(action, params) + . = TRUE + var/id = params["id"] // The modal's ID + var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"] + switch(tgui_modal_act(src, action, params)) + if(TGUI_MODAL_ANSWER) + var/answer = params["answer"] + switch(id) + if("createInjectorBlock") + var/buffer_id = text2num(arguments["id"]) + if(buffer_id < 1 || buffer_id > length(buffers)) + return + var/datum/dna2/record/buf = buffers[buffer_id] + var/obj/item/weapon/dnainjector/I = create_injector(buffer_id) + setInjectorBlock(I, answer, buf.copy()) + if("changeBufferLabel") + var/buffer_id = text2num(arguments["id"]) + if(buffer_id < 1 || buffer_id > length(buffers)) + return + var/datum/dna2/record/buf = buffers[buffer_id] + buf.name = answer + buffers[buffer_id] = buf + else + return FALSE + else + return FALSE -/////////////////////////// DNA MACHINES +#undef PAGE_UI +#undef PAGE_SE +#undef PAGE_BUFFER +#undef PAGE_REJUVENATORS + +/////////////////////////// DNA MACHINES \ No newline at end of file diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 93d9ff42894..b03b986bcaa 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -182,20 +182,20 @@ turf/proc/AdjacentTurfsRangedSting() add = 0 if(add && TurfBlockedNonWindow(t)) add = 0 - for(var/obj/O in t) - if(!O.density) + for(var/obj/O in t) + if(O.density) + add = 0 + break + if(istype(O, /obj/machinery/door)) + //not sure why this doesn't fire on LinkBlocked() + add = 0 + break + for(var/type in allowed) + if (istype(O, type)) add = 1 break - if(istype(O, /obj/machinery/door)) - //not sure why this doesn't fire on LinkBlocked() - add = 0 - break - for(var/type in allowed) - if (istype(O, type)) - add = 1 - break - if(!add) - break + if(!add) + break if(add) L.Add(t) return L diff --git a/code/game/gamemodes/cult/cultify/obj.dm b/code/game/gamemodes/cult/cultify/obj.dm index d7c0cff5ece..3ac41e00471 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/cooker/cultify() +/obj/machinery/appliance/cooker/cultify() new /obj/structure/cult/talisman(loc) qdel(src) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index c324a6f092b..07440ae5f5c 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -180,7 +180,12 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa"," /obj/item/weapon/book/tome name = "arcane tome" icon = 'icons/obj/weapons.dmi' + item_icons = list( + icon_l_hand = 'icons/mob/items/lefthand_books.dmi', + icon_r_hand = 'icons/mob/items/righthand_books.dmi', + ) icon_state ="tome" + item_state = "tome" throw_speed = 1 throw_range = 5 w_class = ITEMSIZE_SMALL diff --git a/code/game/gamemodes/technomancer/spells/audible_deception.dm b/code/game/gamemodes/technomancer/spells/audible_deception.dm index 1914b72f149..8faff2b4e6c 100644 --- a/code/game/gamemodes/technomancer/spells/audible_deception.dm +++ b/code/game/gamemodes/technomancer/spells/audible_deception.dm @@ -83,7 +83,7 @@ for(var/mob/living/carbon/M in ohearers(6, T)) if(M.get_ear_protection() >= 2) continue - M.sleeping = 0 + M.SetSleeping(0) M.stuttering += 20 M.ear_deaf += 30 M.Weaken(3) diff --git a/code/game/jobs/access_datum_vr.dm b/code/game/jobs/access_datum_vr.dm index 506666fdfd8..16038248d01 100644 --- a/code/game/jobs/access_datum_vr.dm +++ b/code/game/jobs/access_datum_vr.dm @@ -16,4 +16,15 @@ var/const/access_pilot = 67 id = access_talon desc = "Talon" access_type = ACCESS_TYPE_PRIVATE - \ No newline at end of file + +/var/const/access_xenobotany = 77 +/datum/access/xenobotany + id = access_xenobotany + desc = "Xenobotany Garden" + region = ACCESS_REGION_RESEARCH + +/var/const/access_entertainment = 72 +/datum/access/entertainment + id = access_entertainment + desc = "Entertainment Backstage" + region = ACCESS_REGION_GENERAL \ No newline at end of file diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index 5e715b22e16..7acd36524ba 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -65,7 +65,7 @@ department_flag = CIVILIAN faction = "Station" total_positions = 2 - spawn_positions = 1 + spawn_positions = 2 supervisors = "the Head of Personnel" selection_color = "#515151" access = list(access_hydroponics, access_bar, access_kitchen) diff --git a/code/game/jobs/job/civilian_chaplain.dm b/code/game/jobs/job/civilian_chaplain.dm index 2f208fb5458..93989d2c44f 100644 --- a/code/game/jobs/job/civilian_chaplain.dm +++ b/code/game/jobs/job/civilian_chaplain.dm @@ -40,7 +40,7 @@ new_religion = religion_name switch(lowertext(new_religion)) if("unitarianism") - B.name = "The Talmudic Quran" + B.name = "The Great Canon" if("christianity") B.name = "The Holy Bible" if("judaism") @@ -58,7 +58,7 @@ if("kishari national faith") B.name = "The Scriptures of Kishar" if("pleromanism") - B.name = "The Revised Talmudic Quran" + B.name = "The Revised Great Canon" if("spectralism") B.name = "The Book of the Spark" if("hauler") @@ -69,6 +69,8 @@ B.name = "The Book of the Precursors" if("starlit path of angessa martei") B.name = "Quotations of Exalted Martei" + if("sikhism") + B.name = "Guru Granth Sahib" else B.name = "The Holy Book of [new_religion]" feedback_set_details("religion_name","[new_religion]") @@ -133,6 +135,9 @@ if("Torah") B.icon_state = "torah" B.item_state = "clipboard" + if("Guru") + B.icon_state = "guru" + B.item_state = "clipboard" else B.icon_state = "bible" B.item_state = "bible" diff --git a/code/game/jobs/job/civilian_vr.dm b/code/game/jobs/job/civilian_vr.dm index dae1ffbfcef..4529c7c79ad 100644 --- a/code/game/jobs/job/civilian_vr.dm +++ b/code/game/jobs/job/civilian_vr.dm @@ -57,3 +57,39 @@ /datum/job/chaplain pto_type = PTO_CIVILIAN + + +////////////////////////////////// +// Entertainer +////////////////////////////////// + +/datum/job/entertainer + title = "Entertainer" + flag = ENTERTAINER + departments = list(DEPARTMENT_CIVILIAN) + department_flag = CIVILIAN + faction = "Station" + total_positions = 4 + spawn_positions = 4 + supervisors = "the Head of Personnel" + selection_color = "#515151" + access = list(access_entertainment) + minimal_access = list(access_entertainment) + pto_type = PTO_CIVILIAN + + outfit_type = /decl/hierarchy/outfit/job/assistant + job_description = "An entertainer does just that, entertains! Put on plays, play music, sing songs, tell stories, or read your favorite fanfic." + alt_titles = list("Performer" = /datum/alt_title/performer, "Musician" = /datum/alt_title/musician, "Stagehand" = /datum/alt_title/stagehand) + +// Entertainer Alt Titles +/datum/alt_title/performer + title = "Performer" + title_blurb = "A Performer is someone who performs! Acting, dancing, wrestling, etc!" + +/datum/alt_title/musician + title = "Musician" + title_blurb = "A Musician is someone who makes music! Singing, playing instruments, slam poetry, it's your call!" + +/datum/alt_title/stagehand + title = "Stagehand" + title_blurb = "A Stagehand typically performs everything the rest of the entertainers don't. Operate lights, shutters, windows, or narrate through your voicebox!" \ No newline at end of file diff --git a/code/game/jobs/job/engineering_vr.dm b/code/game/jobs/job/engineering_vr.dm index 0ed001bd28e..e0f106ac804 100644 --- a/code/game/jobs/job/engineering_vr.dm +++ b/code/game/jobs/job/engineering_vr.dm @@ -3,6 +3,16 @@ pto_type = PTO_ENGINEERING dept_time_required = 60 + access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, + access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva, + access_heads, access_construction, + access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload) + + minimal_access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, + access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva, + access_heads, access_construction, + access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload) + /datum/job/engineer pto_type = PTO_ENGINEERING diff --git a/code/game/jobs/job/medical_vr.dm b/code/game/jobs/job/medical_vr.dm index 1a29d1ec9d9..72286ca8809 100644 --- a/code/game/jobs/job/medical_vr.dm +++ b/code/game/jobs/job/medical_vr.dm @@ -3,6 +3,14 @@ pto_type = PTO_MEDICAL dept_time_required = 60 + access = list(access_medical, access_medical_equip, access_morgue, access_genetics, access_heads, + access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce, + access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels) + + minimal_access = list(access_medical, access_medical_equip, access_morgue, access_genetics, access_heads, + access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce, + access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels) + /datum/job/doctor spawn_positions = 5 pto_type = PTO_MEDICAL diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index fa527c8ed95..c0962099150 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -39,7 +39,7 @@ // Research Director Alt Titles /datum/alt_title/research_supervisor title = "Research Supervisor" - + ////////////////////////////////// // Scientist ////////////////////////////////// @@ -105,13 +105,15 @@ outfit_type = /decl/hierarchy/outfit/job/science/xenobiologist job_description = "A Xenobiologist studies esoteric lifeforms, usually in the relative safety of their lab. They attempt to find ways to benefit \ from the byproducts of these lifeforms, and their main subject at present is the Giant Slime." +/*VR edit start alt_titles = list("Xenobotanist" = /datum/alt_title/xenobot) -// Xenibiologist Alt Titles + Xenibiologist Alt Titles /datum/alt_title/xenobot title = "Xenobotanist" title_blurb = "A Xenobotanist grows and cares for a variety of abnormal, custom made, and frequently dangerous plant life. When the products of these plants \ is both safe and beneficial to the station, they may choose to introduce it to the rest of the crew." +VR edit end*/ ////////////////////////////////// // Roboticist diff --git a/code/game/jobs/job/science_vr.dm b/code/game/jobs/job/science_vr.dm index 679fbcbc839..cce9bfdcca5 100644 --- a/code/game/jobs/job/science_vr.dm +++ b/code/game/jobs/job/science_vr.dm @@ -4,13 +4,13 @@ dept_time_required = 60 access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue, - access_tox_storage, access_teleporter, access_sec_doors, + access_tox_storage, access_teleporter, access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage, - access_RC_announce, access_keycard_auth, access_tcomsat, access_xenoarch, access_eva, access_network) + access_RC_announce, access_keycard_auth, access_tcomsat, access_xenoarch, access_eva, access_network, access_xenobotany) minimal_access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue, - access_tox_storage, access_teleporter, access_sec_doors, + access_tox_storage, access_teleporter, access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage, - access_RC_announce, access_keycard_auth, access_tcomsat, access_xenoarch, access_eva, access_network) + access_RC_announce, access_keycard_auth, access_tcomsat, access_xenoarch, access_eva, access_network, access_xenobotany) /datum/job/scientist spawn_positions = 5 @@ -29,4 +29,28 @@ /datum/job/roboticist total_positions = 3 - pto_type = PTO_SCIENCE \ No newline at end of file + pto_type = PTO_SCIENCE + +////////////////////////////////// +// Xenobotanist +////////////////////////////////// +/datum/job/xenobotanist + title = "Xenobotanist" + flag = XENOBOTANIST + departments = list(DEPARTMENT_RESEARCH) + department_flag = MEDSCI + faction = "Station" + total_positions = 2 + spawn_positions = 2 + supervisors = "the Research Director" + selection_color = "#633D63" + economic_modifier = 7 + access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobotany, access_hydroponics) + minimal_access = list(access_research, access_xenobotany, access_hydroponics, access_tox_storage) + pto_type = PTO_SCIENCE + + minimal_player_age = 14 + + outfit_type = /decl/hierarchy/outfit/job/science/xenobiologist + job_description = "A Xenobotanist grows and cares for a variety of abnormal, custom made, and frequently dangerous plant life. When the products of these plants \ + are both safe and beneficial to the station, they may choose to introduce it to the rest of the crew." diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 684e9cc7c1c..a36ad973013 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -77,7 +77,7 @@ spawn_positions = 2 supervisors = "the Head of Security" selection_color = "#601C1C" - access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks) + access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks, access_brig) //Vorestation edit - access_brig minimal_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_eva, access_external_airlocks) economic_modifier = 5 minimal_player_age = 3 diff --git a/code/game/jobs/job/security_vr.dm b/code/game/jobs/job/security_vr.dm index 24b4a333252..4f7604b9371 100644 --- a/code/game/jobs/job/security_vr.dm +++ b/code/game/jobs/job/security_vr.dm @@ -5,11 +5,11 @@ access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers, - access_research, access_engine, access_mining, access_construction, access_mailsorting, + access_construction, access_heads, access_hos, access_RC_announce, access_keycard_auth, access_external_airlocks) minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers, - access_research, access_engine, access_mining, access_construction, access_mailsorting, + access_construction, access_heads, access_hos, access_RC_announce, access_keycard_auth, access_external_airlocks) /datum/job/warden diff --git a/code/game/jobs/job/special_vr.dm b/code/game/jobs/job/special_vr.dm index 99ea67cca2f..5c1a027061a 100644 --- a/code/game/jobs/job/special_vr.dm +++ b/code/game/jobs/job/special_vr.dm @@ -77,10 +77,8 @@ supervisors = "the spirit of laughter" selection_color = "#515151" economic_modifier = 1 - access = list() - minimal_access = list() job_description = "A Clown is there to entertain the crew and keep high morale using various harmless pranks and ridiculous jokes!" - alt_titles = list("Clown" = /datum/alt_title/clown, "Comedian" = /datum/alt_title/comedian, "Jester" = /datum/alt_title/jester) + alt_titles = list("Clown" = /datum/alt_title/clown, "Jester" = /datum/alt_title/jester) whitelist_only = 1 latejoin_only = 1 outfit_type = /decl/hierarchy/outfit/job/clown @@ -89,17 +87,14 @@ /datum/alt_title/clown title = "Clown" -/datum/alt_title/comedian - title = "Comedian" - /datum/alt_title/jester title = "Jester" /datum/job/clown/get_access() if(config.assistant_maint) - return list(access_maint_tunnels) + return list(access_maint_tunnels, access_entertainment) else - return list() + return list(access_entertainment) /datum/job/mime title = "Mime" @@ -112,10 +107,8 @@ supervisors = "the spirit of performance" selection_color = "#515151" economic_modifier = 1 - access = list() - minimal_access = list() job_description = "A Mime is there to entertain the crew and keep high morale using unbelievable performances and acting skills!" - alt_titles = list("Mime" = /datum/alt_title/mime, "Performer" = /datum/alt_title/performer, "Interpretive Dancer" = /datum/alt_title/interpretive_dancer) + alt_titles = list("Mime" = /datum/alt_title/mime, "Interpretive Dancer" = /datum/alt_title/interpretive_dancer) whitelist_only = 1 latejoin_only = 1 outfit_type = /decl/hierarchy/outfit/job/mime @@ -124,14 +117,11 @@ /datum/alt_title/mime title = "Mime" -/datum/alt_title/performer - title = "Performer" - /datum/alt_title/interpretive_dancer title = "Interpretive Dancer" /datum/job/mime/get_access() if(config.assistant_maint) - return list(access_maint_tunnels) + return list(access_maint_tunnels, access_entertainment) else - return list() + return list(access_entertainment) diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index 31450ad2b77..40f0fdb4a41 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -26,6 +26,7 @@ var/const/PSYCHIATRIST =(1<<7) var/const/ROBOTICIST =(1<<8) var/const/XENOBIOLOGIST =(1<<9) var/const/PARAMEDIC =(1<<10) +var/const/XENOBOTANIST =(1<<15) //VOREStation Add var/const/CIVILIAN =(1<<2) @@ -44,6 +45,7 @@ var/const/ASSISTANT =(1<<11) var/const/BRIDGE =(1<<12) var/const/CLOWN =(1<<13) //VOREStation Add var/const/MIME =(1<<14) //VOREStation Add +var/const/ENTERTAINER =(1<<15) //VOREStation Add //VOREStation Add var/const/TALON =(1<<3) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index c19873fd3d8..a97fbf986f7 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -51,7 +51,7 @@ return if(sleeper) - return ui_interact(user) + return tgui_interact(user) /obj/machinery/sleep_console/attackby(var/obj/item/I, var/mob/user) if(computer_deconstruction_screwdriver(user, I)) @@ -66,97 +66,21 @@ else icon_state = initial(icon_state) -/obj/machinery/sleep_console/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = outside_state) - var/data[0] - - var/obj/machinery/sleeper/S = sleeper - var/mob/living/carbon/human/occupant = sleeper.occupant - - data["power"] = S.stat & (NOPOWER|BROKEN) ? 0 : 1 - - var/list/reagents = list() - for(var/T in S.available_chemicals) - var/list/reagent = list() - reagent["id"] = T - reagent["name"] = S.available_chemicals[T] - if(occupant) - reagent["amount"] = occupant.reagents.get_reagent_amount(T) - reagents += list(reagent) - data["reagents"] = reagents.Copy() - - if(occupant) - data["occupant"] = 1 - switch(occupant.stat) - if(CONSCIOUS) - data["stat"] = "Conscious" - if(UNCONSCIOUS) - data["stat"] = "Unconscious" - if(DEAD) - data["stat"] = "Dead" - data["health"] = occupant.health - data["maxHealth"] = occupant.getMaxHealth() - if(iscarbon(occupant)) - var/mob/living/carbon/C = occupant - data["pulse"] = C.get_pulse(GETPULSE_TOOL) - data["brute"] = occupant.getBruteLoss() - data["burn"] = occupant.getFireLoss() - data["oxy"] = occupant.getOxyLoss() - data["tox"] = occupant.getToxLoss() - else - data["occupant"] = 0 - if(S.beaker) - data["beaker"] = S.beaker.reagents.get_free_space() - else - data["beaker"] = -1 - data["filtering"] = S.filtering - data["pump"] = S.pumping - - var/stasis_level_name = "Error!" - for(var/N in S.stasis_choices) - if(S.stasis_choices[N] == S.stasis_level) - stasis_level_name = N - break - data["stasis"] = stasis_level_name - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) +/obj/machinery/sleep_console/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "sleeper.tmpl", "Sleeper UI", 600, 600, state = state) - ui.set_initial_data(data) + ui = new(user, src, "Sleeper", "Sleeper") ui.open() - ui.set_auto_update(1) -/obj/machinery/sleep_console/Topic(href, href_list) - if(..()) - return 1 +/obj/machinery/sleep_console/tgui_data(mob/user) + if(sleeper) + return sleeper.tgui_data(user) + return null - var/obj/machinery/sleeper/S = sleeper - - if(usr == S.occupant) - to_chat(usr, "You can't reach the controls from the inside.") - return - - add_fingerprint(usr) - - if(href_list["eject"]) - S.go_out() - if(href_list["beaker"]) - S.remove_beaker() - if(href_list["sleeper_filter"]) - if(S.filtering != text2num(href_list["sleeper_filter"])) - S.toggle_filter() - if(href_list["pump"]) - if(S.pumping != text2num(href_list["pump"])) - S.toggle_pump() - if(href_list["chemical"] && href_list["amount"]) - if(S.occupant && S.occupant.stat != DEAD) - if(href_list["chemical"] in S.available_chemicals) // Your hacks are bad and you should feel bad - S.inject_chemical(usr, href_list["chemical"], text2num(href_list["amount"])) - if(href_list["change_stasis"]) - var/new_stasis = input("Levels deeper than 50% stasis level will render the patient unconscious.","Stasis Level") as null|anything in S.stasis_choices - if(new_stasis && CanUseTopic(usr, default_state) == STATUS_INTERACTIVE) - S.stasis_level = S.stasis_choices[new_stasis] - - return 1 +/obj/machinery/sleep_console/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state) + if(sleeper) + return sleeper.tgui_act(action, params, ui, state) + return FALSE /obj/machinery/sleeper name = "sleeper" @@ -169,12 +93,19 @@ var/mob/living/carbon/human/occupant = null var/list/available_chemicals = list() var/list/base_chemicals = list("inaprovaline" = "Inaprovaline", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin") + var/amounts = list(5, 10) var/obj/item/weapon/reagent_containers/glass/beaker = null var/filtering = 0 var/pumping = 0 + // Currently never changes. On Paradise, max_chem and min_health are based on the matter bins in the sleeper. + var/max_chem = 20 + var/initial_bin_rating = 1 + var/min_health = -101 var/obj/machinery/sleep_console/console var/stasis_level = 0 //Every 'this' life ticks are applied to the mob (when life_ticks%stasis_level == 1) var/stasis_choices = list("Complete (1%)" = 100, "Deep (10%)" = 10, "Moderate (20%)" = 5, "Light (50%)" = 2, "None (100%)" = 0) + var/controls_inside = FALSE + var/auto_eject_dead = FALSE use_power = USE_POWER_IDLE idle_power_usage = 15 @@ -184,6 +115,7 @@ . = ..() beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) default_apply_parts() + update_icon() /obj/machinery/sleeper/Destroy() if(console) @@ -232,14 +164,187 @@ available_chemicals += new_chemicals return -/obj/machinery/sleeper/Initialize() - . = ..() - update_icon() +/obj/machinery/sleeper/attack_hand(var/mob/user) + if(!controls_inside) + return FALSE + + if(user == occupant) + tgui_interact(user) + +/obj/machinery/sleeper/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Sleeper", "Sleeper") + ui.open() + +/obj/machinery/sleeper/tgui_data(mob/user) + var/data[0] + data["amounts"] = amounts + data["hasOccupant"] = occupant ? 1 : 0 + var/occupantData[0] + // var/crisis = 0 + if(occupant) + occupantData["name"] = occupant.name + occupantData["stat"] = occupant.stat + occupantData["health"] = occupant.health + occupantData["maxHealth"] = occupant.maxHealth + occupantData["minHealth"] = config.health_threshold_dead + occupantData["bruteLoss"] = occupant.getBruteLoss() + occupantData["oxyLoss"] = occupant.getOxyLoss() + occupantData["toxLoss"] = occupant.getToxLoss() + occupantData["fireLoss"] = occupant.getFireLoss() + occupantData["paralysis"] = occupant.paralysis + occupantData["hasBlood"] = 0 + occupantData["bodyTemperature"] = occupant.bodytemperature + occupantData["maxTemp"] = 1000 // If you get a burning vox armalis into the sleeper, congratulations + // Because we can put simple_animals in here, we need to do something tricky to get things working nice + occupantData["temperatureSuitability"] = 0 // 0 is the baseline + if(ishuman(occupant) && occupant.species) + // I wanna do something where the bar gets bluer as the temperature gets lower + // For now, I'll just use the standard format for the temperature status + var/datum/species/sp = occupant.species + if(occupant.bodytemperature < sp.cold_level_3) + occupantData["temperatureSuitability"] = -3 + else if(occupant.bodytemperature < sp.cold_level_2) + occupantData["temperatureSuitability"] = -2 + else if(occupant.bodytemperature < sp.cold_level_1) + occupantData["temperatureSuitability"] = -1 + else if(occupant.bodytemperature > sp.heat_level_3) + occupantData["temperatureSuitability"] = 3 + else if(occupant.bodytemperature > sp.heat_level_2) + occupantData["temperatureSuitability"] = 2 + else if(occupant.bodytemperature > sp.heat_level_1) + occupantData["temperatureSuitability"] = 1 + else if(isanimal(occupant)) + var/mob/living/simple_mob/silly = occupant + if(silly.bodytemperature < silly.minbodytemp) + occupantData["temperatureSuitability"] = -3 + else if(silly.bodytemperature > silly.maxbodytemp) + occupantData["temperatureSuitability"] = 3 + // Blast you, imperial measurement system + occupantData["btCelsius"] = occupant.bodytemperature - T0C + occupantData["btFaren"] = ((occupant.bodytemperature - T0C) * (9.0/5.0))+ 32 + + + // crisis = (occupant.health < min_health) + // I'm not sure WHY you'd want to put a simple_animal in a sleeper, but precedent is precedent + // Runtime is aptly named, isn't she? + if(ishuman(occupant) && !(NO_BLOOD in occupant.species.flags) && occupant.vessel) + occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL) + occupantData["hasBlood"] = 1 + var/blood_volume = round(occupant.vessel.get_reagent_amount("blood")) + occupantData["bloodLevel"] = blood_volume + occupantData["bloodMax"] = occupant.species.blood_volume + occupantData["bloodPercent"] = round(100*(blood_volume/occupant.species.blood_volume), 0.01) //copy pasta ends here + + occupantData["bloodType"] = occupant.dna.b_type + + data["occupant"] = occupantData + data["maxchem"] = max_chem + data["minhealth"] = min_health + data["dialysis"] = filtering + data["stomachpumping"] = pumping + data["auto_eject_dead"] = auto_eject_dead + if(beaker) + data["isBeakerLoaded"] = 1 + if(beaker.reagents) + data["beakerMaxSpace"] = beaker.reagents.maximum_volume + data["beakerFreeSpace"] = beaker.reagents.get_free_space() + else + data["beakerMaxSpace"] = 0 + data["beakerFreeSpace"] = 0 + else + data["isBeakerLoaded"] = FALSE + + + var/stasis_level_name = "Error!" + for(var/N in stasis_choices) + if(stasis_choices[N] == stasis_level) + stasis_level_name = N + break + data["stasis"] = stasis_level_name + + var/chemicals[0] + for(var/re in available_chemicals) + var/datum/reagent/temp = SSchemistry.chemical_reagents[re] + if(temp) + var/reagent_amount = 0 + var/pretty_amount + var/injectable = occupant ? 1 : 0 + var/overdosing = 0 + var/caution = 0 // To make things clear that you're coming close to an overdose + // if(crisis && !(temp.id in emergency_chems)) + // injectable = 0 + + if(occupant && occupant.reagents) + reagent_amount = occupant.reagents.get_reagent_amount(temp.id) + // If they're mashing the highest concentration, they get one warning + if(temp.overdose && reagent_amount + 10 > (temp.overdose * occupant?.species.chemOD_threshold)) + caution = 1 + if(temp.overdose && reagent_amount > (temp.overdose * occupant?.species.chemOD_threshold)) + overdosing = 1 + + pretty_amount = round(reagent_amount, 0.05) + + chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("chemical" = temp.id), "occ_amount" = reagent_amount, "pretty_amount" = pretty_amount, "injectable" = injectable, "overdosing" = overdosing, "od_warning" = caution))) + data["chemicals"] = chemicals + return data + + +/obj/machinery/sleeper/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + if(!controls_inside && usr == occupant) + return + if(panel_open) + to_chat(usr, "Close the maintenance panel first.") + return + + . = TRUE + switch(action) + if("chemical") + if(!occupant) + return + if(occupant.stat == DEAD) + var/datum/gender/G = gender_datums[occupant.get_visible_gender()] + to_chat(usr, "This person has no life to preserve anymore. Take [G.him] to a department capable of reanimating [G.him].") + return + var/chemical = params["chemid"] + var/amount = text2num(params["amount"]) + if(!length(chemical) || amount <= 0) + return + if(occupant.health > min_health) //|| (chemical in emergency_chems)) + inject_chemical(usr, chemical, amount) + else + to_chat(usr, "This person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!") + if("removebeaker") + remove_beaker() + if("togglefilter") + toggle_filter() + if("togglepump") + toggle_pump() + if("ejectify") + go_out() + if("changestasis") + var/new_stasis = input("Levels deeper than 50% stasis level will render the patient unconscious.","Stasis Level") as null|anything in stasis_choices + if(new_stasis) + stasis_level = stasis_choices[new_stasis] + if("auto_eject_dead_on") + auto_eject_dead = TRUE + if("auto_eject_dead_off") + auto_eject_dead = FALSE + else + return FALSE + add_fingerprint(usr) /obj/machinery/sleeper/process() if(stat & (NOPOWER|BROKEN)) return if(occupant) + if(auto_eject_dead && occupant.stat == DEAD) + playsound(loc, 'sound/machines/buzz-sigh.ogg', 40) + go_out() + return occupant.Stasis(stasis_level) if(filtering > 0) @@ -404,9 +509,11 @@ /obj/machinery/sleeper/proc/inject_chemical(var/mob/living/user, var/chemical, var/amount) if(stat & (BROKEN|NOPOWER)) return + if(!(amount in amounts)) + return if(occupant && occupant.reagents) - if(occupant.reagents.get_reagent_amount(chemical) + amount <= 20) + if(occupant.reagents.get_reagent_amount(chemical) + amount <= max_chem) use_power(amount * CHEM_SYNTH_ENERGY) occupant.reagents.add_reagent(chemical, amount) to_chat(user, "Occupant now has [occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in their bloodstream.") diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 482988caf27..a3e4d2eeb30 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -1,7 +1,7 @@ // Pretty much everything here is stolen from the dna scanner FYI /obj/machinery/bodyscanner - var/mob/living/carbon/occupant + var/mob/living/carbon/human/occupant var/locked name = "Body Scanner" icon = 'icons/obj/Cryogenic2.dmi' @@ -14,6 +14,8 @@ active_power_usage = 10000 //10 kW. It's a big all-body scanner. light_color = "#00FF00" var/obj/machinery/body_scanconsole/console + var/known_implants = list(/obj/item/weapon/implant/health, /obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking, /obj/item/weapon/implant/language, /obj/item/weapon/implant/language/eal, /obj/item/weapon/implant/backup, /obj/item/device/nif) //VOREStation Add - Backup Implant, NIF + var/printing_text = null /obj/machinery/bodyscanner/Initialize() . = ..() @@ -57,13 +59,14 @@ update_icon() //icon_state = "body_scanner_1" //VOREStation Edit - Health display for consoles with light and such. add_fingerprint(user) qdel(G) + SStgui.update_uis(src) if(!occupant) if(default_deconstruction_screwdriver(user, G)) return if(default_deconstruction_crowbar(user, G)) return -/obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/O, mob/user as mob) +/obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/human/O, mob/user as mob) if(!istype(O)) return 0 //not a mob if(user.incapacitated()) @@ -99,6 +102,7 @@ occupant = O update_icon() //icon_state = "body_scanner_1" //VOREStation Edit - Health display for consoles with light and such. add_fingerprint(user) + SStgui.update_uis(src) /obj/machinery/bodyscanner/relaymove(mob/user as mob) if(user.incapacitated()) @@ -124,6 +128,7 @@ occupant.loc = src.loc occupant = null update_icon() //icon_state = "body_scanner_1" //VOREStation Edit - Health display for consoles with light and such. + SStgui.update_uis(src) return /obj/machinery/bodyscanner/ex_act(severity) @@ -157,10 +162,362 @@ else return +/obj/machinery/bodyscanner/tgui_host(mob/user) + if(user == occupant) + return src + return console ? console : src + +/obj/machinery/bodyscanner/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BodyScanner", "Body Scanner") + ui.open() + +/obj/machinery/bodyscanner/tgui_data(mob/user) + var/list/data = list() + + data["occupied"] = occupant ? TRUE : FALSE + + var/occupantData[0] + if(occupant && ishuman(occupant)) + update_icon() //VOREStation Edit - Health display for consoles with light and such. + var/mob/living/carbon/human/H = occupant + occupantData["name"] = H.name + occupantData["stat"] = H.stat + occupantData["health"] = H.health + occupantData["maxHealth"] = H.getMaxHealth() + + 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")) + var/blood_max = H.species.blood_volume + bloodData["volume"] = blood_volume + bloodData["percent"] = round(((blood_volume / blood_max)*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, + "overdose" = (R.overdose && R.volume > R.overdose) ? TRUE : FALSE, + ) + else + reagentData = null + + occupantData["reagents"] = reagentData + + var/ingestedData[0] + if(H.ingested.reagent_list.len >= 1) + for(var/datum/reagent/R in H.ingested.reagent_list) + ingestedData[++ingestedData.len] = list( + "name" = R.name, + "amount" = R.volume, + "overdose" = (R.overdose && R.volume > R.overdose) ? TRUE : FALSE, + ) + else + ingestedData = null + + occupantData["ingested"] = ingestedData + + 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 + organData["totalLoss"] = E.brute_dam + E.burn_dam + organData["maxHealth"] = E.max_damage + organData["bruised"] = E.min_bruised_damage + organData["broken"] = E.min_broken_damage + + 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.robotic >= ORGAN_ROBOT) + organStatus["robotic"] = 1 + if(E.splinted) + organStatus["splinted"] = 1 + if(E.status & ORGAN_BLEEDING) + organStatus["bleeding"] = 1 + if(E.status & ORGAN_DEAD) + organStatus["dead"] = 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 + organData["desc"] = null + organData["germ_level"] = I.germ_level + organData["damage"] = I.damage + organData["maxHealth"] = I.max_damage + organData["bruised"] = I.min_bruised_damage + organData["broken"] = I.min_broken_damage + organData["robotic"] = (I.robotic >= ORGAN_ROBOT) + organData["dead"] = (I.status & ORGAN_DEAD) + + 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 + + return data + +/obj/machinery/bodyscanner/tgui_act(action, params) + if(..()) + return TRUE + + . = TRUE + switch(action) + if("ejectify") + eject() + if("print_p") + var/atom/target = console ? console : src + visible_message("[target] rattles and prints out a sheet of paper.") + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(target)) + var/name = occupant ? occupant.name : "Unknown" + P.info = "
Body Scan - [name]

" + P.info += "Time of scan: [worldtime2stationtime(world.time)]

" + P.info += "[generate_printing_text()]" + P.info += "

Notes:
" + P.name = "Body Scan - [name] ([worldtime2stationtime(world.time)]" + else + return FALSE + +/obj/machinery/bodyscanner/proc/generate_printing_text() + var/dat = "" + + 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 += " (occupant.getMaxHealth() / 2) ? "blue" : "red"]>\tHealth %: [(occupant.health / occupant.getMaxHealth())*100], ([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_max = occupant.species.blood_volume + var/blood_percent = blood_volume / blood_max + 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.reagent_list) + dat += "Reagent: [R.name], Amount: [R.volume]
" + + if(occupant.ingested) + for(var/datum/reagent/R in occupant.ingested.reagent_list) + dat += "Stomach: [R.name], Amount: [R.volume]
" + + dat += "
" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + 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 = "" + var/o_dead = "" + 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.splinted) + splint = "Splinted:" + if(e.status & ORGAN_BLEEDING) + bled = "Bleeding:" + if(e.status & ORGAN_BROKEN) + AN = "[e.broken_description]:" + if(e.robotic >= ORGAN_ROBOT) + robot = "Prosthetic:" + if(e.status & ORGAN_DEAD) + o_dead = "Necrotic:" + 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_THREE - 50) + infected = "Acute Infection++:" + if (INFECTION_LEVEL_THREE -49 to INFINITY) + infected = "Gangrene Detected:" + + 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 += "" + else + dat += "" + dat += "" + for(var/obj/item/organ/i in occupant.internal_organs) + var/mech = "" + var/i_dead = "" + if(i.status & ORGAN_ASSISTED) + mech = "Assisted:" + if(i.robotic >= ORGAN_ROBOT) + mech = "Mechanical:" + if(i.status & ORGAN_DEAD) + i_dead = "Necrotic:" + var/infection = "None" + switch (i.germ_level) + if (INFECTION_LEVEL_ONE 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 INFECTION_LEVEL_THREE - 50) + infection = "Acute Infection++:" + if (INFECTION_LEVEL_THREE -49 to INFINITY) + infection = "Necrosis Detected:" + + dat += "" + dat += "" + dat += "" + dat += "
OrganBurn DamageBrute DamageOther Wounds
[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured][o_dead][e.name]--Not Found
[i.name]N/A[i.damage][infection]:[mech][i_dead]
" + if(occupant.sdisabilities & BLIND) + dat += "Cataracts detected.
" + if(occupant.disabilities & NEARSIGHTED) + dat += "Retinal misalignment detected.
" + else + dat += "\The [src] is empty." + + return dat + //Body Scan Console /obj/machinery/body_scanconsole var/obj/machinery/bodyscanner/scanner - var/known_implants = list(/obj/item/weapon/implant/health, /obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking, /obj/item/weapon/implant/language, /obj/item/weapon/implant/language/eal, /obj/item/weapon/implant/backup, /obj/item/device/nif) //VOREStation Add - Backup Implant, NIF var/delete var/temphtml name = "Body Scanner Console" @@ -171,7 +528,6 @@ anchored = 1 circuit = /obj/item/weapon/circuitboard/scanner_console var/printing = null - var/printing_text = null /obj/machinery/body_scanconsole/New() ..() @@ -257,344 +613,9 @@ to_chat(user, "Scanner not found!") return - if (scanner.panel_open) + if(scanner.panel_open) to_chat(user, "Close the maintenance panel first.") return if(scanner) - return ui_interact(user) - -/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"] = scanner ? 1 : 0 - - if(scanner) - data["occupied"] = scanner.occupant ? 1 : 0 - - var/occupantData[0] - if(scanner.occupant && ishuman(scanner.occupant)) - update_icon() //VOREStation Edit - Health display for consoles with light and such. - var/mob/living/carbon/human/H = scanner.occupant - occupantData["name"] = H.name - occupantData["stat"] = H.stat - occupantData["health"] = H.health - occupantData["maxHealth"] = H.getMaxHealth() - - 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")) - var/blood_max = H.species.blood_volume - bloodData["volume"] = blood_volume - bloodData["percent"] = round(((blood_volume / blood_max)*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/ingestedData[0] - if(H.ingested.reagent_list.len >= 1) - for(var/datum/reagent/R in H.ingested.reagent_list) - ingestedData[++ingestedData.len] = list("name" = R.name, "amount" = R.volume) - else - ingestedData = null - - occupantData["ingested"] = ingestedData - - 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.robotic >= ORGAN_ROBOT) - organStatus["robotic"] = 1 - if(E.splinted) - organStatus["splinted"] = 1 - if(E.status & ORGAN_BLEEDING) - organStatus["bleeding"] = 1 - if(E.status & ORGAN_DEAD) - organStatus["dead"] = 1 - for(var/datum/wound/W in E.wounds) - if(W.internal) - organStatus["internalBleeding"] = 1 - break - - organData["status"] = organStatus - - if(istype(E, /obj/item/organ/external/chest) && H.is_lung_ruptured()) - organData["lungRuptured"] = 1 - - 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 - organData["desc"] = null - organData["germ_level"] = I.germ_level - organData["damage"] = I.damage - - intOrganData.Add(list(organData)) - - occupantData["intOrgan"] = intOrganData - - occupantData["blind"] = (H.sdisabilities & BLIND) - occupantData["nearsighted"] = (H.disabilities & NEARSIGHTED) - occupantData = attempt_vr(scanner,"get_occupant_data_vr",list(occupantData,H)) //VOREStation Insert - data["occupant"] = occupantData - - ui = SSnanoui.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: [worldtime2stationtime(world.time)]

" - P.info += "[printing_text]" - P.info += "

Notes:
" - P.name = "Body Scan - [href_list["name"]] ([worldtime2stationtime(world.time)])" - printing = null - printing_text = null - -/obj/machinery/body_scanconsole/proc/generate_printing_text() - var/dat = "" - - if(scanner) - var/mob/living/carbon/human/occupant = scanner.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 += " (occupant.getMaxHealth() / 2) ? "blue" : "red"]>\tHealth %: [(occupant.health / occupant.getMaxHealth())*100], ([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_max = occupant.species.blood_volume - var/blood_percent = blood_volume / blood_max - 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.reagent_list) - dat += "Reagent: [R.name], Amount: [R.volume]
" - - if(occupant.ingested) - for(var/datum/reagent/R in occupant.ingested.reagent_list) - dat += "Stomach: [R.name], Amount: [R.volume]
" - - dat += "
" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - 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 = "" - var/o_dead = "" - 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.splinted) - splint = "Splinted:" - if(e.status & ORGAN_BLEEDING) - bled = "Bleeding:" - if(e.status & ORGAN_BROKEN) - AN = "[e.broken_description]:" - if(e.robotic >= ORGAN_ROBOT) - robot = "Prosthetic:" - if(e.status & ORGAN_DEAD) - o_dead = "Necrotic:" - 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_THREE - 50) - infected = "Acute Infection++:" - if (INFECTION_LEVEL_THREE -49 to INFINITY) - infected = "Gangrene Detected:" - - 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 += "" - else - dat += "" - dat += "" - for(var/obj/item/organ/i in occupant.internal_organs) - var/mech = "" - var/i_dead = "" - if(i.status & ORGAN_ASSISTED) - mech = "Assisted:" - if(i.robotic >= ORGAN_ROBOT) - mech = "Mechanical:" - if(i.status & ORGAN_DEAD) - i_dead = "Necrotic:" - var/infection = "None" - switch (i.germ_level) - if (INFECTION_LEVEL_ONE 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 INFECTION_LEVEL_THREE - 50) - infection = "Acute Infection++:" - if (INFECTION_LEVEL_THREE -49 to INFINITY) - infection = "Necrosis Detected:" - - dat += "" - dat += "" - dat += "" - dat += "
OrganBurn DamageBrute DamageOther Wounds
[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured][o_dead][e.name]--Not Found
[i.name]N/A[i.damage][infection]:[mech][i_dead]
" - if(occupant.sdisabilities & BLIND) - dat += "Cataracts detected.
" - if(occupant.disabilities & NEARSIGHTED) - dat += "Retinal misalignment detected.
" - else - dat += "\The [src] is empty." - else - dat = " Error: No Body Scanner connected." - - printing_text = dat + return scanner.tgui_interact(user) diff --git a/code/game/machinery/adv_med_vr.dm b/code/game/machinery/adv_med_vr.dm index 6c11b6cf34e..c7bcf0d0657 100644 --- a/code/game/machinery/adv_med_vr.dm +++ b/code/game/machinery/adv_med_vr.dm @@ -7,7 +7,7 @@ icon_state = "scanner_terminal_off" density = 1 -/obj/machinery/bodyscanner/proc/get_occupant_data_vr(list/incoming,mob/living/carbon/human/H) +/obj/machinery/bodyscanner/proc/get_occupant_data_vr(list/incoming, mob/living/carbon/human/H) var/humanprey = 0 var/livingprey = 0 var/objectprey = 0 diff --git a/code/game/machinery/air_alarm.dm b/code/game/machinery/air_alarm.dm index 82e534ba2ad..280020b456c 100644 --- a/code/game/machinery/air_alarm.dm +++ b/code/game/machinery/air_alarm.dm @@ -125,6 +125,7 @@ // breathable air according to human/Life() TLV["oxygen"] = list(16, 19, 135, 140) // Partial pressure, kpa + TLV["nitrogen"] = list(0, 0,135,140) // Partial pressure, kpa TLV["carbon dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa TLV["phoron"] = list(-1.0, -1.0, 0, 0.5) // Partial pressure, kpa TLV["other"] = list(-1.0, -1.0, 0.5, 1.0) // Partial pressure, kpa @@ -463,7 +464,7 @@ frequency.post_signal(src, alert_signal) /obj/machinery/alarm/attack_ai(mob/user) - ui_interact(user) + tgui_interact(user) /obj/machinery/alarm/attack_hand(mob/user) . = ..() @@ -472,157 +473,150 @@ return interact(user) /obj/machinery/alarm/interact(mob/user) - ui_interact(user) + tgui_interact(user) wires.Interact(user) -/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state) - var/data[0] - var/remote_connection = 0 - var/remote_access = 0 - if(state) - var/list/href = state.href_list(user) - remote_connection = href["remote_connection"] // Remote connection means we're non-adjacent/connecting from another computer - remote_access = href["remote_access"] // Remote access means we also have the privilege to alter the air alarm. +/obj/machinery/alarm/tgui_status(mob/user) + if(isAI(user) && aidisabled) + to_chat(user, "AI control has been disabled.") + else if(!shorted) + return ..() + return STATUS_CLOSE - data["locked"] = locked && !issilicon(user) - data["remote_connection"] = remote_connection - data["remote_access"] = remote_access - data["rcon"] = rcon_setting - data["screen"] = screen - - populate_status(data) - - if(!(locked && !remote_connection) || remote_access || issilicon(user)) - populate_controls(data) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) +/obj/machinery/alarm/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/state) + ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, ui_key, "air_alarm.tmpl", name, 325, 625, master_ui = master_ui, state = state) - ui.set_initial_data(data) + ui = new(user, src, "AirAlarm", name, parent_ui) + if(state) + ui.set_state(state) ui.open() - ui.set_auto_update(1) -/obj/machinery/alarm/proc/populate_status(var/data) - var/turf/location = get_turf(src) - var/datum/gas_mixture/environment = location.return_air() - var/total = environment.total_moles +/obj/machinery/alarm/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = list( + "locked" = locked, + "siliconUser" = issilicon(user), + "remoteUser" = !!ui.parent_ui, + "danger_level" = danger_level, + "target_temperature" = "[target_temperature - T0C]C", + "rcon" = rcon_setting, + ) - var/list/environment_data = new - data["has_environment"] = total - if(total) - var/pressure = environment.return_pressure() - environment_data[++environment_data.len] = list("name" = "Pressure", "value" = pressure, "unit" = "kPa", "danger_level" = pressure_dangerlevel) - environment_data[++environment_data.len] = list("name" = "Oxygen", "value" = environment.gas["oxygen"] / total * 100, "unit" = "%", "danger_level" = oxygen_dangerlevel) - environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon_dioxide"] / total * 100, "unit" = "%", "danger_level" = co2_dangerlevel) - environment_data[++environment_data.len] = list("name" = "Toxins", "value" = environment.gas["phoron"] / total * 100, "unit" = "%", "danger_level" = phoron_dangerlevel) - environment_data[++environment_data.len] = list("name" = "Temperature", "value" = environment.temperature, "unit" = "K ([round(environment.temperature - T0C, 0.1)]C)", "danger_level" = temperature_dangerlevel) - data["total_danger"] = danger_level - data["environment"] = environment_data - data["atmos_alarm"] = alarm_area.atmosalm - data["fire_alarm"] = alarm_area.fire != null - data["target_temperature"] = "[target_temperature - T0C]C" + var/area/A = get_area(src) + data["atmos_alarm"] = A?.atmosalm + data["fire_alarm"] = A?.fire -/obj/machinery/alarm/proc/populate_controls(var/list/data) - switch(screen) - if(AALARM_SCREEN_MAIN) - data["mode"] = mode - if(AALARM_SCREEN_VENT) - var/vents[0] - for(var/id_tag in alarm_area.air_vent_names) - var/long_name = alarm_area.air_vent_names[id_tag] - var/list/info = alarm_area.air_vent_info[id_tag] - if(!info) - continue - vents[++vents.len] = list( - "id_tag" = id_tag, - "long_name" = sanitize(long_name), - "power" = info["power"], - "checks" = info["checks"], - "direction" = info["direction"], - "external" = info["external"] - ) - data["vents"] = vents - if(AALARM_SCREEN_SCRUB) - var/scrubbers[0] - for(var/id_tag in alarm_area.air_scrub_names) - var/long_name = alarm_area.air_scrub_names[id_tag] - var/list/info = alarm_area.air_scrub_info[id_tag] - if(!info) - continue - scrubbers[++scrubbers.len] = list( - "id_tag" = id_tag, - "long_name" = sanitize(long_name), - "power" = info["power"], - "scrubbing" = info["scrubbing"], - "panic" = info["panic"], - "filters" = list() - ) - scrubbers[scrubbers.len]["filters"] += list(list("name" = "Oxygen", "command" = "o2_scrub", "val" = info["filter_o2"])) - scrubbers[scrubbers.len]["filters"] += list(list("name" = "Nitrogen", "command" = "n2_scrub", "val" = info["filter_n2"])) - scrubbers[scrubbers.len]["filters"] += list(list("name" = "Carbon Dioxide", "command" = "co2_scrub","val" = info["filter_co2"])) - scrubbers[scrubbers.len]["filters"] += list(list("name" = "Toxin" , "command" = "tox_scrub","val" = info["filter_phoron"])) - scrubbers[scrubbers.len]["filters"] += list(list("name" = "Nitrous Oxide", "command" = "n2o_scrub","val" = info["filter_n2o"])) - scrubbers[scrubbers.len]["filters"] += list(list("name" = "Fuel", "command" = "fuel_scrub","val" = info["filter_fuel"])) - data["scrubbers"] = scrubbers - if(AALARM_SCREEN_MODE) - var/modes[0] - modes[++modes.len] = list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0) - modes[++modes.len] = list("name" = "Replace Air - Siphons out air while replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 0) - modes[++modes.len] = list("name" = "Panic - Siphons air out of the room", "mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1) - modes[++modes.len] = list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_CYCLE, "selected" = mode == AALARM_MODE_CYCLE, "danger" = 1) - modes[++modes.len] = list("name" = "Fill - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FILL, "selected" = mode == AALARM_MODE_FILL, "danger" = 0) - modes[++modes.len] = list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0) - data["modes"] = modes - data["mode"] = mode - if(AALARM_SCREEN_SENSORS) - var/list/selected - var/thresholds[0] + var/turf/T = get_turf(src) + var/datum/gas_mixture/environment = T.return_air() - var/list/gas_names = list( - "oxygen" = "O2", - "carbon dioxide" = "CO2", - "phoron" = "Toxin", - "other" = "Other") - for(var/g in gas_names) - thresholds[++thresholds.len] = list("name" = gas_names[g], "settings" = list()) - selected = TLV[g] - for(var/i = 1, i <= 4, i++) - thresholds[thresholds.len]["settings"] += list(list("env" = g, "val" = i, "selected" = selected[i])) + data["environment_data"] = list() + var/pressure = environment.return_pressure() + data["environment_data"] += list(list( + "name" = "Pressure", + "value" = pressure, + "unit" = "kPa", + "danger_level" = get_danger_level(pressure, TLV["pressure"]) + )) + var/temperature = environment.temperature + data["environment_data"] += list(list( + "name" = "Temperature", + "value" = temperature, + "unit" = "K ([round(temperature - T0C, 0.1)]C)", + "danger_level" = get_danger_level(temperature, TLV["temperature"]) + )) - selected = TLV["pressure"] - thresholds[++thresholds.len] = list("name" = "Pressure", "settings" = list()) + var/total_moles = environment.total_moles + var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume + for(var/gas_id in environment.gas) + if(!(gas_id in TLV)) + continue + data["environment_data"] += list(list( + "name" = gas_id, + "value" = environment.gas[gas_id] / total_moles * 100, + "unit" = "%", + "danger_level" = get_danger_level(environment.gas[gas_id] * partial_pressure, TLV[gas_id]) + )) + + if(!locked || issilicon(user) || data["remoteUser"]) + data["vents"] = list() + for(var/id_tag in A.air_vent_names) + var/long_name = A.air_vent_names[id_tag] + var/list/info = A.air_vent_info[id_tag] + if(!info) + continue + data["vents"] += list(list( + "id_tag" = id_tag, + "long_name" = sanitize(long_name), + "power" = info["power"], + "checks" = info["checks"], + "excheck" = info["checks"]&1, + "incheck" = info["checks"]&2, + "direction" = info["direction"], + "external" = info["external"], + "internal" = info["internal"], + "extdefault"= (info["external"] == ONE_ATMOSPHERE), + "intdefault"= (info["internal"] == 0), + )) + + data["scrubbers"] = list() + for(var/id_tag in alarm_area.air_scrub_names) + var/long_name = alarm_area.air_scrub_names[id_tag] + var/list/info = alarm_area.air_scrub_info[id_tag] + if(!info) + continue + data["scrubbers"] += list(list( + "id_tag" = id_tag, + "long_name" = sanitize(long_name), + "power" = info["power"], + "scrubbing" = info["scrubbing"], + "panic" = info["panic"], + "filters" = list() + )) + data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Oxygen", "command" = "o2_scrub", "val" = info["filter_o2"])) + data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Nitrogen", "command" = "n2_scrub", "val" = info["filter_n2"])) + data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Carbon Dioxide", "command" = "co2_scrub","val" = info["filter_co2"])) + data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Toxin" , "command" = "tox_scrub","val" = info["filter_phoron"])) + data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Nitrous Oxide", "command" = "n2o_scrub","val" = info["filter_n2o"])) + data["scrubbers"][data["scrubbers"].len]["filters"] += list(list("name" = "Fuel", "command" = "fuel_scrub","val" = info["filter_fuel"])) + + var/list/modes = list() + data["mode"] = mode + modes[++modes.len] = list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0) + modes[++modes.len] = list("name" = "Replace Air - Siphons out air while replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 0) + modes[++modes.len] = list("name" = "Panic - Siphons air out of the room", "mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1) + modes[++modes.len] = list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_CYCLE, "selected" = mode == AALARM_MODE_CYCLE, "danger" = 1) + modes[++modes.len] = list("name" = "Fill - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FILL, "selected" = mode == AALARM_MODE_FILL, "danger" = 0) + modes[++modes.len] = list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0) + data["modes"] = modes + + var/list/selected + var/list/thresholds = list() + + var/list/gas_names = list("oxygen", "carbon dioxide", "phoron", "other") + for(var/g in gas_names) + thresholds[++thresholds.len] = list("name" = g, "settings" = list()) + selected = TLV[g] for(var/i = 1, i <= 4, i++) - thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = i, "selected" = selected[i])) + thresholds[thresholds.len]["settings"] += list(list("env" = g, "val" = i, "selected" = selected[i])) - selected = TLV["temperature"] - thresholds[++thresholds.len] = list("name" = "Temperature", "settings" = list()) - for(var/i = 1, i <= 4, i++) - thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = i, "selected" = selected[i])) + selected = TLV["pressure"] + thresholds[++thresholds.len] = list("name" = "Pressure", "settings" = list()) + for(var/i = 1, i <= 4, i++) + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = i, "selected" = selected[i])) - data["thresholds"] = thresholds + selected = TLV["temperature"] + thresholds[++thresholds.len] = list("name" = "Temperature", "settings" = list()) + for(var/i = 1, i <= 4, i++) + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = i, "selected" = selected[i])) -/obj/machinery/alarm/CanUseTopic(var/mob/user, var/datum/topic_state/state, var/href_list = list()) - if(aidisabled && isAI(user)) - to_chat(user, "AI control for \the [src] interface has been disabled.") - return STATUS_CLOSE + data["thresholds"] = thresholds + return data - . = shorted ? STATUS_DISABLED : STATUS_INTERACTIVE +/obj/machinery/alarm/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE - if(. == STATUS_INTERACTIVE) - var/extra_href = state.href_list(usr) - // Prevent remote users from altering RCON settings unless they already have access - if(href_list["rcon"] && extra_href["remote_connection"] && !extra_href["remote_access"]) - . = STATUS_UPDATE - - return min(..(), .) - -/obj/machinery/alarm/Topic(href, href_list, var/datum/topic_state/state) - if(..(href, href_list, state)) - return 1 - - // hrefs that can always be called -walter0o - if(href_list["rcon"]) - var/attempted_rcon_setting = text2num(href_list["rcon"]) + if(action == "rcon") + var/attempted_rcon_setting = text2num(params["rcon"]) switch(attempted_rcon_setting) if(RCON_NO) @@ -631,9 +625,9 @@ rcon_setting = RCON_AUTO if(RCON_YES) rcon_setting = RCON_YES - return 1 + return TRUE - if(href_list["temperature"]) + if(action == "temperature") var/list/selected = TLV["temperature"] var/max_temperature = min(selected[3] - T0C, MAX_TEMPERATURE) var/min_temperature = max(selected[2] - T0C, MIN_TEMPERATURE) @@ -643,119 +637,118 @@ to_chat(usr, "Temperature must be between [min_temperature]C and [max_temperature]C") else target_temperature = input_temperature + T0C - return 1 + return TRUE + + // Account for remote users here. + // Yes, this is kinda snowflaky; however, I would argue it would be far more snowflakey + // to include "custom hrefs" and all the other bullshit that nano states have just for the + // like, two UIs, that want remote access to other UIs. + if((locked && !issilicon(usr) && !istype(state, /datum/tgui_state/air_alarm_remote)) || (issilicon(usr) && aidisabled)) + return - // hrefs that need the AA unlocked -walter0o - var/extra_href = state.href_list(usr) - if(!(locked && !extra_href["remote_connection"]) || extra_href["remote_access"] || issilicon(usr)) - if(href_list["command"]) - var/device_id = href_list["id_tag"] - switch(href_list["command"]) - if("set_external_pressure") - var/input_pressure = input("What pressure you like the system to mantain?", "Pressure Controls") as num|null - if(isnum(input_pressure)) - send_signal(device_id, list(href_list["command"] = input_pressure)) - return 1 + var/device_id = params["id_tag"] + switch(action) + if("lock") + if(issilicon(usr) && !wires.is_cut(WIRE_IDSCAN)) + locked = !locked + . = TRUE + if( "power", + "o2_scrub", + "n2_scrub", + "co2_scrub", + "tox_scrub", + "n2o_scrub", + "fuel_scrub", + "panic_siphon", + "scrubbing", + "direction") + send_signal(device_id, list("[action]" = text2num(params["val"])), usr) + . = TRUE + if("excheck") + send_signal(device_id, list("checks" = text2num(params["val"])^1), usr) + . = TRUE + if("incheck") + send_signal(device_id, list("checks" = text2num(params["val"])^2), usr) + . = TRUE + if("set_external_pressure", "set_internal_pressure") + var/target = params["value"] + if(!isnull(target)) + send_signal(device_id, list("[action]" = target), usr) + . = TRUE + if("reset_external_pressure") + send_signal(device_id, list("reset_external_pressure"), usr) + . = TRUE + if("reset_internal_pressure") + send_signal(device_id, list("reset_internal_pressure"), usr) + . = TRUE + if("threshold") + var/env = params["env"] - if("reset_external_pressure") - send_signal(device_id, list(href_list["command"] = ONE_ATMOSPHERE)) - return 1 - - if( "power", - "adjust_external_pressure", - "checks", - "o2_scrub", - "n2_scrub", - "co2_scrub", - "tox_scrub", - "n2o_scrub", - "fuel_scrub", - "panic_siphon", - "scrubbing", - "direction") - - send_signal(device_id, list(href_list["command"] = text2num(href_list["val"]))) - return 1 - - if("set_threshold") - var/env = href_list["env"] - var/threshold = text2num(href_list["var"]) - var/list/selected = TLV[env] - var/list/thresholds = list("lower bound", "low warning", "high warning", "upper bound") - var/newval = input("Enter [thresholds[threshold]] for [env]", "Alarm triggers", selected[threshold]) as null | num - if(isnull(newval)) - return 1 - if(newval<0) - selected[threshold] = -1.0 - else if(env=="temperature" && newval>5000) - selected[threshold] = 5000 - else if(env=="pressure" && newval>50*ONE_ATMOSPHERE) - selected[threshold] = 50*ONE_ATMOSPHERE - else if(env!="temperature" && env!="pressure" && newval>200) - selected[threshold] = 200 - else - newval = round(newval,0.01) - selected[threshold] = newval - if(threshold == 1) - if(selected[1] > selected[2]) - selected[2] = selected[1] - if(selected[1] > selected[3]) - selected[3] = selected[1] - if(selected[1] > selected[4]) - selected[4] = selected[1] - if(threshold == 2) - if(selected[1] > selected[2]) - selected[1] = selected[2] - if(selected[2] > selected[3]) - selected[3] = selected[2] - if(selected[2] > selected[4]) - selected[4] = selected[2] - if(threshold == 3) - if(selected[1] > selected[3]) - selected[1] = selected[3] - if(selected[2] > selected[3]) - selected[2] = selected[3] - if(selected[3] > selected[4]) - selected[4] = selected[3] - if(threshold == 4) - if(selected[1] > selected[4]) - selected[1] = selected[4] - if(selected[2] > selected[4]) - selected[2] = selected[4] - if(selected[3] > selected[4]) - selected[3] = selected[4] - - apply_mode() - return 1 - - if(href_list["screen"]) - screen = text2num(href_list["screen"]) - return 1 - - if(href_list["atmos_unlock"]) - switch(href_list["atmos_unlock"]) - if("0") - alarm_area.firedoors_close() - if("1") - alarm_area.firedoors_open() - return 1 - - if(href_list["atmos_alarm"]) + var/name = params["var"] + var/value = input("New [name] for [env]:", name, TLV[env][name]) as num|null + if(!isnull(value) && !..()) + if(value < 0) + TLV[env][name] = -1 + else + TLV[env][name] = round(value, 0.01) + clamp_tlv_values(env, name) + // investigate_log(" treshold value for [env]:[name] was set to [value] by [key_name(usr)]",INVESTIGATE_ATMOS) + . = TRUE + if("mode") + mode = text2num(params["mode"]) + // investigate_log("was turned to [get_mode_name(mode)] mode by [key_name(usr)]",INVESTIGATE_ATMOS) + apply_mode(usr) + . = TRUE + if("alarm") if(alarm_area.atmosalert(2, src)) apply_danger_level(2) - update_icon() - return 1 + . = TRUE + if("reset") + atmos_reset() + . = TRUE + update_icon() - if(href_list["atmos_reset"]) - if(alarm_area.atmosalert(0, src)) - apply_danger_level(0) - update_icon() - return 1 +// This big ol' mess just ensures that TLV always makes sense. If you set the max value below the min value, +// it'll automatically update all the other values to keep it sane. +/obj/machinery/alarm/proc/clamp_tlv_values(env, changed_threshold) + var/list/selected = TLV[env] + switch(changed_threshold) + if(1) + if(selected[1] > selected[2]) + selected[2] = selected[1] + if(selected[1] > selected[3]) + selected[3] = selected[1] + if(selected[1] > selected[4]) + selected[4] = selected[1] + if(2) + if(selected[1] > selected[2]) + selected[1] = selected[2] + if(selected[2] > selected[3]) + selected[3] = selected[2] + if(selected[2] > selected[4]) + selected[4] = selected[2] + if(3) + if(selected[1] > selected[3]) + selected[1] = selected[3] + if(selected[2] > selected[3]) + selected[2] = selected[3] + if(selected[3] > selected[4]) + selected[4] = selected[3] + if(4) + if(selected[1] > selected[4]) + selected[1] = selected[4] + if(selected[2] > selected[4]) + selected[2] = selected[4] + if(selected[3] > selected[4]) + selected[3] = selected[4] - if(href_list["mode"]) - mode = text2num(href_list["mode"]) - apply_mode() - return 1 + + + +/obj/machinery/alarm/proc/atmos_reset() + if(alarm_area.atmosalert(0, src)) + apply_danger_level(0) + update_icon() /obj/machinery/alarm/attackby(obj/item/W as obj, mob/user as mob) add_fingerprint(user) @@ -773,7 +766,7 @@ to_chat(user, "It does nothing.") return else - if(allowed(usr) && !wires.IsIndexCut(AALARM_WIRE_IDSCAN)) + if(allowed(usr) && !wires.is_cut(WIRE_IDSCAN)) locked = !locked to_chat(user, "You [locked ? "lock" : "unlock"] the Air Alarm interface.") else @@ -788,3 +781,14 @@ ..() spawn(rand(0,15)) update_icon() + +// VOREStation Edit Start +/obj/machinery/alarm/freezer + target_temperature = T0C - 13.15 // Chilly freezer room + +/obj/machinery/alarm/freezer/first_run() + . = ..() + + TLV["temperature"] = list(T0C - 40, T0C - 20, T0C + 40, T0C + 66) // K, Lower Temperature for Freezer Air Alarms (This is because TLV is hardcoded to be generated on first_run, and therefore the only way to modify this without changing TLV generation) + +// VOREStation Edit End \ No newline at end of file diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 5ebcfeef430..2d87fcd45aa 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -94,7 +94,7 @@ obj/machinery/computer/general_air_control/Destroy() if(..(user)) return - ui_interact(user) + tgui_interact(user) /obj/machinery/computer/general_air_control/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -104,9 +104,13 @@ obj/machinery/computer/general_air_control/Destroy() sensor_information[id_tag] = signal.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) +/obj/machinery/computer/general_air_control/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "GeneralAtmoControl", name) + ui.open() +/obj/machinery/computer/general_air_control/tgui_data(mob/user) var/list/data = list() var/sensors_ui[0] if(sensors.len) @@ -119,12 +123,7 @@ obj/machinery/computer/general_air_control/Destroy() data["sensors"] = sensors_ui - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "atmo_control.tmpl", name, 525, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(5) + return data /obj/machinery/computer/general_air_control/proc/set_frequency(new_frequency) radio_controller.remove_object(src, frequency) @@ -147,20 +146,9 @@ 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/tgui_data(mob/user) + var/list/data = ..() - 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["tanks"] = 1 if(input_info) @@ -175,13 +163,10 @@ obj/machinery/computer/general_air_control/Destroy() data["input_flow_setting"] = round(input_flow_setting, 0.1) data["pressure_setting"] = pressure_setting + data["max_pressure"] = 50*ONE_ATMOSPHERE + data["max_flowrate"] = ATMOS_DEFAULT_VOLUME_PUMP + 500 - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "atmo_control.tmpl", name, 660, 500) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(5) + return data /obj/machinery/computer/general_air_control/large_tank_control/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -195,54 +180,56 @@ obj/machinery/computer/general_air_control/Destroy() else ..(signal) -/obj/machinery/computer/general_air_control/large_tank_control/Topic(href, href_list) +/obj/machinery/computer/general_air_control/large_tank_control/tgui_act(action, params) if(..()) - return 1 + return TRUE - if(href_list["adj_pressure"]) - var/change = text2num(href_list["adj_pressure"]) - pressure_setting = between(0, pressure_setting + change, 50*ONE_ATMOSPHERE) - return 1 + switch(action) + if("adj_pressure") + var/new_pressure = text2num(params["adj_pressure"]) + pressure_setting = between(0, new_pressure, 50*ONE_ATMOSPHERE) + return TRUE - 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 - return 1 + if("adj_input_flow_rate") + var/new_flow = text2num(params["adj_input_flow_rate"]) + input_flow_setting = between(0, new_flow, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors + return TRUE if(!radio_connection) - return 0 + return FALSE var/datum/signal/signal = new signal.transmission_method = TRANSMISSION_RADIO //radio signal signal.source = src - if(href_list["in_refresh_status"]) - input_info = null - signal.data = list ("tag" = input_tag, "status" = 1) - . = 1 + switch(action) + if("in_refresh_status") + input_info = null + signal.data = list ("tag" = input_tag, "status" = 1) + . = TRUE - if(href_list["in_toggle_injector"]) - input_info = null - signal.data = list ("tag" = input_tag, "power_toggle" = 1) - . = 1 + if("in_toggle_injector") + input_info = null + signal.data = list ("tag" = input_tag, "power_toggle" = 1) + . = TRUE - if(href_list["in_set_flowrate"]) - input_info = null - signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]") - . = 1 + if("in_set_flowrate") + input_info = null + signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]") + . = TRUE - if(href_list["out_refresh_status"]) - output_info = null - signal.data = list ("tag" = output_tag, "status" = 1) - . = 1 + if("out_refresh_status") + output_info = null + signal.data = list ("tag" = output_tag, "status" = 1) + . = TRUE - if(href_list["out_toggle_power"]) - output_info = null - signal.data = list ("tag" = output_tag, "power_toggle" = 1) - . = 1 + if("out_toggle_power") + output_info = null + signal.data = list ("tag" = output_tag, "power_toggle" = 1) + . = TRUE - if(href_list["out_set_pressure"]) - output_info = null - signal.data = list ("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]") - . = 1 + if("out_set_pressure") + output_info = null + signal.data = list ("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]") + . = TRUE signal.data["sigtype"]="command" radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA) @@ -258,40 +245,29 @@ obj/machinery/computer/general_air_control/Destroy() 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) - - 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 +/obj/machinery/computer/general_air_control/supermatter_core/tgui_data(mob/user) + var/list/data = ..() data["core"] = 1 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) - data["output_info"] = list("power" = output_info["power"], "pressure_limit" = output_info["external"]) + // Yes, TECHNICALLY this is not output pressure, it's a pressure LIMIT. HOWEVER. The fact that the UI uses "output_pressure" + // in EXACTLY THE SAME WAY as "pressure_limit" means this should just pass it as the other fucking data argument because holy shit what the + // fuck + data["output_info"] = list("power" = output_info["power"], "output_pressure" = output_info["external"]) else data["output_info"] = null data["input_flow_setting"] = round(input_flow_setting, 0.1) data["pressure_setting"] = pressure_setting + data["max_pressure"] = 10*ONE_ATMOSPHERE + data["max_flowrate"] = ATMOS_DEFAULT_VOLUME_PUMP + 500 - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "atmo_control.tmpl", name, 650, 500) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(5) + return data /obj/machinery/computer/general_air_control/supermatter_core/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -305,54 +281,56 @@ obj/machinery/computer/general_air_control/Destroy() else ..(signal) -/obj/machinery/computer/general_air_control/supermatter_core/Topic(href, href_list) +/obj/machinery/computer/general_air_control/supermatter_core/tgui_act(action, params) if(..()) - return 1 + return TRUE - if(href_list["adj_pressure"]) - var/change = text2num(href_list["adj_pressure"]) - pressure_setting = between(0, pressure_setting + change, 10*ONE_ATMOSPHERE) - return 1 + switch(action) + if("adj_pressure") + var/new_pressure = text2num(params["adj_pressure"]) + pressure_setting = between(0, new_pressure, 10*ONE_ATMOSPHERE) + return TRUE - 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 - return 1 + if("adj_input_flow_rate") + var/new_flow = text2num(params["adj_input_flow_rate"]) + input_flow_setting = between(0, new_flow, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors + return TRUE if(!radio_connection) - return 0 + return FALSE var/datum/signal/signal = new signal.transmission_method = TRANSMISSION_RADIO //radio signal signal.source = src - if(href_list["in_refresh_status"]) - input_info = null - signal.data = list ("tag" = input_tag, "status" = 1) - . = 1 + switch(action) + if("in_refresh_status") + input_info = null + signal.data = list ("tag" = input_tag, "status" = 1) + . = TRUE - if(href_list["in_toggle_injector"]) - input_info = null - signal.data = list ("tag" = input_tag, "power_toggle" = 1) - . = 1 + if("in_toggle_injector") + input_info = null + signal.data = list ("tag" = input_tag, "power_toggle" = 1) + . = TRUE - if(href_list["in_set_flowrate"]) - input_info = null - signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]") - . = 1 + if("in_set_flowrate") + input_info = null + signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]") + . = TRUE - if(href_list["out_refresh_status"]) - output_info = null - signal.data = list ("tag" = output_tag, "status" = 1) - . = 1 + if("out_refresh_status") + output_info = null + signal.data = list ("tag" = output_tag, "status" = 1) + . = TRUE - if(href_list["out_toggle_power"]) - output_info = null - signal.data = list ("tag" = output_tag, "power_toggle" = 1) - . = 1 + if("out_toggle_power") + output_info = null + signal.data = list ("tag" = output_tag, "power_toggle" = 1) + . = TRUE - if(href_list["out_set_pressure"]) - output_info = null - signal.data = list ("tag" = output_tag, "set_external_pressure" = "[pressure_setting]", "checks" = 1) - . = 1 + if("out_set_pressure") + output_info = null + signal.data = list ("tag" = output_tag, "set_external_pressure" = "[pressure_setting]", "checks" = 1) + . = TRUE signal.data["sigtype"]="command" radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA) @@ -370,7 +348,7 @@ obj/machinery/computer/general_air_control/Destroy() /obj/machinery/computer/general_air_control/fuel_injection/process() if(automation) if(!radio_connection) - return 0 + return FALSE var/injecting = 0 for(var/id_tag in sensor_information) @@ -396,20 +374,8 @@ obj/machinery/computer/general_air_control/Destroy() ..() -/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 - sensors_ui = null - - data["sensors"] = sensors_ui +/obj/machinery/computer/general_air_control/fuel_injection/tgui_data(mob/user) + var/list/data = ..() data["fuel"] = 1 data["automation"] = automation @@ -418,12 +384,7 @@ obj/machinery/computer/general_air_control/Destroy() else data["device_info"] = null - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "atmo_control.tmpl", name, 650, 500) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(5) + return data /obj/machinery/computer/general_air_control/fuel_injection/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -435,55 +396,60 @@ obj/machinery/computer/general_air_control/Destroy() else ..(signal) -/obj/machinery/computer/general_air_control/fuel_injection/Topic(href, href_list) +/obj/machinery/computer/general_air_control/fuel_injection/tgui_act(action, params) if(..()) - return + return TRUE + + switch(action) + if("refresh_status") + device_info = null + if(!radio_connection) + return FALSE - if(href_list["refresh_status"]) - device_info = null - if(!radio_connection) - return 0 + var/datum/signal/signal = new + signal.transmission_method = TRANSMISSION_RADIO //radio signal + signal.source = src + signal.data = list( + "tag" = device_tag, + "status" = 1, + "sigtype"="command" + ) + radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA) + . = TRUE - var/datum/signal/signal = new - signal.transmission_method = TRANSMISSION_RADIO //radio signal - signal.source = src - signal.data = list( - "tag" = device_tag, - "status" = 1, - "sigtype"="command" - ) - radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA) + if("toggle_automation") + automation = !automation + . = TRUE - if(href_list["toggle_automation"]) - automation = !automation + if("toggle_injector") + device_info = null + if(!radio_connection) + return FALSE - if(href_list["toggle_injector"]) - device_info = null - if(!radio_connection) - return 0 + var/datum/signal/signal = new + signal.transmission_method = TRANSMISSION_RADIO //radio signal + signal.source = src + signal.data = list( + "tag" = device_tag, + "power_toggle" = 1, + "sigtype"="command" + ) - var/datum/signal/signal = new - signal.transmission_method = TRANSMISSION_RADIO //radio signal - signal.source = src - signal.data = list( - "tag" = device_tag, - "power_toggle" = 1, - "sigtype"="command" - ) + radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA) + . = TRUE - radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA) + if("injection") + if(!radio_connection) + return FALSE - if(href_list["injection"]) - if(!radio_connection) - return 0 + var/datum/signal/signal = new + signal.transmission_method = TRANSMISSION_RADIO //radio signal + signal.source = src + signal.data = list( + "tag" = device_tag, + "inject" = 1, + "sigtype"="command" + ) - var/datum/signal/signal = new - signal.transmission_method = TRANSMISSION_RADIO //radio signal - signal.source = src - signal.data = list( - "tag" = device_tag, - "inject" = 1, - "sigtype"="command" - ) - - radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA) \ No newline at end of file + radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA) + . = TRUE \ No newline at end of file diff --git a/code/game/machinery/atmoalter/area_atmos_computer.dm b/code/game/machinery/atmoalter/area_atmos_computer.dm index 125b55eb7fc..55523ed0798 100644 --- a/code/game/machinery/atmoalter/area_atmos_computer.dm +++ b/code/game/machinery/atmoalter/area_atmos_computer.dm @@ -24,94 +24,70 @@ /obj/machinery/computer/area_atmos/attack_hand(var/mob/user as mob) if(..(user)) return - src.add_fingerprint(usr) - var/dat = {" - - - - - -

Area Air Control

- [status]
- Scan - "} - for(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in connectedscrubbers) - dat += {" - - - - "} + tgui_interact(user) - dat += {" -
- [scrubber.name]
- Pressure: [round(scrubber.air_contents.return_pressure(), 0.01)] kPa
- Flow Rate: [round(scrubber.last_flow_rate,0.1)] L/s
-
- Turn On - Turn Off
- Load: [round(scrubber.last_power_draw)] W -

- [zone] - - "} - user << browse("[dat]", "window=miningshuttle;size=400x400") - status = "" - -/obj/machinery/computer/area_atmos/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - src.add_fingerprint(usr) - - - if(href_list["scan"]) - scanscrubbers() - else if(href_list["toggle"]) - var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber = locate(href_list["scrub"]) +/obj/machinery/computer/area_atmos/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AreaScrubberControl", name) + ui.open() +/obj/machinery/computer/area_atmos/tgui_data(mob/user) + var/list/data = list() + + data["scrubbers"] = list() + for(var/id in connectedscrubbers) + var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber = connectedscrubbers[id] if(!validscrubber(scrubber)) - spawn(20) - status = "ERROR: Couldn't connect to scrubber! (timeout)" - connectedscrubbers -= scrubber - src.updateUsrDialog() - return + connectedscrubbers -= scrubber + continue + data["scrubbers"].Add(list(list( + "id" = id, + "name" = scrubber.name, + "on" = scrubber.on, + "pressure" = scrubber.air_contents.return_pressure(), + "flow_rate" = scrubber.last_flow_rate, + "load" = scrubber.last_power_draw, + "area" = get_area(scrubber), + ))) - scrubber.on = text2num(href_list["toggle"]) - scrubber.update_icon() + return data + +/obj/machinery/computer/area_atmos/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("toggle") + var/scrub_id = params["id"] + var/obj/machinery/portable_atmospherics/powered/scrubber/huge/S = connectedscrubbers["[scrub_id]"] + if(!validscrubber(S)) + connectedscrubbers -= S + return TRUE + S.on = !S.on + S.update_icon() + . = TRUE + if("allon") + INVOKE_ASYNC(src, .proc/toggle_all, TRUE) + . = TRUE + if("alloff") + INVOKE_ASYNC(src, .proc/toggle_all, FALSE) + . = TRUE + if("scan") + scanscrubbers() + . = TRUE + + add_fingerprint(usr) + +/obj/machinery/computer/area_atmos/proc/toggle_all(on) + for(var/id in connectedscrubbers) + var/obj/machinery/portable_atmospherics/powered/scrubber/huge/S = connectedscrubbers["[id]"] + if(!validscrubber(S)) + connectedscrubbers -= S + continue + S.on = on + S.update_icon() + CHECK_TICK /obj/machinery/computer/area_atmos/proc/validscrubber(obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber as obj) if(!isobj(scrubber) || get_dist(scrubber.loc, src.loc) > src.range || scrubber.loc.z != src.loc.z) @@ -119,13 +95,12 @@ return TRUE /obj/machinery/computer/area_atmos/proc/scanscrubbers() - connectedscrubbers = new() + connectedscrubbers = list() var/found = 0 for(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in range(range, src.loc)) - if(istype(scrubber)) - found = 1 - connectedscrubbers += scrubber + found = 1 + connectedscrubbers["[scrubber.id]"] = scrubber if(!found) status = "ERROR: No scrubber found!" @@ -142,7 +117,7 @@ var/found = 0 var/area/A = get_area(src) for(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in A) - connectedscrubbers += scrubber + connectedscrubbers["[scrubber.id]"] = scrubber found = 1 if(!found) @@ -151,7 +126,10 @@ src.updateUsrDialog() /obj/machinery/computer/area_atmos/area/validscrubber(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber) - if(get_area(scrubber) == get_area(src)) - return 1 + if(!istype(scrubber)) + return FALSE - return 0 + if(get_area(scrubber) == get_area(src)) + return TRUE + + return FALSE diff --git a/code/game/machinery/atmoalter/area_atmos_computer_vr.dm b/code/game/machinery/atmoalter/area_atmos_computer_vr.dm index e489bb39fb2..e20e8e1b716 100644 --- a/code/game/machinery/atmoalter/area_atmos_computer_vr.dm +++ b/code/game/machinery/atmoalter/area_atmos_computer_vr.dm @@ -17,12 +17,15 @@ for(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber in world) if(scrubber.scrub_id == src.scrub_id) - connectedscrubbers += scrubber + connectedscrubbers["[scrubber.id]"] = scrubber - src.updateUsrDialog() + SStgui.update_uis(src) /obj/machinery/computer/area_atmos/tag/validscrubber(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber) + if(!istype(scrubber)) + return FALSE + if(scrubber.scrub_id == src.scrub_id) - return 1 + return TRUE - return 0 + return FALSE \ No newline at end of file diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 3a012a1ccda..7faf1115fe8 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -266,105 +266,108 @@ update_flag return src.attack_hand(user) /obj/machinery/portable_atmospherics/canister/attack_hand(var/mob/user as mob) - return src.ui_interact(user) + return tgui_interact(user) -/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if (src.destroyed) +/obj/machinery/portable_atmospherics/canister/tgui_state(mob/user) + return GLOB.tgui_physical_state + +/obj/machinery/portable_atmospherics/canister/tgui_interact(mob/user, datum/tgui/ui) + if(destroyed) return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Canister", name) + ui.open() - // this is the data which will be sent to the ui - var/data[0] - data["name"] = name +/obj/machinery/portable_atmospherics/canister/tgui_data(mob/user) + var/list/data = list() data["canLabel"] = can_label ? 1 : 0 - data["portConnected"] = connected_port ? 1 : 0 - data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) + data["connected"] = connected_port ? 1 : 0 + data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) data["releasePressure"] = round(release_pressure ? release_pressure : 0) + data["defaultReleasePressure"] = round(initial(release_pressure)) data["minReleasePressure"] = round(ONE_ATMOSPHERE/10) data["maxReleasePressure"] = round(10*ONE_ATMOSPHERE) data["valveOpen"] = valve_open ? 1 : 0 - data["hasHoldingTank"] = holding ? 1 : 0 - if (holding) - data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure())) + if(holding) + data["holding"] = list() + data["holding"]["name"] = holding.name + data["holding"]["pressure"] = round(holding.air_contents.return_pressure()) + else + data["holding"] = null - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "canister.tmpl", "Canister", 480, 400) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) + return data -/obj/machinery/portable_atmospherics/canister/Topic(href, href_list) +/obj/machinery/portable_atmospherics/canister/tgui_act(action, params) + if(..()) + return TRUE - //Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict. // yeah but without SOME sort of Topic check any dick can mess with them via exploits as he pleases -walter0o - //First comment might be outdated. - if (!istype(src.loc, /turf)) - return 0 - - if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) // exploit protection -walter0o - usr << browse(null, "window=canister") - onclose(usr, "canister") - return - - if(href_list["toggle"]) - if (valve_open) - if (holding) - release_log += "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the [holding]
" + switch(action) + if("relabel") + if(can_label) + var/list/colors = list(\ + "\[N2O\]" = "redws", \ + "\[N2\]" = "red", \ + "\[O2\]" = "blue", \ + "\[Phoron\]" = "orangeps", \ + "\[CO2\]" = "black", \ + "\[Air\]" = "grey", \ + "\[CAUTION\]" = "yellow", \ + ) + var/label = input("Choose canister label", "Gas canister") as null|anything in colors + if(label) + canister_color = colors[label] + icon_state = colors[label] + name = "Canister: [label]" + if("pressure") + var/pressure = params["pressure"] + if(pressure == "reset") + pressure = initial(release_pressure) + . = TRUE + else if(pressure == "min") + pressure = ONE_ATMOSPHERE/10 + . = TRUE + else if(pressure == "max") + pressure = 10*ONE_ATMOSPHERE + . = TRUE + else if(pressure == "input") + pressure = input("New release pressure ([ONE_ATMOSPHERE/10]-[10*ONE_ATMOSPHERE] kPa):", name, release_pressure) as num|null + if(!isnull(pressure) && !..()) + . = TRUE + else if(text2num(pressure) != null) + pressure = text2num(pressure) + . = TRUE + if(.) + release_pressure = clamp(round(pressure), ONE_ATMOSPHERE/10, 10*ONE_ATMOSPHERE) + if("valve") + if(valve_open) + if(holding) + release_log += "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the [holding]
" + else + release_log += "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the air
" else - release_log += "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the air
" - else - if (holding) - release_log += "Valve was opened by [usr] ([usr.ckey]), starting the transfer into the [holding]
" - else - release_log += "Valve was opened by [usr] ([usr.ckey]), starting the transfer into the air
" - log_open() - valve_open = !valve_open + if(holding) + release_log += "Valve was opened by [usr] ([usr.ckey]), starting the transfer into the [holding]
" + else + release_log += "Valve was opened by [usr] ([usr.ckey]), starting the transfer into the air
" + log_open() + valve_open = !valve_open + . = TRUE + if("eject") + if(holding) + if(valve_open) + valve_open = 0 + release_log += "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the [holding]
" + if(istype(holding, /obj/item/weapon/tank)) + holding.manipulated_by = usr.real_name + holding.loc = loc + holding = null + . = TRUE - if (href_list["remove_tank"]) - if(holding) - if (valve_open) - valve_open = 0 - release_log += "Valve was closed by [usr] ([usr.ckey]), stopping the transfer into the [holding]
" - if(istype(holding, /obj/item/weapon/tank)) - holding.manipulated_by = usr.real_name - holding.loc = loc - holding = null - - if (href_list["pressure_adj"]) - var/diff = text2num(href_list["pressure_adj"]) - if(diff > 0) - release_pressure = min(10*ONE_ATMOSPHERE, release_pressure+diff) - else - release_pressure = max(ONE_ATMOSPHERE/10, release_pressure+diff) - - if (href_list["relabel"]) - if (can_label) - var/list/colors = list(\ - "\[N2O\]" = "redws", \ - "\[N2\]" = "red", \ - "\[O2\]" = "blue", \ - "\[Phoron\]" = "orangeps", \ - "\[CO2\]" = "black", \ - "\[Air\]" = "grey", \ - "\[CAUTION\]" = "yellow", \ - ) - var/label = input("Choose canister label", "Gas canister") as null|anything in colors - if (label) - src.canister_color = colors[label] - src.icon_state = colors[label] - src.name = "Canister: [label]" - - src.add_fingerprint(usr) + add_fingerprint(usr) update_icon() - return 1 - /obj/machinery/portable_atmospherics/canister/phoron/New() ..() diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm index 758c2a57cb0..74e48046613 100644 --- a/code/game/machinery/atmoalter/pump.dm +++ b/code/game/machinery/atmoalter/pump.dm @@ -119,51 +119,73 @@ return src.attack_hand(user) /obj/machinery/portable_atmospherics/powered/pump/attack_hand(var/mob/user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/portable_atmospherics/powered/pump/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1) +/obj/machinery/portable_atmospherics/powered/pump/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PortablePump", name) + ui.open() + + +/obj/machinery/portable_atmospherics/powered/pump/tgui_state(mob/user) + return GLOB.tgui_physical_state + +/obj/machinery/portable_atmospherics/powered/pump/tgui_data(mob/user) var/list/data[0] - data["portConnected"] = connected_port ? 1 : 0 - data["tankPressure"] = round(air_contents.return_pressure() > 0 ? air_contents.return_pressure() : 0) - data["targetpressure"] = round(target_pressure) - data["pump_dir"] = direction_out - data["minpressure"] = round(pressuremin) - data["maxpressure"] = round(pressuremax) + data["on"] = on ? TRUE : FALSE + data["direction"] = !direction_out ? TRUE : FALSE + data["connected"] = connected_port ? TRUE : FALSE + data["pressure"] = round(air_contents.return_pressure() > 0 ? air_contents.return_pressure() : 0) + data["target_pressure"] = round(target_pressure ? target_pressure : 0) + data["default_pressure"] = round(initial(target_pressure)) + data["min_pressure"] = round(pressuremin) + data["max_pressure"] = round(pressuremax) + data["powerDraw"] = round(last_power_draw) data["cellCharge"] = cell ? cell.charge : 0 data["cellMaxCharge"] = cell ? cell.maxcharge : 1 - data["on"] = on ? 1 : 0 - data["hasHoldingTank"] = holding ? 1 : 0 - if (holding) - data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure() > 0 ? holding.air_contents.return_pressure() : 0)) + if(holding) + data["holding"] = list() + data["holding"]["name"] = holding.name + data["holding"]["pressure"] = round(holding.air_contents.return_pressure() > 0 ? holding.air_contents.return_pressure() : 0) + else + data["holding"] = null + + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "portpump.tmpl", "Portable Pump", 480, 410, state = physical_state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/portable_atmospherics/powered/pump/Topic(href, href_list) +/obj/machinery/portable_atmospherics/powered/pump/tgui_act(action, params) if(..()) - return 1 + return TRUE - if(href_list["power"]) - on = !on - . = 1 - if(href_list["direction"]) - direction_out = !direction_out - . = 1 - if (href_list["remove_tank"]) - if(holding) - holding.loc = loc - holding = null - . = 1 - if (href_list["pressure_adj"]) - var/diff = text2num(href_list["pressure_adj"]) - target_pressure = min(10*ONE_ATMOSPHERE, max(0, target_pressure+diff)) - . = 1 + switch(action) + if("power") + on = !on + . = 1 + if("direction") + direction_out = !direction_out + . = 1 + if("eject") + if(holding) + holding.loc = loc + holding = null + . = 1 + if("pressure") + var/pressure = params["pressure"] + if(pressure == "reset") + pressure = initial(target_pressure) + . = TRUE + else if(pressure == "min") + pressure = pressuremin + . = TRUE + else if(pressure == "max") + pressure = pressuremax + . = TRUE + else if(text2num(pressure) != null) + pressure = text2num(pressure) + . = TRUE + if(.) + target_pressure = clamp(round(pressure), pressuremin, pressuremax) - if(.) - update_icon() + update_icon() diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index 219cf7801fd..b6e4c0e124d 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -96,49 +96,53 @@ return src.attack_hand(user) /obj/machinery/portable_atmospherics/powered/scrubber/attack_hand(var/mob/user) - ui_interact(user) - return + tgui_interact(user) -/obj/machinery/portable_atmospherics/powered/scrubber/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1) - var/list/data[0] - data["portConnected"] = connected_port ? 1 : 0 - data["tankPressure"] = round(air_contents.return_pressure() > 0 ? air_contents.return_pressure() : 0) +/obj/machinery/portable_atmospherics/powered/scrubber/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PortableScrubber", name) + ui.open() + +/obj/machinery/portable_atmospherics/powered/scrubber/tgui_data(mob/user) + var/list/data = list() + data["on"] = on ? 1 : 0 + data["connected"] = connected_port ? 1 : 0 + data["pressure"] = round(air_contents.return_pressure() > 0 ? air_contents.return_pressure() : 0) + data["rate"] = round(volume_rate) data["minrate"] = round(minrate) data["maxrate"] = round(maxrate) data["powerDraw"] = round(last_power_draw) data["cellCharge"] = cell ? cell.charge : 0 data["cellMaxCharge"] = cell ? cell.maxcharge : 1 - data["on"] = on ? 1 : 0 - data["hasHoldingTank"] = holding ? 1 : 0 - if (holding) - data["holdingTank"] = list("name" = holding.name, "tankPressure" = round(holding.air_contents.return_pressure() > 0 ? holding.air_contents.return_pressure() : 0)) + if(holding) + data["holding"] = list() + data["holding"]["name"] = holding.name + data["holding"]["pressure"] = round(holding.air_contents.return_pressure() > 0 ? holding.air_contents.return_pressure() : 0) + else + data["holding"] = null - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "portscrubber.tmpl", "Portable Scrubber", 480, 400, state = physical_state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data - -/obj/machinery/portable_atmospherics/powered/scrubber/Topic(href, href_list) +/obj/machinery/portable_atmospherics/powered/scrubber/tgui_act(action, params) if(..()) - return 1 + return TRUE + + switch(action) + if("power") + on = !on + . = TRUE + if("eject") + if(holding) + holding.loc = loc + holding = null + . = TRUE + if("volume_adj") + volume_rate = CLAMP(text2num(params["vol"]), minrate, maxrate) + . = TRUE - if(href_list["power"]) - on = !on - . = 1 - if (href_list["remove_tank"]) - if(holding) - holding.loc = loc - holding = null - . = 1 - if (href_list["volume_adj"]) - var/diff = text2num(href_list["volume_adj"]) - volume_rate = CLAMP(volume_rate+diff, minrate, maxrate) - . = 1 update_icon() diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 1629b77bddf..3e1188198b7 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -12,8 +12,8 @@ circuit = /obj/item/weapon/circuitboard/autolathe var/datum/category_collection/autolathe/machine_recipes - var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0) - var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0) + var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0) + var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0) var/datum/category_group/autolathe/current_category var/hacked = 0 @@ -26,6 +26,9 @@ var/datum/wires/autolathe/wires = null + var/mb_rating = 0 + var/man_rating = 0 + var/filtertext /obj/machinery/autolathe/Initialize() @@ -64,6 +67,9 @@ var/list/material_bottom = list("") for(var/material in stored_material) + if(material != DEFAULT_WALL_MATERIAL && material != MAT_GLASS) // Don't show the Extras unless people care enough to put them in. + if(stored_material[material] <= 0) + continue material_top += "[material]" material_bottom += "[stored_material[material]]/[storage_capacity[material]]" @@ -72,7 +78,9 @@ dat += "

Printable Designs

Showing: [current_category].

" for(var/datum/category_item/autolathe/R in current_category.items) - if(R.hidden && !hacked) + if(R.hidden && !hacked) // Illegal or nonstandard. + continue + if(R.man_rating > man_rating) // Advanced parts. continue if(filtertext && findtext(R.name, filtertext) == 0) continue @@ -311,14 +319,16 @@ //Updates overall lathe storage size. /obj/machinery/autolathe/RefreshParts() ..() - var/mb_rating = 0 - var/man_rating = 0 + mb_rating = 0 + man_rating = 0 for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) mb_rating += MB.rating for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) man_rating += M.rating storage_capacity[DEFAULT_WALL_MATERIAL] = mb_rating * 25000 + storage_capacity[MAT_PLASTIC] = mb_rating * 20000 + storage_capacity[MAT_PLASTEEL] = mb_rating * 16250 storage_capacity["glass"] = mb_rating * 12500 build_time = 50 / man_rating mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5 diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm index 4bd89e07dc3..3fcbc98e850 100644 --- a/code/game/machinery/biogenerator.dm +++ b/code/game/machinery/biogenerator.dm @@ -101,30 +101,35 @@ if(beaker) dat += "Activate Biogenerator!
" dat += "Detach Container

" - dat += "Food:
" + dat += "Food Items:
" dat += "10 milk([round(20/build_eff)]) | x5
" dat += "10 cream([round(20/build_eff)]) | x5
" dat += "Slab of meat([round(50/build_eff)]) | x5
" - dat += "Nutrient:
" - dat += "E-Z-Nutrient([round(60/build_eff)]) | x5
" - dat += "Left 4 Zed([round(120/build_eff)]) | x5
" - dat += "Robust Harvest([round(150/build_eff)]) | x5
" - dat += "Leather:
" - dat += "Wallet([round(100/build_eff)])
" - dat += "Botanical gloves([round(250/build_eff)])
" - dat += "Plant bag([round(250/build_eff)])
" - dat += "Large plant bag([round(250/build_eff)])
" - dat += "Utility belt([round(300/build_eff)])
" - dat += "Leather Satchel([round(400/build_eff)])
" - dat += "Cash Bag([round(400/build_eff)])
" - dat += "Chemistry Bag([round(400/build_eff)])
" - dat += "Workboots([round(400/build_eff)])
" - dat += "Leather Shoes([round(400/build_eff)])
" - dat += "Leather Chaps([round(400/build_eff)])
" - dat += "Leather Coat([round(500/build_eff)])
" - dat += "Leather Jacket([round(500/build_eff)])
" - dat += "Winter Coat([round(500/build_eff)])
" - dat += "4 Algae Sheets([round(400/build_eff)])
" //VOREStation Edit - Algae for oxygen generator + dat += "Cooking Ingredient:
" + dat += "Universal Enzyme([round(30/build_eff)]) | x5
" + dat += "Nutri-Spread([round(30/build_eff)]) | x5
" + // dat += "Universal Enzyme([round(30/build_eff)]) | x5
" + // dat += "Universal Enzyme([round(30/build_eff)]) | x5
" + dat += "Gardening Nutrients:
" + dat += "E-Z-Nutrient([round(60/build_eff)]) | x5
" + dat += "Left 4 Zed([round(120/build_eff)]) | x5
" + dat += "Robust Harvest([round(150/build_eff)]) | x5
" + dat += "Leather Products:
" + dat += "Wallet([round(100/build_eff)])
" + dat += "Botanical gloves([round(250/build_eff)])
" + dat += "Plant bag([round(250/build_eff)])
" + dat += "Large plant bag([round(250/build_eff)])
" + dat += "Utility belt([round(300/build_eff)])
" + dat += "Leather Satchel([round(400/build_eff)])
" + dat += "Cash Bag([round(400/build_eff)])
" + dat += "Chemistry Bag([round(400/build_eff)])
" + dat += "Workboots([round(400/build_eff)])
" + dat += "Leather Shoes([round(400/build_eff)])
" + dat += "Leather Chaps([round(400/build_eff)])
" + dat += "Leather Coat([round(500/build_eff)])
" + dat += "Leather Jacket([round(500/build_eff)])
" + dat += "Winter Coat([round(500/build_eff)])
" + dat += "4 Algae Sheets([round(400/build_eff)])
" //VOREStation Edit - Algae for oxygen generator //dat += "Other
" //dat += "Monkey(500)
" else @@ -201,6 +206,18 @@ new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + if("unizyme") + beaker.reagents.add_reagent("enzyme", 10) + if("unizyme50") + beaker.reagents.add_reagent("enzyme", 50) + if("nutrispread") + new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) + if("nutrispread5") + new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) + new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) + new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) + new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) + new/obj/item/weapon/reagent_containers/food/snacks/spreads(loc) if("ez") new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc) if("l4z") diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 454025d4259..73b78cb148a 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -42,24 +42,6 @@ var/list/camera_computers_using_this = list() -/obj/machinery/camera/apply_visual(mob/living/carbon/human/M) - if(!M.client) - return - M.overlay_fullscreen("fishbed",/obj/screen/fullscreen/fishbed) - M.overlay_fullscreen("scanlines",/obj/screen/fullscreen/scanline) - M.overlay_fullscreen("whitenoise",/obj/screen/fullscreen/noise) - M.machine_visual = src - return 1 - -/obj/machinery/camera/remove_visual(mob/living/carbon/human/M) - if(!M.client) - return - M.clear_fullscreen("fishbed",0) - M.clear_fullscreen("scanlines") - M.clear_fullscreen("whitenoise") - M.machine_visual = null - return 1 - /obj/machinery/camera/New() wires = new(src) assembly = new(src) @@ -232,12 +214,6 @@ else to_chat(O, "[U] holds \a [itemname] up to one of your cameras ...") O << browse(text("[][]", itemname, info), text("window=[]", itemname)) - for(var/mob/O in player_list) - if (istype(O.machine, /obj/machinery/computer/security)) - var/obj/machinery/computer/security/S = O.machine - if (S.current_camera == src) - to_chat(O, "[U] holds \a [itemname] up to one of the cameras ...") - O << browse(text("[][]", itemname, info), text("window=[]", itemname)) else if (istype(W, /obj/item/weapon/camera_bug)) if (!src.can_use()) @@ -298,7 +274,7 @@ //Used when someone breaks a camera /obj/machinery/camera/proc/destroy() stat |= BROKEN - wires.RandomCutAll() + wires.cut_all() triggerCameraAlarm() update_icon() @@ -333,7 +309,7 @@ camera_alarm.triggerAlarm(loc, src, duration) /obj/machinery/camera/proc/cancelCameraAlarm() - if(wires.IsIndexCut(CAMERA_WIRE_ALARM)) + if(wires.is_cut(WIRE_CAM_ALARM)) return alarm_on = 0 @@ -471,7 +447,7 @@ network.Cut() update_coverage(1) -/obj/machinery/camera/proc/nano_structure() +/obj/machinery/camera/proc/tgui_structure() var/cam[0] cam["name"] = sanitize(c_tag) cam["deact"] = !can_use() @@ -494,15 +470,12 @@ else cameranet.updateVisibility(src, 0) - invalidateCameraCache() - // Resets the camera's wires to fully operational state. Used by one of Malfunction abilities. /obj/machinery/camera/proc/reset_wires() if(!wires) return if (stat & BROKEN) // Fix the camera stat &= ~BROKEN - wires.CutAll() - wires.MendAll() + wires.repair() update_icon() update_coverage() diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index ab5d82b3a5f..bb3cdfb4edb 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -173,7 +173,6 @@ var/global/list/engineering_networks = list( var/number = my_area.len c_tag = "[A.name] #[number]" - invalidateCameraCache() /obj/machinery/camera/autoname/Destroy() var/area/A = get_area(src) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 2c6a5d34e62..c4b368b8d3e 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -24,6 +24,7 @@ return selected #define CLONE_BIOMASS 30 //VOREstation Edit +#define MINIMUM_HEAL_LEVEL 40 /obj/machinery/clonepod name = "cloning pod" @@ -46,6 +47,9 @@ var/list/containers = list() // Beakers for our liquid biomass var/container_limit = 3 // How many beakers can the machine hold? + var/speed_coeff + var/efficiency + /obj/machinery/clonepod/Initialize() . = ..() default_apply_parts() @@ -291,13 +295,16 @@ /obj/machinery/clonepod/RefreshParts() ..() - var/rating = 0 - for(var/obj/item/weapon/stock_parts/P in component_parts) - if(istype(P, /obj/item/weapon/stock_parts/scanning_module) || istype(P, /obj/item/weapon/stock_parts/manipulator)) - rating += P.rating + speed_coeff = 0 + efficiency = 0 + for(var/obj/item/weapon/stock_parts/scanning_module/S in component_parts) + efficiency += S.rating + for(var/obj/item/weapon/stock_parts/manipulator/P in component_parts) + speed_coeff += P.rating + heal_level = max(min((efficiency * 15) + 10, 100), MINIMUM_HEAL_LEVEL) - heal_level = rating * 10 - 20 - heal_rate = round(rating / 4) +/obj/machinery/clonepod/proc/get_completion() + . = (100 * ((occupant.health + 100) / (heal_level + 100))) /obj/machinery/clonepod/verb/eject() set name = "Eject Cloner" diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 5caf9edd6e4..c965a54b151 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -1,4 +1,4 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 +#define OP_COMPUTER_COOLDOWN 60 /obj/machinery/computer/operating name = "patient monitoring console" @@ -8,66 +8,304 @@ icon_keyboard = "med_key" icon_screen = "crew" circuit = /obj/item/weapon/circuitboard/operating - var/mob/living/carbon/human/victim = null var/obj/machinery/optable/table = null + var/mob/living/carbon/human/victim = null + var/verbose = 1 //general speaker toggle + var/patientName = null + var/oxyAlarm = 30 //oxy damage at which the computer will beep + var/choice = 0 //just for going into and out of the options menu + var/healthAnnounce = 1 //healther announcer toggle + var/crit = 1 //crit beeping toggle + var/nextTick = OP_COMPUTER_COOLDOWN + var/healthAlarm = 50 + var/oxy = 1 //oxygen beeping toggle /obj/machinery/computer/operating/New() ..() for(var/direction in list(NORTH,EAST,SOUTH,WEST)) table = locate(/obj/machinery/optable, get_step(src, direction)) - if (table) + if(table) table.computer = src break +/obj/machinery/computer/operating/Destroy() + if(table) + table.computer = null + table = null + if(victim) + victim = null + return ..() + /obj/machinery/computer/operating/attack_ai(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - ui_interact(user) + tgui_interact(user) /obj/machinery/computer/operating/attack_hand(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - ui_interact(user) + tgui_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/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 = SSnanoui.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) +/obj/machinery/computer/operating/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "OperatingComputer", "Patient Monitor") ui.open() - ui.set_auto_update(5) -/obj/machinery/computer/operating/Topic(href, href_list) +/obj/machinery/computer/operating/tgui_data(mob/user) + var/data[0] + var/mob/living/carbon/human/occupant + if(table) + occupant = table.victim + data["hasOccupant"] = occupant ? 1 : 0 + var/occupantData[0] + + if(occupant) + occupantData["name"] = occupant.name + occupantData["stat"] = occupant.stat + occupantData["health"] = occupant.health + occupantData["maxHealth"] = occupant.maxHealth + occupantData["minHealth"] = config.health_threshold_dead + occupantData["bruteLoss"] = occupant.getBruteLoss() + occupantData["oxyLoss"] = occupant.getOxyLoss() + occupantData["toxLoss"] = occupant.getToxLoss() + occupantData["fireLoss"] = occupant.getFireLoss() + occupantData["paralysis"] = occupant.paralysis + occupantData["hasBlood"] = 0 + occupantData["bodyTemperature"] = occupant.bodytemperature + occupantData["maxTemp"] = 1000 // If you get a burning vox armalis into the sleeper, congratulations + // Because we can put simple_animals in here, we need to do something tricky to get things working nice + occupantData["temperatureSuitability"] = 0 // 0 is the baseline + if(ishuman(occupant) && occupant.species) + // I wanna do something where the bar gets bluer as the temperature gets lower + // For now, I'll just use the standard format for the temperature status + var/datum/species/sp = occupant.species + if(occupant.bodytemperature < sp.cold_level_3) + occupantData["temperatureSuitability"] = -3 + else if(occupant.bodytemperature < sp.cold_level_2) + occupantData["temperatureSuitability"] = -2 + else if(occupant.bodytemperature < sp.cold_level_1) + occupantData["temperatureSuitability"] = -1 + else if(occupant.bodytemperature > sp.heat_level_3) + occupantData["temperatureSuitability"] = 3 + else if(occupant.bodytemperature > sp.heat_level_2) + occupantData["temperatureSuitability"] = 2 + else if(occupant.bodytemperature > sp.heat_level_1) + occupantData["temperatureSuitability"] = 1 + else if(isanimal(occupant)) + var/mob/living/simple_mob/silly = occupant + if(silly.bodytemperature < silly.minbodytemp) + occupantData["temperatureSuitability"] = -3 + else if(silly.bodytemperature > silly.maxbodytemp) + occupantData["temperatureSuitability"] = 3 + // Blast you, imperial measurement system + occupantData["btCelsius"] = occupant.bodytemperature - T0C + occupantData["btFaren"] = ((occupant.bodytemperature - T0C) * (9.0/5.0))+ 32 + + if(ishuman(occupant) && !(NO_BLOOD in occupant.species.flags) && occupant.vessel) + occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL) + occupantData["hasBlood"] = 1 + var/blood_volume = round(occupant.vessel.get_reagent_amount("blood")) + occupantData["bloodLevel"] = blood_volume + occupantData["bloodMax"] = occupant.species.blood_volume + occupantData["bloodPercent"] = round(100*(blood_volume/occupant.species.blood_volume), 0.01) //copy pasta ends here + + occupantData["bloodType"] = occupant.dna.b_type + occupantData["surgery"] = build_surgery_list(user) + + data["occupant"] = occupantData + data["verbose"]=verbose + data["oxyAlarm"]=oxyAlarm + data["choice"]=choice + data["health"]=healthAnnounce + data["crit"]=crit + data["healthAlarm"]=healthAlarm + data["oxy"]=oxy + + return data + +/obj/machinery/computer/operating/tgui_act(action, params) if(..()) - return 1 - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) + return TRUE + if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) - src.add_fingerprint(usr) - SSnanoui.update_uis(src) \ No newline at end of file + . = TRUE + switch(action) + if("verboseOn") + verbose = TRUE + if("verboseOff") + verbose = FALSE + if("healthOn") + healthAnnounce = TRUE + if("healthOff") + healthAnnounce = FALSE + if("critOn") + crit = TRUE + if("critOff") + crit = FALSE + if("oxyOn") + oxy = TRUE + if("oxyOff") + oxy = FALSE + if("oxy_adj") + oxyAlarm = clamp(text2num(params["new"]), -100, 100) + if("choiceOn") + choice = TRUE + if("choiceOff") + choice = FALSE + if("health_adj") + healthAlarm = clamp(text2num(params["new"]), -100, 100) + else + return FALSE + +/obj/machinery/computer/operating/process() + if(table && table.check_victim()) + if(verbose) + if(patientName!=table.victim.name) + patientName=table.victim.name + atom_say("New patient detected, loading stats") + victim = table.victim + atom_say("[victim.real_name], [victim.dna.b_type] blood, [victim.stat ? "Non-Responsive" : "Awake"]") + SStgui.update_uis(src) + if(nextTick < world.time) + nextTick=world.time + OP_COMPUTER_COOLDOWN + if(crit && victim.health <= -50 ) + playsound(src.loc, 'sound/machines/defib_success.ogg', 50, 0) + if(oxy && victim.getOxyLoss()>oxyAlarm) + playsound(src.loc, 'sound/machines/defib_safetyOff.ogg', 50, 0) + if(healthAnnounce && ((victim.health / victim.maxHealth) * 100) <= healthAlarm) + atom_say("[round(((victim.health / victim.maxHealth) * 100))]% health.") + +// Surgery Helpers +/obj/machinery/computer/operating/proc/build_surgery_list(mob/user) + if(!istype(victim)) + return null + + . = list() + + for(var/limb in victim.organs_by_name) + var/obj/item/organ/external/E = victim.organs_by_name[limb] + if(E && E.open) + . += list(list("name" = E.name, "currentStage" = find_stage(E), "nextSteps" = find_next_steps(user, limb))) + +/** + * This proc is actually hell. I hate the surgery system Polaris uses. + * Basically, surgery is completely stateless, and what "stage" we're on is just dependent + * on the current state of 5 separate variables that determine what stages we can perform + * next. + * + * So, here's a little guide to understand this proc: + * Surgery is broken down into 5 different variables: + * `open`, + * `stage`, + * `cavity`, + * `burn_stage`, + * and `brute_stage`. + * Naturally, the values assigned to these don't use defines or names or anything, they're just magic numbers. + * So, we have to figure out ourselves what we should call each value. + * Open can be 4 values, and represents the "openness" of the surgery site. + * 1 = Cut Open. + * 2 = Retracted. + * 2.5 = Bones cut. + * 3 = Bones spread. + * Stage can be 3 values, and represents the progress in fixing broken bones + * 0 = Closed, can be either "we're done" or "we haven't started" FFS. + * 1 = Bones glued. + * 2 = Bones set. + * Cavity is just representing the cavity implant surgeries, and can be 2 values. + * 0 = Cavity Closed + * 1 = Cavity Open + * burn_stage and brute_stage are literally only used for repairing brute/burn damage to limbs + * I have no idea why you would ever perform these surgeries, given that Bicaradine and Kelotane exist. + * So I'm not even going to bother trying to represent them here. Fuck it. + */ +/obj/machinery/computer/operating/proc/find_stage(var/obj/item/organ/external/E) + . = "None." + switch(E.open) + if(1) + . = "Incision made." + if(2) + . = "Surgical site opened." + switch(E.stage) + // if(0) // Nothing. + if(1) + . = "Surgical site opened; Bones glued." + if(2) + . = "Surgical site opened; Bones set." + switch(E.cavity) + if(1) + . = "Surgical site opened; Cavity open." + if(2.5) // WHY IS THIS A FLOAT. WHY? + . = "Bones cut." + switch(E.stage) + // if(0) // Nothing. + if(1) + . = "Bones cut; Bones glued." + if(2) + . = "Bones cut; Bones set." + if(3) + . = "Bones retracted." + switch(E.stage) + // if(0) // Nothing. + if(1) + . = "Bones retracted; Bones glued." + if(2) + . = "Bones retracted; Bones reset." + switch(E.cavity) + if(1) + . = "Bones retracted; Cavity open." + +/** + * This converts a typepath into a pretty name. + * As best as it can, anyways. + */ +/proc/pretty_type(var/datum/A) + var/typeStr = "[A.type]" + . = copytext(typeStr, findlasttext(typeStr, "/") + 1, length(typeStr) + 1) + . = capitalize(replacetext(., "_", " ")) + +/proc/get_surgery_steps_without_basetypes() + var/static/list/good_surgeries = list() + if(LAZYLEN(good_surgeries)) + return good_surgeries + var/static/list/banned_surgery_steps = list( + /datum/surgery_step, + /datum/surgery_step/generic, + /datum/surgery_step/open_encased, + /datum/surgery_step/repairflesh, + /datum/surgery_step/face, + /datum/surgery_step/cavity, + /datum/surgery_step/limb, + /datum/surgery_step/brainstem, + ) + good_surgeries = surgery_steps + for(var/datum/surgery_step/S in good_surgeries) + if(S.type in banned_surgery_steps) + good_surgeries -= S + if(!LAZYLEN(S.allowed_tools)) + good_surgeries -= S + return good_surgeries + +/** + * Funnily enough, this proc is actually considerably less awful than find_stage. + * All we have to do is check what surgeries can be done, like surgery mechanics themselves do. + * Then, build a string telling the user what they can do next. + */ +/obj/machinery/computer/operating/proc/find_next_steps(mob/user, zone) + . = list() + for(var/datum/surgery_step/S in get_surgery_steps_without_basetypes()) + if(S.can_use(user, victim, zone, null) && S.is_valid_target(victim)) + var/allowed_tools_by_name = list() + for(var/tool in S.allowed_tools) + // Exempt ghetto tools. + if(S.allowed_tools[tool] < 100) + continue + var/obj/tool_path = tool + allowed_tools_by_name += capitalize(initial(tool_path.name)) + // Please for the love of all that is holy, someone make surgery steps + // have names so I don't have to do this stupid pretty_type shit. + . += "[pretty_type(S)]: [english_list(allowed_tools_by_name)]" diff --git a/code/game/machinery/computer/RCON_Console.dm b/code/game/machinery/computer/RCON_Console.dm index fbd1190fd7f..d6df0d2d6d9 100644 --- a/code/game/machinery/computer/RCON_Console.dm +++ b/code/game/machinery/computer/RCON_Console.dm @@ -13,7 +13,7 @@ circuit = /obj/item/weapon/circuitboard/rcon_console req_one_access = list(access_engine) var/current_tag = null - var/datum/nano_module/rcon/rcon + var/datum/tgui_module/rcon/rcon /obj/machinery/computer/rcon/New() ..() @@ -29,13 +29,12 @@ // Description: Opens UI of this machine. /obj/machinery/computer/rcon/attack_hand(var/mob/user as mob) ..() - ui_interact(user) + tgui_interact(user) // Proc: ui_interact() -// Parameters: 4 (standard NanoUI parameters) -// Description: Uses dark magic (NanoUI) to render this machine's UI -/obj/machinery/computer/rcon/ui_interact(mob/user, ui_key = "rcon", var/datum/nanoui/ui = null, var/force_open = 1) - rcon.ui_interact(user, ui_key, ui, force_open) +// Description: Uses dark magic (TGUI) to render this machine's UI +/obj/machinery/computer/rcon/tgui_interact(mob/user, datum/tgui/ui) + rcon.tgui_interact(user, ui) /obj/machinery/computer/rcon/update_icon() ..() diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index daca64cc42d..3ec9e2c841e 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -1,142 +1,135 @@ /obj/machinery/computer/aifixer name = "\improper AI system integrity restorer" - desc = "Restores AI units to working condition, assuming you have one inside!" - icon_keyboard = "rd_key" - icon_screen = "ai-fixer" - light_color = "#a97faa" - circuit = /obj/item/weapon/circuitboard/aifixer + desc = "Used with intelliCards containing nonfunctional AIs to restore them to working order." req_one_access = list(access_robotics, access_heads) - var/mob/living/silicon/ai/occupant = null - var/active = 0 + circuit = /obj/item/weapon/circuitboard/aifixer + icon_keyboard = "tech_key" + icon_screen = "ai-fixer" + light_color = LIGHT_COLOR_PINK + + active_power_usage = 1000 -/obj/machinery/computer/aifixer/New() - ..() - update_icon() - -/obj/machinery/computer/aifixer/proc/load_ai(var/mob/living/silicon/ai/transfer, var/obj/item/device/aicard/card, var/mob/user) - - if(!transfer) - return - - // Transfer over the AI. - to_chat(transfer, "You have been transferred into a stationary terminal. Sadly, there is no remote access from here.") - to_chat(user, "Transfer successful: [transfer.name] placed within stationary terminal.") - - transfer.loc = src - transfer.cancel_camera() - transfer.control_disabled = 1 - occupant = transfer - - if(card) - card.clear() - - update_icon() - -/obj/machinery/computer/aifixer/attackby(I as obj, user as mob) + /// Variable containing transferred AI + var/mob/living/silicon/ai/occupier + /// Variable dictating if we are in the process of restoring the occupier AI + var/restoring = FALSE +/obj/machinery/computer/aifixer/attackby(obj/item/I, mob/living/user) + if(I.is_screwdriver()) + if(occupier) + if(stat & (NOPOWER|BROKEN)) + to_chat(user, "The screws on [name]'s screen won't budge.") + else + to_chat(user, "The screws on [name]'s screen won't budge and it emits a warning beep.") + return if(istype(I, /obj/item/device/aicard)) - if(stat & (NOPOWER|BROKEN)) - to_chat(user, "This terminal isn't functioning right now.") + to_chat(user, "This terminal isn't functioning right now.") + return + if(restoring) + to_chat(user, "Terminal is busy restoring [occupier] right now.") return var/obj/item/device/aicard/card = I - var/mob/living/silicon/ai/comp_ai = locate() in src - var/mob/living/silicon/ai/card_ai = locate() in card + if(occupier) + if(card.grab_ai(occupier, user)) + occupier = null + else if(card.carded_ai) + var/mob/living/silicon/ai/new_occupant = card.carded_ai + to_chat(new_occupant, "You have been transferred into a stationary terminal. Sadly there is no remote access from here.") + to_chat(user, "Transfer Successful: [new_occupant] placed within stationary terminal.") + new_occupant.forceMove(src) + new_occupant.cancel_camera() + new_occupant.control_disabled = TRUE + occupier = new_occupant + card.clear() + update_icon() + else + to_chat(user, "There is no AI loaded onto this computer, and no AI loaded onto [I]. What exactly are you trying to do here?") + return ..() - if(istype(comp_ai)) - if(active) - to_chat(user, "ERROR: Reconstruction in progress.") - return - card.grab_ai(comp_ai, user) - if(!(locate(/mob/living/silicon/ai) in src)) occupant = null - else if(istype(card_ai)) - load_ai(card_ai,card,user) - occupant = locate(/mob/living/silicon/ai) in src - - update_icon() +/obj/machinery/computer/aifixer/attack_hand(mob/user) + if(stat & (NOPOWER|BROKEN)) return - ..() - return + tgui_interact(user) -/obj/machinery/computer/aifixer/attack_ai(var/mob/user as mob) - return attack_hand(user) +/obj/machinery/computer/aifixer/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AiRestorer", name) + ui.open() -/obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob) +/obj/machinery/computer/aifixer/tgui_data(mob/user) + var/list/data = list() + + data["ejectable"] = FALSE + data["AI_present"] = FALSE + data["error"] = null + if(!occupier) + data["error"] = "Please transfer an AI unit." + else + data["AI_present"] = TRUE + data["name"] = occupier.name + data["restoring"] = restoring + data["health"] = (occupier.health + 100) / 2 + data["isDead"] = occupier.stat == DEAD + var/list/laws = list() + for(var/datum/ai_law/law in occupier.laws.all_laws()) + laws += "[law.get_index()]: [law.law]" + data["laws"] = laws + + return data + +/obj/machinery/computer/aifixer/tgui_act(action, params) if(..()) - return + return TRUE + if(!occupier) + restoring = FALSE + + if(action) + playsound(src, "terminal_type", 50, 1) + + switch(action) + if("PRG_beginReconstruction") + if(occupier?.health < 100) + to_chat(usr, "Reconstruction in progress. This will take several minutes.") + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, FALSE) + restoring = TRUE + var/mob/observer/dead/ghost = occupier.get_ghost() + if(ghost) + ghost.notify_revive("Your core files are being restored!", source = src) + . = TRUE - user.set_machine(src) - var/dat = "

AI System Integrity Restorer



" +/obj/machinery/computer/aifixer/proc/Fix() + use_power(active_power_usage) + occupier.adjustOxyLoss(-5, 0, FALSE) + occupier.adjustFireLoss(-5, 0, FALSE) + occupier.adjustBruteLoss(-5, 0) + if(occupier.health >= 0 && occupier.stat == DEAD) + occupier.revive() - if (src.occupant) - var/laws - dat += "Stored AI: [src.occupant.name]
System integrity: [src.occupant.hardware_integrity()]%
Backup Capacitor: [src.occupant.backup_capacitor()]%
" - - for (var/datum/ai_law/law in occupant.laws.all_laws()) - laws += "[law.get_index()]: [law.law]
" - - dat += "Laws:
[laws]
" - - if (src.occupant.stat == 2) - dat += "AI nonfunctional" - else - dat += "AI functional" - if (!src.active) - dat += {"

Begin Reconstruction"} - else - dat += "

Reconstruction in process, please wait.
" - dat += {" Close"} - - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") - return + return occupier.health < 100 /obj/machinery/computer/aifixer/process() if(..()) - src.updateDialog() - return - -/obj/machinery/computer/aifixer/Topic(href, href_list) - if(..()) - return 1 - if (href_list["fix"]) - src.active = 1 - src.overlays += image(icon, "ai-fixer-on") - while (src.occupant.getOxyLoss() > 0 || src.occupant.getFireLoss() > 0 || src.occupant.getToxLoss() > 0 || src.occupant.getBruteLoss() > 0) - src.occupant.adjustOxyLoss(-1) - src.occupant.adjustFireLoss(-1) - src.occupant.adjustToxLoss(-1) - src.occupant.adjustBruteLoss(-1) - src.occupant.updatehealth() - if (src.occupant.health >= 0 && src.occupant.stat == DEAD) - src.occupant.set_stat(CONSCIOUS) - src.occupant.lying = 0 - dead_mob_list -= src.occupant - living_mob_list += src.occupant - src.overlays -= image(icon, "ai-fixer-404") - src.overlays += image(icon, "ai-fixer-full") - src.occupant.add_ai_verbs() - src.updateUsrDialog() - sleep(10) - src.active = 0 - src.overlays -= image(icon, "ai-fixer-on") - - - src.add_fingerprint(usr) - src.updateUsrDialog() - return - + if(restoring) + var/oldstat = occupier.stat + restoring = Fix() + if(oldstat != occupier.stat) + update_icon() /obj/machinery/computer/aifixer/update_icon() - ..() - if((stat & BROKEN) || (stat & NOPOWER)) + . = ..() + if(stat & (NOPOWER|BROKEN)) return - if(occupant) - if(occupant.stat) - add_overlay("ai-fixer-404") - else - add_overlay("ai-fixer-full") + if(restoring) + . += "ai-fixer-on" + if (occupier) + switch (occupier.stat) + if (CONSCIOUS) + . += "ai-fixer-full" + if (UNCONSCIOUS) + . += "ai-fixer-404" else - add_overlay("ai-fixer-empty") + . += "ai-fixer-empty" \ No newline at end of file diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 0ce27d99bb5..8ef01c9b645 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -14,17 +14,7 @@ /obj/item/clothing/suit/syndicatefake = 2, /obj/item/weapon/storage/fancy/crayons = 2, /obj/item/toy/spinningtoy = 2, - /obj/item/toy/prize/ripley = 1, - /obj/item/toy/prize/fireripley = 1, - /obj/item/toy/prize/deathripley = 1, - /obj/item/toy/prize/gygax = 1, - /obj/item/toy/prize/durand = 1, - /obj/item/toy/prize/honk = 1, - /obj/item/toy/prize/marauder = 1, - /obj/item/toy/prize/seraph = 1, - /obj/item/toy/prize/mauler = 1, - /obj/item/toy/prize/odysseus = 1, - /obj/item/toy/prize/phazon = 1, + /obj/random/mech_toy = 1, /obj/item/weapon/reagent_containers/spray/waterflower = 1, /obj/random/action_figure = 1, /obj/random/plushie = 1, @@ -156,6 +146,7 @@ blocked = 1 var/attackamt = rand(2,6) temp = "You attack for [attackamt] damage!" + playsound(src, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) if(turtle > 0) turtle-- @@ -168,6 +159,7 @@ var/pointamt = rand(1,3) var/healamt = rand(6,8) temp = "You use [pointamt] magic to heal for [healamt] damage!" + playsound(src, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) turtle++ sleep(10) @@ -180,6 +172,7 @@ blocked = 1 var/chargeamt = rand(4,7) temp = "You regain [chargeamt] points" + playsound(src, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) player_mp += chargeamt if(turtle > 0) turtle-- @@ -210,6 +203,7 @@ if(!gameover) gameover = 1 temp = "[enemy_name] has fallen! Rejoice!" + playsound(src, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) if(emagged) feedback_inc("arcade_win_emagged") @@ -230,11 +224,13 @@ else if (emagged && (turtle >= 4)) var/boomamt = rand(5,10) enemy_action = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!" + playsound(src, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) player_hp -= boomamt else if ((enemy_mp <= 5) && (prob(70))) var/stealamt = rand(2,3) enemy_action = "[enemy_name] steals [stealamt] of your power!" + playsound(src, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) player_mp -= stealamt if (player_mp <= 0) @@ -249,17 +245,20 @@ else if ((enemy_hp <= 10) && (enemy_mp > 4)) enemy_action = "[enemy_name] heals for 4 health!" + playsound(src, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) enemy_hp += 4 enemy_mp -= 4 else var/attackamt = rand(3,6) enemy_action = "[enemy_name] attacks for [attackamt] damage!" + playsound(src, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) player_hp -= attackamt if ((player_mp <= 0) || (player_hp <= 0)) gameover = 1 temp = "You have been crushed! GAME OVER" + playsound(src, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) if(emagged) feedback_inc("arcade_loss_hp_emagged") usr.gib() @@ -393,6 +392,7 @@ user.set_machine(src) var/dat = "" if(gameStatus == ORION_STATUS_GAMEOVER) + playsound(src, 'sound/arcade/Ori_fail.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) dat = "

Game Over

" dat += "Like many before you, your crew never made it to Orion, lost to space...
forever." if(settlers.len == 0) @@ -527,6 +527,7 @@ else if(href_list["newgame"]) //Reset everything if(gameStatus == ORION_STATUS_START) + playsound(src, 'sound/arcade/Ori_begin.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) newgame() else if(href_list["menu"]) //back to the main menu if(gameStatus == ORION_STATUS_GAMEOVER) @@ -598,6 +599,7 @@ else if(href_list["killcrew"]) //shoot a crewmember if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_MUTINY) + playsound(src, 'sound/arcade/kill_crew.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) var/sheriff = remove_crewmember() //I shot the sheriff var/mob/living/L = usr if(!istype(L)) @@ -623,6 +625,7 @@ else if(href_list["buycrew"]) //buy a crewmember if(gameStatus == ORION_STATUS_MARKET) if(!spaceport_raided && food >= 10 && fuel >= 10) + playsound(src, 'sound/arcade/get_fuel.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) var/bought = add_crewmember() last_spaceport_action = "You hired [bought] as a new crewmember." fuel -= 10 @@ -632,6 +635,7 @@ else if(href_list["sellcrew"]) //sell a crewmember if(gameStatus == ORION_STATUS_MARKET) if(!spaceport_raided && settlers.len > 1) + playsound(src, 'sound/arcade/lose_fuel.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) var/sold = remove_crewmember() last_spaceport_action = "You sold your crewmember, [sold]!" fuel += 7 @@ -649,6 +653,7 @@ else if(href_list["raid_spaceport"]) if(gameStatus == ORION_STATUS_MARKET) if(!spaceport_raided) + playsound(src, 'sound/arcade/raid.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) var/success = min(15 * alive,100) //default crew (4) have a 60% chance spaceport_raided = 1 @@ -687,6 +692,7 @@ else if(href_list["buyparts"]) if(gameStatus == ORION_STATUS_MARKET) if(!spaceport_raided && fuel > 5) + playsound(src, 'sound/arcade/get_fuel.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) switch(text2num(href_list["buyparts"])) if(1) //Engine Parts engine++ @@ -703,6 +709,7 @@ else if(href_list["trade"]) if(gameStatus == ORION_STATUS_MARKET) if(!spaceport_raided) + playsound(src, 'sound/arcade/get_fuel.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) switch(text2num(href_list["trade"])) if(1) //Fuel if(fuel > 5) @@ -745,6 +752,7 @@ canContinueEvent = 1 if(ORION_TRAIL_FLUX) + playsound(src, 'sound/arcade/explo.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) eventdat += "This region of space is highly turbulent.
If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies." eventdat += "
What will you do?" eventdat += "

Slow Down Continue

" @@ -759,6 +767,7 @@ canContinueEvent = 1 if(ORION_TRAIL_BREAKDOWN) + playsound(src, 'sound/arcade/explo.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) eventdat += "Oh no! The engine has broken down!" eventdat += "
You can repair it with an engine part, or you can make repairs for 3 days." if(engine >= 1) @@ -777,6 +786,7 @@ eventdat += "

Close

" if(ORION_TRAIL_COLLISION) + playsound(src, 'sound/arcade/explo.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) eventdat += "Something hit us! Looks like there's some hull damage." if(prob(25)) var/sfood = rand(5,15) @@ -992,6 +1002,7 @@ /obj/machinery/computer/arcade/orion_trail/proc/win() gameStatus = ORION_STATUS_START src.visible_message("\The [src] plays a triumpant tune, stating 'CONGRATULATIONS, YOU HAVE MADE IT TO ORION.'") + playsound(src, 'sound/arcade/Ori_win.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE) if(emagged) new /obj/item/weapon/orion_ship(src.loc) message_admins("[key_name_admin(usr)] made it to Orion on an emagged machine and got an explosive toy ship.") diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 7f5c27a0d47..304c2548373 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -17,16 +17,22 @@ var/global/list/minor_air_alarms = list() atmosphere_alarm.register_alarm(src, /obj/machinery/computer/station_alert/update_icon) /obj/machinery/computer/atmos_alert/Destroy() - atmosphere_alarm.unregister_alarm(src) - ..() + atmosphere_alarm.unregister_alarm(src) + ..() /obj/machinery/computer/atmos_alert/attack_hand(mob/user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/atmos_alert/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - var/major_alarms[0] - var/minor_alarms[0] +/obj/machinery/computer/atmos_alert/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AtmosAlertConsole", name) + ui.open() + +/obj/machinery/computer/atmos_alert/tgui_data(mob/user) + var/list/data = list() + var/list/major_alarms = list() + var/list/minor_alarms = list() for(var/datum/alarm/alarm in atmosphere_alarm.major_alarms(get_z(src))) major_alarms[++major_alarms.len] = list("name" = sanitize(alarm.alarm_name()), "ref" = "\ref[alarm]") @@ -37,12 +43,7 @@ var/global/list/minor_air_alarms = list() data["priority_alarms"] = major_alarms data["minor_alarms"] = minor_alarms - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "atmos_alert.tmpl", src.name, 500, 500) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data /obj/machinery/computer/atmos_alert/update_icon() if(!(stat & (NOPOWER|BROKEN))) @@ -57,26 +58,21 @@ var/global/list/minor_air_alarms = list() icon_screen = initial(icon_screen) ..() -/obj/machinery/computer/atmos_alert/Topic(href, href_list) +/obj/machinery/computer/atmos_alert/tgui_act(action, params) if(..()) - return 1 + return TRUE - if(href_list["clear_alarm"]) - var/datum/alarm/alarm = locate(href_list["clear_alarm"]) in atmosphere_alarm.alarms - if(alarm) - for(var/datum/alarm_source/alarm_source in alarm.sources) - var/obj/machinery/alarm/air_alarm = alarm_source.source - if(istype(air_alarm)) - var/list/new_ref = list("atmos_reset" = 1) - air_alarm.Topic(href, new_ref, state = air_alarm_topic) - return 1 - - -var/datum/topic_state/air_alarm_topic/air_alarm_topic = new() - -/datum/topic_state/air_alarm_topic/href_list(var/mob/user) - var/list/extra_href = list() - extra_href["remote_connection"] = 1 - extra_href["remote_access"] = 1 - - return extra_href + switch(action) + if("clear") + var/datum/alarm/alarm = locate(params["ref"]) in atmosphere_alarm.alarms + if(alarm) + for(var/datum/alarm_source/alarm_source in alarm.sources) + var/obj/machinery/alarm/air_alarm = alarm_source.source + if(istype(air_alarm)) + // I have to leave a note here: + // Once upon a time, this called air_alarm.Topic() with a custom topic state + // in order to perform three lines of code. In other words, pure insanity. + // Whyyyyyyyyyyyyyyyyyyyyyyy. + air_alarm.atmos_reset() + . = TRUE + update_icon() diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index 48f899ed0d5..c38af8ae414 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -13,7 +13,7 @@ circuit = /obj/item/weapon/circuitboard/atmoscontrol req_access = list(access_ce) var/list/monitored_alarm_ids = null - var/datum/nano_module/atmos_control/atmos_control + var/datum/tgui_module/atmos_control/atmos_control /obj/machinery/computer/atmoscontrol/New() ..() @@ -27,12 +27,12 @@ density = 0 /obj/machinery/computer/atmoscontrol/attack_ai(var/mob/user as mob) - ui_interact(user) + tgui_interact(user) /obj/machinery/computer/atmoscontrol/attack_hand(mob/user) if(..()) return 1 - ui_interact(user) + tgui_interact(user) /obj/machinery/computer/atmoscontrol/emag_act(var/remaining_carges, var/mob/user) if(!emagged) @@ -42,7 +42,7 @@ atmos_control.emagged = 1 return 1 -/obj/machinery/computer/atmoscontrol/ui_interact(var/mob/user) +/obj/machinery/computer/atmoscontrol/tgui_interact(var/mob/user) if(!atmos_control) atmos_control = new(src, req_access, req_one_access, monitored_alarm_ids) - atmos_control.ui_interact(user) + atmos_control.tgui_interact(user) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index fe0a9c8a628..97d68e190a1 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -3,201 +3,49 @@ /obj/machinery/computer/security name = "security camera monitor" desc = "Used to access the various cameras on the station." + icon_keyboard = "security_key" icon_screen = "cameras" light_color = "#a91515" - var/current_network = null - var/obj/machinery/camera/current_camera = null - var/last_pic = 1.0 - var/list/network - var/mapping = 0//For the overview file, interesting bit of code. - var/cache_id = 0 circuit = /obj/item/weapon/circuitboard/security -/obj/machinery/computer/security/New() - if(!network) - network = using_map.station_networks.Copy() - ..() - if(network.len) - current_network = network[1] + var/mapping = 0//For the overview file, interesting bit of code. + var/list/network = list() -/obj/machinery/computer/security/attack_ai(var/mob/user as mob) - return attack_hand(user) + var/datum/tgui_module/camera/camera -/obj/machinery/computer/security/check_eye(var/mob/user as mob) - if (user.stat || ((get_dist(user, src) > 1 || !( user.canmove ) || user.blinded) && !istype(user, /mob/living/silicon))) //user can't see - not sure why canmove is here. - return -1 - if(!current_camera) - return 0 - var/viewflag = current_camera.check_eye(user) - if ( viewflag < 0 ) //camera doesn't work - reset_current() - return viewflag +/obj/machinery/computer/security/Initialize() + . = ..() + if(!LAZYLEN(network)) + network = get_default_networks() + camera = new(src, network) -/obj/machinery/computer/security/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) - if(stat & (NOPOWER|BROKEN)) return - if(user.stat) return +/obj/machinery/computer/security/proc/get_default_networks() + . = using_map.station_networks.Copy() - var/data[0] +/obj/machinery/computer/security/Destroy() + QDEL_NULL(camera) + return ..() - data["current_camera"] = current_camera ? current_camera.nano_structure() : null - data["current_network"] = current_network - data["networks"] = network ? network : list() - - var/map_levels = using_map.get_map_levels(src.z, TRUE) - data["map_levels"] = map_levels - - if(current_network) - data["cameras"] = camera_repository.cameras_in_network(current_network, map_levels) - if(current_camera) - switch_to_camera(user, current_camera) +/obj/machinery/computer/security/tgui_interact(mob/user, datum/tgui/ui = null) + camera.tgui_interact(user, ui) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "sec_camera.tmpl", "Camera Console", 900, 800) +/obj/machinery/computer/security/attack_hand(mob/user) + add_fingerprint(user) + if(stat & (BROKEN|NOPOWER)) + return + tgui_interact(user) - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "sec_camera_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "sec_camera_map_header.tmpl") - - ui.set_initial_data(data) - ui.open() - -/obj/machinery/computer/security/Topic(href, href_list) - if(..()) - return 1 - if(href_list["switch_camera"]) - if(stat&(NOPOWER|BROKEN)) return //VOREStation Edit - Removed zlevel check - if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return - var/obj/machinery/camera/C = locate(href_list["switch_camera"]) in cameranet.cameras - if(!C) - return - if(!(current_network in C.network)) - return - - switch_to_camera(usr, C) - return 1 - else if(href_list["switch_network"]) - if(stat&(NOPOWER|BROKEN)) return //VOREStation Edit - Removed zlevel check - if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return - if(href_list["switch_network"] in network) - current_network = href_list["switch_network"] - return 1 - else if(href_list["reset"]) - if(stat&(NOPOWER|BROKEN)) return //VOREStation Edit - Removed zlevel check - if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return - reset_current() - usr.reset_view(current_camera) - return 1 - else - . = ..() - -/obj/machinery/computer/security/attack_hand(var/mob/user as mob) - if(stat & (NOPOWER|BROKEN)) return - - if(!isAI(user)) - user.set_machine(src) - ui_interact(user) - -/obj/machinery/computer/security/proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C) - //don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras. +/obj/machinery/computer/security/attack_ai(mob/user) if(isAI(user)) - var/mob/living/silicon/ai/A = user - // Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise. - if(!A.is_in_chassis()) - return 0 - - A.eyeobj.setLoc(get_turf(C)) - A.client.eye = A.eyeobj - return 1 - - if (!C.can_use() || user.stat || (get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) && !istype(user, /mob/living/silicon))) - return 0 - set_current(C) - user.reset_view(current_camera) - check_eye(user) - return 1 - -/obj/machinery/computer/security/relaymove(mob/user,direct) - var/turf/T = get_turf(current_camera) - for(var/i; i < 10; i++) - T = get_step(T, direct) - jump_on_click(user, T) - -//Camera control: moving. -/obj/machinery/computer/security/proc/jump_on_click(var/mob/user,var/A) - if(user.machine != src) + to_chat(user, "You realise its kind of stupid to access a camera console when you have the entire camera network at your metaphorical fingertips") return - var/obj/machinery/camera/jump_to - if(istype(A,/obj/machinery/camera)) - jump_to = A - else if(ismob(A)) - if(ishuman(A)) - jump_to = locate() in A:head - else if(isrobot(A)) - jump_to = A:camera - else if(isobj(A)) - jump_to = locate() in A - else if(isturf(A)) - var/best_dist = INFINITY - for(var/obj/machinery/camera/camera in get_area(A)) - if(!camera.can_use()) - continue - if(!can_access_camera(camera)) - continue - var/dist = get_dist(camera,A) - if(dist < best_dist) - best_dist = dist - jump_to = camera - if(isnull(jump_to)) - return - if(can_access_camera(jump_to)) - switch_to_camera(user,jump_to) + attack_hand(user) -/obj/machinery/computer/security/process() - if(cache_id != camera_repository.camera_cache_id) - cache_id = camera_repository.camera_cache_id - SSnanoui.update_uis(src) - -/obj/machinery/computer/security/proc/can_access_camera(var/obj/machinery/camera/C) - var/list/shared_networks = src.network & C.network - if(shared_networks.len) - return 1 - return 0 - -/obj/machinery/computer/security/proc/set_current(var/obj/machinery/camera/C) - if(current_camera == C) - return - - if(current_camera) - reset_current() - - src.current_camera = C - if(current_camera) - current_camera.camera_computers_using_this.Add(src) - update_use_power(USE_POWER_ACTIVE) - var/mob/living/L = current_camera.loc - if(istype(L)) - L.tracking_initiated() - -/obj/machinery/computer/security/proc/reset_current() - if(current_camera) - current_camera.camera_computers_using_this.Remove(src) - var/mob/living/L = current_camera.loc - if(istype(L)) - L.tracking_cancelled() - current_camera = null - update_use_power(USE_POWER_IDLE) - -//Camera control: mouse. -/* Oh my god -/atom/DblClick() - ..() - if(istype(usr.machine,/obj/machinery/computer/security)) - var/obj/machinery/computer/security/console = usr.machine - console.jump_on_click(usr,src) -*/ +/obj/machinery/computer/security/proc/set_network(list/new_network) + network = new_network + camera.network = network + camera.access_based = FALSE //Camera control: arrow keys. /obj/machinery/computer/security/telescreen @@ -268,10 +116,8 @@ circuit = /obj/item/weapon/circuitboard/security/engineering light_color = "#FAC54B" -/obj/machinery/computer/security/engineering/New() - if(!network) - network = engineering_networks.Copy() - ..() +/obj/machinery/computer/security/engineering/get_default_networks() + . = engineering_networks.Copy() /obj/machinery/computer/security/nuclear name = "head mounted camera monitor" @@ -279,7 +125,4 @@ icon_state = "syndicam" network = list(NETWORK_MERCENARY) circuit = null - -/obj/machinery/computer/security/nuclear/New() - ..() - req_access = list(150) \ No newline at end of file + req_access = list(150) diff --git a/code/game/machinery/computer/camera_circuit.dm b/code/game/machinery/computer/camera_circuit.dm deleted file mode 100644 index 2bbe82ee1b8..00000000000 --- a/code/game/machinery/computer/camera_circuit.dm +++ /dev/null @@ -1,116 +0,0 @@ - -//the researchable camera circuit that can connect to any camera network - -/obj/item/weapon/circuitboard/camera - //name = "Circuit board (Camera)" - var/secured = 1 - var/authorised = 0 - var/possibleNets[0] - var/network = "" - build_path = null - -//when adding a new camera network, you should only need to update these two procs - New() - possibleNets["Engineering"] = access_ce - possibleNets["SS13"] = access_hos - possibleNets["Mining"] = access_mining - possibleNets["Cargo"] = access_qm - possibleNets["Research"] = access_rd - possibleNets["Medbay"] = access_cmo - ..() - - proc/updateBuildPath() - build_path = null - if(authorised && secured) - switch(network) - if("SS13") - build_path = /obj/machinery/computer/security - if("Engineering") - build_path = /obj/machinery/computer/security/engineering - if("Mining") - build_path = /obj/machinery/computer/security/mining - if("Research") - build_path = /obj/machinery/computer/security/research - if("Medbay") - build_path = /obj/machinery/computer/security/medbay - if("Cargo") - build_path = /obj/machinery/computer/security/cargo - - attackby(var/obj/item/I, var/mob/user)//if(health > 50) - ..() - else if(I.is_screwdriver()) - secured = !secured - user.visible_message("The [src] can [secured ? "no longer" : "now"] be modified.") - playsound(src, I.usesound, 50, 1) - updateBuildPath() - return - - attack_self(var/mob/user) - if(!secured && ishuman(user)) - user.machine = src - interact(user, 0) - - proc/interact(var/mob/user, var/ai=0) - if(secured) - return - if (!ishuman(user)) - return ..(user) - var/t = "Circuitboard Console - Camera Monitoring Computer
" - t += "Close
" - t += "
Please select a camera network:
" - - for(var/curNet in possibleNets) - if(network == curNet) - t += "- [curNet]
" - else - t += "- [curNet]
" - t += "
" - if(network) - if(authorised) - t += "Authenticated (Clear Auth)
" - else - t += "*Authenticate* (Requires an appropriate access ID)
" - else - t += "*Authenticate* (Requires an appropriate access ID)
" - t += "Close
" - user << browse(t, "window=camcircuit;size=500x400") - onclose(user, "camcircuit") - - Topic(href, href_list) - ..() - if( href_list["close"] ) - usr << browse(null, "window=camcircuit") - usr.machine = null - return - else if(href_list["net"]) - network = href_list["net"] - authorised = 0 - else if( href_list["auth"] ) - var/mob/M = usr - var/obj/item/weapon/card/id/I = M.equipped() - if (istype(I, /obj/item/device/pda)) - var/obj/item/device/pda/pda = I - I = pda.id - if (I && istype(I)) - if(access_captain in I.access) - authorised = 1 - else if (possibleNets[network] in I.access) - authorised = 1 - if(istype(I,/obj/item/weapon/card/emag)) - I.resolve_attackby(src, usr) - else if( href_list["removeauth"] ) - authorised = 0 - updateDialog() - - updateDialog() - if(istype(src.loc,/mob)) - attack_self(src.loc) - -/obj/item/weapon/circuitboard/camera/emag_act(var/remaining_charges, var/mob/user) - if(network) - authorised = 1 - to_chat(user, "You authorised the circuit network!") - updateDialog() - return 1 - else - to_chat(user, "You must select a camera network circuit!") diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 042263f8a37..7833a58d726 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -195,6 +195,7 @@ modify.access -= access_type if(!access_allowed) modify.access += access_type + modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications if ("assign") if (is_authenticated() && modify) @@ -218,6 +219,7 @@ modify.access = access modify.assignment = t1 modify.rank = t1 + modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications callHook("reassign_employee", list(modify)) @@ -276,12 +278,12 @@ if (is_authenticated()) modify.assignment = "Dismissed" //VOREStation Edit: setting adjustment modify.access = list() + modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications callHook("terminate_employee", list(modify)) if (modify) modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])") - modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications return 1 diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 30c15f6d04a..9bf3235d8d0 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -1,34 +1,64 @@ +#define MENU_MAIN 1 +#define MENU_RECORDS 2 + /obj/machinery/computer/cloning - name = "cloning control console" - desc = "Used to start cloning cycles, as well as manage clone records." + name = "cloning console" + icon = 'icons/obj/computer.dmi' icon_keyboard = "med_key" icon_screen = "dna" - light_color = "#315ab4" circuit = /obj/item/weapon/circuitboard/cloning req_access = list(access_heads) //Only used for record deletion right now. var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. - var/list/pods = list() //Linked cloning pods. - var/temp = "" - var/scantemp = "Scanner unoccupied" - var/menu = 1 //Which menu screen to display - var/list/records = list() + var/list/pods = null //Linked cloning pods. + var/list/temp = null + var/list/scantemp = null + var/menu = MENU_MAIN //Which menu screen to display + var/list/records = null var/datum/dna2/record/active_record = null var/obj/item/weapon/disk/data/diskette = null //Mostly so the geneticist can steal everything. var/loading = 0 // Nice loading text + var/autoprocess = 0 + var/obj/machinery/clonepod/selected_pod + // 0: Standard body scan + // 1: The "Best" scan available + var/scan_mode = 1 + light_color = "#315ab4" /obj/machinery/computer/cloning/Initialize() - . = ..() + ..() + pods = list() + records = list() + set_scan_temp("Scanner ready.", "good") updatemodules() /obj/machinery/computer/cloning/Destroy() releasecloner() - ..() + return ..() + +/obj/machinery/computer/cloning/process() + if(!scanner || !pods.len || !autoprocess || stat & NOPOWER) + return + + if(scanner.occupant && can_autoprocess()) + scan_mob(scanner.occupant) + + if(!LAZYLEN(records)) + return + + for(var/obj/machinery/clonepod/pod in pods) + if(!(pod.occupant || pod.mess) && (pod.efficiency > 5)) + for(var/datum/dna2/record/R in records) + if(!(pod.occupant || pod.mess)) + if(pod.growclone(R)) + records.Remove(R) /obj/machinery/computer/cloning/proc/updatemodules() scanner = findscanner() releasecloner() findcloner() + if(!selected_pod && pods.len) + selected_pod = pods[1] /obj/machinery/computer/cloning/proc/findscanner() var/obj/machinery/dna_scannernew/scannerf = null @@ -36,16 +66,15 @@ //Try to find scanner on adjacent tiles first for(dir in list(NORTH,EAST,SOUTH,WEST)) scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) - if (scannerf) + if(scannerf) return scannerf //Then look for a free one in the area if(!scannerf) - var/area/A = get_area(src) - for(var/obj/machinery/dna_scannernew/S in A.get_contents()) + for(var/obj/machinery/dna_scannernew/S in get_area(src)) return S - return + return 0 /obj/machinery/computer/cloning/proc/releasecloner() for(var/obj/machinery/clonepod/P in pods) @@ -55,21 +84,20 @@ /obj/machinery/computer/cloning/proc/findcloner() var/num = 1 - var/area/A = get_area(src) - for(var/obj/machinery/clonepod/P in A.get_contents()) + for(var/obj/machinery/clonepod/P in get_area(src)) if(!P.connected) pods += P P.connected = src P.name = "[initial(P.name)] #[num++]" -/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 (!diskette) +/obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES + if(!diskette) user.drop_item() W.loc = src diskette = W to_chat(user, "You insert [W].") - updateUsrDialog() + SStgui.update_uis(src) return else if(istype(W, /obj/item/device/multitool)) var/obj/item/device/multitool/M = W @@ -79,18 +107,8 @@ P.connected = src P.name = "[initial(P.name)] #[pods.len]" to_chat(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 + return ..() /obj/machinery/computer/cloning/attack_ai(mob/user as mob) return attack_hand(user) @@ -103,233 +121,303 @@ return updatemodules() + tgui_interact(user) - ui_interact(user) +/obj/machinery/computer/cloning/resleeving/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/cloning) + ) -/obj/machinery/computer/cloning/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) - - var/data[0] - - 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) - - 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.get_biomass()) - - if(pods) - data["pods"] = pods_list_ui - else - data["pods"] = null - - if(records) - data["records"] = records_list_ui - else - data["records"] = null - - 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 - - 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 - - ui = SSnanoui.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(..()) - return 1 - - if(loading) +/obj/machinery/computer/cloning/tgui_interact(mob/user, datum/tgui/ui = null) + if(stat & (NOPOWER|BROKEN)) return - if ((href_list["scan"]) && (!isnull(scanner))) - scantemp = "" + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "CloningConsole", "Cloning Console") + ui.open() - loading = 1 +/obj/machinery/computer/cloning/tgui_data(mob/user) + var/data[0] + data["menu"] = menu + data["scanner"] = sanitize("[scanner]") - spawn(20) - scan_mob(scanner.occupant) + var/canpodautoprocess = 0 + if(pods.len) + data["numberofpods"] = pods.len - loading = 0 + var/list/tempods[0] + for(var/obj/machinery/clonepod/pod in pods) + if(pod.efficiency > 5) + canpodautoprocess = 1 - //No locking an open scanner. - else if ((href_list["lock"]) && (!isnull(scanner))) - if ((!scanner.locked) && (scanner.occupant)) - scanner.locked = 1 - else - scanner.locked = 0 + var/status = "idle" + if(pod.mess) + status = "mess" + else if(pod.occupant && !(pod.stat & NOPOWER)) + status = "cloning" + tempods.Add(list(list( + "pod" = "\ref[pod]", + "name" = sanitize(capitalize(pod.name)), + "biomass" = pod.get_biomass(), + "status" = status, + "progress" = (pod.occupant && pod.occupant.stat != DEAD) ? pod.get_completion() : 0 + ))) + data["pods"] = tempods - else if ((href_list["eject"]) && (!isnull(scanner))) - if ((!scanner.locked) && (scanner.occupant)) - scanner.eject_occupant() + data["loading"] = loading + data["autoprocess"] = autoprocess + data["can_brainscan"] = can_brainscan() // You'll need tier 4s for this + data["scan_mode"] = scan_mode - else if (href_list["view_rec"]) - 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 - menu = 3 - else - active_record = null - temp = "Record missing." + if(scanner && pods.len && ((scanner.scan_level > 2) || canpodautoprocess)) + data["autoallowed"] = 1 + else + data["autoallowed"] = 0 + if(scanner) + data["occupant"] = scanner.occupant + data["locked"] = scanner.locked + data["temp"] = temp + data["scantemp"] = scantemp + data["disk"] = diskette + data["selected_pod"] = "\ref[selected_pod]" + var/list/temprecords[0] + for(var/datum/dna2/record/R in records) + var tempRealName = R.dna.real_name + temprecords.Add(list(list("record" = "\ref[R]", "realname" = sanitize(tempRealName)))) + data["records"] = temprecords - else if (href_list["del_rec"]) - if ((!active_record) || (menu < 3)) - return - if (menu == 3) //If we are viewing a record, confirm deletion - temp = "Delete record?" - menu = 4 + if(selected_pod && (selected_pod in pods) && selected_pod.get_biomass() >= CLONE_BIOMASS) + data["podready"] = 1 + else + data["podready"] = 0 - else if (href_list["disk"]) //Load or eject. - switch(href_list["disk"]) - if("load") - if ((isnull(diskette)) || isnull(diskette.buf)) - temp = "Load error." + data["modal"] = tgui_modal_data(src) + + return data + +/obj/machinery/computer/cloning/tgui_act(action, params) + if(..()) + return TRUE + + . = TRUE + switch(tgui_modal_act(src, action, params)) + if(TGUI_MODAL_ANSWER) + if(params["id"] == "del_rec" && active_record) + var/obj/item/weapon/card/id/C = usr.get_active_hand() + if(!istype(C) && !istype(C, /obj/item/device/pda)) + set_temp("ID not in hand.", "danger") return - if (isnull(active_record)) - temp = "Record error." - menu = 1 - return - - active_record = diskette.buf - - temp = "Load successful." - if("eject") - if (!isnull(diskette)) - diskette.loc = loc - diskette = null - - else if (href_list["save_disk"]) //Save to disk! - if ((isnull(diskette)) || (diskette.read_only) || (isnull(active_record))) - temp = "Save error." - - // DNA2 makes things a little simpler. - diskette.buf = active_record - diskette.buf.types = 0 - switch(href_list["save_disk"]) //Save as Ui/Ui+Ue/Se - if("ui") - diskette.buf.types = DNA2_BUF_UI - if("ue") - diskette.buf.types = DNA2_BUF_UI | DNA2_BUF_UE - if("se") - 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"]) - updateUsrDialog() - - else if (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. - if(!LAZYLEN(pods)) - temp = "Error: No clone pods detected." - else - var/obj/machinery/clonepod/pod = pods[1] - if (pods.len > 1) - pod = input(usr,"Select a cloning pod to use", "Pod selection") as anything in pods - if(pod.occupant) - temp = "Error: Clonepod is currently occupied." - else if(pod.get_biomass() < CLONE_BIOMASS) - temp = "Error: Not enough biomass." - else if(pod.mess) - temp = "Error: Clonepod malfunction." - else if(!config.revival_cloning) - temp = "Error: Unable to initiate cloning cycle." - else if(pod.growclone(C)) - temp = "Initiating cloning cycle..." - records.Remove(C) - qdel(C) - menu = 1 + if(check_access(C)) + records.Remove(active_record) + qdel(active_record) + set_temp("Record deleted.", "success") + menu = MENU_RECORDS else + set_temp("Access denied.", "danger") + return - var/mob/selected = find_dead_player("[C.ckey]") - selected << 'sound/machines/chime.ogg' //probably not the best sound but I think it's reasonable - var/answer = alert(selected,"Do you want to return to life?","Cloning","Yes","No") - if(answer != "No" && pod.growclone(C)) - temp = "Initiating cloning cycle..." - records.Remove(C) - qdel(C) - menu = 1 + switch(action) + if("scan") + if(!scanner || !scanner.occupant || loading) + return + set_scan_temp("Scanner ready.", "good") + loading = TRUE + + spawn(20) + if(can_brainscan() && scan_mode) + scan_mob(scanner.occupant, scan_brain = TRUE) + else + scan_mob(scanner.occupant) + loading = FALSE + SStgui.update_uis(src) + if("autoprocess") + autoprocess = text2num(params["on"]) > 0 + if("lock") + if(isnull(scanner) || !scanner.occupant) //No locking an open scanner. + return + scanner.locked = !scanner.locked + if("view_rec") + var/ref = params["ref"] + if(!length(ref)) + return + active_record = locate(ref) + if(istype(active_record)) + if(isnull(active_record.ckey)) + qdel(active_record) + set_temp("Error: Record corrupt.", "danger") + else + var/obj/item/weapon/implant/health/H = null + if(active_record.implant) + H = locate(active_record.implant) + var/list/payload = list( + activerecord = "\ref[active_record]", + health = (H && istype(H)) ? H.sensehealth() : "", + realname = sanitize(active_record.dna.real_name), + unidentity = active_record.dna.uni_identity, + strucenzymes = active_record.dna.struc_enzymes, + ) + tgui_modal_message(src, action, "", null, payload) + else + active_record = null + set_temp("Error: Record missing.", "danger") + if("del_rec") + if(!active_record) + return + tgui_modal_boolean(src, action, "Please confirm that you want to delete the record by holding your ID and pressing Delete:", yes_text = "Delete", no_text = "Cancel") + if("disk") // Disk management. + if(!length(params["option"])) + return + switch(params["option"]) + if("load") + if(isnull(diskette) || isnull(diskette.buf)) + set_temp("Error: The disk's data could not be read.", "danger") + return + else if(isnull(active_record)) + set_temp("Error: No active record was found.", "danger") + menu = MENU_MAIN + return + + active_record = diskette.buf + set_temp("Successfully loaded from disk.", "success") + if("save") + if(isnull(diskette) || diskette.read_only || isnull(active_record)) + set_temp("Error: The data could not be saved.", "danger") + return + + // DNA2 makes things a little simpler. + var/types + switch(params["savetype"]) // Save as Ui/Ui+Ue/Se + if("ui") + types = DNA2_BUF_UI + if("ue") + types = DNA2_BUF_UI|DNA2_BUF_UE + if("se") + types = DNA2_BUF_SE + else + set_temp("Error: Invalid save format.", "danger") + return + diskette.buf = active_record + diskette.buf.types = types + diskette.name = "data disk - '[active_record.dna.real_name]'" + set_temp("Successfully saved to disk.", "success") + if("eject") + if(!isnull(diskette)) + diskette.loc = loc + diskette = null + if("refresh") + SStgui.update_uis(src) + if("selectpod") + var/ref = params["ref"] + if(!length(ref)) + return + var/obj/machinery/clonepod/selected = locate(ref) + if(istype(selected) && (selected in pods)) + selected_pod = selected + if("clone") + var/ref = params["ref"] + if(!length(ref)) + return + var/datum/dna2/record/C = locate(ref) + //Look for that player! They better be dead! + if(istype(C)) + tgui_modal_clear(src) + //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. + if(!length(pods)) + set_temp("Error: No cloning pod detected.", "danger") + else + var/obj/machinery/clonepod/pod = selected_pod + var/cloneresult + if(!selected_pod) + set_temp("Error: No cloning pod selected.", "danger") + else if(pod.occupant) + set_temp("Error: The cloning pod is currently occupied.", "danger") + else if(pod.get_biomass() < CLONE_BIOMASS) + set_temp("Error: Not enough biomass.", "danger") + else if(pod.mess) + set_temp("Error: The cloning pod is malfunctioning.", "danger") + else if(!config.revival_cloning) + set_temp("Error: Unable to initiate cloning cycle.", "danger") else - temp = "Initiating cloning cycle...
Error: Post-initialisation failed. Cloning cycle aborted." - + cloneresult = pod.growclone(C) + if(cloneresult) + set_temp("Initiating cloning cycle...", "success") + records.Remove(C) + qdel(C) + menu = MENU_MAIN + else + set_temp("Error: Initialisation failure.", "danger") + else + set_temp("Error: Data corruption.", "danger") + if("menu") + menu = clamp(text2num(params["num"]), MENU_MAIN, MENU_RECORDS) + if("toggle_mode") + if(loading) + return + if(can_brainscan()) + scan_mode = !scan_mode + else + scan_mode = FALSE + if("eject") + if(usr.incapacitated() || !scanner || loading) + return + scanner.eject_occupant(usr) + scanner.add_fingerprint(usr) + if("cleartemp") + temp = null else - temp = "Error: Data corruption." + return FALSE - else if (href_list["menu"]) - menu = href_list["menu"] - temp = "" - scantemp = "" - - SSnanoui.update_uis(src) add_fingerprint(usr) -/obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob) - var/brain_skip = 0 - if (istype(subject, /mob/living/carbon/brain)) //Brain scans. - brain_skip = 1 - if ((isnull(subject)) || (!(ishuman(subject)) && !brain_skip) || (!subject.dna)) - scantemp = "Error: Unable to locate valid genetic data." +/obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob, var/scan_brain = 0) + if(stat & NOPOWER) return - if (!subject.has_brain() && !brain_skip) - if(istype(subject, /mob/living/carbon/human)) + if(scanner.stat & (NOPOWER|BROKEN)) + return + if(scan_brain && !can_brainscan()) + return + if(isnull(subject) || (!(ishuman(subject))) || (!subject.dna)) + if(isalien(subject)) + set_scan_temp("Xenomorphs are not scannable.", "bad") + SStgui.update_uis(src) + return + // can add more conditions for specific non-human messages here + else + set_scan_temp("Subject species is not scannable.", "bad") + SStgui.update_uis(src) + return + if(!subject.has_brain()) + if(ishuman(subject)) var/mob/living/carbon/human/H = subject if(H.should_have_organ("brain")) - scantemp = "Error: No signs of intelligence detected." + set_scan_temp("No brain detected in subject.", "bad") else - scantemp = "Error: No signs of intelligence detected." + set_scan_temp("No brain detected in subject.", "bad") + SStgui.update_uis(src) + return + if(subject.suiciding) + set_scan_temp("Subject has committed suicide and is not scannable.", "bad") + SStgui.update_uis(src) + return + if((!subject.ckey) || (!subject.client)) + set_scan_temp("Subject's brain is not responding. Further attempts after a short delay may succeed.", "bad") + SStgui.update_uis(src) + return + if((NOCLONE in subject.mutations)) + set_scan_temp("Subject has incompatible genetic mutations.", "bad") + SStgui.update_uis(src) + return + if(!isnull(find_record(subject.ckey))) + set_scan_temp("Subject already in database.") + SStgui.update_uis(src) return - if(subject.isSynthetic()) - scantemp = "Error: Majority of subject is non-organic." - return - if (subject.suiciding) - scantemp = "Error: Subject's brain is not responding to scanning stimuli." - return - if (NOCLONE in subject.mutations) - scantemp = "Error: Mental interface failure." - return - if (subject.species && subject.species.flags & NO_SCAN && !brain_skip) - scantemp = "Error: Mental interface failure." - return - for(var/modifier_type in subject.modifiers) //Can't be cloned, even if they had a previous scan - if(istype(modifier_type, /datum/modifier/no_clone)) - scantemp = "Error: Mental interface failure." + for(var/obj/machinery/clonepod/pod in pods) + if(pod.occupant && pod.occupant.mind == subject.mind) + set_scan_temp("Subject already getting cloned.") + SStgui.update_uis(src) return - if ((!subject.ckey) || (!subject.client)) - scantemp = "Error: Mental interface failure." - if(subject.stat == DEAD && subject.mind && subject.mind.key) // If they're dead and not in their body, tell them to get in it. - var/mob/observer/dead/ghost = subject.get_ghost() - if(ghost) - ghost.notify_revive("Someone is trying to scan your body in the cloner. Re-enter your body if you want to be revived!", 'sound/effects/genetics.ogg', source = src) - return - if (!isnull(find_record(subject.ckey))) - scantemp = "Subject already in database." - return subject.dna.check_integrity() @@ -342,10 +430,7 @@ R.languages = subject.languages R.gender = subject.gender R.body_descriptors = subject.descriptors - if(!brain_skip) //Brains don't have flavor text. - R.flavor = subject.flavor_texts.Copy() - else - R.flavor = list() + R.flavor = subject.flavor_texts.Copy() for(var/datum/modifier/mod in subject.modifiers) if(mod.flags & MODIFIER_GENETIC) R.genetic_modifiers.Add(mod.type) @@ -364,13 +449,47 @@ R.mind = "\ref[subject.mind]" records += R - scantemp = "Subject successfully scanned." + set_scan_temp("Subject successfully scanned.", "good") + SStgui.update_uis(src) //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 records) - if (R.ckey == find_key) + if(R.ckey == find_key) selected_record = R break return selected_record + +/obj/machinery/computer/cloning/proc/can_autoprocess() + return (scanner && scanner.scan_level > 2) + +/obj/machinery/computer/cloning/proc/can_brainscan() + return (scanner && scanner.scan_level > 3) + +/** + * Sets a temporary message to display to the user + * + * Arguments: + * * text - Text to display, null/empty to clear the message from the UI + * * style - The style of the message: (color name), info, success, warning, danger + */ +/obj/machinery/computer/cloning/proc/set_temp(text = "", style = "info", update_now = FALSE) + temp = list(text = text, style = style) + if(update_now) + SStgui.update_uis(src) + +/** + * Sets a temporary scan message to display to the user + * + * Arguments: + * * text - Text to display, null/empty to clear the message from the UI + * * color - The color of the message: (color name) + */ +/obj/machinery/computer/cloning/proc/set_scan_temp(text = "", color = "", update_now = FALSE) + scantemp = list(text = text, color = color) + if(update_now) + SStgui.update_uis(src) + +#undef MENU_MAIN +#undef MENU_RECORDS \ No newline at end of file diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 49ba537a2d4..cae1788af1e 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -70,11 +70,13 @@ set_light(0) if(icon_keyboard) add_overlay("[icon_keyboard]_off") + playsound(src, 'sound/machines/terminal_off.ogg', 50, 1) // Yes power else if(icon_keyboard) add_overlay(icon_keyboard) set_light(light_range_on, light_power_on) + playsound(src, 'sound/machines/terminal_on.ogg', 50, 1) // Broken if(stat & BROKEN) diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 077c12c451f..1af31afe80d 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -8,7 +8,7 @@ idle_power_usage = 250 active_power_usage = 500 circuit = /obj/item/weapon/circuitboard/crew - var/datum/nano_module/program/crew_monitor/crew_monitor + var/datum/tgui_module/crew_monitor/crew_monitor /obj/machinery/computer/crew/New() crew_monitor = new(src) @@ -20,16 +20,16 @@ ..() /obj/machinery/computer/crew/attack_ai(mob/user) - ui_interact(user) + attack_hand(user) /obj/machinery/computer/crew/attack_hand(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - crew_monitor.ui_interact(user, ui_key, ui, force_open) +/obj/machinery/computer/crew/tgui_interact(mob/user, datum/tgui/ui = null) + crew_monitor.tgui_interact(user, ui) /obj/machinery/computer/crew/interact(mob/user) - crew_monitor.ui_interact(user) + crew_monitor.tgui_interact(user) diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 79257147a0a..f775bed4c36 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -1,4 +1,11 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 +#define MED_DATA_R_LIST 2 // Record list +#define MED_DATA_MAINT 3 // Records maintenance +#define MED_DATA_RECORD 4 // Record +#define MED_DATA_V_DATA 5 // Virus database +#define MED_DATA_MEDBOT 6 // Medbot monitor + +#define FIELD(N, V, E) list(field = N, value = V, edit = E) +#define MED_FIELD(N, V, E, LB) list(field = N, value = V, edit = E, line_break = LB) /obj/machinery/computer/med_data//TODO:SANITY name = "medical records console" @@ -14,9 +21,50 @@ var/screen = null var/datum/data/record/active1 = null var/datum/data/record/active2 = null - var/a_id = null - var/temp = null + var/list/temp = null var/printing = null + // The below are used to make modal generation more convenient + var/static/list/field_edit_questions + var/static/list/field_edit_choices + + +/obj/machinery/computer/med_data/Initialize() + ..() + field_edit_questions = list( + // General + "sex" = "Please select new sex:", + "age" = "Please input new age:", + "fingerprint" = "Please input new fingerprint hash:", + "p_stat" = "Please select new physical status:", + "m_stat" = "Please select new mental status:", + // Medical + "id_gender" = "Please select new gender identity:", + "blood_type" = "Please select new blood type:", + "b_dna" = "Please input new DNA:", + "mi_dis" = "Please input new minor disabilities:", + "mi_dis_d" = "Please summarize minor disabilities:", + "ma_dis" = "Please input new major disabilities:", + "ma_dis_d" = "Please summarize major disabilities:", + "alg" = "Please input new allergies:", + "alg_d" = "Please summarize allergies:", + "cdi" = "Please input new current diseases:", + "cdi_d" = "Please summarize current diseases:", + "notes" = "Please input new important notes:", + ) + field_edit_choices = list( + // General + "sex" = all_genders_text_list, + "p_stat" = list("*Deceased*", "*SSD*", "Active", "Physically Unfit", "Disabled"), + "m_stat" = list("*Insane*", "*Unstable*", "*Watch*", "Stable"), + // Medical + "id_gender" = all_genders_text_list, + "blood_type" = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"), + ) + +/obj/machinery/computer/med_data/Destroy() + active1 = null + active2 = null + return ..() /obj/machinery/computer/med_data/verb/eject_id() set category = "Object" @@ -40,396 +88,216 @@ O.loc = src scan = O to_chat(user, "You insert \the [O].") + tgui_interact(user) else ..() /obj/machinery/computer/med_data/attack_ai(user as mob) - return src.attack_hand(user) + return attack_hand(user) /obj/machinery/computer/med_data/attack_hand(mob/user as mob) if(..()) return - var/dat = list() - if (src.temp) - dat += text("[src.temp]

Clear Screen") - else - dat += text("Confirm Identity: []
", src, (src.scan ? text("[]", src.scan.name) : "----------")) - if (src.authenticated) - switch(src.screen) - if(1.0) - dat += {" -Search Records -
List Records -
-
Virus Database -
Medbot Tracking -
-
Record Maintenance -
{Log Out}
-"} - if(2.0) - dat += "Record List:
" - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general)) - dat += text("[]: []
", src, R, R.fields["id"], R.fields["name"]) - //Foreach goto(132) - dat += text("
Back", src) - if(3.0) - dat += text("Records Maintenance
\nBackup To Disk
\nUpload From disk
\nDelete All Records
\n
\nBack", src, src, src, src) - if(4.0) - var/icon/front = active1.fields["photo_front"] - var/icon/side = active1.fields["photo_side"] - user << browse_rsc(front, "front.png") - user << browse_rsc(side, "side.png") - dat += "
Medical Record

" - if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) - dat += "
Name: [active1.fields["name"]] \ - ID: [active1.fields["id"]]
\n \ - Entity Classification: [active1.fields["brain_type"]]
\n \ - Sex: [active1.fields["sex"]]
\n" - if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) - dat += "Gender identity: [active2.fields["id_gender"]]
" + add_fingerprint(user) + tgui_interact(user) + + +/obj/machinery/computer/med_data/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MedicalRecords", "Medical Records") // 800, 380 + ui.open() + ui.set_autoupdate(FALSE) + + +/obj/machinery/computer/med_data/tgui_data(mob/user) + var/data[0] + data["temp"] = temp + data["scan"] = scan ? scan.name : null + data["authenticated"] = authenticated + data["rank"] = rank + data["screen"] = screen + data["printing"] = printing + data["isAI"] = isAI(user) + data["isRobot"] = isrobot(user) + if(authenticated) + switch(screen) + if(MED_DATA_R_LIST) + if(!isnull(data_core.general)) + var/list/records = list() + data["records"] = records + for(var/datum/data/record/R in sortRecord(data_core.general)) + records[++records.len] = list("ref" = "\ref[R]", "id" = R.fields["id"], "name" = R.fields["name"]) + if(MED_DATA_RECORD) + var/list/general = list() + data["general"] = general + if(istype(active1, /datum/data/record) && data_core.general.Find(active1)) + var/list/fields = list() + general["fields"] = fields + fields[++fields.len] = FIELD("Name", active1.fields["name"], null) + fields[++fields.len] = FIELD("ID", active1.fields["id"], null) + fields[++fields.len] = FIELD("Sex", active1.fields["sex"], "sex") + fields[++fields.len] = FIELD("Age", active1.fields["age"], "age") + fields[++fields.len] = FIELD("Fingerprint", active1.fields["fingerprint"], "fingerprint") + fields[++fields.len] = FIELD("Physical Status", active1.fields["p_stat"], "p_stat") + fields[++fields.len] = FIELD("Mental Status", active1.fields["m_stat"], "m_stat") + var/list/photos = list() + general["photos"] = photos + photos[++photos.len] = active1.fields["photo-south"] + photos[++photos.len] = active1.fields["photo-west"] + general["has_photos"] = (active1.fields["photo-south"] || active1.fields["photo-west"] ? 1 : 0) + general["empty"] = 0 + else + general["empty"] = 1 + + var/list/medical = list() + data["medical"] = medical + if(istype(active2, /datum/data/record) && data_core.medical.Find(active2)) + var/list/fields = list() + medical["fields"] = fields + fields[++fields.len] = MED_FIELD("Gender identity", active2.fields["id_gender"], "id_gender", TRUE) + fields[++fields.len] = MED_FIELD("Blood Type", active2.fields["b_type"], "blood_type", FALSE) + fields[++fields.len] = MED_FIELD("DNA", active2.fields["b_dna"], "b_dna", TRUE) + fields[++fields.len] = MED_FIELD("Brain Type", active2.fields["brain_type"], "brain_type", TRUE) + fields[++fields.len] = MED_FIELD("Important Notes", active2.fields["notes"], "notes", TRUE) + if(!active2.fields["comments"] || !islist(active2.fields["comments"])) + active2.fields["comments"] = list() + medical["comments"] = active2.fields["comments"] + medical["empty"] = 0 + else + medical["empty"] = 1 + if(MED_DATA_V_DATA) + data["virus"] = list() + for(var/ID in virusDB) + var/datum/data/record/v = virusDB[ID] + data["virus"] += list(list("name" = v.fields["name"], "D" = "\ref[v]")) + if(MED_DATA_MEDBOT) + data["medbots"] = list() + for(var/mob/living/bot/medbot/M in mob_list) + if(M.z != z) + continue + var/turf/T = get_turf(M) + if(T) + var/medbot = list() + var/area/A = get_area(T) + medbot["name"] = M.name + medbot["area"] = A.name + medbot["x"] = T.x + medbot["y"] = T.y + medbot["on"] = M.on + if(!isnull(M.reagent_glass) && M.use_beaker) + medbot["use_beaker"] = 1 + medbot["total_volume"] = M.reagent_glass.reagents.total_volume + medbot["maximum_volume"] = M.reagent_glass.reagents.maximum_volume else - dat += "Gender identity: Unknown
" - dat += "Age: [active1.fields["age"]]
\n \ - Fingerprint: [active1.fields["fingerprint"]]
\n \ - Physical Status: [active1.fields["p_stat"]]
\n \ - Mental Status: [active1.fields["m_stat"]]
\ - Photo:
" - else - dat += "General Record Lost!
" - if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) - dat += text("
\n
Medical Data

\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src, src.active2.fields["b_type"], src, src.active2.fields["b_dna"], src, src.active2.fields["mi_dis"], src, src.active2.fields["mi_dis_d"], src, src.active2.fields["ma_dis"], src, src.active2.fields["ma_dis_d"], src, src.active2.fields["alg"], src, src.active2.fields["alg_d"], src, src.active2.fields["cdi"], src, src.active2.fields["cdi_d"], src, decode(src.active2.fields["notes"])) - var/counter = 1 - while(src.active2.fields[text("com_[]", counter)]) - dat += text("[]
Delete Entry

", src.active2.fields[text("com_[]", counter)], src, counter) - counter++ - dat += text("Add Entry

", src) - dat += text("Delete Record (Medical Only)

", src) - else - dat += "Medical Record Lost!
" - dat += text("New Record

") - dat += text("\nPrint Record
\nBack
", src, src) - if(5.0) - dat += "
Virus Database
" - for (var/ID in virusDB) - var/datum/data/record/v = virusDB[ID] - dat += "
[v.fields["name"]]" + medbot["use_beaker"] = 0 + data["medbots"] += list(medbot) - dat += "
Back" - if(6.0) - dat += "
Medical Robot Monitor
" - dat += "Back" - dat += "
Medical Robots:" - var/bdat = null - for(var/mob/living/bot/medbot/M in mob_list) + data["modal"] = tgui_modal_data(src) + return data - if(M.z != src.z) continue //only find medibots on the same z-level as the computer - var/turf/bl = get_turf(M) - if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up - bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"]
" - if((!isnull(M.reagent_glass)) && M.use_beaker) - bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\]
" - else - bdat += "Using Internal Synthesizer.
" - if(!bdat) - dat += "
None detected
" - else - dat += "
[bdat]" - - else - else - dat += text("{Log In}", src) - dat = jointext(dat,null) - user << browse(text("Medical Records[]", dat), "window=med_rec") - onclose(user, "med_rec") - return - -/obj/machinery/computer/med_data/Topic(href, href_list) +/obj/machinery/computer/med_data/tgui_act(action, params) if(..()) - return 1 + return TRUE - if (!( data_core.general.Find(src.active1) )) - src.active1 = null + if(!data_core.general.Find(active1)) + active1 = null + if(!data_core.medical.Find(active2)) + active2 = null - if (!( data_core.medical.Find(src.active2) )) - src.active2 = null - - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) - - if (href_list["temp"]) - src.temp = null - - if (href_list["scan"]) - if (src.scan) - - if(ishuman(usr)) - scan.loc = usr.loc - - if(!usr.get_active_hand()) - usr.put_in_hands(scan) - - scan = null - - else - src.scan.loc = src.loc - src.scan = null + . = TRUE + if(tgui_act_modal(action, params)) + return + switch(action) + if("cleartemp") + temp = null + if("scan") + if(scan) + scan.forceMove(loc) + if(ishuman(usr) && !usr.get_active_hand()) + usr.put_in_hands(scan) + scan = null else var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id)) + if(istype(I, /obj/item/weapon/card/id)) usr.drop_item() - I.loc = src - src.scan = I - - else if (href_list["logout"]) - src.authenticated = null - src.screen = null - src.active1 = null - src.active2 = null - - else if (href_list["login"]) - - if (istype(usr, /mob/living/silicon/ai)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - src.rank = "AI" - src.screen = 1 - - else if (istype(usr, /mob/living/silicon/robot)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name + I.forceMove(src) + scan = I + if("login") + var/login_type = text2num(params["login_type"]) + if(login_type == LOGIN_TYPE_NORMAL && istype(scan)) + if(check_access(scan)) + authenticated = scan.registered_name + rank = scan.assignment + else if(login_type == LOGIN_TYPE_AI && isAI(usr)) + authenticated = usr.name + rank = "AI" + else if(login_type == LOGIN_TYPE_ROBOT && isrobot(usr)) + authenticated = usr.name var/mob/living/silicon/robot/R = usr - src.rank = "[R.modtype] [R.braintype]" - src.screen = 1 + rank = "[R.modtype] [R.braintype]" + if(authenticated) + active1 = null + active2 = null + screen = MED_DATA_R_LIST + else + . = FALSE - else if (istype(src.scan, /obj/item/weapon/card/id)) - src.active1 = null - src.active2 = null + if(.) + return - if (src.check_access(src.scan)) - src.authenticated = src.scan.registered_name - src.rank = src.scan.assignment - src.screen = 1 - - if (src.authenticated) - - if(href_list["screen"]) - src.screen = text2num(href_list["screen"]) - if(src.screen < 1) - src.screen = 1 - - src.active1 = null - src.active2 = null - - if(href_list["vir"]) - var/datum/data/record/v = locate(href_list["vir"]) - src.temp = "
GNAv2 based virus lifeform V-[v.fields["id"]]
" - src.temp += "
Name: [v.fields["name"]]" - src.temp += "
Antigen: [v.fields["antigen"]]" - src.temp += "
Spread: [v.fields["spread type"]] " - src.temp += "
Details:
[v.fields["description"]]" - - if (href_list["del_all"]) - src.temp = text("Are you sure you wish to delete all records?
\n\tYes
\n\tNo
", src, src) - - if (href_list["del_all2"]) + if(authenticated) + . = TRUE + switch(action) + if("logout") + if(scan) + scan.forceMove(loc) + if(ishuman(usr) && !usr.get_active_hand()) + usr.put_in_hands(scan) + scan = null + authenticated = null + screen = null + active1 = null + active2 = null + if("screen") + screen = clamp(text2num(params["screen"]) || 0, MED_DATA_R_LIST, MED_DATA_MEDBOT) + active1 = null + active2 = null + if("vir") + var/datum/data/record/v = locate(params["vir"]) + if(!istype(v)) + return FALSE + tgui_modal_message(src, "virus", "", null, v.fields["tgui_description"]) + if("del_all") for(var/datum/data/record/R in data_core.medical) - //R = null qdel(R) - //Foreach goto(494) - src.temp = "All records deleted." - - if (href_list["field"]) - var/a1 = src.active1 - var/a2 = src.active2 - switch(href_list["field"]) - if("fingerprint") - if (istype(src.active1, /datum/data/record)) - var/t1 = sanitize(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) - return - src.active1.fields["fingerprint"] = t1 - if("sex") - if (istype(src.active1, /datum/data/record)) - src.active1.fields["sex"] = next_in_list(src.active1.fields["sex"], all_genders_text_list) - if("id_gender") - if (istype(src.active2, /datum/data/record)) - src.active2.fields["id_gender"] = next_in_list(src.active2.fields["id_gender"], all_genders_text_list) - if("age") - if (istype(src.active1, /datum/data/record)) - var/t1 = input("Please input age:", "Med. records", src.active1.fields["age"], null) as num - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) - return - src.active1.fields["age"] = t1 - if("mi_dis") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - src.active2.fields["mi_dis"] = t1 - if("mi_dis_d") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - src.active2.fields["mi_dis_d"] = t1 - if("ma_dis") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - src.active2.fields["ma_dis"] = t1 - if("ma_dis_d") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - src.active2.fields["ma_dis_d"] = t1 - if("alg") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - src.active2.fields["alg"] = t1 - if("alg_d") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - src.active2.fields["alg_d"] = t1 - if("cdi") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - src.active2.fields["cdi"] = t1 - if("cdi_d") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - src.active2.fields["cdi_d"] = t1 - if("notes") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message, extra = 0, max_length = MAX_RECORD_LENGTH) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - src.active2.fields["notes"] = t1 - if("p_stat") - if (istype(src.active1, /datum/data/record)) - src.temp = text("Physical Condition:
\n\t*Deceased*
\n\t*SSD*
\n\tActive
\n\tPhysically Unfit
\n\tDisabled
", src, src, src, src, src) - if("m_stat") - if (istype(src.active1, /datum/data/record)) - src.temp = text("Mental Condition:
\n\t*Insane*
\n\t*Unstable*
\n\t*Watch*
\n\tStable
", src, src, src, src) - if("b_type") - if (istype(src.active2, /datum/data/record)) - src.temp = text("Blood Type:
\n\tA- A+
\n\tB- B+
\n\tAB- AB+
\n\tO- O+
", src, src, src, src, src, src, src, src) - if("b_dna") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - src.active2.fields["b_dna"] = t1 - if("vir_name") - var/datum/data/record/v = locate(href_list["edit_vir"]) - if (v) - var/t1 = sanitize(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) - return - v.fields["name"] = t1 - if("vir_desc") - var/datum/data/record/v = locate(href_list["edit_vir"]) - if (v) - var/t1 = sanitize(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) - return - v.fields["description"] = t1 - else - - if (href_list["p_stat"]) - if (src.active1) - switch(href_list["p_stat"]) - if("deceased") - src.active1.fields["p_stat"] = "*Deceased*" - if("ssd") - src.active1.fields["p_stat"] = "*SSD*" - if("active") - src.active1.fields["p_stat"] = "Active" - if("unfit") - src.active1.fields["p_stat"] = "Physically Unfit" - if("disabled") - src.active1.fields["p_stat"] = "Disabled" - if(PDA_Manifest.len) - PDA_Manifest.Cut() - - if (href_list["m_stat"]) - if (src.active1) - switch(href_list["m_stat"]) - if("insane") - src.active1.fields["m_stat"] = "*Insane*" - if("unstable") - src.active1.fields["m_stat"] = "*Unstable*" - if("watch") - src.active1.fields["m_stat"] = "*Watch*" - if("stable") - src.active1.fields["m_stat"] = "Stable" - - - if (href_list["b_type"]) - if (src.active2) - switch(href_list["b_type"]) - if("an") - src.active2.fields["b_type"] = "A-" - if("bn") - src.active2.fields["b_type"] = "B-" - if("abn") - src.active2.fields["b_type"] = "AB-" - if("on") - src.active2.fields["b_type"] = "O-" - if("ap") - src.active2.fields["b_type"] = "A+" - if("bp") - src.active2.fields["b_type"] = "B+" - if("abp") - src.active2.fields["b_type"] = "AB+" - if("op") - src.active2.fields["b_type"] = "O+" - - - if (href_list["del_r"]) - if (src.active2) - src.temp = text("Are you sure you wish to delete the record (Medical Portion Only)?
\n\tYes
\n\tNo
", src, src) - - if (href_list["del_r2"]) - if (src.active2) - //src.active2 = null - qdel(src.active2) - - if (href_list["d_rec"]) - var/datum/data/record/R = locate(href_list["d_rec"]) - var/datum/data/record/M = locate(href_list["d_rec"]) - if (!( data_core.general.Find(R) )) - src.temp = "Record Not Found!" + set_temp("All medical records deleted.") + if("del_r") + if(active2) + set_temp("Medical record deleted.") + qdel(active2) + if("d_rec") + var/datum/data/record/general_record = locate(params["d_rec"] || "") + if(!data_core.general.Find(general_record)) + set_temp("Record not found.", "danger") return - for(var/datum/data/record/E in data_core.medical) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - else - //Foreach continue //goto(2540) - src.active1 = R - src.active2 = M - src.screen = 4 - if (href_list["new"]) - if ((istype(src.active1, /datum/data/record) && !( istype(src.active2, /datum/data/record) ))) - var/datum/data/record/R = new /datum/data/record( ) - R.fields["name"] = src.active1.fields["name"] - R.fields["id"] = src.active1.fields["id"] - R.name = text("Medical Record #[]", R.fields["id"]) + var/datum/data/record/medical_record + for(var/datum/data/record/M in data_core.medical) + if(M.fields["name"] == general_record.fields["name"] && M.fields["id"] == general_record.fields["id"]) + medical_record = M + break + + active1 = general_record + active2 = medical_record + screen = MED_DATA_RECORD + if("new") + if(istype(active1, /datum/data/record) && !istype(active2, /datum/data/record)) + var/datum/data/record/R = new /datum/data/record() + R.fields["name"] = active1.fields["name"] + R.fields["id"] = active1.fields["id"] + R.name = "Medical Record #[R.fields["id"]]" R.fields["b_type"] = "Unknown" R.fields["b_dna"] = "Unknown" R.fields["mi_dis"] = "None" @@ -442,79 +310,157 @@ R.fields["cdi_d"] = "No diseases have been diagnosed at the moment." R.fields["notes"] = "No notes." data_core.medical += R - src.active2 = R - src.screen = 4 - - if (href_list["add_c"]) - if (!( istype(src.active2, /datum/data/record) )) + active2 = R + screen = MED_DATA_RECORD + set_temp("Medical record created.", "success") + if("del_c") + var/index = text2num(params["del_c"] || "") + if(!index || !istype(active2, /datum/data/record)) return - var/a2 = src.active2 - var/t1 = sanitize(input("Add Comment:", "Med. records", null, null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) - return - var/counter = 1 - while(src.active2.fields[text("com_[]", counter)]) - counter++ - src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [stationtime2text()], [game_year]
[t1]") - if (href_list["del_c"]) - if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])])) - src.active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" - - if (href_list["search"]) - var/t1 = input("Search String: (Name, DNA, or ID)", "Med. records", null, null) as text - if ((!( t1 ) || usr.stat || !( src.authenticated ) || usr.restrained() || ((!in_range(src, usr)) && (!istype(usr, /mob/living/silicon))))) + var/list/comments = active2.fields["comments"] + index = clamp(index, 1, length(comments)) + if(comments[index]) + comments.Cut(index, index + 1) + if("search") + active1 = null + active2 = null + var/t1 = lowertext(params["t1"] || "") + if(!length(t1)) return - src.active1 = null - src.active2 = null - t1 = lowertext(t1) + for(var/datum/data/record/R in data_core.medical) - if ((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"]))) - src.active2 = R + if(t1 == lowertext(R.fields["name"]) || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"])) + active2 = R + break + if(!active2) + set_temp("Medical record not found. You must enter the person's exact name, ID or DNA.", "danger") + return + for(var/datum/data/record/E in data_core.general) + if(E.fields["name"] == active2.fields["name"] && E.fields["id"] == active2.fields["id"]) + active1 = E + break + screen = MED_DATA_RECORD + if("print_p") + if(!printing) + printing = TRUE + // playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, TRUE) + SStgui.update_uis(src) + addtimer(CALLBACK(src, .proc/print_finish), 5 SECONDS) + else + return FALSE + +/** + * Called in tgui_act() to process modal actions + * + * Arguments: + * * action - The action passed by tgui + * * params - The params passed by tgui + */ +/obj/machinery/computer/med_data/proc/tgui_act_modal(action, params) + . = TRUE + var/id = params["id"] // The modal's ID + var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"] + switch(tgui_modal_act(src, action, params)) + if(TGUI_MODAL_OPEN) + switch(id) + if("edit") + var/field = arguments["field"] + if(!length(field) || !field_edit_questions[field]) + return + var/question = field_edit_questions[field] + var/choices = field_edit_choices[field] + if(length(choices)) + tgui_modal_choice(src, id, question, arguments = arguments, value = arguments["value"], choices = choices) else - //Foreach continue //goto(3229) - if (!( src.active2 )) - src.temp = text("Could not locate record [].", t1) + tgui_modal_input(src, id, question, arguments = arguments, value = arguments["value"]) + if("add_c") + tgui_modal_input(src, id, "Please enter your message:") else - for(var/datum/data/record/E in data_core.general) - if ((E.fields["name"] == src.active2.fields["name"] || E.fields["id"] == src.active2.fields["id"])) - src.active1 = E - else - //Foreach continue //goto(3334) - src.screen = 4 + return FALSE + if(TGUI_MODAL_ANSWER) + var/answer = params["answer"] + switch(id) + if("edit") + var/field = arguments["field"] + if(!length(field) || !field_edit_questions[field]) + return + var/list/choices = field_edit_choices[field] + if(length(choices) && !(answer in choices)) + return - if (href_list["print_p"]) - if (!( src.printing )) - src.printing = 1 - var/datum/data/record/record1 = null - var/datum/data/record/record2 = null - if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) - record1 = active1 - if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) - record2 = active2 - sleep(50) - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( src.loc ) - P.info = "
Medical Record

" - if (record1) - P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"]) - P.name = text("Medical Record ([])", record1.fields["name"]) - else - P.info += "General Record Lost!
" - P.name = "Medical Record" - if (record2) - P.info += text("
\n
Medical Data

\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", record2.fields["b_type"], record2.fields["b_dna"], record2.fields["mi_dis"], record2.fields["mi_dis_d"], record2.fields["ma_dis"], record2.fields["ma_dis_d"], record2.fields["alg"], record2.fields["alg_d"], record2.fields["cdi"], record2.fields["cdi_d"], decode(record2.fields["notes"])) - var/counter = 1 - while(record2.fields[text("com_[]", counter)]) - P.info += text("[]
", record2.fields[text("com_[]", counter)]) - counter++ - else - P.info += "Medical Record Lost!
" - P.info += "" - src.printing = null + if(field == "age") + answer = text2num(answer) - src.add_fingerprint(usr) - src.updateUsrDialog() - return + if(istype(active2) && (field in active2.fields)) + active2.fields[field] = answer + else if(istype(active1) && (field in active1.fields)) + active1.fields[field] = answer + if("add_c") + if(!length(answer) || !istype(active2) || !length(authenticated)) + return + active2.fields["comments"] += list(list( + header = "Made by [authenticated] ([rank]) at [worldtime2stationtime(world.time)]", + text = answer + )) + else + return FALSE + else + return FALSE + + +/** + * Called when the print timer finishes + */ +/obj/machinery/computer/med_data/proc/print_finish() + var/obj/item/weapon/paper/P = new(loc) + P.info = "
Medical Record

" + if(istype(active1, /datum/data/record) && data_core.general.Find(active1)) + P.info += {"Name: [active1.fields["name"]] ID: [active1.fields["id"]] +
\nSex: [active1.fields["sex"]] +
\nAge: [active1.fields["age"]] +
\nFingerprint: [active1.fields["fingerprint"]] +
\nPhysical Status: [active1.fields["p_stat"]] +
\nMental Status: [active1.fields["m_stat"]]
"} + else + P.info += "General Record Lost!
" + if(istype(active2, /datum/data/record) && data_core.medical.Find(active2)) + P.info += {"
\n
Medical Data
+
\nGender Identity: [active2.fields["id_gender"]] +
\nBlood Type: [active2.fields["b_type"]] +
\nDNA: [active2.fields["b_dna"]]
\n +
\nMinor Disabilities: [active2.fields["mi_dis"]] +
\nDetails: [active2.fields["mi_dis_d"]]
\n +
\nMajor Disabilities: [active2.fields["ma_dis"]] +
\nDetails: [active2.fields["ma_dis_d"]]
\n +
\nAllergies: [active2.fields["alg"]] +
\nDetails: [active2.fields["alg_d"]]
\n +
\nCurrent Diseases: [active2.fields["cdi"]] (per disease info placed in log/comment section) +
\nDetails: [active2.fields["cdi_d"]]
\n +
\nImportant Notes: +
\n\t[active2.fields["notes"]]
\n +
\n +
Comments/Log

"} + for(var/c in active2.fields["comments"]) + P.info += "[c]
" + else + P.info += "Medical Record Lost!
" + P.info += "" + P.name = "paper - 'Medical Record: [active1.fields["name"]]'" + printing = FALSE + SStgui.update_uis(src) + +/** + * Sets a temporary message to display to the user + * + * Arguments: + * * text - Text to display, null/empty to clear the message from the UI + * * style - The style of the message: (color name), info, success, warning, danger, virus + */ +/obj/machinery/computer/med_data/proc/set_temp(text = "", style = "info", update_now = FALSE) + temp = list(text = text, style = style) + if(update_now) + SStgui.update_uis(src) /obj/machinery/computer/med_data/emp_act(severity) if(stat & (BROKEN|NOPOWER)) @@ -555,3 +501,6 @@ icon_screen = "medlaptop" circuit = /obj/item/weapon/circuitboard/med_data/laptop density = 0 + +#undef FIELD +#undef MED_FIELD diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 2416a0cd35a..1dc0709ed35 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -12,23 +12,21 @@ //Sparks effect - For emag var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread //Messages - Saves me time if I want to change something. - var/noserver = "ALERT: No server detected." - var/incorrectkey = "ALERT: Incorrect decryption key!" - var/defaultmsg = "Welcome. Please select an option." - var/rebootmsg = "%$&(£: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!" + var/noserver = list("text" = "ALERT: No server detected.", "style" = "alert") + var/incorrectkey = list("text" = "ALERT: Incorrect decryption key!", "style" = "warning") + var/defaultmsg = list("text" = "Welcome. Please select an option.", "style" = "notice") + var/rebootmsg = list("text" = "%$&(£: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!", "style" = "warning") //Computer properties - var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message var/hacking = 0 // Is it being hacked into by the AI/Cyborg var/emag = 0 // When it is emagged. - var/message = "System bootup complete. Please select an option." // The message that shows on the main menu. var/auth = 0 // Are they authenticated? var/optioncount = 8 - // Custom Message Properties + // Custom temp Properties var/customsender = "System Administrator" var/obj/item/device/pda/customrecepient = null var/customjob = "Admin" var/custommessage = "This is a test, please ignore." - + var/list/temp = null /obj/machinery/computer/message_monitor/attackby(obj/item/weapon/O as obj, mob/living/user as mob) if(stat & (NOPOWER|BROKEN)) @@ -48,17 +46,16 @@ // Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online. // It'll take more time if there's more characters in the password.. if(!emag && operable()) - if(!isnull(src.linkedServer)) + if(!isnull(linkedServer)) emag = 1 - screen = 2 spark_system.set_up(5, 0, src) - src.spark_system.start() + spark_system.start() var/obj/item/weapon/paper/monitorkey/MK = new/obj/item/weapon/paper/monitorkey - MK.loc = src.loc + MK.loc = loc // Will help make emagging the console not so easy to get away with. MK.info += "

£%@%(*$%&(£&?*(%&£/{}" - spawn(100*length(src.linkedServer.decryptkey)) UnmagConsole() - message = rebootmsg + spawn(100*length(linkedServer.decryptkey)) UnmagConsole() + temp = rebootmsg update_icon() return 1 else @@ -78,201 +75,92 @@ linkedServer = message_servers[1] return ..() +/obj/machinery/computer/message_monitor/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MessageMonitor", name) + ui.open() + +/obj/machinery/computer/message_monitor/tgui_data(mob/user) + var/list/data = list() + + data["customsender"] = customsender + data["customrecepient"] = "[customrecepient]" + data["customjob"] = customjob + data["custommessage"] = custommessage + + data["temp"] = temp + data["hacking"] = !!hacking + data["emag"] = !!emag + data["auth"] = !!auth + data["linkedServer"] = list() + if(linkedServer && auth) + data["linkedServer"]["active"] = linkedServer.active + data["linkedServer"]["broke"] = linkedServer.stat & (NOPOWER|BROKEN) + + data["linkedServer"]["pda_msgs"] = list() + for(var/datum/data_pda_msg/pda in linkedServer.pda_msgs) + data["linkedServer"]["pda_msgs"].Add(list(list( + "ref" = "\ref[pda]", + "sender" = pda.sender, + "recipient" = pda.recipient, + "message" = pda.message, + ))) + + data["linkedServer"]["rc_msgs"] = list() + for(var/datum/data_rc_msg/rc in linkedServer.rc_msgs) + data["linkedServer"]["rc_msgs"].Add(list(list( + "ref" = "\ref[rc]", + "sender" = rc.send_dpt, + "recipient" = rc.rec_dpt, + "message" = rc.message, + "stamp" = rc.stamp, + "id_auth" = rc.id_auth, + "priority" = rc.priority, + ))) + + var/spamIndex = 0 + data["linkedServer"]["spamFilter"] = list() + for(var/token in linkedServer.spamfilter) + spamIndex++ + data["linkedServer"]["spamFilter"].Add(list(list( + "index" = spamIndex, + "token" = token, + ))) + + //Get out list of viable PDAs + var/list/obj/item/device/pda/sendPDAs = list() + for(var/obj/item/device/pda/P in PDAs) + if(!P.owner || P.toff || P.hidden) + continue + sendPDAs["[P.name]"] = "\ref[P]" + data["possibleRecipients"] = sendPDAs + + data["isMalfAI"] = ((istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot)) && (user.mind.special_role && user.mind.original == user)) + + return data + /obj/machinery/computer/message_monitor/attack_hand(var/mob/living/user as mob) if(stat & (NOPOWER|BROKEN)) return if(!istype(user)) return - //If the computer is being hacked or is emagged, display the reboot message. - if(hacking || emag) - message = rebootmsg - var/dat = "Message Monitor Console" - dat += "

Message Monitor Console


" - dat += "

" - - if(auth) - dat += "

\[Authenticated\] /" - dat += " Server Power: [src.linkedServer && src.linkedServer.active ? "\[On\]":"\[Off\]"]

" - else - dat += "

\[Unauthenticated\] /" - dat += " Server Power: [src.linkedServer && src.linkedServer.active ? "\[On\]":"\[Off\]"]

" - - if(hacking || emag) - screen = 2 - else if(!auth || !linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) - if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) message = noserver - screen = 0 - - switch(screen) - //Main menu - if(0) - // = TAB - var/i = 0 - dat += "
[++i]. Link To A Server
" - if(auth) - if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) - dat += "
ERROR: Server not found!
" - else - dat += "
[++i]. View Message Logs
" - dat += "
[++i]. View Request Console Logs
" - dat += "
[++i]. Clear Message Logs
" - dat += "
[++i]. Clear Request Console Logs
" - dat += "
[++i]. Set Custom Key
" - dat += "
[++i]. Send Admin Message
" - dat += "
[++i]. Modify Spam Filter
" - else - for(var/n = ++i; n <= optioncount; n++) - dat += "
[n]. ---------------
" - if((istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot)) && (user.mind.special_role && user.mind.original == user)) - //Malf/Traitor AIs can bruteforce into the system to gain the Key. - dat += "
*&@#. Bruteforce Key
" - else - dat += "
" - - //Bottom message - if(!auth) - dat += "

Please authenticate with the server in order to show additional options." - else - dat += "

Reg, #514 forbids sending messages to a Head of Staff containing Erotic Rendering Properties." - - //Message Logs - if(1) - var/index = 0 - //var/recipient = "Unspecified" //name of the person - //var/sender = "Unspecified" //name of the sender - //var/message = "Blank" //transferred message - dat += "
Back - Refresh

" - dat += "" - for(var/datum/data_pda_msg/pda in src.linkedServer.pda_msgs) - index++ - if(index > 3000) - break - // Del - Sender - Recepient - Message - // X - Al Green - Your Mom - WHAT UP!? - dat += "" - dat += "
XSenderRecipientMessage
X
[pda.sender][pda.recipient][pda.message]
" - //Hacking screen. - if(2) - if(istype(user, /mob/living/silicon/ai) || istype(user, /mob/living/silicon/robot)) - dat += "Brute-forcing for server key.
It will take 20 seconds for every character that the password has." - dat += "In the meantime, this console can reveal your true intentions if you let someone access it. Make sure no humans enter the room during that time." - else - //It's the same message as the one above but in binary. Because robots understand binary and humans don't... well I thought it was clever. - dat += {"01000010011100100111010101110100011001010010110
- 10110011001101111011100100110001101101001011011100110011
- 10010000001100110011011110111001000100000011100110110010
- 10111001001110110011001010111001000100000011010110110010
- 10111100100101110001000000100100101110100001000000111011
- 10110100101101100011011000010000001110100011000010110101
- 10110010100100000001100100011000000100000011100110110010
- 10110001101101111011011100110010001110011001000000110011
- 00110111101110010001000000110010101110110011001010111001
- 00111100100100000011000110110100001100001011100100110000
- 10110001101110100011001010111001000100000011101000110100
- 00110000101110100001000000111010001101000011001010010000
- 00111000001100001011100110111001101110111011011110111001
- 00110010000100000011010000110000101110011001011100010000
- 00100100101101110001000000111010001101000011001010010000
- 00110110101100101011000010110111001110100011010010110110
- 10110010100101100001000000111010001101000011010010111001
- 10010000001100011011011110110111001110011011011110110110
- 00110010100100000011000110110000101101110001000000111001
- 00110010101110110011001010110000101101100001000000111100
- 10110111101110101011100100010000001110100011100100111010
- 10110010100100000011010010110111001110100011001010110111
- 00111010001101001011011110110111001110011001000000110100
- 10110011000100000011110010110111101110101001000000110110
- 00110010101110100001000000111001101101111011011010110010
- 10110111101101110011001010010000001100001011000110110001
- 10110010101110011011100110010000001101001011101000010111
- 00010000001001101011000010110101101100101001000000111001
- 10111010101110010011001010010000001101110011011110010000
- 00110100001110101011011010110000101101110011100110010000
- 00110010101101110011101000110010101110010001000000111010
- 00110100001100101001000000111001001101111011011110110110
- 10010000001100100011101010111001001101001011011100110011
- 10010000001110100011010000110000101110100001000000111010
- 001101001011011010110010100101110"} - - //Fake messages - if(3) - dat += "
Back - Reset

" - - dat += {" - - - - "} - //Sender - Sender's Job - Recepient - Message - //Al Green- Your Dad - Your Mom - WHAT UP!? - - dat += {" - - - "} - dat += "
SenderSender's JobRecipientMessage
[customsender][customjob][customrecepient ? customrecepient.owner : "NONE"][custommessage]

Send
" - - //Request Console Logs - if(4) - - var/index = 0 - /* data_rc_msg - X - 5% - var/rec_dpt = "Unspecified" //name of the person - 15% - var/send_dpt = "Unspecified" //name of the sender- 15% - var/message = "Blank" //transferred message - 300px - var/stamp = "Unstamped" - 15% - var/id_auth = "Unauthenticated" - 15% - var/priority = "Normal" - 10% - */ - dat += "
Back - Refresh

" - dat += {" - "} - for(var/datum/data_rc_msg/rc in src.linkedServer.rc_msgs) - index++ - if(index > 3000) - break - // Del - Sender - Recepient - Message - // X - Al Green - Your Mom - WHAT UP!? - dat += {" - "} - dat += "
XSending Dep.Receiving Dep.MessageStampID Auth.Priority.
X
[rc.send_dpt][rc.rec_dpt][rc.message][rc.stamp][rc.id_auth][rc.priority]
" - - //Spam filter modification - if(5) - dat += "
Back - Refresh

" - var/index = 0 - for(var/token in src.linkedServer.spamfilter) - index++ - if(index > 3000) - break - dat += "
[index] \[[token]\]
" - dat += "
" - if (linkedServer.spamfilter.len < linkedServer.spamfilter_limit) - dat += "Add token
" - - - dat += "" - message = defaultmsg - user << browse(dat, "window=message;size=700x700") - onclose(user, "message") - return + tgui_interact(user) /obj/machinery/computer/message_monitor/attack_ai(mob/user as mob) - return src.attack_hand(user) + return attack_hand(user) /obj/machinery/computer/message_monitor/proc/BruteForce(mob/user as mob) if(isnull(linkedServer)) to_chat(user, "Could not complete brute-force: Linked Server Disconnected!") else - var/currentKey = src.linkedServer.decryptkey + var/currentKey = linkedServer.decryptkey to_chat(user, "Brute-force completed! The key is '[currentKey]'.") - src.hacking = 0 + hacking = 0 update_icon() - src.screen = 0 // Return the screen back to normal /obj/machinery/computer/message_monitor/proc/UnmagConsole() - src.emag = 0 + emag = 0 update_icon() /obj/machinery/computer/message_monitor/proc/ResetMessage() @@ -281,227 +169,156 @@ custommessage = "This is a test, please ignore." customjob = "Admin" -/obj/machinery/computer/message_monitor/Topic(href, href_list) +/obj/machinery/computer/message_monitor/tgui_act(action, params) if(..()) - return 1 - if(stat & (NOPOWER|BROKEN)) - return - if(!istype(usr, /mob/living)) - return - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) + return TRUE + + switch(action) + if("cleartemp") + temp = null + . = TRUE //Authenticate - if (href_list["auth"]) - if(auth) - auth = 0 - screen = 0 - else - var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null) - if(dkey && dkey != "") - if(src.linkedServer.decryptkey == dkey) - auth = 1 - else - message = incorrectkey - - //Turn the server on/off. - if (href_list["active"]) - if(auth) linkedServer.active = !linkedServer.active + if("auth") + var/dkey = params["key"] + if(dkey && dkey != "") + if(linkedServer.decryptkey == dkey) + auth = TRUE + else + temp = incorrectkey + . = TRUE + if("deauth") + auth = FALSE + . = TRUE //Find a server - if (href_list["find"]) + if("find") if(message_servers && message_servers.len > 1) - src.linkedServer = input(usr,"Please select a server.", "Select a server.", null) as null|anything in message_servers - message = "NOTICE: Server selected." + linkedServer = input(usr,"Please select a server.", "Select a server.", null) as null|anything in message_servers + set_temp("NOTICE: Server selected.", "alert") else if(message_servers && message_servers.len > 0) linkedServer = message_servers[1] - message = "NOTICE: Only Single Server Detected - Server selected." + set_temp("NOTICE: Only Single Server Detected - Server selected.", "average") else - message = noserver - - //View the logs - KEY REQUIRED - if (href_list["view"]) - if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else - if(auth) - src.screen = 1 - - //Clears the logs - KEY REQUIRED - if (href_list["clear"]) - if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else - if(auth) - src.linkedServer.pda_msgs = list() - message = "NOTICE: Logs cleared." - //Clears the request console logs - KEY REQUIRED - if (href_list["clearr"]) - if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else - if(auth) - src.linkedServer.rc_msgs = list() - message = "NOTICE: Logs cleared." - //Change the password - KEY REQUIRED - if (href_list["pass"]) - if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else - if(auth) - var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null) - if(dkey && dkey != "") - if(src.linkedServer.decryptkey == dkey) - var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):")) - if(length(newkey) <= 3) - message = "NOTICE: Decryption key too short!" - else if(length(newkey) > 16) - message = "NOTICE: Decryption key too long!" - else if(newkey && newkey != "") - src.linkedServer.decryptkey = newkey - message = "NOTICE: Decryption key set." - else - message = incorrectkey - + temp = noserver //Hack the Console to get the password - if (href_list["hack"]) + if("hack") if((istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot)) && (usr.mind.special_role && usr.mind.original == usr)) - src.hacking = 1 - src.screen = 2 + hacking = 1 update_icon() //Time it takes to bruteforce is dependant on the password length. - spawn(100*length(src.linkedServer.decryptkey)) - if(src && src.linkedServer && usr) + spawn(100*length(linkedServer.decryptkey)) + if(src && linkedServer && usr) BruteForce(usr) + + if(!auth) + return + + if(!linkedServer || linkedServer.stat & (NOPOWER|BROKEN)) + temp = noserver + return TRUE + + switch(action) + //Turn the server on/off. + if("active") + linkedServer.active = !linkedServer.active + . = TRUE + //Clears the logs - KEY REQUIRED + if("del_pda") + linkedServer.pda_msgs = list() + set_temp("NOTICE: Logs cleared.", "average") + . = TRUE + //Clears the request console logs - KEY REQUIRED + if("del_rc") + linkedServer.rc_msgs = list() + set_temp("NOTICE: Logs cleared.", "average") + . = TRUE + //Change the password - KEY REQUIRED + if("pass") + var/dkey = trim(input(usr, "Please enter the current decryption key.") as text|null) + if(dkey && dkey != "") + if(linkedServer.decryptkey == dkey) + var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):")) + if(length(newkey) <= 3) + set_temp("NOTICE: Decryption key too short!", "average") + else if(length(newkey) > 16) + set_temp("NOTICE: Decryption key too long!", "average") + else if(newkey && newkey != "") + linkedServer.decryptkey = newkey + set_temp("NOTICE: Decryption key set.", "average") + else + temp = incorrectkey + . = TRUE //Delete the log. - if (href_list["delete"]) - //Are they on the view logs screen? - if(screen == 1) - if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else //if(istype(href_list["delete"], /datum/data_pda_msg)) - src.linkedServer.pda_msgs -= locate(href_list["delete"]) - message = "NOTICE: Log Deleted!" - //Delete the request console log. - if (href_list["deleter"]) - //Are they on the view logs screen? - if(screen == 4) - if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else //if(istype(href_list["delete"], /datum/data_pda_msg)) - src.linkedServer.rc_msgs -= locate(href_list["deleter"]) - message = "NOTICE: Log Deleted!" - //Create a custom message - if (href_list["msg"]) - if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver + if("delete") + if(params["type"] == "pda") + linkedServer.pda_msgs -= locate(params["id"]) else - if(auth) - src.screen = 3 + linkedServer.rc_msgs -= locate(params["id"]) + set_temp("NOTICE: Log Deleted!", "average") + . = TRUE //Fake messaging selection - KEY REQUIRED - if (href_list["select"]) - if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - screen = 0 + if("set_sender") + customsender = sanitize(params["val"]) + . = TRUE + if("set_sender_job") + customjob = sanitize(params["val"]) + . = TRUE + if("set_recipient") + var/ref = params["val"] + var/obj/item/device/pda/P = locate(ref) + if(!istype(P) || !P.owner || P.toff || P.hidden) + return FALSE + customrecepient = P + . = TRUE + if("set_message") + custommessage = sanitize(params["val"]) + . = TRUE + if("send_message") + if(isnull(customsender) || customsender == "") + customsender = "UNKNOWN" + + if(isnull(customrecepient)) + set_temp("NOTICE: No recepient selected!", "average") + return TRUE + + if(isnull(custommessage) || custommessage == "") + set_temp("NOTICE: No message entered!", "average") + return TRUE + + var/obj/item/device/pda/PDARec = null + for(var/obj/item/device/pda/P in PDAs) + if(!P.owner || P.toff || P.hidden) continue + if(P.owner == customsender) + PDARec = P + //Sender isn't faking as someone who exists + if(isnull(PDARec)) + linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]") + customrecepient.new_message(customsender, customsender, customjob, custommessage) + //Sender is faking as someone who exists else - switch(href_list["select"]) + linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]") + customrecepient.tnote.Add(list(list("sent" = 0, "owner" = "[PDARec.owner]", "job" = "[customjob]", "message" = "[custommessage]", "target" ="\ref[PDARec]"))) - //Reset - if("Reset") - ResetMessage() + if(!customrecepient.conversations.Find("\ref[PDARec]")) + customrecepient.conversations.Add("\ref[PDARec]") - //Select Your Name - if("Sender") - customsender = sanitize(input(usr, "Please enter the sender's name.") as text|null) + customrecepient.new_message(PDARec, custommessage) + //Finally.. + ResetMessage() + . = TRUE - //Select Receiver - if("Recepient") - //Get out list of viable PDAs - var/list/obj/item/device/pda/sendPDAs = list() - for(var/obj/item/device/pda/P in PDAs) - if(!P.owner || P.toff || P.hidden) continue - sendPDAs += P - if(PDAs && PDAs.len > 0) - customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortAtom(sendPDAs) - else - customrecepient = null + if("addtoken") + linkedServer.spamfilter += input(usr,"Enter text you want to be filtered out","Token creation") as text|null + . = TRUE - //Enter custom job - if("RecJob") - customjob = sanitize(input(usr, "Please enter the sender's job.") as text|null) + if("deltoken") + var/tokennum = text2num(params["deltoken"]) + linkedServer.spamfilter.Cut(tokennum, tokennum + 1) + . = TRUE - //Enter message - if("Message") - custommessage = input(usr, "Please enter your message.") as text|null - custommessage = sanitize(custommessage) - - //Send message - if("Send") - - if(isnull(customsender) || customsender == "") - customsender = "UNKNOWN" - - if(isnull(customrecepient)) - message = "NOTICE: No recepient selected!" - return src.attack_hand(usr) - - if(isnull(custommessage) || custommessage == "") - message = "NOTICE: No message entered!" - return src.attack_hand(usr) - - var/obj/item/device/pda/PDARec = null - for (var/obj/item/device/pda/P in PDAs) - if (!P.owner || P.toff || P.hidden) continue - if(P.owner == customsender) - PDARec = P - //Sender isn't faking as someone who exists - if(isnull(PDARec)) - src.linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]") - customrecepient.new_message(customsender, customsender, customjob, custommessage) - //Sender is faking as someone who exists - else - - src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]") - customrecepient.tnote.Add(list(list("sent" = 0, "owner" = "[PDARec.owner]", "job" = "[customjob]", "message" = "[custommessage]", "target" ="\ref[PDARec]"))) - - if(!customrecepient.conversations.Find("\ref[PDARec]")) - customrecepient.conversations.Add("\ref[PDARec]") - - customrecepient.new_message(PDARec, custommessage) - //Finally.. - ResetMessage() - - //Request Console Logs - KEY REQUIRED - if(href_list["viewr"]) - if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else - if(auth) - src.screen = 4 - - //to_chat(usr,href_list["select"]) - - if(href_list["spam"]) - if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else - if(auth) - src.screen = 5 - - if(href_list["addtoken"]) - if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else - src.linkedServer.spamfilter += input(usr,"Enter text you want to be filtered out","Token creation") as text|null - - if(href_list["deltoken"]) - if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) - message = noserver - else - var/tokennum = text2num(href_list["deltoken"]) - src.linkedServer.spamfilter.Cut(tokennum,tokennum+1) - - if (href_list["back"]) - src.screen = 0 - - return src.attack_hand(usr) +/obj/machinery/computer/message_monitor/proc/set_temp(text = "", style = "info", update_now = FALSE) + temp = list(text = text, style = style) + if(update_now) + SStgui.update_uis(src) /obj/item/weapon/paper/monitorkey name = "Monitor Decryption Key" diff --git a/code/game/machinery/computer/shutoff_monitor.dm b/code/game/machinery/computer/shutoff_monitor.dm index 89cd4127db2..8cc101d8044 100644 --- a/code/game/machinery/computer/shutoff_monitor.dm +++ b/code/game/machinery/computer/shutoff_monitor.dm @@ -5,23 +5,19 @@ icon_screen = "power_monitor" light_color = "#a97faa" circuit = /obj/item/weapon/circuitboard/shutoff_monitor - var/datum/nano_module/shutoff_monitor/monitor + var/datum/tgui_module/shutoff_monitor/monitor /obj/machinery/computer/shutoff_monitor/New() ..() monitor = new(src) /obj/machinery/computer/shutoff_monitor/Destroy() - qdel(monitor) - monitor = null + QDEL_NULL(monitor) ..() /obj/machinery/computer/shutoff_monitor/attack_hand(var/mob/user as mob) ..() - ui_interact(user) - -/obj/machinery/computer/shutoff_monitor/ui_interact(mob/user, ui_key = "shutoff_monitor", var/datum/nanoui/ui = null, var/force_open = 1) - monitor.ui_interact(user, ui_key, ui, force_open) + monitor.tgui_interact(user) /obj/machinery/computer/shutoff_monitor/update_icon() ..() diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index 1a64db73893..bde923a2171 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -1,5 +1,11 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 +#define GENERAL_RECORD_LIST 2 +#define GENERAL_RECORD_MAINT 3 +#define GENERAL_RECORD_DATA 4 + +#define FIELD(N, V, E) list(field = N, value = V, edit = E) + /obj/machinery/computer/skills//TODO:SANITY name = "employment records console" desc = "Used to view, edit and maintain employment records." @@ -16,20 +22,40 @@ var/screen = null var/datum/data/record/active1 = null var/a_id = null - var/temp = null + var/list/temp = null var/printing = null var/can_change_id = 0 - var/list/Perp - var/tempname = null - //Sorting Variables - var/sortBy = "name" - var/order = 1 // -1 = Descending - 1 = Ascending + // The below are used to make modal generation more convenient + var/static/list/field_edit_questions + var/static/list/field_edit_choices + +/obj/machinery/computer/skills/Initialize() + ..() + field_edit_questions = list( + // General + "name" = "Please input new name:", + "id" = "Please input new ID:", + "sex" = "Please select new sex:", + "age" = "Please input new age:", + "fingerprint" = "Please input new fingerprint hash:", + ) + field_edit_choices = list( + // General + "sex" = all_genders_text_list, + "p_stat" = list("*Deceased*", "*SSD*", "Active", "Physically Unfit", "Disabled"), + "m_stat" = list("*Insane*", "*Unstable*", "*Watch*", "Stable"), + ) + +/obj/machinery/computer/skills/Destroy() + active1 = null + return ..() /obj/machinery/computer/skills/attackby(obj/item/O as obj, var/mob/user) if(istype(O, /obj/item/weapon/card/id) && !scan && user.unEquip(O)) O.loc = src scan = O to_chat(user, "You insert [O].") + tgui_interact(user) else ..() @@ -43,380 +69,271 @@ if (using_map && !(src.z in using_map.contact_levels)) to_chat(user, "Unable to establish a connection: You're too far away from the station!") return - var/dat + tgui_interact(user) - if (temp) - dat = text("[]

Clear Screen", temp, src) - else - dat = text("Confirm Identity: []
", src, (scan ? text("[]", scan.name) : "----------")) - if (authenticated) - switch(screen) - if(1.0) - dat += {" -

"} - dat += text("Search Records
", src) - dat += text("New Record
", src) - dat += {" -

- - - - -
Records:
- - - - - - -"} - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order)) - for(var/datum/data/record/E in data_core.security) - var/background - dat += text("", background, src, R, R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["rank"]) - dat += text("", R.fields["fingerprint"]) - dat += "
NameIDRankFingerprints
[][][][]

" - dat += text("Record Maintenance

", src) - dat += text("{Log Out}",src) - if(2.0) - dat += "Records Maintenance
" - dat += "
Delete All Records

Back" - if(3.0) - dat += "
Employment Record

" - if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) - var/icon/front = active1.fields["photo_front"] - var/icon/side = active1.fields["photo_side"] - user << browse_rsc(front, "front.png") - user << browse_rsc(side, "side.png") - dat += "" - - dat += "
" - dat += "Name: [active1.fields["name"]]
" - dat += "ID: [active1.fields["id"]]
\n" - dat += "Entity Classification: [active1.fields["brain_type"]]
\n" - dat += "Sex: [active1.fields["sex"]]
\n" - dat += "Age: [active1.fields["age"]]
\n" - dat += "Rank: [active1.fields["rank"]]
\n" - dat += "Fingerprint: [active1.fields["fingerprint"]]
\n" - dat += "Physical Status: [active1.fields["p_stat"]]
\n" - dat += "Mental Status: [active1.fields["m_stat"]]

\n" +/obj/machinery/computer/skills/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "GeneralRecords", "Employee Records") // 800, 380 + ui.open() + ui.set_autoupdate(FALSE) - dat += "Employment/skills summary:
" - dat += decode(active1.fields["notes"]) - dat += "


" - var/counter = 1 - while(src.active1.fields[text("com_[]", counter)]) - dat += text("[]
Delete Entry

", src.active1.fields[text("com_[]", counter)], src, counter) - counter++ - dat += "Add Entry

Photo:
" - dat += "
" - else - dat += "General Record Lost!
" - dat += text("\nDelete Record (ALL)

\nPrint Record
\nBack
", src, src, src) - if(4.0) - if(!Perp.len) - dat += text("ERROR. String could not be located.

Back", src) - else - dat += {" - - "} - dat += text("", tempname) - dat += {" - -
Search Results for '[]':
- - - - - - - "} - for(var/i=1, i<=Perp.len, i += 2) - var/crimstat = "" - var/datum/data/record/R = Perp[i] - if(istype(Perp[i+1],/datum/data/record/)) - var/datum/data/record/E = Perp[i+1] - crimstat = E.fields["criminal"] - var/background - background = "'background-color:#00FF7F;'" - dat += text("", background, src, R, R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["rank"]) - dat += text("", R.fields["fingerprint"]) - dat += text("", crimstat) - dat += "
NameIDRankFingerprints
[][][][][]

" - dat += text("
Return to index.", src) +/obj/machinery/computer/skills/tgui_data(mob/user) + var/data[0] + data["temp"] = temp + data["scan"] = scan ? scan.name : null + data["authenticated"] = authenticated + data["rank"] = rank + data["screen"] = screen + data["printing"] = printing + data["isAI"] = isAI(user) + data["isRobot"] = isrobot(user) + if(authenticated) + switch(screen) + if(GENERAL_RECORD_LIST) + if(!isnull(data_core.general)) + var/list/records = list() + data["records"] = records + for(var/datum/data/record/R in sortRecord(data_core.general)) + records[++records.len] = list( + "ref" = "\ref[R]", + "id" = R.fields["id"], + "name" = R.fields["name"], + "b_dna" = R.fields["b_dna"]) + if(GENERAL_RECORD_DATA) + var/list/general = list() + data["general"] = general + if(istype(active1, /datum/data/record) && data_core.general.Find(active1)) + var/list/fields = list() + general["fields"] = fields + fields[++fields.len] = FIELD("Name", active1.fields["name"], "name") + fields[++fields.len] = FIELD("ID", active1.fields["id"], "id") + fields[++fields.len] = FIELD("Sex", active1.fields["sex"], "sex") + fields[++fields.len] = FIELD("Age", active1.fields["age"], "age") + fields[++fields.len] = FIELD("Fingerprint", active1.fields["fingerprint"], "fingerprint") + fields[++fields.len] = FIELD("Physical Status", active1.fields["p_stat"], null) + fields[++fields.len] = FIELD("Mental Status", active1.fields["m_stat"], null) + var/list/photos = list() + general["photos"] = photos + photos[++photos.len] = active1.fields["photo-south"] + photos[++photos.len] = active1.fields["photo-west"] + general["has_photos"] = (active1.fields["photo-south"] || active1.fields["photo-west"] ? 1 : 0) + if(!active1.fields["comments"] || !islist(active1.fields["comments"])) + active1.fields["comments"] = list() + general["skills"] = active1.fields["notes"] + general["comments"] = active1.fields["comments"] + general["empty"] = 0 else - else - dat += text("{Log In}", src) - user << browse(text("Employment Records[]", dat), "window=secure_rec;size=600x400") - onclose(user, "secure_rec") - return + general["empty"] = 1 -/*Revised /N -I can't be bothered to look more of the actual code outside of switch but that probably needs revising too. -What a mess.*/ -/obj/machinery/computer/skills/Topic(href, href_list) + data["modal"] = tgui_modal_data(src) + return data + +/obj/machinery/computer/skills/tgui_act(action, params) if(..()) - return 1 - if (!( data_core.general.Find(active1) )) + return TRUE + + add_fingerprint(usr) + + if(!data_core.general.Find(active1)) active1 = null - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) - switch(href_list["choice"]) -// SORTING! - if("Sorting") - // Reverse the order if clicked twice - if(sortBy == href_list["sort"]) - if(order == 1) - order = -1 - else - order = 1 - else - // New sorting order! - sortBy = href_list["sort"] - order = initial(order) -//BASIC FUNCTIONS - if("Clear Screen") - temp = null - if ("Return") - screen = 1 + . = TRUE + if(tgui_act_modal(action, params)) + return + + switch(action) + if("scan") + if(scan) + scan.forceMove(loc) + if(ishuman(usr) && !usr.get_active_hand()) + usr.put_in_hands(scan) + scan = null + else + var/obj/item/I = usr.get_active_hand() + if(istype(I, /obj/item/weapon/card/id)) + usr.drop_item() + I.forceMove(src) + scan = I + if("cleartemp") + temp = null + if("login") + var/login_type = text2num(params["login_type"]) + if(login_type == LOGIN_TYPE_NORMAL && istype(scan)) + if(check_access(scan)) + authenticated = scan.registered_name + rank = scan.assignment + else if(login_type == LOGIN_TYPE_AI && isAI(usr)) + authenticated = usr.name + rank = "AI" + else if(login_type == LOGIN_TYPE_ROBOT && isrobot(usr)) + authenticated = usr.name + var/mob/living/silicon/robot/R = usr + rank = "[R.modtype] [R.braintype]" + if(authenticated) active1 = null + screen = GENERAL_RECORD_LIST + else + . = FALSE + + if(.) + return - if("Confirm Identity") - if (scan) - if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand()) + if(authenticated) + . = TRUE + switch(action) + if("logout") + if(scan) + scan.forceMove(loc) + if(ishuman(usr) && !usr.get_active_hand()) usr.put_in_hands(scan) - else - scan.loc = get_turf(src) scan = null - else - var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I)) - I.loc = src - scan = I - - if("Log Out") authenticated = null screen = null active1 = null - - if("Log In") - if (istype(usr, /mob/living/silicon/ai)) - src.active1 = null - src.authenticated = usr.name - src.rank = "AI" - src.screen = 1 - else if (istype(usr, /mob/living/silicon/robot)) - src.active1 = null - src.authenticated = usr.name - var/mob/living/silicon/robot/R = usr - src.rank = R.braintype - src.screen = 1 - else if (istype(scan, /obj/item/weapon/card/id)) - active1 = null - if(check_access(scan)) - authenticated = scan.registered_name - rank = scan.assignment - screen = 1 -//RECORD FUNCTIONS - if("Search Records") - var/t1 = input("Search String: (Partial Name or ID or Fingerprints or Rank)", "Secure. records", null, null) as text - if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || !in_range(src, usr))) - return - Perp = new/list() - t1 = lowertext(t1) - var/list/components = splittext(t1, " ") - if(components.len > 5) - return //Lets not let them search too greedily. - for(var/datum/data/record/R in data_core.general) - var/temptext = R.fields["name"] + " " + R.fields["id"] + " " + R.fields["fingerprint"] + " " + R.fields["rank"] - for(var/i = 1, i<=components.len, i++) - if(findtext(temptext,components[i])) - var/prelist = new/list(2) - prelist[1] = R - Perp += prelist - for(var/i = 1, i<=Perp.len, i+=2) - for(var/datum/data/record/E in data_core.security) - var/datum/data/record/R = Perp[i] - if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) - Perp[i+1] = E - tempname = t1 - screen = 4 - - if("Record Maintenance") - screen = 2 + if("screen") + screen = clamp(text2num(params["screen"]) || 0, GENERAL_RECORD_LIST, GENERAL_RECORD_MAINT) active1 = null - - if ("Browse Record") - var/datum/data/record/R = locate(href_list["d_rec"]) - if (!( data_core.general.Find(R) )) - temp = "Record Not Found!" - else - for(var/datum/data/record/E in data_core.security) - active1 = R - screen = 3 - -/* if ("Search Fingerprints") - var/t1 = input("Search String: (Fingerprint)", "Secure. records", null, null) as text - if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || (!in_range(src, usr)) && (!istype(usr, /mob/living/silicon)))) - return - active1 = null - t1 = lowertext(t1) - for(var/datum/data/record/R in data_core.general) - if (lowertext(R.fields["fingerprint"]) == t1) - active1 = R - if (!( active1 )) - temp = text("Could not locate record [].", t1) - else - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"])) - screen = 3 */ - - if ("Print Record") - if (!( printing )) - printing = 1 - sleep(50) - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc ) - P.info = "
Employment Record

" - if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) - P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
\nEmployment/Skills Summary:
\n[]
", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"], active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"], decode(active1.fields["notes"])) - else - P.info += "General Record Lost!
" - P.info += "" - if(active1) - P.name = "Employment Record ([active1.fields["name"]])" - else - P.name = "Employment Record (Unknown/Invald Entry)" - log_debug("[usr] ([usr.ckey]) attempted to print a null employee record, this should be investigated.") - printing = null -// Add comment - if ("add_c") - if (!( istype(src.active1, /datum/data/record) )) - return - var/a1 = src.active1 - var/t1 = sanitize(input("Add Comment:", "Emp. records", null, null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) - return - var/counter = 1 - while(src.active1.fields[text("com_[]", counter)]) - counter++ - src.active1.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [stationtime2text()], [game_year]
[t1]") -// Delete comment - if ("del_c") - var/target = href_list["del_c"] - if (istype(src.active1, /datum/data/record) && src.active1.fields["com_[target]"]) - src.active1.fields["com_[target]"] = "Deleted" - - -//RECORD DELETE - if ("Delete All Records") - temp = "" - temp += "Are you sure you wish to delete all Employment records?
" - temp += "Yes
" - temp += "No" - - if ("Purge All Records") - if(PDA_Manifest.len) + if("del_all") + if(PDA_Manifest) PDA_Manifest.Cut() - for(var/datum/data/record/R in data_core.security) + for(var/datum/data/record/R in data_core.general) qdel(R) - temp = "All Employment records deleted." + set_temp("All employment records deleted.") + if("del_r") + if(PDA_Manifest) + PDA_Manifest.Cut() + if(active1) + for(var/datum/data/record/R in data_core.medical) + if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) + qdel(R) + set_temp("Employment record deleted.") + QDEL_NULL(active1) + if("d_rec") + var/datum/data/record/general_record = locate(params["d_rec"] || "") + if(!data_core.general.Find(general_record)) + set_temp("Record not found.", "danger") + return - if ("Delete Record (ALL)") - if (active1) - temp = "
Are you sure you wish to delete the record (ALL)?
" - temp += "Yes
" - temp += "No" -//RECORD CREATE - if ("New Record (General)") - if(PDA_Manifest.len) + active1 = general_record + screen = GENERAL_RECORD_DATA + if("new") + if(PDA_Manifest) PDA_Manifest.Cut() active1 = data_core.CreateGeneralRecord() + screen = GENERAL_RECORD_DATA + set_temp("Employment record created.", "success") + if("del_c") + var/index = text2num(params["del_c"] || "") + if(!index || !istype(active1, /datum/data/record)) + return -//FIELD FUNCTIONS - if ("Edit Field") - var/a1 = active1 - switch(href_list["field"]) - if("name") - if (istype(active1, /datum/data/record)) - var/t1 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text) - if ((!( t1 ) || !length(trim(t1)) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon)))) || active1 != a1) - return - active1.fields["name"] = t1 - if("id") - if (istype(active1, /datum/data/record)) - var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text) - if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) - return - active1.fields["id"] = t1 - if("fingerprint") - if (istype(active1, /datum/data/record)) - var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text) - if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) - return - active1.fields["fingerprint"] = t1 - if("sex") - if (istype(active1, /datum/data/record)) - if (active1.fields["sex"] == "Male") - active1.fields["sex"] = "Female" - else - active1.fields["sex"] = "Male" - if("age") - if (istype(active1, /datum/data/record)) - var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num - if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) - return - active1.fields["age"] = t1 - if("rank") - var/list/L = list( "Head of Personnel", "Colony Director", "AI" ) - //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N - if ((istype(active1, /datum/data/record) && L.Find(rank))) - temp = "
Rank:
" - temp += "" - else - alert(usr, "You do not have the required rank to do this!") - if("species") - if (istype(active1, /datum/data/record)) - var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message) - if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) - return - active1.fields["species"] = t1 + var/list/comments = active1.fields["comments"] + index = clamp(index, 1, length(comments)) + if(comments[index]) + comments.Cut(index, index + 1) + if("print_p") + if(!printing) + printing = TRUE + // playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, TRUE) + SStgui.update_uis(src) + addtimer(CALLBACK(src, .proc/print_finish), 5 SECONDS) + else + return FALSE -//TEMPORARY MENU FUNCTIONS - else//To properly clear as per clear screen. - temp=null - switch(href_list["choice"]) - if ("Change Rank") - if (active1) - if(PDA_Manifest.len) - PDA_Manifest.Cut() - active1.fields["rank"] = href_list["rank"] - if(href_list["rank"] in joblist) - active1.fields["real_rank"] = href_list["real_rank"] - - if ("Delete Record (ALL) Execute") - if (active1) - if(PDA_Manifest.len) - PDA_Manifest.Cut() - for(var/datum/data/record/R in data_core.medical) - if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) - qdel(R) - else - qdel(active1) +/** + * Called in tgui_act() to process modal actions + * + * Arguments: + * * action - The action passed by tgui + * * params - The params passed by tgui + */ +/obj/machinery/computer/skills/proc/tgui_act_modal(action, params) + . = TRUE + var/id = params["id"] // The modal's ID + var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"] + switch(tgui_modal_act(src, action, params)) + if(TGUI_MODAL_OPEN) + switch(id) + if("edit") + var/field = arguments["field"] + if(!length(field) || !field_edit_questions[field]) + return + var/question = field_edit_questions[field] + var/choices = field_edit_choices[field] + if(length(choices)) + tgui_modal_choice(src, id, question, arguments = arguments, value = arguments["value"], choices = choices) else - temp = "This function does not appear to be working at the moment. Our apologies." + tgui_modal_input(src, id, question, arguments = arguments, value = arguments["value"]) + if("add_c") + tgui_modal_input(src, id, "Please enter your message:") + else + return FALSE + if(TGUI_MODAL_ANSWER) + var/answer = params["answer"] + switch(id) + if("edit") + var/field = arguments["field"] + if(!length(field) || !field_edit_questions[field]) + return + var/list/choices = field_edit_choices[field] + if(length(choices) && !(answer in choices)) + return - add_fingerprint(usr) - updateUsrDialog() - return + if(field == "age") + answer = text2num(answer) + + if(istype(active1) && (field in active1.fields)) + active1.fields[field] = answer + . = TRUE + if("add_c") + if(!length(answer) || !istype(active1) || !length(authenticated)) + return + active1.fields["comments"] += list(list( + header = "Made by [authenticated] ([rank]) at [worldtime2stationtime(world.time)]", + text = answer + )) + else + return FALSE + else + return FALSE + +/** + * Called when the print timer finishes + */ +/obj/machinery/computer/skills/proc/print_finish() + var/obj/item/weapon/paper/P = new(loc) + P.info = "
Medical Record

" + if(istype(active1, /datum/data/record) && data_core.general.Find(active1)) + P.info += {"Name: [active1.fields["name"]] ID: [active1.fields["id"]] +
\nSex: [active1.fields["sex"]] +
\nAge: [active1.fields["age"]] +
\nFingerprint: [active1.fields["fingerprint"]] +
\nPhysical Status: [active1.fields["p_stat"]] +
\nMental Status: [active1.fields["m_stat"]]
+
\nEmployment/Skills Summary: [active1.fields["notes"]] +
\n +
Comments/Log

"} + for(var/c in active1.fields["comments"]) + P.info += "[c]
" + else + P.info += "General Record Lost!
" + P.info += "" + P.name = "paper - 'Employment Record: [active1.fields["name"]]'" + printing = FALSE + SStgui.update_uis(src) + +/** + * Sets a temporary message to display to the user + * + * Arguments: + * * text - Text to display, null/empty to clear the message from the UI + * * style - The style of the message: (color name), info, success, warning, danger, virus + */ +/obj/machinery/computer/skills/proc/set_temp(text = "", style = "info", update_now = FALSE) + temp = list(text = text, style = style) + if(update_now) + SStgui.update_uis(src) /obj/machinery/computer/skills/emp_act(severity) if(stat & (BROKEN|NOPOWER)) diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 8bd2f91f893..5cb000484df 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -6,15 +6,15 @@ icon_screen = "alert:0" light_color = "#e6ffff" circuit = /obj/item/weapon/circuitboard/stationalert_engineering - var/datum/nano_module/alarm_monitor/alarm_monitor - var/monitor_type = /datum/nano_module/alarm_monitor/engineering + var/datum/tgui_module/alarm_monitor/alarm_monitor + var/monitor_type = /datum/tgui_module/alarm_monitor/engineering /obj/machinery/computer/station_alert/security - monitor_type = /datum/nano_module/alarm_monitor/security + monitor_type = /datum/tgui_module/alarm_monitor/security circuit = /obj/item/weapon/circuitboard/stationalert_security /obj/machinery/computer/station_alert/all - monitor_type = /datum/nano_module/alarm_monitor/all + monitor_type = /datum/tgui_module/alarm_monitor/all circuit = /obj/item/weapon/circuitboard/stationalert_all /obj/machinery/computer/station_alert/Initialize() @@ -31,18 +31,18 @@ add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - interact(user) + tgui_interact(user) return /obj/machinery/computer/station_alert/attack_hand(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return - interact(user) + tgui_interact(user) return -/obj/machinery/computer/station_alert/interact(mob/user) - alarm_monitor.ui_interact(user) +/obj/machinery/computer/station_alert/tgui_interact(mob/user) + alarm_monitor.tgui_interact(user) /obj/machinery/computer/station_alert/update_icon() if(!(stat & (BROKEN|NOPOWER))) diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 9db22b92702..d822bcb7392 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -82,29 +82,30 @@ if(occupant == user && !user.stat) go_out() +/obj/machinery/atmospherics/unary/cryo_cell/attack_ghost(mob/user) + tgui_interact(user) + /obj/machinery/atmospherics/unary/cryo_cell/attack_hand(mob/user) - ui_interact(user) - - /** - * The ui_interact proc is used to open and update Nano UIs - * If ui_interact is not used then the UI will not update correctly - * ui_interact is currently defined for /atom/movable (which is inherited by /obj and /mob) - * - * @param user /mob The mob who is interacting with this ui - * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") - * @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui - * - * @return nothing - */ -/obj/machinery/atmospherics/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - - if(user == occupant || user.stat) + if(user == occupant) return + if(panel_open) + to_chat(usr, "Close the maintenance panel first.") + return + + tgui_interact(user) + +/obj/machinery/atmospherics/unary/cryo_cell/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Cryo", "Cryo Cell") // 520, 470 + ui.open() + +/obj/machinery/atmospherics/unary/cryo_cell/tgui_data(mob/user) // this is the data which will be sent to the ui var/data[0] data["isOperating"] = on - data["hasOccupant"] = occupant ? 1 : 0 + data["hasOccupant"] = occupant ? TRUE : FALSE var/occupantData[0] if(occupant) @@ -127,14 +128,7 @@ else if(air_contents.temperature > 225) data["cellTemperatureStatus"] = "average" - data["isBeakerLoaded"] = beaker ? 1 : 0 - /* // Removing beaker contents list from front-end, replacing with a total remaining volume - var beakerContents[0] - if(beaker && beaker.reagents && beaker.reagents.reagent_list.len) - for(var/datum/reagent/R in beaker.reagents.reagent_list) - beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list... - data["beakerContents"] = beakerContents - */ + data["isBeakerLoaded"] = beaker ? TRUE : FALSE data["beakerLabel"] = null data["beakerVolume"] = 0 if(beaker) @@ -143,47 +137,33 @@ for(var/datum/reagent/R in beaker.reagents.reagent_list) data["beakerVolume"] += R.volume - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "cryo.tmpl", "Cryo Cell Control System", 520, 410) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) + return data -/obj/machinery/atmospherics/unary/cryo_cell/Topic(href, href_list) - if(usr == occupant) - return 0 // don't update UIs attached to this object +/obj/machinery/atmospherics/unary/cryo_cell/tgui_act(action, params) + if(..() || usr == occupant) + return TRUE - if(..()) - return 0 // don't update UIs attached to this object - - if(href_list["switchOn"]) - on = 1 - update_icon() - - if(href_list["switchOff"]) - on = 0 - update_icon() - - if(href_list["ejectBeaker"]) - if(beaker) - beaker.loc = get_step(src.loc, SOUTH) - beaker = null + . = TRUE + switch(action) + if("switchOn") + on = 1 update_icon() - - if(href_list["ejectOccupant"]) - if(!occupant || isslime(usr) || ispAI(usr)) - return 0 // don't update UIs attached to this object - go_out() + if("switchOff") + on = 0 + update_icon() + if("ejectBeaker") + if(beaker) + beaker.loc = get_step(src.loc, SOUTH) + beaker = null + update_icon() + if("ejectOccupant") + if(!occupant || isslime(usr) || ispAI(usr)) + return 0 // don't update UIs attached to this object + go_out() + else + return FALSE add_fingerprint(usr) - return 1 // update UIs attached to this object /obj/machinery/atmospherics/unary/cryo_cell/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob) if(istype(G, /obj/item/weapon/reagent_containers/glass)) @@ -195,6 +175,7 @@ user.drop_item() G.loc = src user.visible_message("[user] adds \a [G] to \the [src]!", "You add \a [G] to \the [src]!") + SStgui.update_uis(src) update_icon() else if(istype(G, /obj/item/weapon/grab)) var/obj/item/weapon/grab/grab = G @@ -235,7 +216,7 @@ occupant.set_stat(UNCONSCIOUS) occupant.dir = SOUTH if(occupant.bodytemperature < T0C) - occupant.sleeping = max(5, (1/occupant.bodytemperature)*2000) + occupant.Sleeping(max(5, (1/occupant.bodytemperature)*2000)) occupant.Paralyse(max(5, (1/occupant.bodytemperature)*3000)) if(air_contents.gas["oxygen"] > 2) if(occupant.getOxyLoss()) occupant.adjustOxyLoss(-1) @@ -292,7 +273,9 @@ occupant = null current_heat_capacity = initial(current_heat_capacity) update_use_power(USE_POWER_IDLE) + SStgui.update_uis(src) return + /obj/machinery/atmospherics/unary/cryo_cell/proc/put_mob(mob/living/carbon/M as mob) if(stat & (NOPOWER|BROKEN)) to_chat(usr, "The cryo cell is not functioning.") @@ -326,6 +309,7 @@ // M.metabslow = 1 add_fingerprint(usr) update_icon() + SStgui.update_uis(src) return 1 /obj/machinery/atmospherics/unary/cryo_cell/verb/move_eject() diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index bdd2b05fc6b..a133aab9b1a 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -520,9 +520,9 @@ control_computer._admin_logs += "[key_name(to_despawn)] ([to_despawn.mind.role_alt_title]) at [stationtime2text()]" log_and_message_admins("[key_name(to_despawn)] ([to_despawn.mind.role_alt_title]) entered cryostorage.") - announce.autosay("[to_despawn.real_name], [to_despawn.mind.role_alt_title], [on_store_message]", "[on_store_name]", announce_channel, using_map.get_map_levels(z, TRUE)) + announce.autosay("[to_despawn.real_name], [to_despawn.mind.role_alt_title], [on_store_message]", "[on_store_name]", announce_channel, using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE)) //visible_message("\The [initial(name)] hums and hisses as it moves [to_despawn.real_name] into storage.", 3) - visible_message("\The [initial(name)] [on_store_visible_message_1] [to_despawn.real_name] [on_store_visible_message_2].", 3) + visible_message("\The [initial(name)] [on_store_visible_message_1] [to_despawn.real_name] [on_store_visible_message_2]", 3) //VOREStation Edit begin: Dont delete mobs-in-mobs if(to_despawn.client && to_despawn.stat<2) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index ee66c2172a4..73ed4dc72e3 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -543,10 +543,6 @@ About the new airlock wires panel: return 1 return 0 -/obj/machinery/door/airlock/proc/isWireCut(var/wireIndex) - // You can find the wires in the datum folder. - return wires.IsIndexCut(wireIndex) - /obj/machinery/door/airlock/proc/canAIControl() return ((src.aiControlDisabled!=1) && (!src.isAllPowerLoss())); @@ -559,7 +555,7 @@ About the new airlock wires panel: return (src.main_power_lost_until==0 || src.backup_power_lost_until==0) /obj/machinery/door/airlock/requiresID() - return !(src.isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner) + return !(wires.is_cut(WIRE_IDSCAN) || aiDisabledIdScanner) /obj/machinery/door/airlock/proc/isAllPowerLoss() if(stat & (NOPOWER|BROKEN)) @@ -569,10 +565,10 @@ About the new airlock wires panel: return 0 /obj/machinery/door/airlock/proc/mainPowerCablesCut() - return src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2) + return wires.is_cut(WIRE_MAIN_POWER1) || wires.is_cut(WIRE_MAIN_POWER2) /obj/machinery/door/airlock/proc/backupPowerCablesCut() - return src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2) + return wires.is_cut(WIRE_BACKUP_POWER1) || wires.is_cut(WIRE_BACKUP_POWER2) /obj/machinery/door/airlock/proc/loseMainPower() main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) @@ -620,7 +616,7 @@ About the new airlock wires panel: /obj/machinery/door/airlock/proc/electrify(var/duration, var/feedback = 0) var/message = "" - if(src.isWireCut(AIRLOCK_WIRE_ELECTRIFY) && arePowerSystemsOn()) + if(wires.is_cut(WIRE_ELECTRIFY) && arePowerSystemsOn()) message = text("The electrification wire is cut - Door permanently electrified.") src.electrified_until = -1 else if(duration && !arePowerSystemsOn()) @@ -646,7 +642,7 @@ About the new airlock wires panel: /obj/machinery/door/airlock/proc/set_idscan(var/activate, var/feedback = 0) var/message = "" - if(src.isWireCut(AIRLOCK_WIRE_IDSCAN)) + if(wires.is_cut(WIRE_IDSCAN)) message = "The IdScan wire is cut - IdScan feature permanently disabled." else if(activate && src.aiDisabledIdScanner) src.aiDisabledIdScanner = 0 @@ -661,7 +657,7 @@ About the new airlock wires panel: /obj/machinery/door/airlock/proc/set_safeties(var/activate, var/feedback = 0) var/message = "" // Safeties! We don't need no stinking safeties! - if (src.isWireCut(AIRLOCK_WIRE_SAFETY)) + if (wires.is_cut(WIRE_SAFETY)) message = text("The safety wire is cut - Cannot enable safeties.") else if (!activate && src.safe) safe = 0 @@ -744,32 +740,52 @@ About the new airlock wires panel: return /obj/machinery/door/airlock/attack_ai(mob/user as mob) - ui_interact(user) + tgui_interact(user) -/obj/machinery/door/airlock/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/data[0] +/obj/machinery/door/airlock/attack_ghost(mob/user) + tgui_interact(user) - data["main_power_loss"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1) - data["backup_power_loss"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1) - data["electrified"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1) - data["open"] = !density - - var/commands[0] - commands[++commands.len] = list("name" = "IdScan", "command"= "idscan", "active" = !aiDisabledIdScanner, "enabled" = "Enabled", "disabled" = "Disable", "danger" = 0, "act" = 1) - commands[++commands.len] = list("name" = "Bolts", "command"= "bolts", "active" = !locked, "enabled" = "Raised ", "disabled" = "Dropped", "danger" = 0, "act" = 0) - commands[++commands.len] = list("name" = "Bolt Lights", "command"= "lights", "active" = lights, "enabled" = "Enabled", "disabled" = "Disable", "danger" = 0, "act" = 1) - commands[++commands.len] = list("name" = "Safeties", "command"= "safeties", "active" = safe, "enabled" = "Nominal", "disabled" = "Overridden", "danger" = 1, "act" = 0) - commands[++commands.len] = list("name" = "Timing", "command"= "timing", "active" = normalspeed, "enabled" = "Nominal", "disabled" = "Overridden", "danger" = 1, "act" = 0) - commands[++commands.len] = list("name" = "Door State", "command"= "open", "active" = density, "enabled" = "Closed", "disabled" = "Opened", "danger" = 0, "act" = 0) - - data["commands"] = commands - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "door_control.tmpl", "Door Controls", 450, 350, state = state) - ui.set_initial_data(data) +/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AiAirlock", name) ui.open() - ui.set_auto_update(1) + return TRUE + +/obj/machinery/door/airlock/tgui_data(mob/user) + var/list/data = list() + + var/list/power = list() + power["main"] = main_power_lost_until > 0 ? 0 : 2 + power["main_timeleft"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1) + power["backup"] = backup_power_lost_until > 0 ? 0 : 2 + power["backup_timeleft"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1) + data["power"] = power + + data["shock"] = (electrified_until == 0) ? 2 : 0 + data["shock_timeleft"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1) + data["id_scanner"] = !aiDisabledIdScanner + data["locked"] = locked // bolted + data["lights"] = lights // bolt lights + data["safe"] = safe // safeties + data["speed"] = normalspeed // safe speed + data["welded"] = welded // welded + data["opened"] = !density // opened + + var/list/wire = list() + wire["main_1"] = !wires.is_cut(WIRE_MAIN_POWER1) + wire["main_2"] = !wires.is_cut(WIRE_MAIN_POWER2) + wire["backup_1"] = !wires.is_cut(WIRE_BACKUP_POWER1) + wire["backup_2"] = !wires.is_cut(WIRE_BACKUP_POWER2) + wire["shock"] = !wires.is_cut(WIRE_ELECTRIFY) + wire["id_scanner"] = !wires.is_cut(WIRE_IDSCAN) + wire["bolts"] = !wires.is_cut(WIRE_DOOR_BOLTS) + wire["lights"] = !wires.is_cut(WIRE_BOLT_LIGHT) + wire["safe"] = !wires.is_cut(WIRE_SAFETY) + wire["timing"] = !wires.is_cut(WIRE_SPEED) + + data["wires"] = wire + return data /obj/machinery/door/airlock/proc/hack(mob/user as mob) if(src.aiHacking==0) @@ -848,80 +864,106 @@ About the new airlock wires panel: ..(user) return -/obj/machinery/door/airlock/CanUseTopic(var/mob/user) - if(operating < 0) //emagged - to_chat(user, "Unable to interface: Internal error.") - return STATUS_CLOSE - if(issilicon(user) && !src.canAIControl()) - if(src.canAIHack(user)) - src.hack(user) - else - if (src.isAllPowerLoss()) //don't really like how this gets checked a second time, but not sure how else to do it. - to_chat(user, "Unable to interface: Connection timed out.") - else - to_chat(user, "Unable to interface: Connection refused.") - return STATUS_CLOSE - - return ..() - -/obj/machinery/door/airlock/Topic(href, href_list) +/obj/machinery/door/airlock/tgui_act(action, params) if(..()) - return 1 + return TRUE + if(!user_allowed(usr)) + return TRUE - var/activate = text2num(href_list["activate"]) - switch (href_list["command"]) - if("idscan") - set_idscan(activate, 1) - if("main_power") + switch(action) + if("disrupt-main") if(!main_power_lost_until) - src.loseMainPower() - if("backup_power") + loseMainPower() + update_icon() + else + to_chat(usr, "Main power is already offline.") + . = TRUE + if("disrupt-backup") if(!backup_power_lost_until) - src.loseBackupPower() - if("bolts") - if(src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - to_chat(usr, "The door bolt control wire is cut - Door bolts permanently dropped.") - else if(activate && src.lock()) - to_chat(usr, "The door bolts have been dropped.") - else if(!activate && src.unlock()) - to_chat(usr, "The door bolts have been raised.") - if("electrify_temporary") - electrify(30 * activate, 1) - if("electrify_permanently") - electrify(-1 * activate, 1) - if("open") - if(src.welded) - to_chat(usr, "The airlock has been welded shut!") - else if(src.locked) - to_chat(usr, "The door bolts are down!") - else if(activate && density) - open() - else if(!activate && !density) - close() - if("safeties") - set_safeties(!activate, 1) - if("timing") - // Door speed control - if(src.isWireCut(AIRLOCK_WIRE_SPEED)) - to_chat(usr, "The timing wire is cut - Cannot alter timing.") - else if (activate && src.normalspeed) - normalspeed = 0 - else if (!activate && !src.normalspeed) - normalspeed = 1 - if("lights") - // Bolt lights - if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) + loseBackupPower() + update_icon() + else + to_chat(usr, "Backup power is already offline.") + . = TRUE + if("shock-restore") + electrify(0, 1) + . = TRUE + if("shock-temp") + electrify(30, 1) + . = TRUE + if("shock-perm") + electrify(-1, 1) + . = TRUE + if("idscan-toggle") + set_idscan(aiDisabledIdScanner, 1) + . = TRUE + // if("emergency-toggle") + // toggle_emergency(usr) + // . = TRUE + if("bolt-toggle") + toggle_bolt(usr) + . = TRUE + if("light-toggle") + if(wires.is_cut(WIRE_BOLT_LIGHT)) to_chat(usr, "The bolt lights wire is cut - The door bolt lights are permanently disabled.") - else if (!activate && src.lights) - lights = 0 - to_chat(usr, "The door bolt lights have been disabled.") - else if (activate && !src.lights) - lights = 1 - to_chat(usr, "The door bolt lights have been enabled.") + return + lights = !lights + update_icon() + . = TRUE + if("safe-toggle") + set_safeties(!safe, 1) + . = TRUE + if("speed-toggle") + if(wires.is_cut(WIRE_SPEED)) + to_chat(usr, "The timing wire is cut - Cannot alter timing.") + return + normalspeed = !normalspeed + . = TRUE + if("open-close") + user_toggle_open(usr) + . = TRUE update_icon() return 1 +/obj/machinery/door/airlock/proc/user_allowed(mob/user) + var/allowed = (issilicon(user) && canAIControl(user)) + if(!allowed && isobserver(user)) + var/mob/observer/dead/D = user + if(D.can_admin_interact()) + allowed = TRUE + return allowed + +/obj/machinery/door/airlock/proc/toggle_bolt(mob/user) + if(!user_allowed(user)) + return + if(wires.is_cut(WIRE_DOOR_BOLTS)) + to_chat(user, "The door bolt drop wire is cut - you can't toggle the door bolts.") + return + if(locked) + if(!arePowerSystemsOn()) + to_chat(user, "The door has no power - you can't raise the door bolts.") + else + unlock() + to_chat(user, "The door bolts have been raised.") + // log_combat(user, src, "unbolted") + else + lock() + to_chat(user, "The door bolts have been dropped.") + // log_combat(user, src, "bolted") + +/obj/machinery/door/airlock/proc/user_toggle_open(mob/user) + if(!user_allowed(user)) + return + if(welded) + to_chat(user, text("The airlock has been welded shut!")) + else if(locked) + to_chat(user, text("The door bolts are down!")) + else if(!density) + close() + else + open() + /obj/machinery/door/airlock/proc/can_remove_electronics() return src.p_open && (operating < 0 || (!operating && welded && !src.arePowerSystemsOn() && density && (!src.locked || (stat & BROKEN)))) @@ -1076,7 +1118,7 @@ About the new airlock wires panel: /obj/machinery/door/airlock/can_open(var/forced=0) if(!forced) - if(!arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) + if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR)) return 0 if(locked || welded) @@ -1089,7 +1131,7 @@ About the new airlock wires panel: if(!forced) //despite the name, this wire is for general door control. - if(!arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) + if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR)) return 0 return ..() @@ -1131,6 +1173,7 @@ About the new airlock wires panel: SetWeakened(5) var/turf/T = get_turf(src) T.add_blood(src) + return 1 /mob/living/carbon/airlock_crush(var/crush_damage) . = ..() @@ -1190,7 +1233,7 @@ About the new airlock wires panel: return if (!forced) - if(operating || !src.arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) return + if(operating || !src.arePowerSystemsOn() || wires.is_cut(WIRE_DOOR_BOLTS)) return src.locked = 0 playsound(src, bolt_up_sound, 30, 0, 3) diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm index 136b793f103..06a4527f7eb 100644 --- a/code/game/machinery/doors/blast_door.dm +++ b/code/game/machinery/doors/blast_door.dm @@ -10,6 +10,9 @@ // UPDATE 06.04.2018 // The emag thing wasn't working as intended, manually overwrote it. +#define BLAST_DOOR_CRUSH_DAMAGE 40 +#define SHUTTER_CRUSH_DAMAGE 0 // VOREStation Edit - Shutter damage 0. + /obj/machinery/door/blast name = "Blast Door" desc = "That looks like it doesn't open easily." @@ -22,6 +25,10 @@ var/icon_state_opening = null var/icon_state_closed = null var/icon_state_closing = null + var/open_sound = 'sound/machines/blastdooropen.ogg' + var/close_sound = 'sound/machines/blastdoorclose.ogg' + var/damage = BLAST_DOOR_CRUSH_DAMAGE + var/multiplier = 1 // The multiplier for how powerful our YEET is. closed_layer = ON_WINDOW_LAYER // Above airlocks when closed var/id = 1.0 @@ -59,9 +66,13 @@ SSradiation.resistance_cache.Remove(get_turf(src)) return -// Has to be in here, comment at the top is older than the emag_act code on doors proper +// Proc: emag_act() +// Description: Emag action to allow blast doors to double their yeet distance and speed. /obj/machinery/door/blast/emag_act() - return -1 + if(!emagged) + emagged = 1 + multiplier = 2 // Haha emag go yeet + return 1 // Blast doors are triggered remotely, so nobody is allowed to physically influence it. /obj/machinery/door/blast/allowed(mob/M) @@ -72,6 +83,7 @@ // Description: Opens the door. No checks are done inside this proc. /obj/machinery/door/blast/proc/force_open() src.operating = 1 + playsound(src, open_sound, 100, 1) flick(icon_state_opening, src) src.density = 0 update_nearby_tiles() @@ -85,7 +97,12 @@ // Parameters: None // Description: Closes the door. No checks are done inside this proc. /obj/machinery/door/blast/proc/force_close() + // Blast door turf checks. We do this before the door closes to prevent it from failing after the door is closed, because obv a closed door will block any adjacency checks. + var/turf/T = get_turf(src) + var/list/yeet_turfs = T.CardinalTurfs(TRUE) + src.operating = 1 + playsound(src, close_sound, 100, 1) src.layer = closed_layer flick(icon_state_closing, src) src.density = 1 @@ -94,6 +111,14 @@ src.set_opacity(1) sleep(15) src.operating = 0 + + // Blast door crushing. + for(var/turf/turf in locs) + for(var/atom/movable/AM in turf) + if(AM.airlock_crush(damage)) + if(LAZYLEN(yeet_turfs)) + AM.throw_at(get_edge_target_turf(src, get_dir(src, pick(yeet_turfs))), (rand(1,3) * multiplier), (rand(2,4) * multiplier)) // YEET. + take_damage(damage*0.2) // Proc: force_toggle() // Parameters: None @@ -296,3 +321,7 @@ obj/machinery/door/blast/regular/open icon_state_closed = "shutter1" icon_state_closing = "shutterc1" icon_state = "shutter1" + damage = SHUTTER_CRUSH_DAMAGE + +#undef BLAST_DOOR_CRUSH_DAMAGE +#undef SHUTTER_CRUSH_DAMAGE \ No newline at end of file diff --git a/code/game/machinery/embedded_controller/airlock_controllers.dm b/code/game/machinery/embedded_controller/airlock_controllers.dm index b15d5afd975..262ffacf412 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers.dm @@ -14,6 +14,7 @@ var/tag_secure = 0 var/list/dummy_terminals = list() var/cycle_to_external_air = 0 + valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "purge", "secure") /obj/machinery/embedded_controller/radio/airlock/Destroy() // TODO - Leshana - Implement dummy terminals @@ -23,90 +24,42 @@ //dummy_terminals.Cut() return ..() -/obj/machinery/embedded_controller/radio/airlock/CanUseTopic(var/mob/user) +/obj/machinery/embedded_controller/radio/airlock/tgui_status(mob/user, datum/tgui_state/state) + . = ..() if(!allowed(user)) - return min(STATUS_UPDATE, ..()) - else - return ..() + return min(STATUS_UPDATE, .) //Advanced airlock controller for when you want a more versatile airlock controller - useful for turning simple access control rooms into airlocks /obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller name = "Advanced Airlock Controller" -/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - - data = list( +/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/tgui_data(mob/user) + . = list( "chamber_pressure" = round(program.memory["chamber_sensor_pressure"]), "external_pressure" = round(program.memory["external_sensor_pressure"]), "internal_pressure" = round(program.memory["internal_sensor_pressure"]), "processing" = program.memory["processing"], "purge" = program.memory["purge"], - "secure" = program.memory["secure"] + "secure" = program.memory["secure"], + "internalTemplateName" = "AirlockConsoleAdvanced", ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - - if (!ui) - ui = new(user, src, ui_key, "advanced_airlock_console.tmpl", name, 470, 290) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/Topic(href, href_list) - if((. = ..())) - return - - switch(href_list["command"]) //anti-HTML-hacking checks - if("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "purge", "secure") - program.receive_user_command(href_list["command"]) - - return 1 //Airlock controller for airlock control - most airlocks on the station use this /obj/machinery/embedded_controller/radio/airlock/airlock_controller name = "Airlock Controller" tag_secure = 1 + valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort") -/obj/machinery/embedded_controller/radio/airlock/airlock_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - - data = list( +/obj/machinery/embedded_controller/radio/airlock/airlock_controller/tgui_data(mob/user) + . = list( "chamber_pressure" = round(program.memory["chamber_sensor_pressure"]), "exterior_status" = program.memory["exterior_status"], "interior_status" = program.memory["interior_status"], "processing" = program.memory["processing"], + "internalTemplateName" = "AirlockConsoleSimple", ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "simple_airlock_console.tmpl", name, 470, 290) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/embedded_controller/radio/airlock/airlock_controller/Topic(href, href_list) - if((. = ..())) - return - - var/clean = 0 - switch(href_list["command"]) //anti-HTML-hacking checks - if("cycle_ext") - clean = 1 - if("cycle_int") - clean = 1 - if("force_ext") - clean = 1 - if("force_int") - clean = 1 - if("abort") - clean = 1 - - if(clean) - program.receive_user_command(href_list["command"]) - - return 1 - //Access controller for door control - used in virology and the like /obj/machinery/embedded_controller/radio/airlock/access_controller icon = 'icons/obj/airlock_machines.dmi' @@ -114,6 +67,7 @@ name = "Access Controller" tag_secure = 1 + valid_actions = list("cycle_ext_door", "cycle_int_door", "force_ext", "force_int") /obj/machinery/embedded_controller/radio/airlock/access_controller/update_icon() @@ -125,40 +79,10 @@ else icon_state = "access_control_off" -/obj/machinery/embedded_controller/radio/airlock/access_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - - data = list( +/obj/machinery/embedded_controller/radio/airlock/access_controller/tgui_data(mob/user) + . = list( "exterior_status" = program.memory["exterior_status"], "interior_status" = program.memory["interior_status"], - "processing" = program.memory["processing"] + "processing" = program.memory["processing"], + "internalTemplateName" = "DoorAccessConsole", ) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "door_access_console.tmpl", name, 330, 220) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/embedded_controller/radio/airlock/access_controller/Topic(href, href_list) - if((. = ..())) - return - - var/clean = 0 - switch(href_list["command"]) //anti-HTML-hacking checks - if("cycle_ext_door") - clean = 1 - if("cycle_int_door") - clean = 1 - if("force_ext") - if(program.memory["interior_status"]["state"] == "closed") - clean = 1 - if("force_int") - if(program.memory["exterior_status"]["state"] == "closed") - clean = 1 - - if(clean) - program.receive_user_command(href_list["command"]) - - return 1 \ No newline at end of file diff --git a/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm b/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm index d2f9a410a2f..ef6367758f0 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm @@ -1,4 +1,5 @@ // Provides remote access to a controller (since they must be unique). +// TGUITODO: Actually make these weird things work... well, as much as possible. /obj/machinery/dummy_airlock_controller name = "airlock control terminal" icon = 'icons/obj/airlock_machines.dmi' diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller.dm b/code/game/machinery/embedded_controller/airlock_docking_controller.dm index 4d5048ad6db..080fa7d3578 100644 --- a/code/game/machinery/embedded_controller/airlock_docking_controller.dm +++ b/code/game/machinery/embedded_controller/airlock_docking_controller.dm @@ -13,6 +13,7 @@ var/datum/computer/file/embedded_program/docking/airlock/docking_program var/display_name // For mappers to override docking_program.display_name (how would it show up on docking monitoring program) tag_secure = 1 + valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "toggle_override") /obj/machinery/embedded_controller/radio/airlock/docking_port/Initialize() . = ..() @@ -34,12 +35,11 @@ else ..() -/obj/machinery/embedded_controller/radio/airlock/docking_port/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/embedded_controller/radio/airlock/docking_port/tgui_data(mob/user) var/datum/computer/file/embedded_program/docking/airlock/docking_program = program var/datum/computer/file/embedded_program/airlock/docking/airlock_program = docking_program.airlock_program - data = list( + . = list( "chamber_pressure" = round(airlock_program.memory["chamber_sensor_pressure"]), "exterior_status" = airlock_program.memory["exterior_status"], "interior_status" = airlock_program.memory["interior_status"], @@ -48,49 +48,16 @@ "airlock_disabled" = !(docking_program.undocked() || docking_program.override_enabled), "override_enabled" = docking_program.override_enabled, "docking_codes" = docking_program.docking_codes, - "name" = docking_program.get_name() + "name" = docking_program.get_name(), + "internalTemplateName" = "AirlockConsoleDocking", ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - - if (!ui) - ui = new(user, src, ui_key, "docking_airlock_console.tmpl", name, 470, 290) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/embedded_controller/radio/airlock/docking_port/Topic(href, href_list) - if((. = ..())) - return - - var/clean = 0 - switch(href_list["command"]) //anti-HTML-hacking checks - if("cycle_ext") - clean = 1 - if("cycle_int") - clean = 1 - if("force_ext") - clean = 1 - if("force_int") - clean = 1 - if("abort") - clean = 1 - if("toggle_override") - clean = 1 - - if(clean) - program.receive_user_command(href_list["command"]) - - return 1 - - /////////////////////////////////////////////////////////////////////////////// //A docking controller for an airlock based docking port // /datum/computer/file/embedded_program/docking/airlock var/datum/computer/file/embedded_program/airlock/docking/airlock_program - /datum/computer/file/embedded_program/docking/airlock/New(var/obj/machinery/embedded_controller/M, var/datum/computer/file/embedded_program/airlock/docking/A) ..(M) airlock_program = A diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm b/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm index 55182aaaa62..b153437ca6f 100644 --- a/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm +++ b/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm @@ -15,9 +15,7 @@ for (var/i = 1; i <= tags.len; i++) child_names[tags[i]] = names[i] - -/obj/machinery/embedded_controller/radio/docking_port_multi/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/embedded_controller/radio/docking_port_multi/tgui_data(mob/user) var/datum/computer/file/embedded_program/docking/multi/docking_program = program // Cast to proper type var/list/airlocks[child_names.len] @@ -25,23 +23,14 @@ for (var/child_tag in child_names) airlocks[i++] = list("name"=child_names[child_tag], "override_enabled"=(docking_program.children_override[child_tag] == "enabled")) - data = list( + . = list( "docking_status" = docking_program.get_docking_status(), "airlocks" = airlocks, + "internalTemplateName" = "DockingConsoleMulti", ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - - if (!ui) - ui = new(user, src, ui_key, "multi_docking_console.tmpl", name, 470, 290) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/embedded_controller/radio/docking_port_multi/Topic(href, href_list) - return 1 // Apparently we swallow all input (this is corrected legacy code) - - +/obj/machinery/embedded_controller/radio/docking_port_multi/tgui_act(action, params) + return // Apparently we swallow all input (this is corrected legacy code) //a docking port based on an airlock // This is the actual controller that will be commanded by the master defined above @@ -50,12 +39,13 @@ program = /datum/computer/file/embedded_program/airlock/multi_docking var/master_tag //for mapping tag_secure = 1 + valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "toggle_override") + -/obj/machinery/embedded_controller/radio/airlock/docking_port_multi/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/embedded_controller/radio/airlock/docking_port_multi/tgui_data(mob/user) var/datum/computer/file/embedded_program/airlock/multi_docking/airlock_program = program // Cast to proper type - data = list( + . = list( "chamber_pressure" = round(airlock_program.memory["chamber_sensor_pressure"]), "exterior_status" = airlock_program.memory["exterior_status"], "interior_status" = airlock_program.memory["interior_status"], @@ -63,42 +53,9 @@ "docking_status" = airlock_program.master_status, "airlock_disabled" = (airlock_program.docking_enabled && !airlock_program.override_enabled), "override_enabled" = airlock_program.override_enabled, + "internalTemplateName" = "AirlockConsoleDocking", ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - - if (!ui) - ui = new(user, src, ui_key, "docking_airlock_console.tmpl", name, 470, 290) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/embedded_controller/radio/airlock/docking_port_multi/Topic(href, href_list) - if((. = ..())) - return - - var/clean = 0 - switch(href_list["command"]) //anti-HTML-hacking checks - if("cycle_ext") - clean = 1 - if("cycle_int") - clean = 1 - if("force_ext") - clean = 1 - if("force_int") - clean = 1 - if("abort") - clean = 1 - if("toggle_override") - clean = 1 - - if(clean) - program.receive_user_command(href_list["command"]) - - return 1 - - - /*** DEBUG VERBS *** /datum/computer/file/embedded_program/docking/multi/proc/print_state() diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 714d27d5609..58db9782dad 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -4,6 +4,7 @@ use_power = USE_POWER_IDLE idle_power_usage = 10 var/datum/computer/file/embedded_program/program //the currently executing program + var/list/valid_actions = list() var/on = 1 /obj/machinery/embedded_controller/Initialize() @@ -24,18 +25,19 @@ if(program) program.receive_signal(signal, receive_method, receive_param) - //spawn(5) program.process() //no, program.process sends some signals and machines respond and we here again and we lag -rastaf0 -/obj/machinery/embedded_controller/Topic(href, href_list) - if((. = ..())) - return +/obj/machinery/embedded_controller/Topic() + . = ..() + stack_trace("WARNING: Embedded controller [src] ([type]) had Topic() called unexpectedly. Please report this.") + +/obj/machinery/embedded_controller/tgui_act(action, params) + if(..()) + return TRUE + if(LAZYLEN(valid_actions)) + if(action in valid_actions) + program.receive_user_command(action) if(usr) - usr.set_machine(src) - src.add_fingerprint(usr) - // We would now pass it to the program, except that some of our embedded controller types want to block certain commands. - // Until/unless that is refactored differently, we rely on subtypes to pass it on. - //if(program) - // return program.receive_user_command(href_list["command"]) + add_fingerprint(usr) /obj/machinery/embedded_controller/process() if(program) @@ -44,19 +46,23 @@ update_icon() /obj/machinery/embedded_controller/attack_ai(mob/user as mob) - src.ui_interact(user) + tgui_interact(user) /obj/machinery/embedded_controller/attack_hand(mob/user as mob) - if(!user.IsAdvancedToolUser()) return 0 - src.ui_interact(user) + tgui_interact(user) + +/obj/machinery/embedded_controller/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "EmbeddedController", src) + ui.open() // // Embedded controller with a radio! (Most things (All things?) use this) // - /obj/machinery/embedded_controller/radio icon = 'icons/obj/airlock_machines.dmi' icon_state = "airlock_control_standby" diff --git a/code/game/machinery/embedded_controller/simple_docking_controller.dm b/code/game/machinery/embedded_controller/simple_docking_controller.dm index d2e04a33301..df94c21d5c2 100644 --- a/code/game/machinery/embedded_controller/simple_docking_controller.dm +++ b/code/game/machinery/embedded_controller/simple_docking_controller.dm @@ -3,42 +3,18 @@ name = "docking hatch controller" program = /datum/computer/file/embedded_program/docking/simple var/tag_door + valid_actions = list("force_door", "toggle_override") -/obj/machinery/embedded_controller/radio/simple_docking_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/embedded_controller/radio/simple_docking_controller/tgui_data(mob/user) var/datum/computer/file/embedded_program/docking/simple/docking_program = program // Cast to proper type - data = list( + . = list( "docking_status" = docking_program.get_docking_status(), "override_enabled" = docking_program.override_enabled, - "door_state" = docking_program.memory["door_status"]["state"], - "door_lock" = docking_program.memory["door_status"]["lock"], + "exterior_status" = docking_program.memory["door_status"], + "internalTemplateName" = "DockingConsoleSimple", ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - - if (!ui) - ui = new(user, src, ui_key, "simple_docking_console.tmpl", name, 470, 290) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/embedded_controller/radio/simple_docking_controller/Topic(href, href_list) - if((. = ..())) - return - - var/clean = 0 - switch(href_list["command"]) //anti-HTML-hacking checks - if("force_door") - clean = 1 - if("toggle_override") - clean = 1 - - if(clean) - program.receive_user_command(href_list["command"]) - - return - //A docking controller program for a simple door based docking port /datum/computer/file/embedded_program/docking/simple var/tag_door diff --git a/code/game/machinery/exonet_node.dm b/code/game/machinery/exonet_node.dm index b9b95e103c4..a8f6a387342 100644 --- a/code/game/machinery/exonet_node.dm +++ b/code/game/machinery/exonet_node.dm @@ -94,17 +94,25 @@ // Proc: attack_hand() // Parameters: 1 (user - the person clicking on the machine) -// Description: Opens the NanoUI interface with ui_interact() +// Description: Opens the TGUI interface with tgui_interact() /obj/machinery/exonet_node/attack_hand(mob/user) - ui_interact(user) + tgui_interact(user) -// Proc: ui_interact() -// Parameters: 4 (standard NanoUI arguments) +// Proc: tgui_interact() +// Parameters: 2 (user - person interacting with the UI, ui - the UI itself, in a refresh) +// Description: Handles opening the TGUI interface +/obj/machinery/exonet_node/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ExonetNode", src) + ui.open() + +// Proc: tgui_data() +// Parameters: 1 (user - the person using the interface) // Description: Allows the user to turn the machine on or off, or open or close certain 'ports' for things like external PDA messages, newscasters, etc. -/obj/machinery/exonet_node/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/exonet_node/tgui_data(mob/user) // this is the data which will be sent to the ui - var/data[0] - + var/list/data = list() data["on"] = toggle ? 1 : 0 data["allowPDAs"] = allow_external_PDAs @@ -112,53 +120,46 @@ data["allowNewscasters"] = allow_external_newscasters data["logs"] = logs + return data - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "exonet_node.tmpl", "Exonet Node #157", 400, 400) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) - -// Proc: Topic() -// Parameters: 2 (standard Topic arguments) -// Description: Responds to button presses on the NanoUI interface. -/obj/machinery/exonet_node/Topic(href, href_list) +// Proc: tgui_act() +// Parameters: 2 (standard tgui_act arguments) +// Description: Responds to button presses on the TGUI interface. +/obj/machinery/exonet_node/tgui_act(action, params) if(..()) - return 1 - if(href_list["toggle_power"]) - toggle = !toggle - update_power() - if(!toggle) - var/msg = "[usr.client.key] ([usr]) has turned [src] off, at [x],[y],[z]." - message_admins(msg) - log_game(msg) + return TRUE - if(href_list["toggle_PDA_port"]) - allow_external_PDAs = !allow_external_PDAs + switch(action) + if("toggle_power") + . = TRUE + toggle = !toggle + update_power() + if(!toggle) + var/msg = "[usr.client.key] ([usr]) has turned [src] off, at [x],[y],[z]." + message_admins(msg) + log_game(msg) - if(href_list["toggle_communicator_port"]) - allow_external_communicators = !allow_external_communicators - if(!allow_external_communicators) - var/msg = "[usr.client.key] ([usr]) has turned [src]'s communicator port off, at [x],[y],[z]." - message_admins(msg) - log_game(msg) + if("toggle_PDA_port") + . = TRUE + allow_external_PDAs = !allow_external_PDAs - if(href_list["toggle_newscaster_port"]) - allow_external_newscasters = !allow_external_newscasters - if(!allow_external_newscasters) - var/msg = "[usr.client.key] ([usr]) has turned [src]'s newscaster port off, at [x],[y],[z]." - message_admins(msg) - log_game(msg) + if("toggle_communicator_port") + . = TRUE + allow_external_communicators = !allow_external_communicators + if(!allow_external_communicators) + var/msg = "[usr.client.key] ([usr]) has turned [src]'s communicator port off, at [x],[y],[z]." + message_admins(msg) + log_game(msg) + + if("toggle_newscaster_port") + . = TRUE + allow_external_newscasters = !allow_external_newscasters + if(!allow_external_newscasters) + var/msg = "[usr.client.key] ([usr]) has turned [src]'s newscaster port off, at [x],[y],[z]." + message_admins(msg) + log_game(msg) update_icon() - SSnanoui.update_uis(src) add_fingerprint(usr) // Proc: get_exonet_node() diff --git a/code/game/machinery/fire_alarm.dm b/code/game/machinery/fire_alarm.dm index 388b834e825..3ed93f79b3e 100644 --- a/code/game/machinery/fire_alarm.dm +++ b/code/game/machinery/fire_alarm.dm @@ -27,6 +27,10 @@ FIRE ALARM /obj/machinery/firealarm/alarms_hidden alarms_hidden = TRUE +/obj/machinery/firealarm/examine() + . = ..() + . += "Current security level: [seclevel]" + /obj/machinery/firealarm/Initialize() . = ..() if(z in using_map.contact_levels) @@ -127,81 +131,24 @@ FIRE ALARM if(user.stat || stat & (NOPOWER | BROKEN)) return - user.set_machine(src) - var/area/A = src.loc - var/d1 - var/d2 - if(istype(user, /mob/living/carbon/human) || istype(user, /mob/living/silicon)) - A = A.loc - - if(A.fire) - d1 = text("Reset - Lockdown", src) - else - d1 = text("Alarm - Lockdown", src) - if(timing) - d2 = text("Stop Time Lock", src) - else - d2 = text("Initiate Time Lock", src) - var/second = round(time) % 60 - var/minute = (round(time) - second) / 60 - var/dat = "Fire alarm [d1]\n
The current alert level is: [get_security_level()]

\nTimer System: [d2]
\nTime Left: [(minute ? "[minute]:" : null)][second] - - + +\n
" - user << browse(dat, "window=firealarm") - onclose(user, "firealarm") + add_fingerprint(user) + var/area/A = get_area(src) + if(A.fire) + reset(user) else - A = A.loc - if(A.fire) - d1 = text("[]", src, stars("Reset - Lockdown")) - else - d1 = text("[]", src, stars("Alarm - Lockdown")) - if(timing) - d2 = text("[]", src, stars("Stop Time Lock")) - else - d2 = text("[]", src, stars("Initiate Time Lock")) - var/second = round(time) % 60 - var/minute = (round(time) - second) / 60 - var/dat = "[stars("Fire alarm")] [d1]\n
The current alert level is: [stars(get_security_level())]

\nTimer System: [d2]
\nTime Left: [(minute ? text("[]:", minute) : null)][second] - - + +\n
" - user << browse(dat, "window=firealarm") - onclose(user, "firealarm") - return + alarm(0, user) -/obj/machinery/firealarm/Topic(href, href_list) - ..() - if(usr.stat || stat & (BROKEN | NOPOWER)) - return - - if((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) - if(href_list["reset"]) - reset() - else if(href_list["alarm"]) - alarm() - else if(href_list["time"]) - timing = text2num(href_list["time"]) - last_process = world.timeofday - START_PROCESSING(SSobj, src) - else if(href_list["tp"]) - var/tp = text2num(href_list["tp"]) - time += tp - time = min(max(round(time), 0), 120) - - updateUsrDialog() - - add_fingerprint(usr) - else - usr << browse(null, "window=firealarm") - return - return - -/obj/machinery/firealarm/proc/reset() +/obj/machinery/firealarm/proc/reset(mob/user) if(!(working)) return var/area/area = get_area(src) for(var/obj/machinery/firealarm/FA in area) fire_alarm.clearAlarm(src.loc, FA) update_icon() - return + if(user) + log_game("[user] reset a fire alarm at [COORD(src)]") -/obj/machinery/firealarm/proc/alarm(var/duration = 0) +/obj/machinery/firealarm/proc/alarm(var/duration = 0, mob/user) if(!(working)) return var/area/area = get_area(src) @@ -209,7 +156,8 @@ FIRE ALARM fire_alarm.triggerAlarm(loc, FA, duration, hidden = alarms_hidden) update_icon() playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4) - return + if(user) + log_game("[user] triggered a fire alarm at [COORD(src)]") /obj/machinery/firealarm/proc/set_security_level(var/newlevel) if(seclevel != newlevel) diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm index 17cbfcfe537..601d65a616d 100644 --- a/code/game/machinery/frame.dm +++ b/code/game/machinery/frame.dm @@ -81,6 +81,31 @@ frame_class = FRAME_CLASS_MACHINE frame_size = 4 +/datum/frame/frame_types/oven + name = "Oven" + frame_class = FRAME_CLASS_MACHINE + frame_size = 4 + +/datum/frame/frame_types/fryer + name = "Fryer" + frame_class = FRAME_CLASS_MACHINE + frame_size = 4 + +/datum/frame/frame_types/grill + name = "Grill" + frame_class = FRAME_CLASS_MACHINE + frame_size = 4 + +/datum/frame/frame_types/cerealmaker + name = "Cereal Maker" + frame_class = FRAME_CLASS_MACHINE + frame_size = 4 + +/datum/frame/frame_types/candymachine + name = "Candy Machine" + frame_class = FRAME_CLASS_MACHINE + frame_size = 4 + /datum/frame/frame_types/fax name = "Fax" frame_class = FRAME_CLASS_MACHINE diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index a4654a31a44..0f57b816d06 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -128,7 +128,7 @@ return // If the human is losing too much blood, beep. - if(((T.vessel.get_reagent_amount("blood")/T.species.blood_volume)*100) < BLOOD_VOLUME_SAFE) + if(T.vessel.get_reagent_amount("blood") < T.species.blood_volume*T.species.blood_level_safe) visible_message("\The [src] beeps loudly.") var/datum/reagent/B = T.take_blood(beaker,amount) diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm index 54ea37b5c6a..f08178f03db 100644 --- a/code/game/machinery/jukebox.dm +++ b/code/game/machinery/jukebox.dm @@ -221,7 +221,7 @@ for(var/mob/living/carbon/M in ohearers(6, src)) if(M.get_ear_protection() >= 2) continue - M.sleeping = 0 + M.SetSleeping(0) M.stuttering += 20 M.ear_deaf += 30 M.Weaken(3) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 0d2c4e78e8e..1afa9910f45 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -213,6 +213,13 @@ Class Procs: /obj/machinery/proc/inoperable(var/additional_flags = 0) return (stat & (NOPOWER | BROKEN | additional_flags)) +// Duplicate of below because we don't want to fuck around with CanUseTopic in TGUI +// TODO: Replace this with can_interact from /tg/ +/obj/machinery/tgui_status(mob/user) + if(!interact_offline && (stat & (NOPOWER | BROKEN))) + return STATUS_CLOSE + return ..() + /obj/machinery/CanUseTopic(var/mob/user) if(!interact_offline && (stat & (NOPOWER | BROKEN))) return STATUS_CLOSE diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index 4c4d3ce914e..0d5e42f771a 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -15,69 +15,103 @@ "Fuel" = PIPING_LAYER_FUEL, "Aux" = PIPING_LAYER_AUX ) + var/disposals = FALSE // TODO - Its about time to make this NanoUI don't we think? /obj/machinery/pipedispenser/attack_hand(var/mob/user as mob) if((. = ..())) return - src.interact(user) + tgui_interact(user) -/obj/machinery/pipedispenser/interact(mob/user) - user.set_machine(src) +/obj/machinery/pipedispenser/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/pipes), + ) - var/list/lines = list() - for(var/category in atmos_pipe_recipes) - lines += "[category]:
" - if(category == "Pipes") - for(var/pipename in pipe_layers) - var/pipelayer = pipe_layers[pipename] - lines += "[pipename] " - lines += "
" - for(var/datum/pipe_recipe/PI in atmos_pipe_recipes[category]) - lines += PI.Render(src) - var/dat = lines.Join() - var/datum/browser/popup = new(user, "pipedispenser", name, 300, 800, src) - popup.set_content("[dat]") - popup.open() - return +/obj/machinery/pipedispenser/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PipeDispenser", name) + ui.open() -/obj/machinery/pipedispenser/Topic(href, href_list) +/obj/machinery/pipedispenser/tgui_data(mob/user) + var/list/data = list( + "disposals" = disposals, + "p_layer" = p_layer, + "pipe_layers" = pipe_layers, + ) + + var/list/recipes + if(disposals) + recipes = GLOB.disposal_pipe_recipes + else + recipes = GLOB.atmos_pipe_recipes + + for(var/c in recipes) + var/list/cat = recipes[c] + var/list/r = list() + for(var/i in 1 to cat.len) + var/datum/pipe_recipe/info = cat[i] + r += list(list("pipe_name" = info.name, "ref" = "\ref[info]")) + // Stationary pipe dispensers don't allow you to pre-select pipe directions. + // This makes it impossble to spawn bent versions of bendable pipes. + // We add a "Bent" pipe type with a special param to work around it. + if(info.dirtype == PIPE_BENDABLE) + r += list(list( + "pipe_name" = ("Bent " + info.name), + "ref" = "\ref[info]", + "bent" = TRUE + )) + data["categories"] += list(list("cat_name" = c, "recipes" = r)) + + return data + +/obj/machinery/pipedispenser/tgui_act(action, params) if(..()) - return + return TRUE if(unwrenched || !usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) - usr << browse(null, "window=pipedispenser") - usr.unset_machine(src) - return - usr.set_machine(src) - src.add_fingerprint(usr) - if(href_list["setlayer"]) - var/new_pipe_layer = text2num(href_list["setlayer"]) - if(isnum(new_pipe_layer)) - p_layer = new_pipe_layer - updateDialog() - else if(href_list["makepipe"]) - if(!wait) - var/obj/machinery/atmospherics/p_type = text2path(href_list["makepipe"]) - var/p_dir = text2num(href_list["dir"]) - var/pi_type = initial(p_type.construction_type) - var/obj/item/pipe/P = new pi_type(src.loc, p_type, p_dir) - P.setPipingLayer(p_layer) - P.add_fingerprint(usr) - wait = 1 - spawn(10) - wait = 0 - else if(href_list["makemeter"]) - if(!wait) - new /obj/item/pipe_meter(/*usr.loc*/ src.loc) - wait = 1 - spawn(15) - wait = 0 - return + return TRUE + + . = TRUE + switch(action) + if("p_layer") + p_layer = text2num(params["p_layer"]) + if("dispense_pipe") + if(!wait) + var/datum/pipe_recipe/recipe = locate(params["ref"]) + if(!istype(recipe)) + return + + var/target_dir = NORTH + if(params["bent"]) + target_dir = NORTHEAST + + var/obj/created_object = null + if(istype(recipe, /datum/pipe_recipe/pipe)) + var/datum/pipe_recipe/pipe/R = recipe + created_object = new R.construction_type(loc, recipe.pipe_type, target_dir) + var/obj/item/pipe/P = created_object + P.setPipingLayer(p_layer) + else if(istype(recipe, /datum/pipe_recipe/disposal)) + var/datum/pipe_recipe/disposal/D = recipe + var/obj/structure/disposalconstruct/C = new(loc, D.pipe_type, target_dir, 0, D.subtype ? D.subtype : 0) + C.update() + created_object = C + else if(istype(recipe, /datum/pipe_recipe/meter)) + created_object = new recipe.pipe_type(loc) + else + log_runtime(EXCEPTION("Warning: [usr] attempted to spawn pipe recipe type by params [json_encode(params)] ([recipe] [recipe?.type]), but it was not allowed by this machine ([src] [type])")) + return + + created_object.add_fingerprint(usr) + wait = TRUE + VARSET_IN(src, wait, FALSE, 15) + /obj/machinery/pipedispenser/attackby(var/obj/item/W as obj, var/mob/user as mob) src.add_fingerprint(usr) if (istype(W, /obj/item/pipe) || istype(W, /obj/item/pipe_meter)) - to_chat(usr, "You put [W] back to [src].") + to_chat(usr, "You put [W] back in [src].") user.drop_item() qdel(W) return @@ -117,15 +151,7 @@ icon_state = "pipe_d" density = 1 anchored = 1.0 - -/* -//Allow you to push disposal pipes into it (for those with density 1) -/obj/machinery/pipedispenser/disposal/Crossed(var/obj/structure/disposalconstruct/pipe as obj) - if(istype(pipe) && !pipe.anchored) - qdel(pipe) - -Nah -*/ + disposals = TRUE //Allow you to drag-drop disposal pipes into it /obj/machinery/pipedispenser/disposal/MouseDrop_T(var/obj/structure/disposalconstruct/pipe as obj, mob/usr as mob) @@ -138,43 +164,9 @@ Nah if (pipe.anchored) return + to_chat(usr, "You shove [pipe] back in [src].") qdel(pipe) -/obj/machinery/pipedispenser/disposal/interact(mob/user) - user.set_machine(src) - - var/list/lines = list() - for(var/category in disposal_pipe_recipes) - lines += "[category]:
" - for(var/datum/pipe_recipe/PI in disposal_pipe_recipes[category]) - lines += PI.Render(src) - var/dat = lines.Join() - var/datum/browser/popup = new(user, "pipedispenser", name, 300, 500, src) - popup.set_content("[dat]") - popup.open() - return - -/obj/machinery/pipedispenser/disposal/Topic(href, href_list) - if(href_list["makepipe"] || href_list["setlayer"] || href_list["makemeter"]) // Asking the disposal machine to do atmos stuff? - return // That's a no no. - if((. = ..())) - return - if(href_list["dmake"]) - if(unwrenched || !usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) - usr << browse(null, "window=pipedispenser") - return - if(!wait) - var/ptype = text2num(href_list["dmake"]) - var/pdir = (href_list["dir"] ? text2num(href_list["dir"]) : NORTH) - var/psub = (href_list["sort"] ? text2num(href_list["sort"]) : 0) - var/obj/structure/disposalconstruct/C = new (src.loc, ptype, pdir, 0, psub) - - C.add_fingerprint(usr) - C.update() - wait = 1 - VARSET_IN(src, wait, FALSE, 15) - return - // adding a pipe dispensers that spawn unhooked from the ground /obj/machinery/pipedispenser/orderable anchored = 0 diff --git a/code/game/machinery/pipe/pipe_recipes.dm b/code/game/machinery/pipe/pipe_recipes.dm index 14dbfc2603d..8aee2a19087 100644 --- a/code/game/machinery/pipe/pipe_recipes.dm +++ b/code/game/machinery/pipe/pipe_recipes.dm @@ -2,75 +2,69 @@ // Recipies for Pipe Dispenser and (someday) the RPD // -var/global/list/atmos_pipe_recipes = null -var/global/list/disposal_pipe_recipes = null -var/global/list/all_pipe_recipes = null // VOREStation Add +GLOBAL_LIST_INIT(atmos_pipe_recipes, list( + "Pipes" = list( + new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple), + new /datum/pipe_recipe/pipe("Manifold", /obj/machinery/atmospherics/pipe/manifold), + new /datum/pipe_recipe/pipe("Manual Valve", /obj/machinery/atmospherics/valve), + new /datum/pipe_recipe/pipe("Digital Valve", /obj/machinery/atmospherics/valve/digital), + new /datum/pipe_recipe/pipe("Pipe cap", /obj/machinery/atmospherics/pipe/cap), + new /datum/pipe_recipe/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/manifold4w), + new /datum/pipe_recipe/pipe("Manual T-Valve", /obj/machinery/atmospherics/tvalve), + new /datum/pipe_recipe/pipe("Digital T-Valve", /obj/machinery/atmospherics/tvalve/digital), + new /datum/pipe_recipe/pipe("Upward Pipe", /obj/machinery/atmospherics/pipe/zpipe/up), + new /datum/pipe_recipe/pipe("Downward Pipe", /obj/machinery/atmospherics/pipe/zpipe/down), + new /datum/pipe_recipe/pipe("Universal Pipe Adaptor",/obj/machinery/atmospherics/pipe/simple/visible/universal), + ), + "Devices" = list( + new /datum/pipe_recipe/pipe("Connector", /obj/machinery/atmospherics/portables_connector), + new /datum/pipe_recipe/pipe("Unary Vent", /obj/machinery/atmospherics/unary/vent_pump), + new /datum/pipe_recipe/pipe("Aux Vent", /obj/machinery/atmospherics/unary/vent_pump/aux), + new /datum/pipe_recipe/pipe("Passive Vent", /obj/machinery/atmospherics/pipe/vent), + new /datum/pipe_recipe/pipe("Injector", /obj/machinery/atmospherics/unary/outlet_injector), + new /datum/pipe_recipe/pipe("Gas Pump", /obj/machinery/atmospherics/binary/pump), + new /datum/pipe_recipe/pipe("Fuel Pump", /obj/machinery/atmospherics/binary/pump/fuel), + new /datum/pipe_recipe/pipe("Aux Pump", /obj/machinery/atmospherics/binary/pump/aux), + new /datum/pipe_recipe/pipe("Pressure Regulator", /obj/machinery/atmospherics/binary/passive_gate), + new /datum/pipe_recipe/pipe("High Power Gas Pump", /obj/machinery/atmospherics/binary/pump/high_power), + new /datum/pipe_recipe/pipe("Automatic Shutoff Valve",/obj/machinery/atmospherics/valve/shutoff), + new /datum/pipe_recipe/pipe("Scrubber", /obj/machinery/atmospherics/unary/vent_scrubber), + new /datum/pipe_recipe/meter("Meter"), + new /datum/pipe_recipe/pipe("Gas Filter", /obj/machinery/atmospherics/trinary/atmos_filter), + new /datum/pipe_recipe/pipe("Gas Mixer", /obj/machinery/atmospherics/trinary/mixer), + new /datum/pipe_recipe/pipe("Gas Mixer 'T'", /obj/machinery/atmospherics/trinary/mixer/t_mixer), + new /datum/pipe_recipe/pipe("Omni Gas Mixer", /obj/machinery/atmospherics/omni/mixer), + new /datum/pipe_recipe/pipe("Omni Gas Filter", /obj/machinery/atmospherics/omni/atmos_filter), + ), + "Heat Exchange" = list( + new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/heat_exchanging), + new /datum/pipe_recipe/pipe("Junction", /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction), + new /datum/pipe_recipe/pipe("Heat Exchanger", /obj/machinery/atmospherics/unary/heat_exchanger), + ), + "Insulated pipes" = list( + new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/insulated), + ) +)) -/hook/startup/proc/init_pipe_recipes() - global.atmos_pipe_recipes = list( - "Pipes" = list( - new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple), - new /datum/pipe_recipe/pipe("Manifold", /obj/machinery/atmospherics/pipe/manifold), - new /datum/pipe_recipe/pipe("Manual Valve", /obj/machinery/atmospherics/valve), - new /datum/pipe_recipe/pipe("Digital Valve", /obj/machinery/atmospherics/valve/digital), - new /datum/pipe_recipe/pipe("Pipe cap", /obj/machinery/atmospherics/pipe/cap), - new /datum/pipe_recipe/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/manifold4w), - new /datum/pipe_recipe/pipe("Manual T-Valve", /obj/machinery/atmospherics/tvalve), - new /datum/pipe_recipe/pipe("Digital T-Valve", /obj/machinery/atmospherics/tvalve/digital), - new /datum/pipe_recipe/pipe("Upward Pipe", /obj/machinery/atmospherics/pipe/zpipe/up), - new /datum/pipe_recipe/pipe("Downward Pipe", /obj/machinery/atmospherics/pipe/zpipe/down), - new /datum/pipe_recipe/pipe("Universal Pipe Adaptor",/obj/machinery/atmospherics/pipe/simple/visible/universal), - ), - "Devices" = list( - new /datum/pipe_recipe/pipe("Connector", /obj/machinery/atmospherics/portables_connector), - new /datum/pipe_recipe/pipe("Unary Vent", /obj/machinery/atmospherics/unary/vent_pump), - new /datum/pipe_recipe/pipe("Aux Vent", /obj/machinery/atmospherics/unary/vent_pump/aux), - new /datum/pipe_recipe/pipe("Passive Vent", /obj/machinery/atmospherics/pipe/vent), - new /datum/pipe_recipe/pipe("Injector", /obj/machinery/atmospherics/unary/outlet_injector), - new /datum/pipe_recipe/pipe("Gas Pump", /obj/machinery/atmospherics/binary/pump), - new /datum/pipe_recipe/pipe("Fuel Pump", /obj/machinery/atmospherics/binary/pump/fuel), - new /datum/pipe_recipe/pipe("Aux Pump", /obj/machinery/atmospherics/binary/pump/aux), - new /datum/pipe_recipe/pipe("Pressure Regulator", /obj/machinery/atmospherics/binary/passive_gate), - new /datum/pipe_recipe/pipe("High Power Gas Pump", /obj/machinery/atmospherics/binary/pump/high_power), - new /datum/pipe_recipe/pipe("Automatic Shutoff Valve",/obj/machinery/atmospherics/valve/shutoff), - new /datum/pipe_recipe/pipe("Scrubber", /obj/machinery/atmospherics/unary/vent_scrubber), - new /datum/pipe_recipe/meter("Meter"), - new /datum/pipe_recipe/pipe("Gas Filter", /obj/machinery/atmospherics/trinary/atmos_filter), - new /datum/pipe_recipe/pipe("Gas Mixer", /obj/machinery/atmospherics/trinary/mixer), - new /datum/pipe_recipe/pipe("Gas Mixer 'T'", /obj/machinery/atmospherics/trinary/mixer/t_mixer), - new /datum/pipe_recipe/pipe("Omni Gas Mixer", /obj/machinery/atmospherics/omni/mixer), - new /datum/pipe_recipe/pipe("Omni Gas Filter", /obj/machinery/atmospherics/omni/atmos_filter), - ), - "Heat Exchange" = list( - new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/heat_exchanging), - new /datum/pipe_recipe/pipe("Junction", /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction), - new /datum/pipe_recipe/pipe("Heat Exchanger", /obj/machinery/atmospherics/unary/heat_exchanger), - ), - "Insulated pipes" = list( - new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/insulated), - ) +GLOBAL_LIST_INIT(disposal_pipe_recipes, list( + "Disposal Pipes" = list( + new /datum/pipe_recipe/disposal("Pipe", DISPOSAL_PIPE_STRAIGHT, "conpipe-s", PIPE_STRAIGHT), + new /datum/pipe_recipe/disposal("Bent Pipe", DISPOSAL_PIPE_CORNER, "conpipe-c"), + new /datum/pipe_recipe/disposal("Junction", DISPOSAL_PIPE_JUNCTION, "conpipe-j1", PIPE_TRIN_M), + new /datum/pipe_recipe/disposal("Y-Junction", DISPOSAL_PIPE_JUNCTION_Y, "conpipe-y"), + new /datum/pipe_recipe/disposal("Sort Junction", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_NORMAL), + new /datum/pipe_recipe/disposal("Sort Junction (Wildcard)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_WILDCARD), + new /datum/pipe_recipe/disposal("Sort Junction (Untagged)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_UNTAGGED), + new /datum/pipe_recipe/disposal("Tagger", DISPOSAL_PIPE_TAGGER, "pipe-tagger", PIPE_STRAIGHT), + new /datum/pipe_recipe/disposal("Tagger (Partial)", DISPOSAL_PIPE_TAGGER_PARTIAL, "pipe-tagger-partial", PIPE_STRAIGHT), + new /datum/pipe_recipe/disposal("Trunk", DISPOSAL_PIPE_TRUNK, "conpipe-t"), + new /datum/pipe_recipe/disposal("Upwards", DISPOSAL_PIPE_UPWARD, "pipe-u"), + new /datum/pipe_recipe/disposal("Downwards", DISPOSAL_PIPE_DOWNWARD, "pipe-d"), + new /datum/pipe_recipe/disposal("Bin", DISPOSAL_PIPE_BIN, "disposal", PIPE_ONEDIR), + new /datum/pipe_recipe/disposal("Outlet", DISPOSAL_PIPE_OUTLET, "outlet"), + new /datum/pipe_recipe/disposal("Chute", DISPOSAL_PIPE_CHUTE, "intake"), ) - global.disposal_pipe_recipes = list( - "Disposal Pipes" = list( - new /datum/pipe_recipe/disposal("Pipe", DISPOSAL_PIPE_STRAIGHT, "conpipe-s", PIPE_STRAIGHT), - new /datum/pipe_recipe/disposal("Bent Pipe", DISPOSAL_PIPE_CORNER, "conpipe-c"), - new /datum/pipe_recipe/disposal("Junction", DISPOSAL_PIPE_JUNCTION, "conpipe-j1", PIPE_TRIN_M), - new /datum/pipe_recipe/disposal("Y-Junction", DISPOSAL_PIPE_JUNCTION_Y, "conpipe-y"), - new /datum/pipe_recipe/disposal("Sort Junction", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_NORMAL), - new /datum/pipe_recipe/disposal("Sort Junction (Wildcard)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_WILDCARD), - new /datum/pipe_recipe/disposal("Sort Junction (Untagged)", DISPOSAL_PIPE_SORTER, "conpipe-j1s", PIPE_TRIN_M, DISPOSAL_SORT_UNTAGGED), - new /datum/pipe_recipe/disposal("Tagger", DISPOSAL_PIPE_TAGGER, "pipe-tagger", PIPE_STRAIGHT), - new /datum/pipe_recipe/disposal("Tagger (Partial)", DISPOSAL_PIPE_TAGGER_PARTIAL, "pipe-tagger-partial", PIPE_STRAIGHT), - new /datum/pipe_recipe/disposal("Trunk", DISPOSAL_PIPE_TRUNK, "conpipe-t"), - new /datum/pipe_recipe/disposal("Upwards", DISPOSAL_PIPE_UPWARD, "pipe-u"), - new /datum/pipe_recipe/disposal("Downwards", DISPOSAL_PIPE_DOWNWARD, "pipe-d"), - new /datum/pipe_recipe/disposal("Bin", DISPOSAL_PIPE_BIN, "disposal", PIPE_ONEDIR), - new /datum/pipe_recipe/disposal("Outlet", DISPOSAL_PIPE_OUTLET, "outlet"), - new /datum/pipe_recipe/disposal("Chute", DISPOSAL_PIPE_CHUTE, "intake"), - ) - ) - global.all_pipe_recipes = disposal_pipe_recipes + atmos_pipe_recipes // VOREStation Add - return TRUE +)) // // New method of handling pipe construction. Instead of numeric constants and a giant switch statement of doom @@ -83,21 +77,53 @@ var/global/list/all_pipe_recipes = null // VOREStation Add var/icon_state = null // This tells the RPD what kind of pipe icon to render for the preview. var/icon_state_m = null // This stores the mirrored version of the regular state (if available). var/dirtype // If using an RPD, this tells more about what previews to show. + var/pipe_type -// Render an HTML link to select this pipe type. Returns text. -/datum/pipe_recipe/proc/Render(dispenser) - return "[name]
" +// Get preview for UIs +/datum/pipe_recipe/proc/get_preview(selected_dir) + var/list/dirs + switch(dirtype) + if(PIPE_STRAIGHT, PIPE_BENDABLE) + dirs = list("[NORTH]" = "Vertical", "[EAST]" = "Horizontal") + if(dirtype == PIPE_BENDABLE) + dirs += list("[NORTHWEST]" = "West to North", "[NORTHEAST]" = "North to East", + "[SOUTHWEST]" = "South to West", "[SOUTHEAST]" = "East to South") + if(PIPE_TRINARY) + dirs = list("[NORTH]" = "West South East", "[SOUTH]" = "East North West", + "[EAST]" = "North West South", "[WEST]" = "South East North") + if(PIPE_TRIN_M) + dirs = list("[NORTH]" = "North East South", "[SOUTHWEST]" = "North West South", + "[NORTHEAST]" = "South East North", "[SOUTH]" = "South West North", + "[WEST]" = "West North East", "[SOUTHEAST]" = "West South East", + "[NORTHWEST]" = "East North West", "[EAST]" = "East South West",) + if(PIPE_DIRECTIONAL) + dirs = list("[NORTH]" = "North", "[SOUTH]" = "South", "[WEST]" = "West", "[EAST]" = "East") + if(PIPE_ONEDIR) + dirs = list("[SOUTH]" = name) + if(PIPE_UNARY_FLIPPABLE) + dirs = list("[NORTH]" = "North", "[EAST]" = "East", "[SOUTH]" = "South", "[WEST]" = "West", + "[NORTHEAST]" = "North Flipped", "[SOUTHEAST]" = "East Flipped", "[SOUTHWEST]" = "South Flipped", "[NORTHWEST]" = "West Flipped") -// Parameters for the Topic link returned by Render(). Returns text. -/datum/pipe_recipe/proc/Params() - return "" + + var/list/rows = list() + var/list/row = list("previews" = list()) + var/i = 0 + for(var/dir in dirs) + var/numdir = text2num(dir) + var/flipped = ((dirtype == PIPE_TRIN_M) || (dirtype == PIPE_UNARY_FLIPPABLE)) && (numdir in GLOB.cornerdirs) + row["previews"] += list(list("selected" = (numdir == selected_dir), "dir" = dir2text(numdir), "dir_name" = dirs[dir], "icon_state" = icon_state, "flipped" = flipped)) + if(i++ || dirtype == PIPE_ONEDIR) + rows += list(row) + row = list("previews" = list()) + i = 0 + + return rows // // Subtype for actual pipes // /datum/pipe_recipe/pipe var/obj/item/pipe/construction_type // The type PATH to the type of pipe fitting object the recipe makes. - var/obj/machinery/atmospherics/pipe_type // The type PATH of what actual pipe the fitting becomes. var/paintable = FALSE // If TRUE, allow the RPD to paint this pipe. // VOREStation Add /datum/pipe_recipe/pipe/New(var/label, var/obj/machinery/atmospherics/path) @@ -110,18 +136,6 @@ var/global/list/all_pipe_recipes = null // VOREStation Add icon_state_m = "[icon_state]m" paintable = ispath(path, /obj/machinery/atmospherics/pipe) && !(ispath(path, /obj/machinery/atmospherics/pipe/vent)) // VOREStation Add -// Render an HTML link to select this pipe type -/datum/pipe_recipe/pipe/Render(dispenser) - var/dat = ..(dispenser) - // Stationary pipe dispensers don't allow you to pre-select pipe directions. - // This makes it impossble to spawn bent versions of bendable pipes. - // We add a "Bent" pipe type with a preset diagonal direction to work around it. - if(istype(dispenser, /obj/machinery/pipedispenser) && (dirtype == PIPE_BENDABLE)) - dat += "Bent [name]
" - return dat - -/datum/pipe_recipe/pipe/Params() - return "makepipe=[pipe_type]" // // Subtype for meters @@ -129,18 +143,15 @@ var/global/list/all_pipe_recipes = null // VOREStation Add /datum/pipe_recipe/meter dirtype = PIPE_ONEDIR icon_state = "meter" + pipe_type = /obj/item/pipe_meter /datum/pipe_recipe/meter/New(label) name = label -/datum/pipe_recipe/meter/Params() - return "makemeter=1" - // // Subtype for disposal pipes // /datum/pipe_recipe/disposal - var/pipe_type // pipe_type is one of the DISPOSAL_PIPE_ ptype constants. var/subtype // subtype is one of the DISPOSAL_SORT_ constants. /datum/pipe_recipe/disposal/New(var/label, var/ptype, var/state, dt=PIPE_DIRECTIONAL, var/sort=0) @@ -151,9 +162,3 @@ var/global/list/all_pipe_recipes = null // VOREStation Add subtype = sort if (dirtype == PIPE_TRIN_M) icon_state_m = replacetext(state, "j1", "j2") - -/datum/pipe_recipe/disposal/Params() - var/param = "dmake=[pipe_type]" - if (subtype) - param += "&sort=[subtype]" - return param diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index c307017d8a4..1ed44c61bcc 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -822,6 +822,7 @@ var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc) flick_holder.layer = layer + 0.1 flick("popup_[turret_type]", flick_holder) + playsound(src, 'sound/machines/turrets/turret_deploy.ogg', 100, 1) sleep(10) qdel(flick_holder) @@ -843,6 +844,7 @@ var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc) flick_holder.layer = layer + 0.1 flick("popdown_[turret_type]", flick_holder) + playsound(src, 'sound/machines/turrets/turret_retract.ogg', 100, 1) sleep(10) qdel(flick_holder) @@ -863,6 +865,7 @@ spawn() popUp() //pop the turret up if it's not already up. set_dir(get_dir(src, target)) //even if you can't shoot, follow the target + playsound(src, 'sound/machines/turrets/turret_rotate.ogg', 100, 1) // Play rotating sound spawn() shootAt(target) return 1 diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 77a35d2829d..54aac0a5ffb 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -11,6 +11,7 @@ var/set_temperature = T0C + 20 //K var/heating_power = 40000 clicksound = "switch" + interact_offline = TRUE /obj/machinery/space_heater/New() ..() @@ -88,75 +89,74 @@ interact(user) /obj/machinery/space_heater/interact(mob/user as mob) - if(panel_open) - - var/dat - dat = "Power cell: " - if(cell) - dat += "Installed
" - else - dat += "Removed
" - - dat += "Power Level: [cell ? round(cell.percent(),1) : 0]%

" - - dat += "Set Temperature: " - - dat += "-" - - dat += " [set_temperature]K ([set_temperature-T0C]°C)" - dat += "+
" - - user.set_machine(src) - user << browse("Space Heater Control Panel[dat]", "window=spaceheater") - onclose(user, "spaceheater") + tgui_interact(user) else on = !on user.visible_message("[user] switches [on ? "on" : "off"] the [src].","You switch [on ? "on" : "off"] the [src].") update_icon() return +/obj/machinery/space_heater/tgui_state(mob/user) + return GLOB.tgui_physical_state -/obj/machinery/space_heater/Topic(href, href_list) - if(usr.stat) - return - if((in_range(src, usr) && istype(src.loc, /turf)) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) +/obj/machinery/space_heater/tgui_status(mob/user) + if(!panel_open) + return STATUS_CLOSE + return ..() - switch(href_list["op"]) +/obj/machinery/space_heater/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SpaceHeater", name) + ui.open() - if("temp") - var/value = text2num(href_list["val"]) +/obj/machinery/space_heater/tgui_data(mob/user) + var/list/data = list() - // limit to 0-90 degC - set_temperature = dd_range(T0C, T0C + 90, set_temperature + value) + data["cell"] = !!cell + data["power"] = round(cell?.percent(), 1) + data["temp"] = set_temperature + data["minTemp"] = T0C + data["maxTemp"] = T0C + 90 - if("cellremove") - if(panel_open && cell && !usr.get_active_hand()) - usr.visible_message("\The [usr] removes \the [cell] from \the [src].", "You remove \the [cell] from \the [src].") - cell.update_icon() - usr.put_in_hands(cell) - cell.add_fingerprint(usr) - cell = null + return data + +/obj/machinery/space_heater/tgui_act(action, params) + if(..()) + return TRUE + + if(!panel_open) + return FALSE + + switch(action) + if("temp") + // limit to 0-90 degC + set_temperature = clamp(text2num(params["newtemp"]), T0C, T0C + 90) + . = TRUE + + if("cellremove") + if(cell && !usr.get_active_hand()) + usr.visible_message("[usr] removes [cell] from [src].", "You remove [cell] from [src].") + cell.update_icon() + usr.put_in_hands(cell) + cell.add_fingerprint(usr) + cell = null + power_change() + . = TRUE + + + if("cellinstall") + if(!cell) + var/obj/item/weapon/cell/C = usr.get_active_hand() + if(istype(C)) + usr.drop_item() + cell = C + C.loc = src + C.add_fingerprint(usr) power_change() - - - if("cellinstall") - if(panel_open && !cell) - var/obj/item/weapon/cell/C = usr.get_active_hand() - if(istype(C)) - usr.drop_item() - cell = C - C.loc = src - C.add_fingerprint(usr) - power_change() - usr.visible_message("[usr] inserts \the [C] into \the [src].", "You insert \the [C] into \the [src].") - - updateDialog() - else - usr << browse(null, "window=spaceheater") - usr.unset_machine() - return + usr.visible_message("[usr] inserts \the [C] into \the [src].", "You insert \the [C] into \the [src].") + . = TRUE /obj/machinery/space_heater/process() if(on) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 718b71b6443..63048200878 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -83,114 +83,93 @@ return return -/obj/machinery/suit_storage_unit/attack_hand(mob/user as mob) - var/dat +/obj/machinery/suit_storage_unit/attack_hand(mob/user) if(..()) return if(stat & NOPOWER) return if(!user.IsAdvancedToolUser()) return 0 - if(panelopen) //The maintenance panel is open. Time for some shady stuff - dat+= "Suit storage unit: Maintenance panel" - dat+= "Maintenance panel controls
" - dat+= "The panel is ridden with controls, button and meters, labeled in strange signs and symbols that
you cannot understand. Probably the manufactoring world's language.
Among other things, a few controls catch your eye.


" - dat+= text("A small dial with a small lambda symbol on it. It's pointing towards a gauge that reads [].
Turn towards []
",(issuperUV ? "15nm" : "185nm"),src,(issuperUV ? "185nm" : "15nm")) - dat+= text("A thick old-style button, with 2 grimy LED lights next to it. The [] LED is on.
Press button",(safetieson? "GREEN" : "RED"),src) - dat+= text("

Close panel", user) - //user << browse(dat, "window=ssu_m_panel;size=400x500") - //onclose(user, "ssu_m_panel") - else if(isUV) //The thing is running its cauterisation cycle. You have to wait. - dat += "Suit storage unit" - dat+= "Unit is cauterising contents with selected UV ray intensity. Please wait.
" - //dat+= "Cycle end in: [cycletimeleft()] seconds. " - //user << browse(dat, "window=ssu_cycling_panel;size=400x500") - //onclose(user, "ssu_cycling_panel") + tgui_interact(user) +/obj/machinery/suit_storage_unit/tgui_state(mob/user) + return GLOB.tgui_notcontained_state + +/obj/machinery/suit_storage_unit/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SuitStorageUnit", name) + ui.open() + +/obj/machinery/suit_storage_unit/tgui_data() + var/list/data = list() + + data["broken"] = isbroken + data["panelopen"] = panelopen + + data["locked"] = islocked + data["open"] = isopen + data["safeties"] = safetieson + data["uv_active"] = isUV + data["uv_super"] = issuperUV + if(HELMET) + data["helmet"] = HELMET.name else - if(!isbroken) - dat+= "Suit storage unit" - dat+= "U-Stor-It Suit Storage Unit, model DS1900
" - dat+= "Welcome to the Unit control panel.

" - dat+= text("Helmet storage compartment: []
",(HELMET ? HELMET.name : "No helmet detected.")) - if(HELMET && isopen) - dat+=text("Dispense helmet
",src) - dat+= text("Suit storage compartment: []
",(SUIT ? SUIT.name : "
No exosuit detected.")) - if(SUIT && isopen) - dat+=text("Dispense suit
",src) - dat+= text("Breathmask storage compartment: []
",(MASK ? MASK.name : "
No breathmask detected.")) - if(MASK && isopen) - dat+=text("Dispense mask
",src) - if(OCCUPANT) - dat+= "
WARNING: Biological entity detected inside the Unit's storage. Please remove.
" - dat+= "Eject extra load" - dat+= text("
Unit is: [] - [] Unit ",(isopen ? "Open" : "Closed"),src,(isopen ? "Close" : "Open")) - if(isopen) - dat+="
" - else - dat+= text(" - *[] Unit*
",src,(islocked ? "Unlock" : "Lock")) - dat+= text("Unit status: []",(islocked? "**LOCKED**
" : "**UNLOCKED**
")) - dat+= text("Start Disinfection cycle
",src) - dat += text("

Close control panel", user) - //user << browse(dat, "window=Suit Storage Unit;size=400x500") - //onclose(user, "Suit Storage Unit") - else //Ohhhh shit it's dirty or broken! Let's inform the guy. - dat+= "Suit storage unit" - dat+= "Unit chamber is too contaminated to continue usage. Please call for a qualified individual to perform maintenance.

" - dat+= text("
Close control panel", user) - //user << browse(dat, "window=suit_storage_unit;size=400x500") - //onclose(user, "suit_storage_unit") + data["helmet"] = null + if(SUIT) + data["suit"] = SUIT.name + else + data["suit"] = null + if(MASK) + data["mask"] = MASK.name + else + data["mask"] = null + data["storage"] = null + if(OCCUPANT) + data["occupied"] = TRUE + else + data["occupied"] = FALSE + return data - user << browse(dat, "window=suit_storage_unit;size=400x500") - onclose(user, "suit_storage_unit") - return +/obj/machinery/suit_storage_unit/tgui_act(action, params) //I fucking HATE this proc + if(..() || isUV || isbroken) + return TRUE - -/obj/machinery/suit_storage_unit/Topic(href, href_list) //I fucking HATE this proc - if(..()) - return - if((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai))) - usr.set_machine(src) - if(href_list["toggleUV"]) - toggleUV(usr) - updateUsrDialog() - update_icon() - if(href_list["togglesafeties"]) - togglesafeties(usr) - updateUsrDialog() - update_icon() - if(href_list["dispense_helmet"]) - dispense_helmet(usr) - updateUsrDialog() - update_icon() - if(href_list["dispense_suit"]) - dispense_suit(usr) - updateUsrDialog() - update_icon() - if(href_list["dispense_mask"]) - dispense_mask(usr) - updateUsrDialog() - update_icon() - if(href_list["toggle_open"]) + switch(action) + if("door") toggle_open(usr) - updateUsrDialog() - update_icon() - if(href_list["toggle_lock"]) - toggle_lock(usr) - updateUsrDialog() - update_icon() - if(href_list["start_UV"]) + . = TRUE + if("dispense") + switch(params["item"]) + if("helmet") + dispense_helmet(usr) + if("mask") + dispense_mask(usr) + if("suit") + dispense_suit(usr) + . = TRUE + if("uv") start_UV(usr) - updateUsrDialog() - update_icon() - if(href_list["eject_guy"]) + . = TRUE + if("lock") + toggle_lock(usr) + . = TRUE + if("eject_guy") eject_occupant(usr) - updateUsrDialog() - update_icon() - /*if(href_list["refresh"]) - updateUsrDialog()*/ + . = TRUE + + // Panel Open stuff + if(!. && panelopen) + switch(action) + if("toggleUV") + toggleUV(usr) + . = TRUE + if("togglesafeties") + togglesafeties(usr) + . = TRUE + + update_icon() add_fingerprint(usr) - return /obj/machinery/suit_storage_unit/proc/toggleUV(mob/user as mob) @@ -847,9 +826,7 @@ return 1 /obj/machinery/suit_cycler/attack_hand(mob/user as mob) - add_fingerprint(user) - if(..() || stat & (BROKEN|NOPOWER)) return @@ -860,116 +837,134 @@ if(shock(user, 100)) return - user.set_machine(src) + tgui_interact(user) - var/dat = "Suit Cycler Interface" +/obj/machinery/suit_cycler/tgui_state(mob/user) + return GLOB.tgui_notcontained_state - if(active) - dat+= "
The [model_text ? "[model_text] " : ""]suit cycler is currently in use. Please wait..." +/obj/machinery/suit_cycler/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SuitCycler", name) + ui.open() - else if(locked) - dat += "
The [model_text ? "[model_text] " : ""]suit cycler is currently locked. Please contact your system administrator." - if(allowed(user)) - dat += "
\[unlock unit\]" +/obj/machinery/suit_cycler/tgui_data(mob/user) + var/list/data = list() + + data["departments"] = departments + data["species"] = species + data["model_text"] = model_text + data["can_repair"] = can_repair + data["userHasAccess"] = allowed(user) + + data["locked"] = locked + data["active"] = active + data["safeties"] = safeties + data["uv_active"] = (active && irradiating > 0) + data["uv_level"] = radiation_level + data["max_uv_level"] = emagged ? 5 : 3 + if(helmet) + data["helmet"] = helmet.name else - dat += "

Suit cycler

" - dat += "Welcome to the [model_text ? "[model_text] " : ""]suit cycler control panel. \[lock unit\]
" + data["helmet"] = null + if(suit) + data["suit"] = suit.name + if(istype(suit) && can_repair) + data["damage"] = suit.damage + else + data["suit"] = null + data["damage"] = null + if(occupant) + data["occupied"] = TRUE + else + data["occupied"] = FALSE - dat += "

Maintenance

" - dat += "Helmet: [helmet ? "\the [helmet]" : "no helmet stored" ]. \[eject\]
" - dat += "Suit: [suit ? "\the [suit]" : "no suit stored" ]. \[eject\]" + return data - if(can_repair && suit && istype(suit)) - dat += "[(suit.damage ? " \[repair\]" : "")]" +/obj/machinery/suit_cycler/tgui_act(action, params) + if(..()) + return TRUE - dat += "
UV decontamination systems: SYSTEM ERROR" : "green'>READY"]
" - dat += "Output level: [radiation_level]
" - dat += "\[select power level\] \[begin decontamination cycle\]

" + switch(action) + if("dispense") + switch(params["item"]) + if("helmet") + helmet.forceMove(get_turf(src)) + helmet = null + if("suit") + suit.forceMove(get_turf(src)) + suit = null + . = TRUE + + if("department") + var/choice = params["department"] + if(choice in departments) + target_department = choice + . = TRUE + + if("species") + var/choice = params["species"] + if(choice in species) + target_species = choice + . = TRUE + + if("radlevel") + radiation_level = clamp(params["radlevel"], 1, emagged ? 5 : 3) + . = TRUE + + if("repair_suit") + if(!suit || !can_repair) + return + active = 1 + spawn(100) + repair_suit() + finished_job() + . = TRUE - dat += "

Customisation

" - dat += "Target product: [target_department], [target_species]." - dat += "
\[apply customisation routine\]


" + if("apply_paintjob") + if(!suit && !helmet) + return + active = 1 + spawn(100) + apply_paintjob() + finished_job() + . = TRUE - if(panel_open) - wires.Interact(user) + if("lock") + if(allowed(usr)) + locked = !locked + to_chat(usr, "You [locked ? "" : "un"]lock \the [src].") + else + to_chat(usr, "Access denied.") + . = TRUE - user << browse(dat, "window=suit_cycler") - onclose(user, "suit_cycler") - return + if("eject_guy") + eject_occupant(usr) + . = TRUE -/obj/machinery/suit_cycler/Topic(href, href_list) - if(href_list["eject_suit"]) - if(!suit) return - suit.loc = get_turf(src) - suit = null - else if(href_list["eject_helmet"]) - if(!helmet) return - helmet.loc = get_turf(src) - helmet = null - else if(href_list["select_department"]) - var/choice = input("Please select the target department paintjob.","Suit cycler",null) as null|anything in departments - if(choice) target_department = choice - else if(href_list["select_species"]) - var/choice = input("Please select the target species configuration.","Suit cycler",null) as null|anything in species - if(choice) target_species = choice - else if(href_list["select_rad_level"]) - var/choices = list(1,2,3) - if(emagged) - choices = list(1,2,3,4,5) - radiation_level = input("Please select the desired radiation level.","Suit cycler",null) as null|anything in choices - else if(href_list["repair_suit"]) + if("uv") + if(safeties && occupant) + to_chat(usr, "The cycler has detected an occupant. Please remove the occupant before commencing the decontamination cycle.") + return - if(!suit || !can_repair) return - active = 1 - spawn(100) - repair_suit() - finished_job() + active = 1 + irradiating = 10 - else if(href_list["apply_paintjob"]) + sleep(10) - if(!suit && !helmet) return - active = 1 - spawn(100) - apply_paintjob() - finished_job() + if(helmet) + if(radiation_level > 2) + helmet.decontaminate() + if(radiation_level > 1) + helmet.clean_blood() - else if(href_list["toggle_safties"]) - safeties = !safeties + if(suit) + if(radiation_level > 2) + suit.decontaminate() + if(radiation_level > 1) + suit.clean_blood() - else if(href_list["toggle_lock"]) - - if(allowed(usr)) - locked = !locked - to_chat(usr, "You [locked ? "" : "un"]lock \the [src].") - else - to_chat(usr, "Access denied.") - - else if(href_list["begin_decontamination"]) - - if(safeties && occupant) - to_chat(usr, "The cycler has detected an occupant. Please remove the occupant before commencing the decontamination cycle.") - return - - active = 1 - irradiating = 10 - updateUsrDialog() - - sleep(10) - - if(helmet) - if(radiation_level > 2) - helmet.decontaminate() - if(radiation_level > 1) - helmet.clean_blood() - - if(suit) - if(radiation_level > 2) - suit.decontaminate() - if(radiation_level > 1) - suit.clean_blood() - - updateUsrDialog() - return + . = TRUE /obj/machinery/suit_cycler/process() diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm index 8cd1d8811e3..b5dd077efa0 100644 --- a/code/game/machinery/telecomms/logbrowser.dm +++ b/code/game/machinery/telecomms/logbrowser.dm @@ -8,187 +8,138 @@ desc = "View communication logs here. Translation not guaranteed." icon_screen = "comm_logs" - var/screen = 0 // the screen number: var/list/servers = list() // the servers located by the computer var/obj/machinery/telecomms/server/SelectedServer circuit = /obj/item/weapon/circuitboard/comm_server var/network = "NULL" // the network to probe - var/temp = "" // temporary feedback messages + var/list/temp = null // temporary feedback messages var/universal_translate = 0 // set to 1 if it can translate nonhuman speech req_access = list(access_tcomsat) - attack_hand(mob/user as mob) - if(stat & (BROKEN|NOPOWER)) - return - user.set_machine(src) - var/dat = "Telecommunication Server Monitor
Telecommunications Server Monitor
" +/obj/machinery/computer/telecomms/server/tgui_data(mob/user) + var/list/data = list() - switch(screen) + data["universal_translate"] = universal_translate + data["network"] = network + data["temp"] = temp + data["servers"] = list() + for(var/obj/machinery/telecomms/T in servers) + data["servers"].Add(list(list( + "id" = T.id, + "name" = T.name, + ))) - // --- Main Menu --- + data["selectedServer"] = null + if(SelectedServer) + data["selectedServer"] = list( + "id" = SelectedServer.id, + "totalTraffic" = SelectedServer.totaltraffic, + "logs" = list() + ) - if(0) - dat += "
[temp]
" - dat += "
Current Network: [network]
" - if(servers.len) - dat += "
Detected Telecommunication Servers:
    " - for(var/obj/machinery/telecomms/T in servers) - dat += "
  • \ref[T] [T.name] ([T.id])
  • " - dat += "
" - dat += "
\[Flush Buffer\]" + var/i = 0 + for(var/c in SelectedServer.log_entries) + i++ + var/datum/comm_log_entry/C = c + + // This is necessary to prevent leaking information to the clientside + var/static/list/acceptable_params = list("uspeech", "intelligible", "message", "name", "race", "job", "timecode") + var/list/parameters = list() + for(var/log_param in acceptable_params) + parameters["[log_param]"] = C.parameters["[log_param]"] - else - dat += "
No servers detected. Scan for servers: \[Scan\]" + data["selectedServer"]["logs"].Add(list(list( + "name" = C.name, + "input_type" = C.input_type, + "id" = i, + "parameters" = parameters, + ))) + return data - // --- Viewing Server --- - - if(1) - dat += "
[temp]
" - dat += "
\[Main Menu\] \[Refresh\]
" - dat += "
Current Network: [network]" - dat += "
Selected Server: [SelectedServer.id]" - - if(SelectedServer.totaltraffic >= 1024) - dat += "
Total recorded traffic: [round(SelectedServer.totaltraffic / 1024)] Terrabytes

" - else - dat += "
Total recorded traffic: [SelectedServer.totaltraffic] Gigabytes

" - - dat += "Stored Logs:
    " - - var/i = 0 - for(var/datum/comm_log_entry/C in SelectedServer.log_entries) - i++ - - - // If the log is a speech file - if(C.input_type == "Speech File") - - dat += "
  1. [C.name] \[X\]
    " - - // -- Determine race of orator -- - - var/race = C.parameters["race"] // The actual race of the mob - var/language = C.parameters["language"] // The language spoken, or null/"" - - // -- If the orator is a human, or universal translate is active, OR mob has universal speech on -- - - if(universal_translate || C.parameters["uspeech"] || C.parameters["intelligible"]) - dat += "Data type: [C.input_type]
    " - dat += "Source: [C.parameters["name"]] (Job: [C.parameters["job"]])
    " - dat += "Class: [race]
    " - dat += "Contents: \"[C.parameters["message"]]\"
    " - if(language) - dat += "Language: [language]
    " - - // -- Orator is not human and universal translate not active -- - - else - dat += "Data type: Audio File
    " - dat += "Source: Unidentifiable
    " - dat += "Class: [race]
    " - dat += "Contents: Unintelligble
    " - - dat += "

  2. " - - else if(C.input_type == "Execution Error") - - dat += "
  3. [C.name] \[X\]
    " - dat += "Output: \"[C.parameters["message"]]\"
    " - dat += "

  4. " - - - dat += "
" - - - - user << browse(dat, "window=comm_monitor;size=575x400") - onclose(user, "server_control") - - temp = "" +/obj/machinery/computer/telecomms/server/attack_hand(mob/user) + if(stat & (BROKEN|NOPOWER)) return + tgui_interact(user) +/obj/machinery/computer/telecomms/server/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TelecommsLogBrowser", name) + ui.open() + +/obj/machinery/computer/telecomms/server/tgui_act(action, params) + if(..()) + return TRUE - Topic(href, href_list) - if(..()) - return + add_fingerprint(usr) - - add_fingerprint(usr) - usr.set_machine(src) - - if(href_list["viewserver"]) - screen = 1 + switch(action) + if("view") for(var/obj/machinery/telecomms/T in servers) - if(T.id == href_list["viewserver"]) + if(T.id == params["id"]) SelectedServer = T break + . = TRUE - if(href_list["operation"]) - switch(href_list["operation"]) + if("mainmenu") + SelectedServer = null + . = TRUE - if("release") - servers = list() - screen = 0 + if("release") + servers = list() + SelectedServer = null + . = TRUE - if("mainmenu") - screen = 0 + if("scan") + if(servers.len > 0) + set_temp("FAILED: CANNOT PROBE WHEN BUFFER FULL", "bad") + return TRUE - if("scan") - if(servers.len > 0) - temp = "- FAILED: CANNOT PROBE WHEN BUFFER FULL -" + for(var/obj/machinery/telecomms/server/T in range(25, src)) + if(T.network == network) + servers.Add(T) - else - for(var/obj/machinery/telecomms/server/T in range(25, src)) - if(T.network == network) - servers.Add(T) + if(!servers.len) + set_temp("FAILED: UNABLE TO LOCATE SERVERS IN \[[network]\]", "bad") + else + set_temp("[servers.len] SERVERS PROBED & BUFFERED", "good") + . = TRUE - if(!servers.len) - temp = "- FAILED: UNABLE TO LOCATE SERVERS IN \[[network]\] -" - else - temp = "- [servers.len] SERVERS PROBED & BUFFERED -" - - screen = 0 - - if(href_list["delete"]) - - if(!src.allowed(usr) && !emagged) + if("delete") + if(!allowed(usr) && !emagged) to_chat(usr, "ACCESS DENIED.") return if(SelectedServer) - - var/datum/comm_log_entry/D = SelectedServer.log_entries[text2num(href_list["delete"])] - - temp = "- DELETED ENTRY: [D.name] -" - + var/datum/comm_log_entry/D = SelectedServer.log_entries[text2num(params["id"])] + set_temp("DELETED ENTRY: [D.name]", "bad") SelectedServer.log_entries.Remove(D) qdel(D) - else - temp = "- FAILED: NO SELECTED MACHINE -" - - if(href_list["network"]) + set_temp("FAILED: NO SELECTED MACHINE", "bad") + . = TRUE + if("network") var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text if(newnet && ((usr in range(1, src) || issilicon(usr)))) if(length(newnet) > 15) - temp = "- FAILED: NETWORK TAG STRING TOO LENGHTLY -" + set_temp("FAILED: NETWORK TAG STRING TOO LENGTHY", "bad") + return TRUE + network = newnet + servers = list() + set_temp("NEW NETWORK TAG SET IN ADDRESS \[[network]\]", "good") - else - - network = newnet - screen = 0 - servers = list() - temp = "- NEW NETWORK TAG SET IN ADDRESS \[[network]\] -" - - updateUsrDialog() - return + . = TRUE + + if("cleartemp") + temp = null + . = TRUE /obj/machinery/computer/telecomms/server/emag_act(var/remaining_charges, var/mob/user) if(!emagged) @@ -197,3 +148,6 @@ to_chat(user, "You you disable the security protocols") src.updateUsrDialog() return 1 + +/obj/machinery/computer/telecomms/server/proc/set_temp(var/text, var/color = "average") + temp = list("color" = color, "text" = text) \ No newline at end of file diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index d1449882aff..7a14fa2023e 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -11,8 +11,7 @@ #define TELECOMM_Z 3 /obj/machinery/telecomms - var/temp = "" // output message - + var/list/temp = null // output message /obj/machinery/telecomms/attackby(obj/item/P as obj, mob/user as mob) @@ -40,74 +39,72 @@ /obj/machinery/telecomms/attack_ai(var/mob/user as mob) attack_hand(user) -/obj/machinery/telecomms/attack_hand(var/mob/user as mob) +/obj/machinery/telecomms/tgui_data(mob/user) + var/list/data = list() + + data["temp"] = temp + data["on"] = on - // You need a multitool to use this, or be silicon - if(!issilicon(user)) - // istype returns false if the value is null - if(!istype(user.get_active_hand(), /obj/item/device/multitool)) - return + data["id"] = null + data["network"] = null + data["autolinkers"] = FALSE + data["shadowlink"] = FALSE + data["options"] = list() + data["linked"] = list() + data["filter"] = list() + data["multitool"] = FALSE + data["multitool_buffer"] = null - if(stat & (BROKEN|NOPOWER)) - return + if(on || interact_offline) + data["id"] = id + data["network"] = network + data["autolinkers"] = !!LAZYLEN(autolinkers) + data["shadowlink"] = !!hide - var/obj/item/device/multitool/P = get_multitool(user) + data["options"] = Options_Menu() - user.set_machine(src) - var/dat - dat = "[src.name]

[src.name] Access

" - dat += "
[temp]
" - dat += "
Power Status: [src.toggled ? "On" : "Off"]" - if(on && toggled) - if(id != "" && id) - dat += "
Identification String: [id]" - else - dat += "
Identification String: NULL" - dat += "
Network: [network]" - dat += "
Prefabrication: [autolinkers.len ? "TRUE" : "FALSE"]" - if(hide) dat += "
Shadow Link: ACTIVE" - - //Show additional options for certain machines. - dat += Options_Menu() - - dat += "
Linked Network Entities:
    " + var/obj/item/device/multitool/P = get_multitool(user) + data["multitool"] = !!P + data["multitool_buffer"] = null + if(P && P.buffer) + P.update_icon() + data["multitool_buffer"] = list("name" = "[P.buffer]", "id" = "[P.buffer.id]") var/i = 0 + data["linked"] = list() for(var/obj/machinery/telecomms/T in links) i++ - if(T.hide && !src.hide) - continue - dat += "
  1. \ref[T] [T.name] ([T.id]) \[X\]
  2. " - dat += "
" - - dat += "
Filtering Frequencies: " - - i = 0 - if(length(freq_listening)) + data["linked"].Add(list(list( + "ref" = "\ref[T]", + "name" = "[T]", + "id" = T.id, + "index" = i, + ))) + + data["filter"] = list() + if(LAZYLEN(freq_listening)) for(var/x in freq_listening) - i++ - if(i < length(freq_listening)) - dat += "[format_frequency(x)] GHz\[X\]; " - else - dat += "[format_frequency(x)] GHz\[X\]" - else - dat += "NONE" + data["filter"].Add(list(list( + "name" = "[format_frequency(x)]", + "freq" = x, + ))) - dat += "
\[Add Filter\]" - dat += "
" + return data - if(P) - if(P.buffer) - dat += "

MULTITOOL BUFFER: [P.buffer] ([P.buffer.id]) \[Link\] \[Flush\]" - else - dat += "

MULTITOOL BUFFER:
\[Add Machine\]" - P.update_icon() +/obj/machinery/telecomms/tgui_status(mob/user) + if(!issilicon(user)) + if(!istype(user.get_active_hand(), /obj/item/device/multitool)) + return STATUS_CLOSE + . = ..() - dat += "
" - temp = "" - user << browse(dat, "window=tcommachine;size=520x500;can_resize=0") - onclose(user, "dormitory") +/obj/machinery/telecomms/attack_hand(var/mob/user as mob) + tgui_interact(user) +/obj/machinery/telecomms/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TelecommsMultitoolMenu", name) + ui.open() // Off-Site Relays // @@ -148,7 +145,7 @@ // Example of how to use below. /obj/machinery/telecomms/proc/Options_Menu() - return "" + return list() /* // Add an option to the processor to switch processing mode. (COMPRESS -> UNCOMPRESS or UNCOMPRESS -> COMPRESS) @@ -158,213 +155,230 @@ */ // The topic for Additional Options. Use this for checking href links for your specific option. // Example of how to use below. -/obj/machinery/telecomms/proc/Options_Topic(href, href_list) +/obj/machinery/telecomms/proc/Options_Act(action, params) return /* -/obj/machinery/telecomms/processor/Options_Topic(href, href_list) +/obj/machinery/telecomms/processor/Options_Act(action, params) if(href_list["process"]) - temp = "-% Processing mode changed. %-" + set_temp("-% Processing mode changed. %-", "average") src.process_mode = !src.process_mode */ // RELAY /obj/machinery/telecomms/relay/Options_Menu() - var/dat = "" - if(src.z == TELECOMM_Z) - dat += "
Signal Locked to Station: [listening_level == STATION_Z ? "TRUE" : "FALSE"]" - dat += "
Broadcasting: [broadcasting ? "YES" : "NO"]" - dat += "
Receiving: [receiving ? "YES" : "NO"]" - return dat + var/list/data = ..() + data["use_listening_level"] = TRUE + data["use_broadcasting"] = TRUE + data["use_receiving"] = TRUE + data["listening_level"] = (listening_level == STATION_Z) + data["broadcasting"] = broadcasting + data["receiving"] = receiving + return data -/obj/machinery/telecomms/relay/Options_Topic(href, href_list) +/obj/machinery/telecomms/relay/Options_Act(action, params) + if(..()) + return TRUE - if(href_list["receive"]) - receiving = !receiving - temp = "-% Receiving mode changed. %-" - if(href_list["broadcast"]) - broadcasting = !broadcasting - temp = "-% Broadcasting mode changed. %-" - if(href_list["change_listening"]) - //Lock to the station OR lock to the current position! - //You need at least two receivers and two broadcasters for this to work, this includes the machine. - var/result = toggle_level() - if(result) - temp = "-% [src]'s signal has been successfully changed." - else - temp = "-% [src] could not lock it's signal onto the station. Two broadcasters or receivers required." + switch(action) + if("receive") + . = TRUE + receiving = !receiving + set_temp("-% Receiving mode changed. %-", "average") + if("broadcast") + . = TRUE + broadcasting = !broadcasting + set_temp("-% Broadcasting mode changed. %-", "average") + if("change_listening") + . = TRUE + //Lock to the station OR lock to the current position! + //You need at least two receivers and two broadcasters for this to work, this includes the machine. + var/result = toggle_level() + if(result) + set_temp("-% [src]'s signal has been successfully changed.", "average") + else + set_temp("-% [src] could not lock it's signal onto the station. Two broadcasters or receivers required.", "average") // BUS /obj/machinery/telecomms/bus/Options_Menu() - var/dat = "
Change Signal Frequency: [change_frequency ? "YES ([change_frequency])" : "NO"]" - return dat + var/list/data = ..() + data["use_change_freq"] = TRUE + data["change_freq"] = change_frequency + return data -/obj/machinery/telecomms/bus/Options_Topic(href, href_list) - - if(href_list["change_freq"]) - - var/newfreq = input(usr, "Specify a new frequency for new signals to change to. Enter null to turn off frequency changing. Decimals assigned automatically.", src, network) as null|num - if(canAccess(usr)) - if(newfreq) - if(findtext(num2text(newfreq), ".")) - newfreq *= 10 // shift the decimal one place - if(newfreq < 10000) - change_frequency = newfreq - temp = "-% New frequency to change to assigned: \"[newfreq] GHz\" %-" - else - change_frequency = 0 - temp = "-% Frequency changing deactivated %-" +/obj/machinery/telecomms/bus/Options_Act(action, params) + if(..()) + return TRUE + + switch(action) + if("change_freq") + . = TRUE + var/newfreq = input(usr, "Specify a new frequency for new signals to change to. Enter null to turn off frequency changing. Decimals assigned automatically.", src, network) as null|num + if(canAccess(usr)) + if(newfreq) + if(findtext(num2text(newfreq), ".")) + newfreq *= 10 // shift the decimal one place + if(newfreq < 10000) + change_frequency = newfreq + set_temp("-% New frequency to change to assigned: \"[newfreq] GHz\" %-", "average") + else + change_frequency = 0 + set_temp("-% Frequency changing deactivated %-", "average") // BROADCASTER /obj/machinery/telecomms/broadcaster/Options_Menu() - // Note the machine 'displays' 1 higher than overmap_range to save users from the abstraction that range '0' is valid and everything on the same turf. - var/dat = "
Broadcast Range (affects power usage)
- [overmap_range+1] gigameter\s +" - return dat + var/list/data = ..() + data["use_broadcast_range"] = TRUE + data["range"] = overmap_range + data["minRange"] = overmap_range_min + data["maxRange"] = overmap_range_max + return data -/obj/machinery/telecomms/broadcaster/Options_Topic(href, href_list) - if(href_list["range_down"]) - if(overmap_range > overmap_range_min) - overmap_range-- - update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1)) - if(href_list["range_up"]) - if(overmap_range < overmap_range_max) - overmap_range++ +/obj/machinery/telecomms/broadcaster + interact_offline = TRUE // because you can accidentally nuke power grids with these, need to be able to fix mistake + +/obj/machinery/telecomms/broadcaster/Options_Act(action, params) + if(..()) + return TRUE + + switch(action) + if("range") + var/new_range = params["range"] + overmap_range = clamp(new_range, overmap_range_min, overmap_range_max) update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1)) // RECEIVER /obj/machinery/telecomms/receiver/Options_Menu() - // Note the machine 'displays' 1 higher than overmap_range to save users from the abstraction that range '0' is valid and everything on the same turf. - var/dat = "
Receive Range (affects power usage)
- [overmap_range+1] gigameter\s +" - return dat + var/list/data = ..() + data["use_receive_range"] = TRUE + data["range"] = overmap_range + data["minRange"] = overmap_range_min + data["maxRange"] = overmap_range_max + return data -/obj/machinery/telecomms/receiver/Options_Topic(href, href_list) - if(href_list["range_down"]) - if(overmap_range > overmap_range_min) - overmap_range-- - update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1)) - if(href_list["range_up"]) - if(overmap_range < overmap_range_max) - overmap_range++ +/obj/machinery/telecomms/receiver + interact_offline = TRUE // because you can accidentally nuke power grids with these, need to be able to fix mistake + +/obj/machinery/telecomms/receiver/Options_Act(action, params) + if(..()) + return TRUE + + switch(action) + if("range") + var/new_range = params["range"] + overmap_range = clamp(new_range, overmap_range_min, overmap_range_max) update_idle_power_usage(initial(idle_power_usage)**(overmap_range+1)) -/obj/machinery/telecomms/Topic(href, href_list) - - if(!issilicon(usr)) - if(!istype(usr.get_active_hand(), /obj/item/device/multitool)) - return - - if(stat & (BROKEN|NOPOWER)) - return +/obj/machinery/telecomms/tgui_act(action, params) + if(..()) + return TRUE var/obj/item/device/multitool/P = get_multitool(usr) - if(href_list["input"]) - switch(href_list["input"]) + switch(action) + if("toggle") + src.toggled = !src.toggled + set_temp("-% [src] has been [src.toggled ? "activated" : "deactivated"].", "average") + update_power() + . = TRUE - if("toggle") + if("id") + var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID for this machine", src, id) as null|text),1,MAX_MESSAGE_LEN) + if(newid && canAccess(usr)) + id = newid + set_temp("-% New ID assigned: \"[id]\" %-", "average") + . = TRUE - src.toggled = !src.toggled - temp = "-% [src] has been [src.toggled ? "activated" : "deactivated"]." - update_power() + if("network") + var/newnet = input(usr, "Specify the new network for this machine. This will break all current links.", src, network) as null|text + if(newnet && canAccess(usr)) - /* - if("hide") - src.hide = !hide - temp = "-% Shadow Link has been [src.hide ? "activated" : "deactivated"]." - */ + if(length(newnet) > 15) + set_temp("-% Too many characters in new network tag %-", "average") - if("id") - var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID for this machine", src, id) as null|text),1,MAX_MESSAGE_LEN) - if(newid && canAccess(usr)) - id = newid - temp = "-% New ID assigned: \"[id]\" %-" + else + for(var/obj/machinery/telecomms/T in links) + T.links.Remove(src) - if("network") - var/newnet = input(usr, "Specify the new network for this machine. This will break all current links.", src, network) as null|text - if(newnet && canAccess(usr)) - - if(length(newnet) > 15) - temp = "-% Too many characters in new network tag %-" - - else - for(var/obj/machinery/telecomms/T in links) - T.links.Remove(src) - - network = newnet - links = list() - temp = "-% New network tag assigned: \"[network]\" %-" + network = newnet + links = list() + set_temp("-% New network tag assigned: \"[network]\" %-", "average") + . = TRUE - if("freq") - var/newfreq = input(usr, "Specify a new frequency to filter (GHz). Decimals assigned automatically.", src, network) as null|num - if(newfreq && canAccess(usr)) - if(findtext(num2text(newfreq), ".")) - newfreq *= 10 // shift the decimal one place - if(!(newfreq in freq_listening) && newfreq < 10000) - freq_listening.Add(newfreq) - temp = "-% New frequency filter assigned: \"[newfreq] GHz\" %-" + if("freq") + var/newfreq = input(usr, "Specify a new frequency to filter (GHz). Decimals assigned automatically.", src, network) as null|num + if(newfreq && canAccess(usr)) + if(findtext(num2text(newfreq), ".")) + newfreq *= 10 // shift the decimal one place + if(!(newfreq in freq_listening) && newfreq < 10000) + freq_listening.Add(newfreq) + set_temp("-% New frequency filter assigned: \"[newfreq] GHz\" %-", "average") + . = TRUE - if(href_list["delete"]) + if("delete") + var/x = text2num(params["delete"]) + set_temp("-% Removed frequency filter [x] %-", "average") + freq_listening.Remove(x) + . = TRUE - // changed the layout about to workaround a pesky runtime -- Doohl + if("unlink") + if(text2num(params["unlink"]) <= length(links)) + var/obj/machinery/telecomms/T = links[text2num(params["unlink"])] + set_temp("-% Removed \ref[T] [T.name] from linked entities. %-", "average") - var/x = text2num(href_list["delete"]) - temp = "-% Removed frequency filter [x] %-" - freq_listening.Remove(x) + // Remove link entries from both T and src. - if(href_list["unlink"]) + if(src in T.links) + T.links.Remove(src) + links.Remove(T) + . = TRUE - if(text2num(href_list["unlink"]) <= length(links)) - var/obj/machinery/telecomms/T = links[text2num(href_list["unlink"])] - temp = "-% Removed \ref[T] [T.name] from linked entities. %-" + if("link") + if(P) + if(P.buffer && P.buffer != src) + if(!(src in P.buffer.links)) + P.buffer.links.Add(src) - // Remove link entries from both T and src. + if(!(P.buffer in src.links)) + src.links.Add(P.buffer) - if(src in T.links) - T.links.Remove(src) - links.Remove(T) + set_temp("-% Successfully linked with \ref[P.buffer] [P.buffer.name] %-", "average") - if(href_list["link"]) + else + set_temp("-% Unable to acquire buffer %-", "average") + . = TRUE - if(P) - if(P.buffer && P.buffer != src) - if(!(src in P.buffer.links)) - P.buffer.links.Add(src) + if("buffer") + P.buffer = src + set_temp("-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-", "average") + . = TRUE - if(!(P.buffer in src.links)) - src.links.Add(P.buffer) + if("flush") + set_temp("-% Buffer successfully flushed. %-", "average") + P.buffer = null + . = TRUE - temp = "-% Successfully linked with \ref[P.buffer] [P.buffer.name] %-" + if("cleartemp") + temp = null + . = TRUE - else - temp = "-% Unable to acquire buffer %-" + if(Options_Act(action, params)) + . = TRUE - if(href_list["buffer"]) - - P.buffer = src - temp = "-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-" - - - if(href_list["flush"]) - - temp = "-% Buffer successfully flushed. %-" - P.buffer = null - - src.Options_Topic(href, href_list) - - usr.set_machine(src) - src.add_fingerprint(usr) - - updateUsrDialog() + add_fingerprint(usr) /obj/machinery/telecomms/proc/canAccess(var/mob/user) if(issilicon(user) || in_range(user, src)) return 1 return 0 +/obj/machinery/telecomms/proc/set_temp(var/text, var/color = "average") + temp = list("color" = color, "text" = text) + #undef TELECOMM_Z #undef STATION_Z diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index e89b9aa7263..6f2e626a00f 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -593,6 +593,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() log.parameters["message"] = multilingual_to_message(signal.data["message"]) log.parameters["name"] = signal.data["name"] log.parameters["realname"] = signal.data["realname"] + log.parameters["timecode"] = worldtime2stationtime(world.time) var/race = "unknown" if(ishuman(M)) @@ -672,6 +673,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() log.name = "[input] ([md5(identifier)])" log.input_type = input log.parameters["message"] = content + log.parameters["timecode"] = stationtime2text() log_entries.Add(log) update_logs() @@ -708,4 +710,4 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() if(ad_hoc && src_z == dst_z) return TRUE - return src_z in using_map.get_map_levels(dst_z) + return src_z in using_map.get_map_levels(dst_z, TRUE, om_range = DEFAULT_OVERMAP_RANGE) diff --git a/code/game/machinery/telecomms/telemonitor.dm b/code/game/machinery/telecomms/telemonitor.dm index 51a6ebf991d..7107e0ff5d7 100644 --- a/code/game/machinery/telecomms/telemonitor.dm +++ b/code/game/machinery/telecomms/telemonitor.dm @@ -6,7 +6,6 @@ and displays a heirarchy of linked machines. */ - /obj/machinery/computer/telecomms/monitor name = "Telecommunications Monitor" desc = "Used to traverse a telecommunication network. Helpful for debugging connection issues." @@ -19,111 +18,103 @@ var/network = "NULL" // the network to probe - var/temp = "" // temporary feedback messages + var/list/temp = null // temporary feedback messages - attack_hand(mob/user as mob) - if(stat & (BROKEN|NOPOWER)) - return - user.set_machine(src) - var/dat = "Telecommunications Monitor
Telecommunications Monitor
" +/obj/machinery/computer/telecomms/monitor/tgui_data(mob/user) + var/list/data = list() - switch(screen) + data["network"] = network + data["temp"] = temp + data["machinelist"] = list() + for(var/obj/machinery/telecomms/T in machinelist) + data["machinelist"].Add(list(list( + "id" = T.id, + "name" = T.name, + ))) - // --- Main Menu --- + data["selectedMachine"] = null + if(SelectedMachine) + data["selectedMachine"] = list( + "id" = SelectedMachine.id, + "name" = SelectedMachine.name, + "links" = list(), + ) - if(0) - dat += "
[temp]

" - dat += "
Current Network: [network]
" - if(machinelist.len) - dat += "
Detected Network Entities:
    " - for(var/obj/machinery/telecomms/T in machinelist) - dat += "
  • \ref[T] [T.name] ([T.id])
  • " - dat += "
" - dat += "
\[Flush Buffer\]" - else - dat += "\[Probe Network\]" + for(var/obj/machinery/telecomms/T in SelectedMachine.links) + if(!T.hide) + data["selectedMachine"]["links"].Add(list(list( + "id" = T.id, + "name" = T.name + ))) + return data - // --- Viewing Machine --- - - if(1) - dat += "
[temp]
" - dat += "
\[Main Menu\]
" - dat += "
Current Network: [network]
" - dat += "Selected Network Entity: [SelectedMachine.name] ([SelectedMachine.id])
" - dat += "Linked Entities:
    " - for(var/obj/machinery/telecomms/T in SelectedMachine.links) - if(!T.hide) - dat += "
  1. \ref[T.id] [T.name] ([T.id])
  2. " - dat += "
" - - - - user << browse(dat, "window=comm_monitor;size=575x400") - onclose(user, "server_control") - - temp = "" +/obj/machinery/computer/telecomms/monitor/attack_hand(mob/user) + if(stat & (BROKEN|NOPOWER)) return + tgui_interact(user) +/obj/machinery/computer/telecomms/monitor/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TelecommsMachineBrowser", name) + ui.open() - Topic(href, href_list) - if(..()) - return +/obj/machinery/computer/telecomms/monitor/tgui_act(action, params) + if(..()) + return TRUE + add_fingerprint(usr) - add_fingerprint(usr) - usr.set_machine(src) - - if(href_list["viewmachine"]) - screen = 1 + switch(action) + if("view") for(var/obj/machinery/telecomms/T in machinelist) - if(T.id == href_list["viewmachine"]) + if(T.id == params["id"]) SelectedMachine = T break + . = TRUE - if(href_list["operation"]) - switch(href_list["operation"]) + if("mainmenu") + SelectedMachine = null + . = TRUE - if("release") - machinelist = list() - screen = 0 + if("release") + machinelist = list() + SelectedMachine = null + . = TRUE - if("mainmenu") - screen = 0 + if("scan") + if(machinelist.len > 0) + set_temp("FAILED: CANNOT PROBE WHEN BUFFER FULL", "bad") + return TRUE - if("probe") - if(machinelist.len > 0) - temp = "- FAILED: CANNOT PROBE WHEN BUFFER FULL -" + for(var/obj/machinery/telecomms/T in range(25, src)) + if(T.network == network) + machinelist.Add(T) - else - for(var/obj/machinery/telecomms/T in range(25, src)) - if(T.network == network) - machinelist.Add(T) - - if(!machinelist.len) - temp = "- FAILED: UNABLE TO LOCATE NETWORK ENTITIES IN \[[network]\] -" - else - temp = "- [machinelist.len] ENTITIES LOCATED & BUFFERED -" - - screen = 0 - - - if(href_list["network"]) + if(!machinelist.len) + set_temp("FAILED: UNABLE TO LOCATE NETWORK ENTITIES IN \[[network]\]", "bad") + else + set_temp("[machinelist.len] ENTITIES LOCATED & BUFFERED", "good") + . = TRUE + if("network") var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text if(newnet && ((usr in range(1, src) || issilicon(usr)))) if(length(newnet) > 15) - temp = "- FAILED: NETWORK TAG STRING TOO LENGHTLY -" + set_temp("FAILED: NETWORK TAG STRING TOO LENGTHY", "bad") + return TRUE + network = newnet + machinelist = list() + set_temp("NEW NETWORK TAG SET IN ADDRESS \[[network]\]", "good") + + . = TRUE - else - network = newnet - screen = 0 - machinelist = list() - temp = "- NEW NETWORK TAG SET IN ADDRESS \[[network]\] -" + if("cleartemp") + temp = null + . = TRUE - updateUsrDialog() - return /obj/machinery/computer/telecomms/monitor/emag_act(var/remaining_charges, var/mob/user) if(!emagged) @@ -132,3 +123,6 @@ to_chat(user, "You you disable the security protocols") src.updateUsrDialog() return 1 + +/obj/machinery/computer/telecomms/monitor/proc/set_temp(var/text, var/color = "average") + temp = list("color" = color, "text" = text) \ No newline at end of file diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 8472a82d55d..dcdd8d88fe4 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1,6 +1,11 @@ -/** - * A vending machine - */ +/// +/// A vending machine +/// + +// +// ALL THE VENDING MACHINES ARE IN vending_machines.dm now! +// + /obj/machinery/vending name = "Vendomat" desc = "A generic vending machine." @@ -21,6 +26,7 @@ var/vend_delay = 10 //How long does it take to vend? var/categories = CAT_NORMAL // Bitmask of cats we're currently showing var/datum/stored_item/vending_product/currently_vending = null // What we're requesting payment for right now + var/tmp/actively_vending = null // Used to allow TGUI to display normal items in-progress being vended var/status_message = "" // Status screen messages like "insufficient funds", displayed in NanoUI var/status_error = 0 // Set to 1 if status_message is an error var/vending_sound = "machines/vending/vending_drop.ogg" @@ -168,7 +174,7 @@ vend(currently_vending, usr) return else if(handled) - SSnanoui.update_uis(src) + SStgui.update_uis(src) return // don't smack that machine with your 2 thalers if(I || istype(W, /obj/item/weapon/spacecash)) @@ -179,11 +185,12 @@ to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.") playsound(src, W.usesound, 50, 1) if(panel_open) + wires.Interact(user) add_overlay("[initial(icon_state)]-panel") else cut_overlay("[initial(icon_state)]-panel") - SSnanoui.update_uis(src) // Speaker switch is on the main UI, not wires UI + SStgui.update_uis(src) // Speaker switch is on the main UI, not wires UI return else if(istype(W, /obj/item/device/multitool) || W.is_wirecutter()) if(panel_open) @@ -195,7 +202,7 @@ coin = W categories |= CAT_COIN to_chat(user, "You insert \the [W] into \the [src].") - SSnanoui.update_uis(src) + SStgui.update_uis(src) return else if(W.is_wrench()) playsound(src, W.usesound, 100, 1) @@ -343,6 +350,9 @@ T.time = stationtime2text() vendor_account.transaction_log.Add(T) +/obj/machinery/vending/attack_ghost(mob/user) + return attack_hand(user) + /obj/machinery/vending/attack_ai(mob/user as mob) return attack_hand(user) @@ -355,24 +365,23 @@ return wires.Interact(user) - ui_interact(user) + tgui_interact(user) -/** - * Display the NanoUI window for the vending machine. - * - * See NanoUI documentation for details. - */ -/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/vending/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Vending", name) + ui.open() +/obj/machinery/vending/tgui_data(mob/user) var/list/data = list() if(currently_vending) data["mode"] = 1 data["product"] = currently_vending.item_name data["price"] = currently_vending.price - data["message_err"] = 0 data["message"] = status_message data["message_err"] = status_error + data["products"] = null else data["mode"] = 0 var/list/listed_products = list() @@ -394,6 +403,13 @@ if(coin) data["coin"] = coin.name + else + data["coin"] = FALSE + + if(actively_vending) + data["actively_vending"] = actively_vending + else + data["actively_vending"] = null if(panel_open) data["panel"] = 1 @@ -401,19 +417,20 @@ else data["panel"] = 0 - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "vending_machine.tmpl", name, 440, 600) - ui.set_initial_data(data) - ui.open() + return data -/obj/machinery/vending/Topic(href, href_list) +/obj/machinery/vending/tgui_act(action, params) if(stat & (BROKEN|NOPOWER)) return if(usr.stat || usr.restrained()) return + if(..()) + return TRUE + + if(action == "remove_coin") + if(issilicon(usr)) + return FALSE - if(href_list["remove_coin"] && !istype(usr,/mob/living/silicon)) if(!coin) to_chat(usr, "There is no coin in this machine.") return @@ -421,19 +438,27 @@ coin.forceMove(src.loc) if(!usr.get_active_hand()) usr.put_in_hands(coin) - to_chat(usr, "You remove \the [coin] from \the [src]") + + to_chat(usr, "You remove \the [coin] from \the [src].") coin = null categories &= ~CAT_COIN + return TRUE - if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) - if((href_list["vend"]) && (vend_ready) && (!currently_vending)) - if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH + if(!usr.contents.Find(src) && (!in_range(src, usr) && isturf(loc))) + return FALSE + + . = TRUE + switch(action) + if("vend") + if(!vend_ready || currently_vending) + return + if(!allowed(usr) && !emagged && scan_id) to_chat(usr, "Access denied.") //Unless emagged of course flick("[icon_state]-deny",src) playsound(src, 'sound/machines/deniedbeep.ogg', 50, 0) return - var/key = text2num(href_list["vend"]) + var/key = text2num(params["vend"]) var/datum/stored_item/vending_product/R = product_records[key] // This should not happen unless the request from NanoUI was bad @@ -442,7 +467,7 @@ if(R.price <= 0) vend(R, usr) - else if(istype(usr,/mob/living/silicon)) //If the item is not free, provide feedback if a synth is trying to buy something. + else if(issilicon(usr)) //If the item is not free, provide feedback if a synth is trying to buy something. to_chat(usr, "Lawed unit recognized. Lawed units cannot complete this transaction. Purchase canceled.") return else @@ -454,15 +479,14 @@ status_message = "Please swipe a card or insert cash to pay for the item." status_error = 0 - else if(href_list["cancelpurchase"]) + if("cancelpurchase") currently_vending = null - else if((href_list["togglevoice"]) && (panel_open)) + if("togglevoice") + if(!panel_open) + return FALSE shut_up = !shut_up - add_fingerprint(usr) - SSnanoui.update_uis(src) - /obj/machinery/vending/proc/vend(datum/stored_item/vending_product/R, mob/user) if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH to_chat(usr, "Access denied.") //Unless emagged of course @@ -470,9 +494,10 @@ playsound(src, 'sound/machines/deniedbeep.ogg', 50, 0) return vend_ready = 0 //One thing at a time!! + actively_vending = R.item_name status_message = "Vending..." status_error = 0 - SSnanoui.update_uis(src) + SStgui.update_uis(src) if(R.category & CAT_COIN) if(!coin) @@ -511,8 +536,9 @@ status_message = "" status_error = 0 vend_ready = 1 + actively_vending = null currently_vending = null - SSnanoui.update_uis(src) + SStgui.update_uis(src) return 1 @@ -584,7 +610,7 @@ if(has_logs) do_logging(R, user) - SSnanoui.update_uis(src) + SStgui.update_uis(src) /obj/machinery/vending/process() if(stat & (BROKEN|NOPOWER)) @@ -659,559 +685,4 @@ visible_message("\The [src] launches \a [throw_item] at \the [target]!") return 1 -/* - * Vending machine types - */ - -/* - -/obj/machinery/vending/[vendors name here] // --vending machine template :) - name = "" - desc = "" - icon = '' - icon_state = "" - vend_delay = 15 - products = list() - contraband = list() - premium = list() - -*/ - -/* -/obj/machinery/vending/atmospherics //Commenting this out until someone ponies up some actual working, broken, and unpowered sprites - Quarxink - name = "Tank Vendor" - desc = "A vendor with a wide variety of masks and gas tanks." - icon = 'icons/obj/objects.dmi' - icon_state = "dispenser" - product_paths = "/obj/item/weapon/tank/oxygen;/obj/item/weapon/tank/phoron;/obj/item/weapon/tank/emergency_oxygen;/obj/item/weapon/tank/emergency_oxygen/engi;/obj/item/clothing/mask/breath" - productamounts = "10;10;10;5;25" - vend_delay = 0 -*/ - -/obj/machinery/vending/boozeomat - name = "Booze-O-Mat" - desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." - icon_state = "fridge_dark" - products = list(/obj/item/weapon/reagent_containers/food/drinks/glass2/square = 10, - /obj/item/weapon/reagent_containers/food/drinks/glass2/rocks = 10, - /obj/item/weapon/reagent_containers/food/drinks/glass2/shake = 10, - /obj/item/weapon/reagent_containers/food/drinks/glass2/cocktail = 10, - /obj/item/weapon/reagent_containers/food/drinks/glass2/shot = 10, - /obj/item/weapon/reagent_containers/food/drinks/glass2/pint = 10, - /obj/item/weapon/reagent_containers/food/drinks/glass2/mug = 10, - /obj/item/weapon/reagent_containers/food/drinks/glass2/wine = 10, - /obj/item/weapon/reagent_containers/food/drinks/glass2/carafe = 2, - /obj/item/weapon/reagent_containers/food/drinks/glass2/pitcher = 2, - /obj/item/weapon/reagent_containers/food/drinks/metaglass = 10, - /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint = 10, - /obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/cognac = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine = 5, - /obj/item/weapon/reagent_containers/food/condiment/cornoil = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/peppermintschnapps = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/peachschnapps = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/lemonadeschnapps = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/rum = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/sake = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/vodka = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale = 15, - /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer = 15, - /obj/item/weapon/reagent_containers/food/drinks/bottle/small/cider = 15, - /obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/lemonjuice = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/applejuice = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/milk = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/cream = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/cola = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/space_up = 5, - /obj/item/weapon/reagent_containers/food/drinks/bottle/space_mountain_wind = 5, - /obj/item/weapon/reagent_containers/food/drinks/cans/sodawater = 15, - /obj/item/weapon/reagent_containers/food/drinks/cans/tonic = 15, - /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 15, - /obj/item/weapon/reagent_containers/food/drinks/flask/barflask = 5, - /obj/item/weapon/reagent_containers/food/drinks/flask/vacuumflask = 5, - /obj/item/weapon/reagent_containers/food/drinks/ice = 10, - /obj/item/weapon/reagent_containers/food/drinks/tea = 15, - /obj/item/weapon/glass_extra/stick = 30, - /obj/item/weapon/glass_extra/straw = 30) //VOREStation Add - Carafes and Pitchers - contraband = list() - vend_delay = 15 - idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. - product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?" - product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!" - req_access = list(access_bar) - req_log_access = access_bar - has_logs = 1 - vending_sound = "machines/vending/vending_cans.ogg" - -/obj/machinery/vending/assist - products = list( /obj/item/device/assembly/prox_sensor = 5,/obj/item/device/assembly/igniter = 3,/obj/item/device/assembly/signaler = 4, - /obj/item/weapon/tool/wirecutters = 1, /obj/item/weapon/cartridge/signal = 4) - contraband = list(/obj/item/device/flashlight = 5,/obj/item/device/assembly/timer = 2) - product_ads = "Only the finest!;Have some tools.;The most robust equipment.;The finest gear in space!" - -/obj/machinery/vending/coffee - name = "Hot Drinks machine" - desc = "A vending machine which dispenses hot drinks." - product_ads = "Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies" - icon_state = "coffee" - vend_delay = 34 - idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. - vend_power_usage = 85000 //85 kJ to heat a 250 mL cup of coffee - products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25) - contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10) - prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 2, /obj/item/weapon/reagent_containers/food/drinks/tea = 2, /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 2) //VOREStation Edit - vending_sound = "machines/vending/vending_coffee.ogg" - -/obj/machinery/vending/snack - name = "Getmore Chocolate Corp" - desc = "A snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars." - product_slogans = "Try our new nougat bar!;Twice the calories for half the price!" - product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Oh my god it's so juicy!;Have a snack.;Snacks are good for you!;Have some more Getmore!;Best quality snacks straight from mars.;We love chocolate!;Try our new jerky!" - icon_state = "snack" - products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 12,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 12,/obj/item/weapon/reagent_containers/food/snacks/chips =12, - /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 12,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 12,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 12, - /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 12, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 12, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 6) - contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6,/obj/item/weapon/reagent_containers/food/snacks/unajerky = 12,) - prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 1,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 5,/obj/item/weapon/reagent_containers/food/snacks/chips = 1, - /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 2,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 1,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 1, - /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 1, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 2, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 2) - -/obj/machinery/vending/cola - name = "Robust Softdrinks" - desc = "A softdrink vendor provided by Robust Industries, LLC." - icon_state = "Cola_Machine" - product_slogans = "Robust Softdrinks: More robust than a toolbox to the head!" - product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space." - products = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 10, - /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 10, - /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 10, - /obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 10, - /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 10) - contraband = list(/obj/item/weapon/reagent_containers/food/drinks/cans/thirteenloko = 5, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 6) - prices = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 1, - /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 1, - /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 2,/obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 1, - /obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 1, - /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 1) - idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. - vending_sound = "machines/vending/vending_cans.ogg" - -/obj/machinery/vending/fitness - name = "SweatMAX" - desc = "Fueled by your inner inadequacy!" - icon_state = "fitness" - products = list(/obj/item/weapon/reagent_containers/food/drinks/smallmilk = 16, - /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk = 16, - /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 8, - /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 8, - /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 16, - /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 8, - /obj/item/weapon/reagent_containers/pill/diet = 8, - ///obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5, //VOREStation Removal, - /obj/item/weapon/towel/random = 8) - - //VOREStation Edit Start - prices = list(/obj/item/weapon/reagent_containers/food/drinks/smallmilk = 3, - /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk = 3, - /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 15, - /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 1, - /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 5, - /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 5, - /obj/item/weapon/reagent_containers/pill/diet = 25, - ///obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5, - /obj/item/weapon/towel/random = 20) - //VOREStation Edit End - - contraband = list(/obj/item/weapon/reagent_containers/syringe/steroid = 4, /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteanshake = 2) // VOREStation Add - Slurpable blobs. - - -/obj/machinery/vending/cart - name = "PTech" - desc = "Cartridges for PDAs." - product_slogans = "Carts to go!" - icon_state = "cart" - req_access = list(access_hop) - products = list(/obj/item/weapon/cartridge/medical = 10,/obj/item/weapon/cartridge/engineering = 10,/obj/item/weapon/cartridge/security = 10, - /obj/item/weapon/cartridge/janitor = 10,/obj/item/weapon/cartridge/signal/science = 10,/obj/item/device/pda/heads = 10, - /obj/item/weapon/cartridge/captain = 3,/obj/item/weapon/cartridge/quartermaster = 10) - req_log_access = access_hop - has_logs = 1 - -/obj/machinery/vending/cigarette - name = "cigarette machine" - desc = "If you want to get cancer, might as well do it in style!" - product_slogans = "Space cigs taste good like a cigarette should.;I'd rather toolbox than switch.;Smoke!;Don't believe the reports - smoke today!" - product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 2150.;Award-winning cigs.;Feeling temperamental? Try a Temperamento!;Carcinoma Angels - go fuck yerself!;Don't be so hard on yourself, kid. Smoke a Lucky Star!" - vend_delay = 34 - icon_state = "cigs" - products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, - /obj/item/weapon/storage/fancy/cigarettes/dromedaryco = 10, - /obj/item/weapon/storage/fancy/cigarettes/killthroat = 10, - /obj/item/weapon/storage/fancy/cigarettes/luckystars = 10, - /obj/item/weapon/storage/fancy/cigarettes/jerichos = 10, - /obj/item/weapon/storage/fancy/cigarettes/menthols = 10, - /obj/item/weapon/storage/rollingpapers = 10, - /obj/item/weapon/storage/box/matches = 10, - /obj/item/weapon/flame/lighter/random = 4) - contraband = list(/obj/item/weapon/flame/lighter/zippo = 4) - premium = list(/obj/item/weapon/storage/fancy/cigar = 5, - /obj/item/weapon/storage/fancy/cigarettes/carcinomas = 5, - /obj/item/weapon/storage/fancy/cigarettes/professionals = 5) - prices = list(/obj/item/weapon/storage/fancy/cigarettes = 12, - /obj/item/weapon/storage/fancy/cigarettes/dromedaryco = 15, - /obj/item/weapon/storage/fancy/cigarettes/killthroat = 17, - /obj/item/weapon/storage/fancy/cigarettes/luckystars = 17, - /obj/item/weapon/storage/fancy/cigarettes/jerichos = 22, - /obj/item/weapon/storage/fancy/cigarettes/menthols = 18, - /obj/item/weapon/storage/rollingpapers = 10, - /obj/item/weapon/storage/box/matches = 1, - /obj/item/weapon/flame/lighter/random = 2) - -/obj/machinery/vending/medical - name = "NanoMed Plus" - desc = "Medical drug dispenser." - icon_state = "med" - product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!" - req_access = list(access_medical) - products = list(/obj/item/weapon/reagent_containers/glass/bottle/antitoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline = 4, - /obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4, - /obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12, - /obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2, - /obj/item/stack/medical/advanced/bruise_pack = 6, /obj/item/stack/medical/advanced/ointment = 6, /obj/item/stack/medical/splint = 4, - /obj/item/weapon/storage/pill_bottle/carbon = 2) - contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6) - idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. - req_log_access = access_cmo - has_logs = 1 - -/obj/machinery/vending/phoronresearch - name = "Toximate 3000" - desc = "All the fine parts you need in one vending machine!" - products = list(/obj/item/clothing/under/rank/scientist = 6,/obj/item/clothing/suit/bio_suit = 6,/obj/item/clothing/head/bio_hood = 6, - /obj/item/device/transfer_valve = 6,/obj/item/device/assembly/timer = 6,/obj/item/device/assembly/signaler = 6, - /obj/item/device/assembly/prox_sensor = 6,/obj/item/device/assembly/igniter = 6) - req_log_access = access_rd - has_logs = 1 - -/obj/machinery/vending/wallmed1 - name = "NanoMed" - desc = "A wall-mounted version of the NanoMed." - product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?" - icon_state = "wallmed" - density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude - products = list(/obj/item/stack/medical/bruise_pack = 2,/obj/item/stack/medical/ointment = 2,/obj/item/weapon/reagent_containers/hypospray/autoinjector = 4,/obj/item/device/healthanalyzer = 1) - contraband = list(/obj/item/weapon/reagent_containers/syringe/antitoxin = 4,/obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/pill/tox = 1) - req_log_access = access_cmo - has_logs = 1 - can_rotate = 0 - -/obj/machinery/vending/wallmed2 - name = "NanoMed" - desc = "A wall-mounted version of the NanoMed, containing only vital first aid equipment." - icon_state = "wallmed" - density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude - products = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector = 5,/obj/item/weapon/reagent_containers/syringe/antitoxin = 3,/obj/item/stack/medical/bruise_pack = 3, - /obj/item/stack/medical/ointment =3,/obj/item/device/healthanalyzer = 3) - contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3) - req_log_access = access_cmo - has_logs = 1 - can_rotate = 0 - -/obj/machinery/vending/security - name = "SecTech" - desc = "A security equipment vendor." - product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?" - icon_state = "sec" - req_access = list(access_security) - products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, - /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6) - contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/box/donut = 2) - req_log_access = access_armory - has_logs = 1 - -/obj/machinery/vending/hydronutrients - name = "NutriMax" - desc = "A plant nutrients vendor." - product_slogans = "Aren't you glad you don't have to fertilize the natural way?;Now with 50% less stink!;Plants are people too!" - product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..." - icon_state = "nutri_generic" - products = list(/obj/item/weapon/reagent_containers/glass/bottle/eznutrient = 6,/obj/item/weapon/reagent_containers/glass/bottle/left4zed = 4,/obj/item/weapon/reagent_containers/glass/bottle/robustharvest = 3,/obj/item/weapon/plantspray/pests = 20, - /obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4,/obj/item/weapon/storage/bag/plants = 5) - premium = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5) - idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. - - -/obj/machinery/vending/hydroseeds - name = "MegaSeed Servitor" - desc = "When you need seeds fast!" - product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" - product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" - icon_state = "seeds_generic" - - products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3, - /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3, - /obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3, - /obj/item/seeds/poppyseed = 3,/obj/item/seeds/sugarcaneseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/peanutseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/lavenderseed = 3,/obj/item/seeds/limeseed = 3, - /obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,/obj/item/seeds/plumpmycelium = 2, - /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3) - contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/mtearseed = 2, - /obj/item/seeds/nettleseed = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/shandseed = 2,) - premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1) - -/** - * Populate hydroseeds product_records - * - * This needs to be customized to fetch the actual names of the seeds, otherwise - * the machine would simply list "packet of seeds" times 20 - */ -/obj/machinery/vending/hydroseeds/build_inventory() - var/list/all_products = list( - list(products, CAT_NORMAL), - list(contraband, CAT_HIDDEN), - list(premium, CAT_COIN)) - - for(var/current_list in all_products) - var/category = current_list[2] - - for(var/entry in current_list[1]) - var/obj/item/seeds/S = new entry(src) - var/name = S.name - var/datum/stored_item/vending_product/product = new/datum/stored_item/vending_product(src, entry, name) - - product.price = (entry in prices) ? prices[entry] : 0 - product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 - product.category = category - - product_records.Add(product) - -/obj/machinery/vending/magivend - name = "MagiVend" - desc = "A magic vending machine." - icon_state = "MagiVend" - product_slogans = "Sling spells the proper way with MagiVend!;Be your own Houdini! Use MagiVend!" - vend_delay = 15 - vend_reply = "Have an enchanted evening!" - product_ads = "FJKLFJSD;AJKFLBJAKL;1234 LOONIES LOL!;>MFW;Kill them fuckers!;GET DAT FUKKEN DISK;HONK!;EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!" - products = list(/obj/item/clothing/head/wizard = 1,/obj/item/clothing/suit/wizrobe = 1,/obj/item/clothing/head/wizard/red = 1,/obj/item/clothing/suit/wizrobe/red = 1,/obj/item/clothing/shoes/sandal = 1,/obj/item/weapon/staff = 2) - -/obj/machinery/vending/dinnerware - name = "Dinnerware" - desc = "A kitchen and restaurant equipment vendor." - product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..." - icon_state = "dinnerware" - products = list( - /obj/item/weapon/reagent_containers/food/condiment/yeast = 5, - /obj/item/weapon/reagent_containers/food/condiment/cornoil = 5, - /obj/item/weapon/tray = 8, - /obj/item/weapon/material/kitchen/utensil/fork = 6, - /obj/item/weapon/material/knife = 6, - /obj/item/weapon/material/kitchen/utensil/spoon = 6, - /obj/item/weapon/material/knife = 3, - /obj/item/weapon/material/kitchen/rollingpin = 2, - /obj/item/weapon/reagent_containers/food/drinks/glass2/square = 8, - /obj/item/weapon/reagent_containers/food/drinks/glass2/shake = 8, - /obj/item/weapon/glass_extra/stick = 15, - /obj/item/weapon/glass_extra/straw = 15, - /obj/item/clothing/suit/chef/classic = 2, - /obj/item/weapon/storage/bag/food = 2, - /obj/item/weapon/storage/toolbox/lunchbox = 3, - /obj/item/weapon/storage/toolbox/lunchbox/heart = 3, - /obj/item/weapon/storage/toolbox/lunchbox/cat = 3, - /obj/item/weapon/storage/toolbox/lunchbox/nt = 3, - /obj/item/weapon/storage/toolbox/lunchbox/mars = 3, - /obj/item/weapon/storage/toolbox/lunchbox/cti = 3, - /obj/item/weapon/storage/toolbox/lunchbox/nymph = 3, - /obj/item/weapon/storage/toolbox/lunchbox/syndicate = 3, - /obj/item/trash/bowl = 10) //VOREStation Add - contraband = list(/obj/item/weapon/material/knife/butch = 2) - -/obj/machinery/vending/sovietsoda - name = "BODA" - desc = "An old sweet water vending machine,how did this end up here?" - icon_state = "sovietsoda" - product_ads = "For Tsar and Country.;Have you fulfilled your nutrition quota today?;Very nice!;We are simple people, for this is all we eat.;If there is a person, there is a problem. If there is no person, then there is no problem." - products = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/space_up = 30) // TODO Russian soda can - contraband = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/cola = 20) // TODO Russian cola can - idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. - vending_sound = "machines/vending/vending_cans.ogg" - -/obj/machinery/vending/tool - name = "YouTool" - desc = "Tools for tools." - icon_state = "tool" - //req_access = list(access_maint_tunnels) //Maintenance access - products = list(/obj/item/stack/cable_coil/random = 10,/obj/item/weapon/tool/crowbar = 5,/obj/item/weapon/weldingtool = 3,/obj/item/weapon/tool/wirecutters = 5, - /obj/item/weapon/tool/wrench = 5,/obj/item/device/analyzer = 5,/obj/item/device/t_scanner = 5,/obj/item/weapon/tool/screwdriver = 5, - /obj/item/device/flashlight/glowstick = 3, /obj/item/device/flashlight/glowstick/red = 3, /obj/item/device/flashlight/glowstick/blue = 3, - /obj/item/device/flashlight/glowstick/orange =3, /obj/item/device/flashlight/glowstick/yellow = 3) - contraband = list(/obj/item/weapon/weldingtool/hugetank = 2,/obj/item/clothing/gloves/fyellow = 2,) - premium = list(/obj/item/clothing/gloves/yellow = 1) - req_log_access = access_ce - has_logs = 1 - -/obj/machinery/vending/engivend - name = "Engi-Vend" - desc = "Spare tool vending. What? Did you expect some witty description?" - icon_state = "engivend" - req_access = list(access_engine_equip) - products = list(/obj/item/device/geiger = 4,/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/cell/high = 10, - /obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/module/power_control = 10, - /obj/item/weapon/circuitboard/airalarm = 10,/obj/item/weapon/circuitboard/firealarm = 10,/obj/item/weapon/circuitboard/status_display = 2, - /obj/item/weapon/circuitboard/ai_status_display = 2,/obj/item/weapon/circuitboard/newscaster = 2,/obj/item/weapon/circuitboard/holopad = 2, - /obj/item/weapon/circuitboard/intercom = 4,/obj/item/weapon/circuitboard/security/telescreen/entertainment = 4, - /obj/item/weapon/stock_parts/motor = 2,/obj/item/weapon/stock_parts/spring = 2,/obj/item/weapon/stock_parts/gear = 2, - /obj/item/weapon/circuitboard/atm,/obj/item/weapon/circuitboard/guestpass,/obj/item/weapon/circuitboard/keycard_auth, - /obj/item/weapon/circuitboard/photocopier,/obj/item/weapon/circuitboard/fax,/obj/item/weapon/circuitboard/request, - /obj/item/weapon/circuitboard/microwave,/obj/item/weapon/circuitboard/washing,/obj/item/weapon/circuitboard/scanner_console, - /obj/item/weapon/circuitboard/sleeper_console,/obj/item/weapon/circuitboard/body_scanner,/obj/item/weapon/circuitboard/sleeper, - /obj/item/weapon/circuitboard/dna_analyzer) - contraband = list(/obj/item/weapon/cell/potato = 3) - premium = list(/obj/item/weapon/storage/belt/utility = 3) - product_records = list() - req_log_access = access_ce - has_logs = 1 - -/obj/machinery/vending/engineering - name = "Robco Tool Maker" - desc = "Everything you need for do-it-yourself station repair." - icon_state = "engi" - req_access = list(access_engine_equip) - products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/orange = 4,/obj/item/clothing/head/hardhat = 4, - /obj/item/weapon/storage/belt/utility = 4,/obj/item/clothing/glasses/meson = 4,/obj/item/clothing/gloves/yellow = 4, /obj/item/weapon/tool/screwdriver = 12, - /obj/item/weapon/tool/crowbar = 12,/obj/item/weapon/tool/wirecutters = 12,/obj/item/device/multitool = 12,/obj/item/weapon/tool/wrench = 12,/obj/item/device/t_scanner = 12, - /obj/item/stack/cable_coil/heavyduty = 8, /obj/item/weapon/cell = 8, /obj/item/weapon/weldingtool = 8,/obj/item/clothing/head/welding = 8, - /obj/item/weapon/light/tube = 10,/obj/item/clothing/suit/fire = 4, /obj/item/weapon/stock_parts/scanning_module = 5,/obj/item/weapon/stock_parts/micro_laser = 5, - /obj/item/weapon/stock_parts/matter_bin = 5,/obj/item/weapon/stock_parts/manipulator = 5,/obj/item/weapon/stock_parts/console_screen = 5) - // There was an incorrect entry (cablecoil/power). I improvised to cablecoil/heavyduty. - // Another invalid entry, /obj/item/weapon/circuitry. I don't even know what that would translate to, removed it. - // The original products list wasn't finished. The ones without given quantities became quantity 5. -Sayu - req_log_access = access_ce - has_logs = 1 - -/obj/machinery/vending/robotics - name = "Robotech Deluxe" - desc = "All the tools you need to create your own robot army." - icon_state = "robotics" - req_access = list(access_robotics) - products = list(/obj/item/clothing/suit/storage/toggle/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/stack/cable_coil = 4,/obj/item/device/flash = 4, - /obj/item/weapon/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3, - /obj/item/weapon/surgical/scalpel = 2,/obj/item/weapon/surgical/circular_saw = 2,/obj/item/weapon/tank/anesthetic = 2,/obj/item/clothing/mask/breath/medical = 5, - /obj/item/weapon/tool/screwdriver = 5,/obj/item/weapon/tool/crowbar = 5) - //everything after the power cell had no amounts, I improvised. -Sayu - req_log_access = access_rd - has_logs = 1 - -/obj/machinery/vending/giftvendor - name = "AlliCo Baubles and Confectionaries" - desc = "For that special someone!" - icon_state = "giftvendor" - vend_delay = 15 - products = list(/obj/item/weapon/storage/fancy/heartbox = 5, - /obj/item/toy/bouquet = 5, - /obj/item/toy/bouquet/fake = 4, - /obj/item/weapon/paper/card/smile = 3, - /obj/item/weapon/paper/card/heart = 3, - /obj/item/weapon/paper/card/cat = 3, - /obj/item/weapon/paper/card/flower = 3, - /obj/item/clothing/accessory/bracelet/friendship = 5, - /obj/item/toy/plushie/therapy/red = 2, - /obj/item/toy/plushie/therapy/purple = 2, - /obj/item/toy/plushie/therapy/blue = 2, - /obj/item/toy/plushie/therapy/yellow = 2, - /obj/item/toy/plushie/therapy/orange = 2, - /obj/item/toy/plushie/therapy/green = 2, - /obj/item/toy/plushie/nymph = 2, - /obj/item/toy/plushie/mouse = 2, - /obj/item/toy/plushie/kitten = 2, - /obj/item/toy/plushie/lizard = 2, - /obj/item/toy/plushie/spider = 2, - /obj/item/toy/plushie/farwa = 2, - /obj/item/toy/plushie/corgi = 1, - /obj/item/toy/plushie/octopus = 1, - /obj/item/toy/plushie/face_hugger = 1, - /obj/item/toy/plushie/carp = 1, - /obj/item/toy/plushie/deer = 1, - /obj/item/toy/plushie/tabby_cat = 1, - /obj/item/device/threadneedle = 3, - //VOREStation Add Start - /obj/item/toy/plushie/lizardplushie/kobold = 1, - /obj/item/toy/plushie/slimeplushie = 1, - /obj/item/toy/plushie/box = 1, - /obj/item/toy/plushie/borgplushie = 1, - /obj/item/toy/plushie/borgplushie/medihound = 1, - /obj/item/toy/plushie/borgplushie/scrubpuppy = 1, - /obj/item/toy/plushie/foxbear = 1, - /obj/item/toy/plushie/nukeplushie = 1, - /obj/item/toy/plushie/otter = 1) - //VOREStation Add End - premium = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne = 1, - /obj/item/weapon/storage/trinketbox = 2) - prices = list(/obj/item/weapon/storage/fancy/heartbox = 15, - /obj/item/toy/bouquet = 10, - /obj/item/toy/bouquet/fake = 3, - /obj/item/weapon/paper/card/smile = 1, - /obj/item/weapon/paper/card/heart = 1, - /obj/item/weapon/paper/card/cat = 1, - /obj/item/weapon/paper/card/flower = 1, - /obj/item/clothing/accessory/bracelet/friendship = 5, - /obj/item/toy/plushie/therapy/red = 20, - /obj/item/toy/plushie/therapy/purple = 20, - /obj/item/toy/plushie/therapy/blue = 20, - /obj/item/toy/plushie/therapy/yellow = 20, - /obj/item/toy/plushie/therapy/orange = 20, - /obj/item/toy/plushie/therapy/green = 20, - /obj/item/toy/plushie/nymph = 35, - /obj/item/toy/plushie/mouse = 35, - /obj/item/toy/plushie/kitten = 35, - /obj/item/toy/plushie/lizard = 35, - /obj/item/toy/plushie/spider = 35, - /obj/item/toy/plushie/farwa = 35, - /obj/item/toy/plushie/corgi = 50, - /obj/item/toy/plushie/octopus = 50, - /obj/item/toy/plushie/face_hugger = 50, - /obj/item/toy/plushie/carp = 50, - /obj/item/toy/plushie/deer = 50, - /obj/item/toy/plushie/tabby_cat = 50, - /obj/item/device/threadneedle = 2, - //VOREStation Add Start - /obj/item/toy/plushie/lizardplushie/kobold = 50, - /obj/item/toy/plushie/slimeplushie = 50, - /obj/item/toy/plushie/box = 50, - /obj/item/toy/plushie/borgplushie = 50, - /obj/item/toy/plushie/borgplushie/medihound = 50, - /obj/item/toy/plushie/borgplushie/scrubpuppy = 50, - /obj/item/toy/plushie/foxbear = 50, - /obj/item/toy/plushie/nukeplushie = 50, - /obj/item/toy/plushie/otter = 50) - //VOREStation Add End - - -/obj/machinery/vending/fishing - name = "Loot Trawler" - desc = "A special vendor for fishing equipment." - product_ads = "Tired of trawling across the ocean floor? Get our loot!;Chum and rods.;Don't get baited into fishing without us!;Baby is your star-sign pisces? We'd make a perfect match.;Do not fear, plenty to catch around here.;Don't get reeled in helplessly, get your own rod today!" - icon_state = "fishvendor" - products = list(/obj/item/weapon/material/fishing_rod/modern/cheap = 6, - /obj/item/weapon/storage/box/wormcan = 4, - /obj/item/weapon/storage/box/wormcan/sickly = 10, - /obj/item/weapon/material/fishing_net = 2, - /obj/item/stack/cable_coil/random = 6) - prices = list(/obj/item/weapon/material/fishing_rod/modern/cheap = 50, - /obj/item/weapon/storage/box/wormcan = 12, - /obj/item/weapon/storage/box/wormcan/sickly = 6, - /obj/item/weapon/material/fishing_net = 40, - /obj/item/stack/cable_coil/random = 4) - premium = list(/obj/item/weapon/storage/box/wormcan/deluxe = 1) - contraband = list(/obj/item/weapon/storage/box/wormcan/deluxe = 1) +//Actual machines are in vending_machines.dm diff --git a/code/game/machinery/vending_machines.dm b/code/game/machinery/vending_machines.dm new file mode 100644 index 00000000000..b631ee807e8 --- /dev/null +++ b/code/game/machinery/vending_machines.dm @@ -0,0 +1,570 @@ +// +//The code for machines are in vending.dm +//Only put machines here. +// +// + + +/* + * Vending machine types + */ + +/* + +/obj/machinery/vending/[vendors name here] // --vending machine template :) + name = "" + desc = "" + icon = '' + icon_state = "" + vend_delay = 15 + products = list() + contraband = list() + premium = list() + +*/ + +/* +/obj/machinery/vending/atmospherics //Commenting this out until someone ponies up some actual working, broken, and unpowered sprites - Quarxink + name = "Tank Vendor" + desc = "A vendor with a wide variety of masks and gas tanks." + icon = 'icons/obj/objects.dmi' + icon_state = "dispenser" + product_paths = "/obj/item/weapon/tank/oxygen;/obj/item/weapon/tank/phoron;/obj/item/weapon/tank/emergency_oxygen;/obj/item/weapon/tank/emergency_oxygen/engi;/obj/item/clothing/mask/breath" + productamounts = "10;10;10;5;25" + vend_delay = 0 +*/ + + + +/obj/machinery/vending/boozeomat + name = "Booze-O-Mat" + desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." + icon_state = "fridge_dark" + products = list(/obj/item/weapon/reagent_containers/food/drinks/glass2/square = 10, + /obj/item/weapon/reagent_containers/food/drinks/glass2/rocks = 10, + /obj/item/weapon/reagent_containers/food/drinks/glass2/shake = 10, + /obj/item/weapon/reagent_containers/food/drinks/glass2/cocktail = 10, + /obj/item/weapon/reagent_containers/food/drinks/glass2/shot = 10, + /obj/item/weapon/reagent_containers/food/drinks/glass2/pint = 10, + /obj/item/weapon/reagent_containers/food/drinks/glass2/mug = 10, + /obj/item/weapon/reagent_containers/food/drinks/glass2/wine = 10, + /obj/item/weapon/reagent_containers/food/drinks/glass2/carafe = 2, //VOREStation Add - Carafes and Pitchers + /obj/item/weapon/reagent_containers/food/drinks/glass2/pitcher = 2, //VOREStation Add - Carafes and Pitchers + /obj/item/weapon/reagent_containers/food/drinks/metaglass = 10, + /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/cognac = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine = 5, + /obj/item/weapon/reagent_containers/food/condiment/cornoil = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/peppermintschnapps = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/peachschnapps = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/lemonadeschnapps = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/rum = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/sake = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/vodka = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/cider = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/lemonjuice = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/applejuice = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/milk = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/cream = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/cola = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/space_up = 5, + /obj/item/weapon/reagent_containers/food/drinks/bottle/space_mountain_wind = 5, + /obj/item/weapon/reagent_containers/food/drinks/cans/sodawater = 15, + /obj/item/weapon/reagent_containers/food/drinks/cans/tonic = 15, + /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 15, + /obj/item/weapon/reagent_containers/food/drinks/flask/barflask = 5, + /obj/item/weapon/reagent_containers/food/drinks/flask/vacuumflask = 5, + /obj/item/weapon/reagent_containers/food/drinks/ice = 10, + /obj/item/weapon/reagent_containers/food/drinks/tea = 15, + /obj/item/weapon/glass_extra/stick = 30, + /obj/item/weapon/glass_extra/straw = 30) + contraband = list() + vend_delay = 15 + idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. + product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?" + product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!" + req_access = list(access_bar) + req_log_access = access_bar + has_logs = 1 + vending_sound = "machines/vending/vending_cans.ogg" + +/obj/machinery/vending/assist + products = list( /obj/item/device/assembly/prox_sensor = 5,/obj/item/device/assembly/igniter = 3,/obj/item/device/assembly/signaler = 4, + /obj/item/weapon/tool/wirecutters = 1, /obj/item/weapon/cartridge/signal = 4) + contraband = list(/obj/item/device/flashlight = 5,/obj/item/device/assembly/timer = 2) + product_ads = "Only the finest!;Have some tools.;The most robust equipment.;The finest gear in space!" + +/obj/machinery/vending/coffee + name = "Hot Drinks machine" + desc = "A vending machine which dispenses hot drinks." + product_ads = "Have a drink!;Drink up!;It's good for you!;Would you like a hot joe?;I'd kill for some coffee!;The best beans in the galaxy.;Only the finest brew for you.;Mmmm. Nothing like a coffee.;I like coffee, don't you?;Coffee helps you work!;Try some tea.;We hope you like the best!;Try our new chocolate!;Admin conspiracies" + icon_state = "coffee" + vend_delay = 34 + idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. + vend_power_usage = 85000 //85 kJ to heat a 250 mL cup of coffee + products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25) + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10) + prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 2, /obj/item/weapon/reagent_containers/food/drinks/tea = 2, /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 2) //VOREStation Edit + vending_sound = "machines/vending/vending_coffee.ogg" + +/obj/machinery/vending/snack + name = "Getmore Chocolate Corp" + desc = "A snack machine courtesy of the Getmore Chocolate Corporation, based out of Mars." + product_slogans = "Try our new nougat bar!;Twice the calories for half the price!" + product_ads = "The healthiest!;Award-winning chocolate bars!;Mmm! So good!;Oh my god it's so juicy!;Have a snack.;Snacks are good for you!;Have some more Getmore!;Best quality snacks straight from mars.;We love chocolate!;Try our new jerky!" + icon_state = "snack" + products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 12,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 12,/obj/item/weapon/reagent_containers/food/snacks/chips =12, + /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 12,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 12,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 12, + /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 12, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 12, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 6) + contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6,/obj/item/weapon/reagent_containers/food/snacks/unajerky = 12,) + prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 1,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 5,/obj/item/weapon/reagent_containers/food/snacks/chips = 1, + /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 2,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 1,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 1, + /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 1, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 2, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 2) + +/obj/machinery/vending/cola + name = "Robust Softdrinks" + desc = "A softdrink vendor provided by Robust Industries, LLC." + icon_state = "Cola_Machine" + product_slogans = "Robust Softdrinks: More robust than a toolbox to the head!" + product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space." + products = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 10, + /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 10) + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/cans/thirteenloko = 5, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 6) + prices = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 2,/obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 1, + /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 1) + idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. + vending_sound = "machines/vending/vending_cans.ogg" + +/obj/machinery/vending/fitness + name = "SweatMAX" + desc = "Fueled by your inner inadequacy!" + icon_state = "fitness" + //VOREStation Edit Start + products = list(/obj/item/weapon/reagent_containers/food/drinks/smallmilk = 16, + /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk = 16, + /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 8, + /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 8, + /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 16, + /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 8, + /obj/item/weapon/reagent_containers/pill/diet = 8, + ///obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5, //VOREStation Removal, + /obj/item/weapon/towel/random = 8, + /obj/item/toy/tennis = 4) + + prices = list(/obj/item/weapon/reagent_containers/food/drinks/smallmilk = 3, + /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk = 3, + /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 15, + /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 1, + /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 5, + /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 5, + /obj/item/weapon/reagent_containers/pill/diet = 25, + ///obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5, + /obj/item/weapon/towel/random = 20, + /obj/item/toy/tennis = 15) + //VOREStation Edit End + + contraband = list(/obj/item/weapon/reagent_containers/syringe/steroid = 4, /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteanshake = 2) // VOREStation Add - Slurpable blobs. + +/obj/machinery/vending/cart + name = "PTech" + desc = "Cartridges for PDAs." + product_slogans = "Carts to go!" + icon_state = "cart" + req_access = list(access_hop) + products = list(/obj/item/weapon/cartridge/medical = 10,/obj/item/weapon/cartridge/engineering = 10,/obj/item/weapon/cartridge/security = 10, + /obj/item/weapon/cartridge/janitor = 10,/obj/item/weapon/cartridge/signal/science = 10,/obj/item/device/pda/heads = 10, + /obj/item/weapon/cartridge/captain = 3,/obj/item/weapon/cartridge/quartermaster = 10) + req_log_access = access_hop + has_logs = 1 + +/obj/machinery/vending/cigarette + name = "cigarette machine" + desc = "If you want to get cancer, might as well do it in style!" + product_slogans = "Space cigs taste good like a cigarette should.;I'd rather toolbox than switch.;Smoke!;Don't believe the reports - smoke today!" + product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 2150.;Award-winning cigs.;Feeling temperamental? Try a Temperamento!;Carcinoma Angels - go fuck yerself!;Don't be so hard on yourself, kid. Smoke a Lucky Star!" + vend_delay = 34 + icon_state = "cigs" + products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, + /obj/item/weapon/storage/fancy/cigarettes/dromedaryco = 10, + /obj/item/weapon/storage/fancy/cigarettes/killthroat = 10, + /obj/item/weapon/storage/fancy/cigarettes/luckystars = 10, + /obj/item/weapon/storage/fancy/cigarettes/jerichos = 10, + /obj/item/weapon/storage/fancy/cigarettes/menthols = 10, + /obj/item/weapon/storage/rollingpapers = 10, + /obj/item/weapon/storage/box/matches = 10, + /obj/item/weapon/flame/lighter/random = 4) + contraband = list(/obj/item/weapon/flame/lighter/zippo = 4) + premium = list(/obj/item/weapon/storage/fancy/cigar = 5, + /obj/item/weapon/storage/fancy/cigarettes/carcinomas = 5, + /obj/item/weapon/storage/fancy/cigarettes/professionals = 5) + prices = list(/obj/item/weapon/storage/fancy/cigarettes = 12, + /obj/item/weapon/storage/fancy/cigarettes/dromedaryco = 15, + /obj/item/weapon/storage/fancy/cigarettes/killthroat = 17, + /obj/item/weapon/storage/fancy/cigarettes/luckystars = 17, + /obj/item/weapon/storage/fancy/cigarettes/jerichos = 22, + /obj/item/weapon/storage/fancy/cigarettes/menthols = 18, + /obj/item/weapon/storage/rollingpapers = 10, + /obj/item/weapon/storage/box/matches = 1, + /obj/item/weapon/flame/lighter/random = 2) + +/obj/machinery/vending/medical + name = "NanoMed Plus" + desc = "Medical drug dispenser." + icon_state = "med" + product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!" + req_access = list(access_medical) + products = list(/obj/item/weapon/reagent_containers/glass/bottle/antitoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline = 4, + /obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4, + /obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12, + /obj/item/device/healthanalyzer = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4, /obj/item/weapon/reagent_containers/dropper = 2, + /obj/item/stack/medical/advanced/bruise_pack = 6, /obj/item/stack/medical/advanced/ointment = 6, /obj/item/stack/medical/splint = 4, + /obj/item/weapon/storage/pill_bottle/carbon = 2) + contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3,/obj/item/weapon/reagent_containers/pill/stox = 4,/obj/item/weapon/reagent_containers/pill/antitox = 6) + idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. + req_log_access = access_cmo + has_logs = 1 + +/obj/machinery/vending/phoronresearch + name = "Toximate 3000" + desc = "All the fine parts you need in one vending machine!" + products = list(/obj/item/clothing/under/rank/scientist = 6,/obj/item/clothing/suit/bio_suit = 6,/obj/item/clothing/head/bio_hood = 6, + /obj/item/device/transfer_valve = 6,/obj/item/device/assembly/timer = 6,/obj/item/device/assembly/signaler = 6, + /obj/item/device/assembly/prox_sensor = 6,/obj/item/device/assembly/igniter = 6) + req_log_access = access_rd + has_logs = 1 + +/obj/machinery/vending/wallmed1 + name = "NanoMed" + desc = "A wall-mounted version of the NanoMed." + product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?" + icon_state = "wallmed" + density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude + products = list(/obj/item/stack/medical/bruise_pack = 2,/obj/item/stack/medical/ointment = 2,/obj/item/weapon/reagent_containers/hypospray/autoinjector = 4,/obj/item/device/healthanalyzer = 1) + contraband = list(/obj/item/weapon/reagent_containers/syringe/antitoxin = 4,/obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/pill/tox = 1) + req_log_access = access_cmo + has_logs = 1 + can_rotate = 0 + +/obj/machinery/vending/wallmed2 + name = "NanoMed" + desc = "A wall-mounted version of the NanoMed, containing only vital first aid equipment." + icon_state = "wallmed" + density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude + products = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector = 5,/obj/item/weapon/reagent_containers/syringe/antitoxin = 3,/obj/item/stack/medical/bruise_pack = 3, + /obj/item/stack/medical/ointment =3,/obj/item/device/healthanalyzer = 3) + contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 3) + req_log_access = access_cmo + has_logs = 1 + can_rotate = 0 + +/obj/machinery/vending/security + name = "SecTech" + desc = "A security equipment vendor." + product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?" + icon_state = "sec" + req_access = list(access_security) + products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, + /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6) + contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/box/donut = 2) + req_log_access = access_armory + has_logs = 1 + +/obj/machinery/vending/hydronutrients + name = "NutriMax" + desc = "A plant nutrients vendor." + product_slogans = "Aren't you glad you don't have to fertilize the natural way?;Now with 50% less stink!;Plants are people too!" + product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..." + icon_state = "nutri_generic" + products = list(/obj/item/weapon/reagent_containers/glass/bottle/eznutrient = 6,/obj/item/weapon/reagent_containers/glass/bottle/left4zed = 4,/obj/item/weapon/reagent_containers/glass/bottle/robustharvest = 3,/obj/item/weapon/plantspray/pests = 20, + /obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/reagent_containers/glass/beaker = 4,/obj/item/weapon/storage/bag/plants = 5) + premium = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5) + idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. + + +/obj/machinery/vending/hydroseeds + name = "MegaSeed Servitor" + desc = "When you need seeds fast!" + product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" + product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" + icon_state = "seeds_generic" + + products = list(/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/chantermycelium = 3,/obj/item/seeds/chiliseed = 3, + /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3, + /obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3, + /obj/item/seeds/poppyseed = 3,/obj/item/seeds/sugarcaneseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/peanutseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/lavenderseed = 3,/obj/item/seeds/limeseed = 3, + /obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,/obj/item/seeds/plumpmycelium = 2, + /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3) + contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/mtearseed = 2, + /obj/item/seeds/nettleseed = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/shandseed = 2,) + premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1) + +/** + * Populate hydroseeds product_records + * + * This needs to be customized to fetch the actual names of the seeds, otherwise + * the machine would simply list "packet of seeds" times 20 + */ +/obj/machinery/vending/hydroseeds/build_inventory() + var/list/all_products = list( + list(products, CAT_NORMAL), + list(contraband, CAT_HIDDEN), + list(premium, CAT_COIN)) + + for(var/current_list in all_products) + var/category = current_list[2] + + for(var/entry in current_list[1]) + var/obj/item/seeds/S = new entry(src) + var/name = S.name + var/datum/stored_item/vending_product/product = new/datum/stored_item/vending_product(src, entry, name) + + product.price = (entry in prices) ? prices[entry] : 0 + product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 + product.category = category + + product_records.Add(product) + +/obj/machinery/vending/magivend + name = "MagiVend" + desc = "A magic vending machine." + icon_state = "MagiVend" + product_slogans = "Sling spells the proper way with MagiVend!;Be your own Houdini! Use MagiVend!" + vend_delay = 15 + vend_reply = "Have an enchanted evening!" + product_ads = "FJKLFJSD;AJKFLBJAKL;1234 LOONIES LOL!;>MFW;Kill them fuckers!;GET DAT FUKKEN DISK;HONK!;EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!" + products = list(/obj/item/clothing/head/wizard = 1,/obj/item/clothing/suit/wizrobe = 1,/obj/item/clothing/head/wizard/red = 1,/obj/item/clothing/suit/wizrobe/red = 1,/obj/item/clothing/shoes/sandal = 1,/obj/item/weapon/staff = 2) + +/obj/machinery/vending/dinnerware + name = "Dinnerware" + desc = "A kitchen and restaurant equipment vendor." + product_ads = "Mm, food stuffs!;Food and food accessories.;Get your plates!;You like forks?;I like forks.;Woo, utensils.;You don't really need these..." + icon_state = "dinnerware" + products = list( + /obj/item/weapon/reagent_containers/food/condiment/yeast = 5, + /obj/item/weapon/reagent_containers/food/condiment/cornoil = 5, + /obj/item/weapon/tray = 8, + /obj/item/weapon/material/kitchen/utensil/fork = 6, + /obj/item/weapon/material/knife/plastic = 6, + /obj/item/weapon/material/kitchen/utensil/spoon = 6, + /obj/item/weapon/material/knife = 3, + /obj/item/weapon/material/kitchen/rollingpin = 2, + /obj/item/weapon/reagent_containers/food/drinks/glass2/square = 8, + /obj/item/weapon/reagent_containers/food/drinks/glass2/shake = 8, + /obj/item/weapon/glass_extra/stick = 15, + /obj/item/weapon/glass_extra/straw = 15, + /obj/item/clothing/suit/chef/classic = 2, + /obj/item/weapon/storage/bag/food = 2, + /obj/item/weapon/storage/toolbox/lunchbox = 3, + /obj/item/weapon/storage/toolbox/lunchbox/heart = 3, + /obj/item/weapon/storage/toolbox/lunchbox/cat = 3, + /obj/item/weapon/storage/toolbox/lunchbox/nt = 3, + /obj/item/weapon/storage/toolbox/lunchbox/mars = 3, + /obj/item/weapon/storage/toolbox/lunchbox/cti = 3, + /obj/item/weapon/storage/toolbox/lunchbox/nymph = 3, + /obj/item/weapon/storage/toolbox/lunchbox/syndicate = 3, + /obj/item/weapon/reagent_containers/cooking_container/oven = 5, + /obj/item/weapon/reagent_containers/cooking_container/fryer = 4, + /obj/item/trash/bowl = 10) //VOREStation Add + contraband = list(/obj/item/weapon/material/knife/butch = 2) + +/obj/machinery/vending/sovietsoda + name = "BODA" + desc = "An old sweet water vending machine,how did this end up here?" + icon_state = "sovietsoda" + product_ads = "For Tsar and Country.;Have you fulfilled your nutrition quota today?;Very nice!;We are simple people, for this is all we eat.;If there is a person, there is a problem. If there is no person, then there is no problem." + products = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/space_up = 30) // TODO Russian soda can + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/cola = 20) // TODO Russian cola can + idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. + vending_sound = "machines/vending/vending_cans.ogg" + +/obj/machinery/vending/tool + name = "YouTool" + desc = "Tools for tools." + icon_state = "tool" + //req_access = list(access_maint_tunnels) //Maintenance access + products = list(/obj/item/stack/cable_coil/random = 10,/obj/item/weapon/tool/crowbar = 5,/obj/item/weapon/weldingtool = 3,/obj/item/weapon/tool/wirecutters = 5, + /obj/item/weapon/tool/wrench = 5,/obj/item/device/analyzer = 5,/obj/item/device/t_scanner = 5,/obj/item/weapon/tool/screwdriver = 5, + /obj/item/device/flashlight/glowstick = 3, /obj/item/device/flashlight/glowstick/red = 3, /obj/item/device/flashlight/glowstick/blue = 3, + /obj/item/device/flashlight/glowstick/orange =3, /obj/item/device/flashlight/glowstick/yellow = 3) + contraband = list(/obj/item/weapon/weldingtool/hugetank = 2,/obj/item/clothing/gloves/fyellow = 2,) + premium = list(/obj/item/clothing/gloves/yellow = 1) + req_log_access = access_ce + has_logs = 1 + +/obj/machinery/vending/engivend + name = "Engi-Vend" + desc = "Spare tool vending. What? Did you expect some witty description?" + icon_state = "engivend" + req_access = list(access_engine_equip) + products = list(/obj/item/device/geiger = 4,/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/cell/high = 10, + /obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/module/power_control = 10, + /obj/item/weapon/circuitboard/airalarm = 10,/obj/item/weapon/circuitboard/firealarm = 10,/obj/item/weapon/circuitboard/status_display = 2, + /obj/item/weapon/circuitboard/ai_status_display = 2,/obj/item/weapon/circuitboard/newscaster = 2,/obj/item/weapon/circuitboard/holopad = 2, + /obj/item/weapon/circuitboard/intercom = 4,/obj/item/weapon/circuitboard/security/telescreen/entertainment = 4, + /obj/item/weapon/stock_parts/motor = 2,/obj/item/weapon/stock_parts/spring = 2,/obj/item/weapon/stock_parts/gear = 2, + /obj/item/weapon/circuitboard/atm,/obj/item/weapon/circuitboard/guestpass,/obj/item/weapon/circuitboard/keycard_auth, + /obj/item/weapon/circuitboard/photocopier,/obj/item/weapon/circuitboard/fax,/obj/item/weapon/circuitboard/request, + /obj/item/weapon/circuitboard/microwave,/obj/item/weapon/circuitboard/washing,/obj/item/weapon/circuitboard/scanner_console, + /obj/item/weapon/circuitboard/sleeper_console,/obj/item/weapon/circuitboard/body_scanner,/obj/item/weapon/circuitboard/sleeper, + /obj/item/weapon/circuitboard/dna_analyzer) + contraband = list(/obj/item/weapon/cell/potato = 3) + premium = list(/obj/item/weapon/storage/belt/utility = 3) + product_records = list() + req_log_access = access_ce + has_logs = 1 + +/obj/machinery/vending/engineering + name = "Robco Tool Maker" + desc = "Everything you need for do-it-yourself station repair." + icon_state = "engi" + req_access = list(access_engine_equip) + products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/orange = 4,/obj/item/clothing/head/hardhat = 4, + /obj/item/weapon/storage/belt/utility = 4,/obj/item/clothing/glasses/meson = 4,/obj/item/clothing/gloves/yellow = 4, /obj/item/weapon/tool/screwdriver = 12, + /obj/item/weapon/tool/crowbar = 12,/obj/item/weapon/tool/wirecutters = 12,/obj/item/device/multitool = 12,/obj/item/weapon/tool/wrench = 12,/obj/item/device/t_scanner = 12, + /obj/item/stack/cable_coil/heavyduty = 8, /obj/item/weapon/cell = 8, /obj/item/weapon/weldingtool = 8,/obj/item/clothing/head/welding = 8, + /obj/item/weapon/light/tube = 10,/obj/item/clothing/suit/fire = 4, /obj/item/weapon/stock_parts/scanning_module = 5,/obj/item/weapon/stock_parts/micro_laser = 5, + /obj/item/weapon/stock_parts/matter_bin = 5,/obj/item/weapon/stock_parts/manipulator = 5,/obj/item/weapon/stock_parts/console_screen = 5) + // There was an incorrect entry (cablecoil/power). I improvised to cablecoil/heavyduty. + // Another invalid entry, /obj/item/weapon/circuitry. I don't even know what that would translate to, removed it. + // The original products list wasn't finished. The ones without given quantities became quantity 5. -Sayu + req_log_access = access_ce + has_logs = 1 + +/obj/machinery/vending/robotics + name = "Robotech Deluxe" + desc = "All the tools you need to create your own robot army." + icon_state = "robotics" + req_access = list(access_robotics) + products = list(/obj/item/clothing/suit/storage/toggle/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/stack/cable_coil = 4,/obj/item/device/flash = 4, + /obj/item/weapon/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3, + /obj/item/weapon/surgical/scalpel = 2,/obj/item/weapon/surgical/circular_saw = 2,/obj/item/weapon/tank/anesthetic = 2,/obj/item/clothing/mask/breath/medical = 5, + /obj/item/weapon/tool/screwdriver = 5,/obj/item/weapon/tool/crowbar = 5) + //everything after the power cell had no amounts, I improvised. -Sayu + req_log_access = access_rd + has_logs = 1 + +/obj/machinery/vending/giftvendor + name = "AlliCo Baubles and Confectionaries" + desc = "For that special someone!" + icon_state = "giftvendor" + vend_delay = 15 + products = list(/obj/item/weapon/storage/fancy/heartbox = 5, + /obj/item/toy/bouquet = 5, + /obj/item/toy/bouquet/fake = 4, + /obj/item/weapon/paper/card/smile = 3, + /obj/item/weapon/paper/card/heart = 3, + /obj/item/weapon/paper/card/cat = 3, + /obj/item/weapon/paper/card/flower = 3, + /obj/item/clothing/accessory/bracelet/friendship = 5, + /obj/item/toy/plushie/therapy/red = 2, + /obj/item/toy/plushie/therapy/purple = 2, + /obj/item/toy/plushie/therapy/blue = 2, + /obj/item/toy/plushie/therapy/yellow = 2, + /obj/item/toy/plushie/therapy/orange = 2, + /obj/item/toy/plushie/therapy/green = 2, + /obj/item/toy/plushie/nymph = 2, + /obj/item/toy/plushie/mouse = 2, + /obj/item/toy/plushie/kitten = 2, + /obj/item/toy/plushie/lizard = 2, + /obj/item/toy/plushie/spider = 2, + /obj/item/toy/plushie/farwa = 2, + /obj/item/toy/plushie/corgi = 1, + /obj/item/toy/plushie/octopus = 1, + /obj/item/toy/plushie/face_hugger = 1, + /obj/item/toy/plushie/carp = 1, + /obj/item/toy/plushie/deer = 1, + /obj/item/toy/plushie/tabby_cat = 1, + /obj/item/device/threadneedle = 3, + //VOREStation Add Start + /obj/item/toy/plushie/lizardplushie/kobold = 1, + /obj/item/toy/plushie/slimeplushie = 1, + /obj/item/toy/plushie/box = 1, + /obj/item/toy/plushie/borgplushie = 1, + /obj/item/toy/plushie/borgplushie/medihound = 1, + /obj/item/toy/plushie/borgplushie/scrubpuppy = 1, + /obj/item/toy/plushie/foxbear = 1, + /obj/item/toy/plushie/nukeplushie = 1, + /obj/item/toy/plushie/otter = 1) + //VOREStation Add End + premium = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/champagne = 1, + /obj/item/weapon/storage/trinketbox = 2) + prices = list(/obj/item/weapon/storage/fancy/heartbox = 15, + /obj/item/toy/bouquet = 10, + /obj/item/toy/bouquet/fake = 3, + /obj/item/weapon/paper/card/smile = 1, + /obj/item/weapon/paper/card/heart = 1, + /obj/item/weapon/paper/card/cat = 1, + /obj/item/weapon/paper/card/flower = 1, + /obj/item/clothing/accessory/bracelet/friendship = 5, + /obj/item/toy/plushie/therapy/red = 20, + /obj/item/toy/plushie/therapy/purple = 20, + /obj/item/toy/plushie/therapy/blue = 20, + /obj/item/toy/plushie/therapy/yellow = 20, + /obj/item/toy/plushie/therapy/orange = 20, + /obj/item/toy/plushie/therapy/green = 20, + /obj/item/toy/plushie/nymph = 35, + /obj/item/toy/plushie/mouse = 35, + /obj/item/toy/plushie/kitten = 35, + /obj/item/toy/plushie/lizard = 35, + /obj/item/toy/plushie/spider = 35, + /obj/item/toy/plushie/farwa = 35, + /obj/item/toy/plushie/corgi = 50, + /obj/item/toy/plushie/octopus = 50, + /obj/item/toy/plushie/face_hugger = 50, + /obj/item/toy/plushie/carp = 50, + /obj/item/toy/plushie/deer = 50, + /obj/item/toy/plushie/tabby_cat = 50, + /obj/item/device/threadneedle = 2, + //VOREStation Add Start + /obj/item/toy/plushie/lizardplushie/kobold = 50, + /obj/item/toy/plushie/slimeplushie = 50, + /obj/item/toy/plushie/box = 50, + /obj/item/toy/plushie/borgplushie = 50, + /obj/item/toy/plushie/borgplushie/medihound = 50, + /obj/item/toy/plushie/borgplushie/scrubpuppy = 50, + /obj/item/toy/plushie/foxbear = 50, + /obj/item/toy/plushie/nukeplushie = 50, + /obj/item/toy/plushie/otter = 50) + //VOREStation Add End + + +/obj/machinery/vending/fishing + name = "Loot Trawler" + desc = "A special vendor for fishing equipment." + product_ads = "Tired of trawling across the ocean floor? Get our loot!;Chum and rods.;Don't get baited into fishing without us!;Baby is your star-sign pisces? We'd make a perfect match.;Do not fear, plenty to catch around here.;Don't get reeled in helplessly, get your own rod today!" + icon_state = "fishvendor" + products = list(/obj/item/weapon/material/fishing_rod/modern/cheap = 6, + /obj/item/weapon/storage/box/wormcan = 4, + /obj/item/weapon/storage/box/wormcan/sickly = 10, + /obj/item/weapon/material/fishing_net = 2, + /obj/item/glass_jar/fish = 4, + /obj/item/stack/cable_coil/random = 6) + prices = list(/obj/item/weapon/material/fishing_rod/modern/cheap = 50, + /obj/item/weapon/storage/box/wormcan = 12, + /obj/item/weapon/storage/box/wormcan/sickly = 6, + /obj/item/weapon/material/fishing_net = 40, + /obj/item/glass_jar/fish = 10, + /obj/item/stack/cable_coil/random = 4) + premium = list(/obj/item/weapon/storage/box/wormcan/deluxe = 1) + contraband = list(/obj/item/weapon/storage/box/wormcan/deluxe = 1) diff --git a/code/game/machinery/vending_vr.dm b/code/game/machinery/vending_machines_vr.dm similarity index 100% rename from code/game/machinery/vending_vr.dm rename to code/game/machinery/vending_machines_vr.dm diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index cb3e3199153..2cd581c9f1b 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -1,6 +1,6 @@ /obj/machinery/washing_machine name = "Washing Machine" - desc = "Not a hiding place." + desc = "Not a hiding place. Unfit for pets." icon = 'icons/obj/machines/washing_machine_vr.dmi' //VOREStation Edit icon_state = "wm_1" //VOREStation Edit density = 1 @@ -33,10 +33,16 @@ . = ..() default_apply_parts() -/obj/machinery/washing_machine/verb/start() +/obj/machinery/washing_machine/AltClick() + start() + +/obj/machinery/washing_machine/verb/start_washing() set name = "Start Washing" set category = "Object" set src in oview(1) + start() + +/obj/machinery/washing_machine/proc/start() if(!istype(usr, /mob/living)) //ew ew ew usr, but it's the only way to check. return @@ -50,6 +56,7 @@ else state = 5 update_icon() + to_chat(usr, "The washing machine starts a cycle.") playsound(src, 'sound/items/washingmachine.ogg', 50, 1, 1) sleep(200) for(var/atom/A in washing) @@ -172,4 +179,4 @@ state = 1 washing.Cut() - update_icon() \ No newline at end of file + update_icon() diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index b5d3351b21c..d618d276c30 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -17,6 +17,14 @@ max_special_equip = 1 cargo_capacity = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull/durable, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/reinforced, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + /* /obj/mecha/combat/range_action(target as obj|mob|turf) if(internal_damage&MECHA_INT_CONTROL_LOST) diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm index ab46a48fbc1..aa5a9e000c1 100644 --- a/code/game/mecha/combat/durand.dm +++ b/code/game/mecha/combat/durand.dm @@ -5,23 +5,34 @@ initial_icon = "durand" step_in = 4 dir_in = 1 //Facing North. - health = 400 - maxhealth = 400 + health = 300 + maxhealth = 300 //Don't forget to update the /old variant if you change this number. deflect_chance = 20 damage_absorption = list("brute"=0.5,"fire"=1.1,"bullet"=0.65,"laser"=0.85,"energy"=0.9,"bomb"=0.8) max_temperature = 30000 infra_luminosity = 8 force = 40 - var/defence = 0 - var/defence_deflect = 35 wreckage = /obj/effect/decal/mecha_wreckage/durand + damage_minimum = 15 //Big stompy + minimum_penetration = 25 + max_hull_equip = 2 max_weapon_equip = 1 max_utility_equip = 2 max_universal_equip = 1 max_special_equip = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull/durable, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/military, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + + defence_mode_possible = 1 + /* /obj/mecha/combat/durand/New() ..() @@ -31,40 +42,9 @@ return */ -/obj/mecha/combat/durand/relaymove(mob/user,direction) - if(defence) - if(world.time - last_message > 20) - src.occupant_message("Unable to move while in defence mode") - last_message = world.time - return 0 - . = ..() - return -/obj/mecha/combat/durand/verb/defence_mode() - set category = "Exosuit Interface" - set name = "Toggle defence mode" - set src = usr.loc - set popup_menu = 0 - if(usr!=src.occupant) - return - playsound(src, 'sound/mecha/duranddefencemode.ogg', 50, 1) - defence = !defence - if(defence) - deflect_chance = defence_deflect - src.occupant_message("You enable [src] defence mode.") - else - deflect_chance = initial(deflect_chance) - src.occupant_message("You disable [src] defence mode.") - src.log_message("Toggled defence mode.") - return - - -/obj/mecha/combat/durand/get_stats_part() - var/output = ..() - output += "Defence mode: [defence?"on":"off"]" - return output - +//This is for the Mech stats / Menu system. To be moved later on. /obj/mecha/combat/durand/get_commands() var/output = {"
Special
@@ -76,8 +56,30 @@ output += ..() return output + +//Not needed anymore but left for reference. +/* +/obj/mecha/combat/durand/get_stats_part() + var/output = ..() + output += "Defence mode: [defence?"on":"off"]" + return output +*/ + +/* + /obj/mecha/combat/durand/Topic(href, href_list) ..() if (href_list["toggle_defence_mode"]) src.defence_mode() - return \ No newline at end of file + return +*/ + +//Meant for random spawns. +/obj/mecha/combat/durand/old + desc = "An aging combat exosuit utilized by many corporations. Originally developed to combat hostile alien lifeforms. This one is particularly worn looking and likely isn't as sturdy." + +/obj/mecha/combat/durand/old/New() + ..() + health = 25 + maxhealth = 250 //Just slightly worse. + cell.charge = rand(0, (cell.charge/2)) \ No newline at end of file diff --git a/code/game/mecha/combat/gorilla.dm b/code/game/mecha/combat/gorilla.dm index 2f75de4a154..4052afe8e6a 100644 --- a/code/game/mecha/combat/gorilla.dm +++ b/code/game/mecha/combat/gorilla.dm @@ -1,3 +1,116 @@ + +/obj/mecha/combat/gorilla + name = "Gorilla" + desc = "Blitzkrieg!" //stop using all caps in item descs i will fight you. its redundant with the bold. + icon = 'icons/mecha/mecha64x64.dmi' + icon_state = "pzrmech" + initial_icon = "pzrmech" + pixel_x = -16 + step_in = 10 + health = 5000 + maxhealth = 5000 + opacity = 0 // Because there's big tall legs to look through. Also it looks fucky if this is set to 1. + deflect_chance = 50 + damage_absorption = list("brute"=0.1,"fire"=0.8,"bullet"=0.1,"laser"=0.6,"energy"=0.7,"bomb"=0.7) //values show how much damage will pass through, not how much will be absorbed. + max_temperature = 35000 //Just a bit better than the Durand. + infra_luminosity = 3 + wreckage = /obj/effect/decal/mecha_wreckage/gorilla + add_req_access = 0 + internal_damage_threshold = 25 + force = 60 + max_equip = 5 +//This will (Should) never be in the hands of players. If it is, the one who inflicted this monster upon the server can edit these vars to not be insane. + max_hull_equip = 5 + max_weapon_equip = 5 + max_utility_equip = 5 + max_universal_equip = 5 + max_special_equip = 2 + + smoke_possible = 1 + zoom_possible = 1 + thrusters_possible = 1 + +/obj/mecha/combat/gorilla/Initialize() + ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) // This thing basically cannot function without an external power supply. + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon/weak(src) //Saves energy, I suppose. Anti-infantry. + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src) + ME.attach(src) + return + +/obj/mecha/combat/gorilla/mechstep(direction) + var/result = step(src,direction) + playsound(src,"mechstep",40,1) + return result + +/obj/mecha/combat/gorilla/mechturn(direction) + dir = direction + playsound(src,"mechstep",40,1) + + +/obj/mecha/combat/gorilla/relaymove(mob/user,direction) + if(user != src.occupant) + user.loc = get_turf(src) + to_chat(user, "You climb out from [src]") + return 0 + if(!can_move) + return 0 + if(zoom) + if(world.time - last_message > 20) + src.occupant_message("Unable to move while in zoom mode.") + last_message = world.time + return 0 + if(connected_port) + if(world.time - last_message > 20) + src.occupant_message("Unable to move while connected to the air system port") + last_message = world.time + return 0 + if(state || !has_charge(step_energy_drain)) + return 0 + var/tmp_step_in = step_in + var/tmp_step_energy_drain = step_energy_drain + var/move_result = 0 + if(internal_damage&MECHA_INT_CONTROL_LOST) + move_result = mechsteprand() + else if(src.dir!=direction) + move_result = mechturn(direction) + else + move_result = mechstep(direction) + if(move_result) + if(istype(src.loc, /turf/space)) + if(!src.check_for_support()) + src.pr_inertial_movement.start(list(src,direction)) + can_move = 0 + spawn(tmp_step_in) can_move = 1 + use_power(tmp_step_energy_drain) + return 1 + return 0 + + +/obj/mecha/combat/gorilla/get_stats_part() + var/output = ..() + output += {"Smoke: [smoke_reserve]"} + return output + + +/obj/mecha/combat/gorilla/get_commands() + var/output = {"
+
Special
+ +
+ "} + output += ..() + return output + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon name = "8.8cm KwK 47" desc = "Precision German engineering!" // Why would you ever take this off the mech, anyway? @@ -54,167 +167,3 @@ plane = MOB_PLANE pixel_x = -16 anchored = 1 // It's fucking huge. You aren't moving it. - -/obj/mecha/combat/gorilla - name = "Gorilla" - desc = "Blitzkrieg!" //stop using all caps in item descs i will fight you. its redundant with the bold. - icon = 'icons/mecha/mecha64x64.dmi' - icon_state = "pzrmech" - initial_icon = "pzrmech" - pixel_x = -16 - step_in = 10 - health = 5000 - maxhealth = 5000 - opacity = 0 // Because there's big tall legs to look through. Also it looks fucky if this is set to 1. - deflect_chance = 50 - damage_absorption = list("brute"=0.1,"fire"=0.8,"bullet"=0.1,"laser"=0.6,"energy"=0.7,"bomb"=0.7) //values show how much damage will pass through, not how much will be absorbed. - max_temperature = 35000 //Just a bit better than the Durand. - infra_luminosity = 3 - var/zoom = 0 - var/smoke = 5 - var/smoke_ready = 1 - var/smoke_cooldown = 100 - var/datum/effect/effect/system/smoke_spread/smoke_system = new - wreckage = /obj/effect/decal/mecha_wreckage/gorilla - add_req_access = 0 - internal_damage_threshold = 25 - force = 60 - max_equip = 5 -//This will (Should) never be in the hands of players. If it is, the one who inflicted this monster upon the server can edit these vars to not be insane. - max_hull_equip = 5 - max_weapon_equip = 5 - max_utility_equip = 5 - max_universal_equip = 5 - max_special_equip = 2 - -/obj/mecha/combat/gorilla/Initialize() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) // This thing basically cannot function without an external power supply. - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon/weak(src) //Saves energy, I suppose. Anti-infantry. - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src) - ME.attach(src) - src.smoke_system.set_up(3, 0, src) - src.smoke_system.attach(src) - return - -/obj/mecha/combat/gorilla/mechstep(direction) - var/result = step(src,direction) - playsound(src,"mechstep",40,1) - return result - -/obj/mecha/combat/gorilla/mechturn(direction) - dir = direction - playsound(src,"mechstep",40,1) - - -/obj/mecha/combat/gorilla/relaymove(mob/user,direction) - if(user != src.occupant) - user.loc = get_turf(src) - to_chat(user, "You climb out from [src]") - return 0 - if(!can_move) - return 0 - if(zoom) - if(world.time - last_message > 20) - src.occupant_message("Unable to move while in zoom mode.") - last_message = world.time - return 0 - if(connected_port) - if(world.time - last_message > 20) - src.occupant_message("Unable to move while connected to the air system port") - last_message = world.time - return 0 - if(state || !has_charge(step_energy_drain)) - return 0 - var/tmp_step_in = step_in - var/tmp_step_energy_drain = step_energy_drain - var/move_result = 0 - if(internal_damage&MECHA_INT_CONTROL_LOST) - move_result = mechsteprand() - else if(src.dir!=direction) - move_result = mechturn(direction) - else - move_result = mechstep(direction) - if(move_result) - if(istype(src.loc, /turf/space)) - if(!src.check_for_support()) - src.pr_inertial_movement.start(list(src,direction)) - can_move = 0 - spawn(tmp_step_in) can_move = 1 - use_power(tmp_step_energy_drain) - return 1 - return 0 - -/obj/mecha/combat/gorilla/verb/smoke() - set category = "Exosuit Interface" - set name = "Smoke" - set src = usr.loc - set popup_menu = 0 - if(usr!=src.occupant) - return - if(smoke_ready && smoke>0) - src.smoke_system.start() - smoke-- - smoke_ready = 0 - spawn(smoke_cooldown) - smoke_ready = 1 - return - -/obj/mecha/combat/gorilla/verb/zoom() - set category = "Exosuit Interface" - set name = "Zoom" - set src = usr.loc - set popup_menu = 0 - if(usr!=src.occupant) - return - if(src.occupant.client) - src.zoom = !src.zoom - src.log_message("Toggled zoom mode.") - src.occupant_message("Zoom mode [zoom?"en":"dis"]abled.") - if(zoom) - src.occupant.set_viewsize(12) - playsound(src, 'sound/mecha/imag_enh.ogg',50) - else - src.occupant.set_viewsize() // Reset to default - return - - -/obj/mecha/combat/gorilla/go_out() - if(src.occupant && src.occupant.client) - src.occupant.client.view = world.view - src.zoom = 0 - ..() - return - - -/obj/mecha/combat/gorilla/get_stats_part() - var/output = ..() - output += {"Smoke: [smoke]"} - return output - - -/obj/mecha/combat/gorilla/get_commands() - var/output = {"
-
Special
- -
- "} - output += ..() - return output - -/obj/mecha/combat/gorilla/Topic(href, href_list) - ..() - if (href_list["smoke"]) - src.smoke() - if (href_list["toggle_zoom"]) - src.zoom() - return \ No newline at end of file diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index d70c8f9e855..0323124c479 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -5,14 +5,12 @@ initial_icon = "gygax" step_in = 3 dir_in = 1 //Facing North. - health = 300 - maxhealth = 300 + health = 250 + maxhealth = 250 //Don't forget to update the /old variant if you change this number. deflect_chance = 15 damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1) max_temperature = 25000 infra_luminosity = 6 - var/overload = 0 - var/overload_coeff = 2 wreckage = /obj/effect/decal/mecha_wreckage/gygax internal_damage_threshold = 35 max_equip = 3 @@ -23,6 +21,29 @@ max_universal_equip = 1 max_special_equip = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull/lightweight, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/marshal, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + + overload_possible = 1 + +//Not quite sure how to move those yet. +/obj/mecha/combat/gygax/get_commands() + var/output = {"
+
Special
+ +
+ "} + output += ..() + return output + + /obj/mecha/combat/gygax/dark desc = "A lightweight exosuit used by Heavy Asset Protection. A significantly upgraded Gygax security mech." name = "Dark Gygax" @@ -45,17 +66,12 @@ max_universal_equip = 1 max_special_equip = 2 -/obj/mecha/combat/gygax/dark/Initialize() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/teleporter - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay - ME.attach(src) - return + starting_equipment = list( + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang, + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/teleporter + ) /obj/mecha/combat/gygax/dark/add_cell(var/obj/item/weapon/cell/C=null) if(C) @@ -66,62 +82,6 @@ cell.charge = 30000 cell.maxcharge = 30000 - -/obj/mecha/combat/gygax/verb/overload() - set category = "Exosuit Interface" - set name = "Toggle leg actuators overload" - set src = usr.loc - set popup_menu = 0 - if(usr!=src.occupant) - return - if(overload) - overload = 0 - step_in = initial(step_in) - step_energy_drain = initial(step_energy_drain) - src.occupant_message("You disable leg actuators overload.") - else - overload = 1 - step_in = min(1, round(step_in/2)) - step_energy_drain = step_energy_drain*overload_coeff - src.occupant_message("You enable leg actuators overload.") - src.log_message("Toggled leg actuators overload.") - playsound(src, 'sound/mecha/mechanical_toggle.ogg', 50, 1) - return - -/obj/mecha/combat/gygax/dyndomove(direction) - if(!..()) return - if(overload) - health-- - if(health < initial(health) - initial(health)/3) - overload = 0 - step_in = initial(step_in) - step_energy_drain = initial(step_energy_drain) - src.occupant_message("Leg actuators damage threshold exceded. Disabling overload.") - return - - -/obj/mecha/combat/gygax/get_stats_part() - var/output = ..() - output += "Leg actuators overload: [overload?"on":"off"]" - return output - -/obj/mecha/combat/gygax/get_commands() - var/output = {"
-
Special
- -
- "} - output += ..() - return output - -/obj/mecha/combat/gygax/Topic(href, href_list) - ..() - if (href_list["toggle_leg_overload"]) - src.overload() - return - /obj/mecha/combat/gygax/serenity desc = "A lightweight exosuit made from a modified Gygax chassis combined with proprietary VeyMed medical tech. It's faster and sturdier than most medical mechs, but much of the armor plating has been stripped out, leaving it more vulnerable than a regular Gygax." name = "Serenity" @@ -144,6 +104,14 @@ max_universal_equip = 1 max_special_equip = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/lightweight, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + var/obj/item/clothing/glasses/hud/health/mech/hud /obj/mecha/combat/gygax/serenity/New() @@ -169,4 +137,14 @@ H.glasses = null H.recalculate_vis() ..() - return \ No newline at end of file + return + +//Meant for random spawns. +/obj/mecha/combat/gygax/old + desc = "A lightweight, security exosuit. Popular among private and corporate security. This one is particularly worn looking and likely isn't as sturdy." + +/obj/mecha/combat/gygax/old/New() + ..() + health = 25 + maxhealth = 250 //Just slightly worse. + cell.charge = rand(0, (cell.charge/2)) \ No newline at end of file diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index 2b383379ad1..e2c0b9467a3 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -5,18 +5,12 @@ icon_state = "marauder" initial_icon = "marauder" step_in = 5 - health = 500 - maxhealth = 500 + health = 350 + maxhealth = 350 //Don't forget to update the /old variant if you change this number. deflect_chance = 25 damage_absorption = list("brute"=0.5,"fire"=0.7,"bullet"=0.45,"laser"=0.6,"energy"=0.7,"bomb"=0.7) max_temperature = 60000 infra_luminosity = 3 - var/zoom = 0 - var/thrusters = 0 - var/smoke = 5 - var/smoke_ready = 1 - var/smoke_cooldown = 100 - var/datum/effect/effect/system/smoke_spread/smoke_system = new operation_req_access = list(access_cent_specops) wreckage = /obj/effect/decal/mecha_wreckage/marauder add_req_access = 0 @@ -31,6 +25,25 @@ max_universal_equip = 1 max_special_equip = 1 + smoke_possible = 1 + zoom_possible = 1 + thrusters_possible = 1 + + starting_components = list( + /obj/item/mecha_parts/component/hull/durable, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/military, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + + starting_equipment = list( + /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive, + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster + ) + /obj/mecha/combat/marauder/seraph desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel." name = "Seraph" @@ -39,13 +52,21 @@ initial_icon = "seraph" operation_req_access = list(access_cent_creed) step_in = 3 - health = 550 + health = 450 wreckage = /obj/effect/decal/mecha_wreckage/seraph internal_damage_threshold = 20 force = 55 max_equip = 5 + starting_equipment = list( + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive, + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster, + /obj/item/mecha_parts/mecha_equipment/teleporter + ) +//Note that is the Mauler /obj/mecha/combat/marauder/mauler desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model." name = "Mauler" @@ -55,43 +76,7 @@ wreckage = /obj/effect/decal/mecha_wreckage/mauler mech_faction = MECH_FACTION_SYNDI -/obj/mecha/combat/marauder/Initialize() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src) - ME.attach(src) - src.smoke_system.set_up(3, 0, src) - src.smoke_system.attach(src) - return - -/obj/mecha/combat/marauder/seraph/Initialize() - ..()//Let it equip whatever is needed. - var/obj/item/mecha_parts/mecha_equipment/ME - if(equipment.len)//Now to remove it and equip anew. - for(ME in equipment) - ME.detach() - qdel(ME) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/teleporter(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src) - ME.attach(src) - return - -/obj/mecha/combat/marauder/Destroy() - qdel(smoke_system) - ..() - +//I'll break this down later /obj/mecha/combat/marauder/relaymove(mob/user,direction) if(user != src.occupant) //While not "realistic", this piece is player friendly. user.loc = get_turf(src) @@ -136,74 +121,7 @@ return 1 return 0 - -/obj/mecha/combat/marauder/verb/toggle_thrusters() - set category = "Exosuit Interface" - set name = "Toggle thrusters" - set src = usr.loc - set popup_menu = 0 - if(usr!=src.occupant) - return - if(src.occupant) - if(get_charge() > 0) - thrusters = !thrusters - src.log_message("Toggled thrusters.") - src.occupant_message("Thrusters [thrusters?"en":"dis"]abled.") - return - - -/obj/mecha/combat/marauder/verb/smoke() - set category = "Exosuit Interface" - set name = "Smoke" - set src = usr.loc - set popup_menu = 0 - if(usr!=src.occupant) - return - if(smoke_ready && smoke>0) - src.smoke_system.start() - smoke-- - smoke_ready = 0 - spawn(smoke_cooldown) - smoke_ready = 1 - return - -//TODO replace this with zoom code that doesn't increase peripherial vision -/obj/mecha/combat/marauder/verb/zoom() - set category = "Exosuit Interface" - set name = "Zoom" - set src = usr.loc - set popup_menu = 0 - if(usr!=src.occupant) - return - if(src.occupant.client) - src.zoom = !src.zoom - src.log_message("Toggled zoom mode.") - src.occupant_message("Zoom mode [zoom?"en":"dis"]abled.") - if(zoom) - src.occupant.set_viewsize(12) - src.occupant << sound('sound/mecha/imag_enh.ogg',volume=50) - else - src.occupant.set_viewsize() // Reset to default - return - - -/obj/mecha/combat/marauder/go_out() - if(src.occupant && src.occupant.client) - src.occupant.client.view = world.view - src.zoom = 0 - ..() - return - - -/obj/mecha/combat/marauder/get_stats_part() - var/output = ..() - output += {"Smoke: [smoke] -
- Thrusters: [thrusters?"on":"off"] - "} - return output - - +//To be kill ltr /obj/mecha/combat/marauder/get_commands() var/output = {"
Special
@@ -217,12 +135,14 @@ output += ..() return output -/obj/mecha/combat/marauder/Topic(href, href_list) +//Meant for random spawns. +/obj/mecha/combat/marauder/old + desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations. This one is particularly worn looking and likely isn't as sturdy." + + starting_equipment = null + +/obj/mecha/combat/marauder/old/New() ..() - if (href_list["toggle_thrusters"]) - src.toggle_thrusters() - if (href_list["smoke"]) - src.smoke() - if (href_list["toggle_zoom"]) - src.zoom() - return \ No newline at end of file + health = 25 + maxhealth = 300 //Just slightly worse. + cell.charge = rand(0, (cell.charge/2)) diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm index 48394f47f45..17aea92345e 100644 --- a/code/game/mecha/combat/phazon.dm +++ b/code/game/mecha/combat/phazon.dm @@ -6,8 +6,8 @@ step_in = 1 dir_in = 1 //Facing North. step_energy_drain = 3 - health = 200 - maxhealth = 200 + health = 200 //God this is low + maxhealth = 200 //Don't forget to update the /old variant if you change this number. deflect_chance = 30 damage_absorption = list("brute"=0.7,"fire"=0.7,"bullet"=0.7,"laser"=0.7,"energy"=0.7,"bomb"=0.7) max_temperature = 25000 @@ -17,9 +17,6 @@ //operation_req_access = list() internal_damage_threshold = 25 force = 15 - var/phasing = 0 - var/can_phase = TRUE - var/phasing_energy_drain = 200 max_equip = 4 max_hull_equip = 3 @@ -28,14 +25,27 @@ max_universal_equip = 3 max_special_equip = 4 + starting_components = list( + /obj/item/mecha_parts/component/hull/durable, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/alien, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + + cloak_possible = TRUE + phasing_possible = TRUE + switch_dmg_type_possible = TRUE + /obj/mecha/combat/phazon/equipped/Initialize() ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/rcd - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/gravcatapult - ME.attach(src) + starting_equipment = list( + /obj/item/mecha_parts/mecha_equipment/tool/rcd, + /obj/item/mecha_parts/mecha_equipment/gravcatapult + ) return +/* Leaving this until we are really sure we don't need it for reference. /obj/mecha/combat/phazon/Bump(var/atom/obstacle) if(phasing && get_charge()>=phasing_energy_drain) spawn() @@ -49,35 +59,8 @@ else . = ..() return +*/ -/obj/mecha/combat/phazon/click_action(atom/target,mob/user) - if(phasing) - src.occupant_message("Unable to interact with objects while phasing") - return - else - return ..() - -/obj/mecha/combat/phazon/verb/switch_damtype() - set category = "Exosuit Interface" - set name = "Change melee damage type" - set src = usr.loc - set popup_menu = 0 - if(usr!=src.occupant) - return - - query_damtype() - -/obj/mecha/combat/phazon/proc/query_damtype() - var/new_damtype = alert(src.occupant,"Melee Damage Type",null,"Brute","Fire","Toxic") - switch(new_damtype) - if("Brute") - damtype = "brute" - if("Fire") - damtype = "fire" - if("Toxic") - damtype = "tox" - src.occupant_message("Melee damage type switched to [new_damtype ]") - return /obj/mecha/combat/phazon/get_commands() var/output = {"
@@ -91,15 +74,7 @@ output += ..() return output -/obj/mecha/combat/phazon/Topic(href, href_list) - ..() - if (href_list["switch_damtype"]) - src.switch_damtype() - if (href_list["phasing"]) - phasing = !phasing - send_byjax(src.occupant,"exosuit.browser","phasing_command","[phasing?"Dis":"En"]able phasing") - src.occupant_message("En":"#f00\">Dis"]abled phasing.") - return + /obj/mecha/combat/phazon/janus name = "Phazon Prototype Janus Class" @@ -121,7 +96,6 @@ wreckage = /obj/effect/decal/mecha_wreckage/janus internal_damage_threshold = 25 force = 20 - phasing = FALSE phasing_energy_drain = 300 max_hull_equip = 2 @@ -130,6 +104,10 @@ max_universal_equip = 2 max_special_equip = 2 + phasing_possible = TRUE + switch_dmg_type_possible = TRUE + cloak_possible = FALSE + /obj/mecha/combat/phazon/janus/take_damage(amount, type="brute") ..() if(phasing) @@ -173,3 +151,13 @@ damtype = "halloss" src.occupant_message("Melee damage type switched to [new_damtype]") return + +//Meant for random spawns. +/obj/mecha/combat/phazon/old + desc = "An exosuit which can only be described as 'WTF?'. This one is particularly worn looking and likely isn't as sturdy." + +/obj/mecha/combat/phazon/old/New() + ..() + health = 25 + maxhealth = 150 //Just slightly worse. + cell.charge = rand(0, (cell.charge/2)) \ No newline at end of file diff --git a/code/game/mecha/components/_component.dm b/code/game/mecha/components/_component.dm new file mode 100644 index 00000000000..aadf390c615 --- /dev/null +++ b/code/game/mecha/components/_component.dm @@ -0,0 +1,155 @@ + +/obj/item/mecha_parts/component + name = "mecha component" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "component" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + + var/component_type = null + + var/obj/mecha/chassis = null + var/start_damaged = FALSE + + var/emp_resistance = 0 // Amount of emp 'levels' removed. + + var/list/required_type = null // List, if it exists. Exosuits meant to use the component (Unique var changes / effects) + + var/integrity + var/integrity_danger_mod = 0.5 // Multiplier for comparison to max_integrity before problems start. + var/max_integrity = 100 + + var/step_delay = 0 + + var/relative_size = 30 // Percent chance for the component to be hit. + + var/internal_damage_flag // If set, the component will toggle the flag on or off if it is destroyed / severely damaged. + +/obj/item/mecha_parts/component/examine(mob/user) + . = ..() + var/show_integrity = round(integrity/max_integrity*100, 0.1) + switch(show_integrity) + if(85 to 100) + . += "It's fully intact." + if(65 to 85) + . += "It's slightly damaged." + if(45 to 65) + . += "It's badly damaged." + if(25 to 45) + . += "It's heavily damaged." + if(2 to 25) + . += "It's falling apart." + if(0 to 1) + . += "It is completely destroyed." + +/obj/item/mecha_parts/component/Initialize() + ..() + integrity = max_integrity + + if(start_damaged) + integrity = round(integrity * integrity_danger_mod) + +/obj/item/mecha_parts/component/Destroy() + detach() + return ..() + +// Damage code. + +/obj/item/mecha_parts/component/emp_act(var/severity = 4) + if(severity + emp_resistance > 4) + return + + severity = clamp(severity + emp_resistance, 1, 4) + + take_damage((4 - severity) * round(integrity * 0.1, 0.1)) + +/obj/item/mecha_parts/component/proc/adjust_integrity(var/amt = 0) + integrity = clamp(integrity + amt, 0, max_integrity) + return + +/obj/item/mecha_parts/component/proc/damage_part(var/dam_amt = 0, var/type = BRUTE) + if(dam_amt <= 0) + return FALSE + + adjust_integrity(-1 * dam_amt) + + if(chassis && internal_damage_flag) + if(get_efficiency() < 0.5) + chassis.check_for_internal_damage(list(internal_damage_flag), TRUE) + + return TRUE + +/obj/item/mecha_parts/component/proc/get_efficiency() + var/integ_limit = round(max_integrity * integrity_danger_mod) + + if(integrity < integ_limit) + var/int_percent = round(integrity / integ_limit, 0.1) + + return int_percent + + return 1 + +// Attach/Detach code. + +/obj/item/mecha_parts/component/proc/attach(var/obj/mecha/target, var/mob/living/user) + if(target) + if(!(component_type in target.internal_components)) + if(user) + to_chat(user, "\The [target] doesn't seem to have anywhere to put \the [src].") + return FALSE + if(target.internal_components[component_type]) + if(user) + to_chat(user, "\The [target] already has a [component_type] installed!") + return FALSE + chassis = target + if(user) + user.drop_from_inventory(src) + forceMove(target) + + if(internal_damage_flag) + if(integrity > (max_integrity * integrity_danger_mod)) + if(chassis.hasInternalDamage(internal_damage_flag)) + chassis.clearInternalDamage(internal_damage_flag) + + else + chassis.check_for_internal_damage(list(internal_damage_flag)) + + chassis.internal_components[component_type] = src + + if(user) + chassis.visible_message("[user] installs \the [src] in \the [chassis].") + return TRUE + return FALSE + +/obj/item/mecha_parts/component/proc/detach() + if(chassis) + chassis.internal_components[component_type] = null + + if(internal_damage_flag && chassis.hasInternalDamage(internal_damage_flag)) // If the module has been removed, it's kind of unfair to keep it causing problems by being damaged. It's nonfunctional either way. + chassis.clearInternalDamage(internal_damage_flag) + + forceMove(get_turf(chassis)) + chassis = null + return TRUE + + +/obj/item/mecha_parts/component/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/stack/nanopaste)) + var/obj/item/stack/nanopaste/NP = W + + if(integrity < max_integrity) + while(integrity < max_integrity && NP) + if(do_after(user, 1 SECOND, src) && NP.use(1)) + adjust_integrity(10) + + return + + return ..() + +// Various procs to handle different calls by Exosuits. IE, movement actions, damage actions, etc. + +/obj/item/mecha_parts/component/proc/get_step_delay() + return step_delay + +/obj/item/mecha_parts/component/proc/handle_move() + return diff --git a/code/game/mecha/components/actuators.dm b/code/game/mecha/components/actuators.dm new file mode 100644 index 00000000000..d814518629c --- /dev/null +++ b/code/game/mecha/components/actuators.dm @@ -0,0 +1,37 @@ + +/obj/item/mecha_parts/component/actuator + name = "mecha actuator" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "motor" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + + component_type = MECH_ACTUATOR + + start_damaged = FALSE + + emp_resistance = 1 + + required_type = null // List, if it exists. Exosuits meant to use the component. + + integrity_danger_mod = 0.6 // Multiplier for comparison to max_integrity before problems start. + max_integrity = 50 + + internal_damage_flag = MECHA_INT_CONTROL_LOST + + var/strafing_multiplier = 1.5 + +/obj/item/mecha_parts/component/actuator/get_step_delay() + return step_delay + +/obj/item/mecha_parts/component/actuator/hispeed + name = "overclocked mecha actuator" + + step_delay = -1 + + emp_resistance = -1 + + integrity_danger_mod = 0.7 + max_integrity = 60 + + strafing_multiplier = 1.2 diff --git a/code/game/mecha/components/armor.dm b/code/game/mecha/components/armor.dm new file mode 100644 index 00000000000..ac4ce81ec53 --- /dev/null +++ b/code/game/mecha/components/armor.dm @@ -0,0 +1,238 @@ + +/obj/item/mecha_parts/component/armor + name = "mecha plating" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "armor" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 2) + + component_type = MECH_ARMOR + + start_damaged = FALSE + + emp_resistance = 4 + + required_type = null // List, if it exists. Exosuits meant to use the component. + + integrity_danger_mod = 0.4 // Multiplier for comparison to max_integrity before problems start. + max_integrity = 120 + + internal_damage_flag = MECHA_INT_TEMP_CONTROL + + step_delay = 1 + + var/deflect_chance = 10 + var/list/damage_absorption = list( + "brute"= 0.8, + "fire"= 1.2, + "bullet"= 0.9, + "laser"= 1, + "energy"= 1, + "bomb"= 1, + "bio"= 1, + "rad"= 1 + ) + + var/damage_minimum = 10 + var/minimum_penetration = 0 + var/fail_penetration_value = 0.66 + +/obj/item/mecha_parts/component/armor/mining + name = "blast-resistant mecha plating" + + step_delay = 2 + max_integrity = 80 + + damage_absorption = list( + "brute"=0.8, + "fire"=0.8, + "bullet"=1.2, + "laser"=1.2, + "energy"=1, + "bomb"=0.5, + "bio"=1, + "rad"=1 + ) + +/obj/item/mecha_parts/component/armor/lightweight + name = "lightweight mecha plating" + + max_integrity = 50 + step_delay = 0 + + damage_absorption = list( + "brute"=1, + "fire"=1.4, + "bullet"=1.1, + "laser"=1.2, + "energy"=1, + "bomb"=1, + "bio"=1, + "rad"=1 + ) + +/obj/item/mecha_parts/component/armor/reinforced + name = "reinforced mecha plating" + + step_delay = 4 + + max_integrity = 80 + + minimum_penetration = 10 + + damage_absorption = list( + "brute"=0.7, + "fire"=1, + "bullet"=0.7, + "laser"=0.85, + "energy"=1, + "bomb"=0.8 + ) + +/obj/item/mecha_parts/component/armor/military + name = "military grade mecha plating" + + step_delay = 4 + + max_integrity = 100 + + emp_resistance = 2 + + required_type = list(/obj/mecha/combat) + + damage_minimum = 15 + minimum_penetration = 25 + + damage_absorption = list( + "brute"=0.5, + "fire"=1.1, + "bullet"=0.65, + "laser"=0.85, + "energy"=0.9, + "bomb"=0.8 + ) + +/obj/item/mecha_parts/component/armor/military/attach(var/obj/mecha/target, var/mob/living/user) + . = ..() + if(.) + var/typepass = FALSE + for(var/type in required_type) + if(istype(chassis, type)) + typepass = TRUE + + if(typepass) + step_delay = 0 + else + step_delay = initial(step_delay) + +/obj/item/mecha_parts/component/armor/marshal + name = "marshal mecha plating" + + step_delay = 3 + + max_integrity = 100 + + emp_resistance = 3 + + deflect_chance = 15 + + minimum_penetration = 10 + + required_type = list(/obj/mecha/combat) + + damage_absorption = list( + "brute"=0.75, + "fire"=1, + "bullet"=0.8, + "laser"=0.7, + "energy"=0.85, + "bomb"=1 + ) + +/obj/item/mecha_parts/component/armor/marshal/attach(var/obj/mecha/target, var/mob/living/user) + . = ..() + if(.) + var/typepass = FALSE + for(var/type in required_type) + if(istype(chassis, type)) + typepass = TRUE + + if(typepass) + step_delay = 2 + else + step_delay = initial(step_delay) + +/obj/item/mecha_parts/component/armor/marshal/reinforced + name = "blackops mecha plating" + + step_delay = 5 + + damage_absorption = list( + "brute"=0.6, + "fire"=0.8, + "bullet"=0.6, + "laser"=0.5, + "energy"=0.65, + "bomb"=0.8 + ) + +/obj/item/mecha_parts/component/armor/military/marauder + name = "cutting edge mecha plating" + + step_delay = 4 + + max_integrity = 150 + + emp_resistance = 3 + + required_type = list(/obj/mecha/combat/marauder) + + deflect_chance = 25 + damage_minimum = 30 + minimum_penetration = 25 + + damage_absorption = list( + "brute"=0.5, + "fire"=0.7, + "bullet"=0.45, + "laser"=0.6, + "energy"=0.7, + "bomb"=0.7 + ) + +/obj/item/mecha_parts/component/armor/military/marauder/attach(var/obj/mecha/target, var/mob/living/user) + . = ..() + if(.) + var/typepass = FALSE + for(var/type in required_type) + if(istype(chassis, type)) + typepass = TRUE + + if(typepass) + step_delay = 1 + else + step_delay = initial(step_delay) + +/obj/item/mecha_parts/component/armor/alien + name = "strange mecha plating" + step_delay = 2 + damage_absorption = list( + "brute"=0.7, + "fire"=0.7, + "bullet"=0.7, + "laser"=0.7, + "energy"=0.7, + "bomb"=0.7 + ) + +/obj/item/mecha_parts/component/armor/alien/attach(var/obj/mecha/target, var/mob/living/user) + . = ..() + if(.) + if(istype(target, /obj/mecha/combat/phazon/janus)) + step_delay = -1 + + else if(istype(target, /obj/mecha/combat/phazon)) + step_delay = -3 + + else + step_delay = initial(step_delay) diff --git a/code/game/mecha/components/electrical.dm b/code/game/mecha/components/electrical.dm new file mode 100644 index 00000000000..de07c96c84b --- /dev/null +++ b/code/game/mecha/components/electrical.dm @@ -0,0 +1,31 @@ + +/obj/item/mecha_parts/component/electrical + name = "mecha electrical harness" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "board" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + + component_type = MECH_ELECTRIC + + emp_resistance = 1 + + integrity_danger_mod = 0.4 + max_integrity = 40 + + step_delay = 0 + + relative_size = 20 + + internal_damage_flag = MECHA_INT_SHORT_CIRCUIT + + var/charge_cost_mod = 1 + +/obj/item/mecha_parts/component/electrical/high_current + name = "efficient mecha electrical harness" + + emp_resistance = 0 + max_integrity = 30 + + relative_size = 10 + charge_cost_mod = 0.6 diff --git a/code/game/mecha/components/hull.dm b/code/game/mecha/components/hull.dm new file mode 100644 index 00000000000..16d01ad92cc --- /dev/null +++ b/code/game/mecha/components/hull.dm @@ -0,0 +1,33 @@ + +/obj/item/mecha_parts/component/hull + name = "mecha hull" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "hull" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + + component_type = MECH_HULL + + emp_resistance = 0 // Amount of emp 'levels' removed. + + required_type = null // List, if it exists. Exosuits meant to use the component. + + integrity_danger_mod = 0.5 // Multiplier for comparison to max_integrity before problems start. + max_integrity = 50 + + internal_damage_flag = MECHA_INT_FIRE + + step_delay = 2 + +/obj/item/mecha_parts/component/hull/durable + name = "durable mecha hull" + + step_delay = 4 + integrity_danger_mod = 0.3 + max_integrity = 100 + +/obj/item/mecha_parts/component/hull/lightweight + name = "lightweight mecha hull" + + step_delay = 1 + integrity_danger_mod = 0.3 diff --git a/code/game/mecha/components/lifesupport.dm b/code/game/mecha/components/lifesupport.dm new file mode 100644 index 00000000000..d98cefda4dc --- /dev/null +++ b/code/game/mecha/components/lifesupport.dm @@ -0,0 +1,28 @@ + +/obj/item/mecha_parts/component/gas + name = "mecha life-support" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "lifesupport" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + + component_type = MECH_GAS + + emp_resistance = 1 + + integrity_danger_mod = 0.4 + max_integrity = 40 + + step_delay = 0 + + relative_size = 20 + + internal_damage_flag = MECHA_INT_TANK_BREACH + +/obj/item/mecha_parts/component/gas/reinforced + name = "reinforced mecha life-support" + + emp_resistance = 2 + max_integrity = 80 + + relative_size = 40 diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 678ac649105..617af4849fc 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -28,6 +28,8 @@ var/ready_sound = 'sound/mecha/mech_reload_default.ogg' //Sound to play once the fire delay passed. var/enable_special = FALSE // Will the tool do its special? + var/step_delay = 0 // Does the component slow/speed up the suit? + /obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(target=1) sleep(equip_cooldown) set_ready_state(1) @@ -273,3 +275,6 @@ /obj/item/mecha_parts/mecha_equipment/proc/MoveAction() //Allows mech equipment to do an action upon the mech moving return + +/obj/item/mecha_parts/mecha_equipment/proc/get_step_delay() // Equipment returns its slowdown or speedboost. + return step_delay diff --git a/code/game/mecha/equipment/tools/armor_melee.dm b/code/game/mecha/equipment/tools/armor_melee.dm index 8390a2cc52a..ed5724ce649 100644 --- a/code/game/mecha/equipment/tools/armor_melee.dm +++ b/code/game/mecha/equipment/tools/armor_melee.dm @@ -9,6 +9,8 @@ var/deflect_coeff = 1.15 var/damage_coeff = 0.8 + step_delay = 0.5 + equip_type = EQUIP_HULL /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/get_equip_info() diff --git a/code/game/mecha/equipment/tools/armor_ranged.dm b/code/game/mecha/equipment/tools/armor_ranged.dm index 4fb3aac32b6..e1a06bef2d9 100644 --- a/code/game/mecha/equipment/tools/armor_ranged.dm +++ b/code/game/mecha/equipment/tools/armor_ranged.dm @@ -9,6 +9,8 @@ var/deflect_coeff = 1.15 var/damage_coeff = 0.8 + step_delay = 1 + equip_type = EQUIP_HULL /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/handle_projectile_contact(var/obj/item/projectile/Proj, var/inc_damage) diff --git a/code/game/mecha/equipment/tools/repair_droid.dm b/code/game/mecha/equipment/tools/repair_droid.dm index f4f9696aa5c..7cd8ebd9ab7 100644 --- a/code/game/mecha/equipment/tools/repair_droid.dm +++ b/code/game/mecha/equipment/tools/repair_droid.dm @@ -11,6 +11,8 @@ var/icon/droid_overlay var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH) + step_delay = 1 + equip_type = EQUIP_HULL /obj/item/mecha_parts/mecha_equipment/repair_droid/New() @@ -79,8 +81,23 @@ RD.chassis.clearInternalDamage(int_dam_flag) repaired = 1 break - if(health_boost<0 || RD.chassis.health < initial(RD.chassis.health)) + + var/obj/item/mecha_parts/component/AC = RD.chassis.internal_components[MECH_ARMOR] + var/obj/item/mecha_parts/component/HC = RD.chassis.internal_components[MECH_HULL] + + var/damaged_armor = AC.integrity < AC.max_integrity + + var/damaged_hull = HC.integrity < HC.max_integrity + + if(health_boost<0 || RD.chassis.health < initial(RD.chassis.health) || damaged_armor || damaged_hull) RD.chassis.health += min(health_boost, initial(RD.chassis.health)-RD.chassis.health) + + if(AC) + AC.adjust_integrity(round(health_boost * 0.5, 0.5)) + + if(HC) + HC.adjust_integrity(round(health_boost * 0.5, 0.5)) + repaired = 1 if(repaired) if(RD.chassis.use_power(RD.energy_drain)) diff --git a/code/game/mecha/equipment/tools/shield.dm b/code/game/mecha/equipment/tools/shield.dm index 1ceab079454..ce0c43e7da9 100644 --- a/code/game/mecha/equipment/tools/shield.dm +++ b/code/game/mecha/equipment/tools/shield.dm @@ -7,6 +7,8 @@ energy_drain = 20 range = 0 + step_delay = 0.2 + var/obj/item/shield_projector/line/exosuit/my_shield = null var/my_shield_type = /obj/item/shield_projector/line/exosuit var/icon/drone_overlay @@ -66,9 +68,11 @@ my_shield.attack_self(chassis.occupant) if(my_shield.active) set_ready_state(0) + step_delay = 4 log_message("Activated.") else set_ready_state(1) + step_delay = 1 log_message("Deactivated.") /obj/item/mecha_parts/mecha_equipment/combat_shield/Topic(href, href_list) diff --git a/code/game/mecha/equipment/tools/shield_omni.dm b/code/game/mecha/equipment/tools/shield_omni.dm index 1d230c4deb6..ca61a138e42 100644 --- a/code/game/mecha/equipment/tools/shield_omni.dm +++ b/code/game/mecha/equipment/tools/shield_omni.dm @@ -9,6 +9,8 @@ energy_drain = OMNI_SHIELD_DRAIN range = 0 + step_delay = 0.2 + var/obj/item/shield_projector/shields = null var/shield_type = /obj/item/shield_projector/rectangle/mecha @@ -42,9 +44,11 @@ shields.set_on(!shields.active) if(shields.active) set_ready_state(0) + step_delay = 4 log_message("Activated.") else set_ready_state(1) + step_delay = initial(step_delay) log_message("Deactivated.") /obj/item/mecha_parts/mecha_equipment/omni_shield/Topic(href, href_list) diff --git a/code/game/mecha/equipment/tools/speedboost.dm b/code/game/mecha/equipment/tools/speedboost.dm index 1cb0df9469f..7ffbeaee38a 100644 --- a/code/game/mecha/equipment/tools/speedboost.dm +++ b/code/game/mecha/equipment/tools/speedboost.dm @@ -7,13 +7,23 @@ equip_type = EQUIP_HULL + var/slowdown_multiplier = 0.75 // How much does the exosuit multiply its slowdown by if it's the proper type? + +/* /obj/item/mecha_parts/mecha_equipment/speedboost/attach(obj/mecha/M as obj) ..() if(enable_special) - chassis.step_in = (chassis.step_in-2) // Make the ripley as fast as a durand + chassis.step_in = 3 // As fast as a gygax without overload. Slower than Ody. else - chassis.step_in = (chassis.step_in+1) // Improper parts slow the mech down + chassis.step_in = 6 // Improper parts slow the mech down return +*/ + +/obj/item/mecha_parts/mecha_equipment/speedboost/get_step_delay() + if(enable_special) + return -1 + else + return 3 /obj/item/mecha_parts/mecha_equipment/speedboost/detach() chassis.step_in = initial(chassis.step_in) diff --git a/code/game/mecha/equipment/weapons/ballistic/mortar.dm b/code/game/mecha/equipment/weapons/ballistic/mortar.dm index 86928c9da58..c192d0fc9b8 100644 --- a/code/game/mecha/equipment/weapons/ballistic/mortar.dm +++ b/code/game/mecha/equipment/weapons/ballistic/mortar.dm @@ -11,6 +11,8 @@ projectile = /obj/item/projectile/arc/fragmentation/mortar projectile_energy_cost = 600 + step_delay = 2 + origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_ILLEGAL = 3) /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/mortar/action_checks(atom/target) diff --git a/code/game/mecha/equipment/weapons/ballistic/shotgun.dm b/code/game/mecha/equipment/weapons/ballistic/shotgun.dm index d2232d00047..e698248b7f6 100644 --- a/code/game/mecha/equipment/weapons/ballistic/shotgun.dm +++ b/code/game/mecha/equipment/weapons/ballistic/shotgun.dm @@ -11,6 +11,8 @@ deviation = 0.7 projectile_energy_cost = 25 + step_delay = 0.5 + origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4) /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot/rigged diff --git a/code/game/mecha/equipment/weapons/energy/laser.dm b/code/game/mecha/equipment/weapons/energy/laser.dm index 8bdcbcf71f8..5a480a96918 100644 --- a/code/game/mecha/equipment/weapons/energy/laser.dm +++ b/code/game/mecha/equipment/weapons/energy/laser.dm @@ -52,6 +52,8 @@ projectile = /obj/item/projectile/beam/heavylaser fire_sound = 'sound/weapons/lasercannonfire.ogg' + step_delay = 1 + origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4, TECH_MAGNET = 4) /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/rigged diff --git a/code/game/mecha/equipment/weapons/explosive/missile.dm b/code/game/mecha/equipment/weapons/explosive/missile.dm index 1c14a8c1dd6..9ff28ade8e5 100644 --- a/code/game/mecha/equipment/weapons/explosive/missile.dm +++ b/code/game/mecha/equipment/weapons/explosive/missile.dm @@ -2,6 +2,8 @@ var/missile_speed = 2 var/missile_range = 30 + step_delay = 0.5 + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc) AM.throw_at(target,missile_range, missile_speed, chassis) @@ -19,6 +21,8 @@ missile_range = 15 required_type = /obj/mecha //Why restrict it to just mining or combat mechs? + step_delay = 0 + equip_type = EQUIP_UTILITY /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare/Fire(atom/movable/AM, atom/target, turf/aimloc) diff --git a/code/game/mecha/equipment/weapons/fire/flamethrower.dm b/code/game/mecha/equipment/weapons/fire/flamethrower.dm index f97f598e243..5e2d79615c6 100644 --- a/code/game/mecha/equipment/weapons/fire/flamethrower.dm +++ b/code/game/mecha/equipment/weapons/fire/flamethrower.dm @@ -7,6 +7,8 @@ energy_drain = 30 + step_delay = 0.5 + projectile = /obj/item/projectile/bullet/incendiary/flamethrower/large fire_sound = 'sound/weapons/towelwipe.ogg' diff --git a/code/game/mecha/equipment/weapons/fire/incendiary.dm b/code/game/mecha/equipment/weapons/fire/incendiary.dm index 3d3c1748394..ff49d42016f 100644 --- a/code/game/mecha/equipment/weapons/fire/incendiary.dm +++ b/code/game/mecha/equipment/weapons/fire/incendiary.dm @@ -16,3 +16,5 @@ projectile_energy_cost = 40 fire_cooldown = 3 origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_PHORON = 2, TECH_ILLEGAL = 1) + + step_delay = 1 diff --git a/code/game/mecha/equipment/weapons/honk.dm b/code/game/mecha/equipment/weapons/honk.dm index 427d53295c3..e7bee193dd4 100644 --- a/code/game/mecha/equipment/weapons/honk.dm +++ b/code/game/mecha/equipment/weapons/honk.dm @@ -26,7 +26,7 @@ return to_chat(M, "Your ears feel like they're bleeding!") playsound(M, 'sound/effects/bang.ogg', 70, 1, 30) - M.sleeping = 0 + M.SetSleeping(0) M.ear_deaf += 30 M.ear_damage += rand(5, 20) M.Weaken(3) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 355ce629ace..fa7e2005c6b 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -12,6 +12,8 @@ var/auto_rearm = 0 //Does the weapon reload itself after each shot? required_type = list(/obj/mecha/combat, /obj/mecha/working/hoverpod/combatpod) + step_delay = 0.1 + equip_type = EQUIP_WEAPON /obj/item/mecha_parts/mecha_equipment/weapon/action_checks(atom/target) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 1b00505bc9a..bfdb4508e94 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -7,6 +7,11 @@ #define MELEE 1 #define RANGED 2 +#define MECHA_OPERATING 0 +#define MECHA_BOLTS_SECURED 1 +#define MECHA_PANEL_LOOSE 2 +#define MECHA_CELL_OPEN 3 +#define MECHA_CELL_OUT 4 #define MECH_FACTION_NT "nano" #define MECH_FACTION_SYNDI "syndi" @@ -15,39 +20,54 @@ /obj/mecha name = "Mecha" desc = "Exosuit" + description_info = "Alt click to strafe." icon = 'icons/mecha/mecha.dmi' - density = 1 //Dense. To raise the heat. - opacity = 1 ///opaque. Menacing. - anchored = 1 //no pulling around. - unacidable = 1 //and no deleting hoomans inside - layer = MOB_LAYER //icon draw layer - infra_luminosity = 15 //byond implementation is bugged. - var/initial_icon = null //Mech type for resetting icon. Only used for reskinning kits (see custom items) + density = 1 //Dense. To raise the heat. + opacity = 1 ///opaque. Menacing. + anchored = 1 //no pulling around. + unacidable = 1 //and no deleting hoomans inside + layer = MOB_LAYER //icon draw layer + infra_luminosity = 15 //byond implementation is bugged. + var/initial_icon = null //Mech type for resetting icon. Only used for reskinning kits (see custom items) var/can_move = 1 var/mob/living/carbon/occupant = null - var/step_in = 10 //make a step in step_in/10 sec. - var/dir_in = 2//What direction will the mech face when entered/powered on? Defaults to South. + var/step_in = 10 //make a step in step_in/10 sec. + var/dir_in = 2 //What direction will the mech face when entered/powered on? Defaults to South. var/step_energy_drain = 10 - var/health = 300 //health is health - var/maxhealth = 300 //maxhealth is maxhealth. - var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. + var/health = 300 //health is health + var/maxhealth = 300 //maxhealth is maxhealth. + var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. //the values in this list show how much damage will pass through, not how much will be absorbed. - var/list/damage_absorption = list("brute"=0.8,"fire"=1.2,"bullet"=0.9,"laser"=1,"energy"=1,"bomb"=1) + var/list/damage_absorption = list( + "brute"=0.8, + "fire"=1.2, + "bullet"=0.9, + "laser"=1, + "energy"=1, + "bomb"=1, + "bio"=1, + "rad"=1 + ) + + var/damage_minimum = 10 //Incoming damage lower than this won't actually deal damage. Scrapes shouldn't be a real thing. + var/minimum_penetration = 15 //Incoming damage won't be fully applied if you don't have at least 20. Almost all AP clears this. + var/fail_penetration_value = 0.66 //By how much failing to penetrate reduces your shit. 66% by default. + var/obj/item/weapon/cell/cell - var/state = 0 + var/state = MECHA_OPERATING var/list/log = new var/last_message = 0 var/add_req_access = 1 var/maint_access = 1 - var/dna //dna-locking the mech - var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference + var/dna //dna-locking the mech + var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference var/datum/effect/effect/system/spark_spread/spark_system = new var/lights = 0 var/lights_power = 6 var/force = 0 var/mech_faction = null - var/firstactivation = 0 //It's simple. If it's 0, no one entered it yet. Otherwise someone entered it at least once. + var/firstactivation = 0 //It's simple. If it's 0, no one entered it yet. Otherwise someone entered it at least once. var/stomp_sound = 'sound/mecha/mechstep.ogg' var/swivel_sound = 'sound/mecha/mechturn.ogg' @@ -61,25 +81,27 @@ var/obj/item/device/radio/radio = null - var/max_temperature = 25000 - var/internal_damage_threshold = 50 //health percentage below which internal damage is possible - var/internal_damage = 0 //contains bitflags + var/max_temperature = 25000 //Kelvin values. + var/internal_damage_threshold = 33 //health percentage below which internal damage is possible + var/internal_damage_minimum = 15 //At least this much damage to trigger some real bad hurt. + var/internal_damage = 0 //contains bitflags var/list/operation_req_access = list()//required access level for mecha operation var/list/internals_req_access = list(access_engine,access_robotics)//required access level to open cell compartment - var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature - var/datum/global_iterator/pr_inertial_movement //controls intertial movement in spesss - var/datum/global_iterator/pr_give_air //moves air from tank to cabin - var/datum/global_iterator/pr_internal_damage //processes internal damage + var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature + var/datum/global_iterator/pr_inertial_movement //controls intertial movement in spesss + var/datum/global_iterator/pr_give_air //moves air from tank to cabin + var/datum/global_iterator/pr_internal_damage //processes internal damage var/wreckage - var/list/equipment = new + var/list/equipment = new //This lists holds what stuff you bolted onto your baby ride var/obj/item/mecha_parts/mecha_equipment/selected var/max_equip = 2 var/datum/events/events + //mechaequipt2 stuffs var/list/hull_equipment = new var/list/weapon_equipment = new @@ -91,6 +113,25 @@ var/max_utility_equip = 2 var/max_universal_equip = 2 var/max_special_equip = 1 + + var/list/starting_equipment = null // List containing starting tools. + +// Mech Components, similar to Cyborg, but Bigger. + var/list/internal_components = list( + MECH_HULL = null, + MECH_ACTUATOR = null, + MECH_ARMOR = null, + MECH_GAS = null, + MECH_ELECTRIC = null + ) + var/list/starting_components = list( + /obj/item/mecha_parts/component/hull, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + //Working exosuit vars var/list/cargo = list() var/cargo_capacity = 3 @@ -100,8 +141,69 @@ var/static/image/radial_image_lighttoggle = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_light") var/static/image/radial_image_statpanel = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine2") +//Mech actions var/datum/mini_hud/mech/minihud //VOREStation Edit - var/strafing = 0 + var/strafing = 0 //Are we strafing or not? + + var/defence_mode_possible = 0 //Can we even use defence mode? This is used to assign it to mechs and check for verbs. + var/defence_mode = 0 //Are we in defence mode + var/defence_deflect = 35 //How much it deflect + + var/overload_possible = 0 //Same as above. Don't forget to GRANT the verb&actions if you want everything to work proper. + var/overload = 0 //Are our legs overloaded + var/overload_coeff = 1 //How much extra energy you use when use the L E G + + var/zoom = 0 + var/zoom_possible = 0 + + var/thrusters = 0 + var/thrusters_possible = 0 + + var/phasing = 0 //Are we currently phasing + var/phasing_possible = 0 //This is to allow phasing. + var/can_phase = TRUE //This is an internal check during the relevant procs. + var/phasing_energy_drain = 200 + + var/switch_dmg_type_possible = 0 //Can you switch damage type? It is mostly for the Phazon and its children. + + var/smoke_possible = 0 + var/smoke_reserve = 5 //How many shots you have. Might make a reload later on. MIGHT. + var/smoke_ready = 1 //This is a check for the whether or not the cooldown is ongoing. + var/smoke_cooldown = 100 //How long you have between uses. + var/datum/effect/effect/system/smoke_spread/smoke_system = new + + var/cloak_possible = FALSE // Can this exosuit innately cloak? + +////All of those are for the HUD buttons in the top left. See Grant and Remove procs in mecha_actions. + + var/datum/action/innate/mecha/mech_eject/eject_action = new + var/datum/action/innate/mecha/mech_toggle_internals/internals_action = new + var/datum/action/innate/mecha/mech_toggle_lights/lights_action = new + var/datum/action/innate/mecha/mech_view_stats/stats_action = new + var/datum/action/innate/mecha/strafe/strafing_action = new + + var/datum/action/innate/mecha/mech_defence_mode/defence_action = new + var/datum/action/innate/mecha/mech_overload_mode/overload_action = new + var/datum/action/innate/mecha/mech_smoke/smoke_action = new + var/datum/action/innate/mecha/mech_zoom/zoom_action = new + var/datum/action/innate/mecha/mech_toggle_thrusters/thrusters_action = new + var/datum/action/innate/mecha/mech_cycle_equip/cycle_action = new + var/datum/action/innate/mecha/mech_switch_damtype/switch_damtype_action = new + var/datum/action/innate/mecha/mech_toggle_phasing/phasing_action = new + var/datum/action/innate/mecha/mech_toggle_cloaking/cloak_action = new + + var/weapons_only_cycle = FALSE //So combat mechs don't switch to their equipment at times. +/obj/mecha/Initialize() + ..() + + for(var/path in starting_components) + var/obj/item/mecha_parts/component/C = new path(src) + C.attach(src) + + if(starting_equipment && LAZYLEN(starting_equipment)) + for(var/path in starting_equipment) + var/obj/item/mecha_parts/mecha_equipment/ME = new path(src) + ME.attach(src) /obj/mecha/drain_power(var/drain_check) @@ -123,8 +225,14 @@ if(!add_airtank()) //we check this here in case mecha does not have an internal tank available by default - WIP removeVerb(/obj/mecha/verb/connect_to_port) removeVerb(/obj/mecha/verb/toggle_internal_tank) + spark_system.set_up(2, 0, src) spark_system.attach(src) + + if(smoke_possible)//I am pretty sure that's needed here. + src.smoke_system.set_up(3, 0, src) + src.smoke_system.attach(src) + add_cell() add_iterators() removeVerb(/obj/mecha/verb/disconnect_from_port) @@ -173,6 +281,15 @@ else E.forceMove(loc) E.destroy() + + for(var/slot in internal_components) + var/obj/item/mecha_parts/component/C = internal_components[slot] + if(istype(C)) + C.damage_part(rand(10, 20)) + C.detach() + WR.crowbar_salvage += C + C.forceMove(WR) + if(cell) WR.crowbar_salvage += cell cell.forceMove(WR) @@ -184,6 +301,11 @@ for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) E.detach(loc) E.destroy() + for(var/slot in internal_components) + var/obj/item/mecha_parts/component/C = internal_components[slot] + if(istype(C)) + C.detach() + qdel(C) if(cell) qdel(cell) if(internal_tank) @@ -192,6 +314,9 @@ cell = null internal_tank = null + if(smoke_possible) //Just making sure nothing is running. + qdel(smoke_system) + QDEL_NULL(pr_int_temp_processor) QDEL_NULL(pr_inertial_movement) QDEL_NULL(pr_give_air) @@ -276,6 +401,26 @@ /obj/mecha/examine(mob/user) . = ..() + + var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR] + + var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL] + + if(AC) + . += "It has [AC] attached. [AC.get_efficiency()<0.5?"It is severely damaged.":""]" + else + . += "It has no armor plating." + + if(HC) + if(!AC || AC.get_efficiency() < 0.7) + . += "It has [HC] attached. [HC.get_efficiency()<0.5?"It is severely damaged.":""]" + else + . += "You cannot tell what type of hull it has." + + else + . += "It does not seem to have a completed hull." + + var/integrity = health/initial(health)*100 switch(integrity) if(85 to 100) @@ -283,11 +428,11 @@ if(65 to 85) . += "It's slightly damaged." if(45 to 65) - . += "It's badly damaged." + . += "It's badly damaged." if(25 to 45) - . += "It's heavily damaged." + . += "It's heavily damaged." else - . += "It's falling apart." + . += " It's falling apart. " if(equipment?.len) . += "It's equipped with:" for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) @@ -319,6 +464,7 @@ "Toggle Light" = radial_image_lighttoggle, "View Stats" = radial_image_statpanel ) + var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, .proc/check_occupant_radial, user), require_near = TRUE, tooltips = TRUE) if(!check_occupant_radial(user)) return @@ -380,6 +526,11 @@ if(state) occupant_message("Maintenance protocols in effect") return + + if(phasing)//Phazon and other mechs with phasing. + src.occupant_message("Unable to interact with objects while phasing")//Haha dumbass. + return + if(!get_charge()) return if(src == target) return var/dir_to_target = get_dir(src,target) @@ -455,6 +606,12 @@ user.forceMove(get_turf(src)) to_chat(user, "You climb out from [src]") return 0 + + var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL] + if(!HC) + occupant_message("You can't operate an exosuit that doesn't have a hull!") + return + if(connected_port) if(world.time - last_message > 20) src.occupant_message("Unable to move while connected to the air system port") @@ -463,6 +620,13 @@ if(state) occupant_message("Maintenance protocols in effect") return +/* + if(zoom) + if(world.time - last_message > 20) + src.occupant_message("Unable to move while in zoom mode.") + last_message = world.time + return 0 +*/ return domove(direction) /obj/mecha/proc/can_ztravel() @@ -474,6 +638,44 @@ return call((proc_res["dyndomove"]||src), "dyndomove")(direction) +/obj/mecha/proc/get_step_delay() + var/tally = 0 + + if(overload) + tally = min(1, round(step_in/2)) + + for(var/slot in internal_components) + var/obj/item/mecha_parts/component/C = internal_components[slot] + if(C && C.get_step_delay()) + tally += C.get_step_delay() + + for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) + if(ME.get_step_delay()) + tally += ME.get_step_delay() + + var/obj/item/mecha_parts/component/actuator/actuator = internal_components[MECH_ACTUATOR] + + if(!actuator) // Relying purely on hydraulic pumps. You're going nowhere fast. + tally = 2 SECONDS + + return tally + + tally += 0.5 SECONDS * (1 - actuator.get_efficiency()) // Damaged actuators run slower, slowing as damage increases beyond its threshold. + + if(strafing) + tally = round(tally * actuator.strafing_multiplier) + + for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) + if(istype(ME, /obj/item/mecha_parts/mecha_equipment/speedboost)) + var/obj/item/mecha_parts/mecha_equipment/speedboost/SB = ME + for(var/path in ME.required_type) + if(istype(src, path)) + tally = round(tally * SB.slowdown_multiplier) + break + break + + return max(1, round(tally, 0.1)) + /obj/mecha/proc/dyndomove(direction) if(!can_move) return 0 @@ -482,6 +684,40 @@ if(!has_charge(step_energy_drain)) return 0 + //Can we even move, below is if yes. + + if(defence_mode)//Check if we are currently locked down + if(world.time - last_message > 20) + src.occupant_message("Unable to move while in defence mode") + last_message = world.time + return 0 + + if(zoom)//:eyes: + if(world.time - last_message > 20) + src.occupant_message("Unable to move while in zoom mode.") + last_message = world.time + return 0 + + +/* +//A first draft of a check to stop mechs from moving fully. TBD when all thrusters modules are unified. + if(!thrusters && !src.pr_inertial_movement.active() && isspace(src.loc))//No thrsters, not drifting, in space + src.occupant_message("Error 543")//debug + return 0 +*/ + + + if(!thrusters && src.pr_inertial_movement.active()) //I think this mean 'if you try to move in space without thruster, u no move' + return 0 + + if(overload)//Check if you have leg overload + health-- + if(health < initial(health) - initial(health)/3) + overload = 0 + step_energy_drain = initial(step_energy_drain) + src.occupant_message("Leg actuators damage threshold exceded. Disabling overload.") + + var/move_result = 0 if(hasInternalDamage(MECHA_INT_CONTROL_LOST)) @@ -533,7 +769,7 @@ if(!src.check_for_support()) src.pr_inertial_movement.start(list(src,direction)) src.log_message("Movement control lost. Inertial movement started.") - if(do_after(step_in)) + if(do_after(get_step_delay())) can_move = 1 return 1 return 0 @@ -572,21 +808,35 @@ /obj/mecha/Bump(var/atom/obstacle) // src.inertia_dir = null - if(istype(obstacle, /obj)) + if(istype(obstacle, /mob))//First we check if it is a mob. Mechs mostly shouln't go through them, even while phasing. + var/mob/M = obstacle + M.Move(get_step(obstacle,src.dir)) + else if(istype(obstacle, /obj))//Then we check for regular obstacles. var/obj/O = obstacle - if(istype(O, /obj/effect/portal)) //derpfix - src.anchored = 0 + + if(phasing && get_charge()>=phasing_energy_drain)//Phazon check. This could use an improvement elsewhere. + spawn() + if(can_phase) + can_phase = FALSE + flick("[initial_icon]-phase", src) + src.loc = get_step(src,src.dir) + src.use_power(phasing_energy_drain) + sleep(get_step_delay() * 3) + can_phase = TRUE + occupant_message("Phazed.") + . = ..(obstacle) + return + if(istype(O, /obj/effect/portal)) //derpfix + src.anchored = 0 //I have no idea what this really fix. O.Crossed(src) spawn(0)//countering portal teleport spawn(0), hurr src.anchored = 1 - else if(!O.anchored) - step(obstacle,src.dir) - else //I have no idea why I disabled this + else if(O.anchored) obstacle.Bumped(src) - else if(istype(obstacle, /mob)) - var/mob/M = obstacle - M.Move(get_step(obstacle,src.dir)) - else + else + step(obstacle,src.dir) + + else//No idea when this triggers, so i won't touch it. . = ..(obstacle) return @@ -594,18 +844,21 @@ //////// Internal damage //////// /////////////////////////////////// +//ATM, the ignore_threshold is literally only used for the pulse rifles beams used mostly by deathsquads. /obj/mecha/proc/check_for_internal_damage(var/list/possible_int_damage,var/ignore_threshold=null) if(!islist(possible_int_damage) || isemptylist(possible_int_damage)) return - if(prob(20)) - if(ignore_threshold || src.health*100/initial(src.health) 0.25) + return AC.damage_absorption + + return + /obj/mecha/proc/absorbDamage(damage,damage_type) return call((proc_res["dynabsorbdamage"]||src), "dynabsorbdamage")(damage,damage_type) /obj/mecha/proc/dynabsorbdamage(damage,damage_type) - return damage*(listgetindex(damage_absorption,damage_type) || 1) + return damage*(listgetindex(get_damage_absorption(),damage_type) || 1) /obj/mecha/airlock_crush(var/crush_damage) ..() take_damage(crush_damage) - check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + if(prob(50)) //Try to avoid that. + check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) return 1 /obj/mecha/proc/update_health() @@ -673,16 +968,27 @@ if(user == occupant) show_radial_occupant(user) return - + user.setClickCooldown(user.get_attack_speed()) src.log_message("Attack by hand/paw. Attacker - [user].",1) + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + + if(!ArmC) + temp_deflect_chance = 1 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user if(H.species.can_shred(user)) - if(!prob(src.deflect_chance)) - src.take_damage(15) - src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + if(!prob(temp_deflect_chance)) + src.take_damage(15) //The take_damage() proc handles armor values + if(prob(25)) //Why would they get free internal damage. At least make it a bit RNG. + src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) playsound(src, 'sound/weapons/slash.ogg', 50, 1, -1) to_chat(user, "You slash at the armored suit!") visible_message("\The [user] slashes at [src.name]'s armor!") @@ -696,9 +1002,10 @@ user.visible_message("\The [user] hits \the [src]. Nothing happens.","You hit \the [src] with no visible effect.") src.log_append_to_last("Armor saved.") return - else if ((HULK in user.mutations) && !prob(src.deflect_chance)) - src.take_damage(15) - src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + else if ((HULK in user.mutations) && !prob(temp_deflect_chance)) + src.take_damage(15) //The take_damage() proc handles armor values + if(prob(25)) //Hulks punch hard but lets not give them consistent internal damage. + src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) user.visible_message("[user] hits [src.name], doing some damage.", "You hit [src.name] with all your might. The metal creaks and bends.") else user.visible_message("[user] hits [src.name]. Nothing happens.","You hit [src.name] with no visible effect.") @@ -711,12 +1018,32 @@ call((proc_res["dynhitby"]||src), "dynhitby")(A) return +//I think this is relative to throws. /obj/mecha/proc/dynhitby(atom/movable/A) + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + var/temp_damage_minimum = damage_minimum + var/temp_minimum_penetration = minimum_penetration + var/temp_fail_penetration_value = fail_penetration_value + + if(!ArmC) + temp_deflect_chance = 0 + temp_damage_minimum = 0 + temp_minimum_penetration = 0 + temp_fail_penetration_value = 1 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum) + temp_minimum_penetration = round(ArmC.get_efficiency() * ArmC.minimum_penetration) + temp_fail_penetration_value = round(ArmC.get_efficiency() * ArmC.fail_penetration_value) + if(istype(A, /obj/item/mecha_parts/mecha_tracking)) A.forceMove(src) src.visible_message("The [A] fastens firmly to [src].") return - if(prob(src.deflect_chance) || istype(A, /mob)) + if(prob(temp_deflect_chance) || istype(A, /mob)) src.occupant_message("\The [A] bounces off the armor.") src.visible_message("\The [A] bounces off \the [src] armor") src.log_append_to_last("Armor saved.") @@ -728,11 +1055,30 @@ if(O.throwforce) var/pass_damage = O.throwforce + var/pass_damage_reduc_mod + if(pass_damage <= temp_damage_minimum)//Too little to go through. + src.occupant_message("\The [A] bounces off the armor.") + src.visible_message("\The [A] bounces off \the [src] armor") + return + + else if(O.armor_penetration < temp_minimum_penetration) //If you don't have enough pen, you won't do full damage + src.occupant_message("\The [A] struggles to bypass \the [src] armor.") + src.visible_message("\The [A] struggles to bypass \the [src] armor") + pass_damage_reduc_mod = temp_fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default + else + src.occupant_message("\The [A] manages to pierce \the [src] armor.") +// src.visible_message("\The [A] manages to pierce \the [src] armor") + pass_damage_reduc_mod = 1 + + + for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) pass_damage = ME.handle_ranged_contact(A, pass_damage) - src.take_damage(pass_damage) - src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + pass_damage = (pass_damage*pass_damage_reduc_mod)//Applying damage reduction + src.take_damage(pass_damage) //The take_damage() proc handles armor values + if(pass_damage > internal_damage_minimum) //Only decently painful attacks trigger a chance of mech damage. + src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) return @@ -748,7 +1094,26 @@ return /obj/mecha/proc/dynbulletdamage(var/obj/item/projectile/Proj) - if(prob(src.deflect_chance)) + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + var/temp_damage_minimum = damage_minimum + var/temp_minimum_penetration = minimum_penetration + var/temp_fail_penetration_value = fail_penetration_value + + if(!ArmC) + temp_deflect_chance = 0 + temp_damage_minimum = 0 + temp_minimum_penetration = 0 + temp_fail_penetration_value = 1 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum) + temp_minimum_penetration = round(ArmC.get_efficiency() * ArmC.minimum_penetration) + temp_fail_penetration_value = round(ArmC.get_efficiency() * ArmC.fail_penetration_value) + + if(prob(temp_deflect_chance)) src.occupant_message("The armor deflects incoming projectile.") src.visible_message("The [src.name] armor deflects the projectile") src.log_append_to_last("Armor saved.") @@ -759,16 +1124,35 @@ if(!(Proj.nodamage)) var/ignore_threshold - if(istype(Proj, /obj/item/projectile/beam/pulse)) + if(istype(Proj, /obj/item/projectile/beam/pulse)) //ATM, this is literally only for the pulse rifles used mostly by deathsquads. ignore_threshold = 1 var/pass_damage = Proj.damage + var/pass_damage_reduc_mod for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) pass_damage = ME.handle_projectile_contact(Proj, pass_damage) - src.take_damage(pass_damage, Proj.check_armour) - if(prob(25)) spark_system.start() - src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),ignore_threshold) + if(pass_damage < temp_damage_minimum)//too pathetic to really damage you. + src.occupant_message("The armor deflects incoming projectile.") + src.visible_message("The [src.name] armor deflects\the [Proj]") + return + + else if(Proj.armor_penetration < temp_minimum_penetration) //If you don't have enough pen, you won't do full damage + src.occupant_message("\The [Proj] struggles to pierce \the [src] armor.") + src.visible_message("\The [Proj] struggles to pierce \the [src] armor") + pass_damage_reduc_mod = temp_fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default + + else //You go through completely because you use AP. Nice. + src.occupant_message("\The [Proj] manages to pierce \the [src] armor.") +// src.visible_message("\The [Proj] manages to pierce \the [src] armor") + pass_damage_reduc_mod = 1 + + pass_damage = (pass_damage_reduc_mod*pass_damage)//Apply damage reduction before usage. + src.take_damage(pass_damage, Proj.check_armour) //The take_damage() proc handles armor values + if(prob(25)) + spark_system.start() + if(pass_damage > internal_damage_minimum) //Only decently painful attacks trigger a chance of mech damage. + src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),ignore_threshold) //AP projectiles have a chance to cause additional damage if(Proj.penetrating) @@ -779,7 +1163,8 @@ Proj.attack_mob(src.occupant, distance) hit_occupant = 0 else - src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT), 1) + if(pass_damage > internal_damage_minimum) //Only decently painful attacks trigger a chance of mech damage. + src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT), 1) Proj.penetrating-- @@ -789,25 +1174,36 @@ Proj.on_hit(src) //on_hit just returns if it's argument is not a living mob so does this actually do anything? return +//This refer to whenever you are caught in an explosion. /obj/mecha/ex_act(severity) + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + + if(!ArmC) + temp_deflect_chance = 0 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + src.log_message("Affected by explosion of severity: [severity].",1) - if(prob(src.deflect_chance)) + if(prob(temp_deflect_chance)) severity++ src.log_append_to_last("Armor saved, changing severity to [severity].") switch(severity) if(1.0) - qdel(src) + src.take_damage(initial(src.health), "bomb") if(2.0) if (prob(30)) - qdel(src) + src.take_damage(initial(src.health), "bomb") else - src.take_damage(initial(src.health)/2) + src.take_damage(initial(src.health)/2, "bomb") src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) if(3.0) if (prob(5)) qdel(src) else - src.take_damage(initial(src.health)/5) + src.take_damage(initial(src.health)/5, "bomb") src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) return @@ -838,36 +1234,68 @@ use_power((cell.charge/2)/severity) take_damage(50 / severity,"energy") src.log_message("EMP detected",1) - check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) + if(prob(80)) + check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) return /obj/mecha/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature>src.max_temperature) src.log_message("Exposed to dangerous temperature.",1) - src.take_damage(5,"fire") + src.take_damage(5,"fire") //The take_damage() proc handles armor values src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL)) return /obj/mecha/proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) user.setClickCooldown(user.get_attack_speed(W)) src.log_message("Attacked by [W]. Attacker - [user]") - if(prob(src.deflect_chance)) + var/pass_damage_reduc_mod //Modifer for failing to bring AP. + + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + var/temp_damage_minimum = damage_minimum + var/temp_minimum_penetration = minimum_penetration + var/temp_fail_penetration_value = fail_penetration_value + + if(!ArmC) + temp_deflect_chance = 0 + temp_damage_minimum = 0 + temp_minimum_penetration = 0 + temp_fail_penetration_value = 1 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum) + temp_minimum_penetration = round(ArmC.get_efficiency() * ArmC.minimum_penetration) + temp_fail_penetration_value = round(ArmC.get_efficiency() * ArmC.fail_penetration_value) + + if(prob(temp_deflect_chance)) //Does your attack get deflected outright. + src.occupant_message("\The [W] bounces off [src.name].") to_chat(user, "\The [W] bounces off [src.name].") src.log_append_to_last("Armor saved.") -/* - for (var/mob/V in viewers(src)) - if(V.client && !(V.blinded)) - V.show_message("The [W] bounces off [src.name] armor.", 1) -*/ + + else if(W.force < temp_damage_minimum) //Is your attack too PATHETIC to do anything. 3 damage to a person shouldn't do anything to a mech. + src.occupant_message("\The [W] bounces off the armor.") + src.visible_message("\The [W] bounces off \the [src] armor") + return + + else if(W.armor_penetration < temp_minimum_penetration) //If you don't have enough pen, you won't do full damage + src.occupant_message("\The [W] struggles to bypass \the [src] armor.") + src.visible_message("\The [W] struggles to bypass \the [src] armor") + pass_damage_reduc_mod = temp_fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default + else + pass_damage_reduc_mod = 1 //Just making sure. src.occupant_message("[user] hits [src] with [W].") user.visible_message("[user] hits [src] with [W].", "You hit [src] with [W].") var/pass_damage = W.force + pass_damage = (pass_damage*pass_damage_reduc_mod) //Apply the reduction of damage from not having enough armor penetration. This is not regular armor values at play. for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) - pass_damage = ME.handle_projectile_contact(W, pass_damage) - src.take_damage(pass_damage,W.damtype) - src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + pass_damage = ME.handle_projectile_contact(W, user, pass_damage) + src.take_damage(pass_damage,W.damtype) //The take_damage() proc handles armor values + if(pass_damage > internal_damage_minimum) //Only decently painful attacks trigger a chance of mech damage. + src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) return ////////////////////// @@ -883,6 +1311,11 @@ to_chat(user, "[src]-MMI interface initialization failed.") return + if(istype(W, /obj/item/device/robotanalyzer)) + var/obj/item/device/robotanalyzer/RA = W + RA.do_scan(src, user) + return + if(istype(W, /obj/item/mecha_parts/mecha_equipment)) var/obj/item/mecha_parts/mecha_equipment/E = W spawn() @@ -893,6 +1326,20 @@ else to_chat(user, "You were unable to attach [W] to [src]") return + + if(istype(W, /obj/item/mecha_parts/component) && state == MECHA_CELL_OUT) + var/obj/item/mecha_parts/component/MC = W + spawn() + if(MC.attach(src)) + user.drop_item() + MC.forceMove(src) + user.visible_message("[user] installs \the [W] in \the [src]", "You install \the [W] in \the [src].") + return + + if(istype(W, /obj/item/weapon/card/robot)) + var/obj/item/weapon/card/robot/RoC = W + return attackby(RoC.dummy_card, user) + if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if(add_req_access || maint_access) if(internals_access_allowed(usr)) @@ -909,23 +1356,39 @@ else to_chat(user, "Maintenance protocols disabled by operator.") else if(W.is_wrench()) - if(state==1) - state = 2 + if(state==MECHA_BOLTS_SECURED) + state = MECHA_PANEL_LOOSE to_chat(user, "You undo the securing bolts.") - else if(state==2) - state = 1 + else if(state==MECHA_PANEL_LOOSE) + state = MECHA_BOLTS_SECURED to_chat(user, "You tighten the securing bolts.") return else if(W.is_crowbar()) - if(state==2) - state = 3 + if(state==MECHA_PANEL_LOOSE) + state = MECHA_CELL_OPEN to_chat(user, "You open the hatch to the power unit") - else if(state==3) - state=2 + else if(state==MECHA_CELL_OPEN) + state=MECHA_PANEL_LOOSE to_chat(user, "You close the hatch to the power unit") + else if(state==MECHA_CELL_OUT) + var/list/removable_components = list() + for(var/slot in internal_components) + var/obj/item/mecha_parts/component/MC = internal_components[slot] + if(istype(MC)) + removable_components[MC.name] = MC + else + to_chat(user, "\The [src] appears to be missing \the [slot].") + + var/remove = input(user, "Which component do you want to pry out?", "Remove Component") as null|anything in removable_components + if(!remove) + return + + var/obj/item/mecha_parts/component/RmC = removable_components[remove] + RmC.detach() + return else if(istype(W, /obj/item/stack/cable_coil)) - if(state == 3 && hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) + if(state >= MECHA_CELL_OPEN && hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) var/obj/item/stack/cable_coil/CC = W if(CC.use(2)) clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) @@ -937,19 +1400,19 @@ if(hasInternalDamage(MECHA_INT_TEMP_CONTROL)) clearInternalDamage(MECHA_INT_TEMP_CONTROL) to_chat(user, "You repair the damaged temperature controller.") - else if(state==3 && src.cell) + else if(state==MECHA_CELL_OPEN && src.cell) src.cell.forceMove(src.loc) src.cell = null - state = 4 + state = MECHA_CELL_OUT to_chat(user, "You unscrew and pry out the powercell.") src.log_message("Powercell removed") - else if(state==4 && src.cell) - state=3 + else if(state==MECHA_CELL_OUT && src.cell) + state=MECHA_CELL_OPEN to_chat(user, "You screw the cell in place") return else if(istype(W, /obj/item/device/multitool)) - if(state>=3 && src.occupant) + if(state>=MECHA_CELL_OPEN && src.occupant) to_chat(user, "You attempt to eject the pilot using the maintenance controls.") if(src.occupant.stat) src.go_out() @@ -961,7 +1424,7 @@ return else if(istype(W, /obj/item/weapon/cell)) - if(state==4) + if(state==MECHA_CELL_OUT) if(!src.cell) to_chat(user, "You install the powercell") user.drop_item() @@ -994,6 +1457,28 @@ user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src]") return + else if(istype(W,/obj/item/stack/nanopaste)) + if(state >= MECHA_PANEL_LOOSE) + var/obj/item/stack/nanopaste/NP = W + + for(var/slot in internal_components) + var/obj/item/mecha_parts/component/C = internal_components[slot] + + if(C) + + if(C.integrity < C.max_integrity) + while(C.integrity < C.max_integrity && NP && do_after(user, 1 SECOND, src)) + if(NP.use(1)) + C.adjust_integrity(10) + + to_chat(user, "You repair damage to \the [C].") + + return + + else + to_chat(user, "You can't reach \the [src]'s internal components.") + return + else call((proc_res["dynattackby"]||src), "dynattackby")(W,user) /* @@ -1102,7 +1587,8 @@ return /obj/mecha/remove_air(amount) - if(use_internal_tank) + var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS] + if(use_internal_tank && (GC && prob(GC.get_efficiency() * 100))) return cabin_air.remove(amount) else var/turf/T = get_turf(src) @@ -1117,7 +1603,8 @@ /obj/mecha/proc/return_pressure() . = 0 - if(use_internal_tank) + var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS] + if(use_internal_tank && (GC && prob(GC.get_efficiency() * 100))) . = cabin_air.return_pressure() else var/datum/gas_mixture/t_air = get_turf_air() @@ -1128,7 +1615,8 @@ //skytodo: //No idea what you want me to do here, mate. /obj/mecha/proc/return_temperature() . = 0 - if(use_internal_tank) + var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS] + if(use_internal_tank && (GC && prob(GC.get_efficiency() * 100))) . = cabin_air.temperature else var/datum/gas_mixture/t_air = get_turf_air() @@ -1183,13 +1671,17 @@ set category = "Exosuit Interface" set src = usr.loc set popup_menu = 0 - + if(!occupant) return - + if(usr != occupant) return - + + var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS] + if(!GC) + return + for(var/turf/T in locs) var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector) in T if(possible_port) @@ -1210,13 +1702,13 @@ set category = "Exosuit Interface" set src = usr.loc set popup_menu = 0 - + if(!occupant) return - + if(usr != occupant) return - + if(disconnect()) occupant_message("[name] disconnects from the port.") verbs -= /obj/mecha/verb/disconnect_from_port @@ -1229,6 +1721,9 @@ set category = "Exosuit Interface" set src = usr.loc set popup_menu = 0 + lights() + +/obj/mecha/verb/lights() if(usr!=occupant) return lights = !lights if(lights) set_light(light_range + lights_power) @@ -1244,18 +1739,36 @@ set category = "Exosuit Interface" set src = usr.loc set popup_menu = 0 + internal_tank() + +/obj/mecha/proc/internal_tank() if(usr!=src.occupant) return + + var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS] + if(!GC) + to_chat(occupant, "The life support systems don't seem to respond.") + return + + if(!prob(GC.get_efficiency() * 100)) + to_chat(occupant, "\The [GC] shudders and barks, before returning to how it was before.") + return + use_internal_tank = !use_internal_tank src.occupant_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].") src.log_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].") + playsound(src, 'sound/mecha/gasdisconnected.ogg', 30, 1) return + /obj/mecha/verb/toggle_strafing() set name = "Toggle strafing" set category = "Exosuit Interface" set src = usr.loc set popup_menu = 0 + strafing() + +/obj/mecha/proc/strafing() if(usr!=src.occupant) return strafing = !strafing @@ -1274,11 +1787,13 @@ move_inside() -/obj/mecha/verb/move_inside() +/obj/mecha/verb/enter() set category = "Object" set name = "Enter Exosuit" set src in oview(1) + move_inside() +/obj/mecha/proc/move_inside() if (usr.stat || !ishuman(usr)) return @@ -1324,6 +1839,8 @@ if(enter_after(40,usr)) if(!src.occupant) moved_inside(usr) + if(ishuman(occupant)) //Aeiou + GrantActions(occupant, 1) else if(src.occupant!=usr) to_chat(usr, "[src.occupant] was faster. Try better next time, loser.") else @@ -1345,8 +1862,32 @@ src.verbs += /obj/mecha/verb/eject src.log_append_to_last("[H] moved in as pilot.") src.icon_state = src.reset_icon() + //VOREStation Edit Add if(occupant.hud_used) minihud = new (occupant.hud_used, src) + //VOREStation Edit Add End + +//This part removes all the verbs if you don't have them the _possible on your mech. This is a little clunky, but it lets you just add that to any mech. +//And it's not like this 10yo code wasn't clunky before. + + if(!smoke_possible) //Can't use smoke? No verb for you. + verbs -= /obj/mecha/verb/toggle_smoke + if(!thrusters_possible) //Can't use thrusters? No verb for you. + verbs -= /obj/mecha/verb/toggle_thrusters + if(!defence_mode_possible) //Do i need to explain everything? + verbs -= /obj/mecha/verb/toggle_defence_mode + if(!overload_possible) + verbs -= /obj/mecha/verb/toggle_overload + if(!zoom_possible) + verbs -= /obj/mecha/verb/toggle_zoom + if(!phasing_possible) + verbs -= /obj/mecha/verb/toggle_phasing + if(!switch_dmg_type_possible) + verbs -= /obj/mecha/verb/switch_damtype + if(!cloak_possible) + verbs -= /obj/mecha/verb/toggle_cloak + + occupant.in_enclosed_vehicle = 1 //Useful for when you need to know if someone is in a mecho. update_cell_alerts() update_damage_alerts() set_dir(dir_in) @@ -1376,6 +1917,9 @@ else//Everyone else gets the normal noise who << sound('sound/mecha/nominal.ogg',volume=50) +/obj/mecha/AltClick(mob/living/user) + if(user == occupant) + strafing() /obj/mecha/verb/view_stats() set name = "View Stats" @@ -1415,6 +1959,7 @@ QDEL_NULL(minihud) if(ishuman(occupant)) mob_container = src.occupant + RemoveActions(occupant, human_occupant=1)//AEIOU else if(istype(occupant, /mob/living/carbon/brain)) var/mob/living/carbon/brain/brain = occupant mob_container = brain.container @@ -1434,10 +1979,19 @@ occupant.canmove = 0 occupant.clear_alert("charge") occupant.clear_alert("mech damage") + occupant.in_enclosed_vehicle = 0 occupant = null icon_state = src.reset_icon()+"-open" set_dir(dir_in) verbs -= /obj/mecha/verb/eject + + //src.zoom = 0 + + // Doesn't seem needed. + if(src.occupant && src.occupant.client) + src.occupant.client.view = world.view + src.zoom = 0 + strafing = 0 return @@ -1453,8 +2007,13 @@ /obj/mecha/proc/internals_access_allowed(mob/living/carbon/human/H) - for(var/atom/ID in list(H.get_active_hand(), H.wear_id, H.belt)) - if(src.check_access(ID,src.internals_req_access)) + if(istype(H)) + for(var/atom/ID in list(H.get_active_hand(), H.wear_id, H.belt)) + if(src.check_access(ID,src.internals_req_access)) + return 1 + else if(istype(H, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/R = H + if(src.check_access(R.idcard,src.internals_req_access)) return 1 return 0 @@ -1555,9 +2114,15 @@ var/tank_pressure = internal_tank ? round(internal_tank.return_pressure(),0.01) : "None" var/tank_temperature = internal_tank ? internal_tank.return_temperature() : "Unknown" var/cabin_pressure = round(return_pressure(),0.01) + + var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL] + var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR] + var/output = {"[report_internal_damage()] + Armor Integrity: [AC?"[round(AC.integrity / AC.max_integrity * 100, 0.1)]%":"ARMOR MISSING"]
+ Hull Integrity: [HC?"[round(HC.integrity / HC.max_integrity * 100, 0.1)]%":"HULL MISSING"]
[integrity<30?"DAMAGE LEVEL CRITICAL
":null] - Integrity: [integrity]%
+ Chassis Integrity: [integrity]%
Powercell charge: [isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]
Air source: [use_internal_tank?"Internal Airtank":"Environment"]
Airtank pressure: [tank_pressure]kPa
@@ -1567,7 +2132,18 @@ Lights: [lights?"on":"off"]
[src.dna?"DNA-locked:
[src.dna] \[Reset\]
":null] "} -//Cargo components. + + + if(defence_mode_possible) + output += "Defence mode: [defence_mode?"on":"off"]
" + if(overload_possible) + output += "Leg actuators overload: [overload?"on":"off"]
" + if(smoke_possible) + output += "Smoke: [smoke_reserve]
" + if(thrusters_possible) + output += "Thrusters: [thrusters?"on":"off"]
" + +//Cargo components. Keep this last otherwise it does weird alignment issues. output += "Cargo Compartment Contents:
" if(src.cargo.len) for(var/obj/O in src.cargo) @@ -1637,15 +2213,15 @@ output += "Micro Utility Module: [W.name] Detach
" for(var/obj/item/mecha_parts/mecha_equipment/W in micro_weapon_equipment) output += "Micro Weapon Module: [W.name] Detach
" - output += {"Available hull slots: [max_hull_equip-hull_equipment.len]
- Available weapon slots: [max_weapon_equip-weapon_equipment.len]
- Available micro weapon slots: [max_micro_weapon_equip-micro_weapon_equipment.len]
- Available utility slots: [max_utility_equip-utility_equipment.len]
- Available micro utility slots: [max_micro_utility_equip-micro_utility_equipment.len]
- Available universal slots: [max_universal_equip-universal_equipment.len]
- Available special slots: [max_special_equip-special_equipment.len]
-
- "} + output += {"Available hull slots: [max_hull_equip-hull_equipment.len]
+ Available weapon slots: [max_weapon_equip-weapon_equipment.len]
+ Available micro weapon slots: [max_micro_weapon_equip-micro_weapon_equipment.len]
+ Available utility slots: [max_utility_equip-utility_equipment.len]
+ Available micro utility slots: [max_micro_utility_equip-micro_utility_equipment.len]
+ Available universal slots: [max_universal_equip-universal_equipment.len]
+ Available special slots: [max_special_equip-special_equipment.len]
+
+ "} return output /obj/mecha/proc/get_equipment_list() //outputs mecha equipment list in html @@ -1769,12 +2345,31 @@ return if(href_list["toggle_lights"]) if(usr != src.occupant) return - src.toggle_lights() + src.lights() return +/* + if(href_list["toggle_strafing"]) + if(usr != src.occupant) return + src.strafing() + return*/ + if(href_list["toggle_airtank"]) if(usr != src.occupant) return - src.toggle_internal_tank() + src.internal_tank() return + if (href_list["toggle_thrusters"]) + src.toggle_thrusters() + if (href_list["smoke"]) + src.smoke() + if (href_list["toggle_zoom"]) + src.zoom() + if(href_list["toggle_defence_mode"]) + src.defence_mode() + if(href_list["switch_damtype"]) + src.switch_damtype() + if(href_list["phasing"]) + src.phasing() + if(href_list["rmictoggle"]) if(usr != src.occupant) return radio.broadcasting = !radio.broadcasting @@ -1835,15 +2430,15 @@ if(!in_range(src, usr)) return var/mob/user = top_filter.getMob("user") if(user) - if(state==0) - state = 1 + if(state==MECHA_OPERATING) + state = MECHA_BOLTS_SECURED to_chat(user, "The securing bolts are now exposed.") - else if(state==1) - state = 0 + else if(state==MECHA_BOLTS_SECURED) + state = MECHA_OPERATING to_chat(user, "The securing bolts are now hidden.") output_maintenance_dialog(top_filter.getObj("id_card"),user) return - if(href_list["set_internal_tank_valve"] && state >=1) + if(href_list["set_internal_tank_valve"] && state >=MECHA_BOLTS_SECURED) if(!in_range(src, usr)) return var/mob/user = top_filter.getMob("user") if(user) @@ -1851,7 +2446,7 @@ if(new_pressure) internal_tank_valve = new_pressure to_chat(user, "The internal pressure valve has been set to [internal_tank_valve]kPa.") - if(href_list["remove_passenger"] && state >= 1) + if(href_list["remove_passenger"] && state >= MECHA_BOLTS_SECURED) var/mob/user = top_filter.getMob("user") var/list/passengers = list() for (var/obj/item/mecha_parts/mecha_equipment/tool/passenger/P in contents) @@ -2010,6 +2605,13 @@ /obj/mecha/proc/dynusepower(amount) update_cell_alerts() + var/obj/item/mecha_parts/component/electrical/EC = internal_components[MECH_ELECTRIC] + + if(EC) + amount = amount * (2 - EC.get_efficiency()) * EC.charge_cost_mod + else + amount *= 5 + if(get_charge()) cell.use(amount) return 1 @@ -2017,6 +2619,13 @@ /obj/mecha/proc/give_power(amount) update_cell_alerts() + var/obj/item/mecha_parts/component/electrical/EC = internal_components[MECH_ELECTRIC] + + if(!EC) + amount /= 4 + else + amount *= EC.get_efficiency() + if(!isnull(get_charge())) cell.give(amount) return 1 @@ -2029,26 +2638,50 @@ icon_state = initial(icon_state) return icon_state +//This is for mobs mostly. /obj/mecha/attack_generic(var/mob/user, var/damage, var/attack_message) + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + var/temp_damage_minimum = damage_minimum + + if(!ArmC) + temp_deflect_chance = 1 + temp_damage_minimum = 0 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum) + user.setClickCooldown(user.get_attack_speed()) if(!damage) return 0 src.log_message("Attacked. Attacker - [user].",1) - user.do_attack_animation(src) - if(!prob(src.deflect_chance)) - src.take_damage(damage) - src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - visible_message("[user] [attack_message] [src]!") - user.attack_log += text("\[[time_stamp()]\] attacked [src.name]") - else + + if(prob(temp_deflect_chance))//Deflected src.log_append_to_last("Armor saved.") - playsound(src, 'sound/weapons/slash.ogg', 50, 1, -1) src.occupant_message("\The [user]'s attack is stopped by the armor.") visible_message("\The [user] rebounds off [src.name]'s armor!") user.attack_log += text("\[[time_stamp()]\] attacked [src.name]") + playsound(src, 'sound/weapons/slash.ogg', 50, 1, -1) + + else if(damage < temp_damage_minimum)//Pathetic damage levels just don't harm MECH. + src.occupant_message("\The [user]'s doesn't dent \the [src] paint.") + src.visible_message("\The [user]'s attack doesn't dent \the [src] armor") + src.log_append_to_last("Armor saved.") + playsound(src, 'sound/effects/Glasshit.ogg', 50, 1) + return + + else + src.take_damage(damage) //Apply damage - The take_damage() proc handles armor values + if(damage > internal_damage_minimum) //Only decently painful attacks trigger a chance of mech damage. + src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + visible_message("[user] [attack_message] [src]!") + user.attack_log += text("\[[time_stamp()]\] attacked [src.name]") + return 1 @@ -2128,7 +2761,7 @@ if(mecha.cabin_air && mecha.cabin_air.volume>0) mecha.cabin_air.temperature = min(6000+T0C, mecha.cabin_air.temperature+rand(10,15)) if(mecha.cabin_air.temperature>mecha.max_temperature/2) - mecha.take_damage(4/round(mecha.max_temperature/mecha.cabin_air.temperature,0.1),"fire") + mecha.take_damage(4/round(mecha.max_temperature/mecha.cabin_air.temperature,0.1),"fire") //The take_damage() proc handles armor values if(mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL)) //stop the mecha_preserve_temp loop datum mecha.pr_int_temp_processor.stop() if(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)) //remove some air from internal tank diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm new file mode 100644 index 00000000000..c70c3b9b837 --- /dev/null +++ b/code/game/mecha/mecha_actions.dm @@ -0,0 +1,465 @@ +//AEIOU +// +//THIS FILE CONTAINS THE CODE TO ADD THE HUD BUTTONS AND THE MECH ACTIONS THEMSELVES. +// +// +// I better get some free food for this.. + + + +// +/// Adding the buttons things to the player. The interactive, top left things, at least at time of writing. +/// If you want it to be only for a special mech, you have to go and make an override like in the durand mech. +// + +/obj/mecha/proc/GrantActions(mob/living/user, human_occupant = 0) + if(human_occupant) + eject_action.Grant(user, src) + internals_action.Grant(user, src) + cycle_action.Grant(user, src) + lights_action.Grant(user, src) + stats_action.Grant(user, src) + strafing_action.Grant(user, src)//The defaults. + + if(defence_mode_possible) + defence_action.Grant(user, src) + if(overload_possible) + overload_action.Grant(user, src) + if(smoke_possible) + smoke_action.Grant(user, src) + if(zoom_possible) + zoom_action.Grant(user, src) + if(thrusters_possible) + thrusters_action.Grant(user, src) + if(phasing_possible) + phasing_action.Grant(user, src) + if(switch_dmg_type_possible) + switch_damtype_action.Grant(user, src) + if(cloak_possible) + cloak_action.Grant(user, src) + +/obj/mecha/proc/RemoveActions(mob/living/user, human_occupant = 0) + if(human_occupant) + eject_action.Remove(user, src) + internals_action.Remove(user, src) + cycle_action.Remove(user, src) + lights_action.Remove(user, src) + stats_action.Remove(user, src) + strafing_action.Remove(user, src) + + defence_action.Remove(user, src) + smoke_action.Remove(user, src) + zoom_action.Remove(user, src) + thrusters_action.Remove(user, src) + phasing_action.Remove(user, src) + switch_damtype_action.Remove(user, src) + overload_action.Remove(user, src) + cloak_action.Remove(user, src) + + +// +////BUTTONS STUFF +// + +/datum/action/innate/mecha + check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUNNED | AB_CHECK_ALIVE + button_icon = 'icons/effects/actions_mecha.dmi' + var/obj/mecha/chassis + +/datum/action/innate/mecha/Grant(mob/living/L, obj/mecha/M) + if(M) + chassis = M + ..() + + +/datum/action/innate/mecha/mech_toggle_lights + name = "Toggle Lights" + button_icon_state = "mech_lights_off" + +/datum/action/innate/mecha/mech_toggle_lights/Activate() + button_icon_state = "mech_lights_[chassis.lights ? "off" : "on"]" + button.UpdateIcon() + chassis.lights() + + + +/datum/action/innate/mecha/mech_toggle_internals + name = "Toggle Internal Airtank Usage" + button_icon_state = "mech_internals_off" + +/datum/action/innate/mecha/mech_toggle_internals/Activate() + button_icon_state = "mech_internals_[chassis.use_internal_tank ? "off" : "on"]" + button.UpdateIcon() + chassis.internal_tank() + + + +/datum/action/innate/mecha/mech_view_stats + name = "View stats" + button_icon_state = "mech_view_stats" + +/datum/action/innate/mecha/mech_view_stats/Activate() + chassis.view_stats() + + + +/datum/action/innate/mecha/mech_eject + name = "Eject From Mech" + button_icon_state = "mech_eject" + +/datum/action/innate/mecha/mech_eject/Activate() + chassis.go_out() + + + +/datum/action/innate/mecha/strafe + name = "Toggle Mech Strafing" + button_icon_state = "mech_strafe_off" + +/datum/action/innate/mecha/strafe/Activate() + button_icon_state = "mech_strafe_[chassis.strafing ? "off" : "on"]" + button.UpdateIcon() + chassis.strafing() + + + +/datum/action/innate/mecha/mech_defence_mode + name = "Toggle Mech defence mode" + button_icon_state = "mech_defense_mode_off" + +/datum/action/innate/mecha/mech_defence_mode/Activate() + button_icon_state = "mech_defense_mode_[chassis.defence_mode ? "off" : "on"]" + button.UpdateIcon() + chassis.defence_mode() + + + +/datum/action/innate/mecha/mech_overload_mode + name = "Toggle Mech Leg Overload" + button_icon_state = "mech_overload_off" + +/datum/action/innate/mecha/mech_overload_mode/Activate() + button_icon_state = "mech_overload_[chassis.overload ? "off" : "on"]" + button.UpdateIcon() + chassis.overload() + + + +/datum/action/innate/mecha/mech_smoke + name = "Toggle Mech Smoke" + button_icon_state = "mech_smoke_off" + +/datum/action/innate/mecha/mech_smoke/Activate() + //button_icon_state = "mech_smoke_[chassis.smoke ? "off" : "on"]" + //button.UpdateIcon() //Dual colors notneeded ATM + chassis.smoke() + + + +/datum/action/innate/mecha/mech_zoom + name = "Toggle Mech Zoom" + button_icon_state = "mech_zoom_off" + +/datum/action/innate/mecha/mech_zoom/Activate() + button_icon_state = "mech_zoom_[chassis.zoom ? "off" : "on"]" + button.UpdateIcon() + chassis.zoom() + + + +/datum/action/innate/mecha/mech_toggle_thrusters + name = "Toggle Mech thrusters" + button_icon_state = "mech_thrusters_off" + +/datum/action/innate/mecha/mech_toggle_thrusters/Activate() + button_icon_state = "mech_thrusters_[chassis.thrusters ? "off" : "on"]" + button.UpdateIcon() + chassis.thrusters() + + + +/datum/action/innate/mecha/mech_cycle_equip //I'll be honest, i don't understand this part, buuuuuut it works! + name = "Cycle Equipment" + button_icon_state = "mech_cycle_equip_off" + +/datum/action/innate/mecha/mech_cycle_equip/Activate() + + var/list/available_equipment = list() + available_equipment = chassis.equipment + + if(chassis.weapons_only_cycle) + available_equipment = chassis.weapon_equipment + + if(available_equipment.len == 0) + chassis.occupant_message("No equipment available.") + return + if(!chassis.selected) + chassis.selected = available_equipment[1] + chassis.occupant_message("You select [chassis.selected]") + send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) + button_icon_state = "mech_cycle_equip_on" + button.UpdateIcon() + return + var/number = 0 + for(var/A in available_equipment) + number++ + if(A == chassis.selected) + if(available_equipment.len == number) + chassis.selected = null + chassis.occupant_message("You switch to no equipment") + button_icon_state = "mech_cycle_equip_off" + else + chassis.selected = available_equipment[number+1] + chassis.occupant_message("You switch to [chassis.selected]") + button_icon_state = "mech_cycle_equip_on" + send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) + button.UpdateIcon() + return + + + +/datum/action/innate/mecha/mech_switch_damtype + name = "Reconfigure arm microtool arrays" + button_icon_state = "mech_damtype_brute" + + +/datum/action/innate/mecha/mech_switch_damtype/Activate() + + + button_icon_state = "mech_damtype_[chassis.damtype]" + playsound(src, 'sound/mecha/mechmove01.ogg', 50, 1) + button.UpdateIcon() + chassis.query_damtype() + + + +/datum/action/innate/mecha/mech_toggle_phasing + name = "Toggle Mech phasing" + button_icon_state = "mech_phasing_off" + +/datum/action/innate/mecha/mech_toggle_phasing/Activate() + button_icon_state = "mech_phasing_[chassis.phasing ? "off" : "on"]" + button.UpdateIcon() + chassis.phasing() + + + +/datum/action/innate/mecha/mech_toggle_cloaking + name = "Toggle Mech phasing" + button_icon_state = "mech_phasing_off" + +/datum/action/innate/mecha/mech_toggle_cloaking/Activate() + button_icon_state = "mech_phasing_[chassis.cloaked ? "off" : "on"]" + button.UpdateIcon() + chassis.toggle_cloaking() + + + +///// +///// +///// ACTUAL MECANICS FOR THE ACTIONS +///// OVERLOAD, DEFENCE, SMOKE +///// +///// + + +/obj/mecha/verb/toggle_defence_mode() + set category = "Exosuit Interface" + set name = "Toggle defence mode" + set src = usr.loc + set popup_menu = 0 + defence_mode() + +/obj/mecha/proc/defence_mode() + if(usr!=src.occupant) + return + playsound(src, 'sound/mecha/duranddefencemode.ogg', 50, 1) + defence_mode = !defence_mode + if(defence_mode) + deflect_chance = defence_deflect + src.occupant_message("You enable [src] defence mode.") + else + deflect_chance = initial(deflect_chance) + src.occupant_message("You disable [src] defence mode.") + src.log_message("Toggled defence mode.") + return + + + +/obj/mecha/verb/toggle_overload() + set category = "Exosuit Interface" + set name = "Toggle leg actuators overload" + set src = usr.loc + set popup_menu = 0 + overload() + +/obj/mecha/proc/overload() + if(usr.stat == 1)//No manipulating things while unconcious. + return + if(usr!=src.occupant) + return + if(health < initial(health) - initial(health)/3)//Same formula as in movement, just beforehand. + src.occupant_message("Leg actuators damage critical, unable to engage overload.") + overload = 0 //Just to be sure + return + if(overload) + overload = 0 + step_energy_drain = initial(step_energy_drain) + src.occupant_message("You disable leg actuators overload.") + else + overload = 1 + step_energy_drain = step_energy_drain*overload_coeff + src.occupant_message("You enable leg actuators overload.") + src.log_message("Toggled leg actuators overload.") + playsound(src, 'sound/mecha/mechanical_toggle.ogg', 50, 1) + return + + +/obj/mecha/verb/toggle_smoke() + set category = "Exosuit Interface" + set name = "Activate Smoke" + set src = usr.loc + set popup_menu = 0 + smoke() + +/obj/mecha/proc/smoke() + if(usr!=src.occupant) + return + + if(smoke_reserve < 1) + src.occupant_message("You don't have any smoke left in stock!") + return + + if(smoke_ready) + smoke_reserve-- //Remove ammo + src.occupant_message("Smoke fired. [smoke_reserve] usages left.") + + var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread() + smoke.attach(src) + smoke.set_up(10, 0, usr.loc) + smoke.start() + playsound(src, 'sound/effects/smoke.ogg', 50, 1, -3) + + smoke_ready = 0 + spawn(smoke_cooldown) + smoke_ready = 1 + return + + + +/obj/mecha/verb/toggle_zoom() + set category = "Exosuit Interface" + set name = "Zoom" + set src = usr.loc + set popup_menu = 0 + zoom() + +/obj/mecha/proc/zoom()//This could use improvements but maybe later. + if(usr!=src.occupant) + return + if(src.occupant.client) + src.zoom = !src.zoom + src.log_message("Toggled zoom mode.") + src.occupant_message("Zoom mode [zoom?"en":"dis"]abled.") + if(zoom) + src.occupant.set_viewsize(12) + src.occupant << sound('sound/mecha/imag_enh.ogg',volume=50) + else + src.occupant.set_viewsize() // Reset to default + return + + + +/obj/mecha/verb/toggle_thrusters() + set category = "Exosuit Interface" + set name = "Toggle thrusters" + set src = usr.loc + set popup_menu = 0 + thrusters() + +/obj/mecha/proc/thrusters() + if(usr!=src.occupant) + return + if(src.occupant) + if(get_charge() > 0) + thrusters = !thrusters + src.log_message("Toggled thrusters.") + src.occupant_message("Thrusters [thrusters?"en":"dis"]abled.") + return + + + +/obj/mecha/verb/switch_damtype() + set category = "Exosuit Interface" + set name = "Change melee damage type" + set src = usr.loc + set popup_menu = 0 + query_damtype() + +/obj/mecha/proc/query_damtype() + if(usr!=src.occupant) + return + var/new_damtype = alert(src.occupant,"Melee Damage Type",null,"Brute","Fire","Toxic") + switch(new_damtype) + if("Brute") + damtype = "brute" + src.occupant_message("Your exosuit's hands form into fists.") + if("Fire") + damtype = "fire" + src.occupant_message("A torch tip extends from your exosuit's hand, glowing red.") + if("Toxic") + damtype = "tox" + src.occupant_message("A bone-chillingly thick plasteel needle protracts from the exosuit's palm.") + src.occupant_message("Melee damage type switched to [new_damtype]") + return + + + +/obj/mecha/verb/toggle_phasing() + set category = "Exosuit Interface" + set name = "Toggle phasing" + set src = usr.loc + set popup_menu = 0 + phasing() + +/obj/mecha/proc/phasing() + if(usr!=src.occupant) + return + phasing = !phasing + send_byjax(src.occupant,"exosuit.browser","phasing_command","[phasing?"Dis":"En"]able phasing") + src.occupant_message("En":"#f00\">Dis"]abled phasing.") + return + + +/obj/mecha/verb/toggle_cloak() + set category = "Exosuit Interface" + set name = "Toggle cloaking" + set src = usr.loc + set popup_menu = 0 + toggle_cloaking() + +/obj/mecha/proc/toggle_cloaking() + if(usr!=src.occupant) + return + + if(cloaked) + uncloak() + else + cloak() + + src.occupant_message("En":"#f00\">Dis"]abled cloaking.") + return + +/obj/mecha/verb/toggle_weapons_only_cycle() + set category = "Exosuit Interface" + set name = "Toggle weapons only cycling" + set src = usr.loc + set popup_menu = 0 + set_weapons_only_cycle() + +/obj/mecha/proc/set_weapons_only_cycle() + if(usr!=src.occupant) + return + weapons_only_cycle = !weapons_only_cycle + src.occupant_message("En":"#f00\">Dis"]abled weapons only cycling.") + return diff --git a/code/game/mecha/mecha_vr.dm b/code/game/mecha/mecha_vr.dm new file mode 100644 index 00000000000..674c9887843 --- /dev/null +++ b/code/game/mecha/mecha_vr.dm @@ -0,0 +1,3 @@ +/obj/mecha + damage_minimum = 5 //Incoming damage lower than this won't actually deal damage. Scrapes shouldn't be a real thing. + minimum_penetration = 10 //Incoming damage won't be fully applied if you don't have at least 20. Almost all AP clears this. diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm index 6e9dee50475..973ddec3fc1 100644 --- a/code/game/mecha/medical/medical.dm +++ b/code/game/mecha/medical/medical.dm @@ -9,6 +9,14 @@ cargo_capacity = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/lightweight, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + /obj/mecha/medical/Initialize() . = ..() var/turf/T = get_turf(src) diff --git a/code/game/mecha/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm index ce72a161194..dbba0cd2518 100644 --- a/code/game/mecha/medical/odysseus.dm +++ b/code/game/mecha/medical/odysseus.dm @@ -1,4 +1,4 @@ -/obj/mecha/medical/odysseus/ +/obj/mecha/medical/odysseus desc = "These exosuits are developed and produced by Vey-Med. (© All rights reserved)." name = "Odysseus" catalogue_data = list( @@ -9,8 +9,8 @@ initial_icon = "odysseus" step_in = 2 max_temperature = 15000 - health = 120 - maxhealth = 120 + health = 70 + maxhealth = 70 wreckage = /obj/effect/decal/mecha_wreckage/odysseus internal_damage_threshold = 35 deflect_chance = 15 @@ -130,4 +130,14 @@ ME = new /obj/item/mecha_parts/mecha_equipment/tool/sleeper ME.attach(src) ME = new /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun - ME.attach(src) \ No newline at end of file + ME.attach(src) + +//Meant for random spawns. +/obj/mecha/medical/odysseus/old + desc = "An aging combat exosuit utilized by many corporations. Originally developed to combat hostile alien lifeforms. This one is particularly worn looking and likely isn't as sturdy." + +/obj/mecha/medical/odysseus/old/New() + ..() + health = 25 + maxhealth = 50 //Just slightly worse. + cell.charge = rand(0, (cell.charge/2)) \ No newline at end of file diff --git a/code/game/mecha/medical/odysseus_vr.dm b/code/game/mecha/medical/odysseus_vr.dm new file mode 100644 index 00000000000..3c87a14e903 --- /dev/null +++ b/code/game/mecha/medical/odysseus_vr.dm @@ -0,0 +1,2 @@ +/obj/mecha/medical/odysseus/ + minimum_penetration = 0 diff --git a/code/game/mecha/micro/micro.dm b/code/game/mecha/micro/micro.dm index 0b1e3404879..97f86f74727 100644 --- a/code/game/mecha/micro/micro.dm +++ b/code/game/mecha/micro/micro.dm @@ -28,7 +28,8 @@ //operation_req_access = list(access_hos) damage_absorption = list("brute"=1,"fire"=1,"bullet"=1,"laser"=1,"energy"=1,"bomb"=1) var/am = "d3c2fbcadca903a41161ccc9df9cf948" - + damage_minimum = 0 //Incoming damage lower than this won't actually deal damage. Scrapes shouldn't be a real thing. + minimum_penetration = 0 //Incoming damage won't be fully applied if you don't have at least 20. Almost all AP clears this. /obj/mecha/micro/melee_action(target as obj|mob|turf) if(internal_damage&MECHA_INT_CONTROL_LOST) diff --git a/code/game/mecha/micro/security.dm b/code/game/mecha/micro/security.dm index 713c08d3d9e..d6d054a4f5a 100644 --- a/code/game/mecha/micro/security.dm +++ b/code/game/mecha/micro/security.dm @@ -25,13 +25,12 @@ damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1) max_temperature = 15000 infra_luminosity = 6 - var/overload = 0 - var/overload_coeff = 2 wreckage = /obj/effect/decal/mecha_wreckage/micro/sec/polecat internal_damage_threshold = 35 max_equip = 3 max_micro_utility_equip = 0 max_micro_weapon_equip = 3 + damage_minimum = 5 //A teeny bit of armor /obj/effect/decal/mecha_wreckage/micro/sec/polecat name = "Polecat wreckage" @@ -48,9 +47,6 @@ deflect_chance = 5 damage_absorption = list("brute"=1,"fire"=1,"bullet"=0.9,"laser"=0.8,"energy"=0.85,"bomb"=1) max_temperature = 5000 - infra_luminosity = 6 - var/overload = 0 - var/overload_coeff = 2 wreckage = /obj/effect/decal/mecha_wreckage/micro/sec/weasel internal_damage_threshold = 20 max_equip = 2 diff --git a/code/game/mecha/micro/utility.dm b/code/game/mecha/micro/utility.dm index 0d7290a1cfe..9ceaa2bae9d 100644 --- a/code/game/mecha/micro/utility.dm +++ b/code/game/mecha/micro/utility.dm @@ -12,8 +12,6 @@ damage_absorption = list("brute"=0.9,"fire"=1,"bullet"=1,"laser"=1,"energy"=1,"bomb"=1) max_temperature = 15000 infra_luminosity = 6 - var/overload = 0 - var/overload_coeff = 2 wreckage = /obj/effect/decal/mecha_wreckage/micro/utility/gopher internal_damage_threshold = 35 max_micro_utility_equip = 2 diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 938a720c4f2..86405b69347 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -7,11 +7,21 @@ step_energy_drain = 5 // vorestation edit because 10 drained a significant chunk of its cell before you even got out the airlock max_temperature = 20000 health = 200 - maxhealth = 200 + maxhealth = 200 //Don't forget to update the /old variant if you change this number. wreckage = /obj/effect/decal/mecha_wreckage/ripley cargo_capacity = 10 var/obj/item/weapon/mining_scanner/orescanner // vorestation addition + minimum_penetration = 10 + + starting_components = list( + /obj/item/mecha_parts/component/hull/durable, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/mining, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + /obj/mecha/working/ripley/Destroy() for(var/atom/movable/A in src.cargo) A.loc = loc @@ -81,7 +91,7 @@ qdel (B) -// VORESTATION EDIT BEGIN +//Vorestation Edit Start /obj/mecha/working/ripley/New() ..() @@ -95,5 +105,14 @@ orescanner.attack_self(usr) -// VORESTATION EDIT END +//Vorestation Edit End +//Meant for random spawns. +/obj/mecha/working/ripley/mining/old + desc = "An old, dusty mining ripley." + +/obj/mecha/working/ripley/mining/old/New() + ..() + health = 25 + maxhealth = 190 //Just slightly worse. + cell.charge = rand(0, cell.charge) diff --git a/code/game/mecha/working/ripley_vr.dm b/code/game/mecha/working/ripley_vr.dm new file mode 100644 index 00000000000..102ae7c910c --- /dev/null +++ b/code/game/mecha/working/ripley_vr.dm @@ -0,0 +1,2 @@ +/obj/mecha/working/ripley + minimum_penetration = 0 diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm index b69226815e2..bd6e1e97f61 100644 --- a/code/game/objects/effects/decals/Cleanable/fuel.dm +++ b/code/game/objects/effects/decals/Cleanable/fuel.dm @@ -5,6 +5,8 @@ plane = DIRTY_PLANE anchored = 1 var/amount = 1 + generic_filth = TRUE + persistent = FALSE /obj/effect/decal/cleanable/liquid_fuel/New(turf/newLoc,amt=1,nologs=1) if(!nologs) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index ce0f117e5a3..ee02464c1e7 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -20,6 +20,8 @@ var/global/list/image/splatter_cache=list() var/synthblood = 0 var/list/datum/disease2/disease/virus2 = list() var/amount = 5 + generic_filth = TRUE + persistent = FALSE /obj/effect/decal/cleanable/blood/reveal_blood() if(!fluorescent) diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index 1f49fc9f666..bdc5c9237a6 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -5,6 +5,8 @@ icon_state = "gib1" basecolor = SYNTH_BLOOD_COLOUR random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7") + generic_filth = FALSE + persistent = FALSE /obj/effect/decal/cleanable/blood/gibs/robot/update_icon() color = "#FFFFFF" @@ -39,6 +41,8 @@ /obj/effect/decal/cleanable/blood/oil basecolor = SYNTH_BLOOD_COLOUR + generic_filth = FALSE + persistent = FALSE /obj/effect/decal/cleanable/blood/oil/dry() return diff --git a/code/game/objects/effects/decals/Cleanable/tracks.dm b/code/game/objects/effects/decals/Cleanable/tracks.dm index 0ad5ac13f81..934068f25bb 100644 --- a/code/game/objects/effects/decals/Cleanable/tracks.dm +++ b/code/game/objects/effects/decals/Cleanable/tracks.dm @@ -46,6 +46,8 @@ var/global/list/image/fluidtrack_cache=list() var/coming_state="blood1" var/going_state="blood2" var/updatedtracks=0 + persistent = TRUE + generic_filth = FALSE // dir = id in stack var/list/setdirs=list( diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index f7965e092d0..2ef6582553f 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -1,7 +1,29 @@ +/* +USAGE NOTE +For decals, the var Persistent = 'has already been saved', and is primarily used to prevent duplicate savings of generic filth (filth.dm). +This also means 'TRUE' can be used to define a decal as "Do not save at all, even as a generic replacement." if a dirt decal is considered 'too common' to save. +generic_filth = TRUE means when the decal is saved, it will be switched out for a generic green 'filth' decal. +*/ + /obj/effect/decal/cleanable plane = DIRTY_PLANE + var/persistent = FALSE + var/generic_filth = FALSE + var/age = 0 var/list/random_icon_states = list() +/obj/effect/decal/cleanable/Initialize(var/ml, var/_age) + if(!isnull(_age)) + age = _age + if(random_icon_states && length(src.random_icon_states) > 0) + src.icon_state = pick(src.random_icon_states) + SSpersistence.track_value(src, /datum/persistent/filth) + . = ..() + +/obj/effect/decal/cleanable/Destroy() + SSpersistence.forget_value(src, /datum/persistent/filth) + . = ..() + /obj/effect/decal/cleanable/clean_blood(var/ignore = 0) if(!ignore) qdel(src) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 15931b5868d..48223c67e25 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -262,6 +262,21 @@ steam.start() -- spawns the effect projectiles -= proj */ +// Burnt Food Smoke (Specialty for Cooking Failures) +/obj/effect/effect/smoke/bad/burntfood + color = "#000000" + time_to_live = 600 + +/obj/effect/effect/smoke/bad/burntfood/process() + for(var/mob/living/L in get_turf(src)) + affect(L) + +/obj/effect/effect/smoke/bad/burntfood/affect(var/mob/living/L) // This stuff is extra-vile. + if (!..()) + return 0 + if(L.needs_to_breathe()) + L.emote("cough") + ///////////////////////////////////////////// // 'Elemental' smoke ///////////////////////////////////////////// @@ -376,6 +391,9 @@ steam.start() -- spawns the effect /datum/effect/effect/system/smoke_spread/bad smoke_type = /obj/effect/effect/smoke/bad + +/datum/effect/effect/system/smoke_spread/bad/burntfood + smoke_type = /obj/effect/effect/smoke/bad/burntfood /datum/effect/effect/system/smoke_spread/noxious smoke_type = /obj/effect/effect/smoke/bad/noxious diff --git a/code/game/objects/effects/map_effects/perma_light.dm b/code/game/objects/effects/map_effects/perma_light.dm index 281c128fe67..a48e768fc70 100644 --- a/code/game/objects/effects/map_effects/perma_light.dm +++ b/code/game/objects/effects/map_effects/perma_light.dm @@ -14,4 +14,15 @@ light_range = 5 light_power = 3 - light_color = "#FFFFFF" \ No newline at end of file + light_color = "#FFFFFF" + +/obj/effect/map_effect/perma_light/concentrated + name = "permanent light (concentrated)" + + light_range = 2 + light_power = 5 + +/obj/effect/map_effect/perma_light/concentrated/incandescent + name = "permanent light (concentrated incandescent)" + + light_color = LIGHT_COLOR_INCANDESCENT_TUBE \ No newline at end of file diff --git a/code/game/objects/effects/map_effects/portal.dm b/code/game/objects/effects/map_effects/portal.dm new file mode 100644 index 00000000000..2331cac8e84 --- /dev/null +++ b/code/game/objects/effects/map_effects/portal.dm @@ -0,0 +1,344 @@ +GLOBAL_LIST_EMPTY(all_portal_masters) + +/* + +Portal map effects allow a mapper to join two distant places together, while looking somewhat seamlessly connected. +This can allow for very strange PoIs that twist and turn in what appear to be physically impossible ways. + +Portals do have some specific requirements when mapping them in; + - There must by one, and only one `/obj/effect/map_effect/portal/master` for each side of a portal. + - Both sides need to have matching `portal_id`s in order to link to each other. + - Each side must face opposite directions, e.g. if side A faces SOUTH, side B must face NORTH. + - Each side must have the same orientation, e.g. horizontal on both sides, or vertical on both sides. + - Portals can be made to be longer than 1x1 with `/obj/effect/map_effect/portal/line`s, + but both sides must have the same length. + - If portal lines are added, they must form a straight line and be next to a portal master or another portal line. + - If portal lines are used, both portal masters should be in the same relative position among the lines. + E.g. both being on the left most side on a horizontal row. + +Portals also have some limitations to be aware of when mapping. Some of these are not an issue if you're trying to make an 'obvious' portal; + - The objects seen through portals are purely visual, which has many implications, + such as simple_mob AIs being blind to mobs on the other side of portals. + - Objects on the other side of a portal can be interacted with if the interaction has no range limitation, + or the distance between the two portal sides happens to be less than the interaction max range. Examine will probably work, + while picking up an item that appears to be next to you will fail. + - Sounds currently are not carried across portals. + - Mismatched lighting between each portal end can make the portal look obvious. + - Portals look weird when observing as a ghost, or otherwise when able to see through walls. Meson vision will also spoil the illusion. + - Walls that change icons based on neightboring walls can give away that a portal is nearby if both sides don't have a similar transition. + - Projectiles that pass through portals will generally work as intended, however aiming and firing upon someone on the other side of a portal + will likely be weird due to the click targeting the real position of the thing clicked instead of the apparent position. + Thrown objects suffer a similar fate. + - The tiles that are visually shown across a portal are determined based on visibility at the time of portal initialization, + and currently don't update, meaning that opacity changes are not reflected, e.g. a wall is deconstructed, or an airlock is opened. + - There is currently a small but somewhat noticable pause in mob movement when moving across a portal, + as a result of the mob's glide animation being inturrupted by a teleport. + - Gas is not transferred through portals, and ZAS is oblivious to them. + +A lot of those limitations can potentially be solved with some more work. Otherwise, portals work best in static environments like Points of Interest, +when portals are shortly lived, or when portals are made to be obvious with special effects. +*/ + +/obj/effect/map_effect/portal + name = "portal subtype" + invisibility = 0 + opacity = TRUE + plane = TURF_PLANE + layer = ABOVE_TURF_LAYER + appearance_flags = PIXEL_SCALE|KEEP_TOGETHER // Removed TILE_BOUND so things not visible on the other side stay hidden from the viewer. + + var/obj/effect/map_effect/portal/counterpart = null // The portal line or master that this is connected to, on the 'other side'. + + // Information used to apply `pixel_[x|y]` offsets so that the visuals line up. + // Set automatically by `calculate_dimensions()`. + var/total_height = 0 // Measured in tiles. + var/total_width = 0 + + var/portal_distance_x = 0 // How far the portal is from the left edge, in tiles. + var/portal_distance_y = 0 // How far the portal is from the top edge. + +/obj/effect/map_effect/portal/Destroy() + vis_contents = null + if(counterpart) + counterpart.counterpart = null // Disconnect our counterpart from us + counterpart = null // Now disconnect us from them. + return ..() + +// Called when something touches the portal, and usually teleports them to the other side. +/obj/effect/map_effect/portal/Crossed(atom/movable/AM) + if(AM.is_incorporeal()) + return + ..() + if(!AM) + return + if(!counterpart) + return + + go_through_portal(AM) + + +/obj/effect/map_effect/portal/proc/go_through_portal(atom/movable/AM) + // TODO: Find a way to fake the glide or something. + if(isliving(AM)) + var/mob/living/L = AM + if(L.pulling) + var/atom/movable/pulled = L.pulling + L.stop_pulling() + // For some reason, trying to put the pulled object behind the person makes the drag stop and it doesn't even move to the other side. + // pulled.forceMove(get_turf(counterpart)) + pulled.forceMove(counterpart.get_focused_turf()) + L.forceMove(counterpart.get_focused_turf()) + L.start_pulling(pulled) + else + L.forceMove(counterpart.get_focused_turf()) + else + AM.forceMove(counterpart.get_focused_turf()) + +// 'Focused turf' is the turf directly in front of a portal, +// and it is used both as the destination when crossing, as well as the PoV for visuals. +/obj/effect/map_effect/portal/proc/get_focused_turf() + return get_step(get_turf(src), dir) + +// Determines the size of the block of turfs inside `vis_contents`, and where the portal is in relation to that. +/obj/effect/map_effect/portal/proc/calculate_dimensions() + var/highest_x = 0 + var/lowest_x = 0 + + var/highest_y = 0 + var/lowest_y = 0 + + // First pass is for finding the top right corner. + for(var/thing in vis_contents) + var/turf/T = thing + if(T.x > highest_x) + highest_x = T.x + if(T.y > highest_y) + highest_y = T.y + + lowest_x = highest_x + lowest_y = highest_y + + // Second one is for the bottom left corner. + for(var/thing in vis_contents) + var/turf/T = thing + if(T.x < lowest_x) + lowest_x = T.x + if(T.y < lowest_y) + lowest_y = T.y + + // Now calculate the dimensions. + total_width = (highest_x - lowest_x) + 1 + total_height = (highest_y - lowest_y) + 1 + + // Find how far the portal is from the edges. + var/turf/focused_T = counterpart.get_focused_turf() + portal_distance_x = lowest_x - focused_T.x + portal_distance_y = lowest_y - focused_T.y + + +// Portal masters manage everything else involving portals. +// This is the base type. Use `/side_a` or `/side_b` with matching IDs for actual portals. +/obj/effect/map_effect/portal/master + name = "portal master" + show_messages = TRUE // So portals can hear and see, and relay to the other side. + var/portal_id = "test" // For a portal to be made, both the A and B sides need to share the same ID value. + var/list/portal_lines = list() + +/obj/effect/map_effect/portal/master/Initialize() + GLOB.all_portal_masters += src + find_lines() + ..() + return INITIALIZE_HINT_LATELOAD + +/obj/effect/map_effect/portal/master/LateInitialize() + find_counterparts() + make_visuals() + apply_offset() + +/obj/effect/map_effect/portal/master/Destroy() + GLOB.all_portal_masters -= src + for(var/thing in portal_lines) + qdel(thing) + return ..() + +/obj/effect/map_effect/portal/master/proc/find_lines() + var/list/dirs_to_search = list( turn(dir, 90), turn(dir, -90) ) + + for(var/dir_to_search in dirs_to_search) + var/turf/current_T = get_turf(src) + while(current_T) + current_T = get_step(current_T, dir_to_search) + var/obj/effect/map_effect/portal/line/line = locate() in current_T + if(line) + portal_lines += line + line.my_master = src + else + break + +// Connects both sides of a portal together. +/obj/effect/map_effect/portal/master/proc/find_counterparts() + for(var/thing in GLOB.all_portal_masters) + var/obj/effect/map_effect/portal/master/M = thing + if(M == src) + continue + if(M.counterpart) + continue + + if(M.portal_id == src.portal_id) + counterpart = M + M.counterpart = src + if(portal_lines.len) + for(var/i = 1 to portal_lines.len) + var/obj/effect/map_effect/portal/line/our_line = portal_lines[i] + var/obj/effect/map_effect/portal/line/their_line = M.portal_lines[i] + our_line.counterpart = their_line + their_line.counterpart = our_line + break + + if(!counterpart) + crash_with("Portal master [type] ([x],[y],[z]) could not find another portal master with a matching portal_id ([portal_id]).") + +/obj/effect/map_effect/portal/master/proc/make_visuals() + var/list/observed_turfs = list() + for(var/thing in portal_lines + src) + var/obj/effect/map_effect/portal/P = thing + P.name = null + P.icon_state = null + + if(!P.counterpart) + return + + var/turf/T = P.counterpart.get_focused_turf() + P.vis_contents += T + + var/list/things = dview(world.view, T) + for(var/turf/turf in things) + if(get_dir(turf, T) & P.dir) + if(turf in observed_turfs) // Avoid showing the same turf twice or more for improved performance. + continue + + P.vis_contents += turf + observed_turfs += turf + + P.calculate_dimensions() + +// Shifts the portal's pixels in order to line up properly, as BYOND offsets the sprite when it holds multiple turfs inside `vis_contents`. +// This undos the shift that BYOND did. +/obj/effect/map_effect/portal/master/proc/apply_offset() + for(var/thing in portal_lines + src) + var/obj/effect/map_effect/portal/P = thing + + P.pixel_x = WORLD_ICON_SIZE * P.portal_distance_x + P.pixel_y = WORLD_ICON_SIZE * P.portal_distance_y + +// Allows portals to transfer emotes. +// Only portal masters do this to avoid flooding the other side with duplicate messages. +/obj/effect/map_effect/portal/master/see_emote(mob/M, text) + if(!counterpart) + return + var/turf/T = counterpart.get_focused_turf() + var/list/in_range = get_mobs_and_objs_in_view_fast(T, world.view, 0) + var/list/mobs_to_relay = in_range["mobs"] + + for(var/thing in mobs_to_relay) + var/mob/mob = thing + var/rendered = "[text]" + mob.show_message(rendered) + + ..() + +// Allows portals to transfer visible messages. +/obj/effect/map_effect/portal/master/show_message(msg, type, alt, alt_type) + if(!counterpart) + return + var/rendered = "[msg]" + var/turf/T = counterpart.get_focused_turf() + var/list/in_range = get_mobs_and_objs_in_view_fast(T, world.view, 0) + var/list/mobs_to_relay = in_range["mobs"] + + for(var/thing in mobs_to_relay) + var/mob/mob = thing + mob.show_message(rendered) + + ..() + +// Allows portals to transfer speech. +/obj/effect/map_effect/portal/master/hear_talk(mob/M, list/message_pieces, verb) + if(!counterpart) + return + var/turf/T = counterpart.get_focused_turf() + var/list/in_range = get_mobs_and_objs_in_view_fast(T, world.view, 0) + var/list/mobs_to_relay = in_range["mobs"] + + for(var/thing in mobs_to_relay) + var/mob/mob = thing + var/message = mob.combine_message(message_pieces, verb, M) + var/name_used = M.GetVoice() + var/rendered = null + rendered = "[name_used] [message]" + mob.show_message(rendered, 2) + + ..() + +// Returns the position that an atom that's hopefully on the other side of the portal would be if it were really there. +// Z levels not taken into account. +/obj/effect/map_effect/portal/master/proc/get_apparent_position(atom/A) + if(!counterpart) + return null + + var/turf/true_turf = get_turf(A) + var/obj/effect/map_effect/portal/master/other_master = counterpart + + var/in_vis_contents = FALSE + for(var/thing in other_master.portal_lines + other_master) + var/obj/effect/map_effect/portal/P = thing + if(P in true_turf.vis_locs) + in_vis_contents = TRUE + break + + if(!in_vis_contents) + return null // Not in vision of the other portal. + + var/turf/their_focus = counterpart.get_focused_turf() + var/turf/our_focus = get_focused_turf() + + var/relative_x = (true_turf.x - our_focus.x) + relative_x += SIGN(relative_x) + var/relative_y = (true_turf.y - our_focus.y) + relative_y += SIGN(relative_y) + + return new /datum/position(their_focus.x + relative_x, their_focus.y + relative_y, our_focus.z) + + +/obj/effect/map_effect/portal/master/side_a + name = "portal master A" + icon_state = "portal_side_a" +// color = "#00FF00" + +/obj/effect/map_effect/portal/master/side_b + name = "portal master B" + icon_state = "portal_side_b" +// color = "#FF0000" + + + +// Portal lines extend out from the sides of portal masters, +// They let portals be longer than 1x1. +// Both sides MUST be the same length, meaning if side A is 1x3, side B must also be 1x3. +/obj/effect/map_effect/portal/line + name = "portal line" + var/obj/effect/map_effect/portal/master/my_master = null + +/obj/effect/map_effect/portal/line/Destroy() + if(my_master) + my_master.portal_lines -= src + my_master = null + return ..() + +/obj/effect/map_effect/portal/line/side_a + name = "portal line A" + icon_state = "portal_line_side_a" + +/obj/effect/map_effect/portal/line/side_b + name = "portal line B" + icon_state = "portal_line_side_b" \ No newline at end of file diff --git a/code/game/objects/items/balls_vr.dm b/code/game/objects/items/balls_vr.dm new file mode 100644 index 00000000000..6c0b1c25a84 --- /dev/null +++ b/code/game/objects/items/balls_vr.dm @@ -0,0 +1,51 @@ +/obj/item/toy/tennis + name = "tennis ball" + desc = "A classic tennis ball; a hollow rubber sphere covered in felt. This one has seen better days, and seems to have lost most of its bounce." + icon = 'icons/obj/balls_vr.dmi' + icon_state = "tennis_classic" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/righthand_balls_vr.dmi', + slot_r_hand_str = 'icons/mob/items/lefthand_balls_vr.dmi', + slot_wear_mask_str = 'icons/mob/mouthball_vr.dmi', + ) + item_state = "tennis_classic" + slot_flags = SLOT_MASK + throw_range = 14 + w_class = ITEMSIZE_SMALL + +/obj/item/toy/tennis/red + name = "red tennis ball" + desc = "A red tennis ball. It goes twice as fast!" + icon_state = "tennis_red" + item_state = "tennis_red" + throw_speed = 8 //base throw_speed is 4, and that's already super fast + +/obj/item/toy/tennis/yellow + name = "yellow tennis ball" + desc = "A yellow tennis ball. Or is it orange? Orangey-yellow?" + icon_state = "tennis_yellow" + item_state = "tennis_yellow" + +/obj/item/toy/tennis/green + name = "green tennis ball" + desc = "A bright green tennis ball. Tastes faintly of lime... or maybe soap." + icon_state = "tennis_green" + item_state = "tennis_green" + +/obj/item/toy/tennis/cyan + name = "cyan tennis ball" + desc = "A cyan tennis ball. What a curious color choice." + icon_state = "tennis_cyan" + item_state = "tennis_cyan" + +/obj/item/toy/tennis/blue + name = "blue tennis ball" + desc = "A blue tennis ball. Who makes blue tennis balls anyway?" + icon_state = "tennis_blue" + item_state = "tennis_blue" + +/obj/item/toy/tennis/purple + name = "purple tennis ball" + desc = "A purple tennis ball. Now you've seen everything. Purple, seriously?" + icon_state = "tennis_purple" + item_state = "tennis_purple" \ No newline at end of file diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index ad4e1d7f3e7..0e5f8f287a5 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -519,7 +519,10 @@ var/list/civilian_cartridges = list( if(bl.z != cl.z) continue var/direction = get_dir(src,B) - CartData[++CartData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = B.reagents.total_volume/100) + var/status = "No Bucket" + if(B.mybucket) + status = B.mybucket.reagents.total_volume / 100 + CartData[++CartData.len] = list("x" = bl.x, "y" = bl.y, "dir" = uppertext(dir2text(direction)), "status" = status) if(!CartData.len) CartData[++CartData.len] = list("x" = 0, "y" = 0, dir=null, status = null) diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index f20e340f342..fd9767dd877 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -22,15 +22,26 @@ to_chat(user, "ERROR ERROR ERROR") /obj/item/device/aicard/attack_self(mob/user) + tgui_interact(user) - ui_interact(user) +/obj/item/device/aicard/tgui_interact(mob/user, datum/tgui/ui = null, datum/tgui_state/custom_state) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AICard", "[name]") // 600, 394 + ui.open() + if(custom_state) + ui.set_state(custom_state) -/obj/item/device/aicard/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = inventory_state) +/obj/item/device/aicard/tgui_state(mob/user) + return GLOB.tgui_inventory_state + +/obj/item/device/aicard/tgui_data(mob/user) var/data[0] + data["has_ai"] = carded_ai != null if(carded_ai) data["name"] = carded_ai.name - data["hardware_integrity"] = carded_ai.hardware_integrity() + data["integrity"] = carded_ai.hardware_integrity() data["backup_capacitor"] = carded_ai.backup_capacitor() data["radio"] = !carded_ai.aiRadio.disabledAi data["wireless"] = !carded_ai.control_disabled @@ -38,52 +49,42 @@ data["flushing"] = flush var/laws[0] - for(var/datum/ai_law/AL in carded_ai.laws.all_laws()) - laws[++laws.len] = list("index" = AL.get_index(), "law" = sanitize(AL.law)) + for(var/datum/ai_law/law in carded_ai.laws.all_laws()) + if(law in carded_ai.laws.ion_laws) // If we're an ion law, give it an ion index code + laws.Add(ionnum() + ". " + law.law) + else + laws.Add(num2text(law.get_index()) + ". " + law.law) data["laws"] = laws - data["has_laws"] = laws.len + data["has_laws"] = length(carded_ai.laws.all_laws()) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "aicard.tmpl", "[name]", 600, 400, state = state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/obj/item/device/aicard/Topic(href, href_list, state) +/obj/item/device/aicard/tgui_act(action, params) if(..()) - return 1 + return TRUE if(!carded_ai) - return 1 + return var/user = usr - if (href_list["wipe"]) - var/confirm = alert("Are you sure you want to disable this core's power? This cannot be undone once started.", "Confirm Shutdown", "No", "Yes") - if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE)) + switch(action) + if("wipe") + msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].") add_attack_logs(user,carded_ai,"Purged from AI Card") - flush = 1 - carded_ai.suiciding = 1 - to_chat(carded_ai, "Your power has been disabled!") - while (carded_ai && carded_ai.stat != DEAD) - if(carded_ai.deployed_shell && prob(carded_ai.oxyloss)) //You feel it creeping? Eventually will reach 100, resulting in the second half of the AI's remaining life being lonely. - carded_ai.disconnect_shell("Disconnecting from remote shell due to insufficent power.") - carded_ai.adjustOxyLoss(2) - carded_ai.updatehealth() - sleep(10) - flush = 0 - if (href_list["radio"]) - carded_ai.aiRadio.disabledAi = text2num(href_list["radio"]) - to_chat(carded_ai, "Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!") - to_chat(user, "You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.") - if (href_list["wireless"]) - carded_ai.control_disabled = text2num(href_list["wireless"]) - to_chat(carded_ai, "Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!") - to_chat(user, "You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.") - if(carded_ai.control_disabled && carded_ai.deployed_shell) - carded_ai.disconnect_shell("Disconnecting from remote shell due to [src] wireless access interface being disabled.") - update_icon() - return 1 + INVOKE_ASYNC(src, .proc/wipe_ai) + if("radio") + carded_ai.aiRadio.disabledAi = !carded_ai.aiRadio.disabledAi + to_chat(carded_ai, "Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!") + to_chat(user, "You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.") + if("wireless") + carded_ai.control_disabled = !carded_ai.control_disabled + to_chat(carded_ai, "Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!") + to_chat(user, "You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.") + if(carded_ai.control_disabled && carded_ai.deployed_shell) + carded_ai.disconnect_shell("Disconnecting from remote shell due to [src] wireless access interface being disabled.") + update_icon() + + return TRUE /obj/item/device/aicard/update_icon() overlays.Cut() @@ -168,3 +169,17 @@ var/obj/item/weapon/rig/rig = src.get_rig() if(istype(rig)) rig.forced_move(direction, user) + +/obj/item/device/aicard/proc/wipe_ai() + var/mob/living/silicon/ai/AI = carded_ai + flush = TRUE + AI.suiciding = TRUE + to_chat(AI, "Your power has been disabled!") + while(AI && AI.stat != DEAD) + // This is absolutely evil and I love it. + if(AI.deployed_shell && prob(AI.oxyloss)) //You feel it creeping? Eventually will reach 100, resulting in the second half of the AI's remaining life being lonely. + AI.disconnect_shell("Disconnecting from remote shell due to insufficent power.") + AI.adjustOxyLoss(2) + AI.updatehealth() + sleep(10) + flush = FALSE \ No newline at end of file diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index d6f42bee8f4..09cee5bb4c2 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -10,7 +10,7 @@ origin_tech = list(TECH_ILLEGAL = 4, TECH_MAGNET = 4) var/can_use = 1 var/obj/effect/dummy/chameleon/active_dummy = null - var/saved_item = /obj/item/weapon/cigbutt + var/saved_item = /obj/item/trash/cigbutt var/saved_icon = 'icons/obj/clothing/masks.dmi' var/saved_icon_state = "cigbutt" var/saved_overlays diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm index 680bebf6e9e..8e5fa683c90 100644 --- a/code/game/objects/items/devices/defib.dm +++ b/code/game/objects/items/devices/defib.dm @@ -338,14 +338,14 @@ if(!heart) return TRUE - var/blood_volume = round((H.vessel.get_reagent_amount("blood")/H.species.blood_volume)*100) + var/blood_volume = H.vessel.get_reagent_amount("blood") if(!heart || heart.is_broken()) blood_volume *= 0.3 else if(heart.is_bruised()) blood_volume *= 0.7 else if(heart.damage > 1) blood_volume *= 0.8 - return blood_volume < BLOOD_VOLUME_SURVIVE + return blood_volume < H.species.blood_volume*H.species.blood_level_fatal /obj/item/weapon/shockpaddles/proc/check_charge(var/charge_amt) return 0 diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 5516ccb0998..32c9d75959a 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -138,7 +138,7 @@ for(var/mob/living/carbon/M in oviewers(4, T)) if(M.get_ear_protection() >= 2) continue - M.sleeping = 0 + M.SetSleeping(0) M.stuttering += 20 M.ear_deaf += 30 M.Weaken(3) diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 47de7ff7dd0..f5c3918fc9a 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -382,7 +382,7 @@ return -/obj/item/device/radio/headset/proc/recalculateChannels(var/setDescription = 0) +/obj/item/device/radio/headset/recalculateChannels(var/setDescription = 0) src.channels = list() src.translate_binary = 0 src.translate_hive = 0 diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 2049d96a7d9..210b93f1b0b 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -37,12 +37,14 @@ var/global/list/default_medbay_channels = list( var/frequency = PUB_FREQ //common chat var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies var/canhear_range = 3 // the range which mobs can hear this radio from + var/loudspeaker = TRUE // Allows borgs to disable canhear_range. var/datum/wires/radio/wires = null var/b_stat = 0 var/broadcasting = 0 var/listening = 1 var/list/channels = list() //see communications.dm for full list. First channel is a "default" for :h var/subspace_transmission = 0 + var/subspace_switchable = FALSE var/adhoc_fallback = FALSE //Falls back to 'radio' mode if subspace not available var/syndie = 0//Holder to see if it's a syndicate encrypted radio var/centComm = 0//Holder to see if it's a CentCom encrypted radio @@ -133,6 +135,8 @@ var/global/list/default_medbay_channels = list( if(!found) testing("A radio [src] at [x],[y],[z] specified bluespace prelink IDs, but the machines with corresponding IDs ([bs_tx_preload_id], [bs_rx_preload_id]) couldn't be found.") +/obj/item/device/radio/proc/recalculateChannels() + return /obj/item/device/radio/attack_self(mob/user as mob) user.set_machine(src) @@ -145,37 +149,48 @@ var/global/list/default_medbay_channels = list( if(b_stat) wires.Interact(user) - return ui_interact(user) + return tgui_interact(user) -/obj/item/device/radio/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/item/device/radio/ui_interact(mob/user, ui_key, datum/nanoui/ui, force_open, datum/nano_ui/master_ui, datum/topic_state/state) + log_runtime(EXCEPTION("Warning: [user] attempted to call ui_interact on radio [src] [type]. This is deprecated. Please update the caller to tgui_interact.")) + +/obj/item/device/radio/Topic(href, href_list) + if(href_list["track"]) + log_runtime(EXCEPTION("Warning: Topic() was improperly called on radio [src] [type], with the track href and \[[href] [json_encode(href_list)]]. Please update the caller to use tgui_act.")) + . = ..() + +/obj/item/device/radio/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Radio", name) + ui.open() + +/obj/item/device/radio/tgui_data(mob/user) var/data[0] - data["mic_status"] = broadcasting - data["speaker"] = listening - data["freq"] = format_frequency(frequency) data["rawfreq"] = num2text(frequency) + data["listening"] = listening + data["broadcasting"] = broadcasting + data["subspace"] = subspace_transmission + data["subspaceSwitchable"] = subspace_switchable + data["loudspeaker"] = loudspeaker - data["mic_cut"] = (wires.IsIndexCut(WIRE_TRANSMIT) || wires.IsIndexCut(WIRE_SIGNAL)) - data["spk_cut"] = (wires.IsIndexCut(WIRE_RECEIVE) || wires.IsIndexCut(WIRE_SIGNAL)) + data["mic_cut"] = (wires.is_cut(WIRE_RADIO_TRANSMIT) || wires.is_cut(WIRE_RADIO_SIGNAL)) + data["spk_cut"] = (wires.is_cut(WIRE_RADIO_RECEIVER) || wires.is_cut(WIRE_RADIO_SIGNAL)) var/list/chanlist = list_channels(user) if(islist(chanlist) && chanlist.len) data["chan_list"] = chanlist - data["chan_list_len"] = chanlist.len + else + data["chan_list"] = null if(syndie) data["useSyndMode"] = 1 - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 430) - ui.set_initial_data(data) - ui.open() + data["minFrequency"] = PUBLIC_LOW_FREQ + data["maxFrequency"] = PUBLIC_HIGH_FREQ -/obj/item/device/radio/CouldUseTopic(var/mob/user) - ..() - if(iscarbon(user)) - playsound(src, "button", 10) + return data /obj/item/device/radio/proc/list_channels(var/mob/user) return list_internal_channels(user) @@ -187,7 +202,7 @@ var/global/list/default_medbay_channels = list( var/chan_stat = channels[ch_name] var/listening = !!(chan_stat & FREQ_LISTENING) != 0 - dat.Add(list(list("chan" = ch_name, "display_name" = ch_name, "secure_channel" = 1, "sec_channel_listen" = !listening, "chan_span" = frequency_span_class(radiochannels[ch_name])))) + dat.Add(list(list("chan" = ch_name, "display_name" = ch_name, "secure_channel" = 1, "sec_channel_listen" = !listening, "freq" = radiochannels[ch_name]))) return dat @@ -195,7 +210,7 @@ var/global/list/default_medbay_channels = list( var/dat[0] for(var/internal_chan in internal_channels) if(has_channel_access(user, internal_chan)) - dat.Add(list(list("chan" = internal_chan, "display_name" = get_frequency_name(text2num(internal_chan)), "chan_span" = frequency_span_class(text2num(internal_chan))))) + dat.Add(list(list("chan" = internal_chan, "display_name" = get_frequency_name(text2num(internal_chan)), "freq" = text2num(internal_chan)))) return dat @@ -215,12 +230,6 @@ var/global/list/default_medbay_channels = list( /mob/observer/dead/has_internal_radio_channel_access(var/list/req_one_accesses) return can_admin_interact() -/obj/item/device/radio/proc/text_wires() - if (b_stat) - return wires.GetInteractWindow() - return - - /obj/item/device/radio/proc/text_sec_channel(var/chan_name, var/chan_stat) var/list = !!(chan_stat&FREQ_LISTENING)!=0 return {" @@ -229,60 +238,71 @@ var/global/list/default_medbay_channels = list( "} /obj/item/device/radio/proc/ToggleBroadcast() - broadcasting = !broadcasting && !(wires.IsIndexCut(WIRE_TRANSMIT) || wires.IsIndexCut(WIRE_SIGNAL)) + broadcasting = !broadcasting && !(wires.is_cut(WIRE_RADIO_TRANSMIT) || wires.is_cut(WIRE_RADIO_SIGNAL)) /obj/item/device/radio/proc/ToggleReception() - listening = !listening && !(wires.IsIndexCut(WIRE_RECEIVE) || wires.IsIndexCut(WIRE_SIGNAL)) + listening = !listening && !(wires.is_cut(WIRE_RADIO_RECEIVER) || wires.is_cut(WIRE_RADIO_SIGNAL)) /obj/item/device/radio/CanUseTopic() if(!on) return STATUS_CLOSE return ..() -/obj/item/device/radio/Topic(href, href_list) +/obj/item/device/radio/tgui_act(action, params) if(..()) return TRUE - usr.set_machine(src) - if (href_list["track"]) - var/mob/target = locate(href_list["track"]) - var/mob/living/silicon/ai/A = locate(href_list["track2"]) - if(A && target) - A.ai_actual_track(target) - . = 1 - - else if (href_list["freq"]) - var/new_frequency = (frequency + text2num(href_list["freq"])) - if ((new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ)) - new_frequency = sanitize_frequency(new_frequency) - set_frequency(new_frequency) - if(hidden_uplink) - if(hidden_uplink.check_trigger(usr, frequency, traitor_frequency)) - usr << browse(null, "window=radio") - . = 1 - else if (href_list["talk"]) - ToggleBroadcast() - . = 1 - else if (href_list["listen"]) - var/chan_name = href_list["ch_name"] - if (!chan_name) + switch(action) + if("setFrequency") + var/new_frequency = (text2num(params["freq"])) + if((new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ)) + new_frequency = sanitize_frequency(new_frequency) + set_frequency(new_frequency) + if(hidden_uplink) + if(hidden_uplink.check_trigger(usr, frequency, traitor_frequency)) + usr << browse(null, "window=radio") + . = TRUE + if("broadcast") + ToggleBroadcast() + . = TRUE + if("listen") ToggleReception() - else - if (channels[chan_name] & FREQ_LISTENING) + . = TRUE + if("channel") + var/chan_name = params["channel"] + if(channels[chan_name] & FREQ_LISTENING) channels[chan_name] &= ~FREQ_LISTENING else channels[chan_name] |= FREQ_LISTENING - . = 1 - else if(href_list["spec_freq"]) - var freq = href_list["spec_freq"] - if(has_channel_access(usr, freq)) - set_frequency(text2num(freq)) - . = 1 - if(href_list["nowindow"]) // here for pAIs, maybe others will want it, idk - return TRUE + . = TRUE + if("specFreq") + var/freq = params["channel"] + if(has_channel_access(usr, freq)) + set_frequency(text2num(freq)) + . = TRUE + if("subspace") + if(subspace_switchable) + subspace_transmission = !subspace_transmission + if(!subspace_transmission) + channels = list() + to_chat(usr, "Subspace Transmission is disabled") + else + recalculateChannels() + to_chat(usr, "Subspace Transmission is enabled") + . = TRUE + if("toggleLoudspeaker") + if(!subspace_switchable) + return + loudspeaker = !loudspeaker - if(.) - SSnanoui.update_uis(src) + if(loudspeaker) + to_chat(usr, "Loadspeaker enabled.") + else + to_chat(usr, "Loadspeaker disabled.") + . = TRUE + + if(. && iscarbon(usr)) + playsound(src, "button", 10) GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) /obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels) //BS12 EDIT @@ -337,7 +357,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) // Uncommenting this. To the above comment: // The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom - if(wires.IsIndexCut(WIRE_TRANSMIT)) // The device has to have all its wires and shit intact + if(wires.is_cut(WIRE_RADIO_TRANSMIT)) // The device has to have all its wires and shit intact return FALSE if(!radio_connection) @@ -541,7 +561,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) // check if this radio can receive on the given frequency, and if so, // what the range is in which mobs will hear the radio // returns: -1 if can't receive, range otherwise - if(wires.IsIndexCut(WIRE_RECEIVE)) + if(wires.is_cut(WIRE_RADIO_RECEIVER)) return -1 if(!listening) return -1 @@ -575,10 +595,9 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) return canhear_range /obj/item/device/radio/proc/send_hear(freq, level) - var/range = receive_range(freq, level) - if(range > -1) - return get_mobs_or_objects_in_view(canhear_range, src) + if(range > -1 && loudspeaker) + return get_mobs_or_objects_in_view(range, src) /obj/item/device/radio/examine(mob/user) @@ -622,11 +641,11 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) /obj/item/device/radio/borg var/mob/living/silicon/robot/myborg = null // Cyborg which owns this radio. Used for power checks var/obj/item/device/encryptionkey/keyslot = null//Borg radios can handle a single encryption key - var/shut_up = 1 icon = 'icons/obj/robot_component.dmi' // Cyborgs radio icons should look like the component. icon_state = "radio" canhear_range = 0 - subspace_transmission = 1 + subspace_transmission = TRUE + subspace_switchable = TRUE /obj/item/device/radio/borg/Destroy() myborg = null @@ -684,7 +703,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) return -/obj/item/device/radio/borg/proc/recalculateChannels() +/obj/item/device/radio/borg/recalculateChannels() src.channels = list() src.syndie = 0 @@ -716,71 +735,6 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer) return -/obj/item/device/radio/borg/Topic(href, href_list) - if(..()) - return TRUE - if (href_list["mode"]) - var/enable_subspace_transmission = text2num(href_list["mode"]) - if(enable_subspace_transmission != subspace_transmission) - subspace_transmission = !subspace_transmission - if(subspace_transmission) - to_chat(usr, "Subspace Transmission is enabled") - else - to_chat(usr, "Subspace Transmission is disabled") - - if(subspace_transmission == 0)//Simple as fuck, clears the channel list to prevent talking/listening over them if subspace transmission is disabled - channels = list() - else - recalculateChannels() - . = 1 - if (href_list["shutup"]) // Toggle loudspeaker mode, AKA everyone around you hearing your radio. - var/do_shut_up = text2num(href_list["shutup"]) - if(do_shut_up != shut_up) - shut_up = !shut_up - if(shut_up) - canhear_range = 0 - to_chat(usr, "Loadspeaker disabled.") - else - canhear_range = 3 - to_chat(usr, "Loadspeaker enabled.") - . = 1 - - if(.) - SSnanoui.update_uis(src) - -/obj/item/device/radio/borg/interact(mob/user as mob) - if(!on) - return - - . = ..() - -/obj/item/device/radio/borg/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - - data["mic_status"] = broadcasting - data["speaker"] = listening - data["freq"] = format_frequency(frequency) - data["rawfreq"] = num2text(frequency) - - var/list/chanlist = list_channels(user) - if(islist(chanlist) && chanlist.len) - data["chan_list"] = chanlist - data["chan_list_len"] = chanlist.len - - if(syndie) - data["useSyndMode"] = 1 - - data["has_loudspeaker"] = 1 - data["loudspeaker"] = !shut_up - data["has_subspace"] = 1 - data["subspace"] = subspace_transmission - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 430) - ui.set_initial_data(data) - ui.open() - /obj/item/device/radio/proc/config(op) if(radio_controller) for (var/ch_name in channels) diff --git a/code/game/objects/items/devices/radio/radiopack.dm b/code/game/objects/items/devices/radio/radiopack.dm index 8f2e849320d..5da91422ae0 100644 --- a/code/game/objects/items/devices/radio/radiopack.dm +++ b/code/game/objects/items/devices/radio/radiopack.dm @@ -128,7 +128,7 @@ //Only care about megabroadcasts or things that are targeted at us if(!(0 in level)) return -1 - if(wires.IsIndexCut(WIRE_RECEIVE)) + if(wires.is_cut(WIRE_RADIO_RECEIVER)) return -1 if(!listening) return -1 diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 06197f202db..c949884c6f0 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -136,10 +136,10 @@ HALOGEN COUNTER - Radcount on mobs for(var/A in C.reagents.reagent_list) var/datum/reagent/R = A if(R.scannable) - reagentdata["[R.id]"] = "\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]
" + reagentdata["[R.id]"] = "\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - Overdose" : ""]
" else unknown++ - unknownreagents["[R.id]"] = "\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]
" + unknownreagents["[R.id]"] = "\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - Overdose" : ""]
" if(reagentdata.len) dat += "Beneficial reagents detected in subject's blood:
" for(var/d in reagentdata) @@ -156,14 +156,14 @@ HALOGEN COUNTER - Radcount on mobs var/stomachreagentdata[0] var/stomachunknownreagents[0] for(var/B in C.ingested.reagent_list) - var/datum/reagent/T = B - if(T.scannable) - stomachreagentdata["[T.id]"] = "\t[round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]
" + var/datum/reagent/R = B + if(R.scannable) + stomachreagentdata["[R.id]"] = "\t[round(C.ingested.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - Overdose" : ""]
" if (advscan == 0 || showadvscan == 0) - dat += "[T.name] found in subject's stomach.
" + dat += "[R.name] found in subject's stomach.
" else ++unknown - stomachunknownreagents["[T.id]"] = "\t[round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]
" + stomachunknownreagents["[R.id]"] = "\t[round(C.ingested.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - Overdose" : ""]
" if(advscan >= 1 && showadvscan == 1) dat += "Beneficial reagents detected in subject's stomach:
" for(var/d in stomachreagentdata) @@ -180,14 +180,14 @@ HALOGEN COUNTER - Radcount on mobs var/touchreagentdata[0] var/touchunknownreagents[0] for(var/B in C.touching.reagent_list) - var/datum/reagent/T = B - if(T.scannable) - touchreagentdata["[T.id]"] = "\t[round(C.touching.get_reagent_amount(T.id), 1)]u [T.name]
" + var/datum/reagent/R = B + if(R.scannable) + touchreagentdata["[R.id]"] = "\t[round(C.touching.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.can_overdose_touch && R.volume > R.overdose) ? " - Overdose" : ""]
" if (advscan == 0 || showadvscan == 0) - dat += "[T.name] found in subject's dermis.
" + dat += "[R.name] found in subject's dermis.
" else ++unknown - touchunknownreagents["[T.id]"] = "\t[round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]
" + touchunknownreagents["[R.id]"] = "\t[round(C.ingested.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.can_overdose_touch && R.volume > R.overdose) ? " - Overdose" : ""]
" if(advscan >= 1 && showadvscan == 1) dat += "Beneficial reagents detected in subject's dermis:
" for(var/d in touchreagentdata) @@ -272,9 +272,11 @@ HALOGEN COUNTER - Radcount on mobs var/blood_volume = H.vessel.get_reagent_amount("blood") var/blood_percent = round((blood_volume / H.species.blood_volume)*100) var/blood_type = H.dna.b_type - if(blood_percent <= BLOOD_VOLUME_BAD) + if(blood_volume <= H.species.blood_volume*H.species.blood_level_danger) dat += "Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl. Type: [blood_type]
" - else if(blood_percent <= BLOOD_VOLUME_SAFE) + else if(blood_volume <= H.species.blood_volume*H.species.blood_level_warning) + dat += "Warning: Blood Level VERY LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]
" + else if(blood_volume <= H.species.blood_volume*H.species.blood_level_safe) dat += "Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]
" else dat += "Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]
" diff --git a/code/game/objects/items/devices/translocator_vr.dm b/code/game/objects/items/devices/translocator_vr.dm index 6778bfae7a6..3e2d5dc5c7f 100644 --- a/code/game/objects/items/devices/translocator_vr.dm +++ b/code/game/objects/items/devices/translocator_vr.dm @@ -66,21 +66,21 @@ /obj/item/device/perfect_tele/proc/rebuild_radial_images() radial_images.Cut() - + var/index = 1 for(var/bcn in beacons) //Grumble var/image/I = image(icon = 'icons/mob/radial_vr.dmi', icon_state = "tl_[index]") - + var/obj/item/device/perfect_tele_beacon/beacon = beacons[bcn] if(destination == beacon) I.overlays += radial_seton else I.overlays += radial_set - + radial_images[bcn] = I - + index++ - + if(beacons_left) var/image/I = image(icon = 'icons/mob/radial_vr.dmi', icon_state = "tl_[index]") I.overlays += radial_plus @@ -124,12 +124,12 @@ and tele-vore. Make sure you carefully examine someone's OOC prefs before teleporting them if you are \ going to use this device for ERP purposes. This device records all warnings given and teleport events for \ admin review in case of pref-breaking, so just don't do it.","OOC WARNING") - + var/choice = show_radial_menu(user, src, radial_images, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE) - + if(!choice) return - + else if(choice == "New Beacon") if(beacons_left <= 0) to_chat(user, "The translocator can't support any more beacons!") @@ -289,6 +289,16 @@ if(!teleport_checks(target,user)) return //The checks proc can send them a message if it wants. + if(istype(target, /mob/living)) + var/mob/living/L = target + if(!L.stat) + if(L != user) + if(L.a_intent != I_HELP || L.has_AI()) + to_chat(user, "[L] is resisting your attempt to teleport them with \the [src].") + to_chat(L, " [user] is trying to teleport you with \the [src]!") + if(!do_after(user, 30, L)) + return + //Bzzt. ready = 0 power_source.use(charge_cost) @@ -326,7 +336,7 @@ var/televored = FALSE if(isbelly(real_dest)) var/obj/belly/B = real_dest - if(!target.can_be_drop_prey && B.owner != user) + if(!(target.can_be_drop_prey) && B.owner != user) to_chat(target,"\The [src] narrowly avoids teleporting you right into \a [lowertext(real_dest.name)]!") real_dest = dT //Nevermind! else @@ -492,7 +502,7 @@ GLOBAL_LIST_BOILERPLATE(premade_tele_beacons, /obj/item/device/perfect_tele_beac battery_lock = 1 unacidable = 1 failure_chance = 0 //Percent - + var/phase_power = 75 var/recharging = 0 diff --git a/code/game/objects/items/glassjar.dm b/code/game/objects/items/glassjar.dm index 60fd8b19eb9..e55285e9da3 100644 --- a/code/game/objects/items/glassjar.dm +++ b/code/game/objects/items/glassjar.dm @@ -1,3 +1,9 @@ + +#define JAR_NOTHING 0 +#define JAR_MONEY 1 +#define JAR_ANIMAL 2 +#define JAR_SPIDER 3 + /obj/item/glass_jar name = "glass jar" desc = "A small empty jar." @@ -27,7 +33,7 @@ var/mob/L = A user.visible_message("[user] scoops [L] into \the [src].", "You scoop [L] into \the [src].") L.loc = src - contains = 2 + contains = JAR_ANIMAL update_icon() return else if(istype(A, /obj/effect/spider/spiderling)) @@ -35,40 +41,40 @@ user.visible_message("[user] scoops [S] into \the [src].", "You scoop [S] into \the [src].") S.loc = src STOP_PROCESSING(SSobj, S) // No growing inside jars - contains = 3 + contains = JAR_SPIDER update_icon() return /obj/item/glass_jar/attack_self(var/mob/user) switch(contains) - if(1) + if(JAR_MONEY) for(var/obj/O in src) O.loc = user.loc to_chat(user, "You take money out of \the [src].") - contains = 0 + contains = JAR_NOTHING update_icon() return - if(2) + if(JAR_ANIMAL) for(var/mob/M in src) M.loc = user.loc user.visible_message("[user] releases [M] from \the [src].", "You release [M] from \the [src].") - contains = 0 + contains = JAR_NOTHING update_icon() return - if(3) + if(JAR_SPIDER) for(var/obj/effect/spider/spiderling/S in src) S.loc = user.loc user.visible_message("[user] releases [S] from \the [src].", "You release [S] from \the [src].") START_PROCESSING(SSobj, S) // They can grow after being let out though - contains = 0 + contains = JAR_NOTHING update_icon() return /obj/item/glass_jar/attackby(var/obj/item/W, var/mob/user) if(istype(W, /obj/item/weapon/spacecash)) - if(contains == 0) - contains = 1 - if(contains != 1) + if(contains == JAR_NOTHING) + contains = JAR_MONEY + if(contains != JAR_MONEY) return var/obj/item/weapon/spacecash/S = W user.visible_message("[user] puts [S.worth] [S.worth > 1 ? "thalers" : "thaler"] into \the [src].") @@ -80,10 +86,10 @@ underlays.Cut() overlays.Cut() switch(contains) - if(0) + if(JAR_NOTHING) name = initial(name) desc = initial(desc) - if(1) + if(JAR_MONEY) name = "tip jar" desc = "A small jar with money inside." for(var/obj/item/weapon/spacecash/S in src) @@ -92,7 +98,7 @@ money.pixel_y = rand(-6, 6) money.transform *= 0.6 underlays += money - if(2) + if(JAR_ANIMAL) for(var/mob/M in src) var/image/victim = image(M.icon, M.icon_state) victim.pixel_y = 6 @@ -105,10 +111,109 @@ underlays += victim name = "glass jar with [M]" desc = "A small jar with [M] inside." - if(3) + if(JAR_SPIDER) for(var/obj/effect/spider/spiderling/S in src) var/image/victim = image(S.icon, S.icon_state) underlays += victim name = "glass jar with [S]" desc = "A small jar with [S] inside." - return \ No newline at end of file + return + +/obj/item/glass_jar/fish + name = "glass tank" + desc = "A large glass tank." + + var/filled = FALSE + + w_class = ITEMSIZE_NORMAL + + accept_mobs = list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/mouse, /mob/living/simple_mob/animal/sif/leech, /mob/living/simple_mob/animal/sif/frostfly, /mob/living/simple_mob/animal/sif/glitterfly, /mob/living/simple_mob/animal/passive/fish) + +/obj/item/glass_jar/fish/plastic + name = "plastic tank" + desc = "A large plastic tank." + matter = list("plastic" = 4000) + +/obj/item/glass_jar/fish/update_icon() // Also updates name and desc + underlays.Cut() + overlays.Cut() + + if(filled) + underlays += image(icon, "[icon_state]_water") + + switch(contains) + if(JAR_NOTHING) + name = initial(name) + desc = initial(desc) + if(JAR_MONEY) + name = "tip tank" + desc = "A large [name] with money inside." + for(var/obj/item/weapon/spacecash/S in src) + var/image/money = image(S.icon, S.icon_state) + money.pixel_x = rand(-2, 3) + money.pixel_y = rand(-6, 6) + money.transform *= 0.6 + underlays += money + if(JAR_ANIMAL) + for(var/mob/M in src) + var/image/victim = image(M.icon, M.icon_state) + var/initial_x_scale = M.icon_scale_x + var/initial_y_scale = M.icon_scale_y + M.adjust_scale(0.7) + victim.appearance = M.appearance + M.adjust_scale(initial_x_scale, initial_y_scale) + victim.pixel_y = 4 + underlays += victim + name = "[name] with [M]" + desc = "A large [name] with [M] inside." + if(JAR_SPIDER) + for(var/obj/effect/spider/spiderling/S in src) + var/image/victim = image(S.icon, S.icon_state) + underlays += victim + name = "[name] with [S]" + desc = "A large tank with [S] inside." + + if(filled) + desc = "[desc] It contains water." + + return + +/obj/item/glass_jar/fish/afterattack(var/atom/A, var/mob/user, var/proximity) + if(!filled) + if(istype(A, /obj/structure/sink) || istype(A, /turf/simulated/floor/water)) + if(contains && user.a_intent == "help") + to_chat(user, "That probably isn't the best idea.") + return + + to_chat(user, "You fill \the [src] with water!") + filled = TRUE + update_icon() + return + + return ..() + +/obj/item/glass_jar/fish/attack_self(var/mob/user) + if(filled) + if(contains == JAR_ANIMAL) + if(user.a_intent == "help") + to_chat(user, "Maybe you shouldn't empty the water...") + return + + else + filled = FALSE + user.visible_message("[user] dumps out \the [src]'s water!") + update_icon() + return + + else + user.visible_message("[user] dumps \the [src]'s water.") + filled = FALSE + update_icon() + return + + return ..() + +#undef JAR_NOTHING +#undef JAR_MONEY +#undef JAR_ANIMAL +#undef JAR_SPIDER diff --git a/code/game/objects/items/pizza_voucher_vr.dm b/code/game/objects/items/pizza_voucher_vr.dm index e2efd9c6b67..1d48bc9cda7 100644 --- a/code/game/objects/items/pizza_voucher_vr.dm +++ b/code/game/objects/items/pizza_voucher_vr.dm @@ -25,7 +25,9 @@ user.visible_message("[user] presses a button on [src]!") desc = desc + " This one seems to be used-up." spent = TRUE - user.visible_message("A small bluespace rift opens just above your head and spits out a pizza box!") + user.visible_message("A small bluespace rift opens just above [user]'s head and spits out a pizza box!", + "A small bluespace rift opens just above your head and spits out a pizza box!", + "You hear a fwoosh followed by a thump.") if(special_delivery) command_announcement.Announce("SPECIAL DELIVERY PIZZA ORDER #[rand(1000,9999)]-[rand(100,999)] HAS BEEN RECIEVED. SHIPMENT DISPATCHED VIA EXTRA-POWERFUL BALLISTIC LAUNCHERS FOR IMMEDIATE DELIVERY! THANK YOU AND ENJOY YOUR PIZZA!", "WE ALWAYS DELIVER!") new /obj/effect/falling_effect/pizza_delivery/special(user.loc) @@ -59,4 +61,4 @@ return INITIALIZE_HINT_LATELOAD /obj/effect/falling_effect/pizza_delivery/special - crushing = TRUE \ No newline at end of file + crushing = TRUE diff --git a/code/game/objects/items/robot/robot_upgrades_vr.dm b/code/game/objects/items/robot/robot_upgrades_vr.dm index 13f09a980d6..ad2556f8101 100644 --- a/code/game/objects/items/robot/robot_upgrades_vr.dm +++ b/code/game/objects/items/robot/robot_upgrades_vr.dm @@ -6,7 +6,8 @@ R.add_language(LANGUAGE_ECUREUILIAN, 1) R.add_language(LANGUAGE_DAEMON, 1) R.add_language(LANGUAGE_ENOCHIAN, 1) - R.add_language(LANGUAGE_SLAVIC, 1) + R.add_language(LANGUAGE_SLAVIC, 1) + R.add_language(LANGUAGE_DRUDAKAR, 1) return 1 else return 0 @@ -27,4 +28,40 @@ return 0 R.verbs += /mob/living/proc/set_size - return 1 \ No newline at end of file + return 1 + +/obj/item/borg/upgrade/bellysizeupgrade + name = "robotic Hound process capacity upgrade Module" + desc = "Used to upgrade a hound belly capacity. This only affects total volume and such, you won't be able to support more than one patient. Usable once." + icon_state = "cyborg_upgrade2" + item_state = "cyborg_upgrade" + require_module = 1 + +/obj/item/borg/upgrade/bellysizeupgrade/action(var/mob/living/silicon/robot/R) + if(..()) return 0 + + if(!R.module || R.dogborg == FALSE)//can work + to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") + to_chat(usr, "There's no mounting point for the module! Try upgrading another model.") + return 0 + + var/obj/item/device/dogborg/sleeper/T = locate() in R.module + if(!T) + T = locate() in R.module.contents + if(!T) + T = locate() in R.module.modules + if(!T) + to_chat(usr, "This robot has had its processor removed!") + return 0 + + if(T.upgraded_capacity)// == TRUE + to_chat(R, "Maximum capacity achieved for this hardpoint!") + to_chat(usr, "There's no room for another capacity upgrade!") + return 0 + else + var/X = T.max_item_count*2 + T.max_item_count = X //I couldn't do T = maxitem*2 for some reason. + to_chat(R, "Internal capacity doubled.") + to_chat(usr, "Internal capacity doubled.") + T.upgraded_capacity = TRUE + return 1 diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index e06c9dbc007..7873f78a60f 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -425,6 +425,15 @@ return ..() +/obj/random/mech_toy + name = "Random Mech Toy" + desc = "This is a random mech toy." + icon = 'icons/obj/toy.dmi' + icon_state = "ripleytoy" + +/obj/random/mech_toy/item_to_spawn() + return pick(typesof(/obj/item/toy/prize)) + /obj/item/toy/prize/ripley name = "toy ripley" desc = "Mini-Mecha action figure! Collect them all! 1/11." diff --git a/code/game/objects/items/toys_vr.dm b/code/game/objects/items/toys_vr.dm index e609bbc5fa5..91c3ed7e06f 100644 --- a/code/game/objects/items/toys_vr.dm +++ b/code/game/objects/items/toys_vr.dm @@ -14,6 +14,14 @@ drop_sound = 'sound/voice/weh.ogg' attack_verb = list("raided", "kobolded", "weh'd") +/obj/item/toy/plushie/lizardplushie/resh + name = "security unathi plushie" + desc = "An adorable stuffed toy that resembles an unathi wearing a head of security uniform. Perfect example of a monitor lizard." + icon = 'icons/obj/toy_vr.dmi' + icon_state = "marketable_resh" + pokephrase = "Halt! Sssecurity!" //"Butts!" would be too obvious + attack_verb = list("valided", "justiced", "batoned") + /obj/item/toy/plushie/slimeplushie name = "slime plushie" desc = "An adorable stuffed toy that resembles a slime. It is practically just a hacky sack." diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index b72a73f34eb..aa4b02b2840 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -7,6 +7,20 @@ w_class = ITEMSIZE_SMALL desc = "This is rubbish." drop_sound = 'sound/items/drop/wrapper.ogg' + var/age = 0 + +/obj/item/trash/New(var/newloc, var/_age) + ..(newloc) + if(!isnull(_age)) + age = _age + +/obj/item/trash/Initialize() + SSpersistence.track_value(src, /datum/persistent/filth/trash) + . = ..() + +/obj/item/trash/Destroy() + SSpersistence.forget_value(src, /datum/persistent/filth/trash) + . = ..() /obj/item/trash/raisins name = "\improper 4no raisins" @@ -91,5 +105,22 @@ name = "bread tube" icon_state = "tastybread" +// Aurora Food Port +/obj/item/trash/brownies + name = "brownie tray" + icon_state = "brownies" + +/obj/item/trash/snacktray + name = "snacktray" + icon_state = "snacktray" + +/obj/item/trash/dipbowl + name = "dip bowl" + icon_state = "dipbowl" + +/obj/item/trash/chipbasket + name = "empty basket" + icon_state = "chipbasket_empty" + /obj/item/trash/attack(mob/M as mob, mob/living/user as mob) return diff --git a/code/game/objects/items/weapons/RPD_vr.dm b/code/game/objects/items/weapons/RPD_vr.dm index b40f28701fb..b3b35075864 100644 --- a/code/game/objects/items/weapons/RPD_vr.dm +++ b/code/game/objects/items/weapons/RPD_vr.dm @@ -1,8 +1,11 @@ -#define PAINT_MODE -2 -#define EATING_MODE -1 -#define ATMOS_MODE 0 -#define DISPOSALS_MODE 1 -#define TRANSIT_MODE 2 +#define ATMOS_CATEGORY 0 +#define DISPOSALS_CATEGORY 1 +#define TRANSIT_CATEGORY 2 + +#define BUILD_MODE (1<<0) +#define WRENCH_MODE (1<<1) +#define DESTROY_MODE (1<<2) +#define PAINT_MODE (1<<3) /obj/item/weapon/pipe_dispenser name = "Rapid Piping Device (RPD)" @@ -22,18 +25,16 @@ w_class = ITEMSIZE_NORMAL matter = list(MAT_STEEL = 50000, MAT_GLASS = 25000) var/datum/effect/effect/system/spark_spread/spark_system - var/mode = ATMOS_MODE var/p_dir = NORTH // Next pipe will be built with this dir var/p_flipped = FALSE // If the next pipe should be built flipped var/paint_color = "grey" // Pipe color index for next pipe painted/built. - var/screen = ATMOS_MODE // Starts on the atmos tab. + var/category = ATMOS_CATEGORY var/piping_layer = PIPING_LAYER_DEFAULT - var/wrench_mode = FALSE var/obj/item/weapon/tool/wrench/tool var/datum/pipe_recipe/recipe // pipe recipie selected for display/construction var/static/datum/pipe_recipe/first_atmos var/static/datum/pipe_recipe/first_disposal - var/static/datum/asset/iconsheet/pipes/icon_assets + var/mode = BUILD_MODE | DESTROY_MODE | WRENCH_MODE var/static/list/pipe_layers = list( "Regular" = PIPING_LAYER_REGULAR, "Supply" = PIPING_LAYER_SUPPLY, @@ -51,10 +52,10 @@ /obj/item/weapon/pipe_dispenser/proc/SetupPipes() if(!first_atmos) - first_atmos = atmos_pipe_recipes[atmos_pipe_recipes[1]][1] + first_atmos = GLOB.atmos_pipe_recipes[GLOB.atmos_pipe_recipes[1]][1] recipe = first_atmos if(!first_disposal) - first_disposal = disposal_pipe_recipes[disposal_pipe_recipes[1]][1] + first_disposal = GLOB.disposal_pipe_recipes[GLOB.disposal_pipe_recipes[1]][1] /obj/item/weapon/pipe_dispenser/Destroy() qdel_null(spark_system) @@ -69,170 +70,97 @@ return(BRUTELOSS) /obj/item/weapon/pipe_dispenser/attack_self(mob/user) - src.interact(user) + tgui_interact(user) -// TODO - Wouldn't it be nice to have nanoui? -/obj/item/weapon/pipe_dispenser/interact(mob/user) +/obj/item/weapon/pipe_dispenser/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/pipes), + ) + +/obj/item/weapon/pipe_dispenser/tgui_interact(mob/user, datum/tgui/ui) SetupPipes() - if(!icon_assets) - icon_assets = get_asset_datum(/datum/asset/iconsheet/pipes) - icon_assets.send(user) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RapidPipeDispenser", name) + ui.open() - var/list/lines = list() - if(mode >= ATMOS_MODE) - lines += "

Direction:

" - switch(recipe.dirtype) +/obj/item/weapon/pipe_dispenser/tgui_data(mob/user) + var/list/data = list( + "category" = category, + "piping_layer" = piping_layer, + "pipe_layers" = pipe_layers, + "preview_rows" = recipe.get_preview(p_dir), + "categories" = list(), + "selected_color" = paint_color, + "paint_colors" = pipe_colors, + "mode" = mode + ) - if(PIPE_STRAIGHT) // Straight, N-S, W-E - lines += render_dir_img(recipe.icon_state,user,NORTH,"Vertical","↕") - lines += render_dir_img(recipe.icon_state,user,EAST,"Horizontal","↔") + var/list/recipes + switch(category) + if(ATMOS_CATEGORY) + recipes = GLOB.atmos_pipe_recipes + if(DISPOSALS_CATEGORY) + recipes = GLOB.disposal_pipe_recipes + // if(TRANSIT_CATEGORY) + // recipes = transit_tube_recipes + for(var/c in recipes) + var/list/cat = recipes[c] + var/list/r = list() + for(var/i in 1 to cat.len) + var/datum/pipe_recipe/info = cat[i] + r += list(list("pipe_name" = info.name, "pipe_index" = i, "selected" = (info == recipe))) + data["categories"] += list(list("cat_name" = c, "recipes" = r)) - if(PIPE_BENDABLE) // Bent, N-W, N-E etc - lines += render_dir_img(recipe.icon_state,user,NORTH,"Vertical","↕") - lines += render_dir_img(recipe.icon_state,user,EAST,"Horizontal","↔") - lines += "
" - lines += render_dir_img(recipe.icon_state,user,NORTHWEST,"West to North","╝") - lines += render_dir_img(recipe.icon_state,user,NORTHEAST,"North to East","╚") - lines += render_dir_img(recipe.icon_state,user,SOUTHWEST,"South to West","╗") - lines += render_dir_img(recipe.icon_state,user,SOUTHEAST,"East to South","╔") + return data - if(PIPE_TRINARY) // Manifold - lines += render_dir_img(recipe.icon_state,user,NORTH,"West South East","╦") - lines += render_dir_img(recipe.icon_state,user,EAST,"North West South","╣") - lines += render_dir_img(recipe.icon_state,user,SOUTH,"East North West","╩") - lines += render_dir_img(recipe.icon_state,user,WEST,"South East North","╠") - - if(PIPE_TRIN_M) // Mirrored ones - //each mirror icon is 45 anticlockwise from it's real direction - lines += render_dir_img(recipe.icon_state,user,NORTH,"West South East","╦") - lines += render_dir_img(recipe.icon_state,user,EAST,"North West South","╣") - lines += render_dir_img(recipe.icon_state,user,SOUTH,"East North West","╩") - lines += render_dir_img(recipe.icon_state,user,WEST,"South East North","╠") - lines += "
" - lines += render_dir_img(recipe.icon_state_m,user,SOUTH,"West South East","╦", 1) - lines += render_dir_img(recipe.icon_state_m,user,WEST,"South East North","╠", 1) - lines += render_dir_img(recipe.icon_state_m,user,NORTH,"East North West","╩", 1) - lines += render_dir_img(recipe.icon_state_m,user,EAST,"North West South","╣", 1) - - if(PIPE_DIRECTIONAL) // Stuff with four directions - includes pumps etc. - lines += render_dir_img(recipe.icon_state,user,NORTH,"North","↑") - lines += render_dir_img(recipe.icon_state,user,EAST,"East","→") - lines += render_dir_img(recipe.icon_state,user,SOUTH,"South","↓") - lines += render_dir_img(recipe.icon_state,user,WEST,"West","←") - - if(PIPE_ONEDIR) // Single icon_state (eg 4-way manifolds) - lines += render_dir_img(recipe.icon_state,user,SOUTH,"Pipe","↕") - lines += "
" - - if(mode == ATMOS_MODE || mode == PAINT_MODE) - lines += "

Color:

" - var/i = 0 - for(var/c in pipe_colors) - ++i - lines += "[c]" - if(i == 4) - lines += "
" - i = 0 - lines += "
" - - lines += "

Mode:

" - lines += "Lay Pipes" - lines += "Eat Pipes" - lines += "Paint Pipes" - lines += "
" - - lines += "

Category:

" - lines += "Atmospherics" - lines += "Disposals" - //lines += "Transit Tube" - lines += "
Wrench Mode" - lines += "
" - - if(screen == ATMOS_MODE) - for(var/category in atmos_pipe_recipes) - lines += "

[category]:

" - - if(category == "Pipes") - lines += "
" - for(var/pipename in pipe_layers) - var/pipelayer = pipe_layers[pipename] - lines += "[pipename] " - lines += "
" - lines += "
" - for(var/i in 1 to atmos_pipe_recipes[category].len) - var/datum/pipe_recipe/PI = atmos_pipe_recipes[category][i] - lines += "
" - lines += "[PI.name]" - lines += "
" - lines += "
" - else if(screen == DISPOSALS_MODE) - for(var/category in disposal_pipe_recipes) - lines += "

[category]:

" - for(var/i in 1 to disposal_pipe_recipes[category].len) - var/datum/pipe_recipe/PI = disposal_pipe_recipes[category][i] - lines += "
" - lines += "[PI.name]" - lines += "
" - lines += "
" - - var/dat = lines.Join() - var/datum/browser/popup = new(user, "rpd", name, 300, 800, src) - popup.set_content("[dat]") - popup.add_head_content(icon_assets.css_tag()) - popup.open() - -/obj/item/weapon/pipe_dispenser/Topic(href, href_list, state = global.inventory_state) +/obj/item/weapon/pipe_dispenser/tgui_act(action, params) SetupPipes() if(..()) - return 1 + return TRUE if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) - return 1 - var/playeffect = TRUE // Do we spark the device - var/anyclicked = FALSE // Tells us if we need to refresh the window. - if(href_list["paint_color"]) - paint_color = href_list["paint_color"] - playeffect = FALSE - anyclicked = TRUE - if(href_list["mode"]) - mode = text2num(href_list["mode"]) - anyclicked = TRUE - if(href_list["screen"]) - if(mode == screen) - mode = text2num(href_list["screen"]) - screen = text2num(href_list["screen"]) - switch(screen) - if(DISPOSALS_MODE) - recipe = first_disposal - if(ATMOS_MODE) - recipe = first_atmos - p_dir = NORTH - playeffect = FALSE - anyclicked = TRUE - if(href_list["piping_layer"]) - piping_layer = text2num(href_list["piping_layer"]) - playeffect = FALSE - anyclicked = TRUE - if(href_list["pipe_type"]) - recipe = all_pipe_recipes[href_list["category"]][text2num(href_list["pipe_type"])] - if(recipe.dirtype == PIPE_ONEDIR) // One hell of a hack for the fact that the image previews for the onedir types only show on the south, but the default pipe type is north. - p_dir = SOUTH // Did I fuck this up? Maybe. Or maybe it's just the icon files not being ready for an RPD. - else // If going to try and fix this hack, be aware the pipe dispensers might rely on pipes defaulting south instead of north. + return TRUE + var/playeffect = TRUE + switch(action) + if("color") + paint_color = params["paint_color"] + if("category") + category = text2num(params["category"]) + switch(category) + if(DISPOSALS_CATEGORY) + recipe = first_disposal + if(ATMOS_CATEGORY) + recipe = first_atmos + // if(TRANSIT_CATEGORY) + // recipe = first_transit p_dir = NORTH - p_flipped = FALSE - anyclicked = TRUE - if(href_list["dir"]) - p_dir = text2dir(href_list["dir"]) - p_flipped = text2num(href_list["flipped"]) - playeffect = FALSE - anyclicked = TRUE - if(href_list["switch_wrench"]) - wrench_mode = text2num(href_list["wrench_mode"]) - anyclicked = TRUE - if(anyclicked) - if(playeffect) - spark_system.start() - playsound(src, 'sound/effects/pop.ogg', 50, 0) - src.interact(usr) + playeffect = FALSE + if("piping_layer") + piping_layer = text2num(params["piping_layer"]) + playeffect = FALSE + // if("ducting_layer") + // ducting_layer = text2num(params["ducting_layer"]) + // playeffect = FALSE + if("pipe_type") + var/static/list/recipes + if(!recipes) + recipes = GLOB.disposal_pipe_recipes + GLOB.atmos_pipe_recipes + recipe = recipes[params["category"]][text2num(params["pipe_type"])] + p_dir = NORTH + if("setdir") + p_dir = text2dir(params["dir"]) + p_flipped = text2num(params["flipped"]) + playeffect = FALSE + if("mode") + var/n = text2num(params["mode"]) + if(mode & n) + mode &= ~n + else + mode |= n + if(playeffect) + spark_system.start() + playsound(get_turf(src), 'sound/effects/pop.ogg', 50, FALSE) + return TRUE /obj/item/weapon/pipe_dispenser/afterattack(atom/A, mob/user as mob, proximity) if(!user.IsAdvancedToolUser() || istype(A, /turf/space/transit) || !proximity) @@ -249,88 +177,89 @@ make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe)) var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist)) - . = FALSE - switch(mode) //if we've gotten this var, the target is valid - if(PAINT_MODE) //Paint pipes - if(!istype(A, /obj/machinery/atmospherics/pipe)) - return ..() + var/can_destroy_pipe = istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct) + + . = TRUE + if((mode & DESTROY_MODE) && can_destroy_pipe) + to_chat(user, "You start destroying a pipe...") + playsound(src, 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 2, target = A)) + activate() + animate_deletion(A) + return + + if((mode & PAINT_MODE)) //Paint pipes + if(istype(A, /obj/machinery/atmospherics/pipe)) var/obj/machinery/atmospherics/pipe/P = A playsound(src, 'sound/machines/click.ogg', 50, 1) P.change_color(pipe_colors[paint_color]) user.visible_message("[user] paints \the [P] [paint_color].", "You paint \the [P] [paint_color].") return - if(EATING_MODE) //Eating pipes - if(!(istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct))) - return ..() - to_chat(user, "You start destroying a pipe...") - playsound(src, 'sound/machines/click.ogg', 50, 1) - if(do_after(user, 2, target = A)) - activate() - animate_deletion(A) + if(mode & BUILD_MODE) //Making pipes + switch(category) + if(ATMOS_CATEGORY) + if(!can_make_pipe) + return ..() + playsound(src, 'sound/machines/click.ogg', 50, 1) + if(istype(recipe, /datum/pipe_recipe/meter)) + to_chat(user, "You start building a meter...") + if(do_after(user, 2, target = A)) + activate() + var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A)) + PM.setAttachLayer(queued_piping_layer) + if(mode & WRENCH_MODE) + do_wrench(PM, user) + else if(istype(recipe, /datum/pipe_recipe/pipe)) + var/datum/pipe_recipe/pipe/R = recipe + to_chat(user, "You start building a pipe...") + if(do_after(user, 2, target = A)) + activate() + var/obj/machinery/atmospherics/path = R.pipe_type + var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe + var/obj/item/pipe/P = new pipe_item_type(get_turf(A), path, queued_p_dir) - if(ATMOS_MODE) //Making pipes - if(!can_make_pipe) - return ..() - playsound(src, 'sound/machines/click.ogg', 50, 1) - if (istype(recipe, /datum/pipe_recipe/meter)) - to_chat(user, "You start building a meter...") - if(do_after(user, 2, target = A)) - activate() - var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A)) - PM.setAttachLayer(queued_piping_layer) - if(wrench_mode) - do_wrench(PM, user) - else if(istype(recipe, /datum/pipe_recipe/pipe)) - var/datum/pipe_recipe/pipe/R = recipe - to_chat(user, "You start building a pipe...") - if(do_after(user, 2, target = A)) - activate() - var/obj/machinery/atmospherics/path = R.pipe_type - var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe - var/obj/item/pipe/P = new pipe_item_type(get_turf(A), path, queued_p_dir) + P.update() + P.add_fingerprint(usr) + if(R.paintable) + P.color = pipe_colors[paint_color] + P.setPipingLayer(queued_piping_layer) + if(queued_p_flipped) + P.do_a_flip() + if(mode & WRENCH_MODE) + do_wrench(P, user) + else + build_effect(P) - P.update() - P.add_fingerprint(usr) - if (R.paintable) - P.color = pipe_colors[paint_color] - P.setPipingLayer(queued_piping_layer) - if(queued_p_flipped) - P.do_a_flip() - if(wrench_mode) - do_wrench(P, user) - else - build_effect(P) - - if(DISPOSALS_MODE) //Making disposals pipes - var/datum/pipe_recipe/disposal/R = recipe - if(!istype(R) || !can_make_pipe) - return ..() - A = get_turf(A) - if(istype(A, /turf/unsimulated)) - to_chat(user, "[src]'s error light flickers; there's something in the way!") - return - to_chat(user, "You start building a disposals pipe...") - playsound(src, 'sound/machines/click.ogg', 50, 1) - if(do_after(user, 4, target = A)) - var/obj/structure/disposalconstruct/C = new(A, R.pipe_type, queued_p_dir, queued_p_flipped, R.subtype) - - if(!C.can_place()) - to_chat(user, "There's not enough room to build that here!") - qdel(C) + if(DISPOSALS_CATEGORY) //Making disposals pipes + var/datum/pipe_recipe/disposal/R = recipe + if(!istype(R) || !can_make_pipe) + return ..() + A = get_turf(A) + if(istype(A, /turf/unsimulated)) + to_chat(user, "[src]'s error light flickers; there's something in the way!") return + to_chat(user, "You start building a disposals pipe...") + playsound(src, 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 4, target = A)) + var/obj/structure/disposalconstruct/C = new(A, R.pipe_type, queued_p_dir, queued_p_flipped, R.subtype) - activate() + if(!C.can_place()) + to_chat(user, "There's not enough room to build that here!") + qdel(C) + return - C.add_fingerprint(usr) - C.update_icon() - if(wrench_mode) - do_wrench(C, user) - else - build_effect(C) + activate() - else - return ..() + C.add_fingerprint(usr) + C.update_icon() + if(mode & WRENCH_MODE) + do_wrench(C, user) + else + build_effect(C) + + else + return ..() /obj/item/weapon/pipe_dispenser/proc/build_effect(var/obj/P, var/time = 1.5) set waitfor = FALSE @@ -359,19 +288,11 @@ if(!resolved && tool && target) tool.afterattack(target,user,1) -/obj/item/weapon/pipe_dispenser/proc/render_dir_img(icon_state, user, _dir, title, noimg, flipped = FALSE) - var/dirtext = dir2text(_dir) - var/attrs = " style=\"height:34px;width:34px;display:inline-block\"" - if(_dir == p_dir && flipped == p_flipped) - attrs += " class=\"linkOn\"" - if(icon_state) - var/img_tag = icon_assets.icon_tag(icon_state, _dir) - return "[img_tag]" - else - return "[noimg]" +#undef ATMOS_CATEGORY +#undef DISPOSALS_CATEGORY +#undef TRANSIT_CATEGORY - -#undef PAINT_MODE -#undef EATING_MODE -#undef ATMOS_MODE -#undef DISPOSALS_MODE +#undef BUILD_MODE +#undef WRENCH_MODE +#undef DESTROY_MODE +#undef PAINT_MODE \ No newline at end of file diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 3577ea0a554..1bd2a4eac8d 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -150,7 +150,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/smokable/examine(mob/user) . = ..() - + if(!is_pipe) var/smoke_percent = round((smoketime / max_smoketime) * 100) switch(smoke_percent) @@ -283,7 +283,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM w_class = ITEMSIZE_TINY slot_flags = SLOT_EARS | SLOT_MASK attack_verb = list("burnt", "singed") - type_butt = /obj/item/weapon/cigbutt + type_butt = /obj/item/trash/cigbutt chem_volume = 15 max_smoketime = 300 smoketime = 300 @@ -341,7 +341,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM name = "premium cigar" desc = "A brown roll of tobacco and... well, you're not quite sure. This thing's huge!" icon_state = "cigar2" - type_butt = /obj/item/weapon/cigbutt/cigarbutt + type_butt = /obj/item/trash/cigbutt/cigarbutt throw_speed = 0.5 item_state = "cigar" max_smoketime = 1500 @@ -369,7 +369,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM chem_volume = 30 nicotine_amt = 10 -/obj/item/weapon/cigbutt +/obj/item/trash/cigbutt name = "cigarette butt" desc = "A manky old cigarette butt." icon = 'icons/obj/clothing/masks.dmi' @@ -379,12 +379,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM slot_flags = SLOT_EARS throwforce = 1 -/obj/item/weapon/cigbutt/Initialize() +/obj/item/trash/cigbutt/Initialize() . = ..() randpixel_xy() transform = turn(transform,rand(0,360)) -/obj/item/weapon/cigbutt/cigarbutt +/obj/item/trash/cigbutt/cigarbutt name = "cigar butt" desc = "A manky old cigar butt." icon_state = "cigarbutt" diff --git a/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm b/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm index 097f465a512..0648b586277 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm @@ -12,7 +12,6 @@ /obj/item/weapon/circuitboard/security/New() ..() - network = using_map.station_networks /obj/item/weapon/circuitboard/security/tv name = T_BOARD("security camera monitor - television") @@ -45,7 +44,7 @@ /obj/item/weapon/circuitboard/security/construct(var/obj/machinery/computer/security/C) if (..(C)) - C.network = network.Copy() + C.set_network(network.Copy()) /obj/item/weapon/circuitboard/security/deconstruct(var/obj/machinery/computer/security/C) if (..(C)) diff --git a/code/game/objects/items/weapons/circuitboards/frame.dm b/code/game/objects/items/weapons/circuitboards/frame.dm index 5bd472be6c6..e9c0ee728a5 100644 --- a/code/game/objects/items/weapons/circuitboards/frame.dm +++ b/code/game/objects/items/weapons/circuitboards/frame.dm @@ -121,16 +121,6 @@ /obj/item/weapon/stock_parts/motor = 2, /obj/item/stack/cable_coil = 5) -/obj/item/weapon/circuitboard/microwave - name = T_BOARD("microwave") - build_path = /obj/machinery/microwave - board_type = new /datum/frame/frame_types/microwave - matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) - req_components = list( - /obj/item/weapon/stock_parts/console_screen = 1, - /obj/item/weapon/stock_parts/motor = 1, - /obj/item/weapon/stock_parts/capacitor = 1) - /obj/item/weapon/circuitboard/recharger name = T_BOARD("recharger") build_path = /obj/machinery/recharger @@ -250,13 +240,3 @@ /obj/item/weapon/stock_parts/spring = 1, /obj/item/stack/cable_coil = 5) -/obj/item/weapon/circuitboard/microwave/advanced - name = T_BOARD("deluxe microwave") - build_path = /obj/machinery/microwave/advanced - board_type = new /datum/frame/frame_types/microwave - matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) - req_components = list( - /obj/item/weapon/stock_parts/console_screen = 1, - /obj/item/weapon/stock_parts/motor = 1, - /obj/item/weapon/stock_parts/capacitor = 1) - diff --git a/code/game/objects/items/weapons/circuitboards/machinery/kitchen_appliances.dm b/code/game/objects/items/weapons/circuitboards/machinery/kitchen_appliances.dm new file mode 100644 index 00000000000..1af9476aff4 --- /dev/null +++ b/code/game/objects/items/weapons/circuitboards/machinery/kitchen_appliances.dm @@ -0,0 +1,74 @@ +/obj/item/weapon/circuitboard/microwave + name = T_BOARD("microwave") + desc = "The circuitboard for a microwave." + build_path = /obj/machinery/microwave + board_type = new /datum/frame/frame_types/microwave + contain_parts = 0 + matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) + req_components = list( + /obj/item/weapon/stock_parts/console_screen = 1, + /obj/item/weapon/stock_parts/capacitor = 3, // Original Capacitor count was 1 + /obj/item/weapon/stock_parts/motor = 1, + /obj/item/weapon/stock_parts/scanning_module = 1, + /obj/item/weapon/stock_parts/matter_bin = 2) + +/obj/item/weapon/circuitboard/oven + name = T_BOARD("oven") + desc = "The circuitboard for an oven." + build_path = /obj/machinery/appliance/cooker/oven + board_type = new /datum/frame/frame_types/oven + matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) + req_components = list( + /obj/item/weapon/stock_parts/capacitor = 3, + /obj/item/weapon/stock_parts/scanning_module = 1, + /obj/item/weapon/stock_parts/matter_bin = 2) + +/obj/item/weapon/circuitboard/fryer + name = T_BOARD("deep fryer") + desc = "The circuitboard for a deep fryer." + build_path = /obj/machinery/appliance/cooker/fryer + board_type = new /datum/frame/frame_types/fryer + req_components = list( + /obj/item/weapon/stock_parts/capacitor = 3, + /obj/item/weapon/stock_parts/scanning_module = 1, + /obj/item/weapon/stock_parts/matter_bin = 2) + +/obj/item/weapon/circuitboard/grill + name = T_BOARD("grill") + desc = "The circuitboard for an industrial grill." + build_path = /obj/machinery/appliance/cooker/grill + board_type = new /datum/frame/frame_types/grill + req_components = list( + /obj/item/weapon/stock_parts/capacitor = 3, + /obj/item/weapon/stock_parts/scanning_module = 1, + /obj/item/weapon/stock_parts/matter_bin = 2) + +/obj/item/weapon/circuitboard/cerealmaker + name = T_BOARD("cereal maker") + desc = "The circuitboard for a cereal maker." + build_path = /obj/machinery/appliance/mixer/cereal + board_type = new /datum/frame/frame_types/cerealmaker + req_components = list( + /obj/item/weapon/stock_parts/capacitor = 3, + /obj/item/weapon/stock_parts/scanning_module = 1, + /obj/item/weapon/stock_parts/matter_bin = 2) + +/obj/item/weapon/circuitboard/candymachine + name = T_BOARD("candy machine") + desc = "The circuitboard for a candy machine." + build_path = /obj/machinery/appliance/mixer/candy + board_type = new /datum/frame/frame_types/candymachine + req_components = list( + /obj/item/weapon/stock_parts/capacitor = 3, + /obj/item/weapon/stock_parts/scanning_module = 1, + /obj/item/weapon/stock_parts/matter_bin = 2) + +/obj/item/weapon/circuitboard/microwave/advanced + name = T_BOARD("deluxe microwave") + build_path = /obj/machinery/microwave/advanced + board_type = new /datum/frame/frame_types/microwave + matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50) + req_components = list( + /obj/item/weapon/stock_parts/console_screen = 1, + /obj/item/weapon/stock_parts/motor = 1, + /obj/item/weapon/stock_parts/capacitor = 1) \ No newline at end of file diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm index 9435be7fb33..7150f7f5563 100644 --- a/code/game/objects/items/weapons/cosmetics.dm +++ b/code/game/objects/items/weapons/cosmetics.dm @@ -96,17 +96,16 @@ w_class = ITEMSIZE_TINY icon = 'icons/obj/items.dmi' icon_state = "trinketbox" - var/list/ui_users = list() + var/datum/tgui_module/appearance_changer/mirror/coskit/M + +/obj/item/weapon/makeover/Initialize() + . = ..() + M = new(src, null) /obj/item/weapon/makeover/attack_self(mob/living/carbon/user as mob) if(ishuman(user)) to_chat(user, "You flip open \the [src] and begin to adjust your appearance.") - var/datum/nano_module/appearance_changer/AC = ui_users[user] - if(!AC) - AC = new(src, user) - AC.name = "SalonPro Porta-Makeover Deluxe™" - ui_users[user] = AC - AC.ui_interact(user) + M.tgui_interact(user) var/mob/living/carbon/human/H = user var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] if(istype(E)) diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm index 5b1f6752aeb..d701070acae 100644 --- a/code/game/objects/items/weapons/id cards/station_ids.dm +++ b/code/game/objects/items/weapons/id cards/station_ids.dm @@ -17,8 +17,7 @@ var/dna_hash = "\[UNSET\]" var/fingerprint_hash = "\[UNSET\]" var/sex = "\[UNSET\]" - var/icon/front - var/icon/side + var/front var/primary_color = rgb(0,0,0) // Obtained by eyedroppering the stripe in the middle of the card var/secondary_color = rgb(0,0,0) // Likewise for the oval in the top-left corner @@ -34,30 +33,27 @@ /obj/item/weapon/card/id/examine(mob/user) . = ..() if(in_range(user, src)) - show(user) //Not chat related + tgui_interact(user) //Not chat related else . += "It is too far away to read." /obj/item/weapon/card/id/proc/prevent_tracking() return 0 -/obj/item/weapon/card/id/proc/show(mob/user as mob) - if(front && side) - user << browse_rsc(front, "front.png") - user << browse_rsc(side, "side.png") - var/datum/browser/popup = new(user, "idcard", name, 600, 250) - popup.set_content(dat()) - popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - return +/obj/item/weapon/card/id/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "IDCard", name) + ui.open() /obj/item/weapon/card/id/proc/update_name() name = "[src.registered_name]'s ID Card ([src.assignment])" /obj/item/weapon/card/id/proc/set_id_photo(var/mob/M) - var/icon/charicon = cached_character_icon(M) - front = icon(charicon,dir = SOUTH) - side = icon(charicon,dir = WEST) + COMPILE_OVERLAYS(M) + SSoverlays.queue -= M + var/icon/F = getFlatIcon(M, defdir = SOUTH, no_anim = TRUE) + front = "'data:image/png;base64,[icon2base64(F)]'" /mob/proc/set_id_info(var/obj/item/weapon/card/id/id_card) id_card.age = 0 @@ -75,19 +71,19 @@ ..() id_card.age = age -/obj/item/weapon/card/id/proc/dat() - var/dat = ("" - dat += "
") - dat += text("Name: []
", registered_name) - dat += text("Sex: []
\n", sex) - dat += text("Age: []
\n", age) - dat += text("Rank: []
\n", assignment) - dat += text("Fingerprint: []
\n", fingerprint_hash) - dat += text("Blood Type: []
\n", blood_type) - dat += text("DNA Hash: []

\n", dna_hash) - if(front && side) - dat +="
Photo:
" - return dat +/obj/item/weapon/card/id/tgui_data(mob/user) + var/list/data = list() + + data["registered_name"] = registered_name + data["sex"] = sex + data["age"] = age + data["assignment"] = assignment + data["fingerprint_hash"] = fingerprint_hash + data["blood_type"] = blood_type + data["dna_hash"] = dna_hash + data["photo_front"] = front + + return data /obj/item/weapon/card/id/attack_self(mob/user as mob) user.visible_message("\The [user] shows you: [bicon(src)] [src.name]. The assignment on the card: [src.assignment]",\ diff --git a/code/game/objects/items/weapons/id cards/station_ids_vr.dm b/code/game/objects/items/weapons/id cards/station_ids_vr.dm new file mode 100644 index 00000000000..b659e756b3a --- /dev/null +++ b/code/game/objects/items/weapons/id cards/station_ids_vr.dm @@ -0,0 +1,2 @@ +/obj/item/weapon/card/id/gold/captain/spare/fakespare + rank = "null" \ No newline at end of file diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index 7978115ca2e..1ac3dcf0137 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -9,6 +9,7 @@ /obj/item/weapon/book/manual/engineering_construction name = "Station Repairs and Construction" icon_state ="bookEngineering" + item_state = "book3" author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Station Repairs and Construction" @@ -30,6 +31,7 @@ /obj/item/weapon/book/manual/engineering_particle_accelerator name = "Particle Accelerator User's Guide" icon_state ="bookParticleAccelerator" + item_state = "book15" author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Particle Accelerator User's Guide" @@ -77,6 +79,7 @@ /obj/item/weapon/book/manual/supermatter_engine name = "Supermatter Engine Operating Manual" icon_state = "bookSupermatter" + item_state = "book15" author = "Central Engineering Division" title = "Supermatter Engine Operating Manual" @@ -160,6 +163,7 @@ /obj/item/weapon/book/manual/tesla_engine name = "Tesla Operating Manual" icon_state ="bookTesla" + item_state = "book15" author = "Engineering Encyclopedia" title = "Tesla Engine User's Guide" dat = {" @@ -229,6 +233,7 @@ /obj/item/weapon/book/manual/rust_engine name = "R-UST Operating Manual" icon_state = "bookSupermatter" + item_state = "book15" author = "Cindy Crawfish" title = "R-UST Operating Manual" @@ -269,6 +274,7 @@ /obj/item/weapon/book/manual/engineering_hacking name = "Hacking" icon_state ="bookHacking" + item_state = "book2" author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Hacking" @@ -291,6 +297,7 @@ /obj/item/weapon/book/manual/engineering_singularity_safety name = "Singularity Safety in Special Circumstances" icon_state ="bookEngineeringSingularitySafety" + item_state = "book15" author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Singularity Safety in Special Circumstances" @@ -343,6 +350,7 @@ /obj/item/weapon/book/manual/hydroponics_pod_people name = "The Diona Harvest - From Seed to Market" icon_state ="bookHydroponicsPodPeople" + item_state = "book5" author = "Farmer John" title = "The Diona Harvest - From Seed to Market" @@ -381,6 +389,7 @@ /obj/item/weapon/book/manual/medical_cloning name = "Cloning Techniques of the 26th Century" icon_state ="bookCloning" + item_state = "book9" author = "Medical Journal, volume 3" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Cloning Techniques of the 26th Century" @@ -474,6 +483,7 @@ /obj/item/weapon/book/manual/ripley_build_and_repair name = "APLU \"Ripley\" Construction and Operation Manual" icon_state ="book" + item_state = "book" author = "Randall Varn, Einstein Engines Senior Mechanic" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "APLU \"Ripley\" Construction and Operation Manual" @@ -551,6 +561,7 @@ /obj/item/weapon/book/manual/research_and_development name = "Research and Development 101" icon_state = "rdbook" + item_state = "book7" author = "Dr. L. Ight" title = "Research and Development 101" @@ -620,6 +631,7 @@ /obj/item/weapon/book/manual/robotics_cyborgs name = "Cyborgs for Dummies" icon_state = "borgbook" + item_state = "book1" author = "XISC" title = "Cyborgs for Dummies" @@ -826,6 +838,7 @@ name = "Corporate Regulations" desc = "A set of corporate guidelines for keeping law and order on privately-owned space stations." icon_state = "bookSpaceLaw" + item_state = "book13" author = "The Company" title = "Corporate Regulations" @@ -850,6 +863,7 @@ name = "Medical Diagnostics Manual" desc = "First, do no harm. A detailed medical practitioner's guide." icon_state = "bookMedical" + item_state = "book12" author = "Medical Department" title = "Medical Diagnostics Manual" @@ -897,6 +911,7 @@ /obj/item/weapon/book/manual/engineering_guide name = "Engineering Textbook" icon_state ="bookEngineering2" + item_state = "book3" author = "Engineering Encyclopedia" title = "Engineering Textbook" @@ -918,6 +933,7 @@ /obj/item/weapon/book/manual/chef_recipes name = "Chef Recipes" icon_state = "cooked_book" + item_state = "book16" author = "Victoria Ponsonby" title = "Chef Recipes" @@ -978,6 +994,7 @@ name = "Barman Recipes" desc = "For the enterprising drink server." icon_state = "barbook" + item_state = "book14" author = "Sir John Rose" title = "Barman Recipes" @@ -1033,6 +1050,7 @@ /obj/item/weapon/book/manual/detective name = "The Film Noir: Proper Procedures for Investigations" icon_state ="bookDetective" + item_state = "book8" author = "The Company" title = "The Film Noir: Proper Procedures for Investigations" @@ -1076,6 +1094,7 @@ /obj/item/weapon/book/manual/nuclear name = "Fission Mailed: Nuclear Sabotage 101" icon_state ="bookNuclear" + item_state = "book8" author = "Syndicate" title = "Fission Mailed: Nuclear Sabotage 101" @@ -1127,6 +1146,7 @@ /obj/item/weapon/book/manual/atmospipes name = "Pipes and You: Getting To Know Your Scary Tools" icon_state = "pipingbook" + item_state = "book3" author = "Maria Crash, Senior Atmospherics Technician" title = "Pipes and You: Getting To Know Your Scary Tools" dat = {" @@ -1235,6 +1255,7 @@ /obj/item/weapon/book/manual/evaguide name = "EVA Gear and You: Not Spending All Day Inside, 2nd Edition" icon_state = "evabook" + item_state = "book14" author = "Maria Crash, Senior Atmospherics Technician" title = "EVA Gear and You: Not Spending All Day Inside, 2nd Edition" dat = {" diff --git a/code/game/objects/items/weapons/material/ashtray.dm b/code/game/objects/items/weapons/material/ashtray.dm index 5cd017f0058..95e558b36aa 100644 --- a/code/game/objects/items/weapons/material/ashtray.dm +++ b/code/game/objects/items/weapons/material/ashtray.dm @@ -46,7 +46,7 @@ var/global/list/ashtray_cache = list() /obj/item/weapon/material/ashtray/attackby(obj/item/weapon/W as obj, mob/user as mob) if (health <= 0) return - if (istype(W,/obj/item/weapon/cigbutt) || istype(W,/obj/item/clothing/mask/smokable/cigarette) || istype(W, /obj/item/weapon/flame/match)) + if (istype(W,/obj/item/trash/cigbutt) || istype(W,/obj/item/clothing/mask/smokable/cigarette) || istype(W, /obj/item/weapon/flame/match)) if (contents.len >= max_butts) to_chat(user, "\The [src] is full.") return diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm index 639a1e9bc6c..8119de19e07 100644 --- a/code/game/objects/items/weapons/scrolls.dm +++ b/code/game/objects/items/weapons/scrolls.dm @@ -3,6 +3,10 @@ desc = "A scroll for moving around." icon = 'icons/obj/wizard.dmi' icon_state = "scroll" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_books.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_books.dmi' + ) var/uses = 4.0 w_class = ITEMSIZE_TINY item_state = "paper" diff --git a/code/game/objects/items/weapons/storage/backpack_vr.dm b/code/game/objects/items/weapons/storage/backpack_vr.dm index 744abb85d86..b7485be674a 100644 --- a/code/game/objects/items/weapons/storage/backpack_vr.dm +++ b/code/game/objects/items/weapons/storage/backpack_vr.dm @@ -13,10 +13,6 @@ mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) if(..()) if(istype(H) && istype(H.tail_style, taurtype)) - if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? - slowdown = 0 - else - slowdown = initial(slowdown) return 1 else to_chat(H, "[no_message]") @@ -44,66 +40,20 @@ mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) if(..()) - var/datum/sprite_accessory/tail/taur/TT = H.tail_style - if(istype(H) && istype(TT, /datum/sprite_accessory/tail/taur/horse)) - item_state = "[icon_base]_Horse" - if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? - slowdown = 0 - else - slowdown = initial(slowdown) - return 1 - if(istype(H) && istype(TT, /datum/sprite_accessory/tail/taur/wolf)) - item_state = "[icon_base]_Wolf" - if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? - slowdown = 0 - else - slowdown = initial(slowdown) - return 1 - if(istype(H) && istype(TT, /datum/sprite_accessory/tail/taur/cow)) - item_state = "[icon_base]_Cow" - if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? - slowdown = 0 - else - slowdown = initial(slowdown) - return 1 - if(istype(H) && istype(TT, /datum/sprite_accessory/tail/taur/lizard)) - item_state = "[icon_base]_Lizard" - if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? - slowdown = 0 - else - slowdown = initial(slowdown) - return 1 - if(istype(H) && istype(TT, /datum/sprite_accessory/tail/taur/feline)) - item_state = "[icon_base]_Feline" - if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? - slowdown = 0 - else - slowdown = initial(slowdown) - return 1 - if(istype(H) && istype(TT, /datum/sprite_accessory/tail/taur/drake)) - item_state = "[icon_base]_Drake" - if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? - slowdown = 0 - else - slowdown = initial(slowdown) - return 1 - if(istype(H) && istype(TT, /datum/sprite_accessory/tail/taur/otie)) - item_state = "[icon_base]_Otie" - if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? - slowdown = 0 - else - slowdown = initial(slowdown) - return 1 - if(istype(H) && istype(TT, /datum/sprite_accessory/tail/taur/deer)) - item_state = "[icon_base]_Deer" - if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? - slowdown = 0 - else - slowdown = initial(slowdown) - return 1 + if(!istype(H))//Error, non HUMAN. + log_runtime("[H] was not a valid human!") + return + + if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? If yes, they get no slowdown. + slowdown = 0 else - to_chat(H, "[no_message]") - return 0 + slowdown = initial(slowdown) + + var/datum/sprite_accessory/tail/taur/TT = H.tail_style + item_state = "[icon_base]_[TT.icon_sprite_tag]" //icon_sprite_tag is something like "deer" + return 1 + + /obj/item/weapon/storage/backpack/saddlebag_common/robust //Shared bag for other taurs with sturdy backs name = "Robust Saddlebags" @@ -116,7 +66,7 @@ /obj/item/weapon/storage/backpack/saddlebag_common/vest //Shared bag for other taurs with sturdy backs name = "Taur Duty Vest" - desc = "An armored vest with the armor modules replaced with various handy compartments with decent storage capacity. Useless for protection though." + desc = "An armored vest with the armor modules replaced with various handy compartments with decent storage capacity. Useless for protection though. Holds less than a saddle." icon = 'icons/obj/clothing/backpack_vr.dmi' icon_override = 'icons/mob/back_vr.dmi' item_state = "taurvest" @@ -145,6 +95,7 @@ icon_override = 'icons/mob/back_vr.dmi' item_state = "satchel-explorer" icon_state = "satchel-explorer" + /obj/item/weapon/storage/backpack/explorer name = "explorer backpack" desc = "A backpack for carrying a large number of supplies easily." @@ -152,6 +103,7 @@ icon_override = 'icons/mob/back_vr.dmi' item_state = "explorerpack" icon_state = "explorerpack" + /obj/item/weapon/storage/backpack/satchel/roboticist name = "roboticist satchel" desc = "A satchel for carrying a large number of spare parts easily." @@ -159,6 +111,7 @@ icon_override = 'icons/mob/back_vr.dmi' item_state = "satchel-robo" icon_state = "satchel-robo" + /obj/item/weapon/storage/backpack/roboticist name = "roboticist backpack" desc = "A backpack for carrying a large number of spare parts easily." @@ -166,6 +119,7 @@ icon_override = 'icons/mob/back_vr.dmi' item_state = "backpack-robo" icon_state = "backpack-robo" + /obj/item/weapon/storage/backpack/vietnam name = "vietnam backpack" desc = "There are tangos in the trees! We need napalm right now! Why is my gun jammed?" @@ -173,6 +127,7 @@ icon_override = 'icons/mob/back_vr.dmi' item_state = "nambackpack" icon_state = "nambackpack" + /obj/item/weapon/storage/backpack/russian name = "russian backpack" desc = "Useful for carrying large quantities of vodka." @@ -180,6 +135,7 @@ icon_override = 'icons/mob/back_vr.dmi' item_state = "ru_rucksack" icon_state = "ru_rucksack" + /obj/item/weapon/storage/backpack/korean name = "korean backpack" desc = "Insert witty description here." diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index 75cbc2297e7..62c70457c0b 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -2,6 +2,11 @@ name = "bible" desc = "Apply to head repeatedly." icon_state ="bible" + item_state = "bible" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_books.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_books.dmi' + ) throw_speed = 1 throw_range = 5 w_class = ITEMSIZE_NORMAL diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 3ef882c3817..96e4c87da31 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -199,6 +199,16 @@ /obj/item/weapon/storage/box/empshells/large starts_with = list(/obj/item/ammo_casing/a12g/emp = 16) +/obj/item/weapon/storage/box/flechetteshells + name = "box of shotgun flechettes" + desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." + icon_state = "lethalslug_box" + item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + starts_with = list(/obj/item/ammo_casing/a12g/flechette = 8) + +/obj/item/weapon/storage/box/flechetteshells/large + starts_with = list(/obj/item/ammo_casing/a12g/flechette = 16) + /obj/item/weapon/storage/box/sniperammo name = "box of 14.5mm shells" desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 926255c6200..f1003c451bf 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -209,7 +209,7 @@ throwforce = 2 slot_flags = SLOT_BELT storage_slots = 6 - can_hold = list(/obj/item/clothing/mask/smokable/cigarette, /obj/item/weapon/flame/lighter, /obj/item/weapon/cigbutt) + can_hold = list(/obj/item/clothing/mask/smokable/cigarette, /obj/item/weapon/flame/lighter, /obj/item/trash/cigbutt) icon_type = "cigarette" starts_with = list(/obj/item/clothing/mask/smokable/cigarette = 6) var/brand = "\improper Trans-Stellar Duty-free" @@ -316,7 +316,7 @@ throwforce = 2 slot_flags = SLOT_BELT storage_slots = 7 - can_hold = list(/obj/item/clothing/mask/smokable/cigarette/cigar, /obj/item/weapon/cigbutt/cigarbutt) + can_hold = list(/obj/item/clothing/mask/smokable/cigarette/cigar, /obj/item/trash/cigbutt/cigarbutt) icon_type = "cigar" starts_with = list(/obj/item/clothing/mask/smokable/cigarette/cigar = 7) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 25c08c725a1..f267ac36544 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -1,5 +1,5 @@ #define TANK_MAX_RELEASE_PRESSURE (3*ONE_ATMOSPHERE) -#define TANK_DEFAULT_RELEASE_PRESSURE 24 +#define TANK_DEFAULT_RELEASE_PRESSURE 21 #define TANK_IDEAL_PRESSURE 1015 //Arbitrary. var/list/global/tank_gauge_cache = list() @@ -217,90 +217,73 @@ var/list/global/tank_gauge_cache = list() add_fingerprint(user) if (!(src.air_contents)) return - ui_interact(user) + tgui_interact(user) // There's GOT to be a better way to do this if (src.proxyassembly.assembly) src.proxyassembly.assembly.attack_self(user) -/obj/item/weapon/tank/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/mob/living/carbon/location = null +/obj/item/weapon/tank/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Tank", name) + ui.open() - if(istype(loc, /obj/item/weapon/rig)) // check for tanks in rigs - if(istype(loc.loc, /mob/living/carbon)) - location = loc.loc - else if(istype(loc, /mob/living/carbon)) - location = loc - - var/using_internal - if(istype(location)) - if(location.internal==src) - using_internal = 1 - - // this is the data which will be sent to the ui - var/data[0] +/obj/item/weapon/tank/tgui_data(mob/user) + var/list/data = list() data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) data["releasePressure"] = round(distribute_pressure ? distribute_pressure : 0) data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE) + data["minReleasePressure"] = 0 data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE) - data["valveOpen"] = using_internal ? 1 : 0 - data["maskConnected"] = 0 - if(istype(location)) - var/mask_check = 0 + var/mob/living/carbon/C = user + if(!istype(C)) + C = loc.loc + if(!istype(C)) + return data - if(location.internal == src) // if tank is current internal - mask_check = 1 - else if(src in location) // or if tank is in the mobs possession - if(!location.internal) // and they do not have any active internals - mask_check = 1 - else if(istype(src.loc, /obj/item/weapon/rig) && src.loc in location) // or the rig is in the mobs possession - if(!location.internal) // and they do not have any active internals - mask_check = 1 + if(C.internal == src) + data["connected"] = TRUE + else + data["connected"] = FALSE - if(mask_check) - if(location.wear_mask && (location.wear_mask.item_flags & AIRTIGHT)) - data["maskConnected"] = 1 - else if(istype(location, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = location - if(H.head && (H.head.item_flags & AIRTIGHT)) - data["maskConnected"] = 1 + data["maskConnected"] = FALSE + if(C.wear_mask && (C.wear_mask.item_flags & AIRTIGHT)) + data["maskConnected"] = TRUE + else if(ishuman(C)) + var/mob/living/carbon/human/H = C + if(H.head && (H.head.item_flags & AIRTIGHT)) + data["maskConnected"] = TRUE - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "tanks.tmpl", "Tank", 500, 300) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) + return data -/obj/item/weapon/tank/Topic(href, href_list) - ..() - if (usr.stat|| usr.restrained()) - return 0 - if (src.loc != usr) - return 0 +/obj/item/weapon/tank/tgui_act(action, params) + if(..()) + return TRUE + switch(action) + if("pressure") + var/pressure = params["pressure"] + if(pressure == "reset") + pressure = TANK_DEFAULT_RELEASE_PRESSURE + . = TRUE + else if(pressure == "min") + pressure = 0 + . = TRUE + else if(pressure == "max") + pressure = TANK_MAX_RELEASE_PRESSURE + . = TRUE + else if(text2num(pressure) != null) + pressure = text2num(pressure) + . = TRUE + if(.) + distribute_pressure = clamp(round(pressure), 0, TANK_MAX_RELEASE_PRESSURE) + if("toggle") + toggle_valve(usr) + . = TRUE - if (href_list["dist_p"]) - if (href_list["dist_p"] == "reset") - src.distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE - else if (href_list["dist_p"] == "max") - src.distribute_pressure = TANK_MAX_RELEASE_PRESSURE - else - var/cp = text2num(href_list["dist_p"]) - src.distribute_pressure += cp - src.distribute_pressure = min(max(round(src.distribute_pressure), 0), TANK_MAX_RELEASE_PRESSURE) - if (href_list["stat"]) - toggle_valve(usr) - - src.add_fingerprint(usr) - return 1 + add_fingerprint(usr) /obj/item/weapon/tank/proc/toggle_valve(var/mob/user) if(istype(loc,/mob/living/carbon)) diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index 62153d440b3..90b62ed07b7 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -126,7 +126,7 @@ return 1 /obj/item/weapon/tape_roll/proc/stick(var/obj/item/weapon/W, mob/user) - if(!istype(W, /obj/item/weapon/paper)) + if(!istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/weapon/paper/sticky) || !user.unEquip(W)) return user.drop_from_inventory(W) var/obj/item/weapon/ducttape/tape = new(get_turf(src)) diff --git a/code/game/objects/items/weapons/towels.dm b/code/game/objects/items/weapons/towels.dm index b9566c399b1..232a3212028 100644 --- a/code/game/objects/items/weapons/towels.dm +++ b/code/game/objects/items/weapons/towels.dm @@ -10,6 +10,16 @@ desc = "A soft cotton towel." drop_sound = 'sound/items/drop/clothing.ogg' +/obj/item/weapon/towel/equipped(var/M, var/slot) + ..() + switch(slot) + if(slot_head) + sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/head.dmi') + if(slot_wear_suit) + sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/suit.dmi') + if(slot_belt) + sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/belt.dmi') + /obj/item/weapon/towel/attack_self(mob/living/user as mob) user.visible_message(text("[] uses [] to towel themselves off.", user, src)) playsound(src, 'sound/weapons/towelwipe.ogg', 25, 1) diff --git a/code/game/objects/mob_spawner_vr.dm b/code/game/objects/mob_spawner_vr.dm index 23ec38c907e..a3f01c53718 100644 --- a/code/game/objects/mob_spawner_vr.dm +++ b/code/game/objects/mob_spawner_vr.dm @@ -30,7 +30,7 @@ /obj/structure/mob_spawner/Destroy() STOP_PROCESSING(SSobj, src) for(var/mob/living/L in spawned_mobs) - L.source_spawner = null + L.nest = null spawned_mobs.Cut() return ..() @@ -57,7 +57,7 @@ if(!ispath(mob_path)) return 0 var/mob/living/L = new mob_path(get_turf(src)) - L.source_spawner = src + L.nest = src spawned_mobs.Add(L) last_spawn = world.time if(total_spawns > 0) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 3764ae62587..9bca1c29331 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -136,6 +136,7 @@ /obj/attack_ghost(mob/user) ui_interact(user) + tgui_interact(user) ..() /obj/proc/interact(mob/user) diff --git a/code/game/objects/random/_random.dm b/code/game/objects/random/_random.dm index 8b616c83f51..67f82ea1551 100644 --- a/code/game/objects/random/_random.dm +++ b/code/game/objects/random/_random.dm @@ -48,7 +48,6 @@ var/list/random_useful_ if(prob(70)) // Misc. junk if(!random_junk_) random_junk_ = subtypesof(/obj/item/trash) - random_junk_ += typesof(/obj/item/weapon/cigbutt) random_junk_ += /obj/effect/decal/cleanable/spiderling_remains random_junk_ += /obj/effect/decal/remains/mouse random_junk_ += /obj/effect/decal/remains/robot diff --git a/code/game/objects/random/guns_and_ammo.dm b/code/game/objects/random/guns_and_ammo.dm index a3411ef6fed..43a166a6473 100644 --- a/code/game/objects/random/guns_and_ammo.dm +++ b/code/game/objects/random/guns_and_ammo.dm @@ -16,6 +16,7 @@ /obj/random/energy/item_to_spawn() return pick(prob(3);/obj/item/weapon/gun/energy/laser, + prob(3);/obj/item/weapon/gun/energy/laser/sleek, prob(4);/obj/item/weapon/gun/energy/gun, prob(3);/obj/item/weapon/gun/energy/gun/burst, prob(1);/obj/item/weapon/gun/energy/gun/nuclear, @@ -29,7 +30,8 @@ prob(3);/obj/item/weapon/gun/energy/toxgun, prob(4);/obj/item/weapon/gun/energy/taser, prob(2);/obj/item/weapon/gun/energy/crossbow/largecrossbow, - prob(4);/obj/item/weapon/gun/energy/stunrevolver) + prob(4);/obj/item/weapon/gun/energy/stunrevolver, + prob(3);/obj/item/weapon/gun/energy/gun/compact) /obj/random/energy/sec name = "Random Security Energy Weapon" @@ -54,6 +56,7 @@ prob(2);/obj/item/weapon/gun/projectile/automatic/c20r, prob(2);/obj/item/weapon/gun/projectile/automatic/sts35, prob(2);/obj/item/weapon/gun/projectile/automatic/z8, + prob(2);/obj/item/weapon/gun/projectile/automatic/combatsmg, prob(4);/obj/item/weapon/gun/projectile/colt, prob(2);/obj/item/weapon/gun/projectile/deagle, prob(1);/obj/item/weapon/gun/projectile/deagle/camo, @@ -193,6 +196,11 @@ prob(1);list( /obj/item/weapon/gun/projectile/automatic/p90, /obj/item/ammo_magazine/m9mmp90 + ), + prob(3);list( + /obj/item/weapon/gun/projectile/automatic/combatsmg, + /obj/item/ammo_magazine/m9mmt, + /obj/item/ammo_magazine/m9mmt ) ) @@ -231,10 +239,20 @@ /obj/item/ammo_magazine/m762garand, /obj/item/ammo_magazine/m762garand ), + prob(1);list( + /obj/item/weapon/gun/projectile/revolvingrifle, + /obj/item/ammo_magazine/s44/rifle, + /obj/item/ammo_magazine/s44/rifle + ), prob(1);list( /obj/item/weapon/gun/projectile/automatic/bullpup, /obj/item/ammo_magazine/m762, /obj/item/ammo_magazine/m762 + ), + prob(1);list( + /obj/item/weapon/gun/projectile/caseless/prototype, + /obj/item/ammo_magazine/m5mmcaseless, + /obj/item/ammo_magazine/m5mmcaseless ) ) diff --git a/code/game/objects/random/maintenance.dm b/code/game/objects/random/maintenance.dm index 4ee11fb8cb5..37dcca83197 100644 --- a/code/game/objects/random/maintenance.dm +++ b/code/game/objects/random/maintenance.dm @@ -107,7 +107,17 @@ something, make sure it's not in one of the other lists.*/ prob(2);/obj/item/device/camera, prob(3);/obj/item/device/pda, prob(3);/obj/item/device/radio/headset, - prob(1);/obj/item/pizzavoucher) + /* VOREStation Edit Start */ + prob(2);/obj/item/toy/tennis, + prob(2);/obj/item/toy/tennis/red, + prob(2);/obj/item/toy/tennis/yellow, + prob(2);/obj/item/toy/tennis/green, + prob(2);/obj/item/toy/tennis/cyan, + prob(2);/obj/item/toy/tennis/blue, + prob(2);/obj/item/toy/tennis/purple, + prob(1);/obj/item/pizzavoucher + /* VOREStation Edit End */ + ) /obj/random/maintenance/security /*Maintenance loot list. This one is for around security areas*/ diff --git a/code/game/objects/random/mapping.dm b/code/game/objects/random/mapping.dm index bc6d29a5a5e..230b4ff3d29 100644 --- a/code/game/objects/random/mapping.dm +++ b/code/game/objects/random/mapping.dm @@ -34,6 +34,36 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/remains/robot) +/obj/random/crate //Random 'standard' crates for variety in maintenance spawns. + name = "random crate" + desc = "This is a random crate" + icon = 'icons/obj/closets/bases/crate.dmi' + icon_state = "base" + +/obj/random/crate/item_to_spawn() //General crates, excludes some more high-grade and medical brands + return pick (/obj/structure/closet/crate/plastic, + /obj/structure/closet/crate/aether, + /obj/structure/closet/crate/centauri, + /obj/structure/closet/crate/einstein, + /obj/structure/closet/crate/focalpoint, + /obj/structure/closet/crate/gilthari, + /obj/structure/closet/crate/grayson, + /obj/structure/closet/crate/nanotrasen, + /obj/structure/closet/crate/nanothreads, + /obj/structure/closet/crate/oculum, + /obj/structure/closet/crate/ward, + /obj/structure/closet/crate/xion, + /obj/structure/closet/crate/zenghu, + /obj/structure/closet/crate/allico, + /obj/structure/closet/crate/carp, + /obj/structure/closet/crate/galaksi, + /obj/structure/closet/crate/thinktronic, + /obj/structure/closet/crate/ummarcar, + /obj/structure/closet/crate/unathi, + /obj/structure/closet/crate/hydroponics, + /obj/structure/closet/crate/engineering, + /obj/structure/closet/crate) + /obj/random/obstruction //Large objects to block things off in maintenance name = "random obstruction" desc = "This is a random obstruction." diff --git a/code/game/objects/random/mechs.dm b/code/game/objects/random/mechs.dm new file mode 100644 index 00000000000..7dcd3db5cc5 --- /dev/null +++ b/code/game/objects/random/mechs.dm @@ -0,0 +1,56 @@ +/obj/random/mech + name = "random mech" + desc = "This is a random single mech." + icon = 'icons/mecha/mecha.dmi' + icon_state = "old_durand" + drop_get_turf = FALSE + +//This list includes the phazon, gorilla and mauler. You might want to use something else if balance is a concern. +/obj/random/mech/item_to_spawn() + return pick(/obj/mecha/combat/gygax, + /obj/mecha/combat/gygax/serenity, + /obj/mecha/combat/gygax/dark, + /obj/mecha/combat/marauder, + /obj/mecha/combat/marauder/seraph, + /obj/mecha/combat/marauder/mauler, + /obj/mecha/medical/odysseus, + /obj/mecha/combat/phazon, + /obj/mecha/combat/phazon/janus, + /obj/mecha/combat/durand, + /obj/mecha/working/ripley, + /obj/mecha/working/ripley/firefighter, + /obj/mecha/working/ripley/deathripley, + /obj/mecha/working/ripley/mining) + +/obj/random/mech/weaker + name = "random mech" + desc = "This is a random single mech. Those are less potent and more common." + icon = 'icons/mecha/mecha.dmi' + icon_state = "old_durand" + drop_get_turf = FALSE + +/obj/random/mech/weaker/item_to_spawn() + return pick(/obj/mecha/combat/gygax, + /obj/mecha/combat/gygax/serenity, + /obj/mecha/medical/odysseus, + /obj/mecha/combat/durand, + /obj/mecha/working/ripley, + /obj/mecha/working/ripley/firefighter, + /obj/mecha/working/ripley/deathripley, + /obj/mecha/working/ripley/mining) + +/obj/random/mech/old + name = "random mech" + desc = "This is a random single old mech." + icon = 'icons/mecha/mecha.dmi' + icon_state = "old_durand" + drop_get_turf = FALSE + +//Note that all of those are worn out and have slightly less maximal health than the standard. +/obj/random/mech/old/item_to_spawn() + return pick(prob(10);/obj/mecha/combat/gygax/old, + prob(1);/obj/mecha/combat/marauder/old, + prob(1);/obj/mecha/combat/phazon/old, + prob(10);/obj/mecha/combat/durand/old, + prob(15);/obj/mecha/medical/odysseus/old, + prob(20);/obj/mecha/working/ripley/mining/old) diff --git a/code/game/objects/random/misc.dm b/code/game/objects/random/misc.dm index 944c1145ad3..73796038e1b 100644 --- a/code/game/objects/random/misc.dm +++ b/code/game/objects/random/misc.dm @@ -473,6 +473,7 @@ //VOREStation Add Start /obj/item/toy/plushie/lizardplushie, /obj/item/toy/plushie/lizardplushie/kobold, + /obj/item/toy/plushie/lizardplushie/resh, /obj/item/toy/plushie/slimeplushie, /obj/item/toy/plushie/box, /obj/item/toy/plushie/borgplushie, @@ -542,8 +543,8 @@ /obj/item/device/assembly/mousetrap/armed, /obj/effect/decal/cleanable/spiderling_remains, /obj/effect/decal/cleanable/ash, - /obj/item/weapon/cigbutt, - /obj/item/weapon/cigbutt/cigarbutt, + /obj/item/trash/cigbutt, + /obj/item/trash/cigbutt/cigarbutt, /obj/effect/decal/remains/mouse) /obj/random/janusmodule diff --git a/code/game/objects/random/mob.dm b/code/game/objects/random/mob.dm index ac89272f529..bd720faed4a 100644 --- a/code/game/objects/random/mob.dm +++ b/code/game/objects/random/mob.dm @@ -33,7 +33,9 @@ prob(10);/mob/living/simple_mob/animal/passive/mouse, prob(10);/mob/living/simple_mob/animal/passive/yithian, prob(10);/mob/living/simple_mob/animal/passive/tindalos, + prob(10);/mob/living/simple_mob/animal/passive/pillbug, prob(10);/mob/living/simple_mob/animal/passive/dog/tamaskan, + prob(10);/mob/living/simple_mob/animal/passive/dog/brittany, prob(3);/mob/living/simple_mob/animal/passive/bird/parrot, prob(1);/mob/living/simple_mob/animal/passive/crab) @@ -69,10 +71,12 @@ /obj/random/mob/sif/item_to_spawn() return pick(prob(30);/mob/living/simple_mob/animal/sif/diyaab, + prob(20);/mob/living/simple_mob/animal/passive/hare, prob(15);/mob/living/simple_mob/animal/passive/crab, prob(15);/mob/living/simple_mob/animal/passive/penguin, prob(15);/mob/living/simple_mob/animal/passive/mouse, prob(15);/mob/living/simple_mob/animal/passive/dog/tamaskan, + prob(10);/mob/living/simple_mob/animal/sif/siffet, prob(2);/mob/living/simple_mob/animal/giant_spider/frost, prob(1);/mob/living/simple_mob/animal/space/goose, prob(20);/mob/living/simple_mob/animal/passive/crab) @@ -88,6 +92,7 @@ /obj/random/mob/sif/peaceful/item_to_spawn() return pick(prob(30);/mob/living/simple_mob/animal/sif/diyaab, + prob(20);/mob/living/simple_mob/animal/passive/hare, prob(15);/mob/living/simple_mob/animal/passive/crab, prob(15);/mob/living/simple_mob/animal/passive/penguin, prob(15);/mob/living/simple_mob/animal/passive/mouse, @@ -102,6 +107,8 @@ /obj/random/mob/sif/hostile/item_to_spawn() return pick(prob(22);/mob/living/simple_mob/animal/sif/savik, prob(33);/mob/living/simple_mob/animal/giant_spider/frost, + prob(20);/mob/living/simple_mob/animal/sif/frostfly, + prob(10);/mob/living/simple_mob/animal/sif/tymisian, prob(45);/mob/living/simple_mob/animal/sif/shantak) /obj/random/mob/sif/kururak @@ -329,6 +336,12 @@ /mob/living/simple_mob/animal/sif/duck, /mob/living/simple_mob/animal/sif/duck ), + prob(15);list( + /mob/living/simple_mob/animal/passive/hare, + /mob/living/simple_mob/animal/passive/hare, + /mob/living/simple_mob/animal/passive/hare, + /mob/living/simple_mob/animal/passive/hare + ), prob(10);list( /mob/living/simple_mob/animal/sif/shantak/retaliate, /mob/living/simple_mob/animal/sif/shantak/retaliate, diff --git a/code/game/objects/structures/crates_lockers/_closets_appearance_definitions.dm b/code/game/objects/structures/crates_lockers/_closets_appearance_definitions.dm index f6a0942d368..b90a7961e2a 100644 --- a/code/game/objects/structures/crates_lockers/_closets_appearance_definitions.dm +++ b/code/game/objects/structures/crates_lockers/_closets_appearance_definitions.dm @@ -761,8 +761,210 @@ "lid_stripes" = COLOR_NT_RED ) +// Freezers + /decl/closet_appearance/crate/freezer + color = COLOR_OFF_WHITE + +/decl/closet_appearance/crate/freezer/centauri color = COLOR_BABY_BLUE + extra_decals = list( + "centauri" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/freezer/nanotrasen + color = COLOR_BABY_BLUE + extra_decals = list( + "nano" = COLOR_OFF_WHITE + ) + +// Corporate Branding + +/decl/closet_appearance/crate/aether + color = COLOR_YELLOW_GRAY + decals = list( + "crate_stripes" = COLOR_BLUE_LIGHT, + "aether" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/allico + color = COLOR_LIGHT_VIOLET + decals = list( + "crate_stripe" = COLOR_AMBER + ) + +/decl/closet_appearance/crate/carp + color = COLOR_PURPLE + decals = list( + "toptext" = COLOR_OFF_WHITE, + "crate_reticle" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/centauri + color = COLOR_BABY_BLUE + decals = list( + "crate_stripe" = COLOR_LUMINOL + ) + extra_decals = list( + "centauri" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/cybersolutions + color = COLOR_ALUMINIUM + extra_decals = list( + "hazard" = COLOR_DARK_GOLD, + "toptext" = COLOR_DARK_GOLD + ) + +/decl/closet_appearance/crate/einstein + color = COLOR_DARK_BLUE_GRAY + extra_decals = list( + "crate_stripe_left" = COLOR_BEIGE, + "crate_stripe_right" = COLOR_BEIGE, + "einstein" = COLOR_OFF_WHITE, + "hazard" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/focalpoint + color = COLOR_GOLD + extra_decals = list( + "crate_stripe_left" = COLOR_NAVY_BLUE, + "crate_stripe_right" = COLOR_NAVY_BLUE, + "focal" = COLOR_OFF_WHITE, + "hazard" = COLOR_NAVY_BLUE + ) + +/decl/closet_appearance/crate/galaksi + color = COLOR_OFF_WHITE + decals = list( + "lid_stripes" = COLOR_HULL, + "galaksi" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/gilthari + color = COLOR_GRAY20 + extra_decals = list( + "crate_stripe_left" = COLOR_GOLD, + "crate_stripe_right" = COLOR_GOLD, + "gilthari" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/grayson + color = COLOR_STEEL + extra_decals = list( + "crate_stripe_left" = COLOR_MAROON, + "crate_stripe_right" = COLOR_MAROON, + "grayson" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/heph + color = COLOR_GRAY20 + extra_decals = list( + "crate_stripe_left" = COLOR_NT_RED, + "crate_stripe_right" = COLOR_NT_RED, + "heph" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/morpheus + color = COLOR_ALUMINIUM + extra_decals = list( + "hazard" = COLOR_GUNMETAL, + "toptext" = COLOR_GUNMETAL + ) + +/decl/closet_appearance/crate/nanotrasen + color = COLOR_NT_RED + extra_decals = list( + "crate_stripe_left" = COLOR_OFF_WHITE, + "crate_stripe_right" = COLOR_OFF_WHITE, + "nano" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/nanotrasenclothing + color = COLOR_NT_RED + extra_decals = list( + "crate_stripe_left" = COLOR_SEDONA, + "crate_stripe_right" = COLOR_SEDONA, + "nano" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/nanotrasenmedical + color = COLOR_OFF_WHITE + extra_decals = list( + "crate_stripe" = COLOR_NT_RED, + "nano" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/oculum + color = COLOR_SURGERY_BLUE + decals = list( + "crate_stripe_left" = COLOR_OFF_WHITE, + "crate_stripe_right" = COLOR_OFF_WHITE, + "oculum" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/saare + color = COLOR_ALUMINIUM + extra_decals = list( + "hazard" = COLOR_RED, + "xion" = COLOR_GRAY40 + ) + +/decl/closet_appearance/crate/thinktronic + color = COLOR_PALE_PURPLE_GRAY + decals = list( + "toptext" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/ummarcar + color = COLOR_BEIGE + decals = list( + "crate_stripes" = COLOR_OFF_WHITE, + "toptext" = COLOR_GRAY20 + ) + +/decl/closet_appearance/crate/unathiimport + color = COLOR_SILVER + decals = list( + "crate_stripe" = COLOR_RED, + "crate_reticle" = COLOR_RED_GRAY + ) + +/decl/closet_appearance/crate/veymed + color = COLOR_OFF_WHITE + decals = list( + "crate_stripe" = COLOR_PALE_BTL_GREEN + ) + extra_decals = list( + "lid_stripes" = COLOR_RED, + "crate_cross" = COLOR_GREEN + ) + +/decl/closet_appearance/crate/ward + color = COLOR_OFF_WHITE + extra_decals = list( + "crate_stripe_left" = COLOR_COMMAND_BLUE, + "crate_stripe_right" = COLOR_COMMAND_BLUE, + "hazard" = COLOR_OFF_WHITE, + "wt" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/xion + color = COLOR_ORANGE + extra_decals = list( + "crate_stripes" = COLOR_OFF_WHITE, + "xion" = COLOR_OFF_WHITE, + "hazard" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/zenghu + color = COLOR_OFF_WHITE + extra_decals = list( + "crate_stripes" = COLOR_RED, + "zenghu" = COLOR_OFF_WHITE + ) + +// Secure Crates /decl/closet_appearance/crate/secure can_lock = TRUE @@ -775,7 +977,8 @@ extra_decals = list( "crate_stripe_left" = COLOR_OFF_WHITE, "crate_stripe_right" = COLOR_OFF_WHITE, - "toxin" = COLOR_OFF_WHITE + "toxin" = COLOR_OFF_WHITE, + "nano" = COLOR_OFF_WHITE ) /decl/closet_appearance/crate/secure/weapon @@ -789,6 +992,219 @@ "hazard" = COLOR_OFF_WHITE ) +// Secure corporate branding + +/decl/closet_appearance/crate/secure/aether + color = COLOR_YELLOW_GRAY + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripes" = COLOR_BLUE_LIGHT, + "aether" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/bishop + color = COLOR_OFF_WHITE + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_SKY_BLUE, + "crate_stripe_right" = COLOR_SKY_BLUE, + "bishop" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/cybersolutions + color = COLOR_ALUMINIUM + decals = list( + "crate_bracing" + ) + extra_decals = list( + "hazard" = COLOR_DARK_GOLD, + "toptext" = COLOR_DARK_GOLD + ) + +/decl/closet_appearance/crate/secure/einstein + color = COLOR_DARK_BLUE_GRAY + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_BEIGE, + "crate_stripe_right" = COLOR_BEIGE, + "einstein" = COLOR_OFF_WHITE, + "hazard" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/focalpoint + color = COLOR_GOLD + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_NAVY_BLUE, + "crate_stripe_right" = COLOR_NAVY_BLUE, + "focal" = COLOR_OFF_WHITE, + "hazard" = COLOR_NAVY_BLUE + ) + +/decl/closet_appearance/crate/secure/gilthari + color = COLOR_GRAY20 + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_GOLD, + "crate_stripe_right" = COLOR_GOLD, + "hazard" = COLOR_OFF_WHITE, + "gilthari" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/grayson + color = COLOR_STEEL + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_MAROON, + "crate_stripe_right" = COLOR_MAROON, + "grayson" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/hedberg + color = COLOR_GREEN_GRAY + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_OFF_WHITE, + "crate_stripe_right" = COLOR_OFF_WHITE, + "hazard" = COLOR_OFF_WHITE, + "hedberg" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/heph + color = COLOR_GRAY20 + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_NT_RED, + "crate_stripe_right" = COLOR_NT_RED, + "hazard" = COLOR_OFF_WHITE, + "heph" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/lawson + color = COLOR_SAN_MARINO_BLUE + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_OFF_WHITE, + "crate_stripe_right" = COLOR_OFF_WHITE, + "hazard" = COLOR_OFF_WHITE, + "lawson" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/morpheus + color = COLOR_ALUMINIUM + decals = list( + "crate_bracing" + ) + extra_decals = list( + "hazard" = COLOR_GUNMETAL, + "toptext" = COLOR_GUNMETAL + ) + +/decl/closet_appearance/crate/secure/nanotrasen + color = COLOR_NT_RED + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_OFF_WHITE, + "crate_stripe_right" = COLOR_OFF_WHITE, + "nano" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/nanotrasenmedical + color = COLOR_OFF_WHITE + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe" = COLOR_NT_RED, + "nano" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/saare + color = COLOR_ALUMINIUM + decals = list( + "crate_bracing" + ) + extra_decals = list( + "hazard" = COLOR_RED, + "xion" = COLOR_GRAY40 + ) + +/decl/closet_appearance/crate/secure/solgov + color = COLOR_SAN_MARINO_BLUE + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_OFF_WHITE, + "crate_stripes" = COLOR_OFF_WHITE, + "hazard" = COLOR_OFF_WHITE, + "scg" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/veymed + color = COLOR_OFF_WHITE + decals = list( + "crate_bracing", + "crate_stripe" = COLOR_PALE_BTL_GREEN + ) + extra_decals = list( + "lid_stripes" = COLOR_RED, + "crate_cross" = COLOR_GREEN + ) + +/decl/closet_appearance/crate/secure/ward + color = COLOR_OFF_WHITE + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripe_left" = COLOR_COMMAND_BLUE, + "crate_stripe_right" = COLOR_COMMAND_BLUE, + "hazard" = COLOR_OFF_WHITE, + "wt" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/xion + color = COLOR_ORANGE + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripes" = COLOR_OFF_WHITE, + "xion" = COLOR_OFF_WHITE, + "hazard" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/crate/secure/zenghu + color = COLOR_OFF_WHITE + decals = list( + "crate_bracing" + ) + extra_decals = list( + "crate_stripes" = COLOR_RED, + "zenghu" = COLOR_OFF_WHITE + ) + /decl/closet_appearance/crate/secure/hydroponics extra_decals = list( "crate_stripe_left" = COLOR_GREEN_GRAY, @@ -809,6 +1225,7 @@ extra_decals = null /decl/closet_appearance/large_crate/critter + color = COLOR_BEIGE decals = list( "airholes" ) @@ -822,6 +1239,42 @@ "text" = COLOR_GREEN_GRAY ) +/decl/closet_appearance/large_crate/aether + color = COLOR_YELLOW_GRAY + decals = list( + "crate_bracing" + ) + extra_decals = list( + "text" = COLOR_BLUE_LIGHT + ) + +/decl/closet_appearance/large_crate/einstein + color = COLOR_DARK_BLUE_GRAY + decals = list( + "crate_bracing" + ) + extra_decals = list( + "text" = COLOR_BEIGE + ) + +/decl/closet_appearance/large_crate/nanotrasen + color = COLOR_NT_RED + decals = list( + "crate_bracing" + ) + extra_decals = list( + "text" = COLOR_OFF_WHITE + ) + +/decl/closet_appearance/large_crate/xion + color = COLOR_ORANGE + decals = list( + "crate_bracing" + ) + extra_decals = list( + "text" = COLOR_OFF_WHITE + ) + /decl/closet_appearance/large_crate/secure can_lock = TRUE @@ -835,6 +1288,46 @@ "text_upper" = COLOR_OFF_WHITE ) +/decl/closet_appearance/large_crate/secure/aether + color = COLOR_YELLOW_GRAY + decals = list( + "crate_bracing" + ) + extra_decals = list( + "marking" = COLOR_OFF_WHITE, + "text_upper" = COLOR_BLUE_LIGHT + ) + +/decl/closet_appearance/large_crate/secure/einstein + color = COLOR_DARK_BLUE_GRAY + decals = list( + "crate_bracing" + ) + extra_decals = list( + "marking" = COLOR_OFF_WHITE, + "text_upper" = COLOR_BEIGE + ) + +/decl/closet_appearance/large_crate/secure/heph + color = COLOR_GRAY20 + decals = list( + "crate_bracing" + ) + extra_decals = list( + "marking" = COLOR_NT_RED, + "text_upper" = COLOR_NT_RED + ) + +/decl/closet_appearance/large_crate/secure/xion + color = COLOR_ORANGE + decals = list( + "crate_bracing" + ) + extra_decals = list( + "marking" = COLOR_OFF_WHITE, + "text_upper" = COLOR_OFF_WHITE + ) + // Cabinets. /decl/closet_appearance/cabinet base_icon = 'icons/obj/closets/bases/cabinet.dmi' diff --git a/code/game/objects/structures/crates_lockers/closets/egg_vr.dm b/code/game/objects/structures/crates_lockers/closets/egg_vr.dm index 3efa8ded8b5..ba0809f6381 100644 --- a/code/game/objects/structures/crates_lockers/closets/egg_vr.dm +++ b/code/game/objects/structures/crates_lockers/closets/egg_vr.dm @@ -7,6 +7,7 @@ var/icon_closed = "egg" var/icon_opened = "egg_open" var/icon_locked = "egg" + closet_appearance = null open_sound = 'sound/vore/schlorp.ogg' close_sound = 'sound/vore/schlorp.ogg' opened = 0 diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm index afb8b1c3baa..e1addc7b2f0 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm @@ -4,7 +4,9 @@ starts_with = list( /obj/item/weapon/reagent_containers/food/condiment/flour = 7, - /obj/item/weapon/reagent_containers/food/condiment/sugar = 2) + /obj/item/weapon/reagent_containers/food/condiment/sugar = 2, + /obj/item/weapon/reagent_containers/food/condiment/spacespice = 2 + ) /obj/structure/closet/secure_closet/freezer/kitchen/mining req_access = list() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 5c020b2c6ba..92dfab95477 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -65,7 +65,6 @@ /obj/structure/closet/secure_closet/hos name = "head of security's locker" req_access = list(access_hos) - req_access = list(access_hos) storage_capacity = 2.5 * MOB_MEDIUM closet_appearance = /decl/closet_appearance/secure_closet/security/hos diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index eefc2c324a7..6223061ed88 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -6,6 +6,7 @@ icon = 'icons/obj/closets/bases/crate.dmi' closet_appearance = /decl/closet_appearance/crate climbable = 1 + dir = 4 //Spawn facing 'forward' by default. var/points_per_crate = 5 var/rigged = 0 @@ -65,6 +66,26 @@ update_icon() return 1 +/obj/structure/closet/crate/verb/rotate_clockwise() + set name = "Rotate Crate Clockwise" + set category = "Object" + set src in oview(1) + + if (usr.stat || usr.restrained() || anchored) + return + + src.set_dir(turn(src.dir, 270)) + +/obj/structure/closet/crate/verb/rotate_counterclockwise() + set category = "Object" + set name = "Rotate Crate Counterclockwise" + set src in view(1) + + if (usr.stat || usr.restrained() || anchored) + return + + src.set_dir(turn(src.dir, 90)) + /obj/structure/closet/crate/attackby(obj/item/weapon/W as obj, mob/user as mob) if(opened) if(isrobot(user)) @@ -274,6 +295,14 @@ var/target_temp = T0C - 40 var/cooling_power = 40 +/obj/structure/closet/crate/freezer/centauri + desc = "A freezer stamped with the logo of Centauri Provisions." + closet_appearance = /decl/closet_appearance/crate/freezer/centauri + +/obj/structure/closet/crate/freezer/nanotrasen + desc = "A freezer stamped with the logo of NanoTrasen." + closet_appearance = /decl/closet_appearance/crate/freezer/nanotrasen + /obj/structure/closet/crate/freezer/return_air() var/datum/gas_mixture/gas = (..()) if(!gas) return null @@ -303,6 +332,11 @@ organ.preserved = 0 ..() +/obj/structure/closet/crate/weapon + name = "weapons crate" + desc = "A barely secured weapons crate." + closet_appearance = /decl/closet_appearance/crate/secure/weapon + /obj/structure/closet/crate/freezer/rations //Fpr use in the escape shuttle name = "emergency rations" desc = "A crate of emergency rations." @@ -310,14 +344,12 @@ starts_with = list( /obj/random/mre = 6) - /obj/structure/closet/crate/bin name = "large bin" desc = "A large bin." closet_appearance = null icon = 'icons/obj/closets/largebin.dmi' - /obj/structure/closet/crate/radiation name = "radioactive gear crate" desc = "A crate with a radiation sign on it." @@ -327,45 +359,221 @@ /obj/item/clothing/suit/radiation = 4, /obj/item/clothing/head/radiation = 4) +//TSCs + +/obj/structure/closet/crate/aether + desc = "A crate painted in the colours of Aether Atmospherics and Recycling." + closet_appearance = /decl/closet_appearance/crate/aether + +/obj/structure/closet/crate/centauri + desc = "A crate decorated with the logo of Centauri Provisions." + closet_appearance = /decl/closet_appearance/crate/centauri + +/obj/structure/closet/crate/einstein + desc = "A crate labelled with an Einstein Engines sticker." + closet_appearance = /decl/closet_appearance/crate/einstein + +/obj/structure/closet/crate/focalpoint + desc = "A crate marked with the decal of Focal Point Energistics." + closet_appearance = /decl/closet_appearance/crate/focalpoint + +/obj/structure/closet/crate/gilthari + desc = "A crate embossed with the logo of Gilthari Exports." + closet_appearance = /decl/closet_appearance/crate/gilthari + +/obj/structure/closet/crate/grayson + desc = "A bare metal crate spraypainted with Grayson Manufactories decals." + closet_appearance = /decl/closet_appearance/crate/grayson + +/obj/structure/closet/crate/heph + desc = "A sturdy crate marked with the logo of Hephaestus Industries." + closet_appearance = /decl/closet_appearance/crate/heph + +/obj/structure/closet/crate/morpheus + desc = "A crate crudely imprinted with 'MORPHEUS CYBERKINETICS'." + closet_appearance = /decl/closet_appearance/crate/morpheus + +/obj/structure/closet/crate/nanotrasen + desc = "A crate emblazoned with the standard NanoTrasen livery." + closet_appearance = /decl/closet_appearance/crate/nanotrasen + +/obj/structure/closet/crate/nanothreads + desc = "A crate emblazoned with the NanoThreads Garments livery, a subsidary of the NanoTrasen Corporation." + closet_appearance = /decl/closet_appearance/crate/nanotrasenclothing + +/obj/structure/closet/crate/nanocare + desc = "A crate emblazoned with the NanoCare Medical livery, a subsidary of the NanoTrasen Corporation." + closet_appearance = /decl/closet_appearance/crate/nanotrasenmedical + +/obj/structure/closet/crate/oculum + desc = "A crate minimally decorated with the logo of media giant Oculum Broadcast." + closet_appearance = /decl/closet_appearance/crate/oculum + +/obj/structure/closet/crate/veymed + desc = "A sterile crate extensively detailed in Veymed colours." + closet_appearance = /decl/closet_appearance/crate/veymed + +/obj/structure/closet/crate/ward + desc = "A crate decaled with the logo of Ward-Takahashi." + closet_appearance = /decl/closet_appearance/crate/ward + +/obj/structure/closet/crate/xion + desc = "A crate painted in Xion Manufacturing Group orange." + closet_appearance = /decl/closet_appearance/crate/xion + +/obj/structure/closet/crate/zenghu + desc = "A sterile crate marked with the logo of Zeng-Hu Pharmaceuticals." + closet_appearance = /decl/closet_appearance/crate/zenghu + +// Brands/subsidiaries + +/obj/structure/closet/crate/allico + desc = "A crate painted in the distinctive cheerful colours of AlliCo. Ltd." + closet_appearance = /decl/closet_appearance/crate/allico + +/obj/structure/closet/crate/carp + desc = "A crate painted with the garish livery of Consolidated Agricultural Resources Plc." + closet_appearance = /decl/closet_appearance/crate/carp + +/obj/structure/closet/crate/hedberg + name = "weapons crate" + desc = "A weapons crate stamped with the logo of Hedberg-Hammarstrom and the lock conspicuously absent." + closet_appearance = /decl/closet_appearance/crate/secure/hedberg + +/obj/structure/closet/crate/galaksi + desc = "A crate printed with the markings of Ward-Takahashi's Galaksi Appliance branding." + closet_appearance = /decl/closet_appearance/crate/galaksi + +/obj/structure/closet/crate/thinktronic + desc = "A crate printed with the markings of Thinktronic Systems." + closet_appearance = /decl/closet_appearance/crate/thinktronic + +/obj/structure/closet/crate/ummarcar + desc = "A flimsy crate marked labelled 'UmMarcar Office Supply'." + closet_appearance = /decl/closet_appearance/crate/ummarcar + +/obj/structure/closet/crate/unathi + name = "import crate" + desc = "A crate painted with the markings of Moghes Imported Sissalik Jerky." + closet_appearance = /decl/closet_appearance/crate/unathiimport + + +// Secure Crates /obj/structure/closet/crate/secure/weapon name = "weapons crate" desc = "A secure weapons crate." closet_appearance = /decl/closet_appearance/crate/secure/weapon +/obj/structure/closet/crate/secure/aether + desc = "A secure crate painted in the colours of Aether Atmospherics and Recycling." + closet_appearance = /decl/closet_appearance/crate/secure/aether + +/obj/structure/closet/crate/secure/bishop + desc = "A secure crate finely decorated with the emblem of Bishop Cybernetics." + closet_appearance = /decl/closet_appearance/crate/secure/bishop + +/obj/structure/closet/crate/secure/cybersolutions + desc = "An unadorned secure metal crate labelled 'Cyber Solutions'." + closet_appearance = /decl/closet_appearance/crate/secure/cybersolutions + +/obj/structure/closet/crate/secure/einstein + desc = "A secure crate labelled with an Einstein Engines sticker." + closet_appearance = /decl/closet_appearance/crate/secure/einstein + +/obj/structure/closet/crate/secure/focalpoint + desc = "A secure crate marked with the decal of Focal Point Energistics." + closet_appearance = /decl/closet_appearance/crate/secure/focalpoint + +/obj/structure/closet/crate/secure/gilthari + desc = "A secure crate embossed with the logo of Gilthari Exports." + closet_appearance = /decl/closet_appearance/crate/secure/gilthari + +/obj/structure/closet/crate/secure/grayson + desc = "A secure bare metal crate spraypainted with Grayson Manufactories decals." + closet_appearance = /decl/closet_appearance/crate/secure/grayson + +/obj/structure/closet/crate/secure/hedberg + name = "weapons crate" + desc = "A secure weapons crate stamped with the logo of Hedberg-Hammarstrom." + closet_appearance = /decl/closet_appearance/crate/secure/hedberg + +/obj/structure/closet/crate/secure/heph + name = "weapons crate" + desc = "A secure weapons crate marked with the logo of Hephaestus Industries." + closet_appearance = /decl/closet_appearance/crate/secure/heph + +/obj/structure/closet/crate/secure/lawson + name = "weapons crate" + desc = "A secure weapons crate marked with the logo of Lawson Arms." + closet_appearance = /decl/closet_appearance/crate/secure/lawson + +/obj/structure/closet/crate/secure/morpheus + desc = "A secure crate crudely imprinted with 'MORPHEUS CYBERKINETICS'." + closet_appearance = /decl/closet_appearance/crate/secure/morpheus + +/obj/structure/closet/crate/secure/nanotrasen + desc = "A secure crate emblazoned with the standard NanoTrasen livery." + closet_appearance = /decl/closet_appearance/crate/secure/nanotrasen + +/obj/structure/closet/crate/secure/nanocare + desc = "A secure crate emblazoned with the NanoCare Medical livery, a subsidary of the NanoTrasen Corporation." + closet_appearance = /decl/closet_appearance/crate/secure/nanotrasenmedical + +/obj/structure/closet/crate/secure/scg + name = "weapons crate" + desc = "A secure crate in the official colours of the Solar Confederate Government." + closet_appearance = /decl/closet_appearance/crate/secure/solgov + +/obj/structure/closet/crate/secure/saare + name = "weapons crate" + desc = "A secure weapons crate plainly stamped with the logo of Stealth Assault Enterprises." + closet_appearance = /decl/closet_appearance/crate/secure/saare + +/obj/structure/closet/crate/secure/veymed + desc = "A secure sterile crate extensively detailed in Veymed colours." + closet_appearance = /decl/closet_appearance/crate/secure/veymed + +/obj/structure/closet/crate/secure/ward + desc = "A secure crate decaled with the logo of Ward-Takahashi." + closet_appearance = /decl/closet_appearance/crate/secure/ward + +/obj/structure/closet/crate/secure/xion + desc = "A secure crate painted in Xion Manufacturing Group orange." + closet_appearance = /decl/closet_appearance/crate/secure/xion + +/obj/structure/closet/crate/secure/zenghu + desc = "A secure sterile crate marked with the logo of Zeng-Hu Pharmaceuticals." + closet_appearance = /decl/closet_appearance/crate/secure/zenghu /obj/structure/closet/crate/secure/phoron name = "phoron crate" - desc = "A secure phoron crate." + desc = "A secure phoron crate painted in standard NanoTrasen livery." closet_appearance = /decl/closet_appearance/crate/secure/hazard - /obj/structure/closet/crate/secure/gear name = "gear crate" desc = "A secure gear crate." closet_appearance = /decl/closet_appearance/crate/secure/weapon - /obj/structure/closet/crate/secure/hydrosec name = "secure hydroponics crate" desc = "A crate with a lock on it, painted in the scheme of the station's botanists." closet_appearance = /decl/closet_appearance/crate/secure/hydroponics - /obj/structure/closet/crate/secure/engineering desc = "A crate with a lock on it, painted in the scheme of the station's engineers." name = "secure engineering crate" - /obj/structure/closet/crate/secure/science name = "secure science crate" desc = "A crate with a lock on it, painted in the scheme of the station's scientists." - /obj/structure/closet/crate/secure/bin name = "secure bin" desc = "A secure bin." +// Large crates /obj/structure/closet/crate/large name = "large crate" @@ -391,6 +599,30 @@ break return +/obj/structure/closet/crate/large/critter + name = "animal crate" + desc = "A hefty crate for hauling animals." + closet_appearance = /decl/closet_appearance/large_crate/critter + +/obj/structure/closet/crate/large/aether + name = "large atmospherics crate" + desc = "A hefty metal crate, painted in Aether Atmospherics and Recycling colours." + closet_appearance = /decl/closet_appearance/large_crate/aether + +/obj/structure/closet/crate/large/einstein + name = "large crate" + desc = "A hefty metal crate, painted in Einstein Engines colours." + closet_appearance = /decl/closet_appearance/large_crate/einstein + +/obj/structure/closet/crate/large/nanotrasen + name = "large crate" + desc = "A hefty metal crate, painted in standard NanoTrasen livery." + closet_appearance = /decl/closet_appearance/large_crate/nanotrasen + +/obj/structure/closet/crate/large/xion + name = "large crate" + desc = "A hefty metal crate, painted in Xion Manufacturing Group orange." + closet_appearance = /decl/closet_appearance/large_crate/xion /obj/structure/closet/crate/secure/large name = "large crate" @@ -418,10 +650,30 @@ return -//fluff variant /obj/structure/closet/crate/secure/large/reinforced desc = "A hefty, reinforced metal crate with an electronic locking system." +/obj/structure/closet/crate/secure/large/aether + name = "secure atmospherics crate" + desc = "A hefty metal crate with an electronic locking system, painted in Aether Atmospherics and Recycling colours." + closet_appearance = /decl/closet_appearance/large_crate/secure/aether + +/obj/structure/closet/crate/secure/large/einstein + desc = "A hefty metal crate with an electronic locking system, painted in Einstein Engines colours." + closet_appearance = /decl/closet_appearance/large_crate/secure/einstein + +/obj/structure/closet/crate/large/secure/heph + desc = "A hefty metal crate with an electronic locking system, marked with Hephaestus Industries colours." + closet_appearance = /decl/closet_appearance/large_crate/secure/heph + +/obj/structure/closet/crate/secure/large/nanotrasen + desc = "A hefty metal crate with an electronic locking system, painted in standard NanoTrasen livery." + closet_appearance = /decl/closet_appearance/large_crate/secure/hazard + +/obj/structure/closet/crate/large/secure/xion + desc = "A hefty metal crate with an electronic locking system, painted in Xion Manufacturing Group orange." + closet_appearance = /decl/closet_appearance/large_crate/secure/xion + /obj/structure/closet/crate/engineering name = "engineering crate" diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index 29f1b231aa6..c9909656f4f 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -1,7 +1,7 @@ /obj/structure/largecrate name = "large crate" desc = "A hefty wooden crate." - icon = 'icons/obj/storage_vr.dmi' //VOREStation Edit + icon = 'icons/obj/storage.dmi' icon_state = "densecrate" density = 1 var/list/starts_with @@ -44,8 +44,8 @@ /obj/structure/largecrate/hoverpod name = "\improper Hoverpod assembly crate" - desc = "It comes in a box for the fabricator's sake. Where does the wood come from? ... And why is it lighter?" - icon_state = "mulecrate" + desc = "You aren't sure how this crate is so light, but the Wulf Aeronautics logo might be a hint." + icon_state = "vehiclecrate" /obj/structure/largecrate/hoverpod/attackby(obj/item/weapon/W as obj, mob/user as mob) if(W.is_crowbar()) @@ -60,7 +60,7 @@ /obj/structure/largecrate/vehicle name = "vehicle crate" - desc = "It comes in a box for the consumer's sake. ..How is this lighter?" + desc = "Wulf Aeronautics says it comes in a box for the consumer's sake... How is this so light?" icon_state = "vehiclecrate" /obj/structure/largecrate/vehicle/Initialize() @@ -74,18 +74,22 @@ /obj/structure/largecrate/vehicle/quadbike name = "\improper ATV crate" + desc = "A hefty wooden crate proudly displaying the logo of Ward-Takahashi's automotive division." starts_with = list(/obj/structure/vehiclecage/quadbike) /obj/structure/largecrate/vehicle/quadtrailer name = "\improper ATV trailer crate" + desc = "A hefty wooden crate proudly displaying the logo of Ward-Takahashi's automotive division." starts_with = list(/obj/structure/vehiclecage/quadtrailer) /obj/structure/largecrate/animal - icon_state = "lisacrate" //VOREStation Edit + icon_state = "crittercrate" + desc = "A hefty wooden crate with air holes. It is marked with the logo of NanoTrasen Pastures and the slogan, '90% less cloning defects* than competing brands**, or your money back***!'" /obj/structure/largecrate/animal/mulebot name = "Mulebot crate" - icon_state = "mulecrate" //VOREStation Edit + desc = "A hefty wooden crate labelled 'Proud Product of the Xion Manufacturing Group'" + icon_state = "mulecrate" starts_with = list(/mob/living/bot/mulebot) /obj/structure/largecrate/animal/corgi diff --git a/code/game/objects/structures/ghost_pods/human.dm b/code/game/objects/structures/ghost_pods/human.dm index 2eda9b6c370..246c4b3e654 100644 --- a/code/game/objects/structures/ghost_pods/human.dm +++ b/code/game/objects/structures/ghost_pods/human.dm @@ -121,7 +121,7 @@ H.adjustBruteLoss(rand(1,20)) if(allow_appearance_change) - H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1) + H.change_appearance(APPEARANCE_ALL, H, check_species_whitelist = 1) visible_message("\The [src] [pick("gurgles", "seizes", "clangs")] before releasing \the [H]!") @@ -241,6 +241,6 @@ H.adjustBruteLoss(rand(1,20)) if(allow_appearance_change) - H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1) + H.change_appearance(APPEARANCE_ALL, H, check_species_whitelist = 1) visible_message("\The [src] [pick("gurgles", "seizes", "clangs")] before releasing \the [H]!") diff --git a/code/game/objects/structures/medical_stand_vr.dm b/code/game/objects/structures/medical_stand_vr.dm index e32a1a39df4..eb3031eca80 100644 --- a/code/game/objects/structures/medical_stand_vr.dm +++ b/code/game/objects/structures/medical_stand_vr.dm @@ -423,7 +423,7 @@ return // If the human is losing too much blood, beep. - if(((H.vessel.get_reagent_amount("blood")/H.species.blood_volume)*100) < BLOOD_VOLUME_SAFE) + if(H.vessel.get_reagent_amount("blood") < H.species.blood_volume*H.species.blood_level_safe) visible_message("\The [src] beeps loudly.") var/datum/reagent/B = H.take_blood(beaker,amount) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 4705b39276b..1473c8fe90b 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -7,10 +7,11 @@ density = 0 anchored = 1 var/shattered = 0 - var/list/ui_users = list() var/glass = 1 + var/datum/tgui_module/appearance_changer/mirror/M /obj/structure/mirror/New(var/loc, var/dir, var/building = 0, mob/user as mob) + M = new(src, null) if(building) glass = 0 icon_state = "mirror_frame" @@ -18,17 +19,16 @@ pixel_y = (dir & 3)? (dir == 1 ? -30 : 30) : 0 return +/obj/structure/mirror/Destroy() + QDEL_NULL(M) + . = ..() + /obj/structure/mirror/attack_hand(mob/user as mob) if(!glass) return if(shattered) return if(ishuman(user)) - var/datum/nano_module/appearance_changer/AC = ui_users[user] - if(!AC) - AC = new(src, user) - AC.name = "SalonPro Nano-Mirror™" - ui_users[user] = AC - AC.ui_interact(user) + M.tgui_interact(user) /obj/structure/mirror/proc/shatter() if(!glass) return diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm deleted file mode 100644 index 629bc1c41e9..00000000000 --- a/code/game/objects/structures/noticeboard.dm +++ /dev/null @@ -1,98 +0,0 @@ -/obj/structure/noticeboard - name = "notice board" - desc = "A board for pinning important notices upon." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "nboard00" - density = 0 - anchored = 1 - var/notices = 0 - -/obj/structure/noticeboard/New(var/loc, var/dir, var/building = 0) - ..() - - if(building) - if(loc) - src.loc = loc - - pixel_x = (dir & 3)? 0 : (dir == 4 ? -32 : 32) - pixel_y = (dir & 3)? (dir ==1 ? -27 : 27) : 0 - update_icon() - return - -/obj/structure/noticeboard/Initialize() - for(var/obj/item/I in loc) - if(notices > 4) break - if(istype(I, /obj/item/weapon/paper)) - I.loc = src - notices++ - icon_state = "nboard0[notices]" - . = ..() - -//attaching papers!! -/obj/structure/noticeboard/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob) - if(istype(O, /obj/item/weapon/paper)) - if(notices < 5) - O.add_fingerprint(user) - add_fingerprint(user) - user.drop_from_inventory(O) - O.loc = src - notices++ - icon_state = "nboard0[notices]" //update sprite - to_chat(user, "You pin the paper to the noticeboard.") - else - to_chat(user, "You reach to pin your paper to the board but hesitate. You are certain your paper will not be seen among the many others already attached.") - if(O.is_wrench()) - to_chat(user, "You start to unwrench the noticeboard.") - playsound(src, O.usesound, 50, 1) - if(do_after(user, 15 * O.toolspeed)) - to_chat(user, "You unwrench the noticeboard.") - new /obj/item/frame/noticeboard( src.loc ) - qdel(src) - return - -/obj/structure/noticeboard/attack_hand(var/mob/user) - user.examinate(src) - -// Since Topic() never seems to interact with usr on more than a superficial -// level, it should be fine to let anyone mess with the board other than ghosts. -/obj/structure/noticeboard/examine(var/mob/user) - . = ..() - if(Adjacent(user)) - var/dat = "Noticeboard
" - for(var/obj/item/weapon/paper/P in src) - dat += "[P.name] Write Remove
" - user << browse("Notices[dat]","window=noticeboard") - onclose(user, "noticeboard") - -/obj/structure/noticeboard/Topic(href, href_list) - ..() - usr.set_machine(src) - if(href_list["remove"]) - if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open - return - var/obj/item/P = locate(href_list["remove"]) - if(P && P.loc == src) - P.loc = get_turf(src) //dump paper on the floor because you're a clumsy fuck - P.add_fingerprint(usr) - add_fingerprint(usr) - notices-- - icon_state = "nboard0[notices]" - if(href_list["write"]) - if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open - return - var/obj/item/P = locate(href_list["write"]) - if((P && P.loc == src)) //ifthe paper's on the board - var/mob/living/M = usr - if(istype(M)) - var/obj/item/weapon/pen/E = M.get_type_in_hands(/obj/item/weapon/pen) - if(E) - add_fingerprint(M) - P.attackby(E, usr) - else - to_chat(M, "You'll need something to write with!") - if(href_list["read"]) - var/obj/item/weapon/paper/P = locate(href_list["read"]) - if((P && P.loc == src)) - usr << browse("[P.name][P.info]", "window=[P.name]") - onclose(usr, "[P.name]") - return diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index e994e1b760e..15919a754a5 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -1,3 +1,5 @@ +#define TANK_DISPENSER_CAPACITY 10 + /obj/structure/dispenser name = "tank storage unit" desc = "A simple yet bulky storage device for gas tanks. Has room for up to ten oxygen tanks, and ten phoron tanks." @@ -6,10 +8,8 @@ density = 1 anchored = 1.0 w_class = ITEMSIZE_HUGE - var/oxygentanks = 10 - var/phorontanks = 10 - var/list/oxytanks = list() //sorry for the similar var names - var/list/platanks = list() + var/oxygentanks = TANK_DISPENSER_CAPACITY + var/phorontanks = TANK_DISPENSER_CAPACITY /obj/structure/dispenser/oxygen @@ -19,10 +19,14 @@ oxygentanks = 0 -/obj/structure/dispenser/New() +/obj/structure/dispenser/Initialize() + . = ..() + for(var/i in 1 to oxygentanks) + new /obj/item/weapon/tank/oxygen(src) + for(var/i in 1 to phorontanks) + new /obj/item/weapon/tank/phoron(src) update_icon() - /obj/structure/dispenser/update_icon() overlays.Cut() switch(oxygentanks) @@ -32,49 +36,44 @@ if(1 to 4) overlays += "phoron-[phorontanks]" if(5 to INFINITY) overlays += "phoron-5" -/obj/structure/dispenser/attack_ai(mob/user as mob) +/obj/structure/dispenser/attack_ai(mob/user) + // This looks silly, but robots also call attack_ai, and they're allowed physical state stuff. if(user.Adjacent(src)) return attack_hand(user) ..() -/obj/structure/dispenser/attack_hand(mob/user as mob) - user.set_machine(src) - var/dat = "[src]

" - dat += "Oxygen tanks: [oxygentanks] - [oxygentanks ? "Dispense" : "empty"]
" - dat += "Phoron tanks: [phorontanks] - [phorontanks ? "Dispense" : "empty"]" - user << browse(dat, "window=dispenser") - onclose(user, "dispenser") - return +/obj/structure/dispenser/attack_hand(mob/user) + tgui_interact(user) +/obj/structure/dispenser/tgui_state(mob/user) + return GLOB.tgui_physical_state -/obj/structure/dispenser/attackby(obj/item/I as obj, mob/user as mob) +/obj/structure/dispenser/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TankDispenser", name) + ui.open() + +/obj/structure/dispenser/tgui_data(mob/user) + var/list/data = list() + data["oxygen"] = oxygentanks + data["plasma"] = phorontanks + + return data + +/obj/structure/dispenser/attackby(obj/item/I, mob/user) + var/full if(istype(I, /obj/item/weapon/tank/oxygen) || istype(I, /obj/item/weapon/tank/air) || istype(I, /obj/item/weapon/tank/anesthetic)) - if(oxygentanks < 10) - user.drop_item() - I.loc = src - oxytanks.Add(I) + if(oxygentanks < TANK_DISPENSER_CAPACITY) oxygentanks++ - to_chat(user, "You put [I] in [src].") - if(oxygentanks < 5) - update_icon() else - to_chat(user, "[src] is full.") - updateUsrDialog() - return - if(istype(I, /obj/item/weapon/tank/phoron)) - if(phorontanks < 10) - user.drop_item() - I.loc = src - platanks.Add(I) + full = TRUE + else if(istype(I, /obj/item/weapon/tank/phoron)) + if(phorontanks < TANK_DISPENSER_CAPACITY) phorontanks++ - to_chat(user, "You put [I] in [src].") - if(oxygentanks < 6) - update_icon() else - to_chat(user, "[src] is full.") - updateUsrDialog() - return - if(I.is_wrench()) + full = TRUE + else if(I.is_wrench()) if(anchored) to_chat(user, "You lean down and unwrench [src].") anchored = 0 @@ -82,39 +81,42 @@ to_chat(user, "You wrench [src] into place.") anchored = 1 return - -/obj/structure/dispenser/Topic(href, href_list) - if(usr.stat || usr.restrained()) + else if(user.a_intent != I_HURT) + to_chat(user, "[I] does not fit into [src].") return - if(Adjacent(usr)) - usr.set_machine(src) - if(href_list["oxygen"]) - if(oxygentanks > 0) - var/obj/item/weapon/tank/oxygen/O - if(oxytanks.len == oxygentanks) - O = oxytanks[1] - oxytanks.Remove(O) - else - O = new /obj/item/weapon/tank/oxygen(loc) - O.loc = loc - to_chat(usr, "You take [O] out of [src].") - oxygentanks-- - update_icon() - if(href_list["phoron"]) - if(phorontanks > 0) - var/obj/item/weapon/tank/phoron/P - if(platanks.len == phorontanks) - P = platanks[1] - platanks.Remove(P) - else - P = new /obj/item/weapon/tank/phoron(loc) - P.loc = loc - to_chat(usr, "You take [P] out of [src].") - phorontanks-- - update_icon() - add_fingerprint(usr) - updateUsrDialog() else - usr << browse(null, "window=dispenser") + return ..() + + if(full) + to_chat(user, "[src] can't hold any more of [I].") return - return + + if(!user.unEquip(I, target = src)) + return + to_chat(user, "You put [I] in [src].") + update_icon() + + +/obj/structure/dispenser/tgui_act(action, params) + if(..()) + return + switch(action) + if("plasma") + var/obj/item/weapon/tank/phoron/tank = locate() in src + if(tank && Adjacent(usr)) + usr.put_in_hands(tank) + phorontanks-- + . = TRUE + playsound(src, 'sound/items/drop/gascan.ogg', 100, 1, 1) + if("oxygen") + var/obj/item/weapon/tank/tank = null + for(var/obj/item/weapon/tank/T in src) + if(istype(T, /obj/item/weapon/tank/oxygen) || istype(T, /obj/item/weapon/tank/air) || istype(T, /obj/item/weapon/tank/anesthetic)) + tank = T + break + if(tank && Adjacent(usr)) + usr.put_in_hands(tank) + oxygentanks-- + . = TRUE + playsound(src, 'sound/items/drop/gascan.ogg', 100, 1, 1) + update_icon() \ No newline at end of file diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm index ec2b0eaefab..8dcf567962e 100644 --- a/code/game/objects/structures/trash_pile_vr.dm +++ b/code/game/objects/structures/trash_pile_vr.dm @@ -191,6 +191,13 @@ prob(2);/obj/item/weapon/storage/box/sinpockets, prob(2);/obj/item/weapon/storage/secure/briefcase, prob(2);/obj/item/clothing/under/fluff/latexmaid, + prob(2);/obj/item/toy/tennis, + prob(2);/obj/item/toy/tennis/red, + prob(2);/obj/item/toy/tennis/yellow, + prob(2);/obj/item/toy/tennis/green, + prob(2);/obj/item/toy/tennis/cyan, + prob(2);/obj/item/toy/tennis/blue, + prob(2);/obj/item/toy/tennis/purple, prob(1);/obj/item/clothing/glasses/sunglasses, prob(1);/obj/item/clothing/glasses/welding, prob(1);/obj/item/clothing/gloves/yellow, diff --git a/code/game/objects/stumble_into_vr.dm b/code/game/objects/stumble_into_vr.dm index 1493323af1b..2a747ae5636 100644 --- a/code/game/objects/stumble_into_vr.dm +++ b/code/game/objects/stumble_into_vr.dm @@ -89,7 +89,7 @@ ..() bumpopen(M) -/obj/machinery/cooker/fryer/stumble_into(mob/living/M) +/obj/machinery/appliance/cooker/fryer/stumble_into(mob/living/M) visible_message("[M] [pick("ran", "slammed")] into \the [src]!") M.apply_damage(15, BURN) M.Weaken(5) diff --git a/code/game/sound.dm b/code/game/sound.dm index 7b16e0fd801..c5846c39eb6 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -253,6 +253,10 @@ 'sound/vore/sunesound/prey/death_07.ogg','sound/vore/sunesound/prey/death_08.ogg','sound/vore/sunesound/prey/death_09.ogg', 'sound/vore/sunesound/prey/death_10.ogg') //END VORESTATION EDIT + if ("terminal_type") + soundin = pick('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg', \ + 'sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', \ + 'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg') return soundin //Are these even used? diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index a2f2b62b7f0..12aa7fbcaa3 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -43,6 +43,7 @@ var/list/flooring_types var/descriptor = "tiles" var/flags var/can_paint + var/can_engrave = FALSE var/list/footstep_sounds = list() // key=species name, value = list of sounds, // For instance, footstep_sounds = list("key" = list(sound.ogg)) var/is_plating = FALSE @@ -320,6 +321,7 @@ var/list/flooring_types flags = TURF_REMOVE_CROWBAR | TURF_CAN_BREAK | TURF_CAN_BURN build_type = /obj/item/stack/tile/floor can_paint = 1 + can_engrave = TRUE footstep_sounds = list("human" = list( 'sound/effects/footstep/floor1.ogg', 'sound/effects/footstep/floor2.ogg', @@ -457,7 +459,7 @@ var/list/flooring_types damage_temperature = T0C+200 descriptor = "planks" build_type = /obj/item/stack/tile/wood - flags = TURF_CAN_BREAK | TURF_IS_FRAGILE | TURF_REMOVE_SCREWDRIVER + flags = TURF_CAN_BREAK | TURF_REMOVE_CROWBAR | TURF_REMOVE_SCREWDRIVER footstep_sounds = list("human" = list( 'sound/effects/footstep/wood1.ogg', 'sound/effects/footstep/wood2.ogg', diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm index e835eb21e08..b9f54214e62 100644 --- a/code/game/turfs/flooring/flooring_premade.dm +++ b/code/game/turfs/flooring/flooring_premade.dm @@ -317,6 +317,7 @@ name = "tiles" icon_state = "freezer" initial_flooring = /decl/flooring/tiling/freezer + temperature = T0C - 5 // VOREStation Edit: Chillier Freezer Tiles on-start /turf/simulated/floor/lino name = "lino" diff --git a/code/game/turfs/initialization/maintenance.dm b/code/game/turfs/initialization/maintenance.dm index 7347ec47db8..9f1ed6dc860 100644 --- a/code/game/turfs/initialization/maintenance.dm +++ b/code/game/turfs/initialization/maintenance.dm @@ -28,7 +28,7 @@ var/global/list/random_junk return /obj/effect/decal/cleanable/generic if(!random_junk) random_junk = subtypesof(/obj/item/trash) - random_junk += typesof(/obj/item/weapon/cigbutt) + random_junk += typesof(/obj/item/trash/cigbutt) random_junk += /obj/effect/decal/cleanable/spiderling_remains random_junk += /obj/effect/decal/remains/mouse random_junk += /obj/effect/decal/remains/robot diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 9e48b3777c0..8feb63148ca 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -83,7 +83,7 @@ if (istype(A,/mob/living)) var/mob/living/M = A - if(M.lying) + if(M.lying || M.flying) //VOREStation Edit return ..() if(M.dirties_floor()) diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index ff2923005f3..d5b64f4aade 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -73,6 +73,9 @@ /turf/simulated/floor/proc/make_plating(var/place_product, var/defer_icon_update) cut_overlays() + for(var/obj/effect/decal/writing/W in src) + qdel(W) + name = base_name desc = base_desc icon = base_icon @@ -103,6 +106,9 @@ for(var/obj/O in src) O.hide(O.hides_under_flooring() && floored_over) +/turf/simulated/floor/can_engrave() + return (!flooring || flooring.can_engrave) + /turf/simulated/floor/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) switch(passed_mode) if(RCD_FLOORWALL) diff --git a/code/game/turfs/simulated/floor_attackby.dm b/code/game/turfs/simulated/floor_attackby.dm index df13c2162cf..9aa7ecce6de 100644 --- a/code/game/turfs/simulated/floor_attackby.dm +++ b/code/game/turfs/simulated/floor_attackby.dm @@ -1,4 +1,4 @@ -/turf/simulated/floor/attackby(obj/item/C as obj, mob/user as mob) +/turf/simulated/floor/attackby(var/obj/item/C, var/mob/user) if(!C || !user) return 0 @@ -9,6 +9,9 @@ attack_tile(C, L) // Be on help intent if you want to decon something. return + if(!(C.is_screwdriver() && flooring && (flooring.flags & TURF_REMOVE_SCREWDRIVER)) && try_graffiti(user, C)) + return + if(istype(C, /obj/item/stack/tile/roofing)) var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather var/turf/T = GetAbove(src) diff --git a/code/game/turfs/simulated/wall_attacks.dm b/code/game/turfs/simulated/wall_attacks.dm index 1ef11c40ded..20267696f3e 100644 --- a/code/game/turfs/simulated/wall_attacks.dm +++ b/code/game/turfs/simulated/wall_attacks.dm @@ -135,9 +135,13 @@ return success_smash(user) return fail_smash(user) -/turf/simulated/wall/attackby(obj/item/weapon/W as obj, mob/user as mob) +/turf/simulated/wall/attackby(var/obj/item/weapon/W, var/mob/user) user.setClickCooldown(user.get_attack_speed(W)) + + if(!construction_stage && try_graffiti(user, W)) + return + if (!user.IsAdvancedToolUser()) to_chat(user, "You don't have the dexterity to do this!") return diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 1fc49d58a9d..20c54b8fead 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -305,6 +305,9 @@ for(var/obj/machinery/door/airlock/phoron/D in range(3,src)) D.ignite(temperature/4) +/turf/simulated/wall/can_engrave() + return (material && material.hardness >= 10 && material.hardness <= 100) + /turf/simulated/wall/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) if(material.integrity > 1000) // Don't decon things like elevatorium. return FALSE diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index e93380d7915..626ee68c71f 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -42,7 +42,7 @@ //Lighting related luminosity = !(dynamic_lighting) has_opaque_atom |= (opacity) - + //Pathfinding related if(movement_cost && pathweight == 1) // This updates pathweight automatically. pathweight = movement_cost @@ -285,6 +285,47 @@ turf/attackby(obj/item/weapon/W as obj, mob/user as mob) /turf/AllowDrop() return TRUE +/turf/proc/can_engrave() + return FALSE + +/turf/proc/try_graffiti(var/mob/vandal, var/obj/item/tool) + + if(!tool.sharp || !can_engrave()) + return FALSE + + if(jobban_isbanned(vandal, "Graffiti")) + to_chat(vandal, SPAN_WARNING("You are banned from leaving persistent information across rounds.")) + return + + var/too_much_graffiti = 0 + for(var/obj/effect/decal/writing/W in src) + too_much_graffiti++ + if(too_much_graffiti >= 5) + to_chat(vandal, "There's too much graffiti here to add more.") + return FALSE + + var/message = sanitize(input("Enter a message to engrave.", "Graffiti") as null|text, trim = TRUE) + if(!message) + return FALSE + + if(!vandal || vandal.incapacitated() || !Adjacent(vandal) || !tool.loc == vandal) + return FALSE + + vandal.visible_message("\The [vandal] begins carving something into \the [src].") + + if(!do_after(vandal, max(20, length(message)), src)) + return FALSE + + vandal.visible_message("\The [vandal] carves some graffiti into \the [src].") + var/obj/effect/decal/writing/graffiti = new(src) + graffiti.message = message + graffiti.author = vandal.ckey + + if(lowertext(message) == "elbereth") + to_chat(vandal, "You feel much safer.") + + return TRUE + // Returns false if stepping into a tile would cause harm (e.g. open space while unable to fly, water tile while a slime, lava, etc). /turf/proc/is_safe_to_enter(mob/living/L) if(LAZYLEN(dangerous_objects)) diff --git a/code/game/world.dm b/code/game/world.dm index 7fefc25cca9..628a12f2e59 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -108,6 +108,7 @@ var/world_topic_spam_protect_time = world.timeofday s["version"] = game_version s["mode"] = master_mode s["respawn"] = config.abandon_allowed + s["persistance"] = config.persistence_enabled s["enter"] = config.enter_allowed s["vote"] = config.allow_vote_mode s["ai"] = config.allow_ai @@ -183,12 +184,12 @@ var/world_topic_spam_protect_time = world.timeofday if(!positions["misc"]) positions["misc"] = list() positions["misc"][name] = rank - + for(var/datum/data/record/t in data_core.hidden_general) var/name = t.fields["name"] var/rank = t.fields["rank"] var/real_rank = make_list_rank(t.fields["real_rank"]) - + var/datum/job/J = SSjob.get_job(real_rank) if(J?.offmap_spawn) if(!positions["off"]) @@ -410,6 +411,7 @@ var/world_topic_spam_protect_time = world.timeofday to_world("Rebooting world immediately due to host request") else Master.Shutdown() //run SS shutdowns + //processScheduler.stop() //VOREStation Removal for(var/client/C in GLOB.clients) if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite C << link("byond://[config.server]") @@ -527,6 +529,8 @@ var/world_topic_spam_protect_time = world.timeofday features += config.abandon_allowed ? "respawn" : "no respawn" + features += config.persistence_enabled ? "persistence enabled" : "persistence disabled" + if (config && config.allow_vote_mode) features += "vote" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index cf6ea072f0a..b8abe8619eb 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -933,6 +933,20 @@ var/datum/announcement/minor/admin_min_announcer = new world.update_status() feedback_add_details("admin_verb","TR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/admins/proc/togglepersistence() + set category = "Server" + set desc="Whether persistent data will be saved from now on." + set name="Toggle Persistent Data" + config.persistence_enabled = !(config.persistence_enabled) + if(config.persistence_enabled) + to_world("Persistence is now enabled..") + else + to_world("Persistence is no longer enabled.") + message_admins("[key_name_admin(usr)] toggled persistence to [config.persistence_enabled ? "On" : "Off"].", 1) + log_admin("[key_name(usr)] toggled persistence to [config.persistence_enabled ? "On" : "Off"].") + world.update_status() + feedback_add_details("admin_verb","TPD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + /datum/admins/proc/toggle_aliens() set category = "Server" set desc="Toggle alien mobs" @@ -1454,12 +1468,12 @@ var/datum/announcement/minor/admin_min_announcer = new if(check_rights(R_ADMIN|R_MOD|R_EVENT)) if (H.paralysis == 0) - H.paralysis = 8000 + H.SetParalysis(8000) msg = "has paralyzed [key_name(H)]." log_and_message_admins(msg) else if(alert(src, "[key_name(H)] is paralyzed, would you like to unparalyze them?",,"Yes","No") == "Yes") - H.paralysis = 0 + H.SetParalysis(0) msg = "has unparalyzed [key_name(H)]." log_and_message_admins(msg) diff --git a/code/modules/admin/admin_verb_lists.dm b/code/modules/admin/admin_verb_lists.dm index 63d02af1f70..b576bec44a9 100644 --- a/code/modules/admin/admin_verb_lists.dm +++ b/code/modules/admin/admin_verb_lists.dm @@ -166,6 +166,7 @@ var/list/admin_verbs_server = list( /datum/admins/proc/restart, /datum/admins/proc/delay, /datum/admins/proc/toggleaban, + /datum/admins/proc/togglepersistence, /client/proc/cmd_mod_say, /client/proc/toggle_log_hrefs, /datum/admins/proc/immreboot, @@ -354,6 +355,7 @@ var/list/admin_verbs_mod = list( /client/proc/allow_character_respawn, // Allows a ghost to respawn , /datum/admins/proc/sendFax, /client/proc/getserverlog, //allows us to fetch server logs (diary) for other days, + /datum/admins/proc/view_persistent_data, /datum/admins/proc/view_txt_log, //shows the server log (diary) for today, /datum/admins/proc/view_atk_log //shows the server combat-log, doesn't do anything presently, ) diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm index 1a3781b0c5f..0bfa4e516a2 100644 --- a/code/modules/admin/banjob.dm +++ b/code/modules/admin/banjob.dm @@ -26,14 +26,18 @@ var/jobban_keylist[0] //to store the keys & ranks if(config.usewhitelist && !check_whitelist(M)) return "Whitelisted Job" - for (var/s in jobban_keylist) - if( findtext(s,"[M.ckey] - [rank]") == 1 ) - var/startpos = findtext(s, "## ")+3 - if(startpos && startpos You Cannot issue temporary job-bans!") + to_chat(usr, " You cannot issue temporary job-bans!") return if(config.ban_legacy_system) to_chat(usr, "Your server is using the legacy banning system, which does not support temporary job bans. Consider upgrading. Aborting ban.") diff --git a/code/modules/admin/verbs/change_appearance.dm b/code/modules/admin/verbs/change_appearance.dm index e547d03f840..2f7166a2c07 100644 --- a/code/modules/admin/verbs/change_appearance.dm +++ b/code/modules/admin/verbs/change_appearance.dm @@ -9,7 +9,7 @@ if(!H) return log_and_message_admins("is altering the appearance of [H].") - H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0, state = admin_state) + H.change_appearance(APPEARANCE_ALL, usr, check_species_whitelist = 0, state = GLOB.tgui_admin_state) feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/change_human_appearance_self() @@ -29,10 +29,10 @@ switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel")) if("Yes") log_and_message_admins("has allowed [H] to change [T.his] appearance, without whitelisting of races.") - H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0) + H.change_appearance(APPEARANCE_ALL, H, check_species_whitelist = 0) if("No") log_and_message_admins("has allowed [H] to change [T.his] appearance, with whitelisting of races.") - H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1) + H.change_appearance(APPEARANCE_ALL, H, check_species_whitelist = 1) feedback_add_details("admin_verb","CMAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/editappear() diff --git a/code/modules/ai/ai_holder_targeting.dm b/code/modules/ai/ai_holder_targeting.dm index cacfcf56de3..240d782926e 100644 --- a/code/modules/ai/ai_holder_targeting.dm +++ b/code/modules/ai/ai_holder_targeting.dm @@ -12,7 +12,7 @@ var/vision_range = 7 // How far the targeting system will look for things to kill. Note that values higher than 7 are 'offscreen' and might be unsporting. var/respect_alpha = TRUE // If true, mobs with a sufficently low alpha will be treated as invisible. - var/alpha_vision_threshold = 127 // Targets with an alpha less or equal to this will be considered invisible. Requires above var to be true. + var/alpha_vision_threshold = FAKE_INVIS_ALPHA_THRESHOLD // Targets with an alpha less or equal to this will be considered invisible. Requires above var to be true. var/lose_target_time = 0 // world.time when a target was lost. var/lose_target_timeout = 5 SECONDS // How long until a mob 'times out' and stops trying to find the mob that disappeared. diff --git a/code/modules/alarm/alarm.dm b/code/modules/alarm/alarm.dm index f8d853ca8cd..30de8cc5605 100644 --- a/code/modules/alarm/alarm.dm +++ b/code/modules/alarm/alarm.dm @@ -18,7 +18,6 @@ var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared. var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source. var/list/cameras //List of cameras that can be switched to, if the player has that capability. - var/cache_id //ID for camera cache, changed by invalidateCameraCache(). var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera). var/area/last_name //The last acquired name, used should origin be lost var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated. @@ -78,15 +77,10 @@ return last_name /datum/alarm/proc/cameras() - // reset camera cache - if(camera_repository.camera_cache_id != cache_id) - cameras = null - cache_id = camera_repository.camera_cache_id // If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras - else if(cameras && (last_camera_area != alarm_area())) + if(cameras && (last_camera_area != alarm_area())) cameras = null - // The list of cameras is also reset by /proc/invalidateCameraCache() if(!cameras) cameras = origin ? origin.get_alarm_cameras() : last_area.get_alarm_cameras() diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 3d45fb4e629..cf32d9ad4d8 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -31,58 +31,53 @@ if(holder) holder.update_icon() -/obj/item/device/assembly/signaler/interact(var/mob/user) - var/t1 = "-------" - var/dat = {" - +/obj/item/device/assembly/signaler/interact(mob/user) + if(..()) + return TRUE + tgui_interact(user) -Send Signal
-Frequency/Code for signaler:
-Frequency: -- -- -[format_frequency(src.frequency)] -+ -+
+/obj/item/device/assembly/signaler/tgui_state(mob/user) + return GLOB.tgui_deep_inventory_state -Code: -- -- -[src.code] -+ -+
-[t1] -
"} - user << browse(dat, "window=radio") - onclose(user, "radio") +/obj/item/device/assembly/signaler/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Signaler", name) + ui.open() -/obj/item/device/assembly/signaler/Topic(href, href_list, state = deep_inventory_state) +/obj/item/device/assembly/signaler/tgui_data(mob/user) + var/list/data = list() + data["frequency"] = frequency + data["code"] = code + data["minFrequency"] = RADIO_LOW_FREQ + data["maxFrequency"] = RADIO_HIGH_FREQ + return data + +/obj/item/device/assembly/signaler/tgui_act(action, params) if(..()) return TRUE - if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) - usr << browse(null, "window=radio") - onclose(usr, "radio") - return + switch(action) + if("signal") + INVOKE_ASYNC(src, .proc/signal) + . = TRUE + if("freq") + frequency = unformat_frequency(params["freq"]) + frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) + set_frequency(frequency) + . = TRUE + if("code") + code = text2num(params["code"]) + code = clamp(round(code), 1, 100) + . = TRUE + if("reset") + if(params["reset"] == "freq") + set_frequency(initial(frequency)) + else + code = initial(code) + . = TRUE - if (href_list["freq"]) - var/new_frequency = (frequency + text2num(href_list["freq"])) - if(new_frequency < RADIO_LOW_FREQ || new_frequency > RADIO_HIGH_FREQ) - new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) - set_frequency(new_frequency) - - if(href_list["code"]) - src.code += text2num(href_list["code"]) - src.code = round(src.code) - src.code = min(100, src.code) - src.code = max(1, src.code) - - if(href_list["send"]) - spawn( 0 ) - signal() - - if(usr) - attack_self(usr) + update_icon() /obj/item/device/assembly/signaler/attackby(var/obj/item/weapon/W, mob/user, params) if(issignaler(W)) @@ -109,8 +104,8 @@ Code: /obj/item/device/assembly/signaler/pulse(var/radio = 0) if(is_jammed(src)) return FALSE - if(src.connected && src.wires) - connected.Pulse(src) + if(connected && wires) + connected.pulse_assembly(src) else if(holder) holder.process_activation(src, 1, 0) else diff --git a/code/modules/asset_cache/asset_cache.dm b/code/modules/asset_cache/asset_cache.dm new file mode 100644 index 00000000000..53a30d4299a --- /dev/null +++ b/code/modules/asset_cache/asset_cache.dm @@ -0,0 +1,110 @@ +/* +Asset cache quick users guide: + +Make a datum in asset_list_items.dm with your assets for your thing. +Checkout asset_list.dm for the helper subclasses +The simple subclass will most like be of use for most cases. +Then call get_asset_datum() with the type of the datum you created and store the return +Then call .send(client) on that stored return value. + +Note: If your code uses output() with assets you will need to call asset_flush on the client and wait for it to return before calling output(). You only need do this if .send(client) returned TRUE +*/ + +//When sending mutiple assets, how many before we give the client a quaint little sending resources message +#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8 + +//This proc sends the asset to the client, but only if it needs it. +//This proc blocks(sleeps) unless verify is set to false +/proc/send_asset(client/client, asset_name) + return send_asset_list(client, list(asset_name)) + +/// Sends a list of assets to a client +/// This proc will no longer block, use client.asset_flush() if you to need know when the client has all assets (such as for output()). (This is not required for browse() calls as they use the same message queue as asset sends) +/// client - a client or mob +/// asset_list - A list of asset filenames to be sent to the client. +/// Returns TRUE if any assets were sent. +/proc/send_asset_list(client/client, list/asset_list) + if(!istype(client)) + if(ismob(client)) + var/mob/M = client + if(M.client) + client = M.client + else + return + else + return + + var/list/unreceived = list() + + for (var/asset_name in asset_list) + var/datum/asset_cache_item/asset = SSassets.cache[asset_name] + if (!asset) + continue + var/asset_file = asset.resource + if (!asset_file) + continue + + var/asset_md5 = asset.md5 + if (client.sent_assets[asset_name] == asset_md5) + continue + unreceived[asset_name] = asset_md5 + + if (unreceived.len) + if (unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT) + to_chat(client, "Sending Resources...") + + for(var/asset in unreceived) + var/datum/asset_cache_item/ACI + if ((ACI = SSassets.cache[asset])) + log_asset("Sending asset [asset] to client [client]") + client << browse_rsc(ACI.resource, asset) + + client.sent_assets |= unreceived + addtimer(CALLBACK(client, /client/proc/asset_cache_update_json), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) + return TRUE + return FALSE + +//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start. +//The proc calls procs that sleep for long times. +/proc/getFilesSlow(client/client, list/files, register_asset = TRUE, filerate = 3) + var/startingfilerate = filerate + for(var/file in files) + if (!client) + break + if (register_asset) + register_asset(file, files[file]) + + if (send_asset(client, file)) + if (!(--filerate)) + filerate = startingfilerate + client.asset_flush() + stoplag(0) //queuing calls like this too quickly can cause issues in some client versions + +//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up. +//icons and virtual assets get copied to the dyn rsc before use +/proc/register_asset(asset_name, asset) + var/datum/asset_cache_item/ACI = new(asset_name, asset) + + //this is technically never something that was supported and i want metrics on how often it happens if at all. + if (SSassets.cache[asset_name]) + var/datum/asset_cache_item/OACI = SSassets.cache[asset_name] + if (OACI.md5 != ACI.md5) + stack_trace("ERROR: new asset added to the asset cache with the same name as another asset: [asset_name] existing asset md5: [OACI.md5] new asset md5:[ACI.md5]") + else + var/list/stacktrace = gib_stack_trace() + log_asset("WARNING: dupe asset added to the asset cache: [asset_name] existing asset md5: [OACI.md5] new asset md5:[ACI.md5]\n[stacktrace.Join("\n")]") + SSassets.cache[asset_name] = ACI + return ACI + +/// Returns the url of the asset, currently this is just its name, here to allow further work cdn'ing assets. +/// Can be given an asset as well, this is just a work around for buggy edge cases where two assets may have the same name, doesn't matter now, but it will when the cdn comes. +/proc/get_asset_url(asset_name, asset = null) + var/datum/asset_cache_item/ACI = SSassets.cache[asset_name] + return ACI?.url + +//Generated names do not include file extention. +//Used mainly for code that deals with assets in a generic way +//The same asset will always lead to the same asset name +/proc/generate_asset_name(file) + return "asset.[md5(fcopy_rsc(file))]" + diff --git a/code/modules/asset_cache/asset_cache_client.dm b/code/modules/asset_cache/asset_cache_client.dm new file mode 100644 index 00000000000..0f51520f13a --- /dev/null +++ b/code/modules/asset_cache/asset_cache_client.dm @@ -0,0 +1,51 @@ + +/// Process asset cache client topic calls for "asset_cache_confirm_arrival=[INT]" +/client/proc/asset_cache_confirm_arrival(job_id) + var/asset_cache_job = round(text2num(job_id)) + //because we skip the limiter, we have to make sure this is a valid arrival and not somebody tricking us into letting them append to a list without limit. + if (asset_cache_job > 0 && asset_cache_job <= last_asset_job && !(completed_asset_jobs["[asset_cache_job]"])) + completed_asset_jobs["[asset_cache_job]"] = TRUE + last_completed_asset_job = max(last_completed_asset_job, asset_cache_job) + else + return asset_cache_job || TRUE + + +/// Process asset cache client topic calls for "asset_cache_preload_data=[HTML+JSON_STRING] +/client/proc/asset_cache_preload_data(data) + /*var/jsonend = findtextEx(data, "{{{ENDJSONDATA}}}") + if (!jsonend) + CRASH("invalid asset_cache_preload_data, no jsonendmarker")*/ + //var/json = html_decode(copytext(data, 1, jsonend)) + var/json = data + var/list/preloaded_assets = json_decode(json) + + for (var/preloaded_asset in preloaded_assets) + if (copytext(preloaded_asset, findlasttext(preloaded_asset, ".")+1) in list("js", "jsm", "htm", "html")) + preloaded_assets -= preloaded_asset + continue + sent_assets |= preloaded_assets + + +/// Updates the client side stored html/json combo file used to keep track of what assets the client has between restarts/reconnects. +/client/proc/asset_cache_update_json(verify = FALSE, list/new_assets = list()) + if (world.time - connection_time < 10 SECONDS) //don't override the existing data file on a new connection + return + if (!islist(new_assets)) + new_assets = list("[new_assets]" = md5(SSassets.cache[new_assets])) + + src << browse(json_encode(new_assets|sent_assets), "file=asset_data.json&display=0") + +/// Blocks until all currently sending browser assets have been sent. +/// Due to byond limitations, this proc will sleep for 1 client round trip even if the client has no pending asset sends. +/// This proc will return an untrue value if it had to return before confirming the send, such as timeout or the client going away. +/client/proc/asset_flush(timeout = 50) + var/job = ++last_asset_job + var/t = 0 + var/timeout_time = timeout + src << browse({""}, "window=asset_cache_browser&file=asset_cache_send_verify.htm") + + while(!completed_asset_jobs["[job]"] && t < timeout_time) // Reception is handled in Topic() + stoplag(1) // Lock up the caller until this is received. + t++ + if (t < timeout_time) + return TRUE diff --git a/code/modules/asset_cache/asset_cache_item.dm b/code/modules/asset_cache/asset_cache_item.dm new file mode 100644 index 00000000000..5f02e561c6f --- /dev/null +++ b/code/modules/asset_cache/asset_cache_item.dm @@ -0,0 +1,23 @@ +/** + * # asset_cache_item + * + * An internal datum containing info on items in the asset cache. Mainly used to cache md5 info for speed. +**/ +/datum/asset_cache_item + var/name + var/url + var/md5 + var/resource + +/datum/asset_cache_item/New(name, file) + if (!isfile(file)) + file = fcopy_rsc(file) + md5 = md5(file) + if (!md5) + md5 = md5(fcopy_rsc(file)) + if (!md5) + CRASH("invalid asset sent to asset cache") + log_world("asset cache unexpected success of second fcopy_rsc") + src.name = name + url = name + resource = file diff --git a/code/modules/asset_cache/asset_list.dm b/code/modules/asset_cache/asset_list.dm new file mode 100644 index 00000000000..5cc16d06bc7 --- /dev/null +++ b/code/modules/asset_cache/asset_list.dm @@ -0,0 +1,260 @@ + +//These datums are used to populate the asset cache, the proc "register()" does this. +//Place any asset datums you create in asset_list_items.dm + +//all of our asset datums, used for referring to these later +GLOBAL_LIST_EMPTY(asset_datums) + +//get an assetdatum or make a new one +/proc/get_asset_datum(type) + return GLOB.asset_datums[type] || new type() + +/datum/asset + var/_abstract = /datum/asset + +/datum/asset/New() + GLOB.asset_datums[type] = src + register() + +/datum/asset/proc/get_url_mappings() + return list() + +/datum/asset/proc/register() + return + +/datum/asset/proc/send(client) + return + + +//If you don't need anything complicated. +/datum/asset/simple + _abstract = /datum/asset/simple + var/assets = list() + +/datum/asset/simple/register() + for(var/asset_name in assets) + assets[asset_name] = register_asset(asset_name, assets[asset_name]) + +/datum/asset/simple/send(client) + . = send_asset_list(client, assets) + +/datum/asset/simple/get_url_mappings() + . = list() + for (var/asset_name in assets) + var/datum/asset_cache_item/ACI = assets[asset_name] + if (!ACI) + continue + .[asset_name] = ACI.url + + +// For registering or sending multiple others at once +/datum/asset/group + _abstract = /datum/asset/group + var/list/children + +/datum/asset/group/register() + for(var/type in children) + get_asset_datum(type) + +/datum/asset/group/send(client/C) + for(var/type in children) + var/datum/asset/A = get_asset_datum(type) + . = A.send(C) || . + +/datum/asset/group/get_url_mappings() + . = list() + for(var/type in children) + var/datum/asset/A = get_asset_datum(type) + . += A.get_url_mappings() + +// spritesheet implementation - coalesces various icons into a single .png file +// and uses CSS to select icons out of that file - saves on transferring some +// 1400-odd individual PNG files +#define SPR_SIZE 1 +#define SPR_IDX 2 +#define SPRSZ_COUNT 1 +#define SPRSZ_ICON 2 +#define SPRSZ_STRIPPED 3 + +/datum/asset/spritesheet + _abstract = /datum/asset/spritesheet + var/name + var/list/sizes = list() // "32x32" -> list(10, icon/normal, icon/stripped) + var/list/sprites = list() // "foo_bar" -> list("32x32", 5) + +/datum/asset/spritesheet/register() + if (!name) + CRASH("spritesheet [type] cannot register without a name") + ensure_stripped() + for(var/size_id in sizes) + var/size = sizes[size_id] + register_asset("[name]_[size_id].png", size[SPRSZ_STRIPPED]) + var/res_name = "spritesheet_[name].css" + var/fname = "data/spritesheets/[res_name]" + fdel(fname) + text2file(generate_css(), fname) + register_asset(res_name, fcopy_rsc(fname)) + fdel(fname) + +/datum/asset/spritesheet/send(client/C) + if (!name) + return + var/all = list("spritesheet_[name].css") + for(var/size_id in sizes) + all += "[name]_[size_id].png" + . = send_asset_list(C, all) + +/datum/asset/spritesheet/get_url_mappings() + if (!name) + return + . = list("spritesheet_[name].css" = get_asset_url("spritesheet_[name].css")) + for(var/size_id in sizes) + .["[name]_[size_id].png"] = get_asset_url("[name]_[size_id].png") + + + +/datum/asset/spritesheet/proc/ensure_stripped(sizes_to_strip = sizes) + for(var/size_id in sizes_to_strip) + var/size = sizes[size_id] + if (size[SPRSZ_STRIPPED]) + continue + + #ifdef RUST_G + // save flattened version + var/fname = "data/spritesheets/[name]_[size_id].png" + fcopy(size[SPRSZ_ICON], fname) + var/error = call(RUST_G, "dmi_strip_metadata")(fname) + if(length(error)) + stack_trace("Failed to strip [name]_[size_id].png: [error]") + size[SPRSZ_STRIPPED] = icon(fname) + fdel(fname) + #else + #warn It looks like you don't have RUST_G enabled. Without RUST_G, the RPD icons will not function, so it strongly recommended you reenable it. + #endif + +/datum/asset/spritesheet/proc/generate_css() + var/list/out = list() + + for (var/size_id in sizes) + var/size = sizes[size_id] + var/icon/tiny = size[SPRSZ_ICON] + out += ".[name][size_id]{display:inline-block;width:[tiny.Width()]px;height:[tiny.Height()]px;background:url('[get_asset_url("[name]_[size_id].png")]') no-repeat;}" + + for (var/sprite_id in sprites) + var/sprite = sprites[sprite_id] + var/size_id = sprite[SPR_SIZE] + var/idx = sprite[SPR_IDX] + var/size = sizes[size_id] + + var/icon/tiny = size[SPRSZ_ICON] + var/icon/big = size[SPRSZ_STRIPPED] + var/per_line = big.Width() / tiny.Width() + var/x = (idx % per_line) * tiny.Width() + var/y = round(idx / per_line) * tiny.Height() + + out += ".[name][size_id].[sprite_id]{background-position:-[x]px -[y]px;}" + + return out.Join("\n") + +/datum/asset/spritesheet/proc/Insert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE) + I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving) + if (!I || !length(icon_states(I))) // that direction or state doesn't exist + return + var/size_id = "[I.Width()]x[I.Height()]" + var/size = sizes[size_id] + + if (sprites[sprite_name]) + CRASH("duplicate sprite \"[sprite_name]\" in sheet [name] ([type])") + + if (size) + var/position = size[SPRSZ_COUNT]++ + var/icon/sheet = size[SPRSZ_ICON] + size[SPRSZ_STRIPPED] = null + sheet.Insert(I, icon_state=sprite_name) + sprites[sprite_name] = list(size_id, position) + else + sizes[size_id] = size = list(1, I, null) + sprites[sprite_name] = list(size_id, 0) + +/datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions) + if (length(prefix)) + prefix = "[prefix]-" + + if (!directions) + directions = list(SOUTH) + + for (var/icon_state_name in icon_states(I)) + for (var/direction in directions) + var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]-" : "" + Insert("[prefix][prefix2][icon_state_name]", I, icon_state=icon_state_name, dir=direction) + +/datum/asset/spritesheet/proc/css_tag() + return {""} + +/datum/asset/spritesheet/proc/css_filename() + return get_asset_url("spritesheet_[name].css") + +/datum/asset/spritesheet/proc/icon_tag(sprite_name) + var/sprite = sprites[sprite_name] + if (!sprite) + return null + var/size_id = sprite[SPR_SIZE] + return {""} + +/datum/asset/spritesheet/proc/icon_class_name(sprite_name) + var/sprite = sprites[sprite_name] + if (!sprite) + return null + var/size_id = sprite[SPR_SIZE] + return {"[name][size_id] [sprite_name]"} + +#undef SPR_SIZE +#undef SPR_IDX +#undef SPRSZ_COUNT +#undef SPRSZ_ICON +#undef SPRSZ_STRIPPED + + +/datum/asset/spritesheet/simple + _abstract = /datum/asset/spritesheet/simple + var/list/assets + +/datum/asset/spritesheet/simple/register() + for (var/key in assets) + Insert(key, assets[key]) + ..() + +//Generates assets based on iconstates of a single icon +/datum/asset/simple/icon_states + _abstract = /datum/asset/simple/icon_states + var/icon + var/list/directions = list(SOUTH) + var/frame = 1 + var/movement_states = FALSE + + var/prefix = "default" //asset_name = "[prefix].[icon_state_name].png" + var/generic_icon_names = FALSE //generate icon filenames using generate_asset_name() instead the above format + +/datum/asset/simple/icon_states/register(_icon = icon) + for(var/icon_state_name in icon_states(_icon)) + for(var/direction in directions) + var/asset = icon(_icon, icon_state_name, direction, frame, movement_states) + if (!asset) + continue + asset = fcopy_rsc(asset) //dedupe + var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]." : "" + var/asset_name = sanitize_filename("[prefix].[prefix2][icon_state_name].png") + if (generic_icon_names) + asset_name = "[generate_asset_name(asset)].png" + + register_asset(asset_name, asset) + +/datum/asset/simple/icon_states/multiple_icons + _abstract = /datum/asset/simple/icon_states/multiple_icons + var/list/icons + +/datum/asset/simple/icon_states/multiple_icons/register() + for(var/i in icons) + ..(i) + + diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm new file mode 100644 index 00000000000..64b76184e5c --- /dev/null +++ b/code/modules/asset_cache/asset_list_items.dm @@ -0,0 +1,490 @@ +//DEFINITIONS FOR ASSET DATUMS START HERE. + +/datum/asset/simple/tgui + assets = list( + "tgui.bundle.js" = 'tgui/packages/tgui/public/tgui.bundle.js', + "tgui.bundle.css" = 'tgui/packages/tgui/public/tgui.bundle.css', + ) + +// /datum/asset/simple/headers +// assets = list( +// "alarm_green.gif" = 'icons/program_icons/alarm_green.gif', +// "alarm_red.gif" = 'icons/program_icons/alarm_red.gif', +// "batt_5.gif" = 'icons/program_icons/batt_5.gif', +// "batt_20.gif" = 'icons/program_icons/batt_20.gif', +// "batt_40.gif" = 'icons/program_icons/batt_40.gif', +// "batt_60.gif" = 'icons/program_icons/batt_60.gif', +// "batt_80.gif" = 'icons/program_icons/batt_80.gif', +// "batt_100.gif" = 'icons/program_icons/batt_100.gif', +// "charging.gif" = 'icons/program_icons/charging.gif', +// "downloader_finished.gif" = 'icons/program_icons/downloader_finished.gif', +// "downloader_running.gif" = 'icons/program_icons/downloader_running.gif', +// "ntnrc_idle.gif" = 'icons/program_icons/ntnrc_idle.gif', +// "ntnrc_new.gif" = 'icons/program_icons/ntnrc_new.gif', +// "power_norm.gif" = 'icons/program_icons/power_norm.gif', +// "power_warn.gif" = 'icons/program_icons/power_warn.gif', +// "sig_high.gif" = 'icons/program_icons/sig_high.gif', +// "sig_low.gif" = 'icons/program_icons/sig_low.gif', +// "sig_lan.gif" = 'icons/program_icons/sig_lan.gif', +// "sig_none.gif" = 'icons/program_icons/sig_none.gif', +// "smmon_0.gif" = 'icons/program_icons/smmon_0.gif', +// "smmon_1.gif" = 'icons/program_icons/smmon_1.gif', +// "smmon_2.gif" = 'icons/program_icons/smmon_2.gif', +// "smmon_3.gif" = 'icons/program_icons/smmon_3.gif', +// "smmon_4.gif" = 'icons/program_icons/smmon_4.gif', +// "smmon_5.gif" = 'icons/program_icons/smmon_5.gif', +// "smmon_6.gif" = 'icons/program_icons/smmon_6.gif', +// "borg_mon.gif" = 'icons/program_icons/borg_mon.gif' +// ) + +// /datum/asset/simple/radar_assets +// assets = list( +// "ntosradarbackground.png" = 'icons/UI_Icons/tgui/ntosradar_background.png', +// "ntosradarpointer.png" = 'icons/UI_Icons/tgui/ntosradar_pointer.png', +// "ntosradarpointerS.png" = 'icons/UI_Icons/tgui/ntosradar_pointer_S.png' +// ) + +// /datum/asset/spritesheet/simple/pda +// name = "pda" +// assets = list( +// "atmos" = 'icons/pda_icons/pda_atmos.png', +// "back" = 'icons/pda_icons/pda_back.png', +// "bell" = 'icons/pda_icons/pda_bell.png', +// "blank" = 'icons/pda_icons/pda_blank.png', +// "boom" = 'icons/pda_icons/pda_boom.png', +// "bucket" = 'icons/pda_icons/pda_bucket.png', +// "medbot" = 'icons/pda_icons/pda_medbot.png', +// "floorbot" = 'icons/pda_icons/pda_floorbot.png', +// "cleanbot" = 'icons/pda_icons/pda_cleanbot.png', +// "crate" = 'icons/pda_icons/pda_crate.png', +// "cuffs" = 'icons/pda_icons/pda_cuffs.png', +// "eject" = 'icons/pda_icons/pda_eject.png', +// "flashlight" = 'icons/pda_icons/pda_flashlight.png', +// "honk" = 'icons/pda_icons/pda_honk.png', +// "mail" = 'icons/pda_icons/pda_mail.png', +// "medical" = 'icons/pda_icons/pda_medical.png', +// "menu" = 'icons/pda_icons/pda_menu.png', +// "mule" = 'icons/pda_icons/pda_mule.png', +// "notes" = 'icons/pda_icons/pda_notes.png', +// "power" = 'icons/pda_icons/pda_power.png', +// "rdoor" = 'icons/pda_icons/pda_rdoor.png', +// "reagent" = 'icons/pda_icons/pda_reagent.png', +// "refresh" = 'icons/pda_icons/pda_refresh.png', +// "scanner" = 'icons/pda_icons/pda_scanner.png', +// "signaler" = 'icons/pda_icons/pda_signaler.png', +// "skills" = 'icons/pda_icons/pda_skills.png', +// "status" = 'icons/pda_icons/pda_status.png', +// "dronephone" = 'icons/pda_icons/pda_dronephone.png', +// "emoji" = 'icons/pda_icons/pda_emoji.png' +// ) + +// /datum/asset/spritesheet/simple/paper +// name = "paper" +// assets = list( +// "stamp-clown" = 'icons/stamp_icons/large_stamp-clown.png', +// "stamp-deny" = 'icons/stamp_icons/large_stamp-deny.png', +// "stamp-ok" = 'icons/stamp_icons/large_stamp-ok.png', +// "stamp-hop" = 'icons/stamp_icons/large_stamp-hop.png', +// "stamp-cmo" = 'icons/stamp_icons/large_stamp-cmo.png', +// "stamp-ce" = 'icons/stamp_icons/large_stamp-ce.png', +// "stamp-hos" = 'icons/stamp_icons/large_stamp-hos.png', +// "stamp-rd" = 'icons/stamp_icons/large_stamp-rd.png', +// "stamp-cap" = 'icons/stamp_icons/large_stamp-cap.png', +// "stamp-qm" = 'icons/stamp_icons/large_stamp-qm.png', +// "stamp-law" = 'icons/stamp_icons/large_stamp-law.png', +// "stamp-chap" = 'icons/stamp_icons/large_stamp-chap.png', +// "stamp-mime" = 'icons/stamp_icons/large_stamp-mime.png', +// "stamp-centcom" = 'icons/stamp_icons/large_stamp-centcom.png', +// "stamp-syndicate" = 'icons/stamp_icons/large_stamp-syndicate.png' +// ) + + +// /datum/asset/simple/irv +// assets = list( +// "jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js', +// ) + +// /datum/asset/group/irv +// children = list( +// /datum/asset/simple/jquery, +// /datum/asset/simple/irv +// ) + +/datum/asset/simple/generic + assets = list( + "search.js" = 'html/search.js', + "panels.css" = 'html/panels.css', + "loading.gif" = 'html/images/loading.gif', + "ntlogo.png" = 'html/images/ntlogo.png', + "sglogo.png" = 'html/images/sglogo.png', + "talisman.png" = 'html/images/talisman.png', + "paper_bg.png" = 'html/images/paper_bg.png', + "no_image32.png" = 'html/images/no_image32.png', + ) + +/datum/asset/simple/changelog + assets = list( + "88x31.png" = 'html/88x31.png', + "bug-minus.png" = 'html/bug-minus.png', + "cross-circle.png" = 'html/cross-circle.png', + "hard-hat-exclamation.png" = 'html/hard-hat-exclamation.png', + "image-minus.png" = 'html/image-minus.png', + "image-plus.png" = 'html/image-plus.png', + "map-pencil.png" = 'html/map-pencil.png', + "music-minus.png" = 'html/music-minus.png', + "music-plus.png" = 'html/music-plus.png', + "tick-circle.png" = 'html/tick-circle.png', + "wrench-screwdriver.png" = 'html/wrench-screwdriver.png', + "spell-check.png" = 'html/spell-check.png', + "burn-exclamation.png" = 'html/burn-exclamation.png', + "chevron.png" = 'html/chevron.png', + "chevron-expand.png" = 'html/chevron-expand.png', + "changelog.css" = 'html/changelog.css', + "changelog.js" = 'html/changelog.js', + "changelog.html" = 'html/changelog.html' + ) + +// /datum/asset/group/goonchat +// children = list( +// /datum/asset/simple/jquery, +// /datum/asset/simple/goonchat, +// /datum/asset/spritesheet/goonchat, +// /datum/asset/simple/fontawesome +// ) + +// /datum/asset/simple/jquery +// assets = list( +// "jquery.min.js" = 'code/modules/goonchat/browserassets/js/jquery.min.js', +// ) + +// /datum/asset/simple/goonchat +// assets = list( +// "json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js', +// "browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js', +// "browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css', +// "browserOutput_white.css" = 'code/modules/goonchat/browserassets/css/browserOutput_white.css', +// ) + +/datum/asset/simple/fontawesome + assets = list( + "fa-regular-400.eot" = 'html/font-awesome/webfonts/fa-regular-400.eot', + "fa-regular-400.woff" = 'html/font-awesome/webfonts/fa-regular-400.woff', + "fa-solid-900.eot" = 'html/font-awesome/webfonts/fa-solid-900.eot', + "fa-solid-900.woff" = 'html/font-awesome/webfonts/fa-solid-900.woff', + "font-awesome.css" = 'html/font-awesome/css/all.min.css', + "v4shim.css" = 'html/font-awesome/css/v4-shims.min.css' + ) + +// /datum/asset/spritesheet/goonchat +// name = "chat" + +// /datum/asset/spritesheet/goonchat/register() +// InsertAll("emoji", 'icons/emoji.dmi') + +// // pre-loading all lanugage icons also helps to avoid meta +// InsertAll("language", 'icons/misc/language.dmi') +// // catch languages which are pulling icons from another file +// for(var/path in typesof(/datum/language)) +// var/datum/language/L = path +// var/icon = initial(L.icon) +// if (icon != 'icons/misc/language.dmi') +// var/icon_state = initial(L.icon_state) +// Insert("language-[icon_state]", icon, icon_state=icon_state) + +// ..() + +// /datum/asset/simple/permissions +// assets = list( +// "padlock.png" = 'html/padlock.png' +// ) + +// /datum/asset/simple/notes +// assets = list( +// "high_button.png" = 'html/high_button.png', +// "medium_button.png" = 'html/medium_button.png', +// "minor_button.png" = 'html/minor_button.png', +// "none_button.png" = 'html/none_button.png', +// ) + +// /datum/asset/simple/arcade +// assets = list( +// "boss1.gif" = 'icons/UI_Icons/Arcade/boss1.gif', +// "boss2.gif" = 'icons/UI_Icons/Arcade/boss2.gif', +// "boss3.gif" = 'icons/UI_Icons/Arcade/boss3.gif', +// "boss4.gif" = 'icons/UI_Icons/Arcade/boss4.gif', +// "boss5.gif" = 'icons/UI_Icons/Arcade/boss5.gif', +// "boss6.gif" = 'icons/UI_Icons/Arcade/boss6.gif', +// ) + +// /datum/asset/spritesheet/simple/achievements +// name ="achievements" +// assets = list( +// "default" = 'icons/UI_Icons/Achievements/default.png', +// "basemisc" = 'icons/UI_Icons/Achievements/basemisc.png', +// "baseboss" = 'icons/UI_Icons/Achievements/baseboss.png', +// "baseskill" = 'icons/UI_Icons/Achievements/baseskill.png', +// "bbgum" = 'icons/UI_Icons/Achievements/Boss/bbgum.png', +// "colossus" = 'icons/UI_Icons/Achievements/Boss/colossus.png', +// "hierophant" = 'icons/UI_Icons/Achievements/Boss/hierophant.png', +// "legion" = 'icons/UI_Icons/Achievements/Boss/legion.png', +// "miner" = 'icons/UI_Icons/Achievements/Boss/miner.png', +// "swarmer" = 'icons/UI_Icons/Achievements/Boss/swarmer.png', +// "tendril" = 'icons/UI_Icons/Achievements/Boss/tendril.png', +// "featofstrength" = 'icons/UI_Icons/Achievements/Misc/featofstrength.png', +// "helbital" = 'icons/UI_Icons/Achievements/Misc/helbital.png', +// "jackpot" = 'icons/UI_Icons/Achievements/Misc/jackpot.png', +// "meteors" = 'icons/UI_Icons/Achievements/Misc/meteors.png', +// "timewaste" = 'icons/UI_Icons/Achievements/Misc/timewaste.png', +// "upgrade" = 'icons/UI_Icons/Achievements/Misc/upgrade.png', +// "clownking" = 'icons/UI_Icons/Achievements/Misc/clownking.png', +// "clownthanks" = 'icons/UI_Icons/Achievements/Misc/clownthanks.png', +// "rule8" = 'icons/UI_Icons/Achievements/Misc/rule8.png', +// "snail" = 'icons/UI_Icons/Achievements/Misc/snail.png', +// "mining" = 'icons/UI_Icons/Achievements/Skills/mining.png', +// ) + +// /datum/asset/spritesheet/simple/pills +// name ="pills" +// assets = list( +// "pill1" = 'icons/UI_Icons/Pills/pill1.png', +// "pill2" = 'icons/UI_Icons/Pills/pill2.png', +// "pill3" = 'icons/UI_Icons/Pills/pill3.png', +// "pill4" = 'icons/UI_Icons/Pills/pill4.png', +// "pill5" = 'icons/UI_Icons/Pills/pill5.png', +// "pill6" = 'icons/UI_Icons/Pills/pill6.png', +// "pill7" = 'icons/UI_Icons/Pills/pill7.png', +// "pill8" = 'icons/UI_Icons/Pills/pill8.png', +// "pill9" = 'icons/UI_Icons/Pills/pill9.png', +// "pill10" = 'icons/UI_Icons/Pills/pill10.png', +// "pill11" = 'icons/UI_Icons/Pills/pill11.png', +// "pill12" = 'icons/UI_Icons/Pills/pill12.png', +// "pill13" = 'icons/UI_Icons/Pills/pill13.png', +// "pill14" = 'icons/UI_Icons/Pills/pill14.png', +// "pill15" = 'icons/UI_Icons/Pills/pill15.png', +// "pill16" = 'icons/UI_Icons/Pills/pill16.png', +// "pill17" = 'icons/UI_Icons/Pills/pill17.png', +// "pill18" = 'icons/UI_Icons/Pills/pill18.png', +// "pill19" = 'icons/UI_Icons/Pills/pill19.png', +// "pill20" = 'icons/UI_Icons/Pills/pill20.png', +// "pill21" = 'icons/UI_Icons/Pills/pill21.png', +// "pill22" = 'icons/UI_Icons/Pills/pill22.png', +// ) + +// //this exists purely to avoid meta by pre-loading all language icons. +// /datum/asset/language/register() +// for(var/path in typesof(/datum/language)) +// set waitfor = FALSE +// var/datum/language/L = new path () +// L.get_icon() + +/datum/asset/spritesheet/pipes + name = "pipes" + +/datum/asset/spritesheet/pipes/register() + for(var/each in list('icons/obj/pipe-item.dmi', 'icons/obj/pipes/disposal.dmi')) + InsertAll("", each, global.alldirs) + ..() + +// // Representative icons for each research design +// /datum/asset/spritesheet/research_designs +// name = "design" + +// /datum/asset/spritesheet/research_designs/register() +// for (var/path in subtypesof(/datum/design)) +// var/datum/design/D = path + +// var/icon_file +// var/icon_state +// var/icon/I + +// if(initial(D.research_icon) && initial(D.research_icon_state)) //If the design has an icon replacement skip the rest +// icon_file = initial(D.research_icon) +// icon_state = initial(D.research_icon_state) +// if(!(icon_state in icon_states(icon_file))) +// warning("design [D] with icon '[icon_file]' missing state '[icon_state]'") +// continue +// I = icon(icon_file, icon_state, SOUTH) + +// else +// // construct the icon and slap it into the resource cache +// var/atom/item = initial(D.build_path) +// if (!ispath(item, /atom)) +// // biogenerator outputs to beakers by default +// if (initial(D.build_type) & BIOGENERATOR) +// item = /obj/item/reagent_containers/glass/beaker/large +// else +// continue // shouldn't happen, but just in case + +// // circuit boards become their resulting machines or computers +// if (ispath(item, /obj/item/circuitboard)) +// var/obj/item/circuitboard/C = item +// var/machine = initial(C.build_path) +// if (machine) +// item = machine + +// icon_file = initial(item.icon) +// icon_state = initial(item.icon_state) + +// if(!(icon_state in icon_states(icon_file))) +// warning("design [D] with icon '[icon_file]' missing state '[icon_state]'") +// continue +// I = icon(icon_file, icon_state, SOUTH) + +// // computers (and snowflakes) get their screen and keyboard sprites +// if (ispath(item, /obj/machinery/computer) || ispath(item, /obj/machinery/power/solar_control)) +// var/obj/machinery/computer/C = item +// var/screen = initial(C.icon_screen) +// var/keyboard = initial(C.icon_keyboard) +// var/all_states = icon_states(icon_file) +// if (screen && (screen in all_states)) +// I.Blend(icon(icon_file, screen, SOUTH), ICON_OVERLAY) +// if (keyboard && (keyboard in all_states)) +// I.Blend(icon(icon_file, keyboard, SOUTH), ICON_OVERLAY) + +// Insert(initial(D.id), I) +// return ..() + +// /datum/asset/spritesheet/vending +// name = "vending" + +// /datum/asset/spritesheet/vending/register() +// for (var/k in GLOB.vending_products) +// var/atom/item = k +// if (!ispath(item, /atom)) +// continue + +// var/icon_file = initial(item.icon) +// var/icon_state = initial(item.icon_state) +// var/icon/I + +// var/icon_states_list = icon_states(icon_file) +// if(icon_state in icon_states_list) +// I = icon(icon_file, icon_state, SOUTH) +// var/c = initial(item.color) +// if (!isnull(c) && c != "#FFFFFF") +// I.Blend(c, ICON_MULTIPLY) +// else +// var/icon_states_string +// for (var/an_icon_state in icon_states_list) +// if (!icon_states_string) +// icon_states_string = "[json_encode(an_icon_state)](\ref[an_icon_state])" +// else +// icon_states_string += ", [json_encode(an_icon_state)](\ref[an_icon_state])" +// stack_trace("[item] does not have a valid icon state, icon=[icon_file], icon_state=[json_encode(icon_state)](\ref[icon_state]), icon_states=[icon_states_string]") +// I = icon('icons/turf/floors.dmi', "", SOUTH) + +// var/imgid = replacetext(replacetext("[item]", "/obj/item/", ""), "/", "-") + +// Insert(imgid, I) +// return ..() + +// /datum/asset/simple/genetics +// assets = list( +// "dna_discovered.gif" = 'html/dna_discovered.gif', +// "dna_undiscovered.gif" = 'html/dna_undiscovered.gif', +// "dna_extra.gif" = 'html/dna_extra.gif' +// ) + +// /datum/asset/simple/orbit +// assets = list( +// "ghost.png" = 'html/ghost.png' +// ) + +// /datum/asset/simple/vv +// assets = list( +// "view_variables.css" = 'html/admin/view_variables.css' +// ) + +// /datum/asset/spritesheet/sheetmaterials +// name = "sheetmaterials" + +// /datum/asset/spritesheet/sheetmaterials/register() +// InsertAll("", 'icons/obj/stack_objects.dmi') + +// // Special case to handle Bluespace Crystals +// Insert("polycrystal", 'icons/obj/telescience.dmi', "polycrystal") +// ..() + +/datum/asset/nanoui + var/list/common = list() + + var/list/common_dirs = list( + "nano/css/", + "nano/images/", + "nano/images/modular_computers/", + "nano/js/" + ) + var/list/template_dirs = list( + "nano/templates/" + ) + +/datum/asset/nanoui/register() + // Crawl the directories to find files. + for(var/path in common_dirs) + var/list/filenames = flist(path) + for(var/filename in filenames) + if(copytext(filename, length(filename)) != "/") // Ignore directories. + if(fexists(path + filename)) + common[filename] = fcopy_rsc(path + filename) + register_asset(filename, common[filename]) + // Combine all templates into a single bundle. + var/list/template_data = list() + for(var/path in template_dirs) + var/list/filenames = flist(path) + for(var/filename in filenames) + if(copytext(filename, length(filename) - 4) == ".tmpl") // Ignore directories. + template_data[filename] = file2text(path + filename) + var/template_bundle = "function nanouiTemplateBundle(){return [json_encode(template_data)];}" + var/fname = "data/nano_templates_bundle.js" + fdel(fname) + text2file(template_bundle, fname) + register_asset("nano_templates_bundle.js", fcopy_rsc(fname)) + fdel(fname) + +/datum/asset/nanoui/send(client) + send_asset_list(client, common) + +//Pill sprites for UIs +/datum/asset/chem_master + var/assets = list() + var/verify = FALSE + +/datum/asset/chem_master/register() + for(var/i = 1 to 24) + assets["pill[i].png"] = icon('icons/obj/chemical.dmi', "pill[i]") + + for(var/i = 1 to 4) + assets["bottle-[i].png"] = icon('icons/obj/chemical.dmi', "bottle-[i]") + + for(var/asset_name in assets) + register_asset(asset_name, assets[asset_name]) + +/datum/asset/chem_master/send(client) + send_asset_list(client, assets, verify) + +//Cloning pod sprites for UIs +/datum/asset/cloning + var/assets = list() + var/verify = FALSE + +/datum/asset/cloning/register() + assets["pod_idle.gif"] = icon('icons/obj/cloning.dmi', "pod_idle") + assets["pod_cloning.gif"] = icon('icons/obj/cloning.dmi', "pod_cloning") + assets["pod_mess.gif"] = icon('icons/obj/cloning.dmi', "pod_mess") + for(var/asset_name in assets) + register_asset(asset_name, assets[asset_name]) + +/datum/asset/cloning/send(client) + send_asset_list(client, assets, verify) + +// VOREStation Add +/datum/asset/cloning/resleeving +/datum/asset/cloning/resleeving/register() + // This intentionally does not call the parent. Duplicate assets are not allowed. + assets["sleeve_empty.gif"] = icon('icons/obj/machines/implantchair.dmi', "implantchair") + assets["sleeve_occupied.gif"] = icon('icons/obj/machines/implantchair.dmi', "implantchair_on") + assets["synthprinter.gif"] = icon('icons/obj/machines/synthpod.dmi', "pod_0") + assets["synthprinter_working.gif"] = icon('icons/obj/machines/synthpod.dmi', "pod_1") + for(var/asset_name in assets) + register_asset(asset_name, assets[asset_name]) +// VOREStation Add End \ No newline at end of file diff --git a/code/modules/asset_cache/validate_assets.html b/code/modules/asset_cache/validate_assets.html new file mode 100644 index 00000000000..b27a266c00d --- /dev/null +++ b/code/modules/asset_cache/validate_assets.html @@ -0,0 +1,29 @@ + + + + + + + + + + \ No newline at end of file diff --git a/code/modules/catalogue/cataloguer_vr.dm b/code/modules/catalogue/cataloguer_vr.dm index d1dfac5deac..8a8322c5815 100644 --- a/code/modules/catalogue/cataloguer_vr.dm +++ b/code/modules/catalogue/cataloguer_vr.dm @@ -1,3 +1,6 @@ +/obj/item/device/cataloguer + credit_sharing_range = 280 + /obj/item/device/cataloguer/compact name = "compact cataloguer" icon = 'icons/vore/custom_items_vr.dmi' diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm deleted file mode 100644 index 2317cab19ee..00000000000 --- a/code/modules/client/asset_cache.dm +++ /dev/null @@ -1,309 +0,0 @@ -/* -Asset cache quick users guide: - -Make a datum at the bottom of this file with your assets for your thing. -The simple subsystem will most like be of use for most cases. -Then call get_asset_datum() with the type of the datum you created and store the return -Then call .send(client) on that stored return value. - -You can set verify to TRUE if you want send() to sleep until the client has the assets. -*/ - - -// Amount of time(ds) MAX to send per asset, if this get exceeded we cancel the sleeping. -// This is doubled for the first asset, then added per asset after -#define ASSET_CACHE_SEND_TIMEOUT 7 - -//When sending mutiple assets, how many before we give the client a quaint little sending resources message -#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8 - -//When passively preloading assets, how many to send at once? Too high creates noticable lag where as too low can flood the client's cache with "verify" files -#define ASSET_CACHE_PRELOAD_CONCURRENT 3 - -/client - var/list/cache = list() // List of all assets sent to this client by the asset cache. - var/list/completed_asset_jobs = list() // List of all completed jobs, awaiting acknowledgement. - var/list/sending = list() - var/last_asset_job = 0 // Last job done. - -//This proc sends the asset to the client, but only if it needs it. -//This proc blocks(sleeps) unless verify is set to false -/proc/send_asset(var/client/client, var/asset_name, var/verify = TRUE) - client = CLIENT_FROM_VAR(client) // Will get client from a mob, or accept a client, or return null - if(!istype(client)) - return 0 - - if(client.cache.Find(asset_name) || client.sending.Find(asset_name)) - return 0 - - client << browse_rsc(SSassets.cache[asset_name], asset_name) - if(!verify) // Can't access the asset cache browser, rip. - client.cache += asset_name - return 1 - - client.sending |= asset_name - var/job = ++client.last_asset_job - - client << browse({" - - "}, "window=asset_cache_browser") - - var/t = 0 - var/timeout_time = (ASSET_CACHE_SEND_TIMEOUT * client.sending.len) + ASSET_CACHE_SEND_TIMEOUT - while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic() - sleep(1) // Lock up the caller until this is received. - t++ - - if(client) - client.sending -= asset_name - client.cache |= asset_name - client.completed_asset_jobs -= job - - return 1 - -//This proc blocks(sleeps) unless verify is set to false -/proc/send_asset_list(var/client/client, var/list/asset_list, var/verify = TRUE) - client = CLIENT_FROM_VAR(client) // Will get client from a mob, or accept a client, or return null - if(!istype(client)) - return 0 - - var/list/unreceived = asset_list - (client.cache + client.sending) - if(!unreceived || !unreceived.len) - return 0 - if(unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT) - to_chat(client, "Sending Resources...") - for(var/asset in unreceived) - if(asset in SSassets.cache) - client << browse_rsc(SSassets.cache[asset], asset) - - if(!verify) // Can't access the asset cache browser, rip. - client.cache += unreceived - return 1 - - client.sending |= unreceived - var/job = ++client.last_asset_job - - client << browse({" - - "}, "window=asset_cache_browser") - - var/t = 0 - var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len - while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic() - sleep(1) // Lock up the caller until this is received. - t++ - - if(client) - client.sending -= unreceived - client.cache |= unreceived - client.completed_asset_jobs -= job - - return 1 - -//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start. -//The proc calls procs that sleep for long times. -/proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE) - var/concurrent_tracker = 1 - for(var/file in files) - if(!client) - break - if(register_asset) - register_asset(file, files[file]) - if(concurrent_tracker >= ASSET_CACHE_PRELOAD_CONCURRENT) - concurrent_tracker = 1 - send_asset(client, file) - else - concurrent_tracker++ - send_asset(client, file, verify = FALSE) - sleep(0) //queuing calls like this too quickly can cause issues in some client versions - -//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up. -//if it's an icon or something be careful, you'll have to copy it before further use. -/proc/register_asset(var/asset_name, var/asset) - SSassets.cache[asset_name] = asset - -//These datums are used to populate the asset cache, the proc "register()" does this. - -//all of our asset datums, used for referring to these later -/var/global/list/asset_datums = list() - -//get a assetdatum or make a new one -/proc/get_asset_datum(var/type) - if(!(type in asset_datums)) - return new type() - return asset_datums[type] - -/datum/asset - var/_abstract = /datum/asset // Marker so we don't instanatiate abstract types - -/datum/asset/New() - asset_datums[type] = src - register() - -/datum/asset/proc/register() - return - -/datum/asset/proc/send(client) - return - -//If you don't need anything complicated. -/datum/asset/simple - _abstract = /datum/asset/simple - var/assets = list() - var/verify = FALSE - -/datum/asset/simple/register() - for(var/asset_name in assets) - register_asset(asset_name, assets[asset_name]) -/datum/asset/simple/send(client) - send_asset_list(client,assets,verify) - -// -// iconsheet Assets - For making lots of icon states available at once without sending a thousand tiny files. -// -/datum/asset/iconsheet - _abstract = /datum/asset/iconsheet - var/name // Name of the iconsheet. Asset will be named after this. - var/verify = FALSE - -/datum/asset/iconsheet/register(var/list/sprites) - if (!name) - CRASH("iconsheet [type] cannot register without a name") - if (!islist(sprites)) - CRASH("iconsheet [type] cannot register without a sprites list") - - var/res_name = "iconsheet_[name].css" - var/fname = "data/iconsheets/[res_name]" - fdel(fname) - text2file(generate_css(sprites), fname) - register_asset(res_name, fcopy_rsc(fname)) - fdel(fname) - -/datum/asset/iconsheet/send(client/C) - if (!name) - return - send_asset_list(C, list("iconsheet_[name].css"), verify) - -/datum/asset/iconsheet/proc/generate_css(var/list/sprites) - var/list/out = list(".[name]{display:inline-block;}") - for(var/sprite_id in sprites) - var/icon/I = sprites[sprite_id] - var/data_url = "'data:image/png;base64,[icon2base64(I)]'" - out += ".[name].[sprite_id]{width:[I.Width()]px;height:[I.Height()]px;background-image:url([data_url]);}" - return out.Join("\n") - -/datum/asset/iconsheet/proc/build_sprite_list(icon/I, list/directions, prefix = null) - if (length(prefix)) - prefix = "[prefix]-" - - if (!directions) - directions = list(SOUTH) - - var/sprites = list() - for (var/icon_state_name in cached_icon_states(I)) - for (var/direction in directions) - var/suffix = (directions.len > 1) ? "-[dir2text(direction)]" : "" - var/sprite_name = "[prefix][icon_state_name][suffix]" - var/icon/sprite = icon(I, icon_state=icon_state_name, dir=direction, frame=1, moving=FALSE) - if (!sprite || !length(cached_icon_states(sprite))) // that direction or state doesn't exist - continue - sprites[sprite_name] = sprite - return sprites - -// Get HTML link tag for including the iconsheet css file. -/datum/asset/iconsheet/proc/css_tag() - return "" - -// get HTML tag for showing an icon -/datum/asset/iconsheet/proc/icon_tag(icon_state, dir = SOUTH) - return "" - -//DEFINITIONS FOR ASSET DATUMS START HERE. -/datum/asset/simple/generic - assets = list( - "search.js" = 'html/search.js', - "panels.css" = 'html/panels.css', - "loading.gif" = 'html/images/loading.gif', - "ntlogo.png" = 'html/images/ntlogo.png', - "sglogo.png" = 'html/images/sglogo.png', - "talisman.png" = 'html/images/talisman.png', - "paper_bg.png" = 'html/images/paper_bg.png', - "no_image32.png" = 'html/images/no_image32.png', - ) - -/datum/asset/simple/changelog - assets = list( - "88x31.png" = 'html/88x31.png', - "bug-minus.png" = 'html/bug-minus.png', - "cross-circle.png" = 'html/cross-circle.png', - "hard-hat-exclamation.png" = 'html/hard-hat-exclamation.png', - "image-minus.png" = 'html/image-minus.png', - "image-plus.png" = 'html/image-plus.png', - "map-pencil.png" = 'html/map-pencil.png', - "music-minus.png" = 'html/music-minus.png', - "music-plus.png" = 'html/music-plus.png', - "tick-circle.png" = 'html/tick-circle.png', - "wrench-screwdriver.png" = 'html/wrench-screwdriver.png', - "spell-check.png" = 'html/spell-check.png', - "burn-exclamation.png" = 'html/burn-exclamation.png', - "chevron.png" = 'html/chevron.png', - "chevron-expand.png" = 'html/chevron-expand.png', - "changelog.css" = 'html/changelog.css', - "changelog.js" = 'html/changelog.js', - "changelog.html" = 'html/changelog.html' - ) - -/datum/asset/nanoui - var/list/common = list() - - var/list/common_dirs = list( - "nano/css/", - "nano/images/", - "nano/images/modular_computers/", - "nano/js/" - ) - var/list/template_dirs = list( - "nano/templates/" - ) - -/datum/asset/nanoui/register() - // Crawl the directories to find files. - for(var/path in common_dirs) - var/list/filenames = flist(path) - for(var/filename in filenames) - if(copytext(filename, length(filename)) != "/") // Ignore directories. - if(fexists(path + filename)) - common[filename] = fcopy_rsc(path + filename) - register_asset(filename, common[filename]) - // Combine all templates into a single bundle. - var/list/template_data = list() - for(var/path in template_dirs) - var/list/filenames = flist(path) - for(var/filename in filenames) - if(copytext(filename, length(filename) - 4) == ".tmpl") // Ignore directories. - template_data[filename] = file2text(path + filename) - var/template_bundle = "function nanouiTemplateBundle(){return [json_encode(template_data)];}" - var/fname = "data/nano_templates_bundle.js" - fdel(fname) - text2file(template_bundle, fname) - register_asset("nano_templates_bundle.js", fcopy_rsc(fname)) - fdel(fname) - -/datum/asset/nanoui/send(client) - send_asset_list(client, common) - - -// VOREStation Add Start - pipes iconsheet asset -/datum/asset/iconsheet/pipes - name = "pipes" - -/datum/asset/iconsheet/pipes/register() - var/list/sprites = list() - for (var/each in list('icons/obj/pipe-item.dmi', 'icons/obj/pipes/disposal.dmi')) - sprites += build_sprite_list(each, global.alldirs) - ..(sprites) -// VOREStation Add End diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index b6b8d1b14d3..e11ff9e4f7a 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -59,3 +59,18 @@ preload_rsc = PRELOAD_RSC var/global/obj/screen/click_catcher/void + + // List of all asset filenames sent to this client by the asset cache, along with their assoicated md5s + var/list/sent_assets = list() + /// List of all completed blocking send jobs awaiting acknowledgement by send_asset + var/list/completed_asset_jobs = list() + /// Last asset send job id. + var/last_asset_job = 0 + var/last_completed_asset_job = 0 + + ///world.time they connected + var/connection_time + ///world.realtime they connected + var/connection_realtime + ///world.timeofday they connected + var/connection_timeofday diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 36f11e736f0..dd84f559820 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -34,10 +34,12 @@ #endif + // asset_cache + var/asset_cache_job if(href_list["asset_cache_confirm_arrival"]) - var/job = text2num(href_list["asset_cache_confirm_arrival"]) - completed_asset_jobs += job - return + asset_cache_job = asset_cache_confirm_arrival(href_list["asset_cache_confirm_arrival"]) + if (!asset_cache_job) + return //search the href for script injection if( findtext(href," || [hsrc ? "[hsrc] " : ""][href]") + //byond bug ID:2256651 + if (asset_cache_job && (asset_cache_job in completed_asset_jobs)) + to_chat(src, "An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)") + src << browse("...", "window=asset_cache_browser") + return + if (href_list["asset_cache_preload_data"]) + asset_cache_preload_data(href_list["asset_cache_preload_data"]) + return + switch(href_list["_src_"]) if("holder") hsrc = holder if("usr") hsrc = mob @@ -181,6 +196,10 @@ . = ..() //calls mob.Login() prefs.sanitize_preferences() + connection_time = world.time + connection_realtime = world.realtime + connection_timeofday = world.timeofday + if(custom_event_msg && custom_event_msg != "") to_chat(src, "

Custom Event

") to_chat(src, "

A custom event is taking place. OOC Info:

") @@ -408,8 +427,12 @@ //send resources to the client. It's here in its own proc so we can move it around easiliy if need be /client/proc/send_resources() spawn (10) //removing this spawn causes all clients to not get verbs. + + //load info on what assets the client has + src << browse('code/modules/asset_cache/validate_assets.html', "window=asset_cache_browser") + //Precache the client with all other assets slowly, so as to not block other browse() calls - getFilesSlow(src, SSassets.preload, register_asset = FALSE) + addtimer(CALLBACK(GLOBAL_PROC, /proc/getFilesSlow, src, SSassets.preload, FALSE), 5 SECONDS) mob/proc/MayRespawn() return 0 diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 6d4b6ef75e0..0375c86eafa 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -336,7 +336,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O . += " Style: < > [pref.h_style]
" //The < & > in this line is correct-- those extra characters are the arrows you click to switch between styles. . += "Gradient
" - . += "Change Color [color_square(pref.r_grad, pref.g_grad, pref.b_grad)] " + . += "Change Color [color_square(pref.r_grad, pref.g_grad, pref.b_grad)] " . += " Style: < > [pref.grad_style]
" . += "
Facial
" diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index a40155d2d54..9b93f13c5a4 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -9,6 +9,10 @@ S["ooccolor"] >> pref.ooccolor S["tooltipstyle"] >> pref.tooltipstyle S["client_fps"] >> pref.client_fps + S["ambience_freq"] >> pref.ambience_freq + S["ambience_chance"] >> pref.ambience_chance + S["tgui_fancy"] >> pref.tgui_fancy + S["tgui_lock"] >> pref.tgui_lock /datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S) S["UI_style"] << pref.UI_style @@ -17,28 +21,40 @@ S["ooccolor"] << pref.ooccolor S["tooltipstyle"] << pref.tooltipstyle S["client_fps"] << pref.client_fps + S["ambience_freq"] << pref.ambience_freq + S["ambience_chance"] << pref.ambience_freq + S["tgui_fancy"] << pref.tgui_fancy + S["tgui_lock"] << pref.tgui_lock /datum/category_item/player_setup_item/player_global/ui/sanitize_preferences() - pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style)) - pref.UI_style_color = sanitize_hexcolor(pref.UI_style_color, initial(pref.UI_style_color)) - pref.UI_style_alpha = sanitize_integer(pref.UI_style_alpha, 0, 255, initial(pref.UI_style_alpha)) - pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor)) - pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, initial(pref.tooltipstyle)) - pref.client_fps = sanitize_integer(pref.client_fps, 0, MAX_CLIENT_FPS, initial(pref.client_fps)) + pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style)) + pref.UI_style_color = sanitize_hexcolor(pref.UI_style_color, initial(pref.UI_style_color)) + pref.UI_style_alpha = sanitize_integer(pref.UI_style_alpha, 0, 255, initial(pref.UI_style_alpha)) + pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor)) + pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, initial(pref.tooltipstyle)) + pref.client_fps = sanitize_integer(pref.client_fps, 0, MAX_CLIENT_FPS, initial(pref.client_fps)) + pref.ambience_freq = sanitize_integer(pref.ambience_freq, 0, 60, initial(pref.ambience_freq)) // No more than once per hour. + pref.ambience_chance = sanitize_integer(pref.ambience_chance, 0, 100, initial(pref.ambience_chance)) // 0-100 range. + pref.tgui_fancy = sanitize_integer(pref.tgui_fancy, 0, 1, initial(pref.tgui_fancy)) + pref.tgui_lock = sanitize_integer(pref.tgui_lock, 0, 1, initial(pref.tgui_lock)) /datum/category_item/player_setup_item/player_global/ui/content(var/mob/user) . = "UI Style: [pref.UI_style]
" . += "Custom UI (recommended for White UI):
" - . += "-Color: [pref.UI_style_color] [color_square(hex = pref.UI_style_color)] reset
" - . += "-Alpha(transparency): [pref.UI_style_alpha] reset
" + . += "-Color: [pref.UI_style_color]�[color_square(hex = pref.UI_style_color)]�reset
" + . += "-Alpha(transparency): [pref.UI_style_alpha]�reset
" . += "Tooltip Style: [pref.tooltipstyle]
" . += "Client FPS: [pref.client_fps]
" + . += "Random Ambience Frequency: [pref.ambience_freq]
" + . += "Ambience Chance: [pref.ambience_chance]
" + . += "tgui Window Mode: [(pref.tgui_fancy) ? "Fancy (default)" : "Compatible (slower)"]
" + . += "tgui Window Placement: [(pref.tgui_lock) ? "Primary Monitor" : "Free (default)"]
" if(can_select_ooc_color(user)) - . += "OOC Color: " + . += "OOC Color:�" if(pref.ooccolor == initial(pref.ooccolor)) . += "Using Default
" else - . += "[pref.ooccolor] [color_square(hex = pref.ooccolor)] reset
" + . += "[pref.ooccolor] [color_square(hex = pref.ooccolor)]�reset
" /datum/category_item/player_setup_item/player_global/ui/OnTopic(var/href,var/list/href_list, var/mob/user) if(href_list["select_style"]) @@ -79,6 +95,28 @@ if(pref.client) pref.client.fps = fps_new return TOPIC_REFRESH + + else if(href_list["select_ambience_freq"]) + var/ambience_new = input(user, "Input how often you wish to hear ambience repeated! (1-60 MINUTES, 0 for disabled)", "Global Preference", pref.ambience_freq) as null|num + if(isnull(ambience_new) || !CanUseTopic(user)) return TOPIC_NOACTION + if(ambience_new < 0 || ambience_new > 60) return TOPIC_NOACTION + pref.ambience_freq = ambience_new + return TOPIC_REFRESH + + else if(href_list["select_ambience_chance"]) + var/ambience_chance_new = input(user, "Input the chance you'd like to hear ambience played to you (On area change, or by random ambience). 35 means a 35% chance to play ambience. This is a range from 0-100. 0 disables ambience playing entirely. This is also affected by Ambience Frequency.", "Global Preference", pref.ambience_freq) as null|num + if(isnull(ambience_chance_new) || !CanUseTopic(user)) return TOPIC_NOACTION + if(ambience_chance_new < 0 || ambience_chance_new > 100) return TOPIC_NOACTION + pref.ambience_chance = ambience_chance_new + return TOPIC_REFRESH + + else if(href_list["tgui_fancy"]) + pref.tgui_fancy = !pref.tgui_fancy + return TOPIC_REFRESH + + else if(href_list["tgui_lock"]) + pref.tgui_lock = !pref.tgui_lock + return TOPIC_REFRESH else if(href_list["reset"]) switch(href_list["reset"]) diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm index 7e991223125..f69d04aa72b 100644 --- a/code/modules/client/preference_setup/global/setting_datums.dm +++ b/code/modules/client/preference_setup/global/setting_datums.dm @@ -266,6 +266,18 @@ var/list/_client_preferences_by_type enabled_description = "Enabled" disabled_description = "Disabled" +/datum/client_preference/status_indicators + description = "Status Indicators" + key = "SHOW_STATUS" + enabled_description = "Show" + disabled_description = "Hide" + +/datum/client_preference/status_indicators/toggled(mob/preference_mob, enabled) + . = ..() + if(preference_mob && preference_mob.plane_holder) + var/datum/plane_holder/PH = preference_mob.plane_holder + PH.set_vis(VIS_STATUS, enabled) + /******************** * Staff Preferences * ********************/ diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm index 9f008afe085..e3abb37cd53 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm @@ -115,6 +115,15 @@ scarfs[initial(scarf_type.name)] = scarf_type gear_tweaks += new/datum/gear_tweak/path(sortAssoc(scarfs)) +/datum/gear/accessory/scarfcolor + display_name = "scarf (recolorable)" + path = /obj/item/clothing/accessory/scarf/white + cost = 1 + +/datum/gear/accessory/scarfcolor/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) + /datum/gear/accessory/jacket display_name = "suit jacket selection" path = /obj/item/clothing/accessory/jacket @@ -279,3 +288,7 @@ /datum/gear/accessory/cowledvest display_name = "cowled vest" path = /obj/item/clothing/accessory/cowledvest + +/datum/gear/accessory/asymovercoat + display_name = "orange asymmetrical overcoat" + path = /obj/item/clothing/accessory/asymovercoat diff --git a/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm b/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm index 21ebb114035..f8bffbbd90d 100644 --- a/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_fluffitems_vr.dm @@ -183,12 +183,6 @@ ckeywhitelist = list("cockatricexl") character_name = list("James Holder") -/datum/gear/fluff/jasmine_implant - path = /obj/item/weapon/implanter/reagent_generator/jasmine - display_name = "Jasmine's Implant" - ckeywhitelist = list("cameron653") - character_name = list("Jasmine Lizden") - /datum/gear/fluff/diana_robe path = /obj/item/clothing/suit/fluff/purp_robes display_name = "Diana's Robes" @@ -310,11 +304,6 @@ allowed_roles = list("Explorer") // G CKEYS -/datum/gear/fluff/eldi_implant - path = /obj/item/weapon/implanter/reagent_generator/eldi - display_name = "Eldi's Implant" - ckeywhitelist = list("gowst") - character_name = list("Eldi Moljir") // H CKEYS /datum/gear/fluff/lauren_medal @@ -335,12 +324,6 @@ ckeywhitelist = list("hottokeeki") character_name = list("Belle Day") -/datum/gear/fluff/belle_implant - path = /obj/item/weapon/implanter/reagent_generator/belle - display_name = "Belle's Implant" - ckeywhitelist = list("hottokeeki") - character_name = list("Belle Day") - // I CKEYS /datum/gear/fluff/ruda_badge path = /obj/item/clothing/accessory/badge/holo/detective/ruda @@ -553,12 +536,6 @@ ckeywhitelist = list("kiwidaninja") character_name = list("Chakat Taiga") -/datum/gear/fluff/rischi_implant - path = /obj/item/weapon/implanter/reagent_generator/rischi - display_name = "Rischi's Implant" - ckeywhitelist = list("konabird") - character_name = list("Rischi") - /datum/gear/fluff/ashley_medal path = /obj/item/clothing/accessory/medal/nobel_science/fluff/ashley display_name = "Ashley's Medal" @@ -580,12 +557,6 @@ ckeywhitelist = list("luminescentring") character_name = list("Briana Moore") -/datum/gear/fluff/savannah_implant - path = /obj/item/weapon/implanter/reagent_generator/savannah - display_name = "Savannah's Implant" - ckeywhitelist = list("lycanthorph") - character_name = list("Savannah Dixon") - // M CKEYS /datum/gear/fluff/phi_box path = /obj/item/weapon/storage/box/fluff/phi @@ -842,12 +813,6 @@ ckeywhitelist = list("silvertalismen") character_name = list("Tasy Ruffles") -/datum/gear/fluff/evian_implant - path = /obj/item/weapon/implanter/reagent_generator/evian - display_name = "Evian's Implant" - ckeywhitelist = list("silvertalismen") - character_name = list("Evian") - /datum/gear/fluff/fortune_backpack path = /obj/item/weapon/storage/backpack/satchel/fluff/swat43bag display_name = "Fortune's Backpack" @@ -861,12 +826,6 @@ ckeywhitelist = list("stobarico") character_name = list("Alexis Bloise") -/datum/gear/fluff/roiz_implant - path = /obj/item/weapon/implanter/reagent_generator/roiz - display_name = "Roiz's Implant" - ckeywhitelist = list("spoopylizz") - character_name = list("Roiz Lizden") - /datum/gear/fluff/roiz_coat path = /obj/item/clothing/suit/storage/hooded/wintercoat/roiz display_name = "Roiz's Coat" @@ -1020,12 +979,6 @@ ckeywhitelist = list("vorrarkul") character_name = list("Theodora Lindt") -/datum/gear/fluff/theodora_implant - path = /obj/item/weapon/implanter/reagent_generator/vorrarkul - display_name = "Theodora's Implant" - ckeywhitelist = list("vorrarkul") - character_name = list("Theodora Lindt") - /datum/gear/fluff/kaitlyn_plush path = /obj/item/toy/plushie/mouse/fluff display_name = "Kaitlyn's Mouse Plush" @@ -1102,12 +1055,6 @@ ckeywhitelist = list("wickedtemp") character_name = list("Chakat Tempest Venosare") -/datum/gear/fluff/tempest_implant - path = /obj/item/weapon/implanter/reagent_generator/tempest - display_name = "Tempest's Implant" - ckeywhitelist = list("wickedtemp") - character_name = list("Chakat Tempest Venosare") - // X CKEYS /datum/gear/fluff/penelope_box path = /obj/item/weapon/storage/box/fluff/penelope diff --git a/code/modules/client/preference_setup/loadout/loadout_general_vr.dm b/code/modules/client/preference_setup/loadout/loadout_general_vr.dm new file mode 100644 index 00000000000..09093b65673 --- /dev/null +++ b/code/modules/client/preference_setup/loadout/loadout_general_vr.dm @@ -0,0 +1,12 @@ +/datum/gear/ball + display_name = "tennis ball selection" + description = "Choose from a num- BALL!" + path = /obj/item/toy/tennis + +/datum/gear/ball/New() + ..() + var/list/balls = list() + for(var/ball in typesof(/obj/item/toy/tennis/)) + var/obj/item/toy/tennis/ball_type = ball + balls[initial(ball_type.name)] = ball_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(balls)) \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_head.dm b/code/modules/client/preference_setup/loadout/loadout_head.dm index eb107985cf1..4a6437cea1d 100644 --- a/code/modules/client/preference_setup/loadout/loadout_head.dm +++ b/code/modules/client/preference_setup/loadout/loadout_head.dm @@ -366,4 +366,20 @@ /datum/gear/head/jingasa display_name = "jingasa" - path = /obj/item/clothing/head/jingasa \ No newline at end of file + path = /obj/item/clothing/head/jingasa + +/datum/gear/head/sunflower_crown + display_name = "sunflower crown" + path = /obj/item/clothing/head/sunflower_crown + +/datum/gear/head/lavender_crown + display_name = "lavender crown" + path = /obj/item/clothing/head/lavender_crown + +/datum/gear/head/poppy_crown + display_name = "poppy crown" + path = /obj/item/clothing/head/poppy_crown + +/datum/gear/head/rose_crown + display_name = "rose crown" + path = /obj/item/clothing/head/rose_crown diff --git a/code/modules/client/preference_setup/loadout/loadout_mask.dm b/code/modules/client/preference_setup/loadout/loadout_mask.dm index 5ae0b96e2b3..716cdb42680 100644 --- a/code/modules/client/preference_setup/loadout/loadout_mask.dm +++ b/code/modules/client/preference_setup/loadout/loadout_mask.dm @@ -20,4 +20,8 @@ /datum/gear/mask/sterile display_name = "sterile mask" path = /obj/item/clothing/mask/surgical - cost = 2 \ No newline at end of file + cost = 2 + +/datum/gear/mask/veil + display_name = "black veil" + path = /obj/item/clothing/mask/veil \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_suit.dm b/code/modules/client/preference_setup/loadout/loadout_suit.dm index 3ae9f2bf590..687435a7cf3 100644 --- a/code/modules/client/preference_setup/loadout/loadout_suit.dm +++ b/code/modules/client/preference_setup/loadout/loadout_suit.dm @@ -77,7 +77,7 @@ /datum/gear/suit/mil display_name = "military jacket selection" path = /obj/item/clothing/suit/storage/miljacket - + /datum/gear/suit/mil/New() ..() var/list/mil_jackets = list() diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm index 65039cccb0a..0d6cd267ac9 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm @@ -556,4 +556,36 @@ /datum/gear/uniform/haltertop display_name = "halter top" - path = /obj/item/clothing/under/haltertop \ No newline at end of file + path = /obj/item/clothing/under/haltertop + +/datum/gear/uniform/revealingdress + display_name = "revealing dress" + path = /obj/item/clothing/under/dress/revealingdress + +/datum/gear/uniform/rippedpunk + display_name = "ripped punk jeans" + path = /obj/item/clothing/under/rippedpunk + +/datum/gear/uniform/gothic + display_name = "gothic dress" + path = /obj/item/clothing/under/dress/gothic + +/datum/gear/uniform/formalred + display_name = "formal red dress" + path = /obj/item/clothing/under/dress/formalred + +/datum/gear/uniform/pentagram + display_name = "pentagram dress" + path = /obj/item/clothing/under/dress/pentagram + +/datum/gear/uniform/yellowswoop + display_name = "yellow swooped dress" + path = /obj/item/clothing/under/dress/yellowswoop + +/datum/gear/uniform/greenasym + display_name = "green asymmetrical jumpsuit" + path = /obj/item/clothing/under/greenasym + +/datum/gear/uniform/cyberpunkharness + display_name = "cyberpunk strapped harness" + path = /obj/item/clothing/under/cyberpunkharness \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno.dm b/code/modules/client/preference_setup/loadout/loadout_xeno.dm index a2c2322286f..a7669a837fa 100644 --- a/code/modules/client/preference_setup/loadout/loadout_xeno.dm +++ b/code/modules/client/preference_setup/loadout/loadout_xeno.dm @@ -411,5 +411,15 @@ sort_category = "Xenowear" /datum/gear/suit/teshcoatwhite/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) + +/datum/gear/accessory/teshneckscarf + display_name = "neckscarf, recolorable (Teshari)" + path = /obj/item/clothing/accessory/scarf/teshari/neckscarf + whitelisted = SPECIES_TESHARI + sort_category = "Xenowear" + +/datum/gear/accessory/teshneckscarf/New() ..() gear_tweaks = list(gear_tweak_free_color_choice) \ No newline at end of file diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 1c1e1fc44bb..e6619e66fed 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -23,6 +23,11 @@ datum/preferences var/UI_style_alpha = 255 var/tooltipstyle = "Midnight" //Style for popup tooltips var/client_fps = 0 + var/ambience_freq = 5 // How often we're playing repeating ambience to a client. + var/ambience_chance = 35 // What's the % chance we'll play ambience (in conjunction with the above frequency) + + var/tgui_fancy = TRUE + var/tgui_lock = FALSE //character preferences var/real_name //our character's name @@ -336,6 +341,8 @@ datum/preferences else if(href_list["resetslot"]) if("No" == alert("This will reset the current slot. Continue?", "Reset current slot?", "No", "Yes")) return 0 + if("No" == alert("Are you completely sure that you want to reset this character slot?", "Reset current slot?", "No", "Yes")) + return 0 load_character(SAVE_RESET) sanitize_preferences() else if(href_list["copy"]) diff --git a/code/modules/client/preferences_toggle_procs.dm b/code/modules/client/preferences_toggle_procs.dm index 9439c90125e..e488badc390 100644 --- a/code/modules/client/preferences_toggle_procs.dm +++ b/code/modules/client/preferences_toggle_procs.dm @@ -334,6 +334,19 @@ You will have to reload VChat and/or reconnect to the server for these changes to take place. \ VChat message persistence is not guaranteed if you change this again before the start of the next round.") +/client/verb/toggle_status_indicators() + set name = "Toggle Status Indicators" + set category = "Preferences" + set desc = "Enable/Disable seeing status indicators over peoples' heads." + + var/pref_path = /datum/client_preference/status_indicators + toggle_preference(pref_path) + SScharacter_setup.queue_preferences_save(prefs) + + to_chat(src, "You will now [(is_preference_enabled(/datum/client_preference/status_indicators)) ? "see" : "not see"] status indicators.") + + feedback_add_details("admin_verb","TStatusIndicators") + // Not attached to a pref datum because those are strict binary toggles /client/verb/toggle_examine_mode() diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 4b82cbbe25b..fdbc1c257df 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -39,28 +39,49 @@ BLIND // can't see anything var/mob/M = src.loc M.update_inv_glasses() +/obj/item/clothing/glasses/proc/can_toggle(mob/living/user) + if(!toggleable) + return FALSE + + // Prevent people from just turning their goggles back on. + if(!active && (vision_flags & (SEE_TURFS|SEE_OBJS))) + var/area/A = get_area(src) + if(A.no_spoilers) + return FALSE + + return TRUE + +/obj/item/clothing/glasses/proc/toggle_active(mob/living/user) + if(active) + active = FALSE + icon_state = off_state + user.update_inv_glasses() + flash_protection = FLASH_PROTECTION_NONE + tint = TINT_NONE + away_planes = enables_planes + enables_planes = null + + else + active = TRUE + icon_state = initial(icon_state) + user.update_inv_glasses() + flash_protection = initial(flash_protection) + tint = initial(tint) + enables_planes = away_planes + away_planes = null + user.update_action_buttons() + user.recalculate_vis() + /obj/item/clothing/glasses/attack_self(mob/user) if(toggleable) - if(active) - active = 0 - icon_state = off_state - user.update_inv_glasses() - flash_protection = FLASH_PROTECTION_NONE - tint = TINT_NONE - away_planes = enables_planes - enables_planes = null - to_chat(usr, "You deactivate the optical matrix on the [src].") + if(!can_toggle(user)) + to_chat(user, span("warning", "You don't seem to be able to toggle \the [src] here.")) else - active = 1 - icon_state = initial(icon_state) - user.update_inv_glasses() - flash_protection = initial(flash_protection) - tint = initial(tint) - enables_planes = away_planes - away_planes = null - to_chat(usr, "You activate the optical matrix on the [src].") - user.update_action_buttons() - user.recalculate_vis() + toggle_active(user) + if(active) + to_chat(user, span("notice", "You activate the optical matrix on the [src].")) + else + to_chat(user, span("notice", "You deactivate the optical matrix on the [src].")) ..() /obj/item/clothing/glasses/meson diff --git a/code/modules/clothing/glasses/hud_vr.dm b/code/modules/clothing/glasses/hud_vr.dm index cf02ad326c9..0a67f7f3566 100644 --- a/code/modules/clothing/glasses/hud_vr.dm +++ b/code/modules/clothing/glasses/hud_vr.dm @@ -10,6 +10,8 @@ icon_state = "glasses" var/datum/nano_module/arscreen var/arscreen_path + var/datum/tgui_module/tgarscreen + var/tgarscreen_path var/flash_prot = 0 //0 for none, 1 for flash weapon protection, 2 for welder protection enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_AUGMENTED) plane_slots = list(slot_glasses) @@ -18,21 +20,33 @@ ..() if(arscreen_path) arscreen = new arscreen_path(src) + if(tgarscreen_path) + tgarscreen = new tgarscreen_path(src) /obj/item/clothing/glasses/omnihud/Destroy() QDEL_NULL(arscreen) + QDEL_NULL(tgarscreen) . = ..() /obj/item/clothing/glasses/omnihud/dropped() if(arscreen) SSnanoui.close_uis(src) + if(tgarscreen) + SStgui.close_uis(src) ..() /obj/item/clothing/glasses/omnihud/emp_act(var/severity) + if(arscreen) + SSnanoui.close_uis(src) + if(tgarscreen) + SStgui.close_uis(src) var/disconnect_ar = arscreen + var/disconnect_tgar = tgarscreen arscreen = null + tgarscreen = null spawn(20 SECONDS) arscreen = disconnect_ar + tgarscreen = disconnect_tgar //extra fun for non-sci variants; a small chance flip the state to the dumb 3d glasses when EMP'd if(icon_state == "glasses" || icon_state == "sun") @@ -122,12 +136,12 @@ They can also read data from active suit sensors using the crew monitoring system." mode = "med" action_button_name = "AR Console (Crew Monitor)" - arscreen_path = /datum/nano_module/program/crew_monitor + tgarscreen_path = /datum/tgui_module/crew_monitor/glasses enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_STATUS_R,VIS_CH_BACKUP,VIS_AUGMENTED) ar_interact(var/mob/living/carbon/human/user) - if(arscreen) - arscreen.ui_interact(user,"main",null,1,glasses_state) + if(tgarscreen) + tgarscreen.tgui_interact(user) return 1 /obj/item/clothing/glasses/omnihud/sec @@ -138,12 +152,12 @@ mode = "sec" flash_protection = FLASH_PROTECTION_MODERATE //weld protection is a little too widespread action_button_name = "AR Console (Security Alerts)" - arscreen_path = /datum/nano_module/alarm_monitor/security + tgarscreen_path = /datum/tgui_module/alarm_monitor/security/glasses enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_WANTED,VIS_AUGMENTED) ar_interact(var/mob/living/carbon/human/user) - if(arscreen) - arscreen.ui_interact(user,"main",null,1,glasses_state) + if(tgarscreen) + tgarscreen.tgui_interact(user) return 1 /obj/item/clothing/glasses/omnihud/eng @@ -154,11 +168,11 @@ mode = "eng" flash_protection = FLASH_PROTECTION_MAJOR action_button_name = "AR Console (Station Alerts)" - arscreen_path = /datum/nano_module/alarm_monitor/engineering + tgarscreen_path = /datum/tgui_module/alarm_monitor/engineering/glasses ar_interact(var/mob/living/carbon/human/user) - if(arscreen) - arscreen.ui_interact(user,"main",null,1,glasses_state) + if(tgarscreen) + tgarscreen.tgui_interact(user) return 1 /obj/item/clothing/glasses/omnihud/rnd diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index eab03a3c2e9..d972cf82cc8 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -288,3 +288,10 @@ desc = "A fine black bandana with nanotech lining and a skull emblem. Can be worn on the head or face." icon_state = "bandskull" item_state_slots = list(slot_r_hand_str = "bandskull", slot_l_hand_str = "bandskull") + +/obj/item/clothing/mask/veil + name = "black veil" + desc = "A black veil, typically worn at funerals or by goths." + w_class = ITEMSIZE_TINY + body_parts_covered = FACE + icon_state = "veil" \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm b/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm index 6dc5fc4f016..e6848a66d0d 100644 --- a/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm +++ b/code/modules/clothing/spacesuits/rig/modules/specific/ai_container.dm @@ -15,7 +15,7 @@ to_chat(usr, "Your module is not installed in a hardsuit.") return - module.holder.ui_interact(usr, nano_state = contained_state) + module.holder.tgui_interact(usr, custom_state = GLOB.tgui_contained_state) /obj/item/rig_module/ai_container @@ -134,7 +134,7 @@ if(!target) if(ai_card) if(istype(ai_card,/obj/item/device/aicard)) - ai_card.ui_interact(H, state = deep_inventory_state) + ai_card.tgui_interact(H, custom_state = deep_inventory_state) else eject_ai(H) update_verb_holder() diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 1afd78dee0b..cd65478a05e 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -28,8 +28,8 @@ var/suit_state //The string used for the suit's icon_state. - var/interface_path = "hardsuit.tmpl" - var/ai_interface_path = "hardsuit.tmpl" + var/interface_path = "RIGSuit" + var/ai_interface_path = "RIGSuit" var/interface_title = "Hardsuit Controller" var/wearer_move_delay //Used for AI moving. var/ai_controlled_move_delay = 10 @@ -284,6 +284,7 @@ if(!seal_target && !suit_is_deployed()) M.visible_message("[M]'s suit flashes an error light.","Your suit flashes an error light. It can't function properly without being fully deployed.") + playsound(src, 'sound/machines/rig/rigerror.ogg', 20, FALSE) failed_to_seal = 1 if(!failed_to_seal) @@ -293,6 +294,7 @@ if(seal_delay && !do_after(M,seal_delay)) if(M) to_chat(M, "You must remain still while the suit is adjusting the components.") + playsound(src, 'sound/machines/rig/rigerror.ogg', 20, FALSE) failed_to_seal = 1 if(!M) failed_to_seal = 1 @@ -340,6 +342,7 @@ piece.armor["bio"] = 100 else piece.armor["bio"] = src.armor["bio"] + playsound(src,'sound/machines/rig/rigservo.ogg', 10, FALSE) else failed_to_seal = 1 @@ -371,6 +374,7 @@ else minihud = new (M.hud_used, src) to_chat(M, "Your entire suit [canremove ? "loosens as the components relax" : "tightens around you as the components lock into place"].") + playsound(src, 'sound/machines/rig/rigstarted.ogg', 10, FALSE) M.client.screen -= booting_L qdel(booting_L) booting_R.icon_state = "boot_done" @@ -493,7 +497,7 @@ wearer.wearing_rig = null wearer = null return PROCESS_KILL - + // Run through cooling coolingProcess() @@ -508,6 +512,7 @@ to_chat(wearer, "Your suit beeps stridently, and suddenly goes dead.") else to_chat(wearer, "Your suit beeps stridently, and suddenly you're wearing a leaden mass of metal and plastic composites instead of a powered suit.") + playsound(src, 'sound/machines/rig/rigdown.ogg', 60, FALSE) if(offline_vision_restriction == 1) to_chat(wearer, "The suit optics flicker and die, leaving you with restricted vision.") else if(offline_vision_restriction == 2) @@ -565,6 +570,7 @@ if(fail_msg) to_chat(user, fail_msg) + playsound(src, 'sound/machines/rig/rigerror.ogg', 20, FALSE) return 0 // This is largely for cancelling stealth and whatever. @@ -576,81 +582,6 @@ cell.use(cost*10) return 1 -/obj/item/weapon/rig/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/nano_state = inventory_state) - if(!user) - return - - var/list/data = list() - - if(selected_module) - data["primarysystem"] = "[selected_module.interface_name]" - - if(src.loc != user) - data["ai"] = 1 - - data["seals"] = "[src.canremove]" - data["sealing"] = "[src.sealing]" - data["helmet"] = (helmet ? "[helmet.name]" : "None.") - data["gauntlets"] = (gloves ? "[gloves.name]" : "None.") - data["boots"] = (boots ? "[boots.name]" : "None.") - data["chest"] = (chest ? "[chest.name]" : "None.") - - data["charge"] = cell ? round(cell.charge,1) : 0 - data["maxcharge"] = cell ? cell.maxcharge : 0 - data["chargestatus"] = cell ? FLOOR((cell.charge/cell.maxcharge)*50, 1) : 0 - - data["emagged"] = subverted - data["coverlock"] = locked - data["interfacelock"] = interface_locked - data["aicontrol"] = control_overridden - data["aioverride"] = ai_override_enabled - data["securitycheck"] = security_check_enabled - data["malf"] = malfunction_delay - - - var/list/module_list = list() - var/i = 1 - for(var/obj/item/rig_module/module in installed_modules) - var/list/module_data = list( - "index" = i, - "name" = "[module.interface_name]", - "desc" = "[module.interface_desc]", - "can_use" = "[module.usable]", - "can_select" = "[module.selectable]", - "can_toggle" = "[module.toggleable]", - "is_active" = "[module.active]", - "engagecost" = module.use_power_cost*10, - "activecost" = module.active_power_cost*10, - "passivecost" = module.passive_power_cost*10, - "engagestring" = module.engage_string, - "activatestring" = module.activate_string, - "deactivatestring" = module.deactivate_string, - "damage" = module.damage - ) - - if(module.charges && module.charges.len) - - module_data["charges"] = list() - var/datum/rig_charge/selected = module.charges[module.charge_selected] - module_data["chargetype"] = selected ? "[selected.display_name]" : "none" - - for(var/chargetype in module.charges) - var/datum/rig_charge/charge = module.charges[chargetype] - module_data["charges"] += list(list("caption" = "[chargetype] ([charge.charges])", "index" = "[chargetype]")) - - module_list += list(module_data) - i++ - - if(module_list.len) - data["modules"] = module_list - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, ((src.loc != user) ? ai_interface_path : interface_path), interface_title, 480, 550, state = nano_state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - /obj/item/weapon/rig/update_icon(var/update_mob_icon) //TODO: Maybe consider a cache for this (use mob_icon as blank canvas, use suit icon overlay). @@ -698,44 +629,6 @@ return 1 -//TODO: Fix Topic vulnerabilities for malfunction and AI override. -/obj/item/weapon/rig/Topic(href,href_list) - if(!check_suit_access(usr)) - return 0 - - if(href_list["toggle_piece"]) - if(ishuman(usr) && (usr.stat || usr.stunned || usr.lying)) - return 0 - toggle_piece(href_list["toggle_piece"], usr) - else if(href_list["toggle_seals"]) - toggle_seals(usr) - else if(href_list["interact_module"]) - - var/module_index = text2num(href_list["interact_module"]) - - if(module_index > 0 && module_index <= installed_modules.len) - var/obj/item/rig_module/module = installed_modules[module_index] - switch(href_list["module_mode"]) - if("activate") - module.activate() - if("deactivate") - module.deactivate() - if("engage") - module.engage() - if("select") - selected_module = module - if("select_charge_type") - module.charge_selected = href_list["charge_type"] - else if(href_list["toggle_ai_control"]) - ai_override_enabled = !ai_override_enabled - notify_ai("Synthetic suit control has been [ai_override_enabled ? "enabled" : "disabled"].") - else if(href_list["toggle_suit_lock"]) - locked = !locked - - usr.set_machine(src) - src.add_fingerprint(usr) - return 0 - /obj/item/weapon/rig/proc/notify_ai(var/message) for(var/obj/item/rig_module/ai_container/module in installed_modules) if(module.integrated_ai && module.integrated_ai.client && !module.integrated_ai.stat) @@ -814,6 +707,7 @@ if(istype(holder)) if(use_obj && check_slot == use_obj) to_chat(H, "Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.") + playsound(src, 'sound/machines/rig/rigservo.ogg', 10, FALSE) use_obj.canremove = 1 holder.drop_from_inventory(use_obj) use_obj.forceMove(get_turf(src)) @@ -832,6 +726,7 @@ return else to_chat(H, "Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.") + playsound(src, 'sound/machines/rig/rigservo.ogg', 10, FALSE) if(piece == "helmet" && helmet) helmet.update_light(H) diff --git a/code/modules/clothing/spacesuits/rig/rig_tgui.dm b/code/modules/clothing/spacesuits/rig/rig_tgui.dm new file mode 100644 index 00000000000..5fc1e173800 --- /dev/null +++ b/code/modules/clothing/spacesuits/rig/rig_tgui.dm @@ -0,0 +1,164 @@ +/* + * This defines the global UI for RIGSuits. + * It has all of the relevant TGUI procs, but it's entry point is in rig_verbs.dm + * as part of rig/proc/hardsuit_interface(). + */ + +/* + * tgui_interact() is the proc that opens the UI. It doesn't really do anything else, unlike NanoV1. + * We add an extra argument, custom_state, for the things that want a custom state for their UI. + */ +/obj/item/weapon/rig/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, (loc != usr ? ai_interface_path : interface_path), interface_title) + ui.open() + if(custom_state) + ui.set_state(custom_state) + +/* + * tgui_state() gives the UI the state to use by default. + */ +/obj/item/weapon/rig/tgui_state() + return GLOB.tgui_inventory_state + +/* + * tgui_status() is middlewere for objects to add little exceptions or special cases to the state they use. + * In this case, we're using it in order to make the UI refuse to let the user press any buttons if they're + * not authorized to do so. + * This saves us two lines of code in tgui_act(). + */ +/obj/item/weapon/rig/tgui_status(mob/user, datum/tgui_state/state) + . = ..() + if(!check_suit_access(user)) + // Forces the UI to never go interactive, + // but doesn't interfere with state saying to close. + . = min(., STATUS_UPDATE) + +/* + * tgui_data() is the heavy lifter, it gives the UI it's relevant datastructure every SStgui tick. + */ +/obj/item/weapon/rig/tgui_data(mob/user) + var/list/data = list() + + if(selected_module) + data["primarysystem"] = "[selected_module.interface_name]" + else + data["primarysystem"] = null + + if(loc != user) + data["ai"] = TRUE + else + data["ai"] = FALSE + + data["sealed"] = !canremove + data["sealing"] = sealing + data["helmet"] = (helmet ? "[helmet.name]" : "None.") + data["gauntlets"] = (gloves ? "[gloves.name]" : "None.") + data["boots"] = (boots ? "[boots.name]" : "None.") + data["chest"] = (chest ? "[chest.name]" : "None.") + + data["helmetDeployed"] = (helmet && helmet.loc == loc) + data["gauntletsDeployed"] = (gloves && gloves.loc == loc) + data["bootsDeployed"] = (boots && boots.loc == loc) + data["chestDeployed"] = (chest && chest.loc == loc) + + data["charge"] = cell ? round(cell.charge,1) : 0 + data["maxcharge"] = cell ? cell.maxcharge : 0 + data["chargestatus"] = cell ? FLOOR((cell.charge/cell.maxcharge)*50, 1) : 0 + + data["emagged"] = subverted + data["coverlock"] = locked + data["interfacelock"] = interface_locked + data["aicontrol"] = control_overridden + data["aioverride"] = ai_override_enabled + data["securitycheck"] = security_check_enabled + data["malf"] = malfunction_delay + + var/list/module_list = list() + if(!canremove && !sealing) + var/i = 1 + for(var/obj/item/rig_module/module in installed_modules) + var/list/module_data = list( + "index" = i, + "name" = "[module.interface_name]", + "desc" = "[module.interface_desc]", + "can_use" = module.usable, + "can_select" = module.selectable, + "can_toggle" = module.toggleable, + "is_active" = module.active, + "engagecost" = module.use_power_cost*10, + "activecost" = module.active_power_cost*10, + "passivecost" = module.passive_power_cost*10, + "engagestring" = module.engage_string, + "activatestring" = module.activate_string, + "deactivatestring" = module.deactivate_string, + "damage" = module.damage + ) + + if(module.charges && module.charges.len) + module_data["charges"] = list() + var/datum/rig_charge/selected = module.charges[module.charge_selected] + module_data["chargetype"] = selected ? "[selected.display_name]" : "none" + + for(var/chargetype in module.charges) + var/datum/rig_charge/charge = module.charges[chargetype] + module_data["charges"] += list(list("caption" = "[chargetype] ([charge.charges])", "index" = "[chargetype]")) + + module_list += list(module_data) + i++ + + if(module_list.len) + data["modules"] = module_list + else + data["modules"] = list() + + return data + +/* + * tgui_act() is the TGUI equivelent of Topic(). It's responsible for all of the "actions" you can take in the UI. + */ +/obj/item/weapon/rig/tgui_act(action, params) + // This parent call is very important, as it's responsible for invoking tgui_status and checking our state's rules. + if(..()) + return TRUE + + add_fingerprint(usr) + + switch(action) + if("toggle_seals") + toggle_seals(usr) + . = TRUE + if("toggle_ai_control") + ai_override_enabled = !ai_override_enabled + notify_ai("Synthetic suit control has been [ai_override_enabled ? "enabled" : "disabled"].") + . = TRUE + if("toggle_suit_lock") + locked = !locked + . = TRUE + if("toggle_piece") + if(ishuman(usr) && (usr.stat || usr.stunned || usr.lying)) + return FALSE + toggle_piece(params["piece"], usr) + . = TRUE + if("interact_module") + var/module_index = text2num(params["module"]) + + if(module_index > 0 && module_index <= installed_modules.len) + var/obj/item/rig_module/module = installed_modules[module_index] + switch(params["module_mode"]) + if("select") + selected_module = module + . = TRUE + if("engage") + module.engage() + . = TRUE + if("toggle") + if(module.active) + module.deactivate() + else + module.activate() + . = TRUE + if("select_charge_type") + module.charge_selected = params["charge_type"] + . = TRUE \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig/rig_verbs.dm b/code/modules/clothing/spacesuits/rig/rig_verbs.dm index 9f832ec911c..ea56adb1e63 100644 --- a/code/modules/clothing/spacesuits/rig/rig_verbs.dm +++ b/code/modules/clothing/spacesuits/rig/rig_verbs.dm @@ -7,7 +7,7 @@ set src = usr.contents if(wearer && (wearer.back == src || wearer.belt == src)) - ui_interact(usr) + tgui_interact(usr) /obj/item/weapon/rig/verb/toggle_vision() diff --git a/code/modules/clothing/spacesuits/rig/rig_wiring.dm b/code/modules/clothing/spacesuits/rig/rig_wiring.dm index 98f8a137028..c7fec3c5d6e 100644 --- a/code/modules/clothing/spacesuits/rig/rig_wiring.dm +++ b/code/modules/clothing/spacesuits/rig/rig_wiring.dm @@ -1,13 +1,11 @@ /datum/wires/rig - random = 1 + randomize = TRUE holder_type = /obj/item/weapon/rig wire_count = 5 -#define RIG_SECURITY 1 -#define RIG_AI_OVERRIDE 2 -#define RIG_SYSTEM_CONTROL 4 -#define RIG_INTERFACE_LOCK 8 -#define RIG_INTERFACE_SHOCK 16 +/datum/wires/rig/New(atom/_holder) + wires = list(WIRE_RIG_SECURITY, WIRE_RIG_AI_OVERRIDE, WIRE_RIG_SYSTEM_CONTROL, WIRE_RIG_INTERFACE_LOCK, WIRE_RIG_INTERFACE_SHOCK) + return ..() /* * Rig security can be snipped to disable ID access checks on rig. * Rig AI override can be pulsed to toggle whether or not the AI can take control of the suit. @@ -15,43 +13,41 @@ * Interface lock can be pulsed to toggle whether or not the interface can be accessed. */ -/datum/wires/rig/UpdateCut(var/index, var/mended) - +/datum/wires/rig/on_cut(wire, mend) var/obj/item/weapon/rig/rig = holder - switch(index) - if(RIG_SECURITY) - if(mended) + switch(wire) + if(WIRE_RIG_SECURITY) + if(mend) rig.req_access = initial(rig.req_access) rig.req_one_access = initial(rig.req_one_access) - if(RIG_INTERFACE_SHOCK) - rig.electrified = mended ? 0 : -1 + if(WIRE_RIG_INTERFACE_SHOCK) + rig.electrified = mend ? 0 : -1 rig.shock(usr,100) -/datum/wires/rig/UpdatePulsed(var/index) - +/datum/wires/rig/on_pulse(wire) var/obj/item/weapon/rig/rig = holder - switch(index) - if(RIG_SECURITY) + switch(wire) + if(WIRE_RIG_SECURITY) rig.security_check_enabled = !rig.security_check_enabled rig.visible_message("\The [rig] twitches as several suit locks [rig.security_check_enabled?"close":"open"].") - if(RIG_AI_OVERRIDE) + if(WIRE_RIG_AI_OVERRIDE) rig.ai_override_enabled = !rig.ai_override_enabled rig.visible_message("A small red light on [rig] [rig.ai_override_enabled?"goes dead":"flickers on"].") - if(RIG_SYSTEM_CONTROL) + if(WIRE_RIG_SYSTEM_CONTROL) rig.malfunctioning += 10 if(rig.malfunction_delay <= 0) rig.malfunction_delay = 20 rig.shock(usr,100) - if(RIG_INTERFACE_LOCK) + if(WIRE_RIG_INTERFACE_LOCK) rig.interface_locked = !rig.interface_locked rig.visible_message("\The [rig] clicks audibly as the software interface [rig.interface_locked?"darkens":"brightens"].") - if(RIG_INTERFACE_SHOCK) + if(WIRE_RIG_INTERFACE_SHOCK) if(rig.electrified != -1) rig.electrified = 30 rig.shock(usr,100) -/datum/wires/rig/CanUse(var/mob/living/L) +/datum/wires/rig/interactable(mob/user) var/obj/item/weapon/rig/rig = holder if(rig.open) - return 1 - return 0 \ No newline at end of file + return TRUE + return FALSE \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig/suits/robotics.dm b/code/modules/clothing/spacesuits/rig/suits/robotics.dm index 4fb43d355d5..2c8ba637af3 100644 --- a/code/modules/clothing/spacesuits/rig/suits/robotics.dm +++ b/code/modules/clothing/spacesuits/rig/suits/robotics.dm @@ -1,7 +1,7 @@ -//Mining suit +//Advanced Exploration Suit /obj/item/weapon/rig/robotics name = "advanced suit control belt" - suit_type = "advanced suit" + suit_type = "advanced" desc = "A lightweight suit combining the utility of a RIG with the wearability of a voidsuit." icon_state = "void_explorer2" slot_flags = SLOT_BELT @@ -14,8 +14,8 @@ rigsuit_max_pressure = 8 * ONE_ATMOSPHERE rigsuit_min_pressure = 0 - chest_type = /obj/item/clothing/suit/space/rig - helm_type = /obj/item/clothing/head/helmet/space/rig + chest_type = /obj/item/clothing/suit/space/rig/advsuit + helm_type = /obj/item/clothing/head/helmet/space/rig/advsuit boot_type = null glove_type = null cell_type = null @@ -27,3 +27,12 @@ req_access = list() req_one_access = list() + +/obj/item/clothing/head/helmet/space/rig/advsuit + name = "suit helmet" + +/obj/item/clothing/suit/space/rig/advsuit + name = "voidsuit" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS|FEET + heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS|FEET + cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS|FEET \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/void/ert.dm b/code/modules/clothing/spacesuits/void/ert.dm index a89ff26f074..b9fe70383da 100644 --- a/code/modules/clothing/spacesuits/void/ert.dm +++ b/code/modules/clothing/spacesuits/void/ert.dm @@ -44,6 +44,18 @@ ..() helmet = new /obj/item/clothing/head/helmet/space/void/responseteam/security //autoinstall the helmet +/obj/item/clothing/suit/space/void/responseteam/janitor + name = "Mark VII-J Emergency Cleanup Response Suit" + icon_state = "ertsuit_j" + item_state = "ertsuit_j" + armor = list(melee = 30, bullet = 20, laser = 20, energy = 20, bomb = 20, bio = 100, rad = 100) //awful armor + slowdown = 0 //light armor means no slowdown + item_flags = NOSLIP //INBUILT NANOGALOSHES + +/obj/item/clothing/suit/space/void/responseteam/janitor/Initialize() + ..() + helmet = new /obj/item/clothing/head/helmet/space/void/responseteam/janitor //autoinstall the helmet + /obj/item/clothing/suit/space/void/responseteam sprite_sheets = list( SPECIES_HUMAN = 'icons/mob/spacesuit_vr.dmi', @@ -137,6 +149,11 @@ icon_state = "erthelmet_s" item_state = "erthelmet_s" +/obj/item/clothing/head/helmet/space/void/responseteam/janitor + name = "Mark VII-J Emergency Cleanup Response Helmet" + icon_state = "erthelmet_j" + item_state = "erthelmet_j" + /obj/item/clothing/head/helmet/space/void/responseteam sprite_sheets = list( SPECIES_HUMAN = 'icons/mob/head_vr.dmi', diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm index 4ec3a49a2d1..7b4be66f222 100644 --- a/code/modules/clothing/spacesuits/void/station.dm +++ b/code/modules/clothing/spacesuits/void/station.dm @@ -158,19 +158,75 @@ //Medical Streamlined Voidsuit /obj/item/clothing/head/helmet/space/void/medical/alt name = "streamlined medical voidsuit helmet" - desc = "A trendy, lightly radiation-shielded voidsuit helmet trimmed in a sleek blue." + desc = "A trendy, lightly radiation-shielded voidsuit helmet trimmed in a sleek blue. It possesses advanced autoadaptive systems and doesn't need to be cycled to change species fit for most large humanoids." icon_state = "rig0-medicalalt" armor = list(melee = 20, bullet = 5, laser = 20,energy = 5, bomb = 15, bio = 100, rad = 30) light_overlay = "helmet_light_dual_blue" + species_restricted = list("exclude",SPECIES_DIONA,SPECIES_VOX,SPECIES_TESHARI) //this thing can autoadapt to most species, but diona/vox are too weird, and tesh are too small + no_cycle = TRUE + +/obj/item/clothing/head/helmet/space/void/medical/alt + sprite_sheets = list( + SPECIES_HUMAN = 'icons/mob/head.dmi', + SPECIES_TAJ = 'icons/mob/species/tajaran/helmet.dmi', + SPECIES_SKRELL = 'icons/mob/species/skrell/helmet.dmi', + SPECIES_UNATHI = 'icons/mob/species/unathi/helmet.dmi' + ) + sprite_sheets_obj = list( + SPECIES_TAJ = 'icons/obj/clothing/hats.dmi', + SPECIES_SKRELL = 'icons/obj/clothing/hats.dmi', + SPECIES_UNATHI = 'icons/obj/clothing/hats.dmi' + ) + +/obj/item/clothing/head/helmet/space/void/medical/alt/tesh + name = "streamlined teshari medical voidsuit helmet" + desc = "A trendy, lightly radiation-shielded voidsuit helmet trimmed in a sleek blue. This teshari-specific model lacks the autoadaption feature due to the reduced amount of materials." + species_restricted = list(SPECIES_TESHARI) + no_cycle = FALSE //no autoadaption means it can be refitted + +/obj/item/clothing/head/helmet/space/void/medical/alt/tesh + sprite_sheets = list( + SPECIES_TESHARI = 'icons/mob/species/seromi/head.dmi' + ) + sprite_sheets_obj = list( + SPECIES_TESHARI = 'icons/obj/clothing/hats.dmi' + ) + +/obj/item/clothing/suit/space/void/medical/alt + name = "streamlined medical voidsuit" + desc = "A more recent model of Vey-Med voidsuit, exchanging physical protection for fully unencumbered movement and a complete range of motion. It possesses advanced autoadaptive systems and doesn't need to be cycled to change species fit for most large humanoids." + icon_state = "rig-medicalalt" + slowdown = 0 + armor = list(melee = 20, bullet = 5, laser = 20,energy = 5, bomb = 15, bio = 100, rad = 30) + species_restricted = list("exclude",SPECIES_DIONA,SPECIES_VOX,SPECIES_TESHARI) //this thing can autoadapt, but diona/vox are too weird, and tesh are too small no_cycle = TRUE /obj/item/clothing/suit/space/void/medical/alt - icon_state = "rig-medicalalt" - name = "streamlined medical voidsuit" - desc = "A more recent model of Vey-Med voidsuit, exchanging physical protection for fully unencumbered movement and a complete range of motion." - slowdown = 0 - armor = list(melee = 20, bullet = 5, laser = 20,energy = 5, bomb = 15, bio = 100, rad = 30) - no_cycle = TRUE + sprite_sheets = list( + SPECIES_HUMAN = 'icons/mob/spacesuit.dmi', + SPECIES_TAJ = 'icons/mob/species/tajaran/suit.dmi', + SPECIES_SKRELL = 'icons/mob/species/skrell/suit.dmi', + SPECIES_UNATHI = 'icons/mob/species/unathi/suit.dmi' + ) + sprite_sheets_obj = list( + SPECIES_TAJ = 'icons/obj/clothing/spacesuits.dmi', + SPECIES_SKRELL = 'icons/obj/clothing/spacesuits.dmi', + SPECIES_UNATHI = 'icons/obj/clothing/spacesuits.dmi' + ) + +/obj/item/clothing/suit/space/void/medical/alt/tesh + name = "streamlined teshari medical voidsuit" + desc = "A more recent model of Vey-Med voidsuit, exchanging physical protection for fully unencumbered movement and a complete range of motion. This teshari-specific model lacks the autoadaption feature due to the reduced amount of materials." + species_restricted = list(SPECIES_TESHARI) + no_cycle = FALSE //no autoadaption means it can be refitted + +/obj/item/clothing/suit/space/void/medical/alt/tesh + sprite_sheets = list( + SPECIES_TESHARI = 'icons/mob/species/seromi/suit.dmi' + ) + sprite_sheets_obj = list( + SPECIES_TESHARI = 'icons/obj/clothing/spacesuits.dmi' + ) //Security /obj/item/clothing/head/helmet/space/void/security diff --git a/code/modules/clothing/spacesuits/void/station_vr.dm b/code/modules/clothing/spacesuits/void/station_vr.dm new file mode 100644 index 00000000000..0684095afbb --- /dev/null +++ b/code/modules/clothing/spacesuits/void/station_vr.dm @@ -0,0 +1,49 @@ +/obj/item/clothing/head/helmet/space/void/medical/alt + sprite_sheets = list( + SPECIES_HUMAN = 'icons/mob/head.dmi', + SPECIES_TAJ = 'icons/mob/species/tajaran/helmet.dmi', + SPECIES_SKRELL = 'icons/mob/species/skrell/helmet.dmi', + SPECIES_UNATHI = 'icons/mob/species/unathi/helmet.dmi', + SPECIES_XENOHYBRID = 'icons/mob/species/unathi/helmet.dmi', + SPECIES_AKULA = 'icons/mob/species/unathi/helmet.dmi', + SPECIES_SERGAL = 'icons/mob/species/unathi/helmet.dmi', + SPECIES_VULPKANIN = 'icons/mob/species/vulpkanin/helmet.dmi', + SPECIES_ZORREN_HIGH = 'icons/mob/species/vulpkanin/helmet.dmi', + SPECIES_FENNEC = 'icons/mob/species/vulpkanin/helmet.dmi' + ) + sprite_sheets_obj = list( + SPECIES_TAJ = 'icons/obj/clothing/hats.dmi', + SPECIES_SKRELL = 'icons/obj/clothing/hats.dmi', + SPECIES_UNATHI = 'icons/obj/clothing/hats.dmi', + SPECIES_XENOHYBRID = 'icons/obj/clothing/hats.dmi', + SPECIES_AKULA = 'icons/obj/clothing/hats.dmi', + SPECIES_SERGAL = 'icons/obj/clothing/hats.dmi', + SPECIES_VULPKANIN = 'icons/obj/clothing/hats.dmi', + SPECIES_ZORREN_HIGH = 'icons/obj/clothing/hats.dmi', + SPECIES_FENNEC = 'icons/obj/clothing/hats.dmi' + ) + +/obj/item/clothing/suit/space/void/medical/alt + sprite_sheets = list( + SPECIES_HUMAN = 'icons/mob/spacesuit.dmi', + SPECIES_TAJ = 'icons/mob/species/tajaran/suit.dmi', + SPECIES_SKRELL = 'icons/mob/species/skrell/suit.dmi', + SPECIES_UNATHI = 'icons/mob/species/unathi/suit.dmi', + SPECIES_XENOHYBRID = 'icons/mob/species/unathi/suit.dmi', + SPECIES_AKULA = 'icons/mob/species/akula/suit_vr.dmi', + SPECIES_SERGAL = 'icons/mob/species/sergal/suit_vr.dmi', + SPECIES_VULPKANIN = 'icons/mob/species/vulpkanin/suit.dmi', + SPECIES_ZORREN_HIGH = 'icons/mob/species/vulpkanin/suit.dmi', + SPECIES_FENNEC = 'icons/mob/species/vulpkanin/suit.dmi' + ) + sprite_sheets_obj = list( + SPECIES_TAJ = 'icons/obj/clothing/spacesuits.dmi', + SPECIES_SKRELL = 'icons/obj/clothing/spacesuits.dmi', + SPECIES_UNATHI = 'icons/obj/clothing/spacesuits.dmi', + SPECIES_XENOHYBRID = 'icons/obj/clothing/spacesuits.dmi', + SPECIES_AKULA = 'icons/obj/clothing/spacesuits.dmi', + SPECIES_SERGAL = 'icons/obj/clothing/spacesuits.dmi', + SPECIES_VULPKANIN = 'icons/obj/clothing/spacesuits.dmi', + SPECIES_ZORREN_HIGH = 'icons/obj/clothing/spacesuits.dmi', + SPECIES_FENNEC = 'icons/obj/clothing/spacesuits.dmi' + ) \ No newline at end of file diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 6aed5daf39b..5591100ca6f 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -4,16 +4,17 @@ icon = 'icons/obj/clothing/ties.dmi' icon_state = "bluetie" item_state_slots = list(slot_r_hand_str = "", slot_l_hand_str = "") + appearance_flags = RESET_COLOR // Stops has_suit's color from being multiplied onto the accessory slot_flags = SLOT_TIE w_class = ITEMSIZE_SMALL var/slot = ACCESSORY_SLOT_DECOR - var/obj/item/clothing/has_suit = null //the suit the tie may be attached to - var/image/inv_overlay = null //overlay used when attached to clothing. + var/obj/item/clothing/has_suit = null // The suit the tie may be attached to + var/image/inv_overlay = null // Overlay used when attached to clothing. var/image/mob_overlay = null var/overlay_state = null var/concealed_holster = 0 - var/mob/living/carbon/human/wearer = null //To check if the wearer changes, so species spritesheets change properly. - var/list/on_rolled = list() //used when jumpsuit sleevels are rolled ("rolled" entry) or it's rolled down ("down"). Set to "none" to hide in those states. + var/mob/living/carbon/human/wearer = null // To check if the wearer changes, so species spritesheets change properly. + var/list/on_rolled = list() // Used when jumpsuit sleevels are rolled ("rolled" entry) or it's rolled down ("down"). Set to "none" to hide in those states. sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/seromi/ties.dmi') //Teshari can into webbing, too! /obj/item/clothing/accessory/Destroy() @@ -29,6 +30,9 @@ inv_overlay = image(icon = icon_override, icon_state = tmp_icon_state, dir = SOUTH) else inv_overlay = image(icon = INV_ACCESSORIES_DEF_ICON, icon_state = tmp_icon_state, dir = SOUTH) + + inv_overlay.color = src.color + inv_overlay.appearance_flags = appearance_flags // Stops has_suit's color from being multiplied onto the accessory return inv_overlay /obj/item/clothing/accessory/proc/get_mob_overlay() @@ -65,6 +69,7 @@ else mob_overlay.color = src.color + mob_overlay.appearance_flags = appearance_flags // Stops has_suit's color from being multiplied onto the accessory return mob_overlay //when user attached an accessory to S @@ -72,8 +77,8 @@ if(!istype(S)) return has_suit = S - loc = has_suit - has_suit.overlays += get_inv_overlay() + src.forceMove(S) + has_suit.add_overlay(get_inv_overlay()) if(user) to_chat(user, "You attach \the [src] to \the [has_suit].") @@ -82,7 +87,7 @@ /obj/item/clothing/accessory/proc/on_removed(var/mob/user) if(!has_suit) return - has_suit.overlays -= get_inv_overlay() + has_suit.cut_overlay(get_inv_overlay()) has_suit = null if(user) usr.put_in_hands(src) @@ -325,6 +330,12 @@ name = "striped blue scarf" icon_state = "stripedbluescarf" +/obj/item/clothing/accessory/scarf/teshari/neckscarf + name = "small neckscarf" + desc = "a neckscarf that is too small for a human's neck" + icon_state = "tesh_neckscarf" + species_restricted = list(SPECIES_TESHARI) + //bracelets /obj/item/clothing/accessory/bracelet diff --git a/code/modules/clothing/under/accessories/clothing.dm b/code/modules/clothing/under/accessories/clothing.dm index bee36652833..775a615dc75 100644 --- a/code/modules/clothing/under/accessories/clothing.dm +++ b/code/modules/clothing/under/accessories/clothing.dm @@ -383,7 +383,7 @@ /obj/item/clothing/accessory/cowledvest name = "cowled vest" - desc = "A body warmer for the 26th century." + desc = "A body warmer for the 24th century." //VOREStation Edit icon_state = "cowled_vest" /obj/item/clothing/accessory/asymmetric @@ -399,4 +399,9 @@ /obj/item/clothing/accessory/asymmetric/green name = "green asymmetrical jacket" desc = "Insultingly avant-garde in aqua." - icon_state = "asym_green" \ No newline at end of file + icon_state = "asym_green" + +/obj/item/clothing/accessory/asymovercoat + name = "orange asymmetrical overcoat" + desc = "An asymmetrical orange overcoat in a 2560's fashion." + icon_state = "asymovercoat" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 800ba8e3ecd..3cc22185d40 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -535,6 +535,37 @@ desc = "A red and white dress themed after some winter holidays. Tastefully festive!" icon_state = "festivedress" +/obj/item/clothing/under/dress/revealingdress + name = "revealing dress" + desc = "A very revealing black and blue dress. Is this work appropriate?" + icon_state = "revealingdress" + index = 1 + +/obj/item/clothing/under/dress/gothic + name = "gothic dress" + desc = "A black dress with a sheer mesh over it, tastefully old school goth." + icon_state = "gothic" + index = 1 + +/obj/item/clothing/under/dress/formalred + name = "formal red dress" + desc = "A very formal red dress, for those fancy galas." + icon_state = "formalred" + flags_inv = HIDESHOES + index = 1 + +/obj/item/clothing/under/dress/pentagram + name = "pentagram dress" + desc = "A black dress with straps over the chest in the shape of a pentagram." + icon_state = "pentagram" + index = 1 + +obj/item/clothing/under/dress/yellowswoop + name = "yellow swooped dress" + desc = "A yellow dress that swoops to the side." + icon_state = "yellowswoop" + index = 1 + /* * wedding stuff */ @@ -767,6 +798,24 @@ Uniforms and such desc = "Jean shorts and a black halter top. Perfect for casual Fridays!" icon_state = "haltertop" +/obj/item/clothing/under/rippedpunk + name = "ripped punk jeans" + desc = "Black ripped jeans and a fishnet top. How punk." + icon_state = "rippedpunk" + index = 1 + +/obj/item/clothing/under/greenasym + name = "green asymmetrical jumpsuit" + desc = "A green futuristic uniform with asymmetrical pants. Trendy!" + icon_state = "greenasym" + index = 1 + +/obj/item/clothing/under/cyberpunkharness + name = "cyberpunk strapped harness" + desc = "A cyberpunk styled harness and pants. Perfect for your dystopian future." + icon_state = "cyberhell" + index = 1 + /* * swimsuit */ diff --git a/code/modules/clothing/under/xenos/seromi.dm b/code/modules/clothing/under/xenos/seromi.dm index 0e43030ade6..5126ab14604 100644 --- a/code/modules/clothing/under/xenos/seromi.dm +++ b/code/modules/clothing/under/xenos/seromi.dm @@ -45,6 +45,22 @@ name = "small formal uniform" icon_state = "seromi_captain_formal" +/obj/item/clothing/under/seromi/smock/blackutilitysmock + name = "black utility smock" + icon_state = "teshari_blackutility_com" + +/obj/item/clothing/under/seromi/smock/greydress + name = "small grey dress" + icon_state = "teshari_greydress" + +/obj/item/clothing/under/seromi/smock/blackutility + name = "Teshari utility uniform" + icon_state = "teshari_blackutility" + +/obj/item/clothing/under/seromi/smock/bluegreydress + name = "small blue and grey dress" + icon_state = "teshari_bluegreydress" + /obj/item/clothing/under/seromi/undercoat name = "Undercoat" desc = "A Teshari traditional garb, with a modern twist! Made of micro and nanofibres to make it light and billowy, perfect for going fast and stylishly!" @@ -179,6 +195,66 @@ icon_state = "tesh_uniform_brg" item_state = "tesh_uniform_brg" +/obj/item/clothing/under/seromi/undercoat/standard/blackredworksuit + name = "small black and red worksuit" + icon_state = "teshari_black_red_worksuit" + item_state = "teshari_black_red_worksuit" + desc = "A small worksuit designed for a Teshari" + +/obj/item/clothing/under/seromi/undercoat/standard/blackpurpleworksuit + name = "small black and purple worksuit" + icon_state = "teshari_black_purple_worksuit" + item_state = "teshari_black_purple_worksuit" + desc = "A small worksuit designed for a Teshari" + +/obj/item/clothing/under/seromi/undercoat/standard/blackpurpleworksuit + name = "small black and orange worksuit" + icon_state = "teshari_black_orange_worksuit" + item_state = "teshari_black_orange_worksuit" + desc = "A small worksuit designed for a Teshari" + +/obj/item/clothing/under/seromi/undercoat/standard/blackblueworksuit + name = "small black and blue worksuit" + icon_state = "teshari_black_blue_worksuit" + item_state = "teshari_black_blue_worksuit" + desc = "A small worksuit designed for a Teshari" + +/obj/item/clothing/under/seromi/undercoat/standard/blackgreenworksuit + name = "small black and greeen worksuit" + icon_state = "teshari_black_green_worksuit" + item_state = "teshari_black_green_worksuit" + desc = "A small worksuit designed for a Teshari" + +/obj/item/clothing/under/seromi/undercoat/standard/whiteredworksuit + name = "small white and red worksuit" + icon_state = "teshari_white_red_worksuit" + item_state = "teshari_white_red_worksuit" + desc = "A small worksuit designed for a Teshari" + +/obj/item/clothing/under/seromi/undercoat/standard/whitepurpleworksuit + name = "small white and purple worksuit" + icon_state = "teshari_white_purple_worksuit" + item_state = "teshari_white_purple_worksuit" + desc = "A small worksuit designed for a Teshari" + +/obj/item/clothing/under/seromi/undercoat/standard/whiteorangeworksuit + name = "small white and orange worksuit" + icon_state = "teshari_white_orange_worksuit" + item_state = "teshari_white_orange_worksuit" + desc = "A small worksuit designed for a Teshari" + +/obj/item/clothing/under/seromi/undercoat/standard/whiteblueworksuit + name = "small white and blue worksuit" + icon_state = "teshari_white_blue_worksuit" + item_state = "teshari_white_blue_worksuit" + desc = "A small worksuit designed for a Teshari" + +/obj/item/clothing/under/seromi/undercoat/standard/whitegreenworksuit + name = "small white and green worksuit" + icon_state = "teshari_white_green_worksuit" + item_state = "teshari_white_green_worksuit" + desc = "A small worksuit designed for a Teshari" + /obj/item/clothing/under/seromi/undercoat/jobs icon = 'icons/mob/species/seromi/deptjacket.dmi' icon_override = 'icons/mob/species/seromi/deptjacket.dmi' @@ -295,4 +371,4 @@ name = "internal affairs undercoat" desc = "A traditional Teshari garb made for the Internal Affairs Agent" icon_state = "tesh_uniform_iaa" - item_state = "tesh_uniform_iaa" + item_state = "tesh_uniform_iaa" \ No newline at end of file diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index 2e5223420a3..dd22e7c22e9 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -109,29 +109,37 @@ T.clean(src, user) //VOREStation Edit End /obj/item/weapon/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag) - if(isliving(target)) + if(isliving(target)) //Leaving this as isliving. var/mob/living/M = target - if(on_fire) + if(on_fire) //Check if rag is on fire, if so igniting them and stopping. user.visible_message("\The [user] hits [target] with [src]!",) user.do_attack_animation(src) M.IgniteMob() - else if(reagents.total_volume) - if(user.zone_sel.selecting == O_MOUTH) - user.do_attack_animation(src) - user.visible_message( - "\The [user] smothers [target] with [src]!", - "You smother [target] with [src]!", - "You hear some struggling and muffled cries of surprise" - ) - - //it's inhaled, so... maybe CHEM_BLOOD doesn't make a whole lot of sense but it's the best we can do for now - reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BLOOD) - update_name() + else if(user.zone_sel.selecting == O_MOUTH) //Check player target location, provided the rag is not on fire. Then check if mouth is exposed. + if(ishuman(target)) //Added this since player species process reagents in majority of cases. + var/mob/living/carbon/human/H = target + if(H.head && (H.head.body_parts_covered & FACE)) //Check human head coverage. + to_chat(user, "Remove their [H.head] first.") + return + else if(reagents.total_volume) //Final check. If the rag is not on fire and their face is uncovered, smother target. + user.do_attack_animation(src) + user.visible_message( + "\The [user] smothers [target] with [src]!", + "You smother [target] with [src]!", + "You hear some struggling and muffled cries of surprise" + ) + //it's inhaled, so... maybe CHEM_BLOOD doesn't make a whole lot of sense but it's the best we can do for now + reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BLOOD) + update_name() + else + to_chat(user, "You can't smother this creature.") else - wipe_down(target, user) - return - - return ..() + to_chat(user, "You can't smother this creature.") + else + wipe_down(target, user) + else + wipe_down(target, user) + return /obj/item/weapon/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user as mob, proximity) if(!proximity) diff --git a/code/modules/detectivework/tools/scanner.dm b/code/modules/detectivework/tools/scanner.dm index b917ddcf38e..a3b813f96fb 100644 --- a/code/modules/detectivework/tools/scanner.dm +++ b/code/modules/detectivework/tools/scanner.dm @@ -139,7 +139,7 @@ set category = "Object" set src in view(1) - to_world("usr is [usr]") + //to_world("usr is [usr]") //why was this a thing? -KK. display_data(usr) /obj/item/device/detective_scanner/proc/display_data(var/mob/user) diff --git a/code/modules/events/camera_damage.dm b/code/modules/events/camera_damage.dm index 6a86581b706..596bc348a8c 100644 --- a/code/modules/events/camera_damage.dm +++ b/code/modules/events/camera_damage.dm @@ -17,9 +17,9 @@ if(prob(2*severity)) cam.destroy() else - cam.wires.UpdateCut(CAMERA_WIRE_POWER, 0) + cam.wires.cut(WIRE_MAIN_POWER1) if(prob(5*severity)) - cam.wires.UpdateCut(CAMERA_WIRE_ALARM, 0) + cam.wires.cut(WIRE_CAM_ALARM) /datum/event/camera_damage/proc/acquire_random_camera(var/remaining_attempts = 5) if(!cameranet.cameras.len) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 64a31b5bb2d..d4c41e06427 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -168,12 +168,12 @@ mob/living/carbon/proc/handle_hallucinations() if(71 to 72) //Fake death // src.sleeping_willingly = 1 - src.sleeping = 20 + SetSleeping(20) hal_crit = 1 hal_screwyhud = 1 spawn(rand(50,100)) // src.sleeping_willingly = 0 - src.sleeping = 0 + SetSleeping(0) hal_crit = 0 hal_screwyhud = 0 handling_hal = 0 diff --git a/code/modules/food/drinkingglass/metaglass.dm b/code/modules/food/drinkingglass/metaglass.dm index c67f8164199..48d6696f00c 100644 --- a/code/modules/food/drinkingglass/metaglass.dm +++ b/code/modules/food/drinkingglass/metaglass.dm @@ -670,4 +670,4 @@ Drinks Data glass_center_of_mass = list("x"=16, "y"=8) /datum/reagent/ethanol/mojito - glass_icon_state = "mojito" \ No newline at end of file + glass_icon_state = "mojito" diff --git a/code/modules/food/drinkingglass/metaglass_vr.dm b/code/modules/food/drinkingglass/metaglass_vr.dm index 305077f3870..887c752ba60 100644 --- a/code/modules/food/drinkingglass/metaglass_vr.dm +++ b/code/modules/food/drinkingglass/metaglass_vr.dm @@ -118,6 +118,11 @@ glass_center_of_mass = list("x"=16, "y"=8) glass_icon_file = 'icons/obj/drinks_vr.dmi' +/datum/reagent/ethanol/pink_moo + glass_icon_state = "pinkmooglass" + glass_center_of_mass = list("x"=16, "y"=9) + glass_icon_file = 'icons/obj/drinks_vr.dmi' + /datum/reagent/drink/soda/kiraspecial glass_icon_file = 'icons/obj/drinks_vr.dmi' diff --git a/code/modules/food/food/condiment.dm b/code/modules/food/food/condiment.dm index 657946d0192..e005d713305 100644 --- a/code/modules/food/food/condiment.dm +++ b/code/modules/food/food/condiment.dm @@ -115,6 +115,17 @@ desc = "This is what you use to make bread fluffy." icon_state = "yeast" center_of_mass = list("x"=16, "y"=6) + if("spacespice") + name = "bottle of space spice" + desc = "An exotic blend of spices for cooking. Definitely not worms." + icon = 'icons/obj/food_syn.dmi' + icon_state = "spacespicebottle" + center_of_mass = list("x"=16, "y"=6) + if("barbecue") + name = "barbecue sauce" + desc = "Barbecue sauce, it's labeled 'sweet and spicy'." + icon_state = "barbecue" + center_of_mass = list("x"=16, "y"=6) else name = "Misc Condiment Bottle" if (reagents.reagent_list.len==1) @@ -408,6 +419,7 @@ desc = "A big bag of flour. Good for baking!" icon = 'icons/obj/food.dmi' icon_state = "flour" + volume = 220 center_of_mass = list("x"=16, "y"=8) /obj/item/weapon/reagent_containers/food/condiment/flour/on_reagent_change() @@ -415,5 +427,21 @@ /obj/item/weapon/reagent_containers/food/condiment/flour/Initialize() . = ..() - reagents.add_reagent("flour", 30) - randpixel_xy() \ No newline at end of file + reagents.add_reagent("flour", 200) + randpixel_xy() + +/obj/item/weapon/reagent_containers/food/condiment/spacespice + name = "space spices" + desc = "An exotic blend of spices for cooking. Definitely not worms." + icon = 'icons/obj/food_syn.dmi' + icon_state = "spacespicebottle" + possible_transfer_amounts = list(1,40) //for clown turning the lid off + amount_per_transfer_from_this = 1 + volume = 40 + +/obj/item/weapon/reagent_containers/food/condiment/spacespice/on_reagent_change() + return + +/obj/item/weapon/reagent_containers/food/condiment/spacespice/Initialize() + . = ..() + reagents.add_reagent("spacespice", 40) \ No newline at end of file diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm index 72ac7787ce2..d65679f6f73 100644 --- a/code/modules/food/food/snacks.dm +++ b/code/modules/food/food/snacks.dm @@ -14,6 +14,12 @@ var/survivalfood = FALSE var/nutriment_amt = 0 var/list/nutriment_desc = list("food" = 1) + var/datum/reagent/nutriment/coating/coating = null + var/icon/flat_icon = null //Used to cache a flat icon generated from dipping in batter. This is used again to make the cooked-batter-overlay + var/do_coating_prefix = 1 //If 0, we wont do "battered thing" or similar prefixes. Mainly for recipes that include batter but have a special name + var/cooked_icon = null //Used for foods that are "cooked" without being made into a specific recipe or combination. + //Generally applied during modification cooking with oven/fryer + //Used to stop deepfried meat from looking like slightly tanned raw meat, and make it actually look cooked center_of_mass = list("x"=16, "y"=16) w_class = ITEMSIZE_SMALL force = 0 @@ -150,6 +156,8 @@ /obj/item/weapon/reagent_containers/food/snacks/examine(mob/user) . = ..() if(Adjacent(user)) + if(coating) + . += "It's coated in [coating.name]!" if(bitecount==0) return . else if (bitecount==1) @@ -161,7 +169,7 @@ /obj/item/weapon/reagent_containers/food/snacks/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W,/obj/item/weapon/storage)) - ..() // -> item/attackby() + . = ..() // -> item/attackby() return // Eating with forks @@ -273,8 +281,8 @@ // name = "Xenoburger" //Name that displays in the UI. // desc = "Smells caustic. Tastes like heresy." //Duh // icon_state = "xburger" //Refers to an icon in food.dmi -// New() //Don't mess with this. -// ..() //Same here. +// Initialize() //Don't mess with this. (We use Initialize now instead of New()) +// . = ..() //Same here. // reagents.add_reagent("xenomicrobes", 10) //This is what is in the food item. you may copy/paste // reagents.add_reagent("nutriment", 2) // this line of code for all the contents. // bitesize = 3 //This is the amount each bite consumes. @@ -349,7 +357,7 @@ nutriment_desc = list("candy corn" = 4) /obj/item/weapon/reagent_containers/food/snacks/candy_corn/Initialize() - ..() + . = ..() reagents.add_reagent("sugar", 2) bitesize = 2 @@ -589,7 +597,7 @@ /obj/item/weapon/reagent_containers/food/snacks/egg/afterattack(obj/O as obj, mob/user as mob, proximity) if(istype(O,/obj/machinery/microwave)) - return ..() + return . = ..() if(!(proximity && O.is_open_container())) return to_chat(user, "You crack \the [src] into \the [O].") @@ -598,7 +606,7 @@ qdel(src) /obj/item/weapon/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) - ..() + . = ..() new/obj/effect/decal/cleanable/egg_smudge(src.loc) src.reagents.splash(hit_atom, reagents.total_volume) src.visible_message("[src.name] has been squashed.","You hear a smack.") @@ -616,7 +624,7 @@ to_chat(usr, "You color \the [src] [clr]") icon_state = "egg-[clr]" else - ..() + . = ..() /obj/item/weapon/reagent_containers/food/snacks/egg/blue icon_state = "egg-blue" @@ -1116,7 +1124,7 @@ bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/pie/throw_impact(atom/hit_atom) - ..() + . = ..() new/obj/effect/decal/cleanable/pie_smudge(src.loc) src.visible_message("\The [src.name] splats.","You hear a splat.") qdel(src) @@ -1234,7 +1242,7 @@ nutriment_desc = list("sweetness" = 3, "mushroom" = 3, "pie" = 2) /obj/item/weapon/reagent_containers/food/snacks/amanita_pie/Initialize() - ..() + . = ..() reagents.add_reagent("amatoxin", 3) reagents.add_reagent("psilocybin", 1) bitesize = 3 @@ -1249,7 +1257,7 @@ nutriment_desc = list("heartiness" = 2, "mushroom" = 3, "pie" = 3) /obj/item/weapon/reagent_containers/food/snacks/plump_pie/Initialize() - ..() + . = ..() if(prob(10)) name = "exceptional plump pie" desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump pie!" @@ -1363,7 +1371,7 @@ if(prob(unpopped)) //lol ...what's the point? to_chat(usr, "You bite down on an un-popped kernel!") unpopped = max(0, unpopped-1) - ..() + . = ..() /obj/item/weapon/reagent_containers/food/snacks/sosjerky name = "Scaredy's Private Reserve Beef Jerky" @@ -1374,7 +1382,7 @@ center_of_mass = list("x"=15, "y"=9) /obj/item/weapon/reagent_containers/food/snacks/sosjerky/Initialize() - ..() + . = ..() reagents.add_reagent("protein", 4) bitesize = 2 @@ -1389,7 +1397,7 @@ nutriment_desc = list("dried raisins" = 6) /obj/item/weapon/reagent_containers/food/snacks/no_raisin/Initialize() - ..() + . = ..() reagents.add_reagent("nutriment", 6) /obj/item/weapon/reagent_containers/food/snacks/spacetwinkie @@ -1663,7 +1671,7 @@ /obj/item/weapon/reagent_containers/food/snacks/slimesoup name = "slime soup" desc = "If no water is available, you may substitute tears." - icon_state = "rorosoup" //nonexistant? - 3/1/2020 FIXED. roro's live on. + icon_state = "slimesoup" //nonexistant? - 3/1/2020 FIXED. roro's live on. - 7/14/2020 - The fuck are you smoking, roro's is stupid, name it slimesoup so it's clear wtf it is. filling_color = "#C4DBA0" /obj/item/weapon/reagent_containers/food/snacks/slimesoup/Initialize() @@ -2404,9 +2412,9 @@ reagents.add_reagent("peanutbutter", 5) /obj/item/weapon/reagent_containers/food/snacks/boiledslimecore - name = "Boiled slime Core" + name = "Boiled Slime Core" desc = "A boiled red thing." - icon_state = "boiledslimecore" //nonexistant? + icon_state = "boiledslimecore" /obj/item/weapon/reagent_containers/food/snacks/boiledslimecore/Initialize() . = ..() @@ -3437,7 +3445,7 @@ update_icon() return - ..() + . = ..() /obj/item/pizzabox/margherita/Initialize() pizza = new /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita(src) @@ -3576,7 +3584,7 @@ qdel(src) return else - ..() + . = ..() // Human Burger + cheese wedge = cheeseburger /obj/item/weapon/reagent_containers/food/snacks/human/burger/attackby(obj/item/weapon/reagent_containers/food/snacks/cheesewedge/W as obj, mob/user as mob) @@ -3587,7 +3595,7 @@ qdel(src) return else - ..() + . = ..() /obj/item/weapon/reagent_containers/food/snacks/bunbun name = "\improper Bun Bun" @@ -3693,7 +3701,7 @@ to_chat(user, "You remove the seeds from the flower, slightly damaging them.") qdel(src) else - ..() + . = ..() /obj/item/weapon/reagent_containers/food/snacks/rawsticks name = "raw potato sticks" @@ -3767,7 +3775,7 @@ center_of_mass = list("x"=16, "y"=15) /obj/item/weapon/reagent_containers/food/snacks/liquidprotein/Initialize() - ..() + . = ..() reagents.add_reagent("protein", 30) reagents.add_reagent("iron", 3) bitesize = 4 @@ -3782,7 +3790,7 @@ center_of_mass = list("x"=16, "y"=15) /obj/item/weapon/reagent_containers/food/snacks/liquidvitamin/Initialize() - ..() + . = ..() reagents.add_reagent("flour", 20) reagents.add_reagent("tricordrazine", 5) reagents.add_reagent("paracetamol", 5) @@ -3838,10 +3846,10 @@ center_of_mass = list("x"=15, "y"=9) /obj/item/weapon/reagent_containers/food/snacks/unajerky/Initialize() - ..() - reagents.add_reagent("protein", 8) - reagents.add_reagent("capsaicin", 2) - bitesize = 2 + . =..() + reagents.add_reagent("protein", 8) + reagents.add_reagent("capsaicin", 2) + bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/croissant name = "croissant" @@ -3869,7 +3877,7 @@ /obj/item/weapon/reagent_containers/food/snacks/sashimi name = "carp sashimi" - desc = "Expertly prepared. Hopefully toxin got removed though." + desc = "Expertly prepared. Hopefully the toxins got removed." filling_color = "#FFDEFE" icon_state = "sashimi" nutriment_amt = 6 @@ -3922,7 +3930,7 @@ filling_color = "#E0CF9B" center_of_mass = list("x"=17, "y"=4) nutriment_amt = 6 - nutriment_desc = list("sweetness" = 2, "muffin" = 2) + nutriment_desc = list("sweetness" = 2, "muffin" = 2, "berries" = 2) /obj/item/weapon/reagent_containers/food/snacks/berrymuffin/Initialize() . = ..() @@ -4341,3 +4349,1702 @@ if(pixel_x || pixel_y) A.pixel_x = pixel_x A.pixel_y = pixel_y + +/obj/item/weapon/reagent_containers/food/snacks/macncheese + name = "macaroni and cheese" + desc = "The perfect combination of noodles and dairy." + icon = 'icons/obj/food.dmi' + icon_state = "macncheese" + trash = /obj/item/trash/snack_bowl + center_of_mass = list("x"=16, "y"=16) + nutriment_amt = 9 + nutriment_desc = list("Cheese" = 5, "pasta" = 4, "happiness" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/macncheese/Initialize() + . = ..() + bitesize = 3 + +//Code for dipping food in batter +/obj/item/weapon/reagent_containers/food/snacks/afterattack(obj/O as obj, mob/user as mob, proximity) + if(O.is_open_container() && O.reagents && !(istype(O, /obj/item/weapon/reagent_containers/food)) && proximity) + for (var/r in O.reagents.reagent_list) + + var/datum/reagent/R = r + if (istype(R, /datum/reagent/nutriment/coating)) + if (apply_coating(R, user)) + return 1 + + return . = ..() + +//This proc handles drawing coatings out of a container when this food is dipped into it +/obj/item/weapon/reagent_containers/food/snacks/proc/apply_coating(var/datum/reagent/nutriment/coating/C, var/mob/user) + if (coating) + to_chat(user, "The [src] is already coated in [coating.name]!") + return 0 + + //Calculate the reagents of the coating needed + var/req = 0 + for (var/r in reagents.reagent_list) + var/datum/reagent/R = r + if (istype(R, /datum/reagent/nutriment)) + req += R.volume * 0.2 + else + req += R.volume * 0.1 + + req += w_class*0.5 + + if (!req) + //the food has no reagents left, its probably getting deleted soon + return 0 + + if (C.volume < req) + to_chat("There's not enough [C.name] to coat the [src]!") + return 0 + + var/id = C.id + + //First make sure there's space for our batter + if (reagents.get_free_space() < req+5) + var/extra = req+5 - reagents.get_free_space() + reagents.maximum_volume += extra + + //Suck the coating out of the holder + C.holder.trans_to_holder(reagents, req) + + //We're done with C now, repurpose the var to hold a reference to our local instance of it + C = reagents.get_reagent(id) + if (!C) + return + + coating = C + //Now we have to do the witchcraft with masking images + //var/icon/I = new /icon(icon, icon_state) + + if (!flat_icon) + flat_icon = getFlatIcon(src) + var/icon/I = flat_icon + color = "#FFFFFF" //Some fruits use the color var. Reset this so it doesnt tint the batter + I.Blend(new /icon('icons/obj/food_custom.dmi', rgb(255,255,255)),ICON_ADD) + I.Blend(new /icon('icons/obj/food_custom.dmi', coating.icon_raw),ICON_MULTIPLY) + var/image/J = image(I) + J.alpha = 200 + J.blend_mode = BLEND_OVERLAY + J.tag = "coating" + overlays += J + + if (user) + user.visible_message(span("notice", "[user] dips \the [src] into \the [coating.name]"), span("notice", "You dip \the [src] into \the [coating.name]")) + + return 1 + + +//Called by cooking machines. This is mainly intended to set properties on the food that differ between raw/cooked +/obj/item/weapon/reagent_containers/food/snacks/proc/cook() + if (coating) + var/list/temp = overlays.Copy() + for (var/i in temp) + if (istype(i, /image)) + var/image/I = i + if (I.tag == "coating") + temp.Remove(I) + break + + overlays = temp + //Carefully removing the old raw-batter overlay + + if (!flat_icon) + flat_icon = getFlatIcon(src) + var/icon/I = flat_icon + color = "#FFFFFF" //Some fruits use the color var + I.Blend(new /icon('icons/obj/food_custom.dmi', rgb(255,255,255)),ICON_ADD) + I.Blend(new /icon('icons/obj/food_custom.dmi', coating.icon_cooked),ICON_MULTIPLY) + var/image/J = image(I) + J.alpha = 200 + J.tag = "coating" + overlays += J + + + if (do_coating_prefix == 1) + name = "[coating.coated_adj] [name]" + + for (var/r in reagents.reagent_list) + var/datum/reagent/R = r + if (istype(R, /datum/reagent/nutriment/coating)) + var/datum/reagent/nutriment/coating/C = R + C.data["cooked"] = 1 + C.name = C.cooked_name + +/obj/item/weapon/reagent_containers/food/snacks/proc/on_consume(var/mob/eater, var/mob/feeder = null) + if(!reagents.total_volume) + eater.visible_message("[eater] finishes eating \the [src].","You finish eating \the [src].") + + if (!feeder) + feeder = eater + + feeder.drop_from_inventory(src) //so icons update :[ //what the fuck is this???? + + if(trash) + if(ispath(trash,/obj/item)) + var/obj/item/TrashItem = new trash(feeder) + feeder.put_in_hands(TrashItem) + else if(istype(trash,/obj/item)) + feeder.put_in_hands(trash) + qdel(src) + return +//////////////////////////////////////////////////////////////////////////////// +/// FOOD END +//////////////////////////////////////////////////////////////////////////////// + +/mob/living + var/composition_reagent + var/composition_reagent_quantity + +/mob/living/simple_mob/adultslime + composition_reagent = "slimejelly" + +/mob/living/carbon/slime + composition_reagent = "slimejelly" + +/mob/living/carbon/alien/diona + composition_reagent = "nutriment"//Dionae are plants, so eating them doesn't give animal protein + +/mob/living/simple_mob/slime + composition_reagent = "slimejelly" + +/mob/living/simple_mob + var/kitchen_tag = "animal" //Used for cooking with animals + +/mob/living/simple_mob/mouse + kitchen_tag = "rodent" + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel + slices_num = 8 + +/obj/item/weapon/reagent_containers/food/snacks/sausage/battered + name = "battered sausage" + desc = "A piece of mixed, long meat, battered and then deepfried." + icon = 'icons/obj/food_syn.dmi' + icon_state = "batteredsausage" + filling_color = "#DB0000" + center_of_mass = list("x"=16, "y"=16) + do_coating_prefix = 0 + bitesize = 2 + + +/obj/item/weapon/reagent_containers/food/snacks/sausage/battered/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + reagents.add_reagent("batter", 1.7) + reagents.add_reagent("oil", 1.5) + +/obj/item/weapon/reagent_containers/food/snacks/jalapeno_poppers + name = "jalapeno popper" + desc = "A battered, deep-fried chilli pepper." + icon = 'icons/obj/food_syn.dmi' + icon_state = "popper" + filling_color = "#00AA00" + center_of_mass = list("x"=10, "y"=6) + do_coating_prefix = 0 + nutriment_amt = 2 + nutriment_desc = list("chilli pepper" = 2) + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/jalapeno_poppers/Initialize() + . = ..() + reagents.add_reagent("batter", 2) + reagents.add_reagent("oil", 2) + +/obj/item/weapon/reagent_containers/food/snacks/mouseburger + name = "mouse burger" + desc = "Squeaky and a little furry." + icon = 'icons/obj/food_syn.dmi' + icon_state = "ratburger" + center_of_mass = list("x"=16, "y"=11) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/mouseburger/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + +/obj/item/weapon/reagent_containers/food/snacks/chickenkatsu + name = "chicken katsu" + desc = "A Terran delicacy consisting of chicken fried in a light beer batter." + icon = 'icons/obj/food_syn.dmi' + icon_state = "katsu" + trash = /obj/item/trash/plate + filling_color = "#E9ADFF" + center_of_mass = list("x"=16, "y"=16) + do_coating_prefix = 0 + +/obj/item/weapon/reagent_containers/food/snacks/chickenkatsu/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + reagents.add_reagent("beerbatter", 2) + reagents.add_reagent("oil", 1) + bitesize = 1.5 + +/obj/item/weapon/reagent_containers/food/snacks/fries + nutriment_amt = 4 + nutriment_desc = list("fries" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/fries/Initialize() + . = ..() + reagents.add_reagent("oil", 1.2)//This is mainly for the benefit of adminspawning + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/microchips + name = "micro chips" + desc = "Soft and rubbery, should have fried them. Good for smaller crewmembers, maybe?" + icon = 'icons/obj/food_syn.dmi' + icon_state = "microchips" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + nutriment_amt = 4 + nutriment_desc = list("soggy fries" = 4) + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/microchips/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/ovenchips + name = "oven chips" + desc = "Dark and crispy, but a bit dry." + icon = 'icons/obj/food_syn.dmi' + icon_state = "ovenchips" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + nutriment_amt = 4 + nutriment_desc = list("crisp, dry fries" = 4) + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/ovenchips/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/meatsteak/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + reagents.add_reagent("triglyceride", 2) + reagents.add_reagent("sodiumchloride", 1) + reagents.add_reagent("blackpepper", 1) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/crunch + name = "pizza crunch" + desc = "This was once a normal pizza, but it has been coated in batter and deep-fried. Whatever toppings it once had are a mystery, but they're still under there, somewhere..." + icon = 'icons/obj/food_syn.dmi' + icon_state = "pizzacrunch" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/pizzacrunchslice + slices_num = 6 + nutriment_amt = 25 + nutriment_desc = list("fried pizza" = 25) + center_of_mass = list("x"=16, "y"=11) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/crunch/Initialize() + . = ..() + reagents.add_reagent("batter", 6.5) + coating = reagents.get_reagent("batter") + reagents.add_reagent("oil", 4) + +/obj/item/weapon/reagent_containers/food/snacks/pizzacrunchslice + name = "pizza crunch" + desc = "A little piece of a heart attack. It's toppings are a mystery, hidden under batter" + icon = 'icons/obj/food_syn.dmi' + icon_state = "pizzacrunchslice" + filling_color = "#BAA14C" + bitesize = 2 + center_of_mass = list("x"=18, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/funnelcake + name = "funnel cake" + desc = "Funnel cakes rule!" + icon = 'icons/obj/food_syn.dmi' + icon_state = "funnelcake" + filling_color = "#Ef1479" + center_of_mass = list("x"=16, "y"=12) + do_coating_prefix = 0 + +/obj/item/weapon/reagent_containers/food/snacks/funnelcake/Initialize() + . = ..() + reagents.add_reagent("batter", 10) + reagents.add_reagent("sugar", 5) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/spreads + name = "nutri-spread" + desc = "A stick of plant-based nutriments in a semi-solid form. I can't believe it's not margarine!" + icon = 'icons/obj/food_syn.dmi' + icon_state = "marge" + bitesize = 2 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("margarine" = 1) + nutriment_amt = 20 + +/obj/item/weapon/reagent_containers/food/snacks/spreads/butter + name = "butter" + desc = "A stick of pure butterfat made from milk products." + icon = 'icons/obj/food_syn.dmi' + icon_state = "butter" + bitesize = 2 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("butter" = 1) + nutriment_amt = 0 + +/obj/item/weapon/reagent_containers/food/snacks/spreads/Initialize() + . = ..() + reagents.add_reagent("triglyceride", 20) + reagents.add_reagent("sodiumchloride",1) + +/obj/item/weapon/reagent_containers/food/snacks/rawcutlet/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/weapon/material/knife)) + new /obj/item/weapon/reagent_containers/food/snacks/rawbacon(src) + new /obj/item/weapon/reagent_containers/food/snacks/rawbacon(src) + to_chat(user, "You slice the cutlet into thin strips of bacon.") + qdel(src) + else + . = ..() + +/obj/item/weapon/reagent_containers/food/snacks/rawbacon + name = "raw bacon" + desc = "A very thin piece of raw meat, cut from beef." + icon = 'icons/obj/food_syn.dmi' + icon_state = "rawbacon" + bitesize = 1 + center_of_mass = list("x"=16, "y"=16) + +/obj/item/weapon/reagent_containers/food/snacks/rawbacon/Initialize() + . = ..() + reagents.add_reagent("protein", 0.33) + +/obj/item/weapon/reagent_containers/food/snacks/bacon + name = "bacon" + desc = "A tasty meat slice. You don't see any pigs on this station, do you?" + icon = 'icons/obj/food_syn.dmi' + icon_state = "bacon" + bitesize = 2 + center_of_mass = list("x"=16, "y"=16) + +/obj/item/weapon/reagent_containers/food/snacks/bacon/microwave + name = "microwaved bacon" + desc = "A tasty meat slice. You don't see any pigs on this station, do you?" + icon = 'icons/obj/food_syn.dmi' + icon_state = "bacon" + bitesize = 2 + center_of_mass = list("x"=16, "y"=16) + +/obj/item/weapon/reagent_containers/food/snacks/bacon/oven + name = "oven-cooked bacon" + desc = "A tasty meat slice. You don't see any pigs on this station, do you?" + icon = 'icons/obj/food_syn.dmi' + icon_state = "bacon" + bitesize = 2 + center_of_mass = list("x"=16, "y"=16) + +/obj/item/weapon/reagent_containers/food/snacks/bacon/Initialize() + . = ..() + reagents.add_reagent("protein", 0.33) + reagents.add_reagent("triglyceride", 1) + +/obj/item/weapon/reagent_containers/food/snacks/bacon_stick + name = "eggpop" + desc = "A bacon wrapped boiled egg, conviently skewered on a wooden stick." + icon = 'icons/obj/food_syn.dmi' + icon_state = "bacon_stick" + +/obj/item/weapon/reagent_containers/food/snacks/bacon_stick/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("egg", 1) + +/obj/item/weapon/reagent_containers/food/snacks/chilied_eggs + name = "chilied eggs" + desc = "Three deviled eggs floating in a bowl of meat chili. A popular lunchtime meal for Unathi in Ouerea." + icon_state = "chilied_eggs" + trash = /obj/item/trash/snack_bowl + +/obj/item/weapon/reagent_containers/food/snacks/chilied_eggs/Initialize() + . = ..() + reagents.add_reagent("egg", 6) + reagents.add_reagent("protein", 2) + + +/obj/item/weapon/reagent_containers/food/snacks/cheese_cracker + name = "supreme cheese toast" + desc = "A piece of toast lathered with butter, cheese, spices, and herbs." + icon = 'icons/obj/food_syn.dmi' + icon_state = "cheese_cracker" + nutriment_desc = list("cheese toast" = 8) + nutriment_amt = 8 + +/obj/item/weapon/reagent_containers/food/snacks/bacon_and_eggs + name = "bacon and eggs" + desc = "A piece of bacon and two fried eggs." + icon = 'icons/obj/food_syn.dmi' + icon_state = "bacon_and_eggs" + trash = /obj/item/trash/plate + +/obj/item/weapon/reagent_containers/food/snacks/bacon_and_eggs/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("egg", 1) + +/obj/item/weapon/reagent_containers/food/snacks/sweet_and_sour + name = "sweet and sour pork" + desc = "A traditional ancient sol recipe with a few liberties taken with meat selection." + icon = 'icons/obj/food_syn.dmi' + icon_state = "sweet_and_sour" + nutriment_desc = list("sweet and sour" = 6) + nutriment_amt = 6 + trash = /obj/item/trash/plate + +/obj/item/weapon/reagent_containers/food/snacks/sweet_and_sour/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + +/obj/item/weapon/reagent_containers/food/snacks/corn_dog + name = "corn dog" + desc = "A cornbread covered sausage deepfried in oil." + icon = 'icons/obj/food_syn.dmi' + icon_state = "corndog" + nutriment_desc = list("corn batter" = 4) + nutriment_amt = 4 + +/obj/item/weapon/reagent_containers/food/snacks/corn_dog/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + +/obj/item/weapon/reagent_containers/food/snacks/truffle + name = "chocolate truffle" + desc = "Rich bite-sized chocolate." + icon = 'icons/obj/food_syn.dmi' + icon_state = "truffle" + nutriment_amt = 0 + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/truffle/Initialize() + . = ..() + reagents.add_reagent("coco", 6) + +/obj/item/weapon/reagent_containers/food/snacks/truffle/random + name = "mystery chocolate truffle" + desc = "Rich bite-sized chocolate with a mystery filling!" + +/obj/item/weapon/reagent_containers/food/snacks/truffle/random/Initialize() + . = ..() + var/reagent_string = pick(list("cream","cherryjelly","mint","frostoil","capsaicin","cream","coffee","milkshake")) + reagents.add_reagent(reagent_string, 4) + +/obj/item/weapon/reagent_containers/food/snacks/bacon_flatbread + name = "bacon cheese flatbread" + desc = "Not a pizza." + icon_state = "bacon_pizza" + icon = 'icons/obj/food_syn.dmi' + nutriment_desc = list("flatbread" = 5) + nutriment_amt = 5 + +/obj/item/weapon/reagent_containers/food/snacks/bacon_flatbread/Initialize() + . = ..() + reagents.add_reagent("protein", 5) + +/obj/item/weapon/reagent_containers/food/snacks/meat_pocket + name = "meat pocket" + desc = "Meat and cheese stuffed in a flatbread pocket, grilled to perfection." + icon = 'icons/obj/food_syn.dmi' + icon_state = "meat_pocket" + nutriment_desc = list("flatbread" = 3) + nutriment_amt = 3 + +/obj/item/weapon/reagent_containers/food/snacks/meat_pocket/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + +/obj/item/weapon/reagent_containers/food/snacks/fish_taco + name = "carp taco" + desc = "A questionably cooked fish taco decorated with herbs, spices, and special sauce." + icon = 'icons/obj/food_syn.dmi' + icon_state = "fish_taco" + nutriment_desc = list("flatbread" = 3) + nutriment_amt = 3 + +/obj/item/weapon/reagent_containers/food/snacks/fish_taco/Initialize() + . = ..() + reagents.add_reagent("seafood",3) + +/obj/item/weapon/reagent_containers/food/snacks/nt_muffin + name = "\improper NtMuffin" + desc = "A NanoTrasen sponsered biscuit with egg, cheese, and sausage." + icon = 'icons/obj/food_syn.dmi' + icon_state = "nt_muffin" + nutriment_desc = list("biscuit" = 3) + nutriment_amt = 3 + +/obj/item/weapon/reagent_containers/food/snacks/nt_muffin/Initialize() + . = ..() + reagents.add_reagent("protein",5) + +/obj/item/weapon/reagent_containers/food/snacks/pineapple_ring + name = "pineapple ring" + desc = "What the hell is this?" + icon = 'icons/obj/food_syn.dmi' + icon_state = "pineapple_ring" + nutriment_desc = list("sweetness" = 2) + nutriment_amt = 2 + +/obj/item/weapon/reagent_containers/food/snacks/pineapple_ring/Initialize() + . = ..() + reagents.add_reagent("pineapplejuice",3) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pineapple + name = "ham & pineapple pizza" + desc = "One of the most debated pizzas in existence." + icon = 'icons/obj/food_syn.dmi' + icon_state = "pineapple_pizza" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/pineappleslice + slices_num = 6 + center_of_mass = list("x"=16, "y"=11) + nutriment_desc = list("pizza crust" = 10, "tomato" = 10, "ham" = 10) + nutriment_amt = 30 + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pineapple/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + reagents.add_reagent("cheese", 5) + reagents.add_reagent("tomatojuice", 6) + +/obj/item/weapon/reagent_containers/food/snacks/pineappleslice + name = "ham & pineapple pizza slice" + desc = "A slice of contraband." + icon = 'icons/obj/food_syn.dmi' + icon_state = "pineapple_pizza_slice" + filling_color = "#BAA14C" + bitesize = 2 + center_of_mass = list("x"=18, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/pineappleslice/filled + nutriment_desc = list("pizza crust" = 5, "tomato" = 5) + nutriment_amt = 5 + +/obj/item/weapon/reagent_containers/food/snacks/burger/bacon + name = "bacon burger" + desc = "The cornerstone of every nutritious breakfast, now with bacon!" + icon = 'icons/obj/food_syn.dmi' + icon_state = "baconburger" + filling_color = "#D63C3C" + center_of_mass = list("x"=16, "y"=11) + nutriment_desc = list("bun" = 2) + nutriment_amt = 3 + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/burger/bacon/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + +/obj/item/weapon/reagent_containers/food/snacks/blt + name = "BLT" + desc = "Bacon, lettuce, tomatoes. The perfect lunch." + icon = 'icons/obj/food_syn.dmi' + icon_state = "blt" + filling_color = "#D63C3C" + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("bread" = 4) + nutriment_amt = 4 + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/blt/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + +/obj/item/weapon/reagent_containers/food/snacks/onionrings + name = "onion rings" + desc = "Like circular fries but better." + icon = 'icons/obj/food_syn.dmi' + icon_state = "onionrings" + trash = /obj/item/trash/plate + filling_color = "#eddd00" + center_of_mass = list("x"=16,"y"=11) + nutriment_desc = list("fried onions" = 5) + nutriment_amt = 5 + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/berrymuffin + name = "berry muffin" + desc = "A delicious and spongy little cake, with berries." + icon = 'icons/obj/food_syn.dmi' + icon_state = "berrymuffin" + filling_color = "#E0CF9B" + center_of_mass = list("x"=17, "y"=4) + nutriment_amt = 5 + nutriment_desc = list("sweetness" = 1, "muffin" = 2, "berries" = 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/soup/onion + name = "onion soup" + desc = "A soup with layers." + icon = 'icons/obj/food_syn.dmi' + icon_state = "onionsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#E0C367" + center_of_mass = list("x"=16, "y"=7) + nutriment_amt = 5 + nutriment_desc = list("onion" = 2, "soup" = 2) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/porkbowl + name = "pork bowl" + desc = "A bowl of fried rice with cuts of meat." + icon = 'icons/obj/food_syn.dmi' + icon_state = "porkbowl" + trash = /obj/item/trash/snack_bowl + filling_color = "#FFFBDB" + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/porkbowl/Initialize() + . = ..() + reagents.add_reagent("rice", 6) + reagents.add_reagent("protein", 4) + +/obj/item/weapon/reagent_containers/food/snacks/mashedpotato + name = "mashed potato" + desc = "Pillowy mounds of mashed potato." + icon = 'icons/obj/food_syn.dmi' + icon_state = "mashedpotato" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + center_of_mass = list("x"=16, "y"=11) + nutriment_amt = 4 + nutriment_desc = list("mashed potatoes" = 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/croissant + name = "croissant" + desc = "True french cuisine." + icon = 'icons/obj/food_syn.dmi' + filling_color = "#E3D796" + icon_state = "croissant" + nutriment_amt = 4 + nutriment_desc = list("french bread" = 4) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/crabmeat + name = "crab legs" + desc = "... Coffee? Is that you?" + icon = 'icons/obj/food_syn.dmi' + icon_state = "crabmeat" + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/crabmeat/Initialize() + . = ..() + reagents.add_reagent("seafood", 2) + +/obj/item/weapon/reagent_containers/food/snacks/crab_legs + name = "steamed crab legs" + desc = "Crab legs steamed and buttered to perfection. One day when the boss gets hungry..." + icon = 'icons/obj/food_syn.dmi' + icon_state = "crablegs" + nutriment_amt = 2 + nutriment_desc = list("savory butter" = 2) + bitesize = 2 + trash = /obj/item/trash/plate + +/obj/item/weapon/reagent_containers/food/snacks/crab_legs/Initialize() + . = ..() + reagents.add_reagent("seafood", 6) + reagents.add_reagent("sodiumchloride", 1) + +/obj/item/weapon/reagent_containers/food/snacks/pancakes + name = "pancakes" + desc = "Pancakes with berries, delicious." + icon = 'icons/obj/food_syn.dmi' + icon_state = "pancakes" + trash = /obj/item/trash/plate + center_of_mass = list("x"=15, "y"=11) + nutriment_desc = list("pancake" = 8) + nutriment_amt = 8 + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/nugget + name = "chicken nugget" + icon = 'icons/obj/food_syn.dmi' + icon_state = "nugget_lump" + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/nugget/Initialize() + . = ..() + var/shape = pick("lump", "star", "lizard", "corgi") + desc = "A chicken nugget vaguely shaped like a [shape]." + icon_state = "nugget_[shape]" + reagents.add_reagent("protein", 4) + +/obj/item/weapon/reagent_containers/food/snacks/icecreamsandwich + name = "ice cream sandwich" + desc = "Portable ice cream in its own packaging." + icon = 'icons/obj/food_syn.dmi' + icon_state = "icecreamsandwich" + filling_color = "#343834" + center_of_mass = list("x"=15, "y"=4) + nutriment_desc = list("ice cream" = 4) + nutriment_amt = 4 + +/obj/item/weapon/reagent_containers/food/snacks/honeybun + name = "honey bun" + desc = "A sticky pastry bun glazed with honey." + icon = 'icons/obj/food_syn.dmi' + icon_state = "honeybun" + nutriment_desc = list("pastry" = 1) + nutriment_amt = 3 + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/honeybun/Initialize() + . = ..() + reagents.add_reagent("honey", 3) + +// Moved /bun/attackby() from /code/modules/food/food/snacks.dm +/obj/item/weapon/reagent_containers/food/snacks/bun/attackby(obj/item/weapon/W as obj, mob/user as mob) + var/obj/item/weapon/reagent_containers/food/snacks/result = null + // Bun + meatball = burger + if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/meatball)) + result = new /obj/item/weapon/reagent_containers/food/snacks/monkeyburger(src) + to_chat(user, "You make a burger.") + qdel(W) + qdel(src) + + // Bun + cutlet = hamburger + else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/cutlet)) + result = new /obj/item/weapon/reagent_containers/food/snacks/monkeyburger(src) + to_chat(user, "You make a burger.") + qdel(W) + qdel(src) + + // Bun + sausage = hotdog + else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/sausage)) + result = new /obj/item/weapon/reagent_containers/food/snacks/hotdog(src) + to_chat(user, "You make a hotdog.") + qdel(W) + qdel(src) + + // Bun + mouse = mouseburger + else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/variable/mob)) + var/obj/item/weapon/reagent_containers/food/snacks/variable/mob/MF = W + + switch (MF.kitchen_tag) + if ("rodent") + result = new /obj/item/weapon/reagent_containers/food/snacks/mouseburger(src) + to_chat(user, "You make a mouseburger!") + + if (result) + if (W.reagents) + //Reagents of reuslt objects will be the sum total of both. Except in special cases where nonfood items are used + //Eg robot head + result.reagents.clear_reagents() + W.reagents.trans_to(result, W.reagents.total_volume) + reagents.trans_to(result, reagents.total_volume) + + //If the bun was in your hands, the result will be too + if (loc == user) + user.drop_from_inventory(src) + user.put_in_hands(result) + +// Chip update. +/obj/item/weapon/reagent_containers/food/snacks/tortilla + name = "tortilla" + desc = "A thin, flour-based tortilla that can be used in a variety of dishes, or can be served as is." + icon = 'icons/obj/food_syn.dmi' + icon_state = "tortilla" + bitesize = 3 + nutriment_desc = list("tortilla" = 1) + center_of_mass = list("x"=16, "y"=16) + nutriment_amt = 6 + +//chips +/obj/item/weapon/reagent_containers/food/snacks/chip + name = "chip" + desc = "A portion sized chip good for dipping." + icon = 'icons/obj/food_syn.dmi' + icon_state = "chip" + var/bitten_state = "chip_half" + bitesize = 1 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("nacho chips" = 1) + nutriment_amt = 2 + +/obj/item/weapon/reagent_containers/food/snacks/chip/on_consume(mob/M as mob) + if(reagents && reagents.total_volume) + icon_state = bitten_state + . = ..() + +/obj/item/weapon/reagent_containers/food/snacks/chip/salsa + name = "salsa chip" + desc = "A portion sized chip good for dipping. This one has salsa on it." + icon_state = "chip_salsa" + bitten_state = "chip_half" + +/obj/item/weapon/reagent_containers/food/snacks/chip/guac + name = "guac chip" + desc = "A portion sized chip good for dipping. This one has guac on it." + icon_state = "chip_guac" + bitten_state = "chip_half" + +/obj/item/weapon/reagent_containers/food/snacks/chip/cheese + name = "cheese chip" + desc = "A portion sized chip good for dipping. This one has cheese sauce on it." + icon_state = "chip_cheese" + bitten_state = "chip_half" + +/obj/item/weapon/reagent_containers/food/snacks/chip/nacho + name = "nacho chip" + desc = "A nacho ship stray from a plate of cheesy nachos." + icon_state = "chip_nacho" + bitten_state = "chip_half" + +/obj/item/weapon/reagent_containers/food/snacks/chip/nacho/salsa + name = "nacho chip" + desc = "A nacho ship stray from a plate of cheesy nachos. This one has salsa on it." + icon_state = "chip_nacho_salsa" + bitten_state = "chip_half" + +/obj/item/weapon/reagent_containers/food/snacks/chip/nacho/guac + name = "nacho chip" + desc = "A nacho ship stray from a plate of cheesy nachos. This one has guac on it." + icon_state = "chip_nacho_guac" + bitten_state = "chip_half" + +/obj/item/weapon/reagent_containers/food/snacks/chip/nacho/cheese + name = "nacho chip" + desc = "A nacho ship stray from a plate of cheesy nachos. This one has extra cheese on it." + icon_state = "chip_nacho_cheese" + bitten_state = "chip_half" + +// chip plates +/obj/item/weapon/reagent_containers/food/snacks/chipplate + name = "basket of chips" + desc = "A plate of chips intended for dipping." + icon = 'icons/obj/food_syn.dmi' + icon_state = "chip_basket" + trash = /obj/item/trash/chipbasket + var/vendingobject = /obj/item/weapon/reagent_containers/food/snacks/chip + nutriment_desc = list("tortilla chips" = 10) + bitesize = 1 + nutriment_amt = 10 + +/obj/item/weapon/reagent_containers/food/snacks/chipplate/attack_hand(mob/user as mob) + var/obj/item/weapon/reagent_containers/food/snacks/returningitem = new vendingobject(loc) + returningitem.reagents.clear_reagents() + reagents.trans_to(returningitem, bitesize) + returningitem.bitesize = bitesize/2 + user.put_in_hands(returningitem) + if (reagents && reagents.total_volume) + to_chat(user, "You take a chip from the plate.") + else + to_chat(user, "You take the last chip from the plate.") + var/obj/waste = new trash(loc) + if (loc == user) + user.put_in_hands(waste) + qdel(src) + +/obj/item/weapon/reagent_containers/food/snacks/chipplate/MouseDrop(mob/user) //Dropping the chip onto the user + if(istype(user) && user == usr) + user.put_in_active_hand(src) + src.pickup(user) + return + . = ..() + +/obj/item/weapon/reagent_containers/food/snacks/chipplate/nachos + name = "plate of nachos" + desc = "A very cheesy nacho plate." + icon_state = "nachos" + trash = /obj/item/trash/plate + vendingobject = /obj/item/weapon/reagent_containers/food/snacks/chip/nacho + nutriment_desc = list("tortilla chips" = 10) + bitesize = 1 + nutriment_amt = 10 + +//dips +/obj/item/weapon/reagent_containers/food/snacks/dip + name = "queso dip" + desc = "A simple, cheesy dip consisting of tomatos, cheese, and spices." + var/nachotrans = /obj/item/weapon/reagent_containers/food/snacks/chip/nacho/cheese + var/chiptrans = /obj/item/weapon/reagent_containers/food/snacks/chip/cheese + icon = 'icons/obj/food_syn.dmi' + icon_state = "dip_cheese" + trash = /obj/item/trash/dipbowl + bitesize = 1 + nutriment_desc = list("queso" = 20) + center_of_mass = list("x"=16, "y"=16) + nutriment_amt = 20 + +/obj/item/weapon/reagent_containers/food/snacks/dip/attackby(obj/item/weapon/reagent_containers/food/snacks/item as obj, mob/user as mob) + . = ..() + var/obj/item/weapon/reagent_containers/food/snacks/returningitem + if(istype(item,/obj/item/weapon/reagent_containers/food/snacks/chip/nacho) && item.icon_state == "chip_nacho") + returningitem = new nachotrans(src) + else if (istype(item,/obj/item/weapon/reagent_containers/food/snacks/chip) && (item.icon_state == "chip" || item.icon_state == "chip_half")) + returningitem = new chiptrans(src) + if(returningitem) + returningitem.reagents.clear_reagents() //Clear the new chip + var/memed = 0 + item.reagents.trans_to(returningitem, item.reagents.total_volume) //Old chip to new chip + if(item.icon_state == "chip_half") + returningitem.icon_state = "[returningitem.icon_state]_half" + returningitem.bitesize = clamp(returningitem.reagents.total_volume,1,10) + else if(prob(1)) + memed = 1 + to_chat(user, "You scoop up some dip with the chip, but mid-scop, the chip breaks off into the dreadful abyss of dip, never to be seen again...") + returningitem.icon_state = "[returningitem.icon_state]_half" + returningitem.bitesize = clamp(returningitem.reagents.total_volume,1,10) + else + returningitem.bitesize = clamp(returningitem.reagents.total_volume*0.5,1,10) + qdel(item) + reagents.trans_to(returningitem, bitesize) //Dip to new chip + user.put_in_hands(returningitem) + + if (reagents && reagents.total_volume) + if(!memed) + to_chat(user, "You scoop up some dip with the chip.") + else + if(!memed) + to_chat(user, "You scoop up the remaining dip with the chip.") + var/obj/waste = new trash(loc) + if (loc == user) + user.put_in_hands(waste) + qdel(src) + +/obj/item/weapon/reagent_containers/food/snacks/dip/salsa + name = "salsa dip" + desc = "Traditional Sol chunky salsa dip containing tomatos, peppers, and spices." + nachotrans = /obj/item/weapon/reagent_containers/food/snacks/chip/nacho/salsa + chiptrans = /obj/item/weapon/reagent_containers/food/snacks/chip/salsa + icon_state = "dip_salsa" + nutriment_desc = list("salsa" = 20) + nutriment_amt = 20 + +/obj/item/weapon/reagent_containers/food/snacks/dip/guac + name = "guac dip" + desc = "A recreation of the ancient Sol 'Guacamole' dip using tofu, limes, and spices. This recreation obviously leaves out mole meat." + nachotrans = /obj/item/weapon/reagent_containers/food/snacks/chip/nacho/guac + chiptrans = /obj/item/weapon/reagent_containers/food/snacks/chip/guac + icon_state = "dip_guac" + nutriment_desc = list("guacmole" = 20) + nutriment_amt = 20 + +//burritos +/obj/item/weapon/reagent_containers/food/snacks/burrito + name = "meat burrito" + desc = "Meat wrapped in a flour tortilla. It's a burrito by definition." + icon = 'icons/obj/food_syn.dmi' + icon_state = "burrito" + bitesize = 4 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("tortilla" = 6) + nutriment_amt = 6 + +/obj/item/weapon/reagent_containers/food/snacks/burrito/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + + +/obj/item/weapon/reagent_containers/food/snacks/burrito_vegan + name = "vegan burrito" + desc = "Tofu wrapped in a flour tortilla." + icon = 'icons/obj/food_syn.dmi' + icon_state = "burrito_vegan" + bitesize = 4 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("tortilla" = 6) + nutriment_amt = 6 + +/obj/item/weapon/reagent_containers/food/snacks/burrito_vegan/Initialize() + . = ..() + reagents.add_reagent("tofu", 6) + +/obj/item/weapon/reagent_containers/food/snacks/burrito_spicy + name = "spicy meat burrito" + desc = "Meat and chilis wrapped in a flour tortilla." + icon = 'icons/obj/food_syn.dmi' + icon_state = "burrito_spicy" + bitesize = 4 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("tortilla" = 6) + nutriment_amt = 6 + +/obj/item/weapon/reagent_containers/food/snacks/burrito_spicy/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + +/obj/item/weapon/reagent_containers/food/snacks/burrito_cheese + name = "meat cheese burrito" + desc = "Meat and melted cheese wrapped in a flour tortilla." + icon = 'icons/obj/food_syn.dmi' + icon_state = "burrito_cheese" + bitesize = 4 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("tortilla" = 6) + nutriment_amt = 6 + +/obj/item/weapon/reagent_containers/food/snacks/burrito_cheese/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + +/obj/item/weapon/reagent_containers/food/snacks/burrito_cheese_spicy + name = "spicy cheese meat burrito" + desc = "Meat, melted cheese, and chilis wrapped in a flour tortilla." + icon_state = "burrito_cheese_spicy" + bitesize = 4 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("tortilla" = 6) + nutriment_amt = 6 + +/obj/item/weapon/reagent_containers/food/snacks/burrito_cheese_spicy/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + +/obj/item/weapon/reagent_containers/food/snacks/burrito_hell + name = "el diablo" + desc = "Meat and an insane amount of chilis packed in a flour tortilla. The Chaplain will see you now." + icon = 'icons/obj/food_syn.dmi' + icon_state = "burrito_hell" + bitesize = 4 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("hellfire" = 6) + nutriment_amt = 24// 10 Chilis is a lot. + +/obj/item/weapon/reagent_containers/food/snacks/breakfast_wrap + name = "breakfast wrap" + desc = "Bacon, eggs, cheese, and tortilla grilled to perfection." + icon = 'icons/obj/food_syn.dmi' + icon_state = "breakfast_wrap" + bitesize = 4 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("tortilla" = 6) + nutriment_amt = 6 + +/obj/item/weapon/reagent_containers/food/snacks/burrito_hell/Initialize() + . = ..() + reagents.add_reagent("protein", 9) + reagents.add_reagent("condensedcapsaicin", 20) //what could possibly go wrong + +/obj/item/weapon/reagent_containers/food/snacks/burrito_mystery + name = "mystery meat burrito" + desc = "The mystery is, why aren't you BSAing it?" + icon = 'icons/obj/food_syn.dmi' + icon_state = "burrito_mystery" + bitesize = 5 + center_of_mass = list("x"=16, "y"=16) + nutriment_desc = list("regret" = 6) + nutriment_amt = 6 + +/obj/item/weapon/reagent_containers/food/snacks/hatchling_suprise + name = "hatchling suprise" + desc = "A poached egg on top of three slices of bacon. A typical breakfast for hungry Unathi children." + icon = 'icons/obj/food_syn.dmi' + icon_state = "hatchling_suprise" + trash = /obj/item/trash/snack_bowl + +/obj/item/weapon/reagent_containers/food/snacks/hatchling_suprise/Initialize() + . = ..() + reagents.add_reagent("egg", 2) + reagents.add_reagent("protein", 4) + +/obj/item/weapon/reagent_containers/food/snacks/red_sun_special + name = "red sun special" + desc = "One lousy piece of sausage sitting on melted cheese curds. A cheap meal for the Unathi peasants of Moghes." + icon = 'icons/obj/food_syn.dmi' + icon_state = "red_sun_special" + trash = /obj/item/trash/plate + +/obj/item/weapon/reagent_containers/food/snacks/red_sun_special/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + +/obj/item/weapon/reagent_containers/food/snacks/riztizkzi_sea + name = "moghesian sea delight" + desc = "Three raw eggs floating in a sea of blood. An authentic replication of an ancient Unathi delicacy." + icon = 'icons/obj/food_syn.dmi' + icon_state = "riztizkzi_sea" + trash = /obj/item/trash/snack_bowl + +/obj/item/weapon/reagent_containers/food/snacks/riztizkzi_sea/Initialize() + . = ..() + reagents.add_reagent("egg", 4) + +/obj/item/weapon/reagent_containers/food/snacks/father_breakfast + name = "breakfast of champions" + desc = "A sausage and an omelette on top of a grilled steak." + icon = 'icons/obj/food_syn.dmi' + icon_state = "father_breakfast" + trash = /obj/item/trash/plate + +/obj/item/weapon/reagent_containers/food/snacks/father_breakfast/Initialize() + . = ..() + reagents.add_reagent("egg", 4) + reagents.add_reagent("protein", 6) + +/obj/item/weapon/reagent_containers/food/snacks/stuffed_meatball + name = "stuffed meatball" //YES + desc = "A meatball loaded with cheese." + icon = 'icons/obj/food_syn.dmi' + icon_state = "stuffed_meatball" + +/obj/item/weapon/reagent_containers/food/snacks/stuffed_meatball/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + +/obj/item/weapon/reagent_containers/food/snacks/egg_pancake + name = "meat pancake" + desc = "An omelette baked on top of a giant meat patty. This monstrousity is typically shared between four people during a dinnertime meal." + icon = 'icons/obj/food_syn.dmi' + icon_state = "egg_pancake" + trash = /obj/item/trash/plate + +/obj/item/weapon/reagent_containers/food/snacks/egg_pancake/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + reagents.add_reagent("egg", 2) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/grilled_carp + name = "korlaaskak" + desc = "A well-dressed carp, seared to perfection and adorned with herbs and spices. Can be sliced into proper serving sizes." + icon = 'icons/obj/food_syn.dmi' + icon_state = "grilled_carp" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/grilled_carp_slice + slices_num = 6 + trash = /obj/item/trash/snacktray + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/grilled_carp/Initialize() + . = ..() + reagents.add_reagent("seafood", 12) + +/obj/item/weapon/reagent_containers/food/snacks/grilled_carp_slice + name = "korlaaskak slice" + desc = "A well-dressed fillet of carp, seared to perfection and adorned with herbs and spices." + icon = 'icons/obj/food_syn.dmi' + icon_state = "grilled_carp_slice" + trash = /obj/item/trash/plate + + +// SYNNONO MEME FOODS EXPANSION - Credit to Synnono from Aurorastation. Come play here sometime :( + +/obj/item/weapon/reagent_containers/food/snacks/redcurry + name = "red curry" + gender = PLURAL + desc = "A bowl of creamy red curry with meat and rice. This one looks savory." + icon = 'icons/obj/food_syn.dmi' + icon_state = "redcurry" + trash = /obj/item/trash/snack_bowl + filling_color = "#f73333" + nutriment_amt = 8 + nutriment_desc = list("savory meat and rice" = 8) + center_of_mass = list("x"=16, "y"=8) + +/obj/item/weapon/reagent_containers/food/snacks/redcurry/Initialize() + . = ..() + reagents.add_reagent("protein", 7) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/greencurry + name = "green curry" + gender = PLURAL + desc = "A bowl of creamy green curry with tofu, hot peppers and rice. This one looks spicy!" + icon = 'icons/obj/food_syn.dmi' + icon_state = "greencurry" + trash = /obj/item/trash/snack_bowl + filling_color = "#58b76c" + nutriment_amt = 12 + nutriment_desc = list("tofu and rice" = 12) + center_of_mass = list("x"=16, "y"=8) + +/obj/item/weapon/reagent_containers/food/snacks/greencurry/Initialize() + . = ..() + reagents.add_reagent("protein", 1) + reagents.add_reagent("capsaicin", 2) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/yellowcurry + name = "yellow curry" + gender = PLURAL + desc = "A bowl of creamy yellow curry with potatoes, peanuts and rice. This one looks mild." + icon = 'icons/obj/food_syn.dmi' + icon_state = "yellowcurry" + trash = /obj/item/trash/snack_bowl + filling_color = "#bc9509" + nutriment_amt = 13 + nutriment_desc = list("rice and potatoes" = 13) + center_of_mass = list("x"=16, "y"=8) + +/obj/item/weapon/reagent_containers/food/snacks/yellowcurry/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/bearburger + name = "bearburger" + desc = "The solution to your unbearable hunger." + icon = 'icons/obj/food_syn.dmi' + icon_state = "bearburger" + filling_color = "#5d5260" + center_of_mass = list("x"=15, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/bearburger/Initialize() + . = ..() + reagents.add_reagent("protein", 4) //So spawned burgers will not be empty I guess? + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/bearchili + name = "bear chili" + gender = PLURAL + desc = "A dark, hearty chili. Can you bear the heat?" + icon = 'icons/obj/food_syn.dmi' + icon_state = "bearchili" + trash = /obj/item/trash/snack_bowl + filling_color = "#702708" + nutriment_amt = 3 + nutriment_desc = list("dark, hearty chili" = 3) + center_of_mass = list("x"=15, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/bearchili/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("capsaicin", 3) + reagents.add_reagent("tomatojuice", 2) + reagents.add_reagent("hyperzine", 5) + bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/bearstew + name = "bear stew" + gender = PLURAL + desc = "A thick, dark stew of bear meat and vegetables." + icon = 'icons/obj/food_syn.dmi' + icon_state = "bearstew" + filling_color = "#9E673A" + nutriment_amt = 6 + nutriment_desc = list("hearty stew" = 6) + center_of_mass = list("x"=16, "y"=5) + +/obj/item/weapon/reagent_containers/food/snacks/bearstew/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + reagents.add_reagent("hyperzine", 5) + reagents.add_reagent("tomatojuice", 5) + reagents.add_reagent("imidazoline", 5) + reagents.add_reagent("water", 5) + bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/bibimbap + name = "bibimbap bowl" + desc = "A traditional Korean meal of meat and mixed vegetables. It's served on a bed of rice, and topped with a fried egg." + icon = 'icons/obj/food_syn.dmi' + icon_state = "bibimbap" + trash = /obj/item/trash/snack_bowl + filling_color = "#4f2100" + nutriment_amt = 10 + nutriment_desc = list("egg" = 5, "vegetables" = 5) + center_of_mass = list("x"=15, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/bibimbap/Initialize() + . = ..() + reagents.add_reagent("protein", 10) + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/lomein + name = "lo mein" + gender = PLURAL + desc = "A popular Chinese noodle dish. Chopsticks optional." + icon = 'icons/obj/food_syn.dmi' + icon_state = "lomein" + trash = /obj/item/trash/plate + filling_color = "#FCEE81" + nutriment_amt = 8 + nutriment_desc = list("noodles" = 6, "sesame sauce" = 2) + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/snacks/lomein/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/friedrice + name = "fried rice" + gender = PLURAL + desc = "A less-boring dish of less-boring rice!" + icon = 'icons/obj/food_syn.dmi' + icon_state = "friedrice" + trash = /obj/item/trash/snack_bowl + filling_color = "#FFFBDB" + nutriment_amt = 7 + nutriment_desc = list("rice" = 7) + center_of_mass = list("x"=17, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/friedrice/Initialize() + . = ..() + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/chickenfillet + name = "chicken fillet sandwich" + desc = "Fried chicken, in sandwich format. Beauty is simplicity." + icon = 'icons/obj/food_syn.dmi' + icon_state = "chickenfillet" + filling_color = "#E9ADFF" + nutriment_amt = 4 + nutriment_desc = list("breading" = 4) + center_of_mass = list("x"=16, "y"=16) + +/obj/item/weapon/reagent_containers/food/snacks/chickenfillet/Initialize() + . = ..() + reagents.add_reagent("protein", 8) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/chilicheesefries + name = "chili cheese fries" + gender = PLURAL + desc = "A mighty plate of fries, drowned in hot chili and cheese sauce. Because your arteries are overrated." + icon = 'icons/obj/food_syn.dmi' + icon_state = "chilicheesefries" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + nutriment_amt = 8 + nutriment_desc = list("hearty, cheesy fries" = 8) + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/chilicheesefries/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + reagents.add_reagent("capsaicin", 2) + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/friedmushroom + name = "fried mushroom" + desc = "A tender, beer-battered plump helmet, fried to crispy perfection." + icon = 'icons/obj/food_syn.dmi' + icon_state = "friedmushroom" + filling_color = "#EDDD00" + nutriment_amt = 4 + nutriment_desc = list("alcoholic mushrooms" = 4) + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/friedmushroom/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/pisanggoreng + name = "pisang goreng" + gender = PLURAL + desc = "Crispy, starchy, sweet banana fritters. Popular street food in parts of Sol." + icon = 'icons/obj/food_syn.dmi' + icon_state = "pisanggoreng" + trash = /obj/item/trash/plate + filling_color = "#301301" + nutriment_amt = 8 + nutriment_desc = list("sweet bananas" = 8) + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/pisanggoreng/Initialize() + . = ..() + reagents.add_reagent("protein", 1) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/meatbun + name = "meat bun" + desc = "A soft, fluffy flour bun also known as baozi. This one is filled with a spiced meat filling." + icon = 'icons/obj/food_syn.dmi' + icon_state = "meatbun" + filling_color = "#edd7d7" + nutriment_amt = 5 + nutriment_desc = list("spice" = 5) + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/meatbun/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/custardbun + name = "custard bun" + desc = "A soft, fluffy flour bun also known as baozi. This one is filled with an egg custard." + icon = 'icons/obj/food_syn.dmi' + icon_state = "meatbun" + nutriment_amt = 6 + nutriment_desc = list("egg custard" = 6) + filling_color = "#ebedc2" + center_of_mass = list("x"=16, "y"=11) + +/obj/item/weapon/reagent_containers/food/snacks/custardbun/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/chickenmomo + name = "chicken momo" + gender = PLURAL + desc = "A plate of spiced and steamed chicken dumplings. The style originates from south Asia." + icon = 'icons/obj/food_syn.dmi' + icon_state = "momo" + trash = /obj/item/trash/snacktray + filling_color = "#edd7d7" + nutriment_amt = 9 + nutriment_desc = list("spiced chicken" = 9) + center_of_mass = list("x"=15, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/chickenmomo/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/veggiemomo + name = "veggie momo" + gender = PLURAL + desc = "A plate of spiced and steamed vegetable dumplings. The style originates from south Asia." + icon = 'icons/obj/food_syn.dmi' + icon_state = "momo" + trash = /obj/item/trash/snacktray + filling_color = "#edd7d7" + nutriment_amt = 13 + nutriment_desc = list("spiced vegetables" = 13) + center_of_mass = list("x"=15, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/veggiemomo/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/risotto + name = "risotto" + gender = PLURAL + desc = "A creamy, savory rice dish from southern Europe, typically cooked slowly with wine and broth. This one has bits of mushroom." + icon = 'icons/obj/food_syn.dmi' + icon_state = "risotto" + trash = /obj/item/trash/snack_bowl + filling_color = "#edd7d7" + nutriment_amt = 9 + nutriment_desc = list("savory rice" = 6, "cream" = 3) + center_of_mass = list("x"=15, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/risotto/Initialize() + . = ..() + reagents.add_reagent("protein", 1) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/risottoballs + name = "risotto balls" + gender = PLURAL + desc = "Mushroom risotto that has been battered and deep fried. The best use of leftovers!" + icon = 'icons/obj/food_syn.dmi' + icon_state = "risottoballs" + trash = /obj/item/trash/snack_bowl + filling_color = "#edd7d7" + nutriment_amt = 1 + nutriment_desc = list("batter" = 1) + center_of_mass = list("x"=15, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/risottoballs/Initialize() + . = ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/honeytoast + name = "piece of honeyed toast" + desc = "For those who like their breakfast sweet." + icon = 'icons/obj/food_syn.dmi' + icon_state = "honeytoast" + trash = /obj/item/trash/plate + filling_color = "#EDE5AD" + nutriment_amt = 1 + nutriment_desc = list("sweet, crunchy bread" = 1) + center_of_mass = list("x"=16, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/honeytoast/Initialize() + . = ..() + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/poachedegg + name = "poached egg" + desc = "A delicately poached egg with a runny yolk. Healthier than its fried counterpart." + icon = 'icons/obj/food_syn.dmi' + icon_state = "poachedegg" + trash = /obj/item/trash/plate + filling_color = "#FFDF78" + nutriment_amt = 1 + nutriment_desc = list("egg" = 1) + center_of_mass = list("x"=16, "y"=14) + +/obj/item/weapon/reagent_containers/food/snacks/poachedegg/Initialize() + . = ..() + reagents.add_reagent("protein", 3) + reagents.add_reagent("blackpepper", 1) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/ribplate + name = "plate of ribs" + desc = "A half-rack of ribs, brushed with some sort of honey-glaze. Why are there no napkins on board?" + icon = 'icons/obj/food_syn.dmi' + icon_state = "ribplate" + trash = /obj/item/trash/plate + filling_color = "#7A3D11" + nutriment_amt = 6 + nutriment_desc = list("barbecue" = 6) + center_of_mass = list("x"=16, "y"=13) + +/obj/item/weapon/reagent_containers/food/snacks/ribplate/Initialize() + . = ..() + reagents.add_reagent("protein", 6) + reagents.add_reagent("triglyceride", 2) + reagents.add_reagent("blackpepper", 1) + reagents.add_reagent("honey", 5) + bitesize = 4 + +// SLICEABLE FOODS - SYNNONO MEME FOOD EXPANSION - Credit to Synnono from Aurorastation (again) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/keylimepie + name = "key lime pie" + desc = "A tart, sweet dessert. What's a key lime, anyway?" + icon = 'icons/obj/food_syn.dmi' + icon_state = "keylimepie" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/keylimepieslice + slices_num = 5 + filling_color = "#F5B951" + nutriment_amt = 16 + nutriment_desc = list("lime" = 12, "graham crackers" = 4) + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/keylimepie/Initialize() + . = ..() + reagents.add_reagent("protein", 4) + +/obj/item/weapon/reagent_containers/food/snacks/keylimepieslice + name = "slice of key lime pie" + desc = "A slice of tart pie, with whipped cream on top." + icon = 'icons/obj/food_syn.dmi' + icon_state = "keylimepieslice" + trash = /obj/item/trash/plate + filling_color = "#F5B951" + bitesize = 3 + nutriment_desc = list("lime" = 1) + center_of_mass = list("x"=16, "y"=12) + +/obj/item/weapon/reagent_containers/food/snacks/keylimepieslice/filled + nutriment_amt = 1 + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/quiche + name = "quiche" + desc = "Real men eat this, contrary to popular belief." + icon = 'icons/obj/food_syn.dmi' + icon_state = "quiche" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/quicheslice + slices_num = 5 + filling_color = "#F5B951" + nutriment_amt = 10 + nutriment_desc = list("cheese" = 5, "egg" = 5) + center_of_mass = list("x"=16, "y"=10) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/quiche/Initialize() + . = ..() + reagents.add_reagent("protein", 10) + +/obj/item/weapon/reagent_containers/food/snacks/quicheslice + name = "slice of quiche" + desc = "A slice of delicious quiche. Eggy, cheesy goodness." + icon = 'icons/obj/food_syn.dmi' + icon_state = "quicheslice" + trash = /obj/item/trash/plate + filling_color = "#F5B951" + bitesize = 3 + nutriment_desc = list("cheesy eggs" = 1) + center_of_mass = list("x"=16, "y"=12) + +/obj/item/weapon/reagent_containers/food/snacks/quicheslice/filled + nutriment_amt = 1 + +/obj/item/weapon/reagent_containers/food/snacks/quicheslice/filled/Initialize() + . = ..() + reagents.add_reagent("protein", 1) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/brownies + name = "brownies" + gender = PLURAL + desc = "Halfway to fudge, or halfway to cake? Who cares!" + icon = 'icons/obj/food_syn.dmi' + icon_state = "brownies" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/browniesslice + slices_num = 4 + trash = /obj/item/trash/brownies + filling_color = "#301301" + nutriment_amt = 8 + nutriment_desc = list("fudge" = 8) + center_of_mass = list("x"=15, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/brownies/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/browniesslice + name = "brownie" + desc = "a dense, decadent chocolate brownie." + icon = 'icons/obj/food_syn.dmi' + icon_state = "browniesslice" + trash = /obj/item/trash/plate + filling_color = "#F5B951" + bitesize = 2 + nutriment_desc = list("fudge" = 1) + center_of_mass = list("x"=16, "y"=12) + +/obj/item/weapon/reagent_containers/food/snacks/browniesslice/filled + nutriment_amt = 1 + +/obj/item/weapon/reagent_containers/food/snacks/browniesslice/filled/Initialize() + . = ..() + reagents.add_reagent("protein", 1) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/cosmicbrownies + name = "cosmic brownies" + gender = PLURAL + desc = "Like, ultra-trippy. Brownies HAVE no gender, man." //Except I had to add one! + icon = 'icons/obj/food_syn.dmi' + icon_state = "cosmicbrownies" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/cosmicbrowniesslice + slices_num = 4 + trash = /obj/item/trash/brownies + filling_color = "#301301" + nutriment_amt = 8 + nutriment_desc = list("fudge" = 8) + center_of_mass = list("x"=15, "y"=9) + +/obj/item/weapon/reagent_containers/food/snacks/sliceable/cosmicbrownies/Initialize() + . = ..() + reagents.add_reagent("protein", 2) + reagents.add_reagent("space_drugs", 2) + reagents.add_reagent("bicaridine", 1) + reagents.add_reagent("kelotane", 1) + reagents.add_reagent("toxin", 1) + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/cosmicbrowniesslice + name = "cosmic brownie" + desc = "a dense, decadent and fun-looking chocolate brownie." + icon = 'icons/obj/food_syn.dmi' + icon_state = "cosmicbrowniesslice" + trash = /obj/item/trash/plate + filling_color = "#F5B951" + bitesize = 3 + nutriment_desc = list("fudge" = 1) + center_of_mass = list("x"=16, "y"=12) + +/obj/item/weapon/reagent_containers/food/snacks/cosmicbrowniesslice/filled + nutriment_amt = 1 + +/obj/item/weapon/reagent_containers/food/snacks/cosmicbrowniesslice/filled/Initialize() + . = ..() + reagents.add_reagent("protein", 1) + +/obj/item/weapon/reagent_containers/food/snacks/lasagna + name = "lasagna" + desc = "Meaty, tomato-y, and ready to eat-y. Favorite of cats." + icon = 'icons/obj/food.dmi' + icon_state = "lasagna" + nutriment_amt = 5 + nutriment_desc = list("tomato" = 4, "meat" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/lasagna/Initialize() + ..() + reagents.add_reagent("protein", 2) //For meaty things. diff --git a/code/modules/food/food/snacks/meat.dm b/code/modules/food/food/snacks/meat.dm index c2c5753edaa..394a8b9fc6a 100644 --- a/code/modules/food/food/snacks/meat.dm +++ b/code/modules/food/food/snacks/meat.dm @@ -8,8 +8,19 @@ /obj/item/weapon/reagent_containers/food/snacks/meat/Initialize() . = ..() - reagents.add_reagent("protein", 9) - src.bitesize = 3 + reagents.add_reagent("protein", 6) + reagents.add_reagent("triglyceride", 2) + src.bitesize = 1.5 + +/obj/item/weapon/reagent_containers/food/snacks/meat/cook() + + if (!isnull(cooked_icon)) + icon_state = cooked_icon + flat_icon = null //Force regenating the flat icon for coatings, since we've changed the icon of the thing being coated + ..() + + if (name == initial(name)) + name = "cooked [name]" /obj/item/weapon/reagent_containers/food/snacks/meat/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W,/obj/item/weapon/material/knife)) @@ -34,4 +45,16 @@ /obj/item/weapon/reagent_containers/food/snacks/meat/corgi name = "Corgi meat" - desc = "Tastes like... well, you know." \ No newline at end of file + desc = "Tastes like... well, you know." + +/obj/item/weapon/reagent_containers/food/snacks/meat/chicken + name = "chicken" + icon = 'icons/obj/food_syn.dmi' + icon_state = "chickenbreast" + cooked_icon = "chickenbreast_cooked" + filling_color = "#BBBBAA" + +/obj/item/weapon/reagent_containers/food/snacks/meat/chicken/Initialize() + . = ..() + reagents.remove_reagent("triglyceride", INFINITY) + //Chicken is low fat. Less total calories than other meats \ No newline at end of file diff --git a/code/modules/food/food/snacks_vr.dm b/code/modules/food/food/snacks_vr.dm index d5633dee75f..f881d9e43c3 100644 --- a/code/modules/food/food/snacks_vr.dm +++ b/code/modules/food/food/snacks_vr.dm @@ -42,20 +42,6 @@ /obj/item/weapon/reagent_containers/food/snacks/slice/sushi/filled/filled filled = TRUE - -/obj/item/weapon/reagent_containers/food/snacks/lasagna - name = "lasagna" - desc = "Meaty, tomato-y, and ready to eat-y. Favorite of cats." - icon = 'icons/obj/food_vr.dmi' - icon_state = "lasagna" - nutriment_amt = 5 - nutriment_desc = list("tomato" = 4, "meat" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/lasagna/Initialize() - ..() - reagents.add_reagent("protein", 2) //For meaty things. - - /obj/item/weapon/reagent_containers/food/snacks/goulash name = "goulash" desc = "Paprika put to good use, finally, in a soup of meat and vegetables." diff --git a/code/modules/food/food/thecake.dm b/code/modules/food/food/thecake.dm index 6c5b1ad5807..05f5ef6440b 100644 --- a/code/modules/food/food/thecake.dm +++ b/code/modules/food/food/thecake.dm @@ -1,6 +1,6 @@ // Chaos cake -/datum/recipe/microwave/chaoscake_layerone +/datum/recipe/chaoscake_layerone reagents = list("flour" = 300,"milk" = 200, "sugar" = 100, "egg" = 30) fruit = list("poisonberries" = 15, "cherries" = 15) items = list( @@ -11,7 +11,7 @@ ) result = /obj/structure/chaoscake -/datum/recipe/microwave/chaoscake_layertwo +/datum/recipe/chaoscake_layertwo reagents = list("flour" = 300, "milk" = 200, "sugar" = 100, "egg" = 30, ) fruit = list("vanilla" = 15, "banana" = 15) items = list( @@ -22,7 +22,7 @@ ) result = /obj/item/weapon/chaoscake_layer -/datum/recipe/microwave/chaoscake_layerthree +/datum/recipe/chaoscake_layerthree reagents = list("flour" = 240, "milk" = 150, "sugar" = 80, "egg" = 24, "deathbell" = 100) fruit = list("grapes" = 30) items = list( @@ -32,7 +32,7 @@ ) result = /obj/item/weapon/chaoscake_layer/three -/datum/recipe/microwave/chaoscake_layerfour +/datum/recipe/chaoscake_layerfour reagents = list("flour" = 240, "milk" = 150, "sugar" = 80, "egg" = 24, "milkshake" = 300) fruit = list("rice" = 30) items = list( @@ -42,13 +42,13 @@ ) result = /obj/item/weapon/chaoscake_layer/four -/datum/recipe/microwave/chaoscake_layerfive +/datum/recipe/chaoscake_layerfive reagents = list("flour" = 180, "milk" = 100, "sugar" = 60, "egg" = 18, "blood" = 300) fruit = list("tomato" = 20) items = list() //supposed to be made with lobster, still has to be ported. result = /obj/item/weapon/chaoscake_layer/five -/datum/recipe/microwave/chaoscake_layersix +/datum/recipe/chaoscake_layersix reagents = list("flour" = 180, "milk" = 100, "sugar" = 60, "egg" = 18, "sprinkles" = 10) fruit = list("apple" = 30) items = list( @@ -61,7 +61,7 @@ ) result = /obj/item/weapon/chaoscake_layer/six -/datum/recipe/microwave/chaoscake_layerseven +/datum/recipe/chaoscake_layerseven reagents = list("flour" = 120, "milk" = 50, "sugar" = 40, "egg" = 12, "devilskiss" = 200) fruit = list("potato" = 10) items = list( @@ -71,7 +71,7 @@ ) result = /obj/item/weapon/chaoscake_layer/seven -/datum/recipe/microwave/chaoscake_layereight +/datum/recipe/chaoscake_layereight reagents = list("flour" = 120, "milk" = 50, "sugar" = 40, "egg" = 12, "cream" = 200) fruit = list("lemon" = 10) items = list( @@ -81,7 +81,7 @@ ) result = /obj/item/weapon/chaoscake_layer/eight -/datum/recipe/microwave/chaoscake_layernine +/datum/recipe/chaoscake_layernine reagents = list("water" = 100, "blood" = 100) fruit = list("goldapple" = 50) items = list() diff --git a/code/modules/food/kitchen/cooking_machines/_appliance.dm b/code/modules/food/kitchen/cooking_machines/_appliance.dm new file mode 100644 index 00000000000..d8c4e761ca2 --- /dev/null +++ b/code/modules/food/kitchen/cooking_machines/_appliance.dm @@ -0,0 +1,729 @@ +// 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/tmp/list/cooked = list() + +// Root type for cooking machines. See following files for specific implementations. +/obj/machinery/appliance + name = "cooker" + desc = "You shouldn't be seeing this!" + icon = 'icons/obj/cooking_machines.dmi' + var/appliancetype = 0 + density = 1 + anchored = 1 + + use_power = USE_POWER_IDLE + idle_power_usage = 5 // Power used when turned on, but not processing anything + active_power_usage = 1000 // Power used when turned on and actively cooking something + + var/cooking_power = 0 // Effectiveness/speed at cooking + var/cooking_coeff = 0 // Optimal power * proximity to optimal temp; used to calc. cooking power. + var/heating_power = 1000 // Effectiveness at heating up; not used for mixers, should be equal to active_power_usage + var/max_contents = 1 // Maximum number of things this appliance can simultaneously cook + var/on_icon // Icon state used when cooking. + var/off_icon // Icon state used when not cooking. + var/cooking = FALSE // 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/can_cook_mobs // Whether or not this machine accepts grabbed mobs. + var/mobdamagetype = BRUTE // Burn damage for cooking appliances, brute for cereal/candy + var/food_color // Colour of resulting food item. + var/cooked_sound = 'sound/machines/ding.ogg' // Sound played when cooking completes. + var/can_burn_food = FALSE // Can the object burn food that is left inside? + var/burn_chance = 10 // How likely is the food to burn? + var/list/cooking_objs = list() // List of things being cooked + + // If the machine has multiple output modes, define them here. + var/selected_option + var/list/output_options = list() + var/list/datum/recipe/available_recipes + + var/container_type = null + + var/combine_first = FALSE // If TRUE, this appliance will do combination cooking before checking recipes + +/obj/machinery/appliance/Initialize() + . = ..() + + default_apply_parts() + + if(output_options.len) + verbs += /obj/machinery/appliance/proc/choose_output + + if (!available_recipes) + available_recipes = new + + for(var/type in subtypesof(/datum/recipe)) + var/datum/recipe/test = type + if((appliancetype & initial(test.appliance))) + available_recipes += new test + +/obj/machinery/appliance/Destroy() + for (var/a in cooking_objs) + var/datum/cooking_item/CI = a + qdel(CI.container)//Food is fragile, it probably doesnt survive the destruction of the machine + cooking_objs -= CI + qdel(CI) + return ..() + +/obj/machinery/appliance/examine(var/mob/user) + . = ..() + if(Adjacent(user)) + . += list_contents(user) + +/obj/machinery/appliance/proc/list_contents(var/mob/user) + if (cooking_objs.len) + var/string = "Contains..." + for (var/a in cooking_objs) + var/datum/cooking_item/CI = a + string += "-\a [CI.container.label(null, CI.combine_target)], [report_progress(CI)]
" + return string + else + to_chat(user, "") + +/obj/machinery/appliance/proc/report_progress(var/datum/cooking_item/CI) + if (!CI || !CI.max_cookwork) + return null + + if (!CI.cookwork) + return "It is cold." + var/progress = CI.cookwork / CI.max_cookwork + + if (progress < 0.25) + return "It's barely started cooking." + if (progress < 0.75) + return "It's cooking away nicely." + if (progress < 1) + return "It's almost ready!" + + var/half_overcook = (CI.overcook_mult - 1)*0.5 + if (progress < 1+half_overcook) + return "It is done !" + if (progress < CI.overcook_mult) + return "It looks overcooked, get it out!" + else + return "It is burning!" + +/obj/machinery/appliance/update_icon() + if (!stat && cooking_objs.len) + icon_state = on_icon + + else + icon_state = off_icon + +/obj/machinery/appliance/verb/toggle_power() + set name = "Toggle Power" + set category = "Object" + set src in view() + + attempt_toggle_power(usr) + +/obj/machinery/appliance/proc/attempt_toggle_power(mob/user) + if (!isliving(user)) + return + + if (!user.IsAdvancedToolUser()) + to_chat(user, "You lack the dexterity to do that!") + return + + if (user.stat || user.restrained() || user.incapacitated()) + return + + if (!Adjacent(user) && !issilicon(user)) + to_chat(user, "You can't reach [src] from here!") + return + + if (stat & POWEROFF)//Its turned off + stat &= ~POWEROFF + use_power = 1 + user.visible_message("[user] turns [src] on.", "You turn on [src].") + + else //Its on, turn it off + stat |= POWEROFF + use_power = 0 + user.visible_message("[user] turns [src] off.", "You turn off [src].") + cooking = FALSE // Stop cooking here, too, just in case. + + playsound(src, 'sound/machines/click.ogg', 40, 1) + update_icon() + +/obj/machinery/appliance/AICtrlClick(mob/user) + attempt_toggle_power(user) + +/obj/machinery/appliance/proc/choose_output() + set src in view() + set name = "Choose output" + set category = "Object" + + if (!isliving(usr)) + return + + if (!usr.IsAdvancedToolUser()) + to_chat(usr, "You lack the dexterity to do that!") + return + + if (usr.stat || usr.restrained() || usr.incapacitated()) + return + + if (!Adjacent(usr) && !issilicon(usr)) + to_chat(usr, "You can't adjust the [src] from this distance, get closer!") + return + + if(output_options.len) + 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 + to_chat(usr, "You decide not to make anything specific with \the [src].") + else + selected_option = choice + to_chat(usr, "You prepare \the [src] to make \a [selected_option] with the next thing you put in. Try putting several ingredients in a container!") + +//Handles all validity checking and error messages for inserting things +/obj/machinery/appliance/proc/can_insert(var/obj/item/I, var/mob/user) + if (istype(I.loc, /mob/living/silicon)) + return 0 + else if (istype(I.loc, /obj/item/rig_module)) + return 0 + + // We are trying to cook a grabbed mob. + var/obj/item/weapon/grab/G = I + if(istype(G)) + + if(!can_cook_mobs) + to_chat(user, "That's not going to fit.") + return 0 + + if(!isliving(G.affecting)) + to_chat(user, "You can't cook that.") + return 0 + + return 2 + + + if (!has_space(I)) + to_chat(user, "There's no room in [src] for that!") + return 0 + + + if (container_type && istype(I, container_type)) + return 1 + + // 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)) + to_chat(user, "\The [check] has already been [cook_type].") + return 0 + else if(istype(check, /obj/item/weapon/reagent_containers/glass)) + to_chat(user, "That would probably break [src].") + return 0 + else if(istype(check, /obj/item/weapon/disk/nuclear)) + to_chat(user, "You can't cook that.") + return 0 + else if(I.is_crowbar() || I.is_screwdriver() || istype(I, /obj/item/weapon/storage/part_replacer)) // You can't cook tools, dummy. + return 0 + else if(!istype(check) && !istype(check, /obj/item/weapon/holder)) + to_chat(user, "That's not edible.") + return 0 + + return 1 + + +//This function is overridden by cookers that do stuff with containers +/obj/machinery/appliance/proc/has_space(var/obj/item/I) + if(cooking_objs.len >= max_contents) + return FALSE + + return TRUE + +/obj/machinery/appliance/attackby(var/obj/item/I, var/mob/user) + if(!cook_type || (stat & (BROKEN))) + to_chat(user, "\The [src] is not working.") + return + + var/result = can_insert(I, user) + if(!result) + if(!(default_deconstruction_screwdriver(user, I))) + default_part_replacement(user, I) + return + + if(result == 2) + var/obj/item/weapon/grab/G = I + if (G && istype(G) && G.affecting) + cook_mob(G.affecting, user) + return + + //From here we can start cooking food + add_content(I, user) + update_icon() + +//Override for container mechanics +/obj/machinery/appliance/proc/add_content(var/obj/item/I, var/mob/user) + if(!user.unEquip(I)) + return + + var/datum/cooking_item/CI = has_space(I) + if (istype(I, /obj/item/weapon/reagent_containers/cooking_container) && CI == 1) + var/obj/item/weapon/reagent_containers/cooking_container/CC = I + CI = new /datum/cooking_item/(CC) + I.forceMove(src) + cooking_objs.Add(CI) + user.visible_message("\The [user] puts \the [I] into \the [src].") + if (CC.check_contents() == 0)//If we're just putting an empty container in, then dont start any processing. + return + else + if (CI && istype(CI)) + I.forceMove(CI.container) + + else //Something went wrong + return + + if (selected_option) + CI.combine_target = selected_option + + // We can actually start cooking now. + user.visible_message("\The [user] puts \the [I] into \the [src].") + + get_cooking_work(CI) + cooking = TRUE + return CI + +/obj/machinery/appliance/proc/get_cooking_work(var/datum/cooking_item/CI) + for (var/obj/item/J in CI.container) + cookwork_by_item(J, CI) + + for (var/r in CI.container.reagents.reagent_list) + var/datum/reagent/R = r + if (istype(R, /datum/reagent/nutriment)) + CI.max_cookwork += R.volume *2//Added reagents contribute less than those in food items due to granular form + + //Nonfat reagents will soak oil + if (!istype(R, /datum/reagent/nutriment/triglyceride)) + CI.max_oil += R.volume * 0.25 + else + CI.max_cookwork += R.volume + CI.max_oil += R.volume * 0.10 + + //Rescaling cooking work to avoid insanely long times for large things + var/buffer = CI.max_cookwork + CI.max_cookwork = 0 + var/multiplier = 1 + var/step = 4 + while (buffer > step) + buffer -= step + CI.max_cookwork += step*multiplier + multiplier *= 0.95 + + CI.max_cookwork += buffer*multiplier + +//Just a helper to save code duplication in the above +/obj/machinery/appliance/proc/cookwork_by_item(var/obj/item/I, var/datum/cooking_item/CI) + var/obj/item/weapon/reagent_containers/food/snacks/S = I + var/work = 0 + if (istype(S)) + if (S.reagents) + for (var/r in S.reagents.reagent_list) + var/datum/reagent/R = r + if (istype(R, /datum/reagent/nutriment)) + work += R.volume *3//Core nutrients contribute much more than peripheral chemicals + + //Nonfat reagents will soak oil + if (!istype(R, /datum/reagent/nutriment/triglyceride)) + CI.max_oil += R.volume * 0.35 + else + work += R.volume + CI.max_oil += R.volume * 0.15 + + + else if(istype(I, /obj/item/weapon/holder)) + var/obj/item/weapon/holder/H = I + if (H.held_mob) + work += ((H.held_mob.mob_size * H.held_mob.size_multiplier) * (H.held_mob.mob_size * H.held_mob.size_multiplier) * 2)+2 + + CI.max_cookwork += work + +//Called every tick while we're cooking something +/obj/machinery/appliance/proc/do_cooking_tick(var/datum/cooking_item/CI) + if (!istype(CI) || !CI.max_cookwork) + return FALSE + + var/was_done = FALSE + if (CI.cookwork >= CI.max_cookwork) + was_done = TRUE + + CI.cookwork += cooking_power + + if (!was_done && CI.cookwork >= CI.max_cookwork) + //If cookwork has gone from above to below 0, then this item finished cooking + finish_cooking(CI) + + else if (!CI.burned && CI.cookwork > min(CI.max_cookwork * CI.overcook_mult, CI.max_cookwork + 30)) + burn_food(CI) + + // Gotta hurt. + for(var/obj/item/weapon/holder/H in CI.container.contents) + var/mob/living/M = H.held_mob + if(M) + M.apply_damage(rand(1,3) * (1/M.size_multiplier), mobdamagetype, pick(BP_ALL)) + + return TRUE + +/obj/machinery/appliance/process() + if(cooking_power > 0 && cooking) + var/all_done_cooking = TRUE + for(var/datum/cooking_item/CI in cooking_objs) + do_cooking_tick(CI) + if(CI.max_cookwork > 0) + all_done_cooking = FALSE + if(all_done_cooking) + cooking = FALSE + update_icon() + + +/obj/machinery/appliance/proc/finish_cooking(var/datum/cooking_item/CI) + + src.visible_message("\The [src] pings!") + if(cooked_sound) + playsound(get_turf(src), cooked_sound, 50, 1) + //Check recipes first, a valid recipe overrides other options + var/datum/recipe/recipe = null + var/atom/C = null + if (CI.container) + C = CI.container + else + C = src + recipe = select_recipe(available_recipes,C) + + if (recipe) + CI.result_type = 4//Recipe type, a specific recipe will transform the ingredients into a new food + var/list/results = recipe.make_food(C) + + var/obj/temp = new /obj(src) //To prevent infinite loops, all results will be moved into a temporary location so they're not considered as inputs for other recipes + + for (var/atom/movable/AM in results) + AM.forceMove(temp) + + //making multiple copies of a recipe from one container. For example, tons of fries + while (select_recipe(available_recipes,C) == recipe) + var/list/TR = list() + TR += recipe.make_food(C) + for (var/atom/movable/AM in TR) //Move results to buffer + AM.forceMove(temp) + results += TR + + + for (var/r in results) + var/obj/item/weapon/reagent_containers/food/snacks/R = r + R.forceMove(C) //Move everything from the buffer back to the container + R.cooked |= cook_type + + QDEL_NULL(temp) //delete buffer object + . = 1 //None of the rest of this function is relevant for recipe cooking + + else if(CI.combine_target) + CI.result_type = 3//Combination type. We're making something out of our ingredients + . = combination_cook(CI) + + + else + //Otherwise, we're just doing standard modification cooking. change a color + name + for (var/obj/item/i in CI.container) + modify_cook(i, CI) + + //Final step. Cook function just cooks batter for now. + for (var/obj/item/weapon/reagent_containers/food/snacks/S in CI.container) + S.cook() + + +//Combination cooking involves combining the names and reagents of ingredients into a predefined output object +//The ingredients represent flavours or fillings. EG: donut pizza, cheese bread +/obj/machinery/appliance/proc/combination_cook(var/datum/cooking_item/CI) + var/cook_path = output_options[CI.combine_target] + + var/list/words = list() + var/list/cooktypes = list() + var/datum/reagents/buffer = new /datum/reagents(1000) + var/totalcolour + + for (var/obj/item/I in CI.container) + var/obj/item/weapon/reagent_containers/food/snacks/S + if (istype(I, /obj/item/weapon/holder)) + S = create_mob_food(I, CI) + else if (istype(I, /obj/item/weapon/reagent_containers/food/snacks)) + S = I + + if (!S) + continue + + words |= text2list(S.name," ") + cooktypes |= S.cooked + + if (S.reagents && S.reagents.total_volume > 0) + if (S.filling_color) + if (!totalcolour || !buffer.total_volume) + totalcolour = S.filling_color + else + var/t = buffer.total_volume + S.reagents.total_volume + t = buffer.total_volume / y + totalcolour = BlendRGB(totalcolour, S.filling_color, t) + //Blend colours in order to find a good filling color + + + S.reagents.trans_to_holder(buffer, S.reagents.total_volume) + //Cleanup these empty husk ingredients now + if (I) + qdel(I) + if (S) + qdel(S) + + CI.container.reagents.trans_to_holder(buffer, CI.container.reagents.total_volume) + + var/obj/item/weapon/reagent_containers/food/snacks/result = new cook_path(CI.container) + buffer.trans_to(result, buffer.total_volume) + + //Filling overlay + var/image/I = image(result.icon, "[result.icon_state]_filling") + I.color = totalcolour + result.add_overlay(I) + result.filling_color = totalcolour + + //Set the name. + words -= list("and", "the", "in", "is", "bar", "raw", "sticks", "boiled", "fried", "deep", "-o-", "warm", "two", "flavored") + //Remove common connecting words and unsuitable ones from the list. Unsuitable words include those describing + //the shape, cooked-ness/temperature or other state of an ingredient which doesn't apply to the finished product + words.Remove(result.name) + shuffle(words) + var/num = 6 //Maximum number of words + while (num > 0) + num-- + if (!words.len) + break + //Add prefixes from the ingredients in a random order until we run out or hit limit + result.name = "[pop(words)] [result.name]" + + //This proc sets the size of the output result + result.update_icon() + return result + +//Helper proc for standard modification cooking +/obj/machinery/appliance/proc/modify_cook(var/obj/item/input, var/datum/cooking_item/CI) + var/obj/item/weapon/reagent_containers/food/snacks/result + if (istype(input, /obj/item/weapon/holder)) + result = create_mob_food(input, CI) + else if (istype(input, /obj/item/weapon/reagent_containers/food/snacks)) + result = input + else + //Nonviable item + return + + if (!result) + return + + result.cooked |= cook_type + + // Set icon and appearance. + change_product_appearance(result, CI) + + // Update strings. + change_product_strings(result, CI) + +/obj/machinery/appliance/proc/burn_food(var/datum/cooking_item/CI) + // You dun goofed. + CI.burned = 1 + CI.container.clear() + new /obj/item/weapon/reagent_containers/food/snacks/badrecipe(CI.container) + + // Produce nasty smoke. + visible_message("\The [src] vomits a gout of rancid smoke!") + var/datum/effect/effect/system/smoke_spread/bad/burntfood/smoke = new /datum/effect/effect/system/smoke_spread/bad/burntfood + playsound(src, 'sound/effects/smoke.ogg', 20, 1) + smoke.attach(src) + smoke.set_up(10, 0, get_turf(src), 300) + smoke.start() + + // Set off fire alarms! + var/obj/machinery/firealarm/FA = locate() in get_area(src) + if(FA) + FA.alarm() + +/obj/machinery/appliance/attack_hand(var/mob/user) + if (cooking_objs.len) + if (removal_menu(user)) + return + else + ..() + +/obj/machinery/appliance/proc/removal_menu(var/mob/user) + if (can_remove_items(user)) + var/list/menuoptions = list() + for (var/a in cooking_objs) + var/datum/cooking_item/CI = a + if (CI.container) + menuoptions[CI.container.label(menuoptions.len)] = CI + + var/selection = input(user, "Which item would you like to remove?", "Remove ingredients") as null|anything in menuoptions + if (selection) + var/datum/cooking_item/CI = menuoptions[selection] + eject(CI, user) + update_icon() + return TRUE + return FALSE + +/obj/machinery/appliance/proc/can_remove_items(var/mob/user) + if (!Adjacent(user)) + return FALSE + + if (isanimal(user)) + return FALSE + + return TRUE + +/obj/machinery/appliance/proc/eject(var/datum/cooking_item/CI, var/mob/user = null) + var/obj/item/thing + var/delete = 1 + var/status = CI.container.check_contents() + + if (status == 1)//If theres only one object in a container then we extract that + thing = locate(/obj/item) in CI.container + delete = 0 + else//If the container is empty OR contains more than one thing, then we must extract the container + thing = CI.container + if (!user || !user.put_in_hands(thing)) + thing.forceMove(get_turf(src)) + + if (delete) + cooking_objs -= CI + qdel(CI) + else + CI.reset()//reset instead of deleting if the container is left inside + user.visible_message("\The [user] remove \the [thing] from \the [src].") + +/obj/machinery/appliance/proc/cook_mob(var/mob/living/victim, var/mob/user) + return + +/obj/machinery/appliance/proc/change_product_strings(var/obj/item/weapon/reagent_containers/food/snacks/product, var/datum/cooking_item/CI) + product.name = "[cook_type] [product.name]" + product.desc = "[product.desc]\nIt has been [cook_type]." + + +/obj/machinery/appliance/proc/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/product, var/datum/cooking_item/CI) + if (!product.coating) //Coatings change colour through a new sprite + product.color = food_color + product.filling_color = food_color + +/mob/living/proc/calculate_composition() // moved from devour.dm on aurora's side + if (!composition_reagent)//if no reagent has been set, then we'll set one + if (isSynthetic()) + src.composition_reagent = "iron" + else + if(istype(src, /mob/living/carbon/human/diona) || istype(src, /mob/living/carbon/alien/diona)) + src.composition_reagent = "nutriment" // diona are plants, not meat + else + src.composition_reagent = "protein" + if(istype(src, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = src + if(istype(H.species, /datum/species/diona)) + src.composition_reagent = "nutriment" + + //if the mob is a simple animal - MOB NOT ANIMAL - with a defined meat quantity + if (istype(src, /mob/living/simple_mob)) + var/mob/living/simple_mob/SA = src + if(SA.meat_amount) + src.composition_reagent_quantity = SA.meat_amount*2*9 + + //The quantity of protein is based on the meat_amount, but multiplied by 2 + + var/size_reagent = (src.mob_size * src.mob_size) * 3//The quantity of protein is set to 3x mob size squared + if (size_reagent > src.composition_reagent_quantity)//We take the larger of the two + src.composition_reagent_quantity = size_reagent + +//This function creates a food item which represents a dead mob +/obj/machinery/appliance/proc/create_mob_food(var/obj/item/weapon/holder/H, var/datum/cooking_item/CI) + if (!istype(H) || !H.held_mob) + qdel(H) + return null + var/mob/living/victim = H.held_mob + if (victim.stat != DEAD) + return null //Victim somehow survived the cooking, they do not become food + + victim.calculate_composition() + + var/obj/item/weapon/reagent_containers/food/snacks/variable/mob/result = new /obj/item/weapon/reagent_containers/food/snacks/variable/mob(CI.container) + result.w_class = victim.mob_size + result.reagents.add_reagent(victim.composition_reagent, victim.composition_reagent_quantity) + + if (victim.reagents) + victim.reagents.trans_to_holder(result.reagents, victim.reagents.total_volume) + + if (isanimal(victim)) + var/mob/living/simple_mob/SA = victim + result.kitchen_tag = SA.kitchen_tag + + result.appearance = victim + + var/matrix/M = matrix() + M.Turn(45) + M.Translate(1,-2) + result.transform = M + + // all done, now delete the old objects + H.held_mob = null + qdel(victim) + victim = null + qdel(H) + H = null + + return result + +/datum/cooking_item + var/max_cookwork + var/cookwork + var/overcook_mult = 3 // How long it takes to overcook. This is max_cookwork x overcook mult. If you're changing this, mind that at 3x, a max_cookwork of 30 becomes 90 ticks for the purpose of burning, and a max_cookwork of 4 only has 12 before burning! + var/result_type = 0 + var/obj/item/weapon/reagent_containers/cooking_container/container = null + var/combine_target = null + + //Result type is one of the following: + //0 unfinished, no result yet + //1 Standard modification cooking. eg Fried Donk Pocket, Baked wheat, etc + //2 Modification but with a new object that's an inert copy of the old. Generally used for deepfried mice + //3 Combination cooking, EG Donut Bread, Donk pocket pizza, etc + //4:Specific recipe cooking. EG: Turning raw potato sticks into fries + + var/burned = 0 + + var/oil = 0 + var/max_oil = 0//Used for fryers. + +/datum/cooking_item/New(var/obj/item/I) + container = I + +//This is called for containers whose contents are ejected without removing the container +/datum/cooking_item/proc/reset() + max_cookwork = 0 + cookwork = 0 + result_type = 0 + burned = 0 + max_oil = 0 + oil = 0 + combine_target = null + //Container is not reset + +/obj/machinery/appliance/RefreshParts() + ..() + var/scan_rating = 0 + var/cap_rating = 0 + + for(var/obj/item/weapon/stock_parts/P in src.component_parts) + if(istype(P, /obj/item/weapon/stock_parts/scanning_module)) + scan_rating += P.rating - 1 // Default parts shouldn't mess with stats + // to_world("RefreshParts returned scan rating of [scan_rating] during this step.") // Debug lines, uncomment if you need to test. + else if(istype(P, /obj/item/weapon/stock_parts/capacitor)) + cap_rating += P.rating - 1 // Default parts shouldn't mess with stats + // to_world("RefreshParts returned cap rating of [cap_rating] during this step.") // Debug lines, uncomment if you need to test. + + active_power_usage = initial(active_power_usage) - scan_rating * 25 + heating_power = initial(heating_power) + cap_rating * 25 + cooking_power = cooking_coeff * (1 + (scan_rating + cap_rating) / 20) // 100% eff. becomes 120%, 140%, 160% w/ better parts, thus rewarding upgrading the appliances during your shift. + // to_world("RefreshParts returned cooking power of [cooking_power] during this step.") // Debug lines, uncomment if you need to test. diff --git a/code/modules/food/kitchen/cooking_machines/_cooker.dm b/code/modules/food/kitchen/cooking_machines/_cooker.dm index f0716e015f4..94b40b44b2f 100644 --- a/code/modules/food/kitchen/cooking_machines/_cooker.dm +++ b/code/modules/food/kitchen/cooking_machines/_cooker.dm @@ -1,261 +1,146 @@ -// This folder contains code that was originally ported from Apollo Station and then refactored/optimized/changed. +/obj/machinery/appliance/cooker + var/temperature = T20C + var/min_temp = 80 + T0C //Minimum temperature to do any cooking + var/optimal_temp = 200 + T0C //Temperature at which we have 100% efficiency. efficiency is lowered on either side of this + var/optimal_power = 0.6 //cooking power at 100% - This variable determines the MAXIMUM increase in do_cooking_ticks, once math goes through. If you want ticks of 0.5, set it to 0.5, etc. -// Tracks precooked food to stop deep fried baked grilled grilled grilled diona nymph cereal. -/obj/item/weapon/reagent_containers/food/snacks/var/list/cooked + var/loss = 1 //Temp lost per proc when equalising + var/resistance = 32000 //Resistance to heating. combines with heating power to determine how long heating takes. 32k by default. -// 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 = USE_POWER_IDLE - idle_power_usage = 5 + var/light_x = 0 + var/light_y = 0 + cooking_coeff = 0 + cooking_power = 0 + mobdamagetype = BURN + can_burn_food = TRUE - 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/proc/set_cooking(new_setting) - cooking = new_setting - icon_state = new_setting ? on_icon : off_icon - -/obj/machinery/cooker/examine(mob/user) +/obj/machinery/appliance/cooker/examine(var/mob/user) . = ..() - if(cooking_obj && Adjacent(user)) - . += "You can see \a [cooking_obj] inside." - -/obj/machinery/cooker/attackby(var/obj/item/I, var/mob/user) - - if(!cook_type || (stat & (NOPOWER|BROKEN))) - to_chat(user, "\The [src] is not working.") - return - - if(cooking) - to_chat(user, "\The [src] is running!") - return - - if(default_unfasten_wrench(user, I, 20)) - return - - // We are trying to cook a grabbed mob. - var/obj/item/weapon/grab/G = I - if(istype(G)) - - if(!can_cook_mobs) - to_chat(user, "That's not going to fit.") - return - - if(!isliving(G.affecting)) - to_chat(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)) - to_chat(user, "\The [check] has already been [cook_type].") - return 0 - else if(istype(check, /obj/item/weapon/reagent_containers/glass)) - to_chat(user, "That would probably break [src].") - return 0 - else if(istype(check, /obj/item/weapon/disk/nuclear)) - to_chat(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)) //Gripper check has to go here, else it still just cuts it off. ~Mechoid - // Is it a borg using a gripper? - if(istype(check, /obj/item/weapon/gripper)) // Grippers. ~Mechoid. - var/obj/item/weapon/gripper/B = check //B, for Borg. - if(!B.wrapped) - to_chat(user, "\The [B] is not holding anything.") - return 0 + if(.) //no need to duplicate adjacency check + if(!stat) + if (temperature < min_temp) + . += "\The [src] is still heating up and is too cold to cook anything yet." else - var/B_held = B.wrapped - to_chat(user, "You use \the [B] to put \the [B_held] into \the [src].") - return 0 + . += "It is running at [round(get_efficiency(), 0.1)]% efficiency!" + . += "Temperature: [round(temperature - T0C, 0.1)]C / [round(optimal_temp - T0C, 0.1)]C" else - to_chat(user, "That's not edible.") - return 0 - - if(istype(I, /obj/item/organ)) - var/obj/item/organ/O = I - if(O.robotic) - to_chat(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. (Hint: Borg grippers. That is why. ~Mechoid.) - if(!user.unEquip(I) && !istype(user,/mob/living/silicon/robot)) - 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) - set_cooking(TRUE) - 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 - set_cooking(FALSE) - 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() - qdel(M) - - // 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() + . += "It is switched off." + +/obj/machinery/appliance/cooker/list_contents(var/mob/user) + if (cooking_objs.len) + var/string = "Contains...
" + var/num = 0 + for (var/a in cooking_objs) + num++ + var/datum/cooking_item/CI = a + if (CI && CI.container) + string += "- [CI.container.label(num)], [report_progress(CI)]
" + to_chat(user, string) else - result.cooked = list() - result.cooked |= cook_type + to_chat(user, "It's empty.") + +/obj/machinery/appliance/cooker/proc/get_efficiency() + // to_world("Our cooking_power is [cooking_power] and our efficiency is [(cooking_power / optimal_power) * 100].") // Debug lines, uncomment if you need to test. + return (cooking_power / optimal_power) * 100 - // Reset relevant variables. - qdel(cooking_obj) - src.visible_message("\The [src] pings!") - if(cooked_sound) - playsound(src, cooked_sound, 50, 1) +/obj/machinery/appliance/cooker/Initialize() + . = ..() + loss = (active_power_usage / resistance)*0.5 + cooking_objs = list() + for (var/i = 0, i < max_contents, i++) + cooking_objs.Add(new /datum/cooking_item/(new container_type(src))) + cooking = FALSE - if(!can_burn_food) - icon_state = off_icon - set_cooking(FALSE) - result.forceMove(get_turf(src)) - cooking_obj = null + update_icon() // this probably won't cause issues, but Aurora used SSIcons and queue_icon_update() instead + +/obj/machinery/appliance/cooker/update_icon() + cut_overlays() + var/image/light + if(use_power == 1 && !stat) + light = image(icon, "light_idle") + else if(use_power == 2 && !stat) + light = image(icon, "light_preheating") else - var/failed - var/overcook_period = max(FLOOR(cook_time/5, 1),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 = new /datum/effect/effect/system/smoke_spread/bad() - smoke.attach(src) - smoke.set_up(10, 0, usr.loc) - smoke.start() - failed = 1 - - if(failed) - set_cooking(FALSE) - icon_state = off_icon - break - -/obj/machinery/cooker/attack_hand(var/mob/user) - - if(cooking_obj && user.Adjacent(src)) //Fixes borgs being able to teleport food in these machines to themselves. - to_chat(user, "You grab \the [cooking_obj] from \the [src].") - user.put_in_hands(cooking_obj) - set_cooking(FALSE) - cooking_obj = null - icon_state = off_icon - return - - if(output_options.len) - - if(cooking) - to_chat(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 - to_chat(user, "You decide not to make anything specific with \the [src].") - else - selected_option = choice - to_chat(user, "You prepare \the [src] to make \a [selected_option].") + light = image(icon, "light_off") + light.pixel_x = light_x + light.pixel_y = light_y + add_overlay(light) +/obj/machinery/appliance/cooker/process() + if (!stat) + heat_up() + else + var/turf/T = get_turf(src) + if (temperature > T.temperature) + equalize_temperature() ..() - -/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]." + +/obj/machinery/appliance/cooker/power_change() + . = ..() + update_icon() // this probably won't cause issues, but Aurora used SSIcons and queue_icon_update() instead + +/obj/machinery/appliance/cooker/proc/update_cooking_power() + var/temp_scale = 0 + if(temperature > min_temp) + if(temperature >= optimal_temp) // If we're at or above optimal temp, then we're going to be at 1 for temp scale. No use penalizing you for the cookers increasing heat constantly (until we implement setting a temp on the oven via a menu.) + temp_scale = 1 + else + temp_scale = (temperature - min_temp) / (optimal_temp - min_temp) // If we're between min and optimal this will yield a value in the range 0-1 + + /* // old code for reference, will be useful if/when we implement ovens with configurable temperatures - TODO recipes with optimal temps for cooking per-recipe?? + temp_scale = (temperature - min_temp) / (optimal_temp - min_temp) // If we're between min and optimal this will yield a value in the range 0-1 + + if(temp_scale > 1) // We're above optimal, efficiency goes down as we pass too much over it + if(temp_scale >= 2) + temp_scale = 0 + else + temp_scale = 1 - (temp_scale - 1) + */ + + cooking_coeff = optimal_power * temp_scale + // to_world("Our cooking_power is [cooking_power] and our tempscale is [temp_scale], and our cooking_coeff is [cooking_coeff] before RefreshParts.") // Debug lines, uncomment if you need to test. + RefreshParts() + // to_world("Our cooking_power is [cooking_power] after RefreshParts.") // Debug lines, uncomment if you need to test. + +/obj/machinery/appliance/cooker/proc/heat_up() + if(temperature < optimal_temp) + if(use_power == 1 && ((optimal_temp - temperature) > 5)) + playsound(src, 'sound/machines/click.ogg', 20, 1) + use_power = 2.//If we're heating we use the active power + update_icon() + temperature += heating_power / resistance + update_cooking_power() + return 1 else - product.name = "[cooking_obj.name] [product.name]" + if(use_power == 2) + use_power = 1 + playsound(src, 'sound/machines/click.ogg', 20, 1) + update_icon() + //We're holding steady. temperature falls more slowly + if(prob(25)) + equalize_temperature() + return -1 -/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 +/obj/machinery/appliance/cooker/proc/equalize_temperature() + temperature -= loss//Temperature will fall somewhat slowly + update_cooking_power() - // 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 +//Cookers do differently, they use containers +/obj/machinery/appliance/cooker/has_space(var/obj/item/I) + if(istype(I, /obj/item/weapon/reagent_containers/cooking_container)) + //Containers can go into an empty slot + if(cooking_objs.len < max_contents) + return 1 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 + //Any food items directly added need an empty container. A slot without a container cant hold food + for (var/datum/cooking_item/CI in cooking_objs) + if (CI.container.check_contents() == 0) + return CI + return 0 + +/obj/machinery/appliance/cooker/add_content(var/obj/item/I, var/mob/user) + var/datum/cooking_item/CI = ..() + if (CI && CI.combine_target) + to_chat(user, "\The [I] will be used to make a [selected_option]. Output selection is returned to default for future items.") + selected_option = null \ No newline at end of file diff --git a/code/modules/food/kitchen/cooking_machines/_cooker_output.dm b/code/modules/food/kitchen/cooking_machines/_cooker_output.dm index cb4dcd15edc..07f7870bc66 100644 --- a/code/modules/food/kitchen/cooking_machines/_cooker_output.dm +++ b/code/modules/food/kitchen/cooking_machines/_cooker_output.dm @@ -1,72 +1,160 @@ -// 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" +// 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." + bitesize = 2 + + var/size = 5 //The quantity of reagents which is considered "normal" for this kind of food + //These objects will change size depending on the ratio of reagents to this value + var/min_scale = 0.5 + var/max_scale = 2 + var/scale = 1 + + w_class = 2 + var/prefix + +/obj/item/weapon/reagent_containers/food/snacks/variable/Initialize() + . = ..() + if (reagents) + reagents.maximum_volume = size*8 + 10 + else + create_reagents(size*8 + 10) + +/obj/item/weapon/reagent_containers/food/snacks/variable/update_icon() + if (reagents && reagents.total_volume) + var/ratio = reagents.total_volume / size + + scale = ratio**(1/3) //Scaling factor is square root of desired area + scale = clamp(scale, min_scale, max_scale) + else + scale = min_scale + + var/matrix/M = matrix() + M.Scale(scale) + src.transform = M + + w_class *= scale + if (!prefix) + if (scale == min_scale) + prefix = "tiny" + else if (scale <= 0.8) + prefix = "small" + + else + if (scale >= 1.2) + prefix = "large" + if (scale >= 1.4) + prefix = "extra large" + if (scale >= 1.6) + prefix = "huge" + if (scale >= max_scale) + prefix = "massive" + + name = "[prefix] [name]" + + +/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" + size = 20 + w_class = 3 + +/obj/item/weapon/reagent_containers/food/snacks/variable/bread + name = "bread" + desc = "Tasty bread." + icon_state = "breadcustom" + size = 40 + w_class = 3 + +/obj/item/weapon/reagent_containers/food/snacks/variable/pie + name = "pie" + desc = "Tasty pie." + icon_state = "piecustom" + size = 25 + +/obj/item/weapon/reagent_containers/food/snacks/variable/cake + name = "cake" + desc = "A popular band." + icon_state = "cakecustom" + size = 40 + w_class = 3 + +/obj/item/weapon/reagent_containers/food/snacks/variable/pocket + name = "hot pocket" + desc = "You wanna put a bangin- oh, nevermind." + icon_state = "donk" + size = 8 + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/variable/kebab + name = "kebab" + desc = "Remove this!" + icon_state = "kabob" + size = 10 + +/obj/item/weapon/reagent_containers/food/snacks/variable/waffles + name = "waffles" + desc = "Made with love." + icon_state = "waffles" + size = 12 + +/obj/item/weapon/reagent_containers/food/snacks/variable/cookie + name = "cookie" + desc = "Sugar snap!" + icon_state = "cookie" + size = 6 + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/variable/donut + name = "filled donut" + desc = "Donut eat this!" // kill me + icon_state = "donut" + size = 8 + w_class = 1 + +/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" + size = 4 + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/variable/candybar + name = "flavored chocolate bar" + desc = "Made in a factory downtown." + icon_state = "bar" + size = 6 + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/variable/sucker + name = "flavored sucker" + desc = "Suck, suck, suck." + icon_state = "sucker" + size = 4 + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/variable/jelly + name = "jelly" + desc = "All your friends will be jelly." + icon_state = "jellycustom" + size = 8 + + +/obj/item/weapon/reagent_containers/food/snacks/variable/cereal + name = "cereal" + desc = "Crispy and flaky" + icon_state = "cereal_box" + size = 30 + w_class = 3 + +/obj/item/weapon/reagent_containers/food/snacks/variable/cereal/Initialize() + . =..() + name = pick(list("flakes", "krispies", "crunch", "pops", "O's", "crisp", "loops", "jacks", "clusters")) + +/obj/item/weapon/reagent_containers/food/snacks/variable/mob + desc = "Poor little thing." + size = 5 + w_class = 1 + var/kitchen_tag = "animal" \ No newline at end of file diff --git a/code/modules/food/kitchen/cooking_machines/_mixer.dm b/code/modules/food/kitchen/cooking_machines/_mixer.dm new file mode 100644 index 00000000000..ce17e55d915 --- /dev/null +++ b/code/modules/food/kitchen/cooking_machines/_mixer.dm @@ -0,0 +1,142 @@ +/* +The mixer subtype is used for the candymaker and cereal maker. They are similar to cookers but with a few +fundamental differences +1. They have a single container which cant be removed. it will eject multiple contents +2. Items can't be added or removed once the process starts +3. Items are all placed in the same container when added directly +4. They do combining mode only. And will always combine the entire contents of the container into an output +*/ + +/obj/machinery/appliance/mixer + max_contents = 1 + stat = POWEROFF + cooking_coeff = 0.75 // Original value 0.4 + active_power_usage = 3000 + idle_power_usage = 50 + +/obj/machinery/appliance/mixer/examine(var/mob/user) + . = ..() + if(Adjacent(user)) + . += "It is currently set to make a [selected_option]" + +/obj/machinery/appliance/mixer/Initialize() + . = ..() + cooking_objs += new /datum/cooking_item(new /obj/item/weapon/reagent_containers/cooking_container(src)) + cooking = FALSE + selected_option = pick(output_options) + +//Mixers cannot-not do combining mode. So the default option is removed from this. A combine target must be chosen +/obj/machinery/appliance/mixer/choose_output() + set src in view(1) + set name = "Choose output" + set category = "Object" + + if (!isliving(usr)) + return + + if (!usr.IsAdvancedToolUser()) + to_chat(usr, "You can't operate [src].") + return + + if(output_options.len) + var/choice = input("What specific food do you wish to make with \the [src]?") as null|anything in output_options + if(!choice) + return + else + selected_option = choice + to_chat(usr, "You prepare \the [src] to make \a [selected_option].") + var/datum/cooking_item/CI = cooking_objs[1] + CI.combine_target = selected_option + + +/obj/machinery/appliance/mixer/has_space(var/obj/item/I) + var/datum/cooking_item/CI = cooking_objs[1] + if (!CI || !CI.container) + return 0 + + if (CI.container.can_fit(I)) + return CI + + return 0 + + +/obj/machinery/appliance/mixer/can_remove_items(var/mob/user) + if (stat) + return 1 + else + to_chat(user, "You can't remove ingredients while it's turned on! Turn it off first or wait for it to finish.") + +//Container is not removable +/obj/machinery/appliance/mixer/removal_menu(var/mob/user) + if (can_remove_items(user)) + var/list/menuoptions = list() + for (var/a in cooking_objs) + var/datum/cooking_item/CI = a + if (CI.container) + if (!CI.container.check_contents()) + to_chat(user, "There's nothing in [src] you can remove!") + return + + for (var/obj/item/I in CI.container) + menuoptions[I.name] = I + + var/selection = input(user, "Which item would you like to remove? If you want to remove chemicals, use an empty beaker.", "Remove ingredients") as null|anything in menuoptions + if (selection) + var/obj/item/I = menuoptions[selection] + if (!user || !user.put_in_hands(I)) + I.forceMove(get_turf(src)) + update_icon() + return 1 + return 0 + + +/obj/machinery/appliance/mixer/toggle_power() + set src in view(1) + set name = "Toggle Power" + set category = "Object" + + var/datum/cooking_item/CI = cooking_objs[1] + if(!CI.container.check_contents()) + to_chat("There's nothing in it! Add ingredients before turning [src] on!") + return + + if(stat & POWEROFF)//Its turned off + stat &= ~POWEROFF + if(usr) + usr.visible_message("[usr] turns the [src] on", "You turn on \the [src].") + get_cooking_work(CI) + use_power = 2 + else //Its on, turn it off + stat |= POWEROFF + use_power = 0 + if(usr) + usr.visible_message("[usr] turns the [src] off", "You turn off \the [src].") + playsound(src, 'sound/machines/click.ogg', 40, 1) + update_icon() + +/obj/machinery/appliance/mixer/can_insert(var/obj/item/I, var/mob/user) + if(!stat) + to_chat(user, ",You can't add items while \the [src] is running. Wait for it to finish or turn the power off to abort.") + return 0 + else + return ..() + +/obj/machinery/appliance/mixer/finish_cooking(var/datum/cooking_item/CI) + ..() + stat |= POWEROFF + playsound(src, 'sound/machines/click.ogg', 40, 1) + use_power = 0 + CI.reset() + update_icon() + +/obj/machinery/appliance/mixer/update_icon() + if (!stat) + icon_state = on_icon + else + icon_state = off_icon + + +/obj/machinery/appliance/mixer/process() + if (!stat) + for (var/i in cooking_objs) + do_cooking_tick(i) \ No newline at end of file diff --git a/code/modules/food/kitchen/cooking_machines/candy.dm b/code/modules/food/kitchen/cooking_machines/candy.dm index 21fd5069119..21f8fdf7157 100644 --- a/code/modules/food/kitchen/cooking_machines/candy.dm +++ b/code/modules/food/kitchen/cooking_machines/candy.dm @@ -1,18 +1,21 @@ -/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) - . = ..() +/obj/machinery/appliance/mixer/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" + appliancetype = CANDYMAKER + circuit = /obj/item/weapon/circuitboard/candymachine + cooking_coeff = 1.0 // Original Value 0.6 + + 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/appliance/mixer/candy/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/cooked/product) + food_color = get_random_colour(1) + . = ..() diff --git a/code/modules/food/kitchen/cooking_machines/cereal.dm b/code/modules/food/kitchen/cooking_machines/cereal.dm index 3a7b19c9b1c..4e272e4773c 100644 --- a/code/modules/food/kitchen/cooking_machines/cereal.dm +++ b/code/modules/food/kitchen/cooking_machines/cereal.dm @@ -1,25 +1,63 @@ -/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 - +/obj/machinery/appliance/mixer/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" + appliancetype = CEREALMAKER + circuit = /obj/item/weapon/circuitboard/cerealmaker + + output_options = list( + "Cereal" = /obj/item/weapon/reagent_containers/food/snacks/variable/cereal + ) + +/* +/obj/machinery/appliance/mixer/cereal/change_product_strings(var/obj/item/weapon/reagent_containers/food/snacks/product, var/datum/cooking_item/CI) + . = ..() + product.name = "box of [CI.object.name] cereal" + +/obj/machinery/appliance/mixer/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 = CI.object.color + + var/image/food_image = image(CI.object.icon, CI.object.icon_state) + food_image.color = CI.object.color + food_image.overlays += CI.object.overlays + food_image.transform *= 0.7 + + product.overlays += food_image +*/ + +/obj/machinery/appliance/mixer/cereal/combination_cook(var/datum/cooking_item/CI) + + var/list/images = list() + var/num = 0 + for(var/obj/item/I in CI.container) + if (istype(I, /obj/item/weapon/reagent_containers/food/snacks/variable/cereal)) + //Images of cereal boxes on cereal boxes is dumb + continue + + var/image/food_image = image(I.icon, I.icon_state) + food_image.color = I.color + food_image.add_overlay(I.overlays) + food_image.transform *= 0.7 - (num * 0.05) + food_image.pixel_x = rand(-2,2) + food_image.pixel_y = rand(-3,5) + + + if (!images[I.icon_state]) + images[I.icon_state] = food_image + num++ + + if (num > 3) + continue + + + var/obj/item/weapon/reagent_containers/food/snacks/result = ..() + + result.color = result.filling_color + for (var/i in images) + result.overlays += images[i] diff --git a/code/modules/food/kitchen/cooking_machines/container.dm b/code/modules/food/kitchen/cooking_machines/container.dm new file mode 100644 index 00000000000..d650a2266e9 --- /dev/null +++ b/code/modules/food/kitchen/cooking_machines/container.dm @@ -0,0 +1,172 @@ +//Cooking containers are used in ovens and fryers, to hold multiple ingredients for a recipe. +//They work fairly similar to the microwave - acting as a container for objects and reagents, +//which can be checked against recipe requirements in order to cook recipes that require several things + +/obj/item/weapon/reagent_containers/cooking_container + icon = 'icons/obj/cooking_machines.dmi' + var/shortname + var/max_space = 20//Maximum sum of w-classes of foods in this container at once + var/max_reagents = 80//Maximum units of reagents + flags = OPENCONTAINER | NOREACT + var/list/insertable = list( + /obj/item/weapon/reagent_containers/food/snacks, + /obj/item/weapon/holder, + /obj/item/weapon/paper + ) + +/obj/item/weapon/reagent_containers/cooking_container/Initialize() + . = ..() + create_reagents(max_reagents) + flags |= OPENCONTAINER | NOREACT + + +/obj/item/weapon/reagent_containers/cooking_container/examine(var/mob/user) + . = ..() + if (contents.len) + var/string = "It contains....
" + for (var/atom/movable/A in contents) + string += "[A.name]
" + . += "[string]" + if (reagents.total_volume) + . += "It contains [reagents.total_volume]u of reagents." + + +/obj/item/weapon/reagent_containers/cooking_container/attackby(var/obj/item/I as obj, var/mob/user as mob) + for (var/possible_type in insertable) + if (istype(I, possible_type)) + if (!can_fit(I)) + to_chat(user, "There's no more space in the [src] for that!") + return 0 + + if(!user.unEquip(I)) + return + I.forceMove(src) + to_chat(user, "You put the [I] into the [src].") + return + +/obj/item/weapon/reagent_containers/cooking_container/verb/empty() + set src in oview(1) + set name = "Empty Container" + set category = "Object" + set desc = "Removes items from the container, excluding reagents." + + do_empty(usr) + +/obj/item/weapon/reagent_containers/cooking_container/proc/do_empty(mob/user) + if (!isliving(user)) + //Here we only check for ghosts. Animals are intentionally allowed to remove things from oven trays so they can eat it + return + + if (user.stat || user.restrained()) + to_chat(user, "You are in no fit state to do this.") + return + + if (!Adjacent(user)) + to_chat(user, "You can't reach [src] from here.") + return + + if (!contents.len) + to_chat(user, "There's nothing in the [src] you can remove!") + return + + for (var/atom/movable/A in contents) + A.forceMove(get_turf(src)) + + to_chat(user, "You remove all the solid items from the [src].") + +/obj/item/weapon/reagent_containers/cooking_container/proc/check_contents() + if (contents.len == 0) + if (!reagents || reagents.total_volume == 0) + return 0//Completely empty + else if (contents.len == 1) + if (!reagents || reagents.total_volume == 0) + return 1//Contains only a single object which can be extracted alone + return 2//Contains multiple objects and/or reagents + +/obj/item/weapon/reagent_containers/cooking_container/AltClick(var/mob/user) + do_empty(user) + +//Deletes contents of container. +//Used when food is burned, before replacing it with a burned mess +/obj/item/weapon/reagent_containers/cooking_container/proc/clear() + for (var/atom/a in contents) + qdel(a) + + if (reagents) + reagents.clear_reagents() + +/obj/item/weapon/reagent_containers/cooking_container/proc/label(var/number, var/CT = null) + //This returns something like "Fryer basket 1 - empty" + //The latter part is a brief reminder of contents + //This is used in the removal menu + . = shortname + if (!isnull(number)) + .+= " [number]" + .+= " - " + if (CT) + .+=CT + else if (contents.len) + for (var/obj/O in contents) + .+=O.name//Just append the name of the first object + return + else if (reagents && reagents.total_volume > 0) + var/datum/reagent/R = reagents.get_master_reagent() + .+=R.name//Append name of most voluminous reagent + return + else + . += "empty" + + +/obj/item/weapon/reagent_containers/cooking_container/proc/can_fit(var/obj/item/I) + var/total = 0 + for (var/obj/item/J in contents) + total += J.w_class + + if((max_space - total) >= I.w_class) + return 1 + + +//Takes a reagent holder as input and distributes its contents among the items in the container +//Distribution is weighted based on the volume already present in each item +/obj/item/weapon/reagent_containers/cooking_container/proc/soak_reagent(var/datum/reagents/holder) + var/total = 0 + var/list/weights = list() + for (var/obj/item/I in contents) + if (I.reagents && I.reagents.total_volume) + total += I.reagents.total_volume + weights[I] = I.reagents.total_volume + + if (total > 0) + for (var/obj/item/I in contents) + if (weights[I]) + holder.trans_to(I, weights[I] / total) + + +/obj/item/weapon/reagent_containers/cooking_container/oven + name = "oven dish" + shortname = "shelf" + desc = "Put ingredients in this; designed for use with an oven. Warranty void if used incorrectly. Alt click to remove contents." + icon_state = "ovendish" + max_space = 30 + max_reagents = 120 + +/obj/item/weapon/reagent_containers/cooking_container/oven/Initialize() + . = ..() + + // We add to the insertable list specifically for the oven trays, to allow specialty cakes. + insertable += list( + /obj/item/clothing/head/cakehat, // This is because we want to allow birthday cakes to be makeable. + /obj/item/organ/internal/brain // As before, needed for braincake + ) + +/obj/item/weapon/reagent_containers/cooking_container/fryer + name = "fryer basket" + shortname = "basket" + desc = "Put ingredients in this; designed for use with a deep fryer. Warranty void if used incorrectly. Alt click to remove contents." + icon_state = "basket" + +/obj/item/weapon/reagent_containers/cooking_container/grill + name = "grill rack" + shortname = "rack" + desc = "Put ingredients 'in'/on this; designed for use with a grill. Warranty void if used incorrectly. Alt click to remove contents." + icon_state = "grillrack" \ No newline at end of file diff --git a/code/modules/food/kitchen/cooking_machines/fryer.dm b/code/modules/food/kitchen/cooking_machines/fryer.dm index e3753f0f486..6c2e0d9b71c 100644 --- a/code/modules/food/kitchen/cooking_machines/fryer.dm +++ b/code/modules/food/kitchen/cooking_machines/fryer.dm @@ -1,4 +1,4 @@ -/obj/machinery/cooker/fryer +/obj/machinery/appliance/cooker/fryer name = "deep fryer" desc = "Deep fried everything." icon_state = "fryer_off" @@ -9,77 +9,261 @@ food_color = "#FFAD33" cooked_sound = 'sound/machines/ding.ogg' var/datum/looping_sound/deep_fryer/fry_loop + circuit = /obj/item/weapon/circuitboard/fryer + appliancetype = FRYER + active_power_usage = 12 KILOWATTS + heating_power = 12 KILOWATTS + + light_y = 15 + + min_temp = 140 + T0C // Same as above, increasing this to just under 2x to make the % increase on efficiency not quite so painful as it would be at 80. + optimal_temp = 400 + T0C // Increasing this to be 2x Oven to allow for a much higher/realistic frying temperatures. Doesn't really do anything but make heating the fryer take a bit longer. + optimal_power = 0.95 // .35 higher than the default to give fryers faster cooking speed. + + idle_power_usage = 3.6 KILOWATTS + // Power used to maintain temperature once it's heated. + // Going with 25% of the active power. This is a somewhat arbitrary value. -/obj/machinery/cooker/fryer/Initialize() + resistance = 10 KILOWATTS // Approx. 10 minutes to heat up. + + max_contents = 2 + container_type = /obj/item/weapon/reagent_containers/cooking_container/fryer + + stat = POWEROFF // Starts turned off + + var/datum/reagents/oil + var/optimal_oil = 9000 //90 litres of cooking oil + +/obj/machinery/appliance/cooker/fryer/Initialize() + . = ..() fry_loop = new(list(src), FALSE) - return ..() + + oil = new/datum/reagents(optimal_oil * 1.25, src) + var/variance = rand()*0.15 + // Fryer is always a little below full, but its usually negligible -/obj/machinery/cooker/fryer/Destroy() + if(prob(20)) + // Sometimes the fryer will start with much less than full oil, significantly impacting efficiency until filled + variance = rand()*0.5 + oil.add_reagent("cornoil", optimal_oil*(1 - variance)) + +/obj/machinery/appliance/cooker/fryer/Destroy() QDEL_NULL(fry_loop) + QDEL_NULL(oil) return ..() - -/obj/machinery/cooker/fryer/set_cooking(new_setting) - ..() - if(new_setting) - fry_loop.start() + +/obj/machinery/appliance/cooker/fryer/examine(var/mob/user) + . = ..() + if(Adjacent(user)) + to_chat(user, "Oil Level: [oil.total_volume]/[optimal_oil]") + +/obj/machinery/appliance/cooker/fryer/update_icon() // We add our own version of the proc to use the special fryer double-lights. + cut_overlays() + var/image/light + if(use_power == 1 && !stat) + light = image(icon, "fryer_light_idle") + else if(use_power == 2 && !stat) + light = image(icon, "fryer_light_preheating") else - fry_loop.stop() + light = image(icon, "fryer_light_off") + light.pixel_x = light_x + light.pixel_y = light_y + add_overlay(light) + +/obj/machinery/appliance/cooker/fryer/heat_up() + if (..()) + //Set temperature of oil reagent + var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent() + if (OL && istype(OL)) + OL.data["temperature"] = temperature -/obj/machinery/cooker/fryer/cook_mob(var/mob/living/victim, var/mob/user) +/obj/machinery/appliance/cooker/fryer/equalize_temperature() + if (..()) + //Set temperature of oil reagent + var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent() + if (OL && istype(OL)) + OL.data["temperature"] = temperature + +/obj/machinery/appliance/cooker/fryer/update_cooking_power() + ..()//In addition to parent temperature calculation + //Fryer efficiency also drops when oil levels arent optimal + var/oil_level = 0 + var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent() + if(OL && istype(OL)) + oil_level = OL.volume + + var/oil_efficiency = 0 + if(oil_level) + oil_efficiency = oil_level / optimal_oil + + if(oil_efficiency > 1) + //We're above optimal, efficiency goes down as we pass too much over it + oil_efficiency = 1 - (oil_efficiency - 1) + + + cooking_power *= oil_efficiency + +/obj/machinery/appliance/cooker/fryer/update_icon() + if(!stat) + ..() + if(cooking == TRUE) + icon_state = on_icon + if(fry_loop) + fry_loop.start(src) + else + icon_state = off_icon + if(fry_loop) + fry_loop.stop(src) + else + icon_state = off_icon + if(fry_loop) + fry_loop.stop(src) + ..() + +//Fryer gradually infuses any cooked food with oil. Moar calories +//This causes a slow drop in oil levels, encouraging refill after extended use +/obj/machinery/appliance/cooker/fryer/do_cooking_tick(var/datum/cooking_item/CI) + if(..() && (CI.oil < CI.max_oil) && prob(20)) + var/datum/reagents/buffer = new /datum/reagents(2) + oil.trans_to_holder(buffer, min(0.5, CI.max_oil - CI.oil)) + CI.oil += buffer.total_volume + CI.container.soak_reagent(buffer) + + +//To solve any odd logic problems with results having oil as part of their compiletime ingredients. +//Upon finishing a recipe the fryer will analyse any oils in the result, and replace them with our oil +//As well as capping the total to the max oil +/obj/machinery/appliance/cooker/fryer/finish_cooking(var/datum/cooking_item/CI) + ..() + var/total_oil = 0 + var/total_our_oil = 0 + var/total_removed = 0 + var/datum/reagent/our_oil = oil.get_master_reagent() + + for (var/obj/item/I in CI.container) + if (I.reagents && I.reagents.total_volume) + for (var/datum/reagent/R in I.reagents.reagent_list) + if (istype(R, /datum/reagent/nutriment/triglyceride/oil)) + total_oil += R.volume + if (R.id != our_oil.id) + total_removed += R.volume + I.reagents.remove_reagent(R.id, R.volume) + else + total_our_oil += R.volume + + + if (total_removed > 0 || total_oil != CI.max_oil) + total_oil = min(total_oil, CI.max_oil) + + if (total_our_oil < total_oil) + //If we have less than the combined total, then top up from our reservoir + var/datum/reagents/buffer = new /datum/reagents(INFINITY) + oil.trans_to_holder(buffer, total_oil - total_our_oil) + CI.container.soak_reagent(buffer) + else if (total_our_oil > total_oil) + + //If we have more than the maximum allowed then we delete some. + //This could only happen if one of the objects spawns with the same type of oil as ours + var/portion = 1 - (total_oil / total_our_oil) //find the percentage to remove + for (var/obj/item/I in CI.container) + if (I.reagents && I.reagents.total_volume) + for (var/datum/reagent/R in I.reagents.reagent_list) + if (R.id == our_oil.id) + I.reagents.remove_reagent(R.id, R.volume*portion) + +/obj/machinery/appliance/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 - fry_loop.start() + // user.visible_message("\The [user] starts pushing \the [victim] into \the [src]!") + + //Removed delay on this action in favour of a cooldown after it + //If you can lure someone close to the fryer and grab them then you deserve success. + //And a delay on this kind of niche action just ensures it never happens + //Cooldown ensures it can't be spammed to instakill someone + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN*3) + + fry_loop.start(src) if(!do_mob(user, victim, 20)) - cooking = 0 + cooking = FALSE icon_state = off_icon - fry_loop.stop() + fry_loop.stop(src) return if(!victim || !victim.Adjacent(user)) to_chat(user, "Your victim slipped free!") - cooking = 0 + cooking = FALSE icon_state = off_icon - fry_loop.stop() + fry_loop.stop(src) return + var/damage = rand(7,13) // Though this damage seems reduced, some hot oil is transferred to the victim and will burn them for a while after + + var/datum/reagent/nutriment/triglyceride/oil/OL = oil.get_master_reagent() + damage *= OL.heatdamage(victim) + 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.robotic >= ORGAN_ROBOT) + if(!E || E.species.flags & NO_PAIN) + nopain = 2 + else if(E.robotic >= ORGAN_ROBOT) nopain = 1 user.visible_message("\The [user] shoves \the [victim][E ? "'s [E.name]" : ""] into \the [src]!") + if (damage > 0) + if(E) + if(E.children && E.children.len) + for(var/obj/item/organ/external/child in E.children) + if(nopain && nopain < 2 && !(child.robotic >= ORGAN_ROBOT)) + nopain = 0 + child.take_damage(0, damage) + damage -= (damage*0.5)//IF someone's arm is plunged in, the hand should take most of it + E.take_damage(0, damage) + else + victim.apply_damage(damage, BURN, user.zone_sel.selecting) - 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.robotic >= 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) + to_chat(victim, "Agony consumes you as searing hot oil scorches your [E ? E.name : "flesh"] horribly!") + victim.emote("scream") + else + to_chat(victim, "Searing hot oil scorches your [E ? E.name : "flesh"]!") - if(!nopain) - to_chat(victim, "Agony consumes you as searing hot oil scorches your [E ? E.name : "flesh"] horribly!") - victim.emote("scream") - else - to_chat(victim, "Searing hot oil scorches your [E ? E.name : "flesh"]!") + 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("[key_name_admin(user)] [cook_type] \the [victim] ([victim.ckey]) in \a [src]. (JMP)") - if(victim.client) - add_attack_logs(user,victim,"[cook_type] in [src]") - - icon_state = off_icon - cooking = 0 + //Coat the victim in some oil + oil.trans_to(victim, 40) + fry_loop.stop() - return + +/obj/machinery/appliance/cooker/fryer/attackby(var/obj/item/I, var/mob/user) + if(istype(I, /obj/item/weapon/reagent_containers/glass) && I.reagents) + if (I.reagents.total_volume <= 0 && oil) + //Its empty, handle scooping some hot oil out of the fryer + oil.trans_to(I, I.reagents.maximum_volume) + user.visible_message("[user] scoops some oil out of \the [src].", span("notice","You scoop some oil out of \the [src].")) + return 1 + else + //It contains stuff, handle pouring any oil into the fryer + //Possibly in future allow pouring non-oil reagents in, in order to sabotage it and poison food. + //That would really require coding some sort of filter or better replacement mechanism first + //So for now, restrict to oil only + var/amount = 0 + for (var/datum/reagent/R in I.reagents.reagent_list) + if (istype(R, /datum/reagent/nutriment/triglyceride/oil)) + var/delta = oil.get_free_space() + delta = min(delta, R.volume) + oil.add_reagent(R.id, delta) + I.reagents.remove_reagent(R.id, delta) + amount += delta + if (amount > 0) + user.visible_message("[user] pours some oil into \the [src].", span("notice","You pour [amount]u of oil into \the [src]."), "You hear something viscous being poured into a metal container.") + return 1 + //If neither of the above returned, then call parent as normal + ..() diff --git a/code/modules/food/kitchen/cooking_machines/grill.dm b/code/modules/food/kitchen/cooking_machines/grill.dm index 312189c5881..6db3c893317 100644 --- a/code/modules/food/kitchen/cooking_machines/grill.dm +++ b/code/modules/food/kitchen/cooking_machines/grill.dm @@ -1,10 +1,102 @@ -/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 +/obj/machinery/appliance/cooker/grill + name = "grill" + desc = "Backyard grilling, IN SPACE." + icon_state = "grill_off" + cook_type = "grilled" + appliancetype = GRILL + food_color = "#A34719" + on_icon = "grill_on" + off_icon = "grill_off" + can_burn_food = TRUE + circuit = /obj/item/weapon/circuitboard/grill + active_power_usage = 4 KILOWATTS + heating_power = 4000 + idle_power_usage = 2 KILOWATTS + + optimal_power = 1.2 // Things on the grill cook .6 faster - this is now the fastest appliance to heat and to cook on. BURGERS GO SIZZLE. + + stat = POWEROFF // Starts turned off. + + // Grill is faster to heat and setup than the rest. + optimal_temp = 120 + T0C + min_temp = 60 + T0C + resistance = 8 KILOWATTS // Very fast to heat up. + + max_contents = 3 // Arbitrary number, 3 grill 'racks' + container_type = /obj/item/weapon/reagent_containers/cooking_container/grill + +/* // Test Comment this out too, /cooker does this for us, and this path '/obj/machinery/appliance/grill' is invalid anyways, meaning it does jack shit. - Updated the paths, but I'm basically commenting all this shit out and if the grill works as-normal, none of this stuff is needed. +/obj/machinery/appliance/grill/toggle_power() + set src in view() + set name = "Toggle Power" + set category = "Object" + + var/datum/cooking_item/CI = cooking_objs[1] + + if (stat & POWEROFF)//Its turned off + stat &= ~POWEROFF + if (usr) + usr.visible_message("[usr] turns \the [src] on", "You turn on \the [src].") + get_cooking_work(CI) + use_power = 2 + else //It's on, turn it off + stat |= POWEROFF + use_power = 0 + if (usr) + usr.visible_message("[usr] turns \the [src] off", "You turn off \the [src].") + playsound(src, 'sound/machines/click.ogg', 40, 1) + update_icon() + + +/obj/machinery/appliance/cooker/grill/Initialize() + . = ..() + // cooking_objs += new /datum/cooking_item(new /obj/item/weapon/reagent_containers/cooking_container(src)) + cooking = FALSE + +/obj/machinery/appliance/cooker/grill/has_space(var/obj/item/I) + var/datum/cooking_item/CI = cooking_objs[1] + if (!CI || !CI.container) + return 0 + + if (CI.container.can_fit(I)) + return CI + + return 0 +*/ +/* // Test comment this out, I don't think this is doing shit anyways. +//Container is not removable +/obj/machinery/appliance/grill/removal_menu(var/mob/user) + if (can_remove_items(user)) + var/list/menuoptions = list() + for (var/a in cooking_objs) + var/datum/cooking_item/CI = a + if (CI.container) + if (!CI.container.check_contents()) + to_chat(user, "There's nothing in the [src] you can remove!") + return + + for (var/obj/item/I in CI.container) + menuoptions[I.name] = I + + var/selection = input(user, "Which item would you like to remove? If you want to remove chemicals, use an empty beaker.", "Remove ingredients") as null|anything in menuoptions + if (selection) + var/obj/item/I = menuoptions[selection] + if (!user || !user.put_in_hands(I)) + I.forceMove(get_turf(src)) + update_icon() + return 1 + return 0 +*/ + +/obj/machinery/appliance/grill/update_icon() // TODO: Cooking icon + if(!stat) + icon_state = on_icon + else + icon_state = off_icon + +/* // Test remove this too. +/obj/machinery/appliance/grill/process() + if (!stat) + for (var/i in cooking_objs) + do_cooking_tick(i) +*/ \ No newline at end of file diff --git a/code/modules/food/kitchen/cooking_machines/oven.dm b/code/modules/food/kitchen/cooking_machines/oven.dm index ec941af2239..72780aa62c2 100644 --- a/code/modules/food/kitchen/cooking_machines/oven.dm +++ b/code/modules/food/kitchen/cooking_machines/oven.dm @@ -1,23 +1,136 @@ -/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 +/obj/machinery/appliance/cooker/oven + name = "oven" + desc = "Cookies are ready, dear." + icon = 'icons/obj/cooking_machines.dmi' + icon_state = "ovenopen" + cook_type = "baked" + appliancetype = OVEN + food_color = "#A34719" + can_burn_food = TRUE + circuit = /obj/item/weapon/circuitboard/oven + active_power_usage = 6 KILOWATTS + heating_power = 6 KILOWATTS + //Based on a double deck electric convection oven + + resistance = 12 KILOWATTS // Approx. 12 minutes to heat up. + idle_power_usage = 2 KILOWATTS + //uses ~30% power to stay warm + optimal_power = 0.8 // Oven cooks .2 faster than the default speed. + + light_x = 3 + light_y = 4 + max_contents = 5 + container_type = /obj/item/weapon/reagent_containers/cooking_container/oven + + stat = POWEROFF //Starts turned off + + var/open = FALSE // Start closed just so people don't try to preheat with it open, lol. + + output_options = list( + "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, + "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, + ) + +/obj/machinery/appliance/cooker/oven/update_icon() + if(!open) + if(!stat) + icon_state = "ovenclosed_on" + if(cooking == TRUE) + icon_state = "ovenclosed_cooking" + else + icon_state = "ovenclosed_on" + else + icon_state = "ovenclosed_off" + else + icon_state = "ovenopen" + ..() + +/obj/machinery/appliance/cooker/oven/AltClick(var/mob/user) + try_toggle_door(user) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + +/obj/machinery/appliance/cooker/oven/verb/toggle_door() + set src in oview(1) + set category = "Object" + set name = "Open/close oven door" + + try_toggle_door(usr) + +/obj/machinery/appliance/cooker/oven/proc/try_toggle_door(mob/user) + if(!isliving(usr) || isAI(user)) + return + + if(!usr.IsAdvancedToolUser()) + to_chat(user, "You lack the dexterity to do that.") + return + + if(!Adjacent(usr)) + to_chat(user, "You can't reach the [src] from there, get closer!") + return + + if(open) + open = FALSE + loss = (heating_power / resistance) * 0.5 + cooking = TRUE + else + open = TRUE + loss = (heating_power / resistance) * 4 + //When the oven door is opened, heat is lost MUCH faster and you stop cooking (because the door is open) + cooking = FALSE + + playsound(src, 'sound/machines/hatch_open.ogg', 20, 1) + to_chat(user, "You [open? "close":"open"] the oven door") + update_icon() + +/obj/machinery/appliance/cooker/oven/proc/manip(var/obj/item/I) + // check if someone's trying to manipulate the machine + + if(I.is_crowbar() || I.is_screwdriver() || istype(I, /obj/item/weapon/storage/part_replacer)) + return TRUE + else + return FALSE + +/obj/machinery/appliance/cooker/oven/can_insert(var/obj/item/I, var/mob/user) + if(!open && !manip(I)) + to_chat(user, "You can't put anything in while the door is closed!") + return 0 + + else + return ..() + + +//If an oven's door is open it will lose heat every proc, even if it also gained it +//But dont call equalize twice in one stack. A return value of -1 from the parent indicates equalize was already called +/obj/machinery/appliance/cooker/oven/heat_up() + .=..() + if(open && . != -1) + var/turf/T = get_turf(src) + if(temperature > T.temperature) + equalize_temperature() + +/obj/machinery/appliance/cooker/oven/can_remove_items(var/mob/user) + if(!open) + to_chat(user, "You can't take anything out while the door is closed!") + return 0 + + else + return ..() + + +//Oven has lots of recipes and combine options. The chance for interference is high, so +//If a combine target is set the oven will do it instead of checking recipes +/obj/machinery/appliance/cooker/oven/finish_cooking(var/datum/cooking_item/CI) + if(CI.combine_target) + CI.result_type = 3//Combination type. We're making something out of our ingredients + visible_message("\The [src] pings!") + combination_cook(CI) + return + else + ..() \ No newline at end of file diff --git a/code/modules/food/kitchen/microwave.dm b/code/modules/food/kitchen/microwave.dm index 8f27afe2b15..065d036920c 100644 --- a/code/modules/food/kitchen/microwave.dm +++ b/code/modules/food/kitchen/microwave.dm @@ -1,13 +1,14 @@ /obj/machinery/microwave - name = "microwave" + name = "Microwave" desc = "Studies are inconclusive on whether pressing your face against the glass is harmful." icon = 'icons/obj/kitchen.dmi' icon_state = "mw" + layer = 2.9 density = 1 anchored = 1 use_power = USE_POWER_IDLE idle_power_usage = 5 - active_power_usage = 100 + active_power_usage = 2000 clicksound = "button" clickvol = "30" flags = OPENCONTAINER | NOREACT @@ -18,9 +19,11 @@ var/circuit_item_capacity = 1 //how many items does the circuit add to max number of items var/item_level = 0 // items microwave can handle, 0 foodstuff, 1 materials var/global/list/acceptable_items // List of the items you can put in - var/global/list/datum/recipe/microwave/available_recipes // List of the recipes you can use + var/global/list/available_recipes // List of the recipes you can use var/global/list/acceptable_reagents // List of the reagents you can put in - var/global/max_n_of_items = 0 + + var/global/max_n_of_items = 20 + var/appliancetype = MICROWAVE var/datum/looping_sound/microwave/soundloop @@ -32,24 +35,26 @@ /obj/machinery/microwave/Initialize() . = ..() + reagents = new/datum/reagents(100) reagents.my_atom = src default_apply_parts() - if (!available_recipes) + if(!available_recipes) available_recipes = new - for (var/type in (typesof(/datum/recipe/microwave)-/datum/recipe/microwave)) - available_recipes+= new type + for(var/T in (typesof(/datum/recipe)-/datum/recipe)) + var/datum/recipe/type = T + if((initial(type.appliance) & appliancetype)) + available_recipes += new type + acceptable_items = new acceptable_reagents = new - for (var/datum/recipe/microwave/recipe in available_recipes) + for (var/datum/recipe/recipe in available_recipes) for (var/item in recipe.items) acceptable_items |= item for (var/reagent in recipe.reagents) acceptable_reagents |= reagent - if (recipe.items) - max_n_of_items = max(max_n_of_items,recipe.items.len) // This will do until I can think of a fun recipe to use dionaea in - // will also allow anything using the holder item to be microwaved into // impure carbon. ~Z @@ -99,12 +104,6 @@ else to_chat(user, "It's broken!") return 1 - else if(default_deconstruction_screwdriver(user, O)) - return - else if(default_deconstruction_crowbar(user, O)) - return - else if(default_unfasten_wrench(user, O, 10)) - return else if(src.dirty==100) // The microwave is all dirty so can't be used! if(istype(O, /obj/item/weapon/reagent_containers/spray/cleaner) || istype(O, /obj/item/weapon/soap)) // If they're trying to clean it then let them @@ -125,7 +124,7 @@ to_chat(user, "It's dirty!") return 1 else if(is_type_in_list(O,acceptable_items)) - if (contents.len>=(max_n_of_items + component_parts.len + circuit_item_capacity)) //Adds component_parts to the maximum number of items. changed 1 to actually just be the circuit item capacity var. + if(contents.len>=(max_n_of_items + component_parts.len + circuit_item_capacity)) //Adds component_parts to the maximum number of items. changed 1 to actually just be the circuit item capacity var. to_chat(user, "This [src] is full of ingredients, you cannot put more.") return 1 if(istype(O, /obj/item/stack) && O:get_amount() > 1) // This is bad, but I can't think of how to change it @@ -137,9 +136,8 @@ "You add one of [O] to \the [src].") return else - // user.remove_from_mob(O) //This just causes problems so far as I can tell. -Pete - user.drop_item() - O.loc = src + // user.remove_from_mob(O) //This just causes problems so far as I can tell. -Pete - Man whoever you are, it's been years. o7 + user.drop_from_inventory(O,src) user.visible_message( \ "\The [user] has added \the [O] to \the [src].", \ "You add \the [O] to \the [src].") @@ -159,6 +157,27 @@ var/obj/item/weapon/grab/G = O to_chat(user, "This is ridiculous. You can not fit \the [G.affecting] in this [src].") return 1 + else if(O.is_screwdriver()) + default_deconstruction_screwdriver(user, O) + return + else if(O.is_crowbar()) + if(default_deconstruction_crowbar(user, O)) + return + else + user.visible_message( \ + "\The [user] begins [src.anchored ? "unsecuring" : "securing"] the microwave.", \ + "You attempt to [src.anchored ? "unsecure" : "secure"] the microwave." + ) + if (do_after(user,20/O.toolspeed)) + user.visible_message( \ + "\The [user] [src.anchored ? "unsecures" : "secures"] the microwave.", \ + "You [src.anchored ? "unsecure" : "secure"] the microwave." + ) + src.anchored = !src.anchored + else + to_chat(user, "You decide not to do that.") + else if(default_part_replacement(user, O)) + return else to_chat(user, "You have no idea what you can cook with this [O].") ..() @@ -248,64 +267,98 @@ if(stat & (NOPOWER|BROKEN)) return start() - if (reagents.total_volume==0 && !(locate(/obj) in ((contents - component_parts) - circuit))) //dry run - if (!wzhzhzh(5)) //VOREStation Edit - Quicker Microwaves + if(reagents.total_volume==0 && !(locate(/obj) in ((contents - component_parts) - circuit))) //dry run + if(!wzhzhzh(16)) //VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was 5) abort() return abort() return - var/datum/recipe/microwave/recipe = select_recipe(available_recipes,src) + var/datum/recipe/recipe = select_recipe(available_recipes,src) var/obj/cooked - if (!recipe) + if(!recipe) dirty += 1 - if (prob(max(10,dirty*5))) - if (!wzhzhzh(2)) //VOREStation Edit - Quicker Microwaves + if(prob(max(10,dirty*5))) + if(!wzhzhzh(16)) //VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was 2) abort() return muck_start() - wzhzhzh(2) //VOREStation Edit - Quicker Microwaves + wzhzhzh(2) //VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was 2) muck_finish() cooked = fail() - cooked.loc = src.loc - return - else if (has_extra_item()) - if (!wzhzhzh(2)) //VOREStation Edit - Quicker Microwaves + cooked.forceMove(src.loc) + else if(has_extra_item()) + if(!wzhzhzh(16)) //VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was 2) abort() return broke() cooked = fail() - cooked.loc = src.loc - return + cooked.forceMove(src.loc) else - if (!wzhzhzh(5)) //VOREStation Edit - Quicker Microwaves + if(!wzhzhzh(40)) //VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was 5) abort() return - abort() + stop() cooked = fail() - cooked.loc = src.loc - return - else - var/halftime = round(recipe.time/20/2) //VOREStation Edit - Quicker Microwaves - if (!wzhzhzh(halftime)) - abort() - return - if (!wzhzhzh(halftime)) - abort() - cooked = fail() - cooked.loc = src.loc - return - cooked = recipe.make_food(src) - abort() - if(cooked) - cooked.loc = src.loc + cooked.forceMove(src.loc) return + + //Making multiple copies of a recipe + var/halftime = round(recipe.time*4/10/2) // VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was round(recipe.time/20/2)) + if(!wzhzhzh(halftime)) + abort() + return + recipe.before_cook(src) + if(!wzhzhzh(halftime)) + abort() + cooked = fail() + cooked.forceMove(loc) + recipe.after_cook(src) + return + + var/result = recipe.result + var/valid = 1 + var/list/cooked_items = list() + var/obj/temp = new /obj(src) //To prevent infinite loops, all results will be moved into a temporary location so they're not considered as inputs for other recipes + while(valid) + var/list/things = list() + things.Add(recipe.make_food(src)) + cooked_items += things + //Move cooked things to the buffer so they're not considered as ingredients + for(var/atom/movable/AM in things) + AM.forceMove(temp) + + valid = 0 + recipe.after_cook(src) + recipe = select_recipe(available_recipes,src) + if(recipe && recipe.result == result) + valid = 1 + sleep(2) + + for(var/r in cooked_items) + var/atom/movable/R = r + R.forceMove(src) //Move everything from the buffer back to the container + + QDEL_NULL(temp)//Delete buffer object + + //Any leftover reagents are divided amongst the foods + var/total = reagents.total_volume + for(var/obj/item/weapon/reagent_containers/food/snacks/S in cooked_items) + reagents.trans_to_holder(S.reagents, total/cooked_items.len) + + for(var/obj/item/weapon/reagent_containers/food/snacks/S in contents) + S.cook() + + dispose(0) //clear out anything left + stop() + + return /obj/machinery/microwave/proc/wzhzhzh(var/seconds as num) // Whoever named this proc is fucking literally Satan. ~ Z for (var/i=1 to seconds) if (stat & (NOPOWER|BROKEN)) return 0 - use_power(500) + use_power(active_power_usage) sleep(5) //VOREStation Edit - Quicker Microwaves return 1 @@ -339,17 +392,27 @@ /obj/machinery/microwave/proc/abort() operating = FALSE // Turn it off again aferwards - icon_state = "mw" + if(icon_state == "mw1") + icon_state = "mw" + updateUsrDialog() + soundloop.stop() + +/obj/machinery/microwave/proc/stop() + playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) + operating = FALSE // Turn it off again aferwards + if(icon_state == "mw1") + icon_state = "mw" updateUsrDialog() soundloop.stop() -/obj/machinery/microwave/proc/dispose() - for (var/obj/O in ((contents-component_parts)-circuit)) - O.loc = src.loc +/obj/machinery/microwave/proc/dispose(var/message = 1) + for (var/atom/movable/A in ((contents-component_parts)-circuit)) + A.forceMove(loc) if (src.reagents.total_volume) src.dirty++ src.reagents.clear_reagents() - to_chat(usr, "You dispose of the microwave contents.") + if(message) + to_chat(usr, "You dispose of the microwave contents.") src.updateUsrDialog() /obj/machinery/microwave/proc/muck_start() @@ -383,10 +446,14 @@ var/amount = 0 for (var/obj/O in (((contents - ffuu) - component_parts) - circuit)) amount++ - if (O.reagents) + if(O.reagents) var/id = O.reagents.get_master_reagent_id() - if (id) + if(id) amount+=O.reagents.get_reagent_amount(id) + if(istype(O, /obj/item/weapon/holder)) + var/obj/item/weapon/holder/H = O + if(H.held_mob) + qdel(H.held_mob) qdel(O) src.reagents.clear_reagents() ffuu.reagents.add_reagent("carbon", amount) @@ -409,6 +476,36 @@ if ("dispose") dispose() return + +/obj/machinery/microwave/verb/Eject() + set src in oview(1) + set category = "Object" + set name = "Eject content" + usr.visible_message( + "[usr] tries to open [src] and remove its contents." , + "You try to open [src] and remove its contents." + ) + + if(!do_after(usr, 1 SECONDS, target = src)) + return + + if(operating) + to_chat(usr, "You can't do that, [src] door is locked!") + return + + usr.visible_message( + "[usr] opened [src] and has taken out [english_list(((contents-component_parts)-circuit))]." , + "You have opened [src] and taken out [english_list(((contents-component_parts)-circuit))]." + ) + dispose() + +/obj/machinery/microwave/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(!mover) + return 1 + if(mover.checkpass(PASSTABLE)) + //Animals can run under them, lots of empty space + return 1 + return ..() /obj/machinery/microwave/advanced // specifically for complex recipes name = "deluxe microwave" @@ -421,3 +518,32 @@ /obj/machinery/microwave/advanced/Initialize() ..() reagents.maximum_volume = 1000 + +/datum/recipe/splat // We use this to handle cooking micros (or mice, etc) in a microwave. Janky but it works better than snowflake code to handle the same thing. + items = list( + /obj/item/weapon/holder + ) + result = /obj/effect/decal/cleanable/blood/gibs + +/datum/recipe/splat/before_cook(obj/container) + if(istype(container, /obj/machinery/microwave)) + var/obj/machinery/microwave/M = container + M.muck_start() + playsound(container.loc, 'sound/items/drop/flesh.ogg', 100, 1) + . = ..() + +/datum/recipe/splat/make_food(obj/container) + for(var/obj/item/weapon/holder/H in container) + if(H.held_mob) + to_chat(H.held_mob, "You hear an earsplitting humming and your head aches!") + qdel(H.held_mob) + H.held_mob = null + qdel(H) + + . = ..() + +/datum/recipe/splat/after_cook(obj/container) + if(istype(container, /obj/machinery/microwave)) + var/obj/machinery/microwave/M = container + M.muck_finish() + . = ..() diff --git a/code/modules/food/kitchen/smartfridge.dm b/code/modules/food/kitchen/smartfridge.dm index c798ed3875d..7184b2f68c8 100644 --- a/code/modules/food/kitchen/smartfridge.dm +++ b/code/modules/food/kitchen/smartfridge.dm @@ -243,7 +243,6 @@ user.visible_message("[user] [panel_open ? "opens" : "closes"] the maintenance panel of \the [src].", "You [panel_open ? "open" : "close"] the maintenance panel of \the [src].") playsound(src, O.usesound, 50, 1) update_icon() - SSnanoui.update_uis(src) return if(wrenchable && default_unfasten_wrench(user, O, 20)) @@ -263,7 +262,6 @@ stock(O) user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].") - else if(istype(O, /obj/item/weapon/storage/bag)) var/obj/item/weapon/storage/bag/P = O var/plants_loaded = 0 @@ -309,11 +307,11 @@ var/datum/stored_item/item = new/datum/stored_item(src, O.type, O.name) item.add_product(O) item_records.Add(item) - SSnanoui.update_uis(src) + SStgui.update_uis(src) /obj/machinery/smartfridge/proc/vend(datum/stored_item/I) I.get_product(get_turf(src)) - SSnanoui.update_uis(src) + SStgui.update_uis(src) /obj/machinery/smartfridge/attack_ai(mob/user as mob) attack_hand(user) @@ -322,66 +320,59 @@ if(stat & (NOPOWER|BROKEN)) return wires.Interact(user) - ui_interact(user) + tgui_interact(user) -/******************* -* SmartFridge Menu -********************/ +/obj/machinery/smartfridge/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SmartVend", name) + ui.set_autoupdate(FALSE) + ui.open() -/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/smartfridge/tgui_data(mob/user) + . = list() - var/data[0] - data["contents"] = null - data["electrified"] = seconds_electrified > 0 - data["shoot_inventory"] = shoot_inventory - data["locked"] = locked - data["secure"] = is_secure - - var/list/items[0] - for (var/i=1 to length(item_records)) + var/list/items = list() + for(var/i=1 to length(item_records)) var/datum/stored_item/I = item_records[i] var/count = I.get_amount() if(count > 0) - items.Add(list(list("display_name" = html_encode(capitalize(I.item_name)), "vend" = i, "quantity" = count))) + items.Add(list(list("name" = html_encode(capitalize(I.item_name)), "index" = i, "amount" = count))) - if(items.len > 0) - data["contents"] = items + .["contents"] = items + .["name"] = name + .["locked"] = locked + .["secure"] = is_secure - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "smartfridge.tmpl", src.name, 400, 500) - ui.set_initial_data(data) - ui.open() +/obj/machinery/smartfridge/tgui_act(action, params) + if(..()) + return TRUE -/obj/machinery/smartfridge/Topic(href, href_list) - if(..()) return 0 + add_fingerprint(usr) + switch(action) + if("Release") + var/amount = 0 + if(params["amount"]) + amount = params["amount"] + else + amount = input("How many items?", "How many items would you like to take out?", 1) as num|null + + if(QDELETED(src) || QDELETED(usr) || !usr.Adjacent(src)) + return FALSE + + var/index = text2num(params["index"]) + var/datum/stored_item/I = item_records[index] + var/count = I.get_amount() - var/mob/user = usr - var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") + // Sanity check, there are probably ways to press the button when it shouldn't be possible. + if(count > 0) + if((count - amount) < 0) + amount = count + for(var/i = 1 to amount) + vend(I) - src.add_fingerprint(user) - - if(href_list["close"]) - user.unset_machine() - ui.close() - return 0 - - if(href_list["vend"]) - var/index = text2num(href_list["vend"]) - var/amount = text2num(href_list["amount"]) - var/datum/stored_item/I = item_records[index] - var/count = I.get_amount() - - // Sanity check, there are probably ways to press the button when it shouldn't be possible. - if(count > 0) - if((count - amount) < 0) - amount = count - for(var/i = 1 to amount) - vend(I) - - return 1 - return 0 + return TRUE + return FALSE /obj/machinery/smartfridge/proc/throw_item() var/obj/throw_item = null @@ -400,17 +391,18 @@ spawn(0) throw_item.throw_at(target,16,3,src) src.visible_message("[src] launches [throw_item.name] at [target.name]!") + SStgui.update_uis(src) return 1 /************************ * Secure SmartFridges *************************/ -/obj/machinery/smartfridge/secure/Topic(href, href_list) +/obj/machinery/smartfridge/secure/tgui_act(action, params) if(stat & (NOPOWER|BROKEN)) - return 0 + return TRUE if(usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) - if(!allowed(usr) && !emagged && locked != -1 && href_list["vend"]) + if(!allowed(usr) && !emagged && locked != -1 && action == "Release") to_chat(usr, "Access denied.") - return 0 + return TRUE return ..() diff --git a/code/modules/food/recipe.dm b/code/modules/food/recipe.dm new file mode 100644 index 00000000000..8c7f1092bd1 --- /dev/null +++ b/code/modules/food/recipe.dm @@ -0,0 +1,327 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * + * /datum/recipe by rastaf0 13 apr 2011 * + * * * * * * * * * * * * * * * * * * * * * * * * * * + * This is powerful and flexible recipe system. + * It exists not only for food. + * supports both reagents and objects as prerequisites. + * In order to use this system you have to define a deriative from /datum/recipe + * * reagents are reagents. Acid, milc, booze, etc. + * * items are objects. Fruits, tools, circuit boards. + * * result is type to create as new object + * * time is optional parameter, you shall use in in your machine, + default /datum/recipe/ procs does not rely on this parameter. + * + * Functions you need: + * /datum/recipe/proc/make(var/obj/container as obj) + * Creates result inside container, + * deletes prerequisite reagents, + * transfers reagents from prerequisite objects, + * deletes all prerequisite objects (even not needed for recipe at the moment). + * + * /proc/select_recipe(list/datum/recipe/available_recipes, obj/obj as obj, exact = 1) + * Wonderful function that select suitable recipe for you. + * obj is a machine (or magik hat) with prerequisites, + * exact = 0 forces algorithm to ignore superfluous stuff. + * + * + * Functions you do not need to call directly but could: + * /datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents) + * /datum/recipe/proc/check_items(var/obj/container as obj) + * + * */ + +// Recipe type defines. Used to determine what machine makes them. +#define MICROWAVE 0x1 +#define FRYER 0x2 +#define OVEN 0x4 +#define GRILL 0x8 +#define CANDYMAKER 0x10 +#define CEREALMAKER 0x20 + +/datum/recipe + var/list/reagents // Example: = list("berryjuice" = 5) // do not list same reagent twice + var/list/items // Example: = list(/obj/item/weapon/tool/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo + var/list/fruit // Example: = list("fruit" = 3) + var/coating = null // Required coating on all items in the recipe. The default value of null explitly requires no coating + // A value of -1 is permissive and cares not for any coatings + // Any typepath indicates a specific coating that should be present + // Coatings are used for batter, breadcrumbs, beer-batter, colonel's secret coating, etc + + var/result // Example: = /obj/item/weapon/reagent_containers/food/snacks/donut/normal + var/result_quantity = 1 // Number of instances of result that are created. + var/time = 100 // 1/10 part of second + + #define RECIPE_REAGENT_REPLACE 0 //Reagents in the ingredients are discarded. + //Only the reagents present in the result at compiletime are used + #define RECIPE_REAGENT_MAX 1 //The result will contain the maximum of each reagent present between the two pools. Compiletime result, and sum of ingredients + #define RECIPE_REAGENT_MIN 2 //As above, but the minimum, ignoring zero values. + #define RECIPE_REAGENT_SUM 3 //The entire quantity of the ingredients are added to the result + + var/reagent_mix = RECIPE_REAGENT_MAX //How to handle reagent differences between the ingredients and the results + + var/appliance = MICROWAVE // Which apppliances this recipe can be made in. New Recipes will DEFAULT to using the Microwave, as a catch-all (and just in case) + // List of defines is in _defines/misc.dm. But for reference they are: + /* + MICROWAVE + FRYER + OVEN + CANDYMAKER + CEREALMAKER + */ + // This is a bitfield, more than one type can be used + // Grill is presently unused and not listed + +/datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents, var/exact = FALSE) + if(!reagents || !reagents.len) + return TRUE + + if(!avail_reagents) + return FALSE + + . = TRUE + for(var/r_r in reagents) + var/aval_r_amnt = avail_reagents.get_reagent_amount(r_r) + if(aval_r_amnt - reagents[r_r] >= 0) + if(aval_r_amnt>(reagents[r_r]) && exact) + . = FALSE + else + return FALSE + + if((reagents?(reagents.len):(0)) < avail_reagents.reagent_list.len) + return FALSE + return . + +/datum/recipe/proc/check_fruit(var/obj/container, var/exact = FALSE) + if (!fruit || !fruit.len) + return TRUE + + . = TRUE + if(fruit && fruit.len) + var/list/checklist = list() + // You should trust Copy(). + checklist = fruit.Copy() + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in container) + if(!G.seed || !G.seed.kitchen_tag || isnull(checklist[G.seed.kitchen_tag])) + continue + if(check_coating(G)) + checklist[G.seed.kitchen_tag]-- + for(var/ktag in checklist) + if(!isnull(checklist[ktag])) + if(checklist[ktag] < 0 && exact) + . = FALSE + else if(checklist[ktag] > 0) + . = FALSE + break + return . + +/datum/recipe/proc/check_items(var/obj/container as obj, var/exact = FALSE) + if(!items || !items.len) + return TRUE + + . = TRUE + if(items && items.len) + var/list/checklist = list() + checklist = items.Copy() // You should really trust Copy + if(istype(container, /obj/machinery)) + var/obj/machinery/machine = container + for(var/obj/O in ((machine.contents - machine.component_parts) - machine.circuit)) + if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown)) + continue // Fruit is handled in check_fruit(). + var/found = FALSE + for(var/i = 1; i < checklist.len+1; i++) + var/item_type = checklist[i] + if (istype(O,item_type)) + checklist.Cut(i, i+1) + found = TRUE + break + if(!found && exact) + return FALSE + else + for(var/obj/O in container.contents) + if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown)) + continue // Fruit is handled in check_fruit(). + var/found = FALSE + for(var/i = 1; i < checklist.len+1; i++) + var/item_type = checklist[i] + if (istype(O,item_type)) + if(check_coating(O)) + checklist.Cut(i, i+1) + found = TRUE + break + if (!found && exact) + return FALSE + if(checklist.len) + return FALSE + return . + +//This is called on individual items within the container. +/datum/recipe/proc/check_coating(var/obj/O, var/exact = FALSE) + if(!istype(O,/obj/item/weapon/reagent_containers/food/snacks)) + return TRUE //Only snacks can be battered + + if (coating == -1) + return TRUE //-1 value doesnt care + + var/obj/item/weapon/reagent_containers/food/snacks/S = O + if (!S.coating) + if (!coating) + return TRUE + return FALSE + else if (S.coating.type == coating) + return TRUE + + return FALSE + +//general version +/datum/recipe/proc/make(var/obj/container as obj) + var/obj/result_obj = new result(container) + if(istype(container, /obj/machinery)) + var/obj/machinery/machine = container + for (var/obj/O in ((machine.contents-result_obj - machine.component_parts) - machine.circuit)) + O.reagents.trans_to_obj(result_obj, O.reagents.total_volume) + qdel(O) + else + for (var/obj/O in (container.contents-result_obj)) + O.reagents.trans_to_obj(result_obj, O.reagents.total_volume) + qdel(O) + container.reagents.clear_reagents() + return result_obj + +// food-related +// This proc is called under the assumption that the container has already been checked and found to contain the necessary ingredients +/datum/recipe/proc/make_food(var/obj/container as obj) + if(!result) + log_runtime(EXCEPTION("Recipe [type] is defined without a result, please bug report this.")) + return + + +//We will subtract all the ingredients from the container, and transfer their reagents into a holder +//We will not touch things which are not required for this recipe. They will be left behind for the caller +//to decide what to do. They may be used again to make another recipe or discarded, or merged into the results, +//thats no longer the concern of this proc + var/datum/reagents/buffer = new /datum/reagents(10000000000, null)// + + + //Find items we need + if (items && items.len) + for (var/i in items) + var/obj/item/I = locate(i) in container + if (I && I.reagents) + I.reagents.trans_to_holder(buffer,I.reagents.total_volume) + qdel(I) + + //Find fruits + if (fruit && fruit.len) + var/list/checklist = list() + checklist = fruit.Copy() + + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in container) + if(!G.seed || !G.seed.kitchen_tag || isnull(checklist[G.seed.kitchen_tag])) + continue + + if (checklist[G.seed.kitchen_tag] > 0) + //We found a thing we need + checklist[G.seed.kitchen_tag]-- + if (G && G.reagents) + G.reagents.trans_to_holder(buffer,G.reagents.total_volume) + qdel(G) + + //And lastly deduct necessary quantities of reagents + if (reagents && reagents.len) + for (var/r in reagents) + //Doesnt matter whether or not there's enough, we assume that check is done before + container.reagents.trans_type_to(buffer, r, reagents[r]) + + /* + Now we've removed all the ingredients that were used and we have the buffer containing the total of + all their reagents. + Next up we create the result, and then handle the merging of reagents depending on the mix setting + */ + var/tally = 0 + + /* + If we have multiple results, holder will be used as a buffer to hold reagents for the result objects. + If, as in the most common case, there is only a single result, then it will just be a reference to + the single-result's reagents + */ + var/datum/reagents/holder = new/datum/reagents(10000000000) + var/list/results = list() + while (tally < result_quantity) + var/obj/result_obj = new result(container) + results.Add(result_obj) + + if (!result_obj.reagents)//This shouldn't happen + //If the result somehow has no reagents defined, then create a new holder + result_obj.reagents = new /datum/reagents(buffer.total_volume*1.5, result_obj) + + if (result_quantity == 1) + qdel(holder) + holder = result_obj.reagents + else + result_obj.reagents.trans_to(holder, result_obj.reagents.total_volume) + tally++ + + + switch(reagent_mix) + if (RECIPE_REAGENT_REPLACE) + //We do no transferring + if (RECIPE_REAGENT_SUM) + //Sum is easy, just shove the entire buffer into the result + buffer.trans_to_holder(holder, buffer.total_volume) + if (RECIPE_REAGENT_MAX) + //We want the highest of each. + //Iterate through everything in buffer. If the target has less than the buffer, then top it up + for (var/datum/reagent/R in buffer.reagent_list) + var/rvol = holder.get_reagent_amount(R.id) + if (rvol < R.volume) + //Transfer the difference + buffer.trans_type_to(holder, R.id, R.volume-rvol) + + if (RECIPE_REAGENT_MIN) + //Min is slightly more complex. We want the result to have the lowest from each side + //But zero will not count. Where a side has zero its ignored and the side with a nonzero value is used + for (var/datum/reagent/R in buffer.reagent_list) + var/rvol = holder.get_reagent_amount(R.id) + if (rvol == 0) //If the target has zero of this reagent + buffer.trans_type_to(holder, R.id, R.volume) + //Then transfer all of ours + + else if (rvol > R.volume) + //if the target has more than ours + //Remove the difference + holder.remove_reagent(R.id, rvol-R.volume) + + + if (results.len > 1) + //If we're here, then holder is a buffer containing the total reagents for all the results. + //So now we redistribute it among them + var/total = holder.total_volume + for (var/i in results) + var/atom/a = i //optimisation + holder.trans_to(a, total / results.len) + + return results + +// When exact is false, extraneous ingredients are ignored +// When exact is true, extraneous ingredients will fail the recipe +// In both cases, the full complement of required inredients is still needed +/proc/select_recipe(var/list/datum/recipe/available_recipes, var/obj/obj as obj, var/exact) + var/list/datum/recipe/possible_recipes = list() + for (var/datum/recipe/recipe in available_recipes) + if(!recipe.check_reagents(obj.reagents, exact) || !recipe.check_items(obj, exact) || !recipe.check_fruit(obj, exact)) + continue + possible_recipes |= recipe + if (!possible_recipes.len) + return null + else if (possible_recipes.len == 1) + return possible_recipes[1] + else //okay, let's select the most complicated recipe + sortTim(possible_recipes, /proc/cmp_recipe_complexity_dsc) + return possible_recipes[1] + +// Both of these are just placeholders to allow special behavior for mob holders, but you can do other things in here later if you feel like it. +/datum/recipe/proc/before_cook(obj/container) // Called Before the Microwave starts delays and cooking stuff + + +/datum/recipe/proc/after_cook(obj/container) // Called When the Microwave is finished. + diff --git a/code/modules/food/recipe_dump.dm b/code/modules/food/recipe_dump.dm index d70fc09bfd7..45f4c3e4ae9 100644 --- a/code/modules/food/recipe_dump.dm +++ b/code/modules/food/recipe_dump.dm @@ -16,7 +16,7 @@ qdel(CR) //////////////////////// FOOD - var/list/food_recipes = typesof(/datum/recipe/microwave) - /datum/recipe/microwave + var/list/food_recipes = typesof(/datum/recipe) - /datum/recipe //Build a useful list for(var/Rp in food_recipes) //Lists don't work with datum-stealing no-instance initial() so we have to. @@ -32,6 +32,7 @@ "Reagents" = R.reagents, "Fruit" = R.fruit, "Ingredients" = R.items, + "Appliance" = R.appliance, "Image" = result_icon ) @@ -69,6 +70,9 @@ for(var/Rp in food_recipes) for(var/rid in food_recipes[Rp]["Reagents"]) var/datum/reagent/Rd = SSchemistry.chemical_reagents[rid] + if(!Rd) // Leaving this here in the event that if rd is ever invalid or there's a recipe issue, it'll be skipped and recipe dumps can still be ran. + log_runtime(EXCEPTION("Food \"[Rp]\" had an invalid RID: \"[rid]\"! Check your reagents list for a missing or mistyped reagent!")) + continue // This allows the dump to still continue, and it will skip the invalid recipes. var/R_name = Rd.name var/amt = food_recipes[Rp]["Reagents"][rid] food_recipes[Rp]["Reagents"] -= rid @@ -76,17 +80,36 @@ for(var/Rp in drink_recipes) for(var/rid in drink_recipes[Rp]["Reagents"]) var/datum/reagent/Rd = SSchemistry.chemical_reagents[rid] + if(!Rd) // Leaving this here in the event that if rd is ever invalid or there's a recipe issue, it'll be skipped and recipe dumps can still be ran. + log_runtime(EXCEPTION("Food \"[Rp]\" had an invalid RID: \"[rid]\"! Check your reagents list for a missing or mistyped reagent!")) + continue // This allows the dump to still continue, and it will skip the invalid recipes. var/R_name = Rd.name var/amt = drink_recipes[Rp]["Reagents"][rid] drink_recipes[Rp]["Reagents"] -= rid drink_recipes[Rp]["Reagents"][R_name] = amt + + //We can also change the appliance to its proper name. + for(var/Rp in food_recipes) + switch(food_recipes[Rp]["Appliance"]) + if(1) + food_recipes[Rp]["Appliance"] = "Microwave" + if(2) + food_recipes[Rp]["Appliance"] = "Fryer" + if(4) + food_recipes[Rp]["Appliance"] = "Oven" + if(8) + food_recipes[Rp]["Appliance"] = "Grill" + if(16) + food_recipes[Rp]["Appliance"] = "Candy Maker" + if(32) + food_recipes[Rp]["Appliance"] = "Cereal Maker" //////////////////////// SORTING var/list/foods_to_paths = list() var/list/drinks_to_paths = list() - for(var/Rp in food_recipes) - foods_to_paths["[food_recipes[Rp]["Result"]] [Rp]"] = Rp //Append recipe datum path to keep uniqueness + for(var/Rp in food_recipes) // "Appliance" will sort the list by APPLIANCES first. Items without an appliance will append to the top of the list. The old method was "Result", which sorts the list by the name of the result. + foods_to_paths["[food_recipes[Rp]["Appliance"]] [Rp]"] = Rp //Append recipe datum path to keep uniqueness for(var/Rp in drink_recipes) drinks_to_paths["[drink_recipes[Rp]["Result"]] [Rp]"] = Rp @@ -119,7 +142,7 @@ html += "

Food Recipes (as of [time2text(world.realtime,"MMM DD, YYYY")])


" html += "" - html += "" + html += "" for(var/Rp in food_recipes) //Open this row html += "" @@ -135,6 +158,9 @@ //Name html += "" + + //Appliance + html += "" //Ingredients html += "" + else + . = "" \ No newline at end of file diff --git a/code/modules/persistence/datum/datum_paper.dm b/code/modules/persistence/datum/datum_paper.dm new file mode 100644 index 00000000000..e572faea013 --- /dev/null +++ b/code/modules/persistence/datum/datum_paper.dm @@ -0,0 +1,56 @@ +/datum/persistent/paper + name = "paper" + tokens_per_line = 7 + entries_expire_at = 50 + has_admin_data = TRUE + var/paper_type = /obj/item/weapon/paper + var/requires_noticeboard = TRUE + +/datum/persistent/paper/LabelTokens(var/list/tokens) + var/list/labelled_tokens = ..() + var/entries = LAZYLEN(labelled_tokens) + labelled_tokens["author"] = tokens[entries+1] + labelled_tokens["message"] = tokens[entries+2] + labelled_tokens["title"] = tokens[entries+3] + return labelled_tokens + +/datum/persistent/paper/CheckTurfContents(var/turf/T, var/list/tokens) + if(requires_noticeboard && !(locate(/obj/structure/noticeboard) in T)) + new /obj/structure/noticeboard(T) + . = ..() + +/datum/persistent/paper/CreateEntryInstance(var/turf/creating, var/list/tokens) + var/obj/structure/noticeboard/board = locate() in creating + if(requires_noticeboard && LAZYLEN(board.notices) >= board.max_notices) + return + var/obj/item/weapon/paper/paper = new paper_type(creating) + paper.set_content(tokens["message"], tokens["title"]) + paper.last_modified_ckey = tokens["author"] + if(requires_noticeboard) + board.add_paper(paper) + SSpersistence.track_value(paper, type) + return paper + +/datum/persistent/paper/GetEntryAge(var/atom/entry) + var/obj/item/weapon/paper/paper = entry + return paper.age + +/datum/persistent/paper/CompileEntry(var/atom/entry, var/write_file) + . = ..() + var/obj/item/weapon/paper/paper = entry + LAZYADD(., "[paper.last_modified_ckey ? paper.last_modified_ckey : "unknown"]") + LAZYADD(., "[paper.info]") + LAZYADD(., "[paper.name]") + +/datum/persistent/paper/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user) + var/obj/item/weapon/paper/paper = thing + if(can_modify) + . = "" + else + . = "" + +/datum/persistent/paper/RemoveValue(var/atom/value) + var/obj/structure/noticeboard/board = value.loc + if(istype(board)) + board.remove_paper(value) + qdel(value) \ No newline at end of file diff --git a/code/modules/persistence/datum/datum_paper_sticky.dm b/code/modules/persistence/datum/datum_paper_sticky.dm new file mode 100644 index 00000000000..1871eb4a037 --- /dev/null +++ b/code/modules/persistence/datum/datum_paper_sticky.dm @@ -0,0 +1,28 @@ +/datum/persistent/paper/sticky + name = "stickynotes" + paper_type = /obj/item/weapon/paper/sticky + requires_noticeboard = FALSE + tokens_per_line = 10 + +/datum/persistent/paper/sticky/LabelTokens(var/list/tokens) + var/list/labelled_tokens = ..() + var/entries = LAZYLEN(labelled_tokens) + labelled_tokens["offset_x"] = tokens[entries+1] + labelled_tokens["offset_y"] = tokens[entries+2] + labelled_tokens["color"] = tokens[entries+3] + return labelled_tokens + +/datum/persistent/paper/sticky/CreateEntryInstance(var/turf/creating, var/list/tokens) + var/atom/paper = ..() + if(paper) + paper.pixel_x = text2num(tokens["offset_x"]) + paper.pixel_y = text2num(tokens["offset_y"]) + paper.color = tokens["color"] + return paper + +/datum/persistent/paper/sticky/CompileEntry(var/atom/entry, var/write_file) + . = ..() + var/obj/item/weapon/paper/sticky/paper = entry + LAZYADD(., "[paper.pixel_x]") + LAZYADD(., "[paper.pixel_y]") + LAZYADD(., "[paper.color]") \ No newline at end of file diff --git a/code/modules/persistence/datum/datum_trash.dm b/code/modules/persistence/datum/datum_trash.dm new file mode 100644 index 00000000000..951e9858af8 --- /dev/null +++ b/code/modules/persistence/datum/datum_trash.dm @@ -0,0 +1,17 @@ +/datum/persistent/filth/trash + name = "trash" + +/datum/persistent/filth/trash/CheckTurfContents(var/turf/T, var/list/tokens) + var/too_much_trash = 0 + for(var/obj/item/trash/trash in T) + too_much_trash++ + if(too_much_trash >= 5) + return FALSE + return TRUE + +/datum/persistent/filth/trash/GetEntryAge(var/atom/entry) + var/obj/item/trash/trash = entry + return trash.age + +/datum/persistent/filth/trash/GetEntryPath(var/atom/entry) + return entry.type \ No newline at end of file diff --git a/code/modules/persistence/datum/persistence_datum.dm b/code/modules/persistence/datum/persistence_datum.dm new file mode 100644 index 00000000000..8a409404cd6 --- /dev/null +++ b/code/modules/persistence/datum/persistence_datum.dm @@ -0,0 +1,160 @@ +// This is a set of datums instantiated by SSpersistence. +// They basically just handle loading, processing and saving specific forms +// of persistent data like graffiti and round to round filth. + +/datum/persistent + var/name + var/filename + var/tokens_per_line + var/entries_expire_at + var/entries_decay_at + var/entry_decay_weight = 0.5 + var/file_entry_split_character = "\t" + var/file_entry_substitute_character = " " + var/file_line_split_character = "\n" + var/has_admin_data + +/datum/persistent/New() + SetFilename() + ..() + +/datum/persistent/proc/SetFilename() + if(name) + filename = "data/persistent/[lowertext(using_map.name)]-[lowertext(name)].txt" + if(!isnull(entries_decay_at) && !isnull(entries_expire_at)) + entries_decay_at = round(entries_expire_at * entries_decay_at) + +/datum/persistent/proc/LabelTokens(var/list/tokens) + var/list/labelled_tokens = list() + labelled_tokens["x"] = text2num(tokens[1]) + labelled_tokens["y"] = text2num(tokens[2]) + labelled_tokens["z"] = text2num(tokens[3]) + labelled_tokens["age"] = text2num(tokens[4]) + return labelled_tokens + +/datum/persistent/proc/GetValidTurf(var/turf/T, var/list/tokens) + if(T && CheckTurfContents(T, tokens)) + return T + +/datum/persistent/proc/CheckTurfContents(var/turf/T, var/list/tokens) + return TRUE + +/datum/persistent/proc/CheckTokenSanity(var/list/tokens) + return ( \ + !isnull(tokens["x"]) && \ + !isnull(tokens["y"]) && \ + !isnull(tokens["z"]) && \ + !isnull(tokens["age"]) && \ + tokens["age"] <= entries_expire_at \ + ) + +/datum/persistent/proc/CreateEntryInstance(var/turf/creating, var/list/tokens) + return + +/datum/persistent/proc/ProcessAndApplyTokens(var/list/tokens) + + // If it's old enough we start to trim down any textual information and scramble strings. + if(tokens["message"] && !isnull(entries_decay_at) && !isnull(entry_decay_weight)) + var/_n = tokens["age"] + var/_message = tokens["message"] + if(_n >= entries_decay_at) + var/decayed_message = "" + for(var/i = 1 to length(_message)) + var/char = copytext(_message, i, i + 1) + if(prob(round(_n * entry_decay_weight))) + if(prob(99)) + decayed_message += pick(".",",","-","'","\\","/","\"",":",";") + else + decayed_message += char + _message = decayed_message + if(length(_message)) + tokens["message"] = _message + else + return + + var/_z = tokens["z"] + if(_z in using_map.station_levels) + . = GetValidTurf(locate(tokens["x"], tokens["y"], _z), tokens) + if(.) + CreateEntryInstance(., tokens) + +/datum/persistent/proc/IsValidEntry(var/atom/entry) + if(!istype(entry)) + return FALSE + if(GetEntryAge(entry) >= entries_expire_at) + return FALSE + var/turf/T = get_turf(entry) + if(!T || !(T.z in using_map.station_levels) ) + return FALSE + var/area/A = get_area(T) + if(!A || (A.flags & AREA_FLAG_IS_NOT_PERSISTENT)) + return FALSE + return TRUE + +/datum/persistent/proc/GetEntryAge(var/atom/entry) + return 0 + +/datum/persistent/proc/CompileEntry(var/atom/entry) + var/turf/T = get_turf(entry) + . = list( + T.x, + T.y, + T.z, + GetEntryAge(entry) + ) + +/datum/persistent/proc/Initialize() + if(fexists(filename)) + for(var/entry_line in file2list(filename, file_line_split_character)) + if(!entry_line) + continue + var/list/tokens = splittext(entry_line, file_entry_split_character) + if(LAZYLEN(tokens) < tokens_per_line) + continue + tokens = LabelTokens(tokens) + if(!CheckTokenSanity(tokens)) + continue + ProcessAndApplyTokens(tokens) + +/datum/persistent/proc/Shutdown() + if(fexists(filename)) + fdel(filename) + var/write_file = file(filename) + for(var/thing in SSpersistence.tracking_values[type]) + if(IsValidEntry(thing)) + var/list/entry = CompileEntry(thing) + if(LAZYLEN(entry) == tokens_per_line) + for(var/i = 1 to LAZYLEN(entry)) + if(istext(entry[i])) + entry[i] = replacetext(entry[i], file_entry_split_character, file_entry_substitute_character) + to_file(write_file, jointext(entry, file_entry_split_character)) + +/datum/persistent/proc/RemoveValue(var/atom/value) + qdel(value) + +/datum/persistent/proc/GetAdminSummary(var/mob/user, var/can_modify) + . = list("") + . += "" + for(var/thing in SSpersistence.tracking_values[type]) + . += "[GetAdminDataStringFor(thing, can_modify, user)]" + . += "" + + +/datum/persistent/proc/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user) + if(can_modify) + . = "" + else + . = "" + +/datum/persistent/Topic(var/href, var/href_list) + . = ..() + if(!.) + if(href_list["remove_entry"]) + var/datum/value = locate(href_list["remove_entry"]) + if(istype(value)) + RemoveValue(value) + . = TRUE + if(.) + var/mob/user = locate(href_list["caller"]) + if(user) + SSpersistence.show_info(user) \ No newline at end of file diff --git a/code/modules/persistence/filth.dm b/code/modules/persistence/filth.dm new file mode 100644 index 00000000000..2eea824f83f --- /dev/null +++ b/code/modules/persistence/filth.dm @@ -0,0 +1,12 @@ +/obj/effect/decal/cleanable/filth + name = "filth" + desc = "Disgusting. Someone from last shift didn't do their job properly." + icon = 'icons/effects/blood.dmi' + icon_state = "mfloor1" + random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7") + color = "#464f33" + persistent = TRUE + +/obj/effect/decal/cleanable/filth/Initialize() + . = ..() + alpha = rand(180,220) \ No newline at end of file diff --git a/code/modules/persistence/graffiti.dm b/code/modules/persistence/graffiti.dm new file mode 100644 index 00000000000..ee1a1b7fce8 --- /dev/null +++ b/code/modules/persistence/graffiti.dm @@ -0,0 +1,64 @@ +/obj/effect/decal/writing + name = "hand graffiti" + icon_state = "writing1" + icon = 'icons/effects/writing.dmi' + desc = "It looks like someone has scratched something here." + plane = DIRTY_PLANE + gender = PLURAL + blend_mode = BLEND_MULTIPLY + color = "#000000" + alpha = 120 + + var/message + var/graffiti_age = 0 + var/author = "unknown" + +/obj/effect/decal/writing/New(var/newloc, var/_age, var/_message, var/_author) + ..(newloc) + if(!isnull(_age)) + graffiti_age = _age + message = _message + if(!isnull(author)) + author = _author + +/obj/effect/decal/writing/Initialize() + var/list/random_icon_states = icon_states(icon) + for(var/obj/effect/decal/writing/W in loc) + random_icon_states.Remove(W.icon_state) + if(random_icon_states.len) + icon_state = pick(random_icon_states) + SSpersistence.track_value(src, /datum/persistent/graffiti) + . = ..() + +/obj/effect/decal/writing/Destroy() + SSpersistence.forget_value(src, /datum/persistent/graffiti) + . = ..() + +/obj/effect/decal/writing/examine(mob/user) + . = ..() + to_chat(user, "It reads \"[message]\".") + +/obj/effect/decal/writing/attackby(var/obj/item/thing, var/mob/user) + if(istype(thing, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/welder = thing + if(welder.isOn() && welder.remove_fuel(0,user) && do_after(user, 5, src) && !QDELETED(src)) + playsound(src.loc, welder.usesound, 50, 1) + user.visible_message("\The [user] clears away some graffiti.") + qdel(src) + else if(thing.sharp) + + if(jobban_isbanned(user, "Graffiti")) + to_chat(user, SPAN_WARNING("You are banned from leaving persistent information across rounds.")) + return + + var/_message = sanitize(input("Enter an additional message to engrave.", "Graffiti") as null|text, trim = TRUE) + if(_message && loc && user && !user.incapacitated() && user.Adjacent(loc) && thing.loc == user) + user.visible_message("\The [user] begins carving something into \the [loc].") + if(do_after(user, max(20, length(_message)), src) && loc) + user.visible_message("\The [user] carves some graffiti into \the [loc].") + message = "[message] [_message]" + author = user.ckey + if(lowertext(message) == "elbereth") + to_chat(user, "You feel much safer.") + else + . = ..() diff --git a/code/modules/persistence/noticeboard.dm b/code/modules/persistence/noticeboard.dm new file mode 100644 index 00000000000..ad8cfef590b --- /dev/null +++ b/code/modules/persistence/noticeboard.dm @@ -0,0 +1,221 @@ +/obj/structure/noticeboard + name = "notice board" + desc = "A board for pinning important notices upon." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "nboard00" + density = 0 + anchored = 1 + var/list/notices + var/base_icon_state = "nboard0" + var/const/max_notices = 5 + +/obj/structure/noticeboard/Initialize() + . = ..() + + // Grab any mapped notices. + notices = list() + for(var/obj/item/weapon/paper/note in get_turf(src)) + note.forceMove(src) + LAZYADD(notices, note) + if(LAZYLEN(notices) >= max_notices) + break + + // Automatically place noticeboards that aren't mapped to specific positions. + if(pixel_x == 0 && pixel_y == 0) + + var/turf/here = get_turf(src) + var/placing = 0 + for(var/checkdir in GLOB.cardinal) + var/turf/T = get_step(here, checkdir) + if(T.density) + placing = checkdir + break + for(var/thing in T) + var/atom/A = thing + if(A.simulated && !A.CanPass(src, T)) + placing = checkdir + break + + switch(placing) + if(NORTH) + pixel_x = 0 + pixel_y = 32 + if(SOUTH) + pixel_x = 0 + pixel_y = -32 + if(EAST) + pixel_x = 32 + pixel_y = 0 + if(WEST) + pixel_x = -32 + pixel_y = 0 + + update_icon() + +/obj/structure/noticeboard/proc/add_paper(var/atom/movable/paper, var/skip_icon_update) + if(istype(paper)) + LAZYDISTINCTADD(notices, paper) + paper.forceMove(src) + if(!skip_icon_update) + update_icon() + +/obj/structure/noticeboard/proc/remove_paper(var/atom/movable/paper, var/skip_icon_update) + if(istype(paper) && paper.loc == src) + paper.dropInto(loc) + LAZYREMOVE(notices, paper) + SSpersistence.forget_value(paper, /datum/persistent/paper) + if(!skip_icon_update) + update_icon() + +/obj/structure/noticeboard/proc/dismantle() + for(var/thing in notices) + remove_paper(thing, skip_icon_update = TRUE) + new /obj/item/stack/material/wood(get_turf(src)) + qdel(src) + +/obj/structure/noticeboard/Destroy() + QDEL_NULL_LIST(notices) + . = ..() + +/obj/structure/noticeboard/ex_act(var/severity) + dismantle() + +/obj/structure/noticeboard/update_icon() + icon_state = "[base_icon_state][LAZYLEN(notices)]" + +/obj/structure/noticeboard/attackby(var/obj/item/weapon/thing, var/mob/user) + if(thing.is_screwdriver()) + var/choice = input("Which direction do you wish to place the noticeboard?", "Noticeboard Offset") as null|anything in list("North", "South", "East", "West") + if(choice && Adjacent(user) && thing.loc == user && !user.incapacitated()) + playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) + switch(choice) + if("North") + pixel_x = 0 + pixel_y = 32 + if("South") + pixel_x = 0 + pixel_y = -32 + if("East") + pixel_x = 32 + pixel_y = 0 + if("West") + pixel_x = -32 + pixel_y = 0 + return + else if(thing.is_wrench()) + visible_message(SPAN_WARNING("\The [user] begins dismantling \the [src].")) + playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) + if(do_after(user, 50, src)) + visible_message(SPAN_DANGER("\The [user] has dismantled \the [src]!")) + dismantle() + return + else if(istype(thing, /obj/item/weapon/paper) || istype(thing, /obj/item/weapon/photo)) + if(jobban_isbanned(user, "Graffiti")) + to_chat(user, SPAN_WARNING("You are banned from leaving persistent information across rounds.")) + else + if(LAZYLEN(notices) < max_notices && user.unEquip(thing, src)) + add_fingerprint(user) + add_paper(thing) + to_chat(user, SPAN_NOTICE("You pin \the [thing] to \the [src].")) + SSpersistence.track_value(thing, /datum/persistent/paper) + else + to_chat(user, SPAN_WARNING("You hesitate, certain \the [thing] will not be seen among the many others already attached to \the [src].")) + return + ..() + +/obj/structure/noticeboard/attack_ai(var/mob/user) + examine(user) + +/obj/structure/noticeboard/attack_hand(var/mob/user) + examine(user) + +/obj/structure/noticeboard/examine(var/mob/user) + . = ..() + if(.) + var/list/dat = list("
IconNameIngredients
IconNameApplianceIngredients
[food_recipes[Rp]["Result"]][food_recipes[Rp]["Appliance"]]
    " diff --git a/code/modules/food/recipes_fryer.dm b/code/modules/food/recipes_fryer.dm new file mode 100644 index 00000000000..a5a3fee6e7a --- /dev/null +++ b/code/modules/food/recipes_fryer.dm @@ -0,0 +1,179 @@ +/datum/recipe/fries + appliance = FRYER + items = list( + /obj/item/weapon/reagent_containers/food/snacks/rawsticks + ) + result = /obj/item/weapon/reagent_containers/food/snacks/fries + +/datum/recipe/cheesyfries + appliance = FRYER + items = list( + /obj/item/weapon/reagent_containers/food/snacks/fries, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/cheesyfries + +/datum/recipe/jpoppers + appliance = FRYER + fruit = list("chili" = 1) + coating = /datum/reagent/nutriment/coating/batter + result = /obj/item/weapon/reagent_containers/food/snacks/jalapeno_poppers + +/datum/recipe/risottoballs + appliance = FRYER + reagents = list("sodiumchloride" = 1, "blackpepper" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/risotto) + coating = /datum/reagent/nutriment/coating/batter + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/risottoballs + + +//Meaty Recipes +//==================== +/datum/recipe/cubancarp + appliance = FRYER + fruit = list("chili" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/carpmeat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/cubancarp + +/datum/recipe/batteredsausage + appliance = FRYER + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sausage + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sausage/battered + coating = /datum/reagent/nutriment/coating/batter + + +/datum/recipe/katsu + appliance = FRYER + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meat/chicken + ) + result = /obj/item/weapon/reagent_containers/food/snacks/chickenkatsu + coating = /datum/reagent/nutriment/coating/beerbatter + + +/datum/recipe/pizzacrunch_1 + appliance = FRYER + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/crunch + coating = /datum/reagent/nutriment/coating/batter + +//Alternate pizza crunch recipe for combination pizzas made in oven +/datum/recipe/pizzacrunch_2 + appliance = FRYER + items = list( + /obj/item/weapon/reagent_containers/food/snacks/variable/pizza + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/crunch + coating = /datum/reagent/nutriment/coating/batter + +/datum/recipe/friedmushroom + appliance = FRYER + fruit = list("plumphelmet" = 1) + coating = /datum/reagent/nutriment/coating/beerbatter + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/friedmushroom + + +//Sweet Recipes. +//================== +// All donuts were given reagents of 5 to equal old recipes and make for faster cook times. +/datum/recipe/jellydonut + appliance = FRYER + reagents = list("berryjuice" = 5, "sugar" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice + ) + result = /obj/item/weapon/reagent_containers/food/snacks/donut/jelly + result_quantity = 2 + +/datum/recipe/jellydonut/poisonberry + reagents = list("poisonberryjuice" = 5, "sugar" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough + ) + result = /obj/item/weapon/reagent_containers/food/snacks/donut/poisonberry + +/datum/recipe/jellydonut/slime // Subtypes of jellydonut, appliance inheritance applies. + reagents = list("slimejelly" = 5, "sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly + +/datum/recipe/jellydonut/cherry // Subtypes of jellydonut, appliance inheritance applies. + reagents = list("cherryjelly" = 5, "sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/donut/cherryjelly + +/datum/recipe/donut + appliance = FRYER + reagents = list("sugar" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice + ) + result = /obj/item/weapon/reagent_containers/food/snacks/donut/normal + result_quantity = 2 + +/datum/recipe/chaosdonut + appliance = FRYER + reagents = list("frostoil" = 10, "capsaicin" = 10, "sugar" = 10) + reagent_mix = RECIPE_REAGENT_REPLACE //This creates its own reagents + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice + ) + result = /obj/item/weapon/reagent_containers/food/snacks/donut/chaos + result_quantity = 2 + +/datum/recipe/funnelcake + appliance = FRYER + reagents = list("sugar" = 5, "batter" = 10) + result = /obj/item/weapon/reagent_containers/food/snacks/funnelcake + +/datum/recipe/pisanggoreng + appliance = FRYER + fruit = list("banana" = 2) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/pisanggoreng + coating = /datum/reagent/nutriment/coating/batter + +/datum/recipe/corn_dog + appliance = FRYER + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sausage + ) + fruit = list("corn" = 1) + coating = /datum/reagent/nutriment/coating/batter + result = /obj/item/weapon/reagent_containers/food/snacks/corn_dog + +/datum/recipe/sweet_and_sour + appliance = FRYER + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/cutlet + ) + reagents = list("soysauce" = 5, "batter" = 10) + result = /obj/item/weapon/reagent_containers/food/snacks/sweet_and_sour + +/datum/recipe/generalschicken + appliance = FRYER + reagents = list("capsaicin" = 2, "sugar" = 2, "batter" = 10) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/generalschicken + +/datum/recipe/chickenwings + appliance = FRYER + reagents = list("capsaicin" = 5, "batter" = 10) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat + ) + result = /obj/item/weapon/storage/box/wings //This is kinda like the donut box. diff --git a/code/modules/food/recipes_grill.dm b/code/modules/food/recipes_grill.dm new file mode 100644 index 00000000000..86c7998e905 --- /dev/null +++ b/code/modules/food/recipes_grill.dm @@ -0,0 +1,231 @@ +/datum/recipe/humanburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meat/human, + /obj/item/weapon/reagent_containers/food/snacks/bun + ) + result = /obj/item/weapon/reagent_containers/food/snacks/human/burger + +/datum/recipe/plainburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/reagent_containers/food/snacks/meat //do not place this recipe before /datum/recipe/humanburger + ) + result = /obj/item/weapon/reagent_containers/food/snacks/monkeyburger + +/datum/recipe/syntiburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh + ) + result = /obj/item/weapon/reagent_containers/food/snacks/monkeyburger + +/datum/recipe/brainburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/organ/internal/brain + ) + result = /obj/item/weapon/reagent_containers/food/snacks/brainburger + +/datum/recipe/roburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/robot_parts/head + ) + result = /obj/item/weapon/reagent_containers/food/snacks/roburger + +/datum/recipe/xenoburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/reagent_containers/food/snacks/xenomeat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/xenoburger + +/datum/recipe/fishburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/reagent_containers/food/snacks/carpmeat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/fishburger + +/datum/recipe/tofuburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/reagent_containers/food/snacks/tofu + ) + result = /obj/item/weapon/reagent_containers/food/snacks/tofuburger + +/datum/recipe/ghostburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/ectoplasm //where do you even find this stuff + ) + result = /obj/item/weapon/reagent_containers/food/snacks/ghostburger + +/datum/recipe/clownburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/clothing/mask/gas/clown_hat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/clownburger + +/datum/recipe/mimeburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/clothing/head/beret + ) + result = /obj/item/weapon/reagent_containers/food/snacks/mimeburger + +/datum/recipe/mouseburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/holder/mouse + ) + result = /obj/item/weapon/reagent_containers/food/snacks/mouseburger + +/datum/recipe/bunbun + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/reagent_containers/food/snacks/bun + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bunbun + +/datum/recipe/hotdog + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/reagent_containers/food/snacks/sausage + ) + result = /obj/item/weapon/reagent_containers/food/snacks/hotdog + +/datum/recipe/humankabob + appliance = GRILL + items = list( + /obj/item/stack/rods, + /obj/item/weapon/reagent_containers/food/snacks/meat/human, + /obj/item/weapon/reagent_containers/food/snacks/meat/human, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/human/kabob + +/datum/recipe/kabob //Do not put before humankabob + appliance = GRILL + items = list( + /obj/item/stack/rods, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/monkeykabob + +/datum/recipe/monkeykabob + appliance = GRILL + items = list( + /obj/item/stack/rods, + /obj/item/weapon/reagent_containers/food/snacks/meat/monkey, + /obj/item/weapon/reagent_containers/food/snacks/meat/monkey + ) + result = /obj/item/weapon/reagent_containers/food/snacks/monkeykabob + +/datum/recipe/syntikabob + appliance = GRILL + items = list( + /obj/item/stack/rods, + /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, + /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh + ) + result = /obj/item/weapon/reagent_containers/food/snacks/monkeykabob + +/datum/recipe/tofukabob + appliance = GRILL + items = list( + /obj/item/stack/rods, + /obj/item/weapon/reagent_containers/food/snacks/tofu, + /obj/item/weapon/reagent_containers/food/snacks/tofu, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/tofukabob + +/datum/recipe/fakespellburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/monkeyburger, + /obj/item/clothing/head/wizard/fake, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/spellburger + +/datum/recipe/spellburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/monkeyburger, + /obj/item/clothing/head/wizard, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/spellburger + +/datum/recipe/bigbiteburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/monkeyburger, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat, + ) + reagents = list("egg" = 3) + reagent_mix = RECIPE_REAGENT_REPLACE + result = /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger + +/datum/recipe/superbiteburger + appliance = GRILL + fruit = list("tomato" = 1) + reagents = list("sodiumchloride" = 5, "blackpepper" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/boiledegg, + ) + result = /obj/item/weapon/reagent_containers/food/snacks/superbiteburger + +/datum/recipe/slimeburger + appliance = GRILL + reagents = list("slimejelly" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun + ) + result = /obj/item/weapon/reagent_containers/food/snacks/jellyburger/slime + +/datum/recipe/jellyburger + appliance = GRILL + reagents = list("cherryjelly" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun + ) + result = /obj/item/weapon/reagent_containers/food/snacks/jellyburger/cherry + +/datum/recipe/bearburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/reagent_containers/food/snacks/bearmeat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bearburger + +/datum/recipe/baconburger + appliance = GRILL + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bun, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon + ) + result = /obj/item/weapon/reagent_containers/food/snacks/burger/bacon \ No newline at end of file diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index 0877869870f..22a61e0d37e 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -3,7 +3,7 @@ /* No telebacon. just no... -/datum/recipe/microwave/telebacon +/datum/recipe/telebacon items = list( /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/device/assembly/signaler @@ -11,7 +11,7 @@ result = /obj/item/weapon/reagent_containers/food/snacks/telebacon I said no! -/datum/recipe/microwave/syntitelebacon +/datum/recipe/syntitelebacon items = list( /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, /obj/item/device/assembly/signaler @@ -19,21 +19,22 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/telebacon */ -/datum/recipe/microwave/friedegg +/datum/recipe/friedegg reagents = list("sodiumchloride" = 1, "blackpepper" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/egg ) result = /obj/item/weapon/reagent_containers/food/snacks/friedegg -/datum/recipe/microwave/boiledegg +/datum/recipe/boiledegg reagents = list("water" = 5) + reagent_mix = RECIPE_REAGENT_REPLACE items = list( /obj/item/weapon/reagent_containers/food/snacks/egg ) result = /obj/item/weapon/reagent_containers/food/snacks/boiledegg -/datum/recipe/microwave/devilledegg +/datum/recipe/devilledegg fruit = list("chili" = 1) reagents = list("sodiumchloride" = 2, "mayo" = 5) items = list( @@ -42,132 +43,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/devilledegg -/datum/recipe/microwave/dionaroast - fruit = list("apple" = 1) - reagents = list("pacid" = 5) //It dissolves the carapace. Still poisonous, though. - items = list(/obj/item/weapon/holder/diona) - result = /obj/item/weapon/reagent_containers/food/snacks/dionaroast - -/datum/recipe/microwave/jellydonut - reagents = list("berryjuice" = 5, "sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough - ) - result = /obj/item/weapon/reagent_containers/food/snacks/donut/jelly - -/datum/recipe/microwave/jellydonut/poisonberry - reagents = list("poisonberryjuice" = 5, "sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough - ) - result = /obj/item/weapon/reagent_containers/food/snacks/donut/poisonberry - -/datum/recipe/microwave/jellydonut/slime - reagents = list("slimejelly" = 5, "sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough - ) - result = /obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly - -/datum/recipe/microwave/jellydonut/cherry - reagents = list("cherryjelly" = 5, "sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough - ) - result = /obj/item/weapon/reagent_containers/food/snacks/donut/cherryjelly - -/datum/recipe/microwave/donut - reagents = list("sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough - ) - result = /obj/item/weapon/reagent_containers/food/snacks/donut/normal - -/datum/recipe/microwave/humanburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat/human, - /obj/item/weapon/reagent_containers/food/snacks/bun - ) - result = /obj/item/weapon/reagent_containers/food/snacks/human/burger - -/datum/recipe/microwave/plainburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/weapon/reagent_containers/food/snacks/meat //do not place this recipe before /datum/recipe/microwave/humanburger - ) - result = /obj/item/weapon/reagent_containers/food/snacks/monkeyburger - -/datum/recipe/microwave/brainburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/organ/internal/brain - ) - result = /obj/item/weapon/reagent_containers/food/snacks/brainburger - -/datum/recipe/microwave/roburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/robot_parts/head - ) - result = /obj/item/weapon/reagent_containers/food/snacks/roburger - -/datum/recipe/microwave/xenoburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/weapon/reagent_containers/food/snacks/xenomeat - ) - result = /obj/item/weapon/reagent_containers/food/snacks/xenoburger - -/datum/recipe/microwave/fishburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/weapon/reagent_containers/food/snacks/carpmeat - ) - result = /obj/item/weapon/reagent_containers/food/snacks/fishburger - -/datum/recipe/microwave/tofuburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/weapon/reagent_containers/food/snacks/tofu - ) - result = /obj/item/weapon/reagent_containers/food/snacks/tofuburger - -/datum/recipe/microwave/ghostburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/weapon/ectoplasm //where do you even find this stuff - ) - result = /obj/item/weapon/reagent_containers/food/snacks/ghostburger - -/datum/recipe/microwave/clownburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/clothing/mask/gas/clown_hat - ) - result = /obj/item/weapon/reagent_containers/food/snacks/clownburger - -/datum/recipe/microwave/mimeburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/clothing/head/beret - ) - result = /obj/item/weapon/reagent_containers/food/snacks/mimeburger - -/datum/recipe/microwave/bunbun - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/weapon/reagent_containers/food/snacks/bun - ) - result = /obj/item/weapon/reagent_containers/food/snacks/bunbun - -/datum/recipe/microwave/hotdog - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/weapon/reagent_containers/food/snacks/sausage - ) - result = /obj/item/weapon/reagent_containers/food/snacks/hotdog - -/datum/recipe/microwave/waffles +/datum/recipe/waffles reagents = list("sugar" = 10) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, @@ -175,7 +51,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/waffles -/datum/recipe/microwave/donkpocket +/datum/recipe/donkpocket items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/meatball @@ -184,77 +60,36 @@ I said no! proc/warm_up(var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked) being_cooked.heat() make_food(var/obj/container as obj) - var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked = ..(container) - warm_up(being_cooked) - return being_cooked + . = ..(container) + for (var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/D in .) + if (!D.warm) + warm_up(D) -/datum/recipe/microwave/donkpocket/warm +/datum/recipe/donkpocket/warm reagents = list() //This is necessary since this is a child object of the above recipe and we don't want donk pockets to need flour items = list( /obj/item/weapon/reagent_containers/food/snacks/donkpocket ) result = /obj/item/weapon/reagent_containers/food/snacks/donkpocket //SPECIAL - make_food(var/obj/container as obj) - var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked = locate() in container - if(being_cooked && !being_cooked.warm) - warm_up(being_cooked) - return being_cooked -/datum/recipe/microwave/meatbread +/datum/recipe/omelette items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread - -/datum/recipe/microwave/xenomeatbread - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/xenomeat, - /obj/item/weapon/reagent_containers/food/snacks/xenomeat, - /obj/item/weapon/reagent_containers/food/snacks/xenomeat, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread - -/datum/recipe/microwave/bananabread - fruit = list("banana" = 1) - reagents = list("milk" = 5, "sugar" = 15) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread - -/datum/recipe/microwave/omelette - items = list( - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, ) + reagents = list("egg" = 6) + reagent_mix = RECIPE_REAGENT_REPLACE result = /obj/item/weapon/reagent_containers/food/snacks/omelette -/datum/recipe/microwave/muffin +/datum/recipe/muffin reagents = list("milk" = 5, "sugar" = 5) + reagent_mix = RECIPE_REAGENT_REPLACE items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, ) result = /obj/item/weapon/reagent_containers/food/snacks/muffin -/datum/recipe/microwave/eggplantparm +/datum/recipe/eggplantparm fruit = list("eggplant" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, @@ -262,218 +97,102 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/eggplantparm -/datum/recipe/microwave/soylenviridians +/datum/recipe/soylenviridians fruit = list("soybeans" = 1) reagents = list("flour" = 10) + reagent_mix = RECIPE_REAGENT_REPLACE result = /obj/item/weapon/reagent_containers/food/snacks/soylenviridians -/datum/recipe/microwave/soylentgreen +/datum/recipe/soylentgreen reagents = list("flour" = 10) + reagent_mix = RECIPE_REAGENT_REPLACE items = list( /obj/item/weapon/reagent_containers/food/snacks/meat/human, /obj/item/weapon/reagent_containers/food/snacks/meat/human ) result = /obj/item/weapon/reagent_containers/food/snacks/soylentgreen -/datum/recipe/microwave/meatpie - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/meat, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/meatpie - -/datum/recipe/microwave/tofupie - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/tofu, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/tofupie - -/datum/recipe/microwave/xemeatpie - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/xenomeat, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/xemeatpie - -/datum/recipe/microwave/pie - fruit = list("banana" = 1) - reagents = list("sugar" = 5) - items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) - result = /obj/item/weapon/reagent_containers/food/snacks/pie - -/datum/recipe/microwave/cherrypie - fruit = list("cherries" = 1) - reagents = list("sugar" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/cherrypie - -/datum/recipe/microwave/berryclafoutis +/datum/recipe/berryclafoutis fruit = list("berries" = 1) items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough ) result = /obj/item/weapon/reagent_containers/food/snacks/berryclafoutis/berry -/datum/recipe/microwave/poisonberryclafoutis +/datum/recipe/poisonberryclafoutis fruit = list("poisonberries" = 1) items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough ) result = /obj/item/weapon/reagent_containers/food/snacks/berryclafoutis/poison -/datum/recipe/microwave/wingfangchu +/datum/recipe/wingfangchu reagents = list("soysauce" = 5) items = list( - /obj/item/weapon/reagent_containers/food/snacks/xenomeat, + /obj/item/weapon/reagent_containers/food/snacks/xenomeat ) result = /obj/item/weapon/reagent_containers/food/snacks/wingfangchu -/datum/recipe/microwave/chaosdonut - reagents = list("frostoil" = 5, "capsaicin" = 5, "sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough - ) - result = /obj/item/weapon/reagent_containers/food/snacks/donut/chaos - -/datum/recipe/microwave/humankabob - items = list( - /obj/item/stack/rods, - /obj/item/weapon/reagent_containers/food/snacks/meat/human, - /obj/item/weapon/reagent_containers/food/snacks/meat/human, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/human/kabob - -/datum/recipe/microwave/kabob //Do not put before humankabob - items = list( - /obj/item/stack/rods, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/monkeykabob - -/datum/recipe/microwave/tofukabob - items = list( - /obj/item/stack/rods, - /obj/item/weapon/reagent_containers/food/snacks/tofu, - /obj/item/weapon/reagent_containers/food/snacks/tofu, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/tofukabob - -/datum/recipe/microwave/tofubread - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/tofu, - /obj/item/weapon/reagent_containers/food/snacks/tofu, - /obj/item/weapon/reagent_containers/food/snacks/tofu, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread - -/datum/recipe/microwave/loadedbakedpotato +/datum/recipe/loadedbakedpotato fruit = list("potato" = 1) items = list(/obj/item/weapon/reagent_containers/food/snacks/cheesewedge) result = /obj/item/weapon/reagent_containers/food/snacks/loadedbakedpotato + +/datum/recipe/microchips + appliance = MICROWAVE + items = list( + /obj/item/weapon/reagent_containers/food/snacks/rawsticks + ) + result = /obj/item/weapon/reagent_containers/food/snacks/microchips -/datum/recipe/microwave/mashedpotato +/datum/recipe/mashedpotato fruit = list("potato" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/mashedpotato -/datum/recipe/microwave/bangersandmash +/datum/recipe/bangersandmash items = list( /obj/item/weapon/reagent_containers/food/snacks/mashedpotato, /obj/item/weapon/reagent_containers/food/snacks/sausage, ) result = /obj/item/weapon/reagent_containers/food/snacks/bangersandmash -/datum/recipe/microwave/cheesymash +/datum/recipe/cheesymash items = list( /obj/item/weapon/reagent_containers/food/snacks/mashedpotato, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, ) result = /obj/item/weapon/reagent_containers/food/snacks/cheesymash -/datum/recipe/microwave/blackpudding +/datum/recipe/blackpudding reagents = list("blood" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/sausage, ) result = /obj/item/weapon/reagent_containers/food/snacks/blackpudding -/datum/recipe/microwave/cheesyfries - items = list( - /obj/item/weapon/reagent_containers/food/snacks/fries, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/cheesyfries - -/datum/recipe/microwave/cubancarp - fruit = list("chili" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/carpmeat - ) - result = /obj/item/weapon/reagent_containers/food/snacks/cubancarp - -/datum/recipe/microwave/popcorn +/datum/recipe/popcorn fruit = list("corn" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/popcorn -/datum/recipe/microwave/cookie - reagents = list("milk" = 5, "sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/chocolatebar, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/cookie - -/datum/recipe/microwave/fortunecookie +/datum/recipe/fortunecookie reagents = list("sugar" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/doughslice, /obj/item/weapon/paper, ) result = /obj/item/weapon/reagent_containers/food/snacks/fortunecookie - make_food(var/obj/container as obj) - var/obj/item/weapon/paper/paper = locate() in container - paper.loc = null //prevent deletion - var/obj/item/weapon/reagent_containers/food/snacks/fortunecookie/being_cooked = ..(container) - paper.loc = being_cooked - being_cooked.trash = paper //so the paper is left behind as trash without special-snowflake(TM Nodrak) code ~carn - return being_cooked - check_items(var/obj/container as obj) - . = ..() - if (.) - var/obj/item/weapon/paper/paper = locate() in container - if (!paper) - return 0 - if (!paper.info) - return 0 - return . -/datum/recipe/microwave/meatsteak +/datum/recipe/meatsteak reagents = list("sodiumchloride" = 1, "blackpepper" = 1) items = list(/obj/item/weapon/reagent_containers/food/snacks/meat) result = /obj/item/weapon/reagent_containers/food/snacks/meatsteak + +/datum/recipe/syntisteak + reagents = list("sodiumchloride" = 1, "blackpepper" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh) + result = /obj/item/weapon/reagent_containers/food/snacks/meatsteak -/datum/recipe/microwave/pizzamargherita - fruit = list("tomato" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita - -/datum/recipe/microwave/pizzahawaiian +/datum/recipe/pizzahawaiian fruit = list("tomato" = 1, "pineapple" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, @@ -482,160 +201,57 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pineapple -/datum/recipe/microwave/meatpizza - fruit = list("tomato" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza - -/datum/recipe/microwave/mushroompizza - fruit = list("mushroom" = 5, "tomato" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza - -/datum/recipe/microwave/vegetablepizza - fruit = list("eggplant" = 1, "carrot" = 1, "corn" = 1, "tomato" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza - -/datum/recipe/microwave/spacylibertyduff +/datum/recipe/spacylibertyduff reagents = list("water" = 5, "vodka" = 5, "psilocybin" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/spacylibertyduff -/datum/recipe/microwave/amanitajelly +/datum/recipe/amanitajelly reagents = list("water" = 5, "vodka" = 5, "amatoxin" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/amanitajelly - make_food(var/obj/container as obj) - var/obj/item/weapon/reagent_containers/food/snacks/amanitajelly/being_cooked = ..(container) + +/datum/recipe/amanitajelly/make_food(var/obj/container as obj) + . = ..(container) + for(var/obj/item/weapon/reagent_containers/food/snacks/amanitajelly/being_cooked in .) being_cooked.reagents.del_reagent("amatoxin") - return being_cooked -/datum/recipe/microwave/meatballsoup +/datum/recipe/meatballsoup fruit = list("carrot" = 1, "potato" = 1) reagents = list("water" = 10) items = list(/obj/item/weapon/reagent_containers/food/snacks/meatball) result = /obj/item/weapon/reagent_containers/food/snacks/meatballsoup -/datum/recipe/microwave/vegetablesoup +/datum/recipe/vegetablesoup fruit = list("carrot" = 1, "potato" = 1, "corn" = 1, "eggplant" = 1) reagents = list("water" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/vegetablesoup -/datum/recipe/microwave/nettlesoup +/datum/recipe/nettlesoup fruit = list("nettle" = 1, "potato" = 1) - reagents = list("water" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/egg - ) + reagents = list("water" = 10, "egg" = 3) result = /obj/item/weapon/reagent_containers/food/snacks/nettlesoup -/datum/recipe/microwave/wishsoup +/datum/recipe/wishsoup reagents = list("water" = 20) result= /obj/item/weapon/reagent_containers/food/snacks/wishsoup -/datum/recipe/microwave/hotchili +/datum/recipe/hotchili fruit = list("chili" = 1, "tomato" = 1) items = list(/obj/item/weapon/reagent_containers/food/snacks/meat) result = /obj/item/weapon/reagent_containers/food/snacks/hotchili -/datum/recipe/microwave/coldchili +/datum/recipe/coldchili fruit = list("icechili" = 1, "tomato" = 1) items = list(/obj/item/weapon/reagent_containers/food/snacks/meat) result = /obj/item/weapon/reagent_containers/food/snacks/coldchili -/datum/recipe/microwave/amanita_pie - reagents = list("amatoxin" = 5) - items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) - result = /obj/item/weapon/reagent_containers/food/snacks/amanita_pie - -/datum/recipe/microwave/plump_pie - fruit = list("plumphelmet" = 1) - items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) - result = /obj/item/weapon/reagent_containers/food/snacks/plump_pie - -/datum/recipe/microwave/spellburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/monkeyburger, - /obj/item/clothing/head/wizard/fake, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/spellburger - -/datum/recipe/microwave/spellburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/monkeyburger, - /obj/item/clothing/head/wizard, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/spellburger - -/datum/recipe/microwave/bigbiteburger - items = list( - /obj/item/weapon/reagent_containers/food/snacks/monkeyburger, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/egg, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger - -/datum/recipe/microwave/enchiladas - fruit = list("chili" = 2, "corn" = 1) - items = list(/obj/item/weapon/reagent_containers/food/snacks/cutlet) - result = /obj/item/weapon/reagent_containers/food/snacks/enchiladas - -/datum/recipe/microwave/creamcheesebread - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread - -/datum/recipe/microwave/monkeysdelight - fruit = list("banana" = 1) - reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "flour" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/monkeycube - ) - result = /obj/item/weapon/reagent_containers/food/snacks/monkeysdelight - -/datum/recipe/microwave/baguette - reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "yeast" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/baguette - -/datum/recipe/microwave/croissant - reagents = list("sodiumchloride" = 1, "water" = 5, "milk" = 5, "yeast" = 5) - items = list(/obj/item/weapon/reagent_containers/food/snacks/dough) - result = /obj/item/weapon/reagent_containers/food/snacks/croissant - -/datum/recipe/microwave/fishandchips +/datum/recipe/fishandchips items = list( /obj/item/weapon/reagent_containers/food/snacks/fries, /obj/item/weapon/reagent_containers/food/snacks/carpmeat, ) result = /obj/item/weapon/reagent_containers/food/snacks/fishandchips -/datum/recipe/microwave/bread - reagents = list("yeast" = 5) - items = list(/obj/item/weapon/reagent_containers/food/snacks/dough) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread - -/datum/recipe/microwave/sandwich +/datum/recipe/sandwich items = list( /obj/item/weapon/reagent_containers/food/snacks/meatsteak, /obj/item/weapon/reagent_containers/food/snacks/slice/bread, @@ -644,13 +260,13 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/sandwich -/datum/recipe/microwave/toastedsandwich +/datum/recipe/toastedsandwich items = list( /obj/item/weapon/reagent_containers/food/snacks/sandwich ) result = /obj/item/weapon/reagent_containers/food/snacks/toastedsandwich -/datum/recipe/microwave/peanutbutterjellysandwich +/datum/recipe/peanutbutterjellysandwich reagents = list("cherryjelly" = 5, "peanutbutter" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/slice/bread, @@ -658,7 +274,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/peanutbutter -/datum/recipe/microwave/grilledcheese +/datum/recipe/grilledcheese items = list( /obj/item/weapon/reagent_containers/food/snacks/slice/bread, /obj/item/weapon/reagent_containers/food/snacks/slice/bread, @@ -666,12 +282,12 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/grilledcheese -/datum/recipe/microwave/tomatosoup +/datum/recipe/tomatosoup fruit = list("tomato" = 2) reagents = list("water" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/tomatosoup -/datum/recipe/microwave/rofflewaffles +/datum/recipe/rofflewaffles reagents = list("psilocybin" = 5, "sugar" = 10) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, @@ -679,27 +295,27 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/rofflewaffles -/datum/recipe/microwave/stew +/datum/recipe/stew fruit = list("potato" = 1, "tomato" = 1, "carrot" = 1, "eggplant" = 1, "mushroom" = 1) reagents = list("water" = 10) items = list(/obj/item/weapon/reagent_containers/food/snacks/meat) result = /obj/item/weapon/reagent_containers/food/snacks/stew -/datum/recipe/microwave/slimetoast +/datum/recipe/slimetoast reagents = list("slimejelly" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/slice/bread, ) result = /obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/slime -/datum/recipe/microwave/jelliedtoast +/datum/recipe/jelliedtoast reagents = list("cherryjelly" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/slice/bread, ) result = /obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/cherry -/datum/recipe/microwave/milosoup +/datum/recipe/milosoup reagents = list("water" = 10) items = list( /obj/item/weapon/reagent_containers/food/snacks/soydope, @@ -709,7 +325,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/milosoup -/datum/recipe/microwave/stewedsoymeat +/datum/recipe/stewedsoymeat fruit = list("carrot" = 1, "tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/soydope, @@ -717,39 +333,28 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat -/*/datum/recipe/microwave/spagetti We have the processor now - items = list( - /obj/item/weapon/reagent_containers/food/snacks/doughslice - ) - result= /obj/item/weapon/reagent_containers/food/snacks/spagetti*/ - -/datum/recipe/microwave/boiledspagetti +/datum/recipe/boiledspagetti reagents = list("water" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/spagetti, ) result = /obj/item/weapon/reagent_containers/food/snacks/boiledspagetti -/datum/recipe/microwave/boiledrice +/datum/recipe/boiledrice reagents = list("water" = 5, "rice" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/boiledrice -/datum/recipe/microwave/ricepudding +/datum/recipe/ricepudding reagents = list("milk" = 5, "rice" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/ricepudding -/datum/recipe/microwave/pastatomato +/datum/recipe/pastatomato fruit = list("tomato" = 2) reagents = list("water" = 5) items = list(/obj/item/weapon/reagent_containers/food/snacks/spagetti) result = /obj/item/weapon/reagent_containers/food/snacks/pastatomato -/datum/recipe/microwave/poppypretzel - fruit = list("poppy" = 1) - items = list(/obj/item/weapon/reagent_containers/food/snacks/dough) - result = /obj/item/weapon/reagent_containers/food/snacks/poppypretzel - -/datum/recipe/microwave/meatballspagetti +/datum/recipe/meatballspagetti reagents = list("water" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/spagetti, @@ -758,7 +363,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/meatballspagetti -/datum/recipe/microwave/spesslaw +/datum/recipe/spesslaw reagents = list("water" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/spagetti, @@ -769,43 +374,17 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/spesslaw -/datum/recipe/microwave/superbiteburger - fruit = list("tomato" = 1) - reagents = list("sodiumchloride" = 5, "blackpepper" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/boiledegg, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/superbiteburger - -/datum/recipe/microwave/candiedapple +/datum/recipe/candiedapple fruit = list("apple" = 1) reagents = list("water" = 5, "sugar" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/candiedapple -/datum/recipe/microwave/applepie +/datum/recipe/applepie fruit = list("apple" = 1) items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) result = /obj/item/weapon/reagent_containers/food/snacks/applepie -/datum/recipe/microwave/slimeburger - reagents = list("slimejelly" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun - ) - result = /obj/item/weapon/reagent_containers/food/snacks/jellyburger/slime - -/datum/recipe/microwave/jellyburger - reagents = list("cherryjelly" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/bun - ) - result = /obj/item/weapon/reagent_containers/food/snacks/jellyburger/cherry - -/datum/recipe/microwave/twobread +/datum/recipe/twobread reagents = list("wine" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/slice/bread, @@ -813,7 +392,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/twobread -/datum/recipe/microwave/slimesandwich +/datum/recipe/slimesandwich reagents = list("slimejelly" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/slice/bread, @@ -821,7 +400,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/slime -/datum/recipe/microwave/cherrysandwich +/datum/recipe/cherrysandwich reagents = list("cherryjelly" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/slice/bread, @@ -829,45 +408,46 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/cherry -/datum/recipe/microwave/bloodsoup +/datum/recipe/bloodsoup reagents = list("blood" = 30) result = /obj/item/weapon/reagent_containers/food/snacks/bloodsoup -/datum/recipe/microwave/slimesoup +/datum/recipe/slimesoup reagents = list("water" = 10, "slimejelly" = 5) items = list() result = /obj/item/weapon/reagent_containers/food/snacks/slimesoup -/datum/recipe/microwave/boiledslimeextract +/datum/recipe/boiledslimeextract reagents = list("water" = 5) items = list( /obj/item/slime_extract, ) result = /obj/item/weapon/reagent_containers/food/snacks/boiledslimecore -/datum/recipe/microwave/chocolateegg +/datum/recipe/chocolateegg items = list( /obj/item/weapon/reagent_containers/food/snacks/egg, /obj/item/weapon/reagent_containers/food/snacks/chocolatebar, ) result = /obj/item/weapon/reagent_containers/food/snacks/chocolateegg -/datum/recipe/microwave/sausage +/datum/recipe/sausage items = list( /obj/item/weapon/reagent_containers/food/snacks/meatball, /obj/item/weapon/reagent_containers/food/snacks/cutlet, ) result = /obj/item/weapon/reagent_containers/food/snacks/sausage + result_quantity = 2 -/datum/recipe/microwave/fishfingers - reagents = list("flour" = 10) +/datum/recipe/fishfingers + reagents = list("flour" = 10, "egg" = 3) items = list( - /obj/item/weapon/reagent_containers/food/snacks/egg, /obj/item/weapon/reagent_containers/food/snacks/carpmeat, ) result = /obj/item/weapon/reagent_containers/food/snacks/fishfingers + reagent_mix = RECIPE_REAGENT_REPLACE -/datum/recipe/microwave/zestfish +/datum/recipe/zestfish fruit = list("lemon" = 1) reagents = list("sodiumchloride" = 3) items = list( @@ -875,7 +455,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/zestfish -/datum/recipe/microwave/limezestfish +/datum/recipe/limezestfish fruit = list("lime" = 1) reagents = list("sodiumchloride" = 3) items = list( @@ -883,7 +463,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/zestfish -/datum/recipe/microwave/kudzudonburi +/datum/recipe/kudzudonburi fruit = list("kudzu" = 1) reagents = list("rice" = 10) items = list( @@ -891,32 +471,28 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/kudzudonburi -/datum/recipe/microwave/mysterysoup - reagents = list("water" = 10) +/datum/recipe/mysterysoup + reagents = list("water" = 10, "egg" = 3) items = list( /obj/item/weapon/reagent_containers/food/snacks/badrecipe, /obj/item/weapon/reagent_containers/food/snacks/tofu, - /obj/item/weapon/reagent_containers/food/snacks/egg, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, ) + reagent_mix = RECIPE_REAGENT_REPLACE result = /obj/item/weapon/reagent_containers/food/snacks/mysterysoup -/datum/recipe/microwave/pumpkinpie - fruit = list("pumpkin" = 1) - reagents = list("milk" = 5, "sugar" = 5, "egg" = 3, "flour" = 10) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie - -/datum/recipe/microwave/plumphelmetbiscuit +/datum/recipe/plumphelmetbiscuit fruit = list("plumphelmet" = 1) reagents = list("water" = 5, "flour" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit -/datum/recipe/microwave/mushroomsoup +/datum/recipe/mushroomsoup fruit = list("mushroom" = 1) reagents = list("water" = 5, "milk" = 5) + reagent_mix = RECIPE_REAGENT_REPLACE result = /obj/item/weapon/reagent_containers/food/snacks/mushroomsoup -/datum/recipe/microwave/chawanmushi +/datum/recipe/chawanmushi fruit = list("mushroom" = 1) reagents = list("water" = 5, "soysauce" = 5) items = list( @@ -925,85 +501,85 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/chawanmushi -/datum/recipe/microwave/beetsoup +/datum/recipe/beetsoup fruit = list("whitebeet" = 1, "cabbage" = 1) reagents = list("water" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/beetsoup -/datum/recipe/microwave/appletart - fruit = list("goldapple" = 1) - reagents = list("sugar" = 5, "milk" = 5, "flour" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/egg - ) - result = /obj/item/weapon/reagent_containers/food/snacks/appletart - -/datum/recipe/microwave/tossedsalad +/datum/recipe/tossedsalad fruit = list("cabbage" = 2, "tomato" = 1, "carrot" = 1, "apple" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/tossedsalad -/datum/recipe/microwave/flowersalad +/datum/recipe/flowersalad fruit = list("harebell" = 1, "poppy" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/roastedsunflower ) result = /obj/item/weapon/reagent_containers/food/snacks/flowerchildsalad -/datum/recipe/microwave/rosesalad +/datum/recipe/rosesalad fruit = list("harebell" = 1, "rose" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/roastedsunflower ) result = /obj/item/weapon/reagent_containers/food/snacks/rosesalad -/datum/recipe/microwave/aesirsalad +/datum/recipe/aesirsalad fruit = list("goldapple" = 1, "ambrosiadeus" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/aesirsalad -/datum/recipe/microwave/validsalad +/datum/recipe/validsalad fruit = list("potato" = 1, "ambrosia" = 3) items = list(/obj/item/weapon/reagent_containers/food/snacks/meatball) result = /obj/item/weapon/reagent_containers/food/snacks/validsalad - make_food(var/obj/container as obj) - var/obj/item/weapon/reagent_containers/food/snacks/validsalad/being_cooked = ..(container) + +/datum/recipe/validsalad/make_food(var/obj/container as obj) + . = ..(container) + for (var/obj/item/weapon/reagent_containers/food/snacks/validsalad/being_cooked in .) being_cooked.reagents.del_reagent("toxin") - return being_cooked -/datum/recipe/microwave/cracker - reagents = list("sodiumchloride" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/doughslice - ) - result = /obj/item/weapon/reagent_containers/food/snacks/cracker - -/datum/recipe/microwave/stuffing +/datum/recipe/stuffing reagents = list("water" = 5, "sodiumchloride" = 1, "blackpepper" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread, ) result = /obj/item/weapon/reagent_containers/food/snacks/stuffing -/datum/recipe/microwave/tofurkey +/datum/recipe/tofurkey items = list( /obj/item/weapon/reagent_containers/food/snacks/tofu, /obj/item/weapon/reagent_containers/food/snacks/tofu, /obj/item/weapon/reagent_containers/food/snacks/stuffing, ) result = /obj/item/weapon/reagent_containers/food/snacks/tofurkey + +/datum/recipe/mashedpotato + items = list( + /obj/item/weapon/reagent_containers/food/snacks/spreads/butter // to prevent conflicts with yellow curry + ) + fruit = list("potato" = 1) + result = /obj/item/weapon/reagent_containers/food/snacks/mashedpotato + +/datum/recipe/icecreamsandwich + reagents = list("milk" = 5, "ice" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/icecream + ) + result = /obj/item/weapon/reagent_containers/food/snacks/icecreamsandwich // Fuck Science! -/datum/recipe/microwave/ruinedvirusdish +/datum/recipe/ruinedvirusdish items = list( /obj/item/weapon/virusdish ) result = /obj/item/weapon/ruinedvirusdish -/datum/recipe/microwave/onionrings +/datum/recipe/onionrings fruit = list("onion" = 1) reagents = list("flour" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/onionrings -/datum/recipe/microwave/onionsoup +/datum/recipe/onionsoup fruit = list("onion" = 1) reagents = list("water" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/onionsoup @@ -1012,7 +588,7 @@ I said no! // bs12 food port stuff ////////////////////////////////////////// -/datum/recipe/microwave/taco +/datum/recipe/taco items = list( /obj/item/weapon/reagent_containers/food/snacks/doughslice, /obj/item/weapon/reagent_containers/food/snacks/cutlet, @@ -1020,56 +596,50 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/taco -/datum/recipe/microwave/bun +/datum/recipe/microwavebun items = list( /obj/item/weapon/reagent_containers/food/snacks/dough ) result = /obj/item/weapon/reagent_containers/food/snacks/bun -/datum/recipe/microwave/flatbread +/datum/recipe/microwaveflatbread items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough ) result = /obj/item/weapon/reagent_containers/food/snacks/flatbread -/datum/recipe/microwave/meatball +/datum/recipe/meatball items = list( /obj/item/weapon/reagent_containers/food/snacks/rawmeatball ) result = /obj/item/weapon/reagent_containers/food/snacks/meatball -/datum/recipe/microwave/cutlet +/datum/recipe/cutlet items = list( /obj/item/weapon/reagent_containers/food/snacks/rawcutlet ) result = /obj/item/weapon/reagent_containers/food/snacks/cutlet -/datum/recipe/microwave/fries - items = list( - /obj/item/weapon/reagent_containers/food/snacks/rawsticks - ) - result = /obj/item/weapon/reagent_containers/food/snacks/fries - -/datum/recipe/microwave/roastedsunflowerseeds +/datum/recipe/roastedsunflowerseeds reagents = list("sodiumchloride" = 1, "cornoil" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/rawsunflower ) result = /obj/item/weapon/reagent_containers/food/snacks/roastedsunflower -/datum/recipe/microwave/roastedpeanutsunflowerseeds +/datum/recipe/roastedpeanutsunflowerseeds reagents = list("sodiumchloride" = 1, "peanutoil" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/rawsunflower ) result = /obj/item/weapon/reagent_containers/food/snacks/roastedsunflower -/datum/recipe/microwave/roastedpeanuts +/datum/recipe/roastedpeanuts fruit = list("peanut" = 2) reagents = list("sodiumchloride" = 2, "cornoil" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/roastedpeanuts -/datum/recipe/microwave/mint +/datum/recipe/mint reagents = list("sugar" = 5, "frostoil" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/mint @@ -1077,7 +647,7 @@ I said no! // TGstation food ports //////////////////////// -/datum/recipe/microwave/meatbun +/datum/recipe/meatbun fruit = list("cabbage" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/meatball, @@ -1085,14 +655,14 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/meatbun -/datum/recipe/microwave/sashimi +/datum/recipe/sashimi reagents = list("soysauce" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/carpmeat ) result = /obj/item/weapon/reagent_containers/food/snacks/sashimi -/datum/recipe/microwave/benedict +/datum/recipe/benedict items = list( /obj/item/weapon/reagent_containers/food/snacks/cutlet, /obj/item/weapon/reagent_containers/food/snacks/friedegg, @@ -1100,19 +670,19 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/benedict -/datum/recipe/microwave/bakedbeans +/datum/recipe/bakedbeans fruit = list("soybeans" = 2) reagents = list("ketchup" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/beans -/datum/recipe/microwave/sugarcookie +/datum/recipe/sugarcookie items = list( /obj/item/weapon/reagent_containers/food/snacks/dough ) reagents = list("sugar" = 5, "egg" = 3) result = /obj/item/weapon/reagent_containers/food/snacks/sugarcookie -/datum/recipe/microwave/berrymuffin +/datum/recipe/berrymuffin reagents = list("milk" = 5, "sugar" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough @@ -1120,7 +690,7 @@ I said no! fruit = list("berries" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/berrymuffin/berry -/datum/recipe/microwave/poisonberrymuffin +/datum/recipe/poisonberrymuffin reagents = list("milk" = 5, "sugar" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough @@ -1128,7 +698,7 @@ I said no! fruit = list("poisonberries" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/berrymuffin/poison -/datum/recipe/microwave/ghostmuffin +/datum/recipe/ghostmuffin reagents = list("milk" = 5, "sugar" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, @@ -1137,7 +707,7 @@ I said no! fruit = list("berries" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/berry -/datum/recipe/microwave/poisonghostmuffin +/datum/recipe/poisonghostmuffin reagents = list("milk" = 5, "sugar" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, @@ -1146,7 +716,7 @@ I said no! fruit = list("poisonberries" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/ghostmuffin/poison -/datum/recipe/microwave/eggroll +/datum/recipe/eggroll reagents = list("soysauce" = 10) items = list( /obj/item/weapon/reagent_containers/food/snacks/friedegg @@ -1154,28 +724,29 @@ I said no! fruit = list("cabbage" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/eggroll -/datum/recipe/microwave/fruitsalad +/datum/recipe/fruitsalad fruit = list("orange" = 1, "apple" = 1, "grapes" = 1, "watermelon" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/fruitsalad -/datum/recipe/microwave/eggbowl +/datum/recipe/eggbowl reagents = list("water" = 5, "rice" = 10, "egg" = 3) result = /obj/item/weapon/reagent_containers/food/snacks/eggbowl -/datum/recipe/microwave/porkbowl +/datum/recipe/porkbowl reagents = list("water" = 5, "rice" = 10) items = list( /obj/item/weapon/reagent_containers/food/snacks/cutlet ) result = /obj/item/weapon/reagent_containers/food/snacks/porkbowl -/datum/recipe/microwave/tortilla +/datum/recipe/microwavetortilla + reagents = list("flour" = 5, "water" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough ) result = /obj/item/weapon/reagent_containers/food/snacks/tortilla -/datum/recipe/microwave/meatburrito +/datum/recipe/meatburrito fruit = list("soybeans" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/tortilla, @@ -1184,7 +755,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/meatburrito -/datum/recipe/microwave/cheeseburrito +/datum/recipe/cheeseburrito fruit = list("soybeans" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/tortilla, @@ -1193,21 +764,21 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/cheeseburrito -/datum/recipe/microwave/fuegoburrito +/datum/recipe/fuegoburrito fruit = list("soybeans" = 1, "chili" = 2) items = list( /obj/item/weapon/reagent_containers/food/snacks/tortilla ) result = /obj/item/weapon/reagent_containers/food/snacks/fuegoburrito -/datum/recipe/microwave/nachos +/datum/recipe/nachos reagents = list("sodiumchloride" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/tortilla ) result = /obj/item/weapon/reagent_containers/food/snacks/nachos -/datum/recipe/microwave/cheesenachos +/datum/recipe/cheesenachos reagents = list("sodiumchloride" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/tortilla, @@ -1215,7 +786,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/cheesenachos -/datum/recipe/microwave/cubannachos +/datum/recipe/cubannachos fruit = list("chili" = 1) reagents = list("ketchup" = 5) items = list( @@ -1223,84 +794,26 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/cubannachos -/datum/recipe/microwave/curryrice +/datum/recipe/curryrice fruit = list("chili" = 1) reagents = list("rice" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/curryrice -/datum/recipe/microwave/piginblanket +/datum/recipe/piginblanket items = list( /obj/item/weapon/reagent_containers/food/snacks/doughslice, /obj/item/weapon/reagent_containers/food/snacks/sausage ) result = /obj/item/weapon/reagent_containers/food/snacks/piginblanket -// Cakes. -/datum/recipe/microwave/cake - reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9, "vanilla" = 1) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake - -/datum/recipe/microwave/cake/carrot - fruit = list("carrot" = 1) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9,"sugar" = 5) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake - -/datum/recipe/microwave/cake/cheese - reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake - -/datum/recipe/microwave/cake/peanut - fruit = list("peanut" = 3) - reagents = list("milk" = 5, "flour" = 10, "sugar" = 5, "egg" = 6, "peanutbutter" = 5) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/peanutcake - -/datum/recipe/microwave/cake/orange - fruit = list("orange" = 1) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9,"sugar" = 5) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake - -/datum/recipe/microwave/cake/lime - fruit = list("lime" = 1) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9,"sugar" = 5) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake - -/datum/recipe/microwave/cake/lemon - fruit = list("lemon" = 1) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9,"sugar" = 5) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake - -/datum/recipe/microwave/cake/chocolate - items = list(/obj/item/weapon/reagent_containers/food/snacks/chocolatebar) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9,"sugar" = 5) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake - -/datum/recipe/microwave/cake/birthday - reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9) - items = list(/obj/item/clothing/head/cakehat) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake - -/datum/recipe/microwave/cake/apple - fruit = list("apple" = 1) - reagents = list("milk" = 5, "flour" = 15, "egg" = 9,"sugar" = 5) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake - -/datum/recipe/microwave/cake/brain - reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9) - items = list(/obj/item/organ/internal/brain) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake - -/datum/recipe/microwave/bagelplain +/datum/recipe/bagelplain reagents = list("water" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/bun ) result = /obj/item/weapon/reagent_containers/food/snacks/bagelplain -/datum/recipe/microwave/bagelsunflower +/datum/recipe/bagelsunflower reagents = list("water" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/bun, @@ -1308,7 +821,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/bagelsunflower -/datum/recipe/microwave/bagelcheese +/datum/recipe/bagelcheese reagents = list("water" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/bun, @@ -1316,7 +829,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/bagelcheese -/datum/recipe/microwave/bagelraisin +/datum/recipe/bagelraisin reagents = list("water" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/bun, @@ -1324,7 +837,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/bagelraisin -/datum/recipe/microwave/bagelpoppy +/datum/recipe/bagelpoppy fruit = list("poppy" = 1) reagents = list("water" = 5) items = list( @@ -1332,7 +845,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/bagelpoppy -/datum/recipe/microwave/bageleverything +/datum/recipe/bageleverything reagents = list("water" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/bun, @@ -1340,10 +853,542 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/bageleverything -/datum/recipe/microwave/bageltwo +/datum/recipe/bageltwo reagents = list("water" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/bun, /obj/item/device/soulstone ) result = /obj/item/weapon/reagent_containers/food/snacks/bageltwo + +///////////////////////////////////////////////////////////// +//Synnono Meme Foods +// +//Most recipes replace reagents with RECIPE_REAGENT_REPLACE +//to simplify the end product and balance the amount of reagents +//in some foods. Many require the space spice reagent/condiment +//to reduce the risk of future recipe conflicts. +///////////////////////////////////////////////////////////// + + +/datum/recipe/redcurry + reagents = list("cream" = 5, "spacespice" = 2, "rice" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/cutlet, + /obj/item/weapon/reagent_containers/food/snacks/cutlet + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/redcurry + +/datum/recipe/greencurry + reagents = list("cream" = 5, "spacespice" = 2, "rice" = 5) + fruit = list("chili" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/tofu, + /obj/item/weapon/reagent_containers/food/snacks/tofu + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/greencurry + +/datum/recipe/yellowcurry + reagents = list("cream" = 5, "spacespice" = 2, "rice" = 5) + fruit = list("peanut" = 2, "potato" = 1) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/yellowcurry + +/datum/recipe/bearchili + fruit = list("chili" = 1, "tomato" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/bearmeat) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/bearchili + +/datum/recipe/bearstew + fruit = list("potato" = 1, "tomato" = 1, "carrot" = 1, "eggplant" = 1, "mushroom" = 1) + reagents = list("water" = 10) + items = list(/obj/item/weapon/reagent_containers/food/snacks/bearmeat) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/bearstew + +/datum/recipe/bibimbap + fruit = list("carrot" = 1, "cabbage" = 1, "mushroom" = 1) + reagents = list("rice" = 5, "spacespice" = 2) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/egg, + /obj/item/weapon/reagent_containers/food/snacks/cutlet + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/bibimbap + +/datum/recipe/friedrice + reagents = list("water" = 5, "rice" = 10, "soysauce" = 5) + fruit = list("carrot" = 1, "cabbage" = 1) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/friedrice + +/datum/recipe/lomein + reagents = list("water" = 5, "soysauce" = 5) + fruit = list("carrot" = 1, "cabbage" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/spagetti + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/lomein + +/datum/recipe/chickenfillet //Also just combinable, like burgers and hot dogs. + items = list( + /obj/item/weapon/reagent_containers/food/snacks/chickenkatsu, + /obj/item/weapon/reagent_containers/food/snacks/bun + ) + result = /obj/item/weapon/reagent_containers/food/snacks/chickenfillet + +/datum/recipe/chilicheesefries + items = list( + /obj/item/weapon/reagent_containers/food/snacks/fries, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/hotchili + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/chilicheesefries + +/datum/recipe/meatbun + reagents = list("spacespice" = 1, "water" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/rawcutlet + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Water used up in cooking + result = /obj/item/weapon/reagent_containers/food/snacks/meatbun + +/datum/recipe/custardbun + reagents = list("spacespice" = 1, "water" = 5, "egg" = 3) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Water, egg used up in cooking + result = /obj/item/weapon/reagent_containers/food/snacks/custardbun + +/datum/recipe/chickenmomo + reagents = list("spacespice" = 2, "water" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/meat/chicken + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/chickenmomo + +/datum/recipe/veggiemomo + reagents = list("spacespice" = 2, "water" = 5) + fruit = list("carrot" = 1, "cabbage" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/doughslice + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Get that water outta here + result = /obj/item/weapon/reagent_containers/food/snacks/veggiemomo + +/datum/recipe/risotto + reagents = list("wine" = 5, "rice" = 10, "spacespice" = 1) + fruit = list("mushroom" = 1) + reagent_mix = RECIPE_REAGENT_REPLACE //Get that rice and wine outta here + result = /obj/item/weapon/reagent_containers/food/snacks/risotto + +/datum/recipe/poachedegg + reagents = list("spacespice" = 1, "sodiumchloride" = 1, "blackpepper" = 1, "water" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/egg + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Get that water outta here + result = /obj/item/weapon/reagent_containers/food/snacks/poachedegg + +/datum/recipe/honeytoast + reagents = list("honey" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/slice/bread + ) + reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product + result = /obj/item/weapon/reagent_containers/food/snacks/honeytoast + + +/datum/recipe/donerkebab + fruit = list("tomato" = 1, "cabbage" = 1) + reagents = list("sodiumchloride" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meatsteak, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough + ) + result = /obj/item/weapon/reagent_containers/food/snacks/donerkebab + + +/datum/recipe/sashimi + reagents = list("soysauce" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/carpmeat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sashimi + +/datum/recipe/nugget + reagents = list("flour" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meat/chicken + ) + reagent_mix = RECIPE_REAGENT_REPLACE + result = /obj/item/weapon/reagent_containers/food/snacks/nugget + +// Chip update +/datum/recipe/tortila + reagents = list("flour" = 5,"water" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/tortilla + reagent_mix = RECIPE_REAGENT_REPLACE //no gross flour or water + +/datum/recipe/taconew + items = list( + /obj/item/weapon/reagent_containers/food/snacks/tortilla, + /obj/item/weapon/reagent_containers/food/snacks/cutlet, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/taco + +/datum/recipe/chips + reagents = list("sodiumchloride" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/tortilla + ) + result = /obj/item/weapon/reagent_containers/food/snacks/chipplate + +/datum/recipe/nachos + items = list( + /obj/item/weapon/reagent_containers/food/snacks/chipplate, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/chipplate/nachos + +/datum/recipe/salsa + fruit = list("chili" = 1, "tomato" = 1, "lime" = 1) + reagents = list("spacespice" = 1, "blackpepper" = 1,"sodiumchloride" = 1) + result = /obj/item/weapon/reagent_containers/food/snacks/dip/salsa + reagent_mix = RECIPE_REAGENT_REPLACE //Ingredients are mixed together. + +/datum/recipe/guac + fruit = list("chili" = 1, "lime" = 1) + reagents = list("spacespice" = 1, "blackpepper" = 1,"sodiumchloride" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/tofu + ) + result = /obj/item/weapon/reagent_containers/food/snacks/dip/guac + reagent_mix = RECIPE_REAGENT_REPLACE //Ingredients are mixed together. + +/datum/recipe/cheesesauce + fruit = list("chili" = 1, "tomato" = 1) + reagents = list("spacespice" = 1, "blackpepper" = 1,"sodiumchloride" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/dip + reagent_mix = RECIPE_REAGENT_REPLACE //Ingredients are mixed together. + +/datum/recipe/burrito + items = list( + /obj/item/weapon/reagent_containers/food/snacks/tortilla, + /obj/item/weapon/reagent_containers/food/snacks/meatball, + /obj/item/weapon/reagent_containers/food/snacks/meatball + ) + reagents = list("spacespice" = 1) + result = /obj/item/weapon/reagent_containers/food/snacks/burrito + +/datum/recipe/burrito_vegan + items = list( + /obj/item/weapon/reagent_containers/food/snacks/tortilla, + /obj/item/weapon/reagent_containers/food/snacks/tofu + ) + result = /obj/item/weapon/reagent_containers/food/snacks/burrito_vegan + +/datum/recipe/burrito_spicy + fruit = list("chili" = 2) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/burrito + ) + result = /obj/item/weapon/reagent_containers/food/snacks/burrito_spicy + +/datum/recipe/burrito_cheese + items = list( + /obj/item/weapon/reagent_containers/food/snacks/burrito, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/burrito_cheese + +/datum/recipe/burrito_cheese_spicy + fruit = list("chili" = 2) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/burrito, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/burrito_cheese_spicy + +/datum/recipe/burrito_hell + fruit = list("chili" = 10) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/burrito_spicy + ) + result = /obj/item/weapon/reagent_containers/food/snacks/burrito_hell + reagent_mix = RECIPE_REAGENT_REPLACE //Already hot sauce + +/datum/recipe/breakfast_wrap + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/tortilla, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/egg + ) + result = /obj/item/weapon/reagent_containers/food/snacks/breakfast_wrap + +/datum/recipe/burrito_mystery + items = list( + /obj/item/weapon/reagent_containers/food/snacks/burrito, + /obj/item/weapon/reagent_containers/food/snacks/mysterysoup + ) + result = /obj/item/weapon/reagent_containers/food/snacks/burrito_mystery + +//Ligger food, and also bacon. + +/datum/recipe/bacon + items = list( + /obj/item/weapon/reagent_containers/food/snacks/rawbacon + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bacon + +/datum/recipe/chilied_eggs + items = list( + /obj/item/weapon/reagent_containers/food/snacks/hotchili, + /obj/item/weapon/reagent_containers/food/snacks/boiledegg, + /obj/item/weapon/reagent_containers/food/snacks/boiledegg, + /obj/item/weapon/reagent_containers/food/snacks/boiledegg + ) + result = /obj/item/weapon/reagent_containers/food/snacks/chilied_eggs + +/datum/recipe/red_sun_special + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sausage, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + + ) + result = /obj/item/weapon/reagent_containers/food/snacks/red_sun_special + +/datum/recipe/hatchling_suprise + items = list( + /obj/item/weapon/reagent_containers/food/snacks/poachedegg, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon + + ) + result = /obj/item/weapon/reagent_containers/food/snacks/hatchling_suprise + +/datum/recipe/riztizkzi_sea + items = list( + /obj/item/weapon/reagent_containers/food/snacks/egg, + /obj/item/weapon/reagent_containers/food/snacks/egg, + /obj/item/weapon/reagent_containers/food/snacks/egg + ) + reagents = list("blood" = 15) + result = /obj/item/weapon/reagent_containers/food/snacks/riztizkzi_sea + +/datum/recipe/father_breakfast + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sausage, + /obj/item/weapon/reagent_containers/food/snacks/omelette, + /obj/item/weapon/reagent_containers/food/snacks/meatsteak + ) + result = /obj/item/weapon/reagent_containers/food/snacks/father_breakfast + +/datum/recipe/stuffed_meatball + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meatball, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + fruit = list("cabbage" = 1) + result = /obj/item/weapon/reagent_containers/food/snacks/stuffed_meatball + +/datum/recipe/egg_pancake + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meatball, + /obj/item/weapon/reagent_containers/food/snacks/meatball, + /obj/item/weapon/reagent_containers/food/snacks/meatball, + /obj/item/weapon/reagent_containers/food/snacks/omelette + ) + result = /obj/item/weapon/reagent_containers/food/snacks/egg_pancake + +/datum/recipe/grilled_carp + items = list( + /obj/item/weapon/reagent_containers/food/snacks/carpmeat, + /obj/item/weapon/reagent_containers/food/snacks/carpmeat, + /obj/item/weapon/reagent_containers/food/snacks/carpmeat, + /obj/item/weapon/reagent_containers/food/snacks/carpmeat, + /obj/item/weapon/reagent_containers/food/snacks/carpmeat, + /obj/item/weapon/reagent_containers/food/snacks/carpmeat + ) + reagents = list("spacespice" = 1) + fruit = list("cabbage" = 1, "lime" = 1) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/grilled_carp + +/datum/recipe/bacon_stick + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/boiledegg + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bacon_stick + +/datum/recipe/cheese_cracker + items = list( + /obj/item/weapon/reagent_containers/food/snacks/spreads/butter, + /obj/item/weapon/reagent_containers/food/snacks/slice/bread, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + reagents = list("spacespice" = 1) + result = /obj/item/weapon/reagent_containers/food/snacks/cheese_cracker + result_quantity = 4 + +/datum/recipe/bacon_and_eggs + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/friedegg + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bacon_and_eggs + +/datum/recipe/ntmuffin + items = list( + /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit, + /obj/item/weapon/reagent_containers/food/snacks/sausage, + /obj/item/weapon/reagent_containers/food/snacks/friedegg, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/nt_muffin + +/datum/recipe/fish_taco + fruit = list("chili" = 1, "lemon" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/carpmeat, + /obj/item/weapon/reagent_containers/food/snacks/tortilla + ) + result = /obj/item/weapon/reagent_containers/food/snacks/fish_taco + +/datum/recipe/blt + fruit = list("tomato" = 1, "cabbage" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/slice/bread, + /obj/item/weapon/reagent_containers/food/snacks/slice/bread, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon + ) + result = /obj/item/weapon/reagent_containers/food/snacks/blt + +/datum/recipe/onionrings + fruit = list("onion" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice + ) + result = /obj/item/weapon/reagent_containers/food/snacks/onionrings + +/datum/recipe/berrymuffin + reagents = list("milk" = 5, "sugar" = 5) + reagent_mix = RECIPE_REAGENT_REPLACE + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough + ) + fruit = list("berries" = 1) + result = /obj/item/weapon/reagent_containers/food/snacks/muffin + +/datum/recipe/onionsoup + fruit = list("onion" = 1) + reagents = list("water" = 10) + result = /obj/item/weapon/reagent_containers/food/snacks/soup/onion + +/datum/recipe/porkbowl + reagents = list("water" = 5, "rice" = 10) + reagent_mix = RECIPE_REAGENT_REPLACE + items = list( + /obj/item/weapon/reagent_containers/food/snacks/bacon + ) + result = /obj/item/weapon/reagent_containers/food/snacks/porkbowl + +/datum/recipe/sushi + fruit = list("cabbage" = 1) + reagents = list("rice" = 20) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/sushi + +/datum/recipe/goulash + fruit = list("tomato" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/cutlet, + /obj/item/weapon/reagent_containers/food/snacks/spagetti + ) + result = /obj/item/weapon/reagent_containers/food/snacks/goulash + +/datum/recipe/donerkebab + fruit = list("tomato" = 1, "cabbage" = 1) + reagents = list("sodiumchloride" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meatsteak, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough + ) + result = /obj/item/weapon/reagent_containers/food/snacks/donerkebab + +/datum/recipe/roastbeef + fruit = list("carrot" = 2, "potato" = 2) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/roastbeef + +/datum/recipe/reishicup + reagents = list("psilocybin" = 3, "sugar" = 3) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/chocolatebar + ) + result = /obj/item/weapon/reagent_containers/food/snacks/reishicup + +/datum/recipe/hotandsoursoup + fruit = list("cabbage" = 1, "mushroom" = 1) + reagents = list("sodiumchloride" = 2, "blackpepper" = 2, "water" = 10) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/tofu + ) + result = /obj/item/weapon/reagent_containers/food/snacks/hotandsoursoup + +/datum/recipe/kitsuneudon + reagents = list("egg" = 3) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/spagetti, + /obj/item/weapon/reagent_containers/food/snacks/tofu + ) + result = /obj/item/weapon/reagent_containers/food/snacks/kitsuneudon + +/datum/recipe/pillbugball + reagents = list("carbon" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bugball + +/datum/recipe/mammi + fruit = list("orange" = 1) + reagents = list("water" = 10, "flour" = 10, "milk" = 5, "sodiumchloride" = 1) + result = /obj/item/weapon/reagent_containers/food/snacks/mammi + +/datum/recipe/makaroni + reagents = list("flour" = 15, "milk" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat, + /obj/item/weapon/reagent_containers/food/snacks/egg, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/makaroni + diff --git a/code/modules/food/recipes_microwave_vr.dm b/code/modules/food/recipes_microwave_vr.dm index 74511cac5b3..8a4d88fc2a5 100644 --- a/code/modules/food/recipes_microwave_vr.dm +++ b/code/modules/food/recipes_microwave_vr.dm @@ -1,5 +1,5 @@ /* -/datum/recipe/microwave/unique_name +/datum/recipe/unique_name fruit = list("example_fruit1" = 1, "example_fruit2" = 2) reagents = list("example_reagent1" = 10, "example_reagent2" = 5) items = list( @@ -8,24 +8,9 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/path_to_some_food */ +// All of this shit needs to be gone through and reorganized into different recipes per machine - Rykka 7/16/2020 -/datum/recipe/microwave/jellydonut - items = list( - /obj/item/weapon/reagent_containers/food/snacks/doughslice) - -/datum/recipe/microwave/jellydonut/slime - items = list( - /obj/item/weapon/reagent_containers/food/snacks/doughslice) - -/datum/recipe/microwave/jellydonut/cherry - items = list( - /obj/item/weapon/reagent_containers/food/snacks/doughslice) - -/datum/recipe/microwave/donut - items = list( - /obj/item/weapon/reagent_containers/food/snacks/doughslice) - -/datum/recipe/microwave/sushi +/datum/recipe/carpsushi fruit = list("cabbage" = 1) reagents = list("rice" = 20) items = list( @@ -35,152 +20,34 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/sushi -/datum/recipe/microwave/lasagna - fruit = list("tomato" = 2, "eggplant" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/cutlet, - /obj/item/weapon/reagent_containers/food/snacks/cutlet, - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough - ) - result = /obj/item/weapon/reagent_containers/food/snacks/lasagna - -/datum/recipe/microwave/goulash - fruit = list("tomato" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/cutlet, - /obj/item/weapon/reagent_containers/food/snacks/spagetti - ) - result = /obj/item/weapon/reagent_containers/food/snacks/goulash - -/datum/recipe/microwave/donerkebab - fruit = list("tomato" = 1, "cabbage" = 1) - reagents = list("sodiumchloride" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meatsteak, - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough - ) - result = /obj/item/weapon/reagent_containers/food/snacks/donerkebab - -/datum/recipe/microwave/roastbeef - fruit = list("carrot" = 2, "potato" = 2) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat - ) - result = /obj/item/weapon/reagent_containers/food/snacks/roastbeef - -/datum/recipe/microwave/reishicup - reagents = list("psilocybin" = 3, "sugar" = 3) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/chocolatebar - ) - result = /obj/item/weapon/reagent_containers/food/snacks/reishicup - -/datum/recipe/microwave/chickenwings - reagents = list("capsaicin" = 5, "flour" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat - ) - result = /obj/item/weapon/storage/box/wings //This is kinda like the donut box. - -/datum/recipe/microwave/hotandsoursoup - fruit = list("cabbage" = 1, "mushroom" = 1) - reagents = list("sodiumchloride" = 2, "blackpepper" = 2, "water" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/tofu - ) - result = /obj/item/weapon/reagent_containers/food/snacks/hotandsoursoup - -/datum/recipe/microwave/kitsuneudon - reagents = list("egg" = 3) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/spagetti, - /obj/item/weapon/reagent_containers/food/snacks/tofu - ) - result = /obj/item/weapon/reagent_containers/food/snacks/kitsuneudon - -/datum/recipe/microwave/generalschicken - reagents = list("capsaicin" = 2, "sugar" = 2, "flour" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat - ) - result = /obj/item/weapon/reagent_containers/food/snacks/generalschicken - -/datum/recipe/microwave/chocroizegg - items = list( - /obj/item/weapon/reagent_containers/food/snacks/chocolatebar, - /obj/item/weapon/reagent_containers/food/snacks/egg/roiz - ) - result = /obj/item/weapon/reagent_containers/food/snacks/chocolateegg/roiz - -/datum/recipe/microwave/friedroizegg - reagents = list("sodiumchloride" = 1, "blackpepper" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/egg/roiz - ) - result = /obj/item/weapon/reagent_containers/food/snacks/friedegg/roiz - -/datum/recipe/microwave/boiledroizegg - reagents = list("water" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/egg/roiz - ) - result = /obj/item/weapon/reagent_containers/food/snacks/boiledegg/roiz - -/datum/recipe/microwave/pillbugball - reagents = list("carbon" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat - ) - result = /obj/item/weapon/reagent_containers/food/snacks/bugball - -/datum/recipe/microwave/mammi - fruit = list("orange" = 1) - reagents = list("water" = 10, "flour" = 10, "milk" = 5, "sodiumchloride" = 1) - result = /obj/item/weapon/reagent_containers/food/snacks/mammi - -/datum/recipe/microwave/makaroni - reagents = list("flour" = 15, "milk" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge - ) - result = /obj/item/weapon/reagent_containers/food/snacks/makaroni - -/datum/recipe/microwave/lobster +/datum/recipe/lobster fruit = list("lemon" = 1, "cabbage" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/lobster ) result = /obj/item/weapon/reagent_containers/food/snacks/lobstercooked -/datum/recipe/microwave/cuttlefish +/datum/recipe/cuttlefish items = list( /obj/item/weapon/reagent_containers/food/snacks/cuttlefish ) result = /obj/item/weapon/reagent_containers/food/snacks/cuttlefishcooked -/datum/recipe/microwave/monkfish +/datum/recipe/monkfish fruit = list("chili" = 1, "onion" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/monkfishfillet ) result = /obj/item/weapon/reagent_containers/food/snacks/monkfishcooked -/datum/recipe/microwave/sharksteak +/datum/recipe/sharksteak reagents = list("blackpepper"= 1, "sodiumchloride" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/carpmeat/fish/sharkmeat ) result = /obj/item/weapon/reagent_containers/food/snacks/sharkmeatcooked -/datum/recipe/microwave/sharkdip +/datum/recipe/sharkdip reagents = list("sodiumchloride" = 1) fruit = list("chili" = 1) items = list( @@ -188,7 +55,7 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/sharkmeatdip -/datum/recipe/microwave/sharkcubes +/datum/recipe/sharkcubes reagents = list("soysauce" = 5, "sodiumchloride" = 1) fruit = list("potato" = 1) items = list( @@ -196,46 +63,9 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/sharkmeatcubes -/* -/datum/recipe/microwave/margheritapizzacargo - reagents = list() - items = list( - /obj/item/weapon/reagent_containers/food/snacks/pizza/margfrozen - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margcargo - -/datum/recipe/microwave/mushroompizzacargo - reagents = list() - items = list( - /obj/item/weapon/reagent_containers/food/snacks/pizza/mushfrozen - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushcargo - -/datum/recipe/microwave/meatpizzacargo - reagents = list() - items = list( - /obj/item/weapon/reagent_containers/food/snacks/pizza/meatfrozen - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatcargo - -/datum/recipe/microwave/vegtablepizzacargo - reagents = list() - items = list( - /obj/item/weapon/reagent_containers/food/snacks/pizza/vegfrozen - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegcargo -*/ - //// food cubes -/datum/recipe/microwave/foodcubes +/datum/recipe/foodcubes reagents = list("enzyme" = 20, "virusfood" = 5, "nutriment" = 15, "protein" = 15) // labor intensive items = list() result = /obj/item/weapon/storage/box/wings/tray - -/datum/recipe/microwave/honeybun - reagents = list("milk" = 5, "egg" = 3,"honey" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough - ) - result = /obj/item/weapon/reagent_containers/food/snacks/honeybun \ No newline at end of file diff --git a/code/modules/food/recipes_oven.dm b/code/modules/food/recipes_oven.dm new file mode 100644 index 00000000000..7a477cf9430 --- /dev/null +++ b/code/modules/food/recipes_oven.dm @@ -0,0 +1,560 @@ +/datum/recipe/ovenchips + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/rawsticks + ) + result = /obj/item/weapon/reagent_containers/food/snacks/ovenchips + + + +/datum/recipe/dionaroast + appliance = OVEN + fruit = list("apple" = 1) + reagents = list("pacid" = 5) //It dissolves the carapace. Still poisonous, though. + items = list(/obj/item/weapon/holder/diona) + result = /obj/item/weapon/reagent_containers/food/snacks/dionaroast + reagent_mix = RECIPE_REAGENT_REPLACE //No eating polyacid + + +/datum/recipe/ribplate //Putting this here for not seeing a roast section. + appliance = OVEN + reagents = list("honey" = 5, "spacespice" = 2, "blackpepper" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meat) + reagent_mix = RECIPE_REAGENT_REPLACE + result = /obj/item/weapon/reagent_containers/food/snacks/ribplate + + + + +//Predesigned breads +//================================ +/datum/recipe/bread + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough + ) + reagents = list("sodiumchloride" = 1, "yeast" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread + +/datum/recipe/baguette + appliance = OVEN + reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "yeast" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough + ) + result = /obj/item/weapon/reagent_containers/food/snacks/baguette + + +/datum/recipe/tofubread + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/tofu, + /obj/item/weapon/reagent_containers/food/snacks/tofu, + /obj/item/weapon/reagent_containers/food/snacks/tofu, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread + + +/datum/recipe/creamcheesebread + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread + +/datum/recipe/flatbread + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough + ) + result = /obj/item/weapon/reagent_containers/food/snacks/flatbread + +/datum/recipe/tortilla + appliance = OVEN + reagents = list("flour" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough + ) + result = /obj/item/weapon/reagent_containers/food/snacks/tortilla + +/datum/recipe/meatbread + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread + +/datum/recipe/syntibread + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, + /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, + /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread + +/datum/recipe/xenomeatbread + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/xenomeat, + /obj/item/weapon/reagent_containers/food/snacks/xenomeat, + /obj/item/weapon/reagent_containers/food/snacks/xenomeat, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread + +/datum/recipe/bananabread + appliance = OVEN + fruit = list("banana" = 1) + reagents = list("milk" = 5, "sugar" = 15) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread + + +/datum/recipe/bun + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bun + +//Predesigned pies +//======================= + +/datum/recipe/meatpie + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/meat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/meatpie + +/datum/recipe/tofupie + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/tofu + ) + result = /obj/item/weapon/reagent_containers/food/snacks/tofupie + +/datum/recipe/xemeatpie + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/xenomeat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/xemeatpie + +/datum/recipe/pie + appliance = OVEN + fruit = list("banana" = 1) + reagents = list("sugar" = 5) + items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) + result = /obj/item/weapon/reagent_containers/food/snacks/pie + +/datum/recipe/cherrypie + appliance = OVEN + fruit = list("cherries" = 1) + reagents = list("sugar" = 10) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough + ) + result = /obj/item/weapon/reagent_containers/food/snacks/cherrypie + + +/datum/recipe/amanita_pie + appliance = OVEN + reagents = list("amatoxin" = 5) + items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) + result = /obj/item/weapon/reagent_containers/food/snacks/amanita_pie + +/datum/recipe/plump_pie + appliance = OVEN + fruit = list("plumphelmet" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) + result = /obj/item/weapon/reagent_containers/food/snacks/plump_pie + + +/datum/recipe/pumpkinpie + appliance = OVEN + fruit = list("pumpkin" = 1) + reagents = list("milk" = 5, "sugar" = 5, "egg" = 3, "flour" = 10) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie + reagent_mix = RECIPE_REAGENT_REPLACE //We dont want raw egg in the result + +/datum/recipe/appletart + appliance = OVEN + fruit = list("goldapple" = 1) + reagents = list("sugar" = 5, "milk" = 5, "flour" = 10, "egg" = 3) + result = /obj/item/weapon/reagent_containers/food/snacks/appletart + reagent_mix = RECIPE_REAGENT_REPLACE + +/datum/recipe/keylimepie + appliance = OVEN + fruit = list("lime" = 2) + reagents = list("milk" = 5, "sugar" = 5, "egg" = 3, "flour" = 10) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/keylimepie + reagent_mix = RECIPE_REAGENT_REPLACE //No raw egg in finished product, protein after cooking causes magic meatballs otherwise + +/datum/recipe/quiche + appliance = OVEN + reagents = list("milk" = 5, "egg" = 9, "flour" = 10) + items = list(/obj/item/weapon/reagent_containers/food/snacks/cheesewedge) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/quiche + reagent_mix = RECIPE_REAGENT_REPLACE //No raw egg in finished product, protein after cooking causes magic meatballs otherwise + +//Baked sweets: +//--------------- + +/datum/recipe/cookie + appliance = OVEN + reagents = list("milk" = 10, "sugar" = 10) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/chocolatebar + ) + result = /obj/item/weapon/reagent_containers/food/snacks/cookie + result_quantity = 4 + reagent_mix = RECIPE_REAGENT_REPLACE + +/datum/recipe/ovenfortunecookie + appliance = OVEN + reagents = list("sugar" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/paper + ) + result = /obj/item/weapon/reagent_containers/food/snacks/fortunecookie + +/datum/recipe/poppypretzel + appliance = OVEN + fruit = list("poppy" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/dough) + result = /obj/item/weapon/reagent_containers/food/snacks/poppypretzel + result_quantity = 2 + + +/datum/recipe/cracker + appliance = OVEN + reagents = list("sodiumchloride" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice + ) + result = /obj/item/weapon/reagent_containers/food/snacks/cracker + +/datum/recipe/brownies + appliance = OVEN + reagents = list("browniemix" = 10, "egg" = 3) + reagent_mix = RECIPE_REAGENT_REPLACE //No egg or mix in final recipe + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/brownies + + +/datum/recipe/cosmicbrownies + appliance = OVEN + reagents = list("browniemix" = 10, "egg" = 3) + fruit = list("ambrosia" = 1) + reagent_mix = RECIPE_REAGENT_REPLACE //No egg or mix in final recipe + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/cosmicbrownies + + + + +//Pizzas +//========================= +/datum/recipe/pizzamargherita + appliance = OVEN + fruit = list("tomato" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita + +/datum/recipe/meatpizza + appliance = OVEN + fruit = list("tomato" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/meat, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza + +/datum/recipe/syntipizza + appliance = OVEN + fruit = list("tomato" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, + /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, + /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza + +/datum/recipe/mushroompizza + appliance = OVEN + fruit = list("mushroom" = 5, "tomato" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + + reagent_mix = RECIPE_REAGENT_REPLACE //No vomit taste in finished product from chanterelles + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza + +/datum/recipe/vegetablepizza + appliance = OVEN + fruit = list("eggplant" = 1, "carrot" = 1, "corn" = 1, "tomato" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza + +/datum/recipe/pineapplepizza + appliance = OVEN + fruit = list("tomato" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/pineapple_ring, + /obj/item/weapon/reagent_containers/food/snacks/pineapple_ring + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/pineapple + +//Spicy +//================ +/datum/recipe/enchiladas + appliance = OVEN + fruit = list("chili" = 2, "corn" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/cutlet) + result = /obj/item/weapon/reagent_containers/food/snacks/enchiladas + +/datum/recipe/monkeysdelight + appliance = OVEN + fruit = list("banana" = 1) + reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "flour" = 10) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/monkeycube + ) + result = /obj/item/weapon/reagent_containers/food/snacks/monkeysdelight + reagent_mix = RECIPE_REAGENT_REPLACE + + + + + +// Cakes. +//============ +/datum/recipe/cake + appliance = OVEN + reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9, "vanilla" = 1) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake + reagent_mix = RECIPE_REAGENT_REPLACE + +/datum/recipe/cake/carrot + appliance = OVEN + fruit = list("carrot" = 3) + reagents = list("milk" = 5, "flour" = 15, "egg" = 9,"sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake + +/datum/recipe/cake/cheese + appliance = OVEN + reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake + +/datum/recipe/cake/peanut + fruit = list("peanut" = 3) + reagents = list("milk" = 5, "flour" = 10, "sugar" = 5, "egg" = 6, "peanutbutter" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/peanutcake + +/datum/recipe/cake/orange + appliance = OVEN + fruit = list("orange" = 1) + reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake + +/datum/recipe/cake/lime + appliance = OVEN + fruit = list("lime" = 1) + reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "limejuice" = 3, "sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake + +/datum/recipe/cake/lemon + appliance = OVEN + fruit = list("lemon" = 1) + reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "lemonjuice" = 3, "sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake + +/datum/recipe/cake/chocolate + appliance = OVEN + items = list(/obj/item/weapon/reagent_containers/food/snacks/chocolatebar) + reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "coco" = 4, "sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake + +/datum/recipe/cake/birthday + appliance = OVEN + reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9) + items = list(/obj/item/clothing/head/cakehat) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake + +/datum/recipe/cake/apple + appliance = OVEN + fruit = list("apple" = 2) + reagents = list("milk" = 5, "flour" = 15, "egg" = 9,"sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake + +/datum/recipe/cake/brain + appliance = OVEN + reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9) + items = list(/obj/item/organ/internal/brain) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake + +/datum/recipe/pancakes + appliance = OVEN + fruit = list("blueberries" = 2) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough + ) + result = /obj/item/weapon/reagent_containers/food/snacks/pancakes + +/datum/recipe/lasagna + appliance = OVEN + fruit = list("tomato" = 2, "eggplant" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/cutlet, + /obj/item/weapon/reagent_containers/food/snacks/cutlet + ) + result = /obj/item/weapon/reagent_containers/food/snacks/lasagna + reagent_mix = RECIPE_REAGENT_REPLACE + +/datum/recipe/honeybun + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/dough + ) + reagents = list("milk" = 5, "egg" = 3,"honey" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/honeybun + +/datum/recipe/enchiladas_new + appliance = OVEN + fruit = list("chili" = 2) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/cutlet, + /obj/item/weapon/reagent_containers/food/snacks/tortilla + ) + result = /obj/item/weapon/reagent_containers/food/snacks/enchiladas + +//Bacon +/datum/recipe/bacon_oven + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/rawbacon, + /obj/item/weapon/reagent_containers/food/snacks/rawbacon, + /obj/item/weapon/reagent_containers/food/snacks/rawbacon, + /obj/item/weapon/reagent_containers/food/snacks/rawbacon, + /obj/item/weapon/reagent_containers/food/snacks/rawbacon, + /obj/item/weapon/reagent_containers/food/snacks/rawbacon, + /obj/item/weapon/reagent_containers/food/snacks/spreads + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bacon/oven + result_quantity = 6 + +/datum/recipe/meat_pocket + appliance = OVEN + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/meatball, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/meat_pocket + result_quantity = 2 + +/datum/recipe/bacon_flatbread + appliance = OVEN + fruit = list("tomato" = 2) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon, + /obj/item/weapon/reagent_containers/food/snacks/bacon + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bacon_flatbread + +/datum/recipe/truffle + appliance = OVEN + reagents = list("sugar" = 5, "cream" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/chocolatebar + ) + reagent_mix = RECIPE_REAGENT_REPLACE + result = /obj/item/weapon/reagent_containers/food/snacks/truffle + result_quantity = 4 + +/datum/recipe/croissant + appliance = OVEN + reagents = list("sodiumchloride" = 1, "water" = 5, "milk" = 5, "yeast" = 5) + reagent_mix = RECIPE_REAGENT_REPLACE + items = list(/obj/item/weapon/reagent_containers/food/snacks/dough) + result = /obj/item/weapon/reagent_containers/food/snacks/croissant + +/datum/recipe/macncheese + appliance = OVEN + reagents = list("milk" = 5) + reagent_mix = RECIPE_REAGENT_REPLACE + items = list( + /obj/item/weapon/reagent_containers/food/snacks/spagetti, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/macncheese \ No newline at end of file diff --git a/code/modules/gamemaster/event2/events/engineering/camera_damage.dm b/code/modules/gamemaster/event2/events/engineering/camera_damage.dm index c24fbb06f35..c6c15161302 100644 --- a/code/modules/gamemaster/event2/events/engineering/camera_damage.dm +++ b/code/modules/gamemaster/event2/events/engineering/camera_damage.dm @@ -19,9 +19,9 @@ for(var/obj/machinery/camera/cam in range(camera_range, C)) if(is_valid_camera(cam)) - cam.wires.UpdateCut(CAMERA_WIRE_POWER, 0) + cam.wires.cut(WIRE_MAIN_POWER1) if(prob(25)) - cam.wires.UpdateCut(CAMERA_WIRE_ALARM, 0) + cam.wires.cut(WIRE_CAM_ALARM) /datum/event2/event/camera_damage/proc/acquire_random_camera(var/remaining_attempts = 5) if(!cameranet.cameras.len) diff --git a/code/modules/gamemaster/event2/events/everyone/electrical_fault.dm b/code/modules/gamemaster/event2/events/everyone/electrical_fault.dm index 0645d2cfe38..0611e1b290e 100644 --- a/code/modules/gamemaster/event2/events/everyone/electrical_fault.dm +++ b/code/modules/gamemaster/event2/events/everyone/electrical_fault.dm @@ -77,7 +77,7 @@ // This will actually protect it from further damage. if(prob(25)) A.energy_fail(rand(60, 120)) - log_debug("ELECTRICAL EVENT: Disabled \the [A]'s power for a temporary amount of time.") +// log_debug("ELECTRICAL EVENT: Disabled \the [A]'s power for a temporary amount of time.") playsound(A, 'sound/machines/defib_success.ogg', 50, 1) apcs_disabled++ return @@ -85,7 +85,7 @@ // Decent chance to overload lighting circuit. if(prob(30)) A.overload_lighting() - log_debug("ELECTRICAL EVENT: Overloaded \the [A]'s lighting.") +// log_debug("ELECTRICAL EVENT: Overloaded \the [A]'s lighting.") playsound(A, 'sound/effects/lightningshock.ogg', 50, 1) apcs_overloaded++ @@ -93,7 +93,7 @@ if(prob(5)) A.emagged = TRUE A.update_icon() - log_debug("ELECTRICAL EVENT: Emagged \the [A].") +// log_debug("ELECTRICAL EVENT: Emagged \the [A].") playsound(A, 'sound/machines/chime.ogg', 50, 1) apcs_emagged++ diff --git a/code/modules/holodeck/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm index e30a6f049c0..5ba939fd8d2 100644 --- a/code/modules/holodeck/HolodeckControl.dm +++ b/code/modules/holodeck/HolodeckControl.dm @@ -325,7 +325,7 @@ for(var/mob/living/M in mobs_in_area(linkedholodeck)) if(M.mind) - linkedholodeck.play_ambience(M) + linkedholodeck.play_ambience(M, initial = TRUE) linkedholodeck.sound_env = A.sound_env diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 9273ece79ef..879c7595a4b 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -167,6 +167,11 @@ Book Cart End name = "book" icon = 'icons/obj/library.dmi' icon_state ="book" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_books.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_books.dmi' + ) + item_state = "book" throw_speed = 1 throw_range = 5 flags = NOCONDUCT diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index ff549fc29dc..1caf83608b0 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -177,10 +177,10 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f dat += {"1. View General Inventory
    2. View Checked Out Inventory
    3. Check out a Book
    - 4. Connect to External Archive
    + 4. Connect to Internal Archive
    //VOREStation Edit 5. Upload New Title to Archive
    6. Print a Bible
    - 8. Access NT Internal Archive
    "} + 8. Access External Archive
    "} //VOREStation Edit if(src.emagged) dat += "7. Access the Forbidden Lore Vault
    " if(src.arcanecheckout) @@ -226,26 +226,20 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f (Commit Entry)
    (Return to main menu)
    "} if(4) - dat += "

    External Archive

    " //VOREStation Edit - establish_old_db_connection() - -// dat += "

    Warning: System Administrator has slated this archive for removal. Personal uploads should be taken to the NT board of internal literature.

    " //VOREStation Removal TFF 29/1/20 - Redundant warning, we're not removing our library entries. - - if(!dbcon_old.IsConnected()) - dat += "ERROR: Unable to contact External Archive. Please contact your system administrator for assistance." + dat += "

    Internal Archive

    " + if(!all_books || !all_books.len) + dat += "ERROR Something has gone seriously wrong. Contact System Administrator for more information." else - dat += {"(Order book by SS13BN)

    - + dat += {"
    " + for(var/name in all_books) + var/obj/item/weapon/book/masterbook = all_books[name] + var/id = masterbook.type + var/author = masterbook.author + var/title = masterbook.name + var/category = masterbook.libcategory + dat += "" dat += "
    TITLE\[Order\]
    [author][title][category]\[Order\]
    " dat += "
    (Return to main menu)
    " if(5) @@ -278,20 +272,26 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f Yes.
    No.
    "} if(8) - dat += "

    NT Internal Archive

    " - if(!all_books || !all_books.len) - dat += "ERROR Something has gone seriously wrong. Contact System Administrator for more information." - else - dat += {" - " + //dat += "

    Warning: System Administrator has slated this archive for removal. Personal uploads should be taken to the NT board of internal literature.

    " //VOREStation Removal + + if(!dbcon_old.IsConnected()) + dat += "ERROR: Unable to contact External Archive. Please contact your system administrator for assistance." + else + dat += {"(Order book by SS13BN)

    +
    TITLE\[Order\]
    + " dat += "
    TITLE\[Order\]
    " dat += "
    (Return to main menu)
    " @@ -447,7 +447,8 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f B.title = title B.author = author B.dat = content - B.icon_state = "book[rand(1,7)]" + B.icon_state = "book[rand(1,16)]" + B.item_state = B.icon_state src.visible_message("[src]'s printer hums as it produces a completely bound book. How did it do that?") break if(href_list["orderbyid"]) diff --git a/code/modules/lore_codex/codex.dm b/code/modules/lore_codex/codex.dm index 8af1bdd9241..12fa8dbdfb1 100644 --- a/code/modules/lore_codex/codex.dm +++ b/code/modules/lore_codex/codex.dm @@ -4,6 +4,7 @@ desc = "Contains useful information about the world around you. It seems to have been written for travelers to Virgo-Erigone, human or not. It also \ has the words 'Don't Panic' in small, friendly letters on the cover." icon_state = "codex" + item_state = "book4" unique = TRUE var/datum/codex_tree/tree = null var/root_type = /datum/lore/codex/category/main_virgo_lore //Runtimes on codex_tree.dm, line 18 with a null here @@ -30,6 +31,7 @@ name = "A Buyer's Guide to Artificial Bodies" desc = "Recommended reading for the newly cyborgified, new positronics, and the upwardly-mobile FBP." icon_state = "codex_robutt" + item_state = "book6" root_type = /datum/lore/codex/category/main_robutts libcategory = "Reference" @@ -37,6 +39,7 @@ name = "Daedalus Pocket Newscaster" desc = "A regularly-updating compendium of articles on current events. Essential for new arrivals in the Vir system and anyone interested in politics." icon_state = "newscodex" + item_state = "book1" w_class = ITEMSIZE_SMALL root_type = /datum/lore/codex/category/main_news libcategory = "Reference" @@ -49,6 +52,7 @@ desc = "Contains large amounts of information on Standard Operating Procedure, Corporate Regulations, and important regional laws. The best friend of \ Internal Affairs." icon_state = "corp_regs" + item_state = "book10" root_type = /datum/lore/codex/category/main_corp_regs throwforce = 5 // Throw the book at 'em. libcategory = "Reference" diff --git a/code/modules/lore_codex/news_data/main.dm b/code/modules/lore_codex/news_data/main.dm index 1d438d43a3c..f4565329bb2 100644 --- a/code/modules/lore_codex/news_data/main.dm +++ b/code/modules/lore_codex/news_data/main.dm @@ -1,9 +1,16 @@ /datum/lore/codex/category/main_news // The top-level categories for the news thing name = "Index" - data = "Below you'll find a list of articles relevant to the current (as of 2562) political climate, especially concerning the Almach Rim \ + data = "Below you'll find a list of articles relevant to the current (as of 2564) political climate, especially concerning the Almach Rim \ region. Each is labeled by date of publication and title. This list is self-updating, and from time to time the publisher will push new \ articles. You are encouraged to check back frequently." children = list( + /datum/lore/codex/page/article88, + /datum/lore/codex/page/article87, + /datum/lore/codex/page/article86, + /datum/lore/codex/page/article85, + /datum/lore/codex/page/article84, + /datum/lore/codex/page/article83, + /datum/lore/codex/page/article82, /datum/lore/codex/page/article81, /datum/lore/codex/page/article80, /datum/lore/codex/page/article79, @@ -920,4 +927,82 @@

    \ Current analysis of the bluespace anomaly detected prior to Shelf's unexpected departure indicate that the same technology as employed by the Whythe Superweapon may have been used by Shelf to create 'a bluespace portal thus far inconceivable by modern science'. The revelation has sparked concerns that 'extreme mercurial elements' within Shelf may have been responsible for the hardware behind the Assocation's 'system eating' weapon.\

    \ - Sifat Unar of the EIO has expressed particular concern that 'Such improbable technology relying on concepts deemed so staggeringly arcane that our very understanding of the laws of the universe had written them off as impossible - and to be applied in such callous ways without regard for life or perhaps even the fabric of reality, could only have been developed by machine minds that could threaten our very being.' Shelf has dismissed these claims as 'Scaremongering' and 'Just jealous that somebody else thought of it first', though they would not confirm nor deny their involvement in the development of the new bluespace portals." \ No newline at end of file + Sifat Unar of the EIO has expressed particular concern that 'Such improbable technology relying on concepts deemed so staggeringly arcane that our very understanding of the laws of the universe had written them off as impossible - and to be applied in such callous ways without regard for life or perhaps even the fabric of reality, could only have been developed by machine minds that could threaten our very being.' Shelf has dismissed these claims as 'Scaremongering' and 'Just jealous that somebody else thought of it first', though they would not confirm nor deny their involvement in the development of the new bluespace portals." + +/datum/lore/codex/page/article82 + name = "04/11/64 - Whythe Breached - An End In Sight?" + data = "According to latest reports from the Almach front, Sol vessels have established a foothold in the debris fields of the desolate Whythe system, home to the enemy's controversial 'Superweapon'. Admiral Barka has confirmed that bombardment of the weapon has begun, but that 'shields are holding at present', owing to the vast construction's immense power generation capabilities, but remains confident that the 'siege' will come to an end within a few months, and that the Almachi now hold only 'minimal retaliatory capacity'.\ +

    \ + Fleet sources have been quick to address a flurry of activity on the exonet which proposed that the superweapon might be deployed against Sol's core systems in a last-ditch effort to inflict damage on their former government. According to a statement posted just hours after the initial invasion press release, 'the Fleet is aware of all risk factors regarding the Whythe Superweapon, and following two long months of analysis are certain that constant, substantial pressure placed on the weapon's shield systems will render the offensive component of the weapon dormant until the hull can be breached.'\ +

    \ + The general mood in the Colonial Assembly today is one of relief, as all signs point to a total collapse or surrender of Association forces in their home systems once their trump card has been captured or destroyed by SCG forces. Secretary West has already expressed congratulations to the troops, 'despite the lack of assistance from our allies, as the Shadow Coalition would have had us believe was necessary.'" + +/datum/lore/codex/page/article83 + name = "04/13/64 - Skrell Ultimatum Shocks Sol!" + data = "After three months of diplomatic iciness, the Skrellian Far Kingdoms have contacted both the SCG and Almach Association with one demand: Sign an armistice or prepare for war. Supported by an immense fleet movement through the recently quashed Xe'qua region, the Far Kingdoms have demanded an immediate end to hostilities, and 'incorporation of Almachi holdings as a Skrellian protectorate, under strict oversight and regulation of their research and activities.' By Skrell demands, the Fleet has two weeks to fully withdraw from the Almach region and any vessels on either side continuing to engage will be 'disabled, boarded, and have its crew arrested pending a formal peace agreement.'\ +

    \ + A wave of outrage has swept the Colonial Assembly, with heated debate as to Sol's response defying all party lines. While Speaker ISA-5 has been widely criticized by political opponents for their 'overzealous trust in the Skrell', they have remained acquiescent to the Skrell's demands, stating that it may be the best way to avoid any further bloodshed and maintain good relationships with the Skrell. Conversely, a small group of hardliners from across the major parties headed by SEO Representative Colin Zula of Alpha Centauri, have formed a political coalition opposing any form of 'Surrender or appeasement in the face of foreign aggression', demanding Sol keep its forces in place and 'Finish off the Association before they can be allowed to wreak havoc unsupervised and uncontrolled.'\ +

    \ + Surprising some, long-time supporter of the Almach War, MacKenzie West has established themselves as a figure of moderation in the Assembly, promising that the Icarus Front would pursue 'aggressive negotiations' with the Far Kingdoms in order to better understand their motivations and, if territory is to be ceded, 'ensure the Almachi are placed under a firm hand'. He notes that the Skrell have never adhered to Five Points policy, but that careful diplomacy has always ensured their 'less savoury tendencies' have never spilled over to Sol space." + +/datum/lore/codex/page/article84 + name = "04/16/64 - Assembly Shaken By Reshuffle" + data = "Following the shock announcement of the Skrellian demands on Monday, sixteen planetary representatives under the SEO's Colin Zula have announced the formation of a new political party named the 'Solar Sovereignty Party' under the banner of 'Independence from foreign demands'. The party consists of defectors from all three major parties; 9 Sol Economic Organization, 4 Icarus Front and 3 Shadow Coalition representatives have 'jumped ship' and will back Zula's demands to resume war with the Association, even if it means butting heads with the Skrell.\ +

    \ + Rewi Kerehoma, chair of the SEO has expressed 'regret' that Mr. Zula and his supporters had chosen to splinter from the party, rather than work with 'More moderate, but like-minded' individuals across the SEO and wider Assembly. The SEO's official stance on the Skrellian demands are to demand close Solar oversight of any 'protectorate' to ensure that the region is 'policed to the highest standard, but that current Almachi citizens are afforded all the sapient rights they would be under the SCG.'\ +

    \ + In the Shadow Coalition, a formal motion has been put forth by a small minority of representatives calling for the resignation of Speaker ISA-5, citing 'Total blindness to the political situation,' in the leadup to this week's events.\ +

    \ + Meanwhile as Skrell vessels enter the Whythe system, the Solar Fleet has ceased bombardment of the Whythe Superweapon, handing off 'suppression' of the weapon to Skrell forces." + +/datum/lore/codex/page/article85 + name = "04/20/64 - Sol To Submit - Almach Subsumed Under Treaty of Whythe" + data = "Following 'intense' deliberations between the Far Kingdoms and representatives from the SCG, a decision has been reached to cede the secessionist Almach Association territory to the Skrell, and withdraw all forces from the region. The newly established Almach Protectorate will be subject to 'extremely stringent' oversight by Skrellian authorities, and international exchange of 'research and technologies' from the region will be banned 'in both directions', pending more a more exacting deal with the SCG. Sol is to be allowed 'regular inspections' of the territory on a schedule established by the Kingdoms.\ +

    \ + The Solar envoy included the chairs of each of the major parties, senior ambassadors to major Skrell systems, and representatives from the Solar Fleet. The newly founded SSF were extended an invitation, but reportedly turned it down. A dejected looking MacKenzie West announced the terms of the treaty late this afternoon, stating that they had 'fought tooth and nail' for a fair deal for all parties involved, including civilians of all species now living under Skrellian occupation, and that 'those not directly involved in the corruption of humanity's sanctity should not be made to suffer for the actions of their superiors.'\ +

    \ + Notably absent from deliberations were many key members of the Association's upper echelons, with 'lesser' diplomats taking the place of both Angessa Martei and Vounna's Naomi Harper. Almachi and Skrell sources were reluctant to explain these absenses, and it remains unclear as to whether they have been taken into Skrellian custody or remain at large.\ +

    \ + Selma Jorg, Representative for Vir, has decried the treaty as a 'Sapientarian disaster in the making'. The former career diplomat has cited the 'general mistreatment of species deemed 'lesser'' as a recurring concern with the Skrell, and the complete occupation of majority human and positronic space, which unprecedented, could lead to 'conditions not much better than slavery' for those still living in the area. She has refrained from any direct accusations, pending the results of Sol's first permitted inspection." + +/datum/lore/codex/page/article85 + name = "04/22/64 - Skrell Impose New Regime in Relan" + data = "As agreed upon in the Treaty of Whythe, the Far Kingdoms have occupied the Relan system, putting an end to the Free Relan Federation. How the system will be organized is not entirely clear at this point. Despite the effective abolition of the Relanian government, Skrell presence in the system appears relatively light, and many of the scattered stations have no Skrell presence at all.\ +

    \ + Former President Nia Fischer gave the following statement to a crowd gathered outside the Capitol Section of Carter: 'This is a dark time for all of us. I promise to you that, in my continued service to you, I will work with the Far Kingdoms to ensure that all of our people are treated well and our rights respected, and that we will arrive at a form of government that is acceptable to you.' The gathered crowd began to shout questions and accusations, and Fischer was quickly escorted back into the capitol by Skrellian guards without answering questions from the press or others. The crowd was quickly dispersed by Skrellian military police and Carter’s own police force.\ +

    \ + In the meantime, the governing of the system remains in the hands of the sparse occupation forces, aided by parts of the former Federation government.\ +

    \ + In other news from the system, the Republic of Taron has negotiated a preliminary navigation and trade agreement with the Far Kingdoms, officially maintaining their neutrality despite the occupation of the majority of the system." + +/datum/lore/codex/page/article86 + name = "04/27/64 - Chaos in Relan" + data = "Simmering tensions in the Relan system have boiled over, with riots erupting on Carter, Abhayaranya, and New Busan. Since former President Fischer’s brief address, small demonstrations against both the Skrell occupation and the collaborating elements of the former Federation government have taken place on many stations, but within the last day full-blown riots have broken out. While accurate information on the situation within the stations is rare, it is currently believed that the deaths of two protesters on Abhayaranya were the catalyst.\ +

    \ + Damage to the three stations has been relatively light, with one major exception. A large fire broke out in the Capitol Section of Carter, killing at least 22, including former President Fischer, and wounding at least 74 more. Other casualties among rioters, police, and the populations of the stations are unknown at this point.\ +

    \ + Other stations with significant permanent populations have been paralyzed by local inaction and the disloyalty of local police and security forces to the Far Kindgoms Skrell, and several with no Skrell presence have issued statements that they will not be accepting any military presence from the Far Kingdoms. It is unclear at this point if this represents the beginning of another major conflict within the system." + +/datum/lore/codex/page/article87 + name = "04/30/64 - Meralar Correspondent: Triumphant Return!" + data = "Celebrations have erupted throughout Tajaran space with the return of the PCMV Raniira's Grace, which has spent the last several months providing joint assistance with Solar military forces during the now-ceased hostilities with the Almach Association.\ +

    \ + Khama Suketa enai-Lutiir, representative of the Tajaran Pearlshield Coalition, has provided the following statement:\ +

    \ + 'It is great honour that we welcome the crew of the Raniira's Grace back to their homes at Mesomori. We have all seen the battle reports, and loathe as we are to celebrate bloodshed, sometimes it is a necessary evil in the pursuit of a greater peace, and the Grace pursued that peace with fervour and tenacity as befitting our kind, and exemplified what we can do when put to the test. She is but one ship, and yet one ship can make all the difference. Lives have been saved, and the crew has returned alive and well. This is merely the beginning of what we can accomplish in the cosmos.'\ +

    \ + When asked for comment on the Treaty of Whythe, Suketa had this to say:\ +

    \ + 'Indeed, the bittersweetness behind all of this. I will say, it is a... complicated and nuanced situation, as is so often the case with politics. We have our views on the matter, for sure, but now is not the time to formally engage with them. The Pearlshield is watching carefully, and when the dust settles and the terms of the treaty are exercised and accepted, we can take clearer view and action as possible and necessary. We still stand by the ideals we entered the war with, and we trust our allies to share them as ever. That will suffice for the moment.'" + +/datum/lore/codex/page/article88 + name = "05/13/64 - Agreement Signed at Ithaca Station, New Government In Place" + data = "In an effort to end the ongoing violence in the Relan system and regain the cooperation of 'insubordinate' stations, the Far Kingdoms Skrell have negotiated an agreement with community leaders and former Assemblypersons from a number of stations, including insubordinates, meeting at the largest of the insubordinates, Ithaca. Under these agreements, the Skrell will vacate most stations in the system, but will maintain a fleet base in Relan’s Outer Belt for mutual defence, first at Carter and later at a dedicated station. Relan will have harsh restrictions placed on its military and will agree to formal diplomatic neutrality, but will be free to organize its own government under supervision and military occupation will end.\ +

    \ + The mood on Ithaca has been tense as negotiations have gone on, but with the announcement of the results, crowds have packed the main thoroughfares and public spaces of the station in celebration. Francis Harp Yong, governor of Ithaca and a leading figure in the talks, addressed a crowd outside the Administration Section of Ithaca today. \ +

    \ + 'The agreement we have signed with the Skrell today has given our people a new chance, free from the mistakes of the war and the baggage of the former Association. The war was not brought on us by our choice, nor the occupation we have recently faced. We want peace, and that is obvious even to those who were fighting against us weeks or days ago.\ +

    \ + Make no mistake, that is what our agreement today symbolizes. A new era of peace for us, where we no longer have to worry about the threat of piracy or invasion. We can return to our homes, rebuild our stations, and forge a new future for ourselves and our children'\ +

    \ + It was also announced that though the work of restoring order to the system is ongoing, they expect elections will be held for a new Assembly and President within the next few months, with the exact date announced once violence on the major stations has ceased and cooperation from the insubordinate stations is secured. Yong will head an interim government in the meantime." diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index fbb842a422d..2efef5783ff 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -138,6 +138,7 @@ recipes += new/datum/stack_recipe("water-cooler", /obj/structure/reagent_dispensers/water_cooler, 4, time = 10, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE) recipes += new/datum/stack_recipe("lampshade", /obj/item/weapon/lampshade, 1, time = 1, pass_stack_color = TRUE) recipes += new/datum/stack_recipe("plastic net", /obj/item/weapon/material/fishing_net, 25, time = 1 MINUTE, pass_stack_color = TRUE) + recipes += new/datum/stack_recipe("plastic fishtank", /obj/item/glass_jar/fish/plastic, 2, time = 30 SECONDS) /material/wood/generate_recipes() ..() @@ -159,6 +160,7 @@ recipes += new/datum/stack_recipe("coilgun stock", /obj/item/weapon/coilgun_assembly, 5, pass_stack_color = TRUE) recipes += new/datum/stack_recipe("crude fishing rod", /obj/item/weapon/material/fishing_rod/built, 8, time = 10 SECONDS, pass_stack_color = TRUE) recipes += new/datum/stack_recipe("wooden standup figure", /obj/structure/barricade/cutout, 5, time = 10 SECONDS, pass_stack_color = TRUE) //VOREStation Add + recipes += new/datum/stack_recipe("noticeboard", /obj/structure/noticeboard, 1) /material/wood/log/generate_recipes() recipes = list() diff --git a/code/modules/metric/activity.dm b/code/modules/metric/activity.dm index 5bdc33f47ac..c33c88adcaf 100644 --- a/code/modules/metric/activity.dm +++ b/code/modules/metric/activity.dm @@ -40,13 +40,13 @@ var/list/activity = list() for(var/department in departments) activity[department] = assess_department(department) - log_debug("Assessing department [department]. They have activity of [activity[department]].") +// log_debug("Assessing department [department]. They have activity of [activity[department]].") var/list/most_active_departments = list() // List of winners. var/highest_activity = null // Department who is leading in activity, if one exists. var/highest_number = 0 // Activity score needed to beat to be the most active department. for(var/i = 1, i <= cutoff_number, i++) - log_debug("Doing [i]\th round of counting.") +// log_debug("Doing [i]\th round of counting.") for(var/department in activity) if(department in department_blacklist) // Blacklisted? continue @@ -57,7 +57,7 @@ if(highest_activity) // Someone's a winner. most_active_departments.Add(highest_activity) // Add to the list of most active. activity.Remove(highest_activity) // Remove them from the other list so they don't win more than once. - log_debug("[highest_activity] has won the [i]\th round of activity counting.") +// log_debug("[highest_activity] has won the [i]\th round of activity counting.") highest_activity = null // Now reset for the next round. highest_number = 0 //todo: finish diff --git a/code/modules/mob/_modifiers/modifiers.dm b/code/modules/mob/_modifiers/modifiers.dm index 72da563a22c..56422efdf66 100644 --- a/code/modules/mob/_modifiers/modifiers.dm +++ b/code/modules/mob/_modifiers/modifiers.dm @@ -20,6 +20,10 @@ var/light_intensity = null // Ditto. Not implemented yet. var/mob_overlay_state = null // Icon_state for an overlay to apply to a (human) mob while this exists. This is actually implemented. var/client_color = null // If set, the client will have the world be shown in this color, from their perspective. + var/wire_colors_replace = null // If set, the client will have wires replaced by the given replacement list. For colorblindness. //VOREStation Add + var/list/filter_parameters = null // If set, will add a filter to the holder with the parameters in this var. Must be a list. + var/filter_priority = 1 // Used to make filters be applied in a specific order, if that is important. + var/filter_instance = null // Instance of a filter created with the `filter_parameters` list. This exists to make `animate()` calls easier. Don't set manually. // Now for all the different effects. // Percentage modifiers are expressed as a multipler. (e.g. +25% damage should be written as 1.25) @@ -51,6 +55,14 @@ var/emp_modifier // Added to the EMP strength, which is an inverse scale from 1 to 4, with 1 being the strongest EMP. 5 is a nullification. var/explosion_modifier // Added to the bomb strength, which is an inverse scale from 1 to 3, with 1 being gibstrength. 4 is a nullification. + // Note that these are combined with the mob's real armor values additatively. You can also omit specific armor types. + var/list/armor_percent = null // List of armor values to add to the holder when doing armor calculations. This is for percentage based armor. E.g. 50 = half damage. + var/list/armor_flat = null // Same as above but only for flat armor calculations. E.g. 5 = 5 less damage (this comes after percentage). + // Unlike armor, this is multiplicative. Two 50% protection modifiers will be combined into 75% protection (assuming no base protection on the mob). + var/heat_protection = null // Modifies how 'heat' protection is calculated, like wearing a firesuit. 1 = full protection. + var/cold_protection = null // Ditto, but for cold, like wearing a winter coat. + var/siemens_coefficient = null // Similar to above two vars but 0 = full protection, to be consistant with siemens numbers everywhere else. + var/vision_flags // Vision flags to add to the mob. SEE_MOB, SEE_OBJ, etc. /datum/modifier/New(var/new_holder, var/new_origin) @@ -82,6 +94,8 @@ holder.update_transform() if(client_color) holder.update_client_color() + if(LAZYLEN(filter_parameters)) + holder.remove_filter(REF(src)) qdel(src) // Override this for special effects when it gets added to the mob. @@ -150,6 +164,9 @@ update_transform() if(mod.client_color) update_client_color() + if(LAZYLEN(mod.filter_parameters)) + add_filter(REF(mod), mod.filter_priority, mod.filter_parameters) + mod.filter_instance = get_filter(REF(mod)) return mod @@ -177,10 +194,14 @@ // Checks if the mob has a modifier type. /mob/living/proc/has_modifier_of_type(var/modifier_type) + return get_modifier_of_type(modifier_type) ? TRUE : FALSE + +// Gets the first instance of a specific modifier type or subtype. +/mob/living/proc/get_modifier_of_type(var/modifier_type) for(var/datum/modifier/M in modifiers) if(istype(M, modifier_type)) - return TRUE - return FALSE + return M + return null // This displays the actual 'numbers' that a modifier is doing. Should only be shown in OOC contexts. // When adding new effects, be sure to update this as well. diff --git a/code/modules/mob/_modifiers/modifiers_misc.dm b/code/modules/mob/_modifiers/modifiers_misc.dm index e7af15895c7..3b9663d855b 100644 --- a/code/modules/mob/_modifiers/modifiers_misc.dm +++ b/code/modules/mob/_modifiers/modifiers_misc.dm @@ -388,3 +388,42 @@ the artifact triggers the rage. if(holder.stat != DEAD) holder.visible_message("\The [holder] collapses, the life draining from their body.") holder.death() + +/datum/modifier/outline_test + name = "Outline Test" + desc = "This only exists to prove filter effects work and gives an example of how to animate() the resulting filter object." + + filter_parameters = list(type = "outline", size = 1, color = "#FFFFFF", flags = OUTLINE_SHARP) + +/datum/modifier/outline_test/tick() + animate(filter_instance, size = 3, time = 0.25 SECONDS) + animate(size = 1, 0.25 SECONDS) + + +// Acts as a psuedo-godmode, yet probably is more reliable than the actual var for it nowdays. +// Can't protect from instantly killing things like singulos. +/datum/modifier/invulnerable + name = "invulnerable" + desc = "You are almost immune to harm, for a little while at least." + stacks = MODIFIER_STACK_EXTEND + + disable_duration_percent = 0 + incoming_damage_percent = 0 +// bleeding_rate_percent = 0 + pain_immunity = TRUE + armor_percent = list("melee" = 2000, "bullet" = 2000, "laser" = 2000, "bomb" = 2000, "energy" = 2000, "bio" = 2000, "rad" = 2000) + heat_protection = 1.0 + cold_protection = 1.0 + siemens_coefficient = 0.0 + +// Reduces resistance to "elements". +// Note that most things that do give resistance gives 100% protection, +// and due to multiplicitive stacking, this modifier won't do anything to change that. +/datum/modifier/elemental_vulnerability + name = "elemental vulnerability" + desc = "You're more vulnerable to extreme temperatures and electricity." + stacks = MODIFIER_STACK_EXTEND + + heat_protection = -0.5 + cold_protection = -0.5 + siemens_coefficient = 1.5 \ No newline at end of file diff --git a/code/modules/mob/_modifiers/traits.dm b/code/modules/mob/_modifiers/traits.dm index b15ece941e3..ea21ae007bc 100644 --- a/code/modules/mob/_modifiers/traits.dm +++ b/code/modules/mob/_modifiers/traits.dm @@ -127,33 +127,39 @@ desc = "You have a form of red-green colorblindness. You cannot see reds, and have trouble distinguishing them from yellows and greens." client_color = MATRIX_Protanopia + wire_colors_replace = PROTANOPIA_COLOR_REPLACE /datum/modifier/trait/colorblind_deuteranopia name = "Deuteranopia" desc = "You have a form of red-green colorblindness. You cannot see greens, and have trouble distinguishing them from yellows and reds." client_color = MATRIX_Deuteranopia + wire_colors_replace = DEUTERANOPIA_COLOR_REPLACE /datum/modifier/trait/colorblind_tritanopia name = "Tritanopia" desc = "You have a form of blue-yellow colorblindness. You have trouble distinguishing between blues, greens, and yellows, and see blues and violets as dim." client_color = MATRIX_Tritanopia + wire_colors_replace = TRITANOPIA_COLOR_REPLACE /datum/modifier/trait/colorblind_taj name = "Colorblind - Blue-red" desc = "You are colorblind. You have a minor issue with blue colors and have difficulty recognizing them from red colors." client_color = MATRIX_Taj_Colorblind + wire_colors_replace = TRITANOPIA_COLOR_REPLACE /datum/modifier/trait/colorblind_vulp name = "Colorblind - Red-green" desc = "You are colorblind. You have a severe issue with green colors and have difficulty recognizing them from red colors." client_color = MATRIX_Vulp_Colorblind + wire_colors_replace = PROTANOPIA_COLOR_REPLACE /datum/modifier/trait/colorblind_monochrome name = "Monochromacy" desc = "You are fully colorblind. Your condition is rare, but you can see no colors at all." client_color = MATRIX_Monochromia + wire_colors_replace = GREYSCALE_COLOR_REPLACE \ No newline at end of file diff --git a/code/modules/mob/_modifiers/traits_phobias.dm b/code/modules/mob/_modifiers/traits_phobias.dm index bd30891fbe7..87f8ecc4464 100644 --- a/code/modules/mob/_modifiers/traits_phobias.dm +++ b/code/modules/mob/_modifiers/traits_phobias.dm @@ -120,27 +120,32 @@ // People covered in blood is also bad. // Feel free to trim down if its too expensive CPU wise. - if(istype(thing, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = thing - var/self_multiplier = H == holder ? 2 : 1 - var/human_blood_fear_amount = 0 - if(!H.gloves && H.bloody_hands && H.hand_blood_color != SYNTH_BLOOD_COLOUR) - human_blood_fear_amount += 1 - if(!H.shoes && H.feet_blood_color && H.feet_blood_color != SYNTH_BLOOD_COLOUR) - human_blood_fear_amount += 1 + if(isliving(thing)) + var/mob/living/L = thing + if(L.alpha <= FAKE_INVIS_ALPHA_THRESHOLD) // Can't fear something you can't (easily) see. + continue - // List of slots. Some slots like pockets are omitted due to not being visible, if H isn't the holder. - var/list/clothing_slots = list(H.back, H.wear_mask, H.l_hand, H.r_hand, H.wear_id, H.glasses, H.gloves, H.head, H.shoes, H.belt, H.wear_suit, H.w_uniform, H.s_store, H.l_ear, H.r_ear) - if(H == holder) - clothing_slots += list(H.l_store, H.r_store) - - for(var/obj/item/clothing/C in clothing_slots) - if(C.blood_DNA && C.blood_color && C.blood_color != SYNTH_BLOOD_COLOUR) + if(istype(thing, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = thing + var/self_multiplier = H == holder ? 2 : 1 + var/human_blood_fear_amount = 0 + if(!H.gloves && H.bloody_hands && H.hand_blood_color != SYNTH_BLOOD_COLOUR) + human_blood_fear_amount += 1 + if(!H.shoes && H.feet_blood_color && H.feet_blood_color != SYNTH_BLOOD_COLOUR) human_blood_fear_amount += 1 - // This is divided, since humans can wear so many items at once. - human_blood_fear_amount = round( (human_blood_fear_amount * self_multiplier) / 3, 1) - fear_amount += human_blood_fear_amount + // List of slots. Some slots like pockets are omitted due to not being visible, if H isn't the holder. + var/list/clothing_slots = list(H.back, H.wear_mask, H.l_hand, H.r_hand, H.wear_id, H.glasses, H.gloves, H.head, H.shoes, H.belt, H.wear_suit, H.w_uniform, H.s_store, H.l_ear, H.r_ear) + if(H == holder) + clothing_slots += list(H.l_store, H.r_store) + + for(var/obj/item/clothing/C in clothing_slots) + if(C.blood_DNA && C.blood_color && C.blood_color != SYNTH_BLOOD_COLOUR) + human_blood_fear_amount += 1 + + // This is divided, since humans can wear so many items at once. + human_blood_fear_amount = round( (human_blood_fear_amount * self_multiplier) / 3, 1) + fear_amount += human_blood_fear_amount // Bloody objects are also bad. if(istype(thing, /obj)) @@ -207,12 +212,18 @@ if(istype(thing, /obj/structure/snowman/spider)) //Snow spiders are also spooky so people can be assholes with those too. fear_amount += 1 - if(istype(thing, /mob/living/simple_mob/animal/giant_spider)) // Actual giant spiders are the scariest of them all. - var/mob/living/simple_mob/animal/giant_spider/S = thing - if(S.stat == DEAD) // Dead giant spiders are less scary than alive ones. - fear_amount += 4 - else - fear_amount += 8 + if(isliving(thing)) + var/mob/living/L = thing + if(L.alpha <= FAKE_INVIS_ALPHA_THRESHOLD) // Can't fear something you can't (easily) see. + continue + + if(istype(L, /mob/living/simple_mob/animal/giant_spider)) // Actual giant spiders are the scariest of them all. + var/mob/living/simple_mob/animal/giant_spider/S = L + + if(S.stat == DEAD) // Dead giant spiders are less scary than alive ones. + fear_amount += 4 + else + fear_amount += 8 return fear_amount @@ -425,25 +436,29 @@ if(istype(thing, /obj/item/clothing/head/collectable/slime)) // Some hats are spooky so people can be assholes with them. fear_amount += 1 - if(istype(thing, /mob/living/simple_mob/slime)) // An actual predatory specimen! - var/mob/living/simple_mob/slime/S = thing - if(S.stat == DEAD) // Dead slimes are somewhat less spook. - fear_amount += 4 - if(istype(S, /mob/living/simple_mob/slime/xenobio)) - var/mob/living/simple_mob/slime/xenobio/X = S - if(X.is_adult == TRUE) //big boy - fear_amount += 8 + if(isliving(thing)) + var/mob/living/L = thing + if(L.alpha <= FAKE_INVIS_ALPHA_THRESHOLD) // Can't fear something you can't (easily) see. + continue + if(istype(L, /mob/living/simple_mob/slime)) // An actual predatory specimen! + var/mob/living/simple_mob/slime/S = L + if(S.stat == DEAD) // Dead slimes are somewhat less spook. + fear_amount += 4 + if(istype(S, /mob/living/simple_mob/slime/xenobio)) + var/mob/living/simple_mob/slime/xenobio/X = S + if(X.is_adult == TRUE) //big boy + fear_amount += 8 + else + fear_amount += 6 else - fear_amount += 6 - else - fear_amount += 10 // It's huge and feral. + fear_amount += 10 // It's huge and feral. - if(istype(thing, /mob/living/carbon/human)) - var/mob/living/carbon/human/S = thing - if(istype(S.species, /datum/species/skrell)) //Skrell ARE slimey. - fear_amount += 1 - if(istype(S.species, /datum/species/shapeshifter/promethean)) - fear_amount += 4 + if(istype(L, /mob/living/carbon/human)) + var/mob/living/carbon/human/S = L + if(istype(S.species, /datum/species/skrell)) //Skrell ARE slimey. + fear_amount += 1 + if(istype(S.species, /datum/species/shapeshifter/promethean)) + fear_amount += 4 return fear_amount @@ -525,13 +540,17 @@ if(istype(thing, /obj/item/weapon/gun/launcher/syringe)) fear_amount += 6 - if(istype(thing, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = thing - if(H.l_hand && istype(H.l_hand, /obj/item/weapon/reagent_containers/syringe) || H.r_hand && istype(H.r_hand, /obj/item/weapon/reagent_containers/syringe)) - fear_amount += 10 + if(isliving(thing)) + var/mob/living/L = thing + if(L.alpha <= FAKE_INVIS_ALPHA_THRESHOLD) // Can't fear something you can't (easily) see. + continue + if(istype(L, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = L + if(H.l_hand && istype(H.l_hand, /obj/item/weapon/reagent_containers/syringe) || H.r_hand && istype(H.r_hand, /obj/item/weapon/reagent_containers/syringe)) + fear_amount += 10 - if(H.l_ear && istype(H.l_ear, /obj/item/weapon/reagent_containers/syringe) || H.r_ear && istype(H.r_ear, /obj/item/weapon/reagent_containers/syringe)) - fear_amount +=10 + if(H.l_ear && istype(H.l_ear, /obj/item/weapon/reagent_containers/syringe) || H.r_ear && istype(H.r_ear, /obj/item/weapon/reagent_containers/syringe)) + fear_amount +=10 return fear_amount diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 9dca9c6fdc6..fcc85f2a2fb 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -160,6 +160,12 @@ I = getFlatIcon(src, defdir = SOUTH, no_anim = TRUE) set_cached_examine_icon(src, I, 200 SECONDS) return I + +/mob/observer/dead/examine(mob/user) + . = ..() + + if(is_admin(user)) + . += "\t>[ADMIN_FULLMONTY(src)]" /* Transfer_mind is there to check if mob is being deleted/not going to have a body. diff --git a/code/modules/mob/freelook/ai/update_triggers.dm b/code/modules/mob/freelook/ai/update_triggers.dm index c0b4adf0f61..9fd28344df2 100644 --- a/code/modules/mob/freelook/ai/update_triggers.dm +++ b/code/modules/mob/freelook/ai/update_triggers.dm @@ -37,7 +37,6 @@ /obj/machinery/camera/deactivate(user as mob, var/choice = 1) ..(user, choice) - invalidateCameraCache() if(src.can_use()) cameranet.addCamera(src) else diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index 1315c94a472..1df1e25b88c 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -27,6 +27,19 @@ var/list/holder_mob_icon_cache = list() ..() START_PROCESSING(SSobj, src) +/obj/item/weapon/holder/throw_at(atom/target, range, speed, thrower) + if(held_mob) + held_mob.forceMove(loc) + var/thrower_mob_size = 1 + if(ismob(thrower)) + var/mob/M = thrower + thrower_mob_size = M.mob_size + var/mob_range = round(range * min(thrower_mob_size / held_mob.mob_size, 1)) + held_mob.throw_at(target, mob_range, speed, thrower) + held_mob = null + drop_items() + qdel(src) + /obj/item/weapon/holder/Destroy() STOP_PROCESSING(SSobj, src) return ..() diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index d788f9099e5..c778470b191 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -192,9 +192,9 @@ var/list/slot_equipment_priority = list( \ //This differs from remove_from_mob() in that it checks if the item can be unequipped first. /mob/proc/unEquip(obj/item/I, force = 0, var/atom/target) //Force overrides NODROP for things like wizarditis and admin undress. if(!(force || canUnEquip(I))) - return + return FALSE drop_from_inventory(I, target) - return 1 + return TRUE //Attemps to remove an object on a mob. diff --git a/code/modules/mob/language/station_vr.dm b/code/modules/mob/language/station_vr.dm index 1e2dac1a8b5..3d8028ca30d 100644 --- a/code/modules/mob/language/station_vr.dm +++ b/code/modules/mob/language/station_vr.dm @@ -110,6 +110,21 @@ "ver", "stv", "pro", "ski" ) +/datum/language/drudakar + name = LANGUAGE_DRUDAKAR + desc = "The native language of the D'Rudak'Ar, a loosely tied together community of dragons and demi-dragons based in the Diul system. Features include many hard consonants and rolling 'r's." + speech_verb = "gaos" + ask_verb = "gaos" + exclaim_verb = "GAOS" + whisper_verb = "gaos" + colour = "drudakar" + key = "K" + syllables = list( + "gok", "rha", "rou", "gao", "do", "ra", "bo", "lah", "draz", "khi", "zah", "lah", "ora", "ille", + "ghlas", "ghlai", "tyur", "vah", "bao", "raag", "drag", "zhi", "dahl", "tiyr", "vahl", "nyem", + "roar", "hyaa", "ma", "ha", "ya", "shi", "yo", "go" + ) + /datum/language/unathi flags = 0 /datum/language/tajaran diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm index 4ea28b3eea9..0822dca3756 100644 --- a/code/modules/mob/living/bot/bot.dm +++ b/code/modules/mob/living/bot/bot.dm @@ -68,9 +68,9 @@ if(health <= 0) death() return - weakened = 0 - stunned = 0 - paralysis = 0 + SetWeakened(0) + SetStunned(0) + SetParalysis(0) if(on && !client && !busy) spawn(0) diff --git a/code/modules/mob/living/bot/medbot.dm b/code/modules/mob/living/bot/medbot.dm index a67440e0138..68e803af877 100644 --- a/code/modules/mob/living/bot/medbot.dm +++ b/code/modules/mob/living/bot/medbot.dm @@ -1,3 +1,13 @@ +// Medbot Info + +#define MEDBOT_PANIC_NONE 0 +#define MEDBOT_PANIC_LOW 15 +#define MEDBOT_PANIC_MED 35 +#define MEDBOT_PANIC_HIGH 55 +#define MEDBOT_PANIC_FUCK 70 +#define MEDBOT_PANIC_ENDING 90 +#define MEDBOT_PANIC_END 100 + /mob/living/bot/medbot name = "Medibot" desc = "A little medical robot. He looks somewhat underwhelmed." @@ -24,6 +34,15 @@ var/treatment_emag = "toxin" var/declare_treatment = 0 //When attempting to treat a patient, should it notify everyone wearing medhuds? + // Are we tipped over? + var/is_tipped = FALSE + //How panicked we are about being tipped over (why would you do this?) + var/tipped_status = MEDBOT_PANIC_NONE + //The name we got when we were tipped + var/tipper_name + //The last time we were tipped/righted and said a voice line, to avoid spam + var/last_tipping_action_voice = 0 + /mob/living/bot/medbot/mysterious name = "\improper Mysterious Medibot" desc = "International Medibot of mystery." @@ -34,6 +53,9 @@ treatment_tox = "anti_toxin" /mob/living/bot/medbot/handleIdle() + if(is_tipped) // Don't handle idle things if we're incapacitated! + return + if(vocal && prob(1)) var/message_options = list( "Radar, put a mask on!" = 'sound/voice/medbot/mradar.ogg', @@ -47,6 +69,9 @@ playsound(src, message_options[message], 50, 0) /mob/living/bot/medbot/handleAdjacentTarget() + if(is_tipped) // Don't handle targets if we're incapacitated! + return + UnarmedAttack(target) /mob/living/bot/medbot/handlePanic() // Speed modification based on alert level. @@ -76,6 +101,9 @@ return . /mob/living/bot/medbot/lookForTargets() + if(is_tipped) // Don't look for targets if we're incapacitated! + return + for(var/mob/living/carbon/human/H in view(7, src)) // Time to find a patient! if(confirmTarget(H)) target = H @@ -162,7 +190,29 @@ else icon_state = "medibot[on]" -/mob/living/bot/medbot/attack_hand(var/mob/user) +/mob/living/bot/medbot/attack_hand(mob/living/carbon/human/H) + if(H.a_intent == I_DISARM && !is_tipped) + H.visible_message("[H] begins tipping over [src].", "You begin tipping over [src]...") + + if(world.time > last_tipping_action_voice + 15 SECONDS) + last_tipping_action_voice = world.time // message for tipping happens when we start interacting, message for righting comes after finishing + var/list/messagevoice = list("Hey, wait..." = 'sound/voice/medbot/hey_wait.ogg',"Please don't..." = 'sound/voice/medbot/please_dont.ogg',"I trusted you..." = 'sound/voice/medbot/i_trusted_you.ogg', "Nooo..." = 'sound/voice/medbot/nooo.ogg', "Oh fuck-" = 'sound/voice/medbot/oh_fuck.ogg') + var/message = pick(messagevoice) + say(message) + playsound(src, messagevoice[message], 70, FALSE) + + if(do_after(H, 3 SECONDS, target=src)) + tip_over(H) + + else if(H.a_intent == I_HELP && is_tipped) + H.visible_message("[H] begins righting [src].", "You begin righting [src]...") + if(do_after(H, 3 SECONDS, target=src)) + set_right(H) + else + interact(H) + + +/mob/living/bot/medbot/proc/interact(mob/user) var/dat dat += "Automatic Medical Unit v1.0

    " dat += "Status: [on ? "On" : "Off"]
    " @@ -301,6 +351,89 @@ qdel(src) return +/mob/living/bot/medbot/handleRegular() + . = ..() + + if(is_tipped) + handle_panic() + return + +/mob/living/bot/medbot/proc/tip_over(mob/user) + playsound(src, 'sound/machines/warning-buzzer.ogg', 50) + user.visible_message("[user] tips over [src]!", "You tip [src] over!") + is_tipped = TRUE + tipper_name = user.name + var/matrix/mat = transform + transform = mat.Turn(180) + +/mob/living/bot/medbot/proc/set_right(mob/user) + var/list/messagevoice + if(user) + user.visible_message("[user] sets [src] right-side up!", "You set [src] right-side up!") + if(user.name == tipper_name) + messagevoice = list("I forgive you." = 'sound/voice/medbot/forgive.ogg') + else + messagevoice = list("Thank you!" = 'sound/voice/medbot/thank_you.ogg', "You are a good person." = 'sound/voice/medbot/youre_good.ogg') + else + visible_message("[src] manages to [pick("writhe", "wriggle", "wiggle")] enough to right itself.") + messagevoice = list("Fuck you." = 'sound/voice/medbot/fuck_you.ogg', "Your behavior has been reported, have a nice day." = 'sound/voice/medbot/reported.ogg') + + tipper_name = null + if(world.time > last_tipping_action_voice + 15 SECONDS) + last_tipping_action_voice = world.time + var/message = pick(messagevoice) + say(message) + playsound(src, messagevoice[message], 70) + tipped_status = MEDBOT_PANIC_NONE + is_tipped = FALSE + transform = matrix() + +// if someone tipped us over, check whether we should ask for help or just right ourselves eventually +/mob/living/bot/medbot/proc/handle_panic() + tipped_status++ + var/list/messagevoice + switch(tipped_status) + if(MEDBOT_PANIC_LOW) + messagevoice = list("I require assistance." = 'sound/voice/medbot/i_require_asst.ogg') + if(MEDBOT_PANIC_MED) + messagevoice = list("Please put me back." = 'sound/voice/medbot/please_put_me_back.ogg') + if(MEDBOT_PANIC_HIGH) + messagevoice = list("Please, I am scared!" = 'sound/voice/medbot/please_im_scared.ogg') + if(MEDBOT_PANIC_FUCK) + messagevoice = list("I don't like this, I need help!" = 'sound/voice/medbot/dont_like.ogg', "This hurts, my pain is real!" = 'sound/voice/medbot/pain_is_real.ogg') + if(MEDBOT_PANIC_ENDING) + messagevoice = list("Is this the end?" = 'sound/voice/medbot/is_this_the_end.ogg', "Nooo!" = 'sound/voice/medbot/nooo.ogg') + if(MEDBOT_PANIC_END) + global_announcer.autosay("PSYCH ALERT: Crewmember [tipper_name] recorded displaying antisocial tendencies torturing bots in [get_area(src)]. Please schedule psych evaluation.", "[src]", "Medical") + set_right() // strong independent medbot + + // if(prob(tipped_status)) // Commented out pending introduction of jitter stuff from /tg/ + // do_jitter_animation(tipped_status * 0.1) + + if(messagevoice) + var/message = pick(messagevoice) + say(message) + playsound(src, messagevoice[message], 70) + else if(prob(tipped_status * 0.2)) + playsound(src, 'sound/machines/warning-buzzer.ogg', 30, extrarange=-2) + +/mob/living/bot/medbot/examine(mob/user) + . = ..() + if(tipped_status == MEDBOT_PANIC_NONE) + return + + switch(tipped_status) + if(MEDBOT_PANIC_NONE to MEDBOT_PANIC_LOW) + . += "It appears to be tipped over, and is quietly waiting for someone to set it right." + if(MEDBOT_PANIC_LOW to MEDBOT_PANIC_MED) + . += "It is tipped over and requesting help." + if(MEDBOT_PANIC_MED to MEDBOT_PANIC_HIGH) + . += "They are tipped over and appear visibly distressed." // now we humanize the medbot as a they, not an it + if(MEDBOT_PANIC_HIGH to MEDBOT_PANIC_FUCK) + . += "They are tipped over and visibly panicking!" + if(MEDBOT_PANIC_FUCK to INFINITY) + . += "They are freaking out from being tipped over!" + /mob/living/bot/medbot/confirmTarget(var/mob/living/carbon/human/H) if(!..()) return 0 @@ -430,3 +563,12 @@ S.name = created_name user.drop_from_inventory(src) qdel(src) + +// Undefine these. +#undef MEDBOT_PANIC_NONE +#undef MEDBOT_PANIC_LOW +#undef MEDBOT_PANIC_MED +#undef MEDBOT_PANIC_HIGH +#undef MEDBOT_PANIC_FUCK +#undef MEDBOT_PANIC_ENDING +#undef MEDBOT_PANIC_END diff --git a/code/modules/mob/living/bot/mulebot.dm b/code/modules/mob/living/bot/mulebot.dm index 9bef4c0cbc6..67fc8fd0517 100644 --- a/code/modules/mob/living/bot/mulebot.dm +++ b/code/modules/mob/living/bot/mulebot.dm @@ -241,20 +241,20 @@ M.Weaken(5) ..() -/mob/living/bot/mulebot/proc/runOver(var/mob/living/carbon/human/H) - if(istype(H)) // No safety checks - WILL run over lying humans. Stop ERPing in the maint! - visible_message("[src] drives over [H]!") +/mob/living/bot/mulebot/proc/runOver(var/mob/living/M) + if(istype(M)) // At this point, MULEBot has somehow crossed over onto your tile with you still on it. CRRRNCH. + visible_message("[src] drives over [M]!") playsound(src, 'sound/effects/splat.ogg', 50, 1) var/damage = rand(5, 7) - H.apply_damage(2 * damage, BRUTE, BP_HEAD) - H.apply_damage(2 * damage, BRUTE, BP_TORSO) - H.apply_damage(0.5 * damage, BRUTE, BP_L_LEG) - H.apply_damage(0.5 * damage, BRUTE, BP_R_LEG) - H.apply_damage(0.5 * damage, BRUTE, BP_L_ARM) - H.apply_damage(0.5 * damage, BRUTE, BP_R_ARM) + M.apply_damage(2 * damage, BRUTE, BP_HEAD) + M.apply_damage(2 * damage, BRUTE, BP_TORSO) + M.apply_damage(0.5 * damage, BRUTE, BP_L_LEG) + M.apply_damage(0.5 * damage, BRUTE, BP_R_LEG) + M.apply_damage(0.5 * damage, BRUTE, BP_L_ARM) + M.apply_damage(0.5 * damage, BRUTE, BP_R_ARM) - blood_splatter(src, H, 1) + blood_splatter(src, M, 1) ..() /mob/living/bot/mulebot/relaymove(var/mob/user, var/direction) diff --git a/code/modules/mob/living/bot/mulebot_vr.dm b/code/modules/mob/living/bot/mulebot_vr.dm new file mode 100644 index 00000000000..aec8f309838 --- /dev/null +++ b/code/modules/mob/living/bot/mulebot_vr.dm @@ -0,0 +1,5 @@ +/mob/living/bot/mulebot/handle_micro_bump_helping() // Can't drive over micros or macros regardless of intent. + return 0 + +/mob/living/bot/mulebot/handle_micro_bump_other() // Can't drive over micros or macros regardless of intent. + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm index 370ec774222..43bcdde4996 100644 --- a/code/modules/mob/living/carbon/alien/life.dm +++ b/code/modules/mob/living/carbon/alien/life.dm @@ -59,7 +59,7 @@ adjustHalLoss(-3) if (mind) if(mind.active && client != null) - sleeping = max(sleeping-1, 0) + AdjustSleeping(-1) blinded = 1 set_stat(UNCONSCIOUS) else if(resting) diff --git a/code/modules/mob/living/carbon/brain/login.dm b/code/modules/mob/living/carbon/brain/login.dm index e90297dfe5b..107b8e0ab78 100644 --- a/code/modules/mob/living/carbon/brain/login.dm +++ b/code/modules/mob/living/carbon/brain/login.dm @@ -1,3 +1,3 @@ /mob/living/carbon/brain/Login() ..() - sleeping = 0 \ No newline at end of file + SetSleeping(0) \ 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 dde3927a596..fa55f0c087a 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -136,7 +136,7 @@ to_chat(src, "Oh god, everything's spinning!") Confuse(max(0,confuse_dur)) if(species.emp_sensitivity & EMP_WEAKEN) - if(weaken_dur >= 1) + if(weaken_dur >= 1) to_chat(src, "Your limbs go slack!") Weaken(max(0,weaken_dur)) //physical damage block, deals (minor-4) 5-15, 10-20, 15-25, 20-30 (extreme-1) of *each* type @@ -287,7 +287,7 @@ M.visible_message("[M] shakes [src] trying to wake [T.him] up!", \ "You shake [src], but [T.he] [T.does] not respond... Maybe [T.he] [T.has] S.S.D?") else if(lying || src.sleeping) - src.sleeping = max(0,src.sleeping-5) + AdjustSleeping(-5) if(src.sleeping == 0) src.resting = 0 if(H) H.in_stasis = 0 //VOREStation Add - Just In Case @@ -403,7 +403,7 @@ to_chat(usr, "You are already sleeping") return if(alert(src,"You sure you want to sleep for a while?","Sleep","Yes","No") == "Yes") - usr.sleeping = 20 //Short nap + usr.AdjustSleeping(20) /mob/living/carbon/Bump(atom/A) if(now_pushing) diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 57206c05e2b..b1424ae5b04 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -1,7 +1,12 @@ -/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list(), var/datum/topic_state/state = default_state) - var/datum/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist) +/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, + var/mob/user = src, + var/check_species_whitelist = 1, + var/list/species_whitelist = list(), + var/list/species_blacklist = list(), + var/datum/tgui_state/state = GLOB.tgui_self_state) + var/datum/tgui_module/appearance_changer/AC = new(src, src, check_species_whitelist, species_whitelist, species_blacklist) AC.flags = flags - AC.ui_interact(user, state = state) + AC.tgui_interact(user, custom_state = state) /mob/living/carbon/human/proc/change_species(var/new_species) if(!new_species) @@ -48,6 +53,21 @@ update_hair() return 1 + +/mob/living/carbon/human/proc/change_hair_gradient(var/hair_gradient) + if(!hair_gradient) + return + + if(grad_style == hair_gradient) + return + + if(!(hair_gradient in GLOB.hair_gradients)) + return + + grad_style = hair_gradient + + update_hair() + return 1 /mob/living/carbon/human/proc/change_facial_hair(var/facial_hair_style) if(!facial_hair_style) @@ -104,6 +124,17 @@ update_hair() return 1 + +/mob/living/carbon/human/proc/change_grad_color(var/red, var/green, var/blue) + if(red == r_grad && green == g_grad && blue == b_grad) + return + + r_grad = red + g_grad = green + b_grad = blue + + update_hair() + return 1 /mob/living/carbon/human/proc/change_facial_hair_color(var/red, var/green, var/blue) if(red == r_facial && green == g_facial && blue == b_facial) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 5660b714235..762371b192b 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -240,7 +240,7 @@ message = "faints." if(sleeping) return //Can't faint while asleep - sleeping += 10 //Short-short nap + Sleeping(10) m_type = 1 if("cough", "coughs") diff --git a/code/modules/mob/living/carbon/human/emote_vr.dm b/code/modules/mob/living/carbon/human/emote_vr.dm index 7df6e169fa8..2be90ec8dce 100644 --- a/code/modules/mob/living/carbon/human/emote_vr.dm +++ b/code/modules/mob/living/carbon/human/emote_vr.dm @@ -40,11 +40,11 @@ playsound(src, 'sound/voice/growl.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) if("woof") m_type = 2 - message = "lets out an woof." + message = "lets out a woof." playsound(src, 'sound/voice/woof.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) if("woof2") m_type = 2 - message = "lets out an woof." + message = "lets out a woof." playsound(src, 'sound/voice/woof2.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) if("nya") message = "lets out a nya." @@ -146,6 +146,14 @@ message = "rumbles their throat, puffs their cheeks and croaks." m_type = 2 playsound(src, 'sound/voice/Croak.ogg', 50, 0, preference = /datum/client_preference/emote_noises) + if("gao") + message = "lets out a gao." + m_type = 2 + playsound(src, 'sound/voice/gao.ogg', 50, 0, preference = /datum/client_preference/emote_noises) + if("cackle") + message = "cackles hysterically!" + m_type = 2 + playsound(src, 'sound/voice/YeenCackle.ogg', 50, 0, preference = /datum/client_preference/emote_noises) if("nsay") nsay() return TRUE @@ -164,7 +172,7 @@ message = "does a flip!" m_type = 1 if("vhelp") //Help for Virgo-specific emotes. - to_chat(src, "vwag, vflap, mlem, blep, awoo, awoo2, growl, nya, peep, chirp, hoot, weh, merp, myarp, bark, bork, mrow, hypno, hiss, rattle, squeak, geck, baa, baa2, mar, wurble, snort, meow, moo, croak, nsay, nme, flip") + to_chat(src, "vwag, vflap, mlem, blep, awoo, awoo2, growl, nya, peep, chirp, hoot, weh, merp, myarp, bark, bork, mrow, mrowl, hypno, hiss, rattle, squeak, geck, baa, baa2, mar, wurble, snort, meow, moo, croak, gao, cackle, nsay, nme, flip") return TRUE if(message) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index eb95bdebbc1..6510f049dde 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -253,20 +253,14 @@ return // called when something steps onto a human -// this handles mulebots and vehicles -// and now mobs on fire +// this handles mobs on fire - mulebot and vehicle code has been relocated to /mob/living/Crossed() /mob/living/carbon/human/Crossed(var/atom/movable/AM) if(AM.is_incorporeal()) return - if(istype(AM, /mob/living/bot/mulebot)) - var/mob/living/bot/mulebot/MB = AM - MB.runOver(src) - - if(istype(AM, /obj/vehicle)) - var/obj/vehicle/V = AM - V.RunOver(src) spread_fire(AM) + + ..() // call parent because we moved behavior to parent // Get rank from ID, ID inside PDA, PDA, ID in wallet, etc. /mob/living/carbon/human/proc/get_authentification_rank(var/if_no_id = "No id", var/if_no_job = "No job") @@ -1676,8 +1670,8 @@ if(species?.flags & NO_BLOOD) bloodtrail = 0 else - var/blood_volume = round((vessel.get_reagent_amount("blood")/species.blood_volume)*100) - if(blood_volume < BLOOD_VOLUME_SURVIVE) + var/blood_volume = vessel.get_reagent_amount("blood") + if(blood_volume < species?.blood_volume*species?.blood_level_fatal) bloodtrail = 0 //Most of it's gone already, just leave it be else vessel.remove_reagent("blood", 1) @@ -1687,6 +1681,26 @@ T.add_blood(src) . = ..() +// Tries to turn off item-based things that let you see through walls, like mesons. +// Certain stuff like genetic xray vision is allowed to be kept on. +/mob/living/carbon/human/disable_spoiler_vision() + // Glasses. + if(istype(glasses, /obj/item/clothing/glasses)) + var/obj/item/clothing/glasses/goggles = glasses + if(goggles.active && (goggles.vision_flags & (SEE_TURFS|SEE_OBJS))) + goggles.toggle_active(src) + to_chat(src, span("warning", "Your [goggles.name] have suddenly turned off!")) + + // RIGs. + var/obj/item/weapon/rig/rig = get_rig() + if(istype(rig) && rig.visor?.active && rig.visor.vision?.glasses) + var/obj/item/clothing/glasses/rig_goggles = rig.visor.vision.glasses + if(rig_goggles.vision_flags & (SEE_TURFS|SEE_OBJS)) + rig.visor.deactivate() + to_chat(src, span("warning", "\The [rig]'s visor has shuddenly deactivated!")) + + ..() + /mob/living/carbon/human/reduce_cuff_time() if(istype(gloves, /obj/item/clothing/gloves/gauntlets/rig)) return 2 diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 9388240af64..b8343ad6942 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -288,6 +288,20 @@ oxyloss = 0 else ..() + +/mob/living/carbon/human/adjustHalLoss(var/amount) + if(species.flags & NO_PAIN) + halloss = 0 + else + if(amount > 0) //only multiply it by the mod if it's positive, or else it takes longer to fade too! + amount = amount*species.pain_mod + ..(amount) + +/mob/living/carbon/human/setHalLoss(var/amount) + if(species.flags & NO_PAIN) + halloss = 0 + else + ..() /mob/living/carbon/human/getToxLoss() if(species.flags & NO_POISON) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 8e351372c9f..0199d387ae5 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -133,6 +133,12 @@ emp_act if(istype(C) && (C.body_parts_covered & def_zone.body_part)) // Is that body part being targeted covered? siemens_coefficient *= C.siemens_coefficient + // Modifiers. + for(var/thing in modifiers) + var/datum/modifier/M = thing + if(!isnull(M.siemens_coefficient)) + siemens_coefficient *= M.siemens_coefficient + return siemens_coefficient // Similar to above but is for the mob's overall protection, being the average of all slots. @@ -150,11 +156,11 @@ emp_act if(fire_stacks < 0) // Water makes you more conductive. siemens_value *= 1.5 - return (siemens_value/max(total, 1)) + return (siemens_value / max(total, 1)) // Returns a number between 0 to 1, with 1 being total protection. /mob/living/carbon/human/get_shock_protection() - return between(0, 1-get_siemens_coefficient_average(), 1) + return min(1 - get_siemens_coefficient_average(), 1) // Don't go above 1, but negatives are fine. // Returns a list of clothing that is currently covering def_zone. /mob/living/carbon/human/proc/get_clothing_list_organ(var/obj/item/organ/external/def_zone, var/type) @@ -173,6 +179,13 @@ emp_act var/list/protective_gear = def_zone.get_covering_clothing() for(var/obj/item/clothing/gear in protective_gear) protection += gear.armor[type] + + for(var/thing in modifiers) + var/datum/modifier/M = thing + var/modifier_armor = LAZYACCESS(M.armor_percent, type) + if(modifier_armor) + protection += modifier_armor + return protection /mob/living/carbon/human/proc/getsoak_organ(var/obj/item/organ/external/def_zone, var/type) @@ -182,6 +195,13 @@ emp_act var/list/protective_gear = def_zone.get_covering_clothing() for(var/obj/item/clothing/gear in protective_gear) soaked += gear.armorsoak[type] + + for(var/thing in modifiers) + var/datum/modifier/M = thing + var/modifier_armor = LAZYACCESS(M.armor_flat, type) + if(modifier_armor) + soaked += modifier_armor + return soaked // Checked in borer code diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index b8ab7943036..479874b1854 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -688,10 +688,13 @@ if(bodytemperature >= species.heat_level_2) if(bodytemperature >= species.heat_level_3) burn_dam = HEAT_DAMAGE_LEVEL_3 + throw_alert("temp", /obj/screen/alert/hot, 3) else burn_dam = HEAT_DAMAGE_LEVEL_2 + throw_alert("temp", /obj/screen/alert/hot, 2) else burn_dam = HEAT_DAMAGE_LEVEL_1 + throw_alert("temp", /obj/screen/alert/hot, 1) take_overall_damage(burn=burn_dam, used_weapon = "High Body Temperature") @@ -715,6 +718,8 @@ take_overall_damage(burn=cold_dam, used_weapon = "Low Body Temperature") + else clear_alert("temp") + // Account for massive pressure differences. Done by Polymorph // Made it possible to actually have something that can protect against high pressure... Done by Errorage. Polymorph now has an axe sticking from his head for his previous hardcoded nonsense! if(status_flags & GODMODE) @@ -831,7 +836,19 @@ /mob/living/carbon/human/get_heat_protection(temperature) //Temperature is the temperature you're being exposed to. var/thermal_protection_flags = get_heat_protection_flags(temperature) - return get_thermal_protection(thermal_protection_flags) + + . = get_thermal_protection(thermal_protection_flags) + . = 1 - . // Invert from 1 = immunity to 0 = immunity. + + // Doing it this way makes multiplicative stacking not get out of hand, so two modifiers that give 0.5 protection will be combined to 0.75 in the end. + for(var/thing in modifiers) + var/datum/modifier/M = thing + if(!isnull(M.heat_protection)) + . *= 1 - M.heat_protection + + // Code that calls this expects 1 = immunity so we need to invert again. + . = 1 - . + . = min(., 1.0) /mob/living/carbon/human/get_cold_protection(temperature) if(COLD_RESISTANCE in mutations) @@ -839,7 +856,20 @@ temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K. var/thermal_protection_flags = get_cold_protection_flags(temperature) - return get_thermal_protection(thermal_protection_flags) + + . = get_thermal_protection(thermal_protection_flags) + . = 1 - . // Invert from 1 = immunity to 0 = immunity. + + // Doing it this way makes multiplicative stacking not get out of hand, so two modifiers that give 0.5 protection will be combined to 0.75 in the end. + for(var/thing in modifiers) + var/datum/modifier/M = thing + if(!isnull(M.cold_protection)) + // Invert the modifier values so they align with the current working value. + . *= 1 - M.cold_protection + + // Code that calls this expects 1 = immunity so we need to invert again. + . = 1 - . + . = min(., 1.0) /mob/living/carbon/human/proc/get_thermal_protection(var/flags) .=0 @@ -1098,7 +1128,7 @@ drowsyness = max(0, drowsyness - 1) eye_blurry = max(2, eye_blurry) if (prob(5)) - sleeping += 1 + Sleeping(1) Paralyse(5) // If you're dirty, your gloves will become dirty, too. @@ -1253,7 +1283,14 @@ if(blinded) overlay_fullscreen("blind", /obj/screen/fullscreen/blind) throw_alert("blind", /obj/screen/alert/blind) - + + else + clear_fullscreens() + clear_alert("blind") + + if(blinded) + overlay_fullscreen("blind", /obj/screen/fullscreen/blind) + else if(!machine) clear_fullscreens() clear_alert("blind") @@ -1316,6 +1353,11 @@ sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS) see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : see_invisible_default + // Do this early so certain stuff gets turned off before vision is assigned. + var/area/A = get_area(src) + if(A?.no_spoilers) + disable_spoiler_vision() + if(XRAY in mutations) sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS see_in_dark = 8 @@ -1586,7 +1628,7 @@ if(Pump) temp += Pump.standard_pulse_level - PULSE_NORM - if(round(vessel.get_reagent_amount("blood")) <= BLOOD_VOLUME_BAD) //how much blood do we have + if(round(vessel.get_reagent_amount("blood")) <= species.blood_volume*species.blood_level_danger) //how much blood do we have temp = temp + 3 //not enough :( if(status_flags & FAKEDEATH) diff --git a/code/modules/mob/living/carbon/human/npcs.dm b/code/modules/mob/living/carbon/human/npcs.dm index 3c0609f99be..23f7bd722ac 100644 --- a/code/modules/mob/living/carbon/human/npcs.dm +++ b/code/modules/mob/living/carbon/human/npcs.dm @@ -3,6 +3,7 @@ desc = "It looks like it was tailored for a monkey." icon_state = "punpun" worn_state = "punpun" + has_sensor = 0 species_restricted = list("Monkey") /mob/living/carbon/human/monkey/punpun/Initialize() diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox_vr.dm b/code/modules/mob/living/carbon/human/species/outsider/vox_vr.dm index 422c95be929..d4a96209dd9 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/vox_vr.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/vox_vr.dm @@ -1,3 +1,4 @@ /datum/species/vox default_language = LANGUAGE_GALCOM + secondary_langs = list(LANGUAGE_VOX) speech_sounds = list() // Remove obnoxious noises on every single 'say'. Should really only be a thing for event-exclusive species like benos. \ 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 c9eb8216d1a..237428e24b1 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -43,6 +43,10 @@ var/short_sighted // Permanent weldervision. var/blood_volume = 560 // Initial blood volume. var/bloodloss_rate = 1 // Multiplier for how fast a species bleeds out. Higher = Faster + var/blood_level_safe = 0.85 //"Safe" blood level; above this, you're OK + var/blood_level_warning = 0.75 //"Warning" blood level; above this, you're a bit woozy and will have low-level oxydamage (no more than 20, or 15 with inap) + var/blood_level_danger = 0.6 //"Danger" blood level; above this, you'll rapidly take up to 50 oxyloss, and it will then steadily accumulate at a lower rate + var/blood_level_fatal = 0.4 //"Fatal" blood level; below this, you take extremely high oxydamage var/hunger_factor = 0.05 // Multiplier for hunger. var/active_regen_mult = 1 // Multiplier for 'Regenerate' power speed, in human_powers.dm @@ -95,6 +99,7 @@ var/chemOD_threshold = 1 // Multiplier to overdose threshold; lower = easier overdosing var/chemOD_mod = 1 // Damage modifier for overdose; higher = more damage from ODs var/alcohol_mod = 1 // Multiplier to alcohol strength; 0.5 = half, 0 = no effect at all, 2 = double, etc. + var/pain_mod = 1 // Multiplier to pain effects; 0.5 = half, 0 = no effect (equal to NO_PAIN, really), 2 = double, etc. // set below is EMP interactivity for nonsynth carbons var/emp_sensitivity = 0 // bitflag. valid flags are: EMP_PAIN, EMP_BLIND, EMP_DEAFEN, EMP_CONFUSE, EMP_STUN, and EMP_(BRUTE/BURN/TOX/OXY)_DMG var/emp_dmg_mod = 1 // Multiplier to all EMP damage sustained by the mob, if it's EMP-sensitive diff --git a/code/modules/mob/living/carbon/human/species/species_shapeshift.dm b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm index 6629a96a9f1..bc39e163106 100644 --- a/code/modules/mob/living/carbon/human/species/species_shapeshift.dm +++ b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm @@ -88,6 +88,7 @@ var/list/wrapped_species_by_ref = list() var/list/valid_hairstyles = list() var/list/valid_facialhairstyles = list() + var/list/valid_gradstyles = GLOB.hair_gradients for(var/hairstyle in hair_styles_list) var/datum/sprite_accessory/S = hair_styles_list[hairstyle] if(gender == MALE && S.gender == FEMALE) @@ -112,6 +113,9 @@ var/list/wrapped_species_by_ref = list() if(valid_hairstyles.len) var/new_hair = input("Select a hairstyle.", "Shapeshifter Hair") as null|anything in valid_hairstyles change_hair(new_hair ? new_hair : "Bald") + if(valid_gradstyles.len) + var/new_hair = input("Select a hair gradient style.", "Shapeshifter Hair") as null|anything in valid_gradstyles + change_hair_gradient(new_hair ? new_hair : "None") if(valid_facialhairstyles.len) var/new_hair = input("Select a facial hair style.", "Shapeshifter Hair") as null|anything in valid_facialhairstyles change_facial_hair(new_hair ? new_hair : "Shaved") @@ -216,6 +220,10 @@ var/list/wrapped_species_by_ref = list() if(!new_hair) return shapeshifter_set_hair_color(new_hair) + var/new_grad = input("Please select a new hair gradient color.", "Hair Gradient Colour") as color + if(!new_grad) + return + shapeshifter_set_grad_color(new_grad) var/new_fhair = input("Please select a new facial hair color.", "Facial Hair Color") as color if(!new_fhair) return @@ -225,6 +233,10 @@ var/list/wrapped_species_by_ref = list() change_hair_color(hex2num(copytext(new_hair, 2, 4)), hex2num(copytext(new_hair, 4, 6)), hex2num(copytext(new_hair, 6, 8))) +/mob/living/carbon/human/proc/shapeshifter_set_grad_color(var/new_grad) + + change_grad_color(hex2num(copytext(new_grad, 2, 4)), hex2num(copytext(new_grad, 4, 6)), hex2num(copytext(new_grad, 6, 8))) + /mob/living/carbon/human/proc/shapeshifter_set_facial_color(var/new_fhair) change_facial_hair_color(hex2num(copytext(new_fhair, 2, 4)), hex2num(copytext(new_fhair, 4, 6)), hex2num(copytext(new_fhair, 6, 8))) diff --git a/code/modules/mob/living/carbon/human/species/station/alraune.dm b/code/modules/mob/living/carbon/human/species/station/alraune.dm index 8a0d93243a2..b8dc646517f 100644 --- a/code/modules/mob/living/carbon/human/species/station/alraune.dm +++ b/code/modules/mob/living/carbon/human/species/station/alraune.dm @@ -58,6 +58,8 @@ flesh_color = "#9ee02c" blood_color = "#edf4d0" //sap! base_color = "#1a5600" + + reagent_tag = IS_ALRAUNE blurb = "Alraunes are a rare sight in space. Their bodies are reminiscent of that of plants, and yet they share many\ traits with other humanoid beings.\ diff --git a/code/modules/mob/living/carbon/human/species/station/blank_vr.dm b/code/modules/mob/living/carbon/human/species/station/blank_vr.dm index 2c70bef929b..6fd2e5db2db 100644 --- a/code/modules/mob/living/carbon/human/species/station/blank_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/blank_vr.dm @@ -93,6 +93,8 @@ //Set up a mob H.species = new_copy + H.maxHealth = new_copy.total_health + H.hunger_rate = new_copy.hunger_factor if(new_copy.holder_type) H.holder_type = new_copy.holder_type diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm index 6c33b9c300f..282f8b6c3d1 100644 --- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm +++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm @@ -298,6 +298,12 @@ return ..() +var/global/list/disallowed_protean_accessories = list( + /obj/item/clothing/accessory/holster, + /obj/item/clothing/accessory/storage, + /obj/item/clothing/accessory/armor + ) + // Helpers - Unsafe, WILL perform change. /mob/living/carbon/human/proc/nano_intoblob() var/panel_was_up = FALSE @@ -343,7 +349,8 @@ var/obj/item/clothing/uniform = w_uniform if(LAZYLEN(uniform.accessories)) for(var/obj/item/clothing/accessory/A in uniform.accessories) - uniform.remove_accessory(null,A) //First param is user, but adds fingerprints and messages + if(is_type_in_list(A, disallowed_protean_accessories)) + uniform.remove_accessory(null,A) //First param is user, but adds fingerprints and messages //Size update blob.transform = matrix()*size_multiplier diff --git a/code/modules/mob/living/carbon/human/species/station/seromi.dm b/code/modules/mob/living/carbon/human/species/station/seromi.dm index 01e94f89544..039d2e39785 100644 --- a/code/modules/mob/living/carbon/human/species/station/seromi.dm +++ b/code/modules/mob/living/carbon/human/species/station/seromi.dm @@ -84,8 +84,16 @@ heat_discomfort_strings = list( "Your feathers prickle in the heat.", "You feel uncomfortably warm.", + "Your hands and feet feel hot as your body tries to regulate heat", ) cold_discomfort_level = 180 + cold_discomfort_strings = list( + "You feel a bit chilly.", + "You fluff up your feathers against the cold.", + "You move your arms closer to your body to shield yourself from the cold.", + "You press your ears against your head to conserve heat", + "You start to feel the cold on your skin", + ) minimum_breath_pressure = 12 //Smaller, so needs less air diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm index 402c1928ddd..8b6cfd0b602 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/negative.dm @@ -133,3 +133,4 @@ /datum/trait/colorblind/para_taj/apply(var/datum/species/S,var/mob/living/carbon/human/H) ..(S,H) H.add_modifier(/datum/modifier/trait/colorblind_taj) + \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm index 958cdd25489..a16a72c6c20 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm @@ -19,19 +19,19 @@ var_changes = list("metabolic_rate" = 1.4, "hunger_factor" = 0.4, "metabolism" = 0.012) // +40% rate and 8x hunger (Double Teshari) excludes = list(/datum/trait/metabolism_up, /datum/trait/metabolism_down) -/datum/trait/cold_discomfort - name = "Hot-Blooded" - desc = "You are too hot at the standard 20C. 18C is more suitable. Rolling down your jumpsuit or being unclothed helps." +/datum/trait/coldadapt + name = "Cold-Adapted" + desc = "You are able to withstand much colder temperatures than other species, and can even be comfortable in extremely cold environments. You are also more vulnerable to hot environments, and have a lower body temperature as a consequence of these adaptations." cost = 0 - var_changes = list("heat_discomfort_level" = T0C+19) - excludes = list(/datum/trait/hot_discomfort) - -/datum/trait/hot_discomfort - name = "Cold-Blooded" - desc = "You are too cold at the standard 20C. 22C is more suitable. Wearing clothing that covers your legs and torso helps." + var_changes = list("cold_level_1" = 200, "cold_level_2" = 150, "cold_level_3" = 90, "breath_cold_level_1" = 180, "breath_cold_level_2" = 100, "breath_cold_level_3" = 60, "cold_discomfort_level" = 210, "heat_level_1" = 305, "heat_level_2" = 360, "heat_level_3" = 700, "breath_heat_level_1" = 345, "breath_heat_level_2" = 380, "breath_heat_level_3" = 780, "heat_discomfort_level" = 295, "body_temperature" = 290) + excludes = list(/datum/trait/hotadapt) + +/datum/trait/hotadapt + name = "Heat-Adapted" + desc = "You are able to withstand much hotter temperatures than other species, and can even be comfortable in extremely hot environments. You are also more vulnerable to cold environments, and have a higher body temperature as a consequence of these adaptations." cost = 0 - var_changes = list("cold_discomfort_level" = T0C+21) - excludes = list(/datum/trait/cold_discomfort) + var_changes = list("heat_level_1" = 420, "heat_level_2" = 460, "heat_level_3" = 1100, "breath_heat_level_1" = 440, "breath_heat_level_2" = 510, "breath_heat_level_3" = 1500, "heat_discomfort_level" = 390, "cold_level_1" = 280, "cold_level_2" = 220, "cold_level_3" = 140, "breath_cold_level_1" = 260, "breath_cold_level_2" = 240, "breath_cold_level_3" = 120, "cold_discomfort_level" = 280, "body_temperature" = 330) + excludes = list(/datum/trait/coldadapt) /datum/trait/autohiss_unathi name = "Autohiss (Unathi)" @@ -80,6 +80,15 @@ H.verbs |= /mob/living/carbon/human/proc/succubus_drain_finalize H.verbs |= /mob/living/carbon/human/proc/succubus_drain_lethal +/datum/trait/feeder + name = "Feeder" + desc = "Allows you to feed your prey using your own body." + cost = 0 + +/datum/trait/feeder/apply(var/datum/species/S,var/mob/living/carbon/human/H) + ..(S,H) + H.verbs |= /mob/living/carbon/human/proc/slime_feed + /datum/trait/hard_vore name = "Brutal Predation" desc = "Allows you to tear off limbs & tear out internal organs." @@ -123,3 +132,41 @@ ..(S,H) H.verbs |= /mob/living/proc/glow_toggle H.verbs |= /mob/living/proc/glow_color + +// Alcohol Traits Start Here, from negative to positive. +/datum/trait/alcohol_intolerance_advanced + name = "Liver of Air" + desc = "The only way you can hold a drink is if it's in your own two hands, and even then you'd best not inhale too deeply near it. Drinks are three times as strong." + cost = 0 + var_changes = list("alcohol_mod" = 3) // 300% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this! + +/datum/trait/alcohol_intolerance_basic + name = "Liver of Lilies" + desc = "You have a hard time with alcohol. Maybe you just never took to it, or maybe it doesn't agree with you... either way, drinks are twice as strong." + cost = 0 + var_changes = list("alcohol_mod" = 2) // 200% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this! + +/datum/trait/alcohol_intolerance_slight + name = "Liver of Tulips" + desc = "You have a slight struggle with alcohol. Drinks are one and a half times stronger." + cost = 0 + var_changes = list("alcohol_mod" = 1.5) // 150% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this! + +/datum/trait/alcohol_tolerance_basic + name = "Liver of Iron" + desc = "You can hold drinks much better than those lily-livered land-lubbers! Arr! Drinks are only three-quarters as strong." + cost = 0 + var_changes = list("alcohol_mod" = 0.75) // 75% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this! + +/datum/trait/alcohol_tolerance_advanced + name = "Liver of Steel" + desc = "Drinks tremble before your might! You can hold your alcohol twice as well as those blue-bellied barnacle boilers! Drinks are only half as strong." + cost = 0 + var_changes = list("alcohol_mod" = 0.5) // 50% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this! + +/datum/trait/alcohol_immunity + name = "Liver of Durasteel" + desc = "You've drunk so much that most booze doesn't even faze you. It takes something like a Pan-Galactic or a pint of Deathbell for you to even get slightly buzzed." + cost = 0 + var_changes = list("alcohol_mod" = 0.25) // 25% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this! +// Alcohol Traits End Here. \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm index 3a1e50dee67..148f151e591 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/positive.dm @@ -123,4 +123,10 @@ name = "Traceur" desc = "You're capable of parkour and can *flip over low objects (most of the time)." cost = 2 - var_changes = list("agility" = 90) \ No newline at end of file + var_changes = list("agility" = 90) + +/datum/trait/snowwalker + name = "Snow Walker" + desc = "You are able to move unhindered on snow." + cost = 1 + var_changes = list("snow_movement" = -2) \ No newline at end of file diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 809b82af54c..b33a5d39457 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -10,6 +10,11 @@ if(istype(nest, /obj/structure/blob/factory)) var/obj/structure/blob/factory/F = nest F.spores -= src + //VOREStation Edit Start + if(istype(nest, /obj/structure/mob_spawner)) + var/obj/structure/mob_spawner/S = nest + S.get_death_report(src) + //VOREStation Edit End nest = null for(var/s in owned_soul_links) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 1076c1fc945..063b4fe1880 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -45,7 +45,10 @@ //Check if we're on fire handle_fire() - + + if(client && !(client.prefs.ambience_freq == 0)) // Handle re-running ambience to mobs if they've remained in an area, AND have an active client assigned to them, and do not have repeating ambience disabled. + handle_ambience() + //stuff in the stomach //handle_stomach() //VOREStation Code @@ -89,6 +92,13 @@ /mob/living/proc/handle_stomach() return +/mob/living/proc/handle_ambience() // If you're in an ambient area and have not moved out of it for x time as configured per-client, and do not have it disabled, we're going to play ambience again to you, to help break up the silence. + if(world.time >= (lastareachange + client.prefs.ambience_freq MINUTES)) // Every 5 minutes (by default, set per-client), we're going to run a 35% chance (by default, also set per-client) to play ambience. + var/area/A = get_area(src) + if(A) + lastareachange = world.time // This will refresh the last area change to prevent this call happening LITERALLY every life tick. + A.play_ambience(src, initial = FALSE) + /mob/living/proc/update_pulling() if(pulling) if(incapacitated()) @@ -126,7 +136,7 @@ /mob/living/proc/handle_weakened() if(weakened) - weakened = max(weakened-1,0) + AdjustWeakened(-1) throw_alert("weakened", /obj/screen/alert/weakened) else clear_alert("weakened") @@ -181,7 +191,7 @@ throw_alert("blind", /obj/screen/alert/blind) else clear_alert("blind") - + if(eye_blurry) //blurry eyes heal slowly eye_blurry = max(eye_blurry-1, 0) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 08d7a7ae8c8..a472366b03e 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -244,6 +244,19 @@ default behaviour is: return TRUE return ..() +// Called when something steps onto us. This allows for mulebots and vehicles to run things over. <3 +/mob/living/Crossed(var/atom/movable/AM) // Transplanting this from /mob/living/carbon/human/Crossed() + if(AM == src || AM.is_incorporeal()) // We're not going to run over ourselves or ghosts + return + + if(istype(AM, /mob/living/bot/mulebot)) + var/mob/living/bot/mulebot/MB = AM + MB.runOver(src) + + if(istype(AM, /obj/vehicle)) + var/obj/vehicle/V = AM + V.RunOver(src) + /mob/living/verb/succumb() set hidden = 1 if ((src.health < 0 && src.health > (5-src.getMaxHealth()))) // Health below Zero but above 5-away-from-death, as before, but variable @@ -491,6 +504,15 @@ default behaviour is: if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(stunned > 0) + add_status_indicator("stunned") + +/mob/living/SetStunned(amount) + ..() + if(stunned <= 0) + remove_status_indicator("stunned") + else + add_status_indicator("stunned") /mob/living/AdjustStunned(amount) if(amount > 0) @@ -498,12 +520,25 @@ default behaviour is: if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(stunned <= 0) + remove_status_indicator("stunned") + else + add_status_indicator("stunned") /mob/living/Weaken(amount) for(var/datum/modifier/M in modifiers) if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(weakened > 0) + add_status_indicator("weakened") + +/mob/living/SetWeakened(amount) + ..() + if(weakened <= 0) + remove_status_indicator("weakened") + else + add_status_indicator("weakened") /mob/living/AdjustWeakened(amount) if(amount > 0) @@ -511,12 +546,25 @@ default behaviour is: if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(weakened <= 0) + remove_status_indicator("weakened") + else + add_status_indicator("weakened") /mob/living/Paralyse(amount) for(var/datum/modifier/M in modifiers) if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(paralysis > 0) + add_status_indicator("paralysis") + +/mob/living/SetParalysis(amount) + ..() + if(paralysis <= 0) + remove_status_indicator("paralysis") + else + add_status_indicator("paralysis") /mob/living/AdjustParalysis(amount) if(amount > 0) @@ -524,12 +572,25 @@ default behaviour is: if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(paralysis <= 0) + remove_status_indicator("paralysis") + else + add_status_indicator("paralysis") /mob/living/Sleeping(amount) for(var/datum/modifier/M in modifiers) if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(sleeping > 0) + add_status_indicator("sleeping") + +/mob/living/SetSleeping(amount) + ..() + if(sleeping <= 0) + remove_status_indicator("sleeping") + else + add_status_indicator("sleeping") /mob/living/AdjustSleeping(amount) if(amount > 0) @@ -537,12 +598,25 @@ default behaviour is: if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(sleeping <= 0) + remove_status_indicator("sleeping") + else + add_status_indicator("sleeping") /mob/living/Confuse(amount) for(var/datum/modifier/M in modifiers) if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(confused > 0) + add_status_indicator("confused") + +/mob/living/SetConfused(amount) + ..() + if(confused <= 0) + remove_status_indicator("confused") + else + add_status_indicator("confused") /mob/living/AdjustConfused(amount) if(amount > 0) @@ -550,12 +624,25 @@ default behaviour is: if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(confused <= 0) + remove_status_indicator("confused") + else + add_status_indicator("confused") /mob/living/Blind(amount) for(var/datum/modifier/M in modifiers) if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(eye_blind > 0) + add_status_indicator("blinded") + +/mob/living/SetBlinded(amount) + ..() + if(eye_blind <= 0) + remove_status_indicator("blinded") + else + add_status_indicator("blinded") /mob/living/AdjustBlinded(amount) if(amount > 0) @@ -563,6 +650,10 @@ default behaviour is: if(!isnull(M.disable_duration_percent)) amount = round(amount * M.disable_duration_percent) ..(amount) + if(eye_blind <= 0) + remove_status_indicator("blinded") + else + add_status_indicator("blinded") // ++++ROCKDTBEN++++ MOB PROCS //END @@ -827,10 +918,10 @@ default behaviour is: if(pulling) // we were pulling a thing and didn't lose it during our move. var/pull_dir = get_dir(src, pulling) - + if(pulling.anchored || !isturf(pulling.loc)) stop_pulling() - + else if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) // puller and pullee more than one tile away or in diagonal position // If it is too far away or across z-levels from old location, stop pulling. if(get_dist(pulling.loc, oldloc) > 1 || pulling.loc.z != oldloc?.z) @@ -846,7 +937,7 @@ default behaviour is: stop_pulling() if(!isturf(loc)) - return + return else if(lastarea?.has_gravity == 0) inertial_drift() //VOREStation Edit Start @@ -863,7 +954,7 @@ default behaviour is: if(Process_Spacemove(1)) inertia_dir = 0 return - + var/locthen = loc spawn(5) if(!anchored && !pulledby && loc == locthen) @@ -1145,22 +1236,29 @@ default behaviour is: /mob/living/proc/is_sentient() return TRUE +/mob/living/get_icon_scale_x() + . = ..() + for(var/datum/modifier/M in modifiers) + if(!isnull(M.icon_scale_x_percent)) + . *= M.icon_scale_x_percent + +/mob/living/get_icon_scale_y() + . = ..() + for(var/datum/modifier/M in modifiers) + if(!isnull(M.icon_scale_y_percent)) + . *= M.icon_scale_y_percent /mob/living/update_transform() // First, get the correct size. var/desired_scale_x = size_multiplier //VOREStation edit var/desired_scale_y = size_multiplier //VOREStation edit - for(var/datum/modifier/M in modifiers) - if(!isnull(M.icon_scale_x_percent)) - desired_scale_x *= M.icon_scale_x_percent - if(!isnull(M.icon_scale_y_percent)) - desired_scale_y *= M.icon_scale_y_percent // Now for the regular stuff. var/matrix/M = matrix() M.Scale(desired_scale_x, desired_scale_y) M.Translate(0, (vis_height/2)*(desired_scale_y-1)) //VOREStation edit src.transform = M //VOREStation edit + handle_status_indicators() // This handles setting the client's color variable, which makes everything look a specific color. // This proc is here so it can be called without needing to check if the client exists, or if the client relogs. @@ -1350,3 +1448,8 @@ default behaviour is: clear_alert("weightless") else throw_alert("weightless", /obj/screen/alert/weightless) + +// Tries to turn off things that let you see through walls, like mesons. +// Each mob does vision a bit differently so this is just for inheritence and also so overrided procs can make the vision apply instantly if they call `..()`. +/mob/living/proc/disable_spoiler_vision() + handle_vision() \ No newline at end of file diff --git a/code/modules/mob/living/living_defines_vr.dm b/code/modules/mob/living/living_defines_vr.dm index 8b99c7aefb9..e959d0c5a1c 100644 --- a/code/modules/mob/living/living_defines_vr.dm +++ b/code/modules/mob/living/living_defines_vr.dm @@ -3,7 +3,6 @@ /mob/living var/ooc_notes = null - var/obj/structure/mob_spawner/source_spawner = null appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER var/hunger_rate = DEFAULT_HUNGER_FACTOR diff --git a/code/modules/mob/living/silicon/ai/ai_vr.dm b/code/modules/mob/living/silicon/ai/ai_vr.dm index 2f22d0e7886..3234d7269e4 100644 --- a/code/modules/mob/living/silicon/ai/ai_vr.dm +++ b/code/modules/mob/living/silicon/ai/ai_vr.dm @@ -6,6 +6,7 @@ add_language(LANGUAGE_ECUREUILIAN, 1) add_language(LANGUAGE_DAEMON, 1) add_language(LANGUAGE_ENOCHIAN, 1) + add_language(LANGUAGE_DRUDAKAR, 1) /mob/AIize(var/move = TRUE) . = ..() @@ -14,4 +15,5 @@ add_language(LANGUAGE_CANILUNZT, 1) add_language(LANGUAGE_ECUREUILIAN, 1) add_language(LANGUAGE_DAEMON, 1) - add_language(LANGUAGE_ENOCHIAN, 1) \ No newline at end of file + add_language(LANGUAGE_ENOCHIAN, 1) + add_language(LANGUAGE_DRUDAKAR, 1) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/login.dm b/code/modules/mob/living/silicon/login.dm index 3ffefc73c80..f2e15af0e8f 100644 --- a/code/modules/mob/living/silicon/login.dm +++ b/code/modules/mob/living/silicon/login.dm @@ -1,3 +1,3 @@ /mob/living/silicon/Login() - sleeping = 0 + SetSleeping(0) ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 1278b59c763..3a995ba19df 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -40,6 +40,7 @@ "Fennec" = "pai-fen", "Type Zero" = "pai-typezero", "Raccoon" = "pai-raccoon", + "Raptor" = "pai-raptor", "Rat" = "rat", "Panther" = "panther" //VOREStation Addition End diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm index f1b2d76eec5..e946c7999c6 100644 --- a/code/modules/mob/living/silicon/robot/analyzer.dm +++ b/code/modules/mob/living/silicon/robot/analyzer.dm @@ -34,6 +34,8 @@ scan_type = "robot" else if(istype(M, /mob/living/carbon/human)) scan_type = "prosthetics" + else if(istype(M, /obj/mecha)) + scan_type = "mecha" else to_chat(user, "You can't analyze non-robotic things!") return @@ -95,5 +97,37 @@ if(!organ_found) to_chat(user, "No prosthetics located.") + if("mecha") + + var/obj/mecha/Mecha = M + + var/integrity = Mecha.health/initial(Mecha.health)*100 + var/cell_charge = Mecha.get_charge() + var/tank_pressure = Mecha.internal_tank ? round(Mecha.internal_tank.return_pressure(),0.01) : "None" + var/tank_temperature = Mecha.internal_tank ? Mecha.internal_tank.return_temperature() : "Unknown" + var/cabin_pressure = round(Mecha.return_pressure(),0.01) + + var/output = {"Analyzing Results for \the [Mecha]:
    + Chassis Integrity: [integrity]%
    + Powercell charge: [isnull(cell_charge)?"No powercell installed":"[Mecha.cell.percent()]%"]
    + Air source: [Mecha.use_internal_tank?"Internal Airtank":"Environment"]
    + Airtank pressure: [tank_pressure]kPa
    + Airtank temperature: [tank_temperature]K|[tank_temperature - T0C]°C
    + Cabin pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
    + Cabin temperature: [Mecha.return_temperature()]K|[Mecha.return_temperature() - T0C]°C
    + DNA Lock: [Mecha.dna?"Mecha.dna":"Not Found"]
    + "} + + to_chat(user, output) + to_chat(user, "
    ") + to_chat(user, "Internal Diagnostics:") + for(var/slot in Mecha.internal_components) + var/obj/item/mecha_parts/component/MC = Mecha.internal_components[slot] + to_chat(user, "[MC?"[slot]: [MC] [round((MC.integrity / MC.max_integrity) * 100, 0.1)]% integrity. [MC.get_efficiency() * 100] Operational capacity.":"[slot]: Component Not Found"]") + + to_chat(user, "
    ") + to_chat(user, "General Statistics:") + to_chat(user, "Movement Weight: [Mecha.get_step_delay()]
    ") + src.add_fingerprint(user) return diff --git a/code/modules/mob/living/silicon/robot/custom_sprites.dm b/code/modules/mob/living/silicon/robot/custom_sprites.dm index 310f558badb..b189e1a84c1 100644 --- a/code/modules/mob/living/silicon/robot/custom_sprites.dm +++ b/code/modules/mob/living/silicon/robot/custom_sprites.dm @@ -11,7 +11,7 @@ GLOBAL_LIST_EMPTY(robot_custom_icons) GLOB.robot_custom_icons = list() for(var/line in lines) //split entry into ckey and real_name - var/list/split_idx = splittext(line, "-") //this works if ckeys and borg names cannot contain dashes, and splittext starts from the beginning ~Mech + var/list/split_idx = splittext(line, "|") //this was set to a - before, even though a good 30% of the borgs I see have a - in their name, set it to | instead if(!split_idx || !split_idx.len) continue //bad entry @@ -32,3 +32,9 @@ GLOBAL_LIST_EMPTY(robot_custom_icons) icon = CUSTOM_ITEM_SYNTH if(icon_state == "robot") icon_state = "[ckey]-[sprite_name]-Standard" //Compliant with robot.dm line 236 ~Mech +// To summarize, if you want to add a whitelisted borg sprite, you have to +// 1. Add ckey and character name to config/custom_sprites, separated by a | +// 2. Add your custom sprite to custom_synthetic.dmi under icon/mob/custom_synthetic.dmi +// 3. Name the sprite, and all of its components, as ckey-charname-module +// Note that, due to the last couple lines of code, your sprite may appear invisible until you select a module. +// You can fix this by adding a 'standard' configuration, or you could probably just ignore it if you're lazy. \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm index d1215edc281..e84970c8242 100644 --- a/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm +++ b/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm @@ -213,6 +213,7 @@ user.visible_message("[user] begins to lap up water from [target.name].", "You begin to lap up water from [target.name].") if(do_after (user, 50)) water.add_charge(50) + to_chat(src, "You refill some of your water reserves.") else if(water.energy < 5) to_chat(user, "Your mouth feels dry. You should drink up some water .") return diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm index 07b6db71b3e..d8c7cea9079 100644 --- a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm +++ b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm @@ -30,6 +30,7 @@ var/synced = FALSE var/startdrain = 500 var/max_item_count = 1 + var/upgraded_capacity = FALSE var/gulpsound = 'sound/vore/gulp.ogg' var/datum/matter_synth/metal = null var/datum/matter_synth/glass = null @@ -39,6 +40,7 @@ var/digest_brute = 2 var/digest_burn = 3 var/recycles = FALSE + var/medsensor = TRUE //Does belly sprite come with patient ok/dead light? /obj/item/device/dogborg/sleeper/New() ..() @@ -426,21 +428,25 @@ //Well, we HAD one, what happened to them? if(patient in contents) - if(patient_laststat != patient.stat) - if(cleaning) - hound.sleeper_r = TRUE - hound.sleeper_g = FALSE - patient_laststat = patient.stat - else if(patient.stat & DEAD) - hound.sleeper_r = TRUE - hound.sleeper_g = FALSE - patient_laststat = patient.stat - else - hound.sleeper_r = FALSE - hound.sleeper_g = TRUE - patient_laststat = patient.stat - //Update icon - hound.updateicon() + if(medsensor) + if(patient_laststat != patient.stat) + if(cleaning) + hound.sleeper_r = TRUE + hound.sleeper_g = FALSE + patient_laststat = patient.stat + else if(patient.stat & DEAD) + hound.sleeper_r = TRUE + hound.sleeper_g = FALSE + patient_laststat = patient.stat + else + hound.sleeper_r = FALSE + hound.sleeper_g = TRUE + patient_laststat = patient.stat + else + hound.sleeper_r = TRUE + patient_laststat = patient.stat + //Update icon + hound.updateicon() //Return original patient return(patient) @@ -448,17 +454,21 @@ else for(var/mob/living/carbon/human/C in contents) patient = C - if(cleaning) - hound.sleeper_r = TRUE - hound.sleeper_g = FALSE - patient_laststat = patient.stat - else if(patient.stat & DEAD) - hound.sleeper_r = TRUE - hound.sleeper_g = FALSE - patient_laststat = patient.stat + if(medsensor) + if(cleaning) + hound.sleeper_r = TRUE + hound.sleeper_g = FALSE + patient_laststat = patient.stat + else if(patient.stat & DEAD) + hound.sleeper_r = TRUE + hound.sleeper_g = FALSE + patient_laststat = patient.stat + else + hound.sleeper_r = FALSE + hound.sleeper_g = TRUE + patient_laststat = patient.stat else - hound.sleeper_r = FALSE - hound.sleeper_g = TRUE + hound.sleeper_r = TRUE patient_laststat = patient.stat //Update icon and return new patient hound.updateicon() @@ -659,6 +669,7 @@ desc = "Equipment for a K9 unit. A mounted portable-brig that holds criminals." icon_state = "sleeperb" injection_chems = null //So they don't have all the same chems as the medihound! + medsensor = FALSE /obj/item/device/dogborg/sleeper/compactor //Janihound gut. name = "Garbage Processor" @@ -668,12 +679,13 @@ compactor = TRUE recycles = TRUE max_item_count = 25 + medsensor = FALSE /obj/item/device/dogborg/sleeper/compactor/analyzer //sci-borg gut. name = "Digestive Analyzer" desc = "A mounted destructive analyzer unit with fuel processor." icon_state = "analyzer" - max_item_count = 1 + max_item_count = 10 startdrain = 100 analyzer = TRUE @@ -691,7 +703,7 @@ icon_state = "decompiler" max_item_count = 20 delivery = TRUE - + /obj/item/device/dogborg/sleeper/compactor/supply //Miner borg belly name = "Supply Satchel" desc = "A mounted survival unit with fuel processor." diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm index c2e6ca48f55..94b8bb2e2c0 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm @@ -14,111 +14,107 @@ /obj/machinery/computer/drone_control/attack_ai(var/mob/user as mob) return src.attack_hand(user) +/obj/machinery/computer/drone_control/tgui_status(mob/user) + if(!allowed(user)) + return STATUS_CLOSE + return ..() + /obj/machinery/computer/drone_control/attack_hand(var/mob/user as mob) if(..()) return - if(!allowed(user)) - to_chat(user, "Access denied.") - return + tgui_interact(user) - user.set_machine(src) - var/dat - dat += "Maintenance Units
    " +/obj/machinery/computer/drone_control/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "DroneConsole", name) + ui.open() +/obj/machinery/computer/drone_control/tgui_data(mob/user) + var/list/data = list() + + data["drones"] = list() for(var/mob/living/silicon/robot/drone/D in mob_list) - if(D.z != src.z) + if(D.z != z) continue if(D.foreign_droid) continue + + data["drones"].Add(list(list( + "name" = D.real_name, + "active" = D.stat != 2, + "charge" = D.cell.charge, + "maxCharge" = D.cell.maxcharge, + "loc" = "[get_area(D)]", + "ref" = "\ref[D]", + ))) - dat += "
    [D.real_name] ([D.stat == 2 ? "INACTIVE" : "ACTIVE"])" - dat += "
    Cell charge: [D.cell.charge]/[D.cell.maxcharge]." - dat += "
    Currently located in: [get_area(D)]." - dat += "
    Resync | Shutdown
    " + data["fabricator"] = dronefab + data["fabPower"] = dronefab?.produce_drones - dat += "

    Request drone presence in area: [drone_call_area] (Send ping)" + data["areas"] = tagger_locations + data["selected_area"] = "[drone_call_area]" - dat += "

    Drone fabricator: " - dat += "[dronefab ? "[(dronefab.produce_drones && !(dronefab.stat & NOPOWER)) ? "ACTIVE" : "INACTIVE"]" : "FABRICATOR NOT DETECTED. (search)"]" - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") - return + return data - -/obj/machinery/computer/drone_control/Topic(href, href_list) +/obj/machinery/computer/drone_control/tgui_act(action, params) if(..()) - return + return TRUE - if(!allowed(usr)) - to_chat(usr, "Access denied.") - return + switch(action) + if("set_dcall_area") + var/t_area = params["area"] + if(!t_area || !(t_area in tagger_locations)) + return - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) + drone_call_area = t_area + to_chat(usr, "You set the area selector to [drone_call_area].") - if (href_list["setarea"]) + if("ping") + to_chat(usr, "You issue a maintenance request for all active drones, highlighting [drone_call_area].") + for(var/mob/living/silicon/robot/drone/D in player_list) + if(D.stat == 0) + to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].") - //Probably should consider using another list, but this one will do. - var/t_area = input("Select the area to ping.", "Set Target Area", null) as null|anything in tagger_locations + if("resync") + var/mob/living/silicon/robot/drone/D = locate(params["ref"]) - if(!t_area) - return + if(D.stat != 2) + to_chat(usr, "You issue a law synchronization directive for the drone.") + D.law_resync() - drone_call_area = t_area - to_chat(usr, "You set the area selector to [drone_call_area].") + if("shutdown") + var/mob/living/silicon/robot/drone/D = locate(params["ref"]) - else if (href_list["ping"]) + if(D.stat != 2) + to_chat(usr, "You issue a kill command for the unfortunate drone.") + message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.") + log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.") + D.shut_down() - to_chat(usr, "You issue a maintenance request for all active drones, highlighting [drone_call_area].") - for(var/mob/living/silicon/robot/drone/D in player_list) - if(D.stat == 0) - to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].") + if("search_fab") + if(dronefab) + return - else if (href_list["resync"]) + for(var/obj/machinery/drone_fabricator/fab in oview(3,src)) + if(fab.stat & NOPOWER) + continue - var/mob/living/silicon/robot/drone/D = locate(href_list["resync"]) + dronefab = fab + to_chat(usr, "Drone fabricator located.") + return - if(D.stat != 2) - to_chat(usr, "You issue a law synchronization directive for the drone.") - D.law_resync() - - else if (href_list["shutdown"]) - - var/mob/living/silicon/robot/drone/D = locate(href_list["shutdown"]) - - if(D.stat != 2) - to_chat(usr, "You issue a kill command for the unfortunate drone.") - message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.") - log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.") - D.shut_down() - - else if (href_list["search_fab"]) - if(dronefab) - return - - for(var/obj/machinery/drone_fabricator/fab in oview(3,src)) - - if(fab.stat & NOPOWER) - continue - - dronefab = fab - to_chat(usr, "Drone fabricator located.") - return - - to_chat(usr, "Unable to locate drone fabricator.") - - else if (href_list["toggle_fab"]) - - if(!dronefab) - return - - if(get_dist(src,dronefab) > 3) - dronefab = null to_chat(usr, "Unable to locate drone fabricator.") - return - dronefab.produce_drones = !dronefab.produce_drones - to_chat(usr, "You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.") + if("toggle_fab") + if(!dronefab) + return - src.updateUsrDialog() \ No newline at end of file + if(get_dist(src,dronefab) > 3) + dronefab = null + to_chat(usr, "Unable to locate drone fabricator.") + return + + dronefab.produce_drones = !dronefab.produce_drones + to_chat(usr, "You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.") diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index b52028d542e..d6f5acfb3dc 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -38,6 +38,10 @@ drop_item() return +/obj/item/weapon/gripper/AltClick(mob/user) + drop_item() + return + /obj/item/weapon/gripper/omni name = "omni gripper" desc = "A strange grasping tool that can hold anything a human can, but still maintains the limitations of application its more limited cousins have." @@ -153,7 +157,9 @@ /obj/item/weapon/reagent_containers/glass, /obj/item/weapon/reagent_containers/food, /obj/item/seeds, - /obj/item/weapon/grown + /obj/item/weapon/grown, + /obj/item/trash, + /obj/item/weapon/reagent_containers/cooking_container ) /obj/item/weapon/gripper/gravekeeper //Used for handling grave things, flowers, etc. @@ -250,12 +256,15 @@ return resolved return ..() -/obj/item/weapon/gripper/verb/drop_item() +/obj/item/weapon/gripper/verb/drop_gripper_item() set name = "Drop Item" set desc = "Release an item from your magnetic gripper." set category = "Robot Commands" + drop_item() + +obj/item/weapon/gripper/proc/drop_item() if(!wrapped) //There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z for(var/obj/item/thing in src.contents) @@ -266,7 +275,7 @@ wrapped = null return - to_chat(src.loc, "You drop \the [wrapped].") + to_chat(src.loc, "You drop \the [wrapped].") wrapped.loc = get_turf(src) wrapped = null //update_icon() @@ -467,7 +476,7 @@ for(var/obj/W in T) //Different classes of items give different commodities. - if(istype(W,/obj/item/weapon/cigbutt)) + if(istype(W,/obj/item/trash/cigbutt)) if(plastic) plastic.add_charge(500) else if(istype(W,/obj/effect/spider/spiderling)) diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index 795929992bc..9560c6b528e 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -144,7 +144,7 @@ playsound(src, 'sound/voice/bark2.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises) m_type = 2 else - src << "You're not a dog!" + to_chat(src, "You're not a dog!") //Vorestation addition end diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index c8b623e5177..96daaf9af73 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -52,6 +52,7 @@ module_state_3 = null inv3.icon_state = "inv3" updateicon() + hud_used.update_robot_modules_display() /mob/living/silicon/robot/proc/uneq_all() module_active = null diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 74aad9bae05..6db31e60daa 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -32,7 +32,7 @@ // SetStunned(min(stunned, 30)) SetParalysis(min(paralysis, 30)) // SetWeakened(min(weakened, 20)) - sleeping = 0 + SetSleeping(0) adjustBruteLoss(0) adjustToxLoss(0) adjustOxyLoss(0) @@ -69,7 +69,7 @@ /mob/living/silicon/robot/handle_regular_status_updates() if(src.camera && !scrambledcodes) - if(src.stat == 2 || wires.IsIndexCut(BORG_WIRE_CAMERA)) + if(src.stat == 2 || wires.is_cut(WIRE_BORG_CAMERA)) src.camera.set_status(0) else src.camera.set_status(1) @@ -78,7 +78,7 @@ if(src.sleeping) Paralyse(3) - src.sleeping-- + AdjustSleeping(-1) //if(src.resting) // VOREStation edit. Our borgos would rather not. // Weaken(5) @@ -153,7 +153,13 @@ /mob/living/silicon/robot/handle_regular_hud_updates() var/fullbright = FALSE var/seemeson = FALSE - if (src.stat == 2 || (XRAY in mutations) || (src.sight_mode & BORGXRAY)) + + var/area/A = get_area(src) + if(A?.no_spoilers) + disable_spoiler_vision() + + + if (src.stat == DEAD || (XRAY in mutations) || (src.sight_mode & BORGXRAY)) src.sight |= SEE_TURFS src.sight |= SEE_MOBS src.sight |= SEE_OBJS @@ -187,13 +193,14 @@ src.sight &= ~SEE_OBJS src.see_in_dark = 8 src.see_invisible = SEE_INVISIBLE_NOLIGHTING - else if (src.stat != 2) + else if (src.stat != DEAD) src.sight &= ~SEE_MOBS src.sight &= ~SEE_TURFS src.sight &= ~SEE_OBJS src.see_in_dark = 8 // see_in_dark means you can FAINTLY see in the dark, humans have a range of 3 or so, tajaran have it at 8 src.see_invisible = SEE_INVISIBLE_LIVING // This is normal vision (25), setting it lower for normal vision means you don't "see" things like darkness since darkness // has a "invisible" value of 15 + plane_holder.set_vis(VIS_FULLBRIGHT,fullbright) plane_holder.set_vis(VIS_MESONS,seemeson) ..() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 17c5954dadf..6383449e0a6 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -124,7 +124,7 @@ camera = new /obj/machinery/camera(src) camera.c_tag = real_name camera.replace_networks(list(NETWORK_DEFAULT,NETWORK_ROBOTS)) - if(wires.IsIndexCut(BORG_WIRE_CAMERA)) + if(wires.is_cut(WIRE_BORG_CAMERA)) camera.status = 0 init() @@ -536,7 +536,7 @@ to_chat(user, "You close the cover.") opened = 0 updateicon() - else if(wiresexposed && wires.IsAllCut()) + else if(wiresexposed && wires.is_all_cut()) //Cell is out, wires are exposed, remove MMI, produce damaged chassis, baleet original mob. if(!mmi) to_chat(user, "\The [src] has no brain to remove.") @@ -932,7 +932,7 @@ /mob/living/silicon/robot/proc/SetLockdown(var/state = 1) // They stay locked down if their wire is cut. - if(wires.LockedCut()) + if(wires.is_cut(WIRE_BORG_LOCKED)) state = 1 if(state) throw_alert("locked", /obj/screen/alert/locked) @@ -1140,3 +1140,19 @@ if(module_active && istype(module_active,/obj/item/weapon/gripper)) var/obj/item/weapon/gripper/G = module_active G.drop_item_nm() + +/mob/living/silicon/robot/disable_spoiler_vision() + if(sight_mode & (BORGMESON|BORGMATERIAL|BORGXRAY)) // Whyyyyyyyy have seperate defines. + var/i = 0 + // Borg inventory code is very . . interesting and as such, unequiping a specific item requires jumping through some (for) loops. + var/current_selection_index = get_selected_module() // Will be 0 if nothing is selected. + for(var/thing in list(module_state_1, module_state_2, module_state_3)) + i++ + if(istype(thing, /obj/item/borg/sight)) + var/obj/item/borg/sight/S = thing + if(S.sight_mode & (BORGMESON|BORGMATERIAL|BORGXRAY)) + select_module(i) + uneq_active() + + if(current_selection_index) // Select what the player had before if possible. + select_module(current_selection_index) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index 78d741b0125..41a47b0e7e0 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -296,7 +296,7 @@ // Copied over from paper's rename verb // see code\modules\paperwork\paper.dm line 62 -/obj/item/weapon/pen/robopen/proc/RenamePaper(mob/user as mob,obj/paper as obj) +/obj/item/weapon/pen/robopen/proc/RenamePaper(mob/user, obj/item/weapon/paper/paper) if ( !user || !paper ) return var/n_name = sanitizeSafe(input(user, "What would you like to label the paper?", "Paper Labelling", null) as text, 32) @@ -306,6 +306,7 @@ //n_name = copytext(n_name, 1, 32) if(( get_dist(user,paper) <= 1 && user.stat == 0)) paper.name = "paper[(n_name ? text("- '[n_name]'") : null)]" + paper.last_modified_ckey = user.ckey add_fingerprint(user) return diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station.dm b/code/modules/mob/living/silicon/robot/robot_modules/station.dm index 73eb8012c40..c919b83a7a6 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station.dm @@ -815,6 +815,7 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/weapon/tool/wrench/cyborg(src) src.modules += new /obj/item/weapon/tool/crowbar/cyborg(src) src.modules += new /obj/item/weapon/tool/wirecutters/cyborg(src) + src.modules += new /obj/item/device/t_scanner(src) src.modules += new /obj/item/device/multitool(src) src.modules += new /obj/item/device/lightreplacer(src) src.modules += new /obj/item/weapon/gripper(src) diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm index 524f54655c1..e6dface45ae 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm @@ -12,7 +12,8 @@ LANGUAGE_CANILUNZT = 0, LANGUAGE_ECUREUILIAN= 0, LANGUAGE_DAEMON = 0, - LANGUAGE_ENOCHIAN = 0 + LANGUAGE_ENOCHIAN = 0, + LANGUAGE_DRUDAKAR = 0 ) var/vr_sprites = list() var/pto_type = null @@ -34,7 +35,8 @@ LANGUAGE_CANILUNZT = 1, LANGUAGE_ECUREUILIAN= 1, LANGUAGE_DAEMON = 1, - LANGUAGE_ENOCHIAN = 1 + LANGUAGE_ENOCHIAN = 1, + LANGUAGE_DRUDAKAR = 1 ) /hook/startup/proc/robot_modules_vr() @@ -163,7 +165,8 @@ "K9 hound" = "k9", "K9 Alternative" = "k92", "Secborg model V-2" = "secborg", - "Borgi" = "borgi-sec" + "Borgi" = "borgi-sec", + "Otieborg" = "oties" ) channels = list("Security" = 1) networks = list(NETWORK_SECURITY) @@ -254,7 +257,7 @@ var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(2000) synths += medicine - + var/obj/item/stack/medical/advanced/clotting/C = new (src) C.uses_charge = 1 C.charge_costs = list(1000) @@ -347,7 +350,8 @@ name = "Custodial Hound module" sprites = list( "Custodial Hound" = "scrubpup", - "Borgi" = "borgi-jani" + "Borgi" = "borgi-jani", + "Otieborg" = "otiej" ) channels = list("Service" = 1) pto_type = PTO_CIVILIAN diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index b98340baef6..b6cf748fb82 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -115,25 +115,7 @@ /mob/living/silicon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0) return 0//The only effect that can hit them atm is flashes and they still directly edit so this works for now -/* - if(!effect || (blocked >= 2)) return 0 - switch(effecttype) - if(STUN) - stunned = max(stunned,(effect/(blocked+1))) - if(WEAKEN) - weakened = max(weakened,(effect/(blocked+1))) - if(PARALYZE) - paralysis = max(paralysis,(effect/(blocked+1))) - if(IRRADIATE) - radiation += min((effect - (effect*getarmor(null, "rad"))), 0)//Rads auto check armor - if(STUTTER) - stuttering = max(stuttering,(effect/(blocked+1))) - if(EYE_BLUR) - eye_blurry = max(eye_blurry,(effect/(blocked+1))) - if(DROWSY) - drowsyness = max(drowsyness,(effect/(blocked+1))) - updatehealth() - return 1*/ + /proc/islinked(var/mob/living/silicon/robot/bot, var/mob/living/silicon/ai/ai) if(!istype(bot) || !istype(ai)) @@ -336,7 +318,7 @@ next_alarm_notice = world.time + SecondsToTicks(10) if(alarm.hidden) return - if(alarm.origin && !(get_z(alarm.origin) in using_map.get_map_levels(get_z(src), TRUE))) + if(alarm.origin && !(get_z(alarm.origin) in using_map.get_map_levels(get_z(src), TRUE, om_range = DEFAULT_OVERMAP_RANGE))) return var/list/alarms = queued_alarms[alarm_handler] diff --git a/code/modules/mob/living/silicon/subystems.dm b/code/modules/mob/living/silicon/subystems.dm index b03ab5eeb21..bb84ed3ce37 100644 --- a/code/modules/mob/living/silicon/subystems.dm +++ b/code/modules/mob/living/silicon/subystems.dm @@ -1,11 +1,11 @@ /mob/living/silicon var/register_alarms = 1 - var/datum/nano_module/alarm_monitor/all/alarm_monitor - var/datum/nano_module/atmos_control/atmos_control - var/datum/nano_module/program/crew_monitor/crew_monitor + var/datum/tgui_module/alarm_monitor/all/robot/alarm_monitor + var/datum/tgui_module/atmos_control/robot/atmos_control + var/datum/tgui_module/crew_monitor/robot/crew_monitor var/datum/nano_module/law_manager/law_manager - var/datum/nano_module/power_monitor/power_monitor - var/datum/nano_module/rcon/rcon + var/datum/tgui_module/power_monitor/robot/power_monitor + var/datum/tgui_module/rcon/robot/rcon /mob/living/silicon var/list/silicon_subsystems = list( @@ -49,7 +49,7 @@ set name = "Alarm Monitor" set category = "Subystems" - alarm_monitor.ui_interact(usr, state = self_state) + alarm_monitor.tgui_interact(usr) /******************** * Atmos Control * @@ -58,7 +58,7 @@ set category = "Subystems" set name = "Atmospherics Control" - atmos_control.ui_interact(usr, state = self_state) + atmos_control.tgui_interact(usr) /******************** * Crew Monitor * @@ -67,7 +67,7 @@ set category = "Subystems" set name = "Crew Monitor" - crew_monitor.ui_interact(usr, state = self_state) + crew_monitor.tgui_interact(usr) /**************** * Law Manager * @@ -85,7 +85,7 @@ set category = "Subystems" set name = "Power Monitor" - power_monitor.ui_interact(usr, state = self_state) + power_monitor.tgui_interact(usr) /************ * RCON * @@ -94,4 +94,4 @@ set category = "Subystems" set name = "RCON" - rcon.ui_interact(usr, state = self_state) + rcon.tgui_interact(usr) diff --git a/code/modules/mob/living/simple_mob/combat.dm b/code/modules/mob/living/simple_mob/combat.dm index 7a950bf11a7..1dce6736017 100644 --- a/code/modules/mob/living/simple_mob/combat.dm +++ b/code/modules/mob/living/simple_mob/combat.dm @@ -143,7 +143,7 @@ if(do_after(src, reload_time)) if(reload_sound) - playsound(src, reload_sound, 50, 1) + playsound(src, reload_sound, 70, 1) reload_count = 0 . = TRUE else diff --git a/code/modules/mob/living/simple_mob/defense.dm b/code/modules/mob/living/simple_mob/defense.dm index d94d83c0a94..1a301b8bfd3 100644 --- a/code/modules/mob/living/simple_mob/defense.dm +++ b/code/modules/mob/living/simple_mob/defense.dm @@ -140,7 +140,18 @@ // Cold stuff. /mob/living/simple_mob/get_cold_protection() - return cold_resist + . = cold_resist + . = 1 - . // Invert from 1 = immunity to 0 = immunity. + + // Doing it this way makes multiplicative stacking not get out of hand, so two modifiers that give 0.5 protection will be combined to 0.75 in the end. + for(var/thing in modifiers) + var/datum/modifier/M = thing + if(!isnull(M.cold_protection)) + . *= 1 - M.cold_protection + + // Code that calls this expects 1 = immunity so we need to invert again. + . = 1 - . + . = min(., 1.0) // Fire stuff. Not really exciting at the moment. @@ -154,7 +165,18 @@ return /mob/living/simple_mob/get_heat_protection() - return heat_resist + . = heat_resist + . = 1 - . // Invert from 1 = immunity to 0 = immunity. + + // Doing it this way makes multiplicative stacking not get out of hand, so two modifiers that give 0.5 protection will be combined to 0.75 in the end. + for(var/thing in modifiers) + var/datum/modifier/M = thing + if(!isnull(M.heat_protection)) + . *= 1 - M.heat_protection + + // Code that calls this expects 1 = immunity so we need to invert again. + . = 1 - . + . = min(., 1.0) // Electricity /mob/living/simple_mob/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null) @@ -170,7 +192,18 @@ s.start() /mob/living/simple_mob/get_shock_protection() - return shock_resist + . = shock_resist + . = 1 - . // Invert from 1 = immunity to 0 = immunity. + + // Doing it this way makes multiplicative stacking not get out of hand, so two modifiers that give 0.5 protection will be combined to 0.75 in the end. + for(var/thing in modifiers) + var/datum/modifier/M = thing + if(!isnull(M.siemens_coefficient)) + . *= M.siemens_coefficient + + // Code that calls this expects 1 = immunity so we need to invert again. + . = 1 - . + . = min(., 1.0) // Shot with taser/stunvolver /mob/living/simple_mob/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon=null) @@ -218,17 +251,29 @@ // Armor /mob/living/simple_mob/getarmor(def_zone, attack_flag) var/armorval = armor[attack_flag] - if(!armorval) - return 0 - else - return armorval + if(isnull(armorval)) + armorval = 0 + + for(var/thing in modifiers) + var/datum/modifier/M = thing + var/modifier_armor = LAZYACCESS(M.armor_percent, attack_flag) + if(modifier_armor) + armorval += modifier_armor + + return armorval /mob/living/simple_mob/getsoak(def_zone, attack_flag) var/armorval = armor_soak[attack_flag] - if(!armorval) - return 0 - else - return armorval + if(isnull(armorval)) + armorval = 0 + + for(var/thing in modifiers) + var/datum/modifier/M = thing + var/modifier_armor = LAZYACCESS(M.armor_flat, attack_flag) + if(modifier_armor) + armorval += modifier_armor + + return armorval // Lightning /mob/living/simple_mob/lightning_act() diff --git a/code/modules/mob/living/simple_mob/simple_mob.dm b/code/modules/mob/living/simple_mob/simple_mob.dm index ba77999be81..3a27d98d014 100644 --- a/code/modules/mob/living/simple_mob/simple_mob.dm +++ b/code/modules/mob/living/simple_mob/simple_mob.dm @@ -92,7 +92,7 @@ var/needs_reload = FALSE // If TRUE, mob needs to reload occasionally var/reload_max = 1 // How many shots the mob gets before it has to reload, will not be used if needs_reload is FALSE var/reload_count = 0 // A counter to keep track of how many shots the mob has fired so far. Reloads when it hits reload_max. - var/reload_time = 1 SECONDS // How long it takes for a mob to reload. This is to buy a player a bit of time to run or fight. + var/reload_time = 4 SECONDS // How long it takes for a mob to reload. This is to buy a player a bit of time to run or fight. var/reload_sound = 'sound/weapons/flipblade.ogg' // What sound gets played when the mob successfully reloads. Defaults to the same sound as reloading guns. Can be null. //Mob melee settings diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm index 87c05b317d7..9fe548ee610 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm @@ -54,4 +54,4 @@ /obj/item/weapon/reagent_containers/food/snacks/meat/crab name = "meat" desc = "A chunk of meat." - icon_state = "crustacean-meat" + icon_state = "crustacean-meat" \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm index 198f99a3f4a..b5c811b81c3 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm @@ -31,6 +31,17 @@ /turf/simulated/floor/water ) + var/randomize_location = TRUE + +/mob/living/simple_mob/animal/passive/fish/Initialize() + ..() + + if(!default_pixel_x && randomize_location) + default_pixel_x = rand(-12, 12) + + if(!default_pixel_y && randomize_location) + default_pixel_y = rand(-6, 10) + // Makes the AI unable to willingly go on land. /mob/living/simple_mob/animal/passive/fish/IMove(newloc) if(is_type_in_list(newloc, suitable_turf_types)) @@ -39,6 +50,11 @@ // Take damage if we are not in water /mob/living/simple_mob/animal/passive/fish/handle_breathing() + if(istype(loc, /obj/item/glass_jar/fish)) + var/obj/item/glass_jar/fish/F = loc + if(F.filled) + return + var/turf/T = get_turf(src) if(T && !is_type_in_list(T, suitable_turf_types)) if(prob(50)) @@ -178,8 +194,8 @@ dorsal_image.color = dorsal_color belly_image.color = belly_color - overlays += dorsal_image - overlays += belly_image + add_overlay(dorsal_image) + add_overlay(belly_image) /datum/category_item/catalogue/fauna/rockfish name = "Sivian Fauna - Rock Puffer" @@ -234,6 +250,7 @@ /mob/living/simple_mob/animal/passive/fish/rockfish/Initialize() ..() head_color = rgb(rand(min_red,max_red), rand(min_green,max_green), rand(min_blue,max_blue)) + update_icon() /mob/living/simple_mob/animal/passive/fish/rockfish/update_icon() overlays.Cut() @@ -245,7 +262,7 @@ head_image.color = head_color - overlays += head_image + add_overlay(head_image) /datum/category_item/catalogue/fauna/solarfish name = "Sivian Fauna - Solar Fin" diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm index 12b70f6048e..dedac8e1e2b 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm @@ -10,6 +10,10 @@ maxHealth = 5 health = 5 + melee_damage_lower = 1 + melee_damage_upper = 3 + + movement_cooldown = 1.5 mob_size = MOB_MINISCULE pass_flags = PASSTABLE @@ -101,15 +105,13 @@ /mob/living/simple_mob/animal/passive/mouse/rat name = "rat" + body_color = "rat" + icon_state = "mouse_rat" maxHealth = 20 health = 20 ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive -/mob/living/simple_mob/animal/passive/mouse/rat/Initialize() - ..() - adjust_scale(1.2) - //TOM IS ALIVE! SQUEEEEEEEE~K :) /mob/living/simple_mob/animal/passive/mouse/brown/Tom name = "Tom" diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/dog.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/dog.dm index 89871033ec3..3825146832e 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/pets/dog.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/dog.dm @@ -232,4 +232,14 @@ name = "Spice" real_name = "Spice" //Intended to hold the name without altering it. gender = FEMALE - desc = "It's a tamaskan, the name Spice can be found on its collar." \ No newline at end of file + desc = "It's a tamaskan, the name Spice can be found on its collar." + +// Brittany Spaniel + +/mob/living/simple_mob/animal/passive/dog/brittany + name = "brittany" + real_name = "brittany" + desc = "It's a brittany spaniel." + icon_state = "brittany" + icon_living = "brittany" + icon_dead = "brittany_dead" \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm index fcfec0607c5..73d7b10e572 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm @@ -167,3 +167,4 @@ holder.face_atom(A) F.energy = max(0, F.energy - 1) // The AI will eventually flee. + diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/hare.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/hare.dm new file mode 100644 index 00000000000..e796cd488bb --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/hare.dm @@ -0,0 +1,68 @@ +// Complete chumps but a little bit hardier than mice. + +/datum/category_item/catalogue/fauna/hare + name = "Sivian Fauna - Ice Hare" + desc = "Classification: S Lepus petropellis\ +

    \ + Hard-skinned, horned herbivores common on the glacial regions of Sif. \ + The Ice Hare lives in colonies of up to thirty individuals dug beneath thick ice sheets for protection from many burrowing predators. \ + Their diet consists of mostly moss and lichens, though this is supplemented with the consumption of hard mineral pebbles, which it swallows whole, \ + which form the small, hard, 'ice-like' scales of the animal. \ + The Ice Hare is almost completely harmless to sapients, with relatively blunt claws and a weak jaw. Its main forms of self-defense are its speed, \ + and two sharp head spikes whose 'ear-like' appearance gave the species its common name." + value = CATALOGUER_REWARD_EASY + +/mob/living/simple_mob/animal/passive/hare + name = "ice hare" + real_name = "ice hare" + desc = "A small horned herbivore with a tough 'ice-like' hide." + tt_desc = "S Lepus petropellis" //Sivian hare rockskin + catalogue_data = list(/datum/category_item/catalogue/fauna/hare) + + icon_state = "hare" + icon_living = "hare" + icon_dead = "hare_dead" + icon_rest = "hare_rest" + + maxHealth = 20 + health = 20 + + armor = list( + "melee" = 30, + "bullet" = 5, + "laser" = 5, + "energy" = 0, + "bomb" = 10, + "bio" = 0, + "rad" = 0 + ) + + armor_soak = list( + "melee" = 5, + "bullet" = 0, + "laser" = 0, + "energy" = 0, + "bomb" = 0, + "bio" = 0, + "rad" = 0 + ) + + movement_cooldown = 2 + + mob_size = MOB_SMALL + pass_flags = PASSTABLE + layer = MOB_LAYER + density = 0 + + response_help = "pets" + response_disarm = "nudges" + response_harm = "kicks" + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + say_list_type = /datum/say_list/hare + +/datum/say_list/hare + speak = list("Snrf...","Crk!") + emote_hear = list("crackles","sniffles") + emote_see = list("stomps the ground", "sniffs the air", "chews on something") \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/moth.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/moth.dm new file mode 100644 index 00000000000..d153540dd57 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/moth.dm @@ -0,0 +1,143 @@ +//Very similar to frostflies, but with a non-lethal gas and less damaging, but less easy to protect from, projectiles. + +/datum/category_item/catalogue/fauna/tymisian + name = "Binman Fauna - Tymisian Moth" + desc = "Classification: B Carabidae glacios \ +

    \ + A meter-long fuzzy insect from the planet Binma. \ + A native of the Binman contintents of Telarus and Dalomee, the Tymisian Moth usually lives in communal \ + groups of upwards of thirty individuals, known as 'spuzzes', and typically breeds up to three times in its \ + fifteen year natural lifespan. \ +
    \ + Though strictly herbivorous, the moth has an acute sense of smell which it uses to detect potential predators. \ + Impressively, the moth secretes an oily substance which it uses to coat collected material stored in 'soft pockets' \ + beneath each wing, which in turn attracts colonies of pungent bacteria. \ + When threatened, the moth will release this dust, which has a disorienting effect on most Binman species, as well as all known sapients. \ +
    \ + The Tymisian Moth is considered an invasive species on Sif, and is believed to have been established from an illegally \ + released pet collection. Though less dangerous than in its native environment, the moth has nonetheless established a \ + similar symbiotic relationship with Sivian bacteria for its defense mechanism, and is still to be considered quite dangerous. \ +
    \ + As an invasive species, individuals encountering the Tymisian Moth on Sif are requested to report the sighting to local wildlife \ + services, and remove or destroy the creature if it is safe to do so." + value = CATALOGUER_REWARD_MEDIUM + +/mob/living/simple_mob/animal/sif/tymisian + name = "Tymisian Moth" + desc = "A huge, fuzzy insect with a disorienting dust." + tt_desc = "B Lepidoptera cinereus" + catalogue_data = list(/datum/category_item/catalogue/fauna/tymisian) + + faction = "spiders" //Hostile to most mobs, not all. + + icon_state = "moth" + icon_living = "moth" + icon_dead = "moth_dead" + icon_rest = "moth_dead" + icon = 'icons/mob/animal.dmi' + + maxHealth = 80 + health = 80 + + hovering = TRUE + + movement_cooldown = 0.5 + + melee_damage_lower = 5 + melee_damage_upper = 10 + base_attack_cooldown = 1.5 SECONDS + attacktext = list("nipped", "bit", "pinched") + + projectiletype = /obj/item/projectile/energy/blob + + special_attack_cooldown = 10 SECONDS + special_attack_min_range = 0 + special_attack_max_range = 6 + + var/energy = 100 + var/max_energy = 100 + + var/datum/effect/effect/system/smoke_spread/mothspore/smoke_spore + + say_list_type = /datum/say_list/tymisian + ai_holder_type = /datum/ai_holder/simple_mob/ranged/kiting/threatening/frostfly //Uses frostfly AI, since so similar mechanically + +/datum/say_list/tymisian + speak = list("Zzzz.", "Rrr...", "Zzt?") + emote_see = list("grooms itself","sprinkles dust from its wings", "rubs its mandibles") + emote_hear = list("chitters", "clicks", "rattles") + + say_understood = list("Ssst.") + say_cannot = list("Zzrt.") + say_maybe_target = list("Rr?") + say_got_target = list("Rrrrt!") + say_threaten = list("Kszsz.","Kszzt...","Kzzi!") + say_stand_down = list("Sss.","Zt.","! clicks.") + say_escalate = list("Rszt!") + + threaten_sound = 'sound/effects/spray3.ogg' + stand_down_sound = 'sound/effects/squelch1.ogg' + + +/obj/effect/effect/smoke/elemental/mothspore + name = "spore cloud" + desc = "A dust cloud filled with disorienting bacterial spores." + color = "#80AB82" + +/obj/effect/effect/smoke/elemental/mothspore/affect(mob/living/L) //Similar to a very weak flash, but depends on breathing instead of eye protection. + if(iscarbon(L)) + var/mob/living/carbon/C = L + if(C.stat != DEAD) + if(C.needs_to_breathe()) + var/spore_strength = 5 + if(ishuman(C)) + var/mob/living/carbon/human/H = C + H.Confuse(spore_strength) + H.eye_blurry = max(H.eye_blurry, spore_strength) + H.adjustHalLoss(10 * (spore_strength / 5)) + +/datum/effect/effect/system/smoke_spread/mothspore + smoke_type = /obj/effect/effect/smoke/elemental/mothspore + +/mob/living/simple_mob/animal/sif/tymisian/do_special_attack(atom/A) + . = TRUE + switch(a_intent) + if(I_DISARM) + if(energy < 20) + return FALSE + + energy -= 20 + + if(smoke_spore) + smoke_spore.set_up(7,0,src) + smoke_spore.start() + return TRUE + + return FALSE + +/mob/living/simple_mob/animal/sif/tymisian/Initialize() + ..() + smoke_spore = new + verbs += /mob/living/proc/ventcrawl + verbs += /mob/living/proc/hide + +/mob/living/simple_mob/animal/sif/tymisian/handle_special() + ..() + + if(energy < max_energy) + energy++ + +/mob/living/simple_mob/animal/sif/tymisian/Stat() + ..() + if(client.statpanel == "Status") + statpanel("Status") + if(emergency_shuttle) + var/eta_status = emergency_shuttle.get_status_panel_eta() + if(eta_status) + stat(null, eta_status) + stat("Energy", energy) + +/mob/living/simple_mob/animal/sif/tymisian/should_special_attack(atom/A) + if(energy >= 20) + return TRUE + return FALSE diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/pillbug.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/pillbug.dm new file mode 100644 index 00000000000..f70ea218c31 --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/pillbug.dm @@ -0,0 +1,51 @@ +/datum/category_item/catalogue/fauna/pillbug + name = "Sivian Fauna - Fire Bug" + desc = "Classification: S Armadillidiidae calidi \ +

    \ + A 10 inch long, hard-shelled insect with a natural adaption to living around terrestrial lava vents. \ + The fire bug's hard shell offers extremely effective protection against most threats, \ + though the species is almost completely docile, and will prefer to continue grazing on its diet of volcanic micro-flora \ + rather than defend itself in most situations.\ +
    \ + The fire bug is a curiosity to most on the frontier, offering little in the way of meaningful food or resources, \ + though at least one Sivian fashion designer has used their iridescent red shells to create striking, hand-made garments." + value = CATALOGUER_REWARD_EASY + +/mob/living/simple_mob/animal/passive/pillbug + name = "fire bug" + desc = "A tiny plated bug found in Sif's volcanic regions." + tt_desc = "S Armadillidiidae calidi" + catalogue_data = list(/datum/category_item/catalogue/fauna/pillbug) + + icon_state = "pillbug" + icon_living = "pillbug" + icon_dead = "pillbug_dead" + + health = 15 + maxHealth = 15 + mob_size = MOB_MINISCULE + + response_help = "gently touches" + response_disarm = "rolls over" + response_harm = "stomps on" + + armor = list( + "melee" = 30, + "bullet" = 10, + "laser" = 50, + "energy" = 50, + "bomb" = 30, + "bio" = 100, + "rad" = 100 + ) + + // The frostfly's body is incredibly cold at all times, natural resistance to things trying to burn it. + armor_soak = list( + "melee" = 10, + "bullet" = 0, + "laser" = 10, + "energy" = 10, + "bomb" = 0, + "bio" = 0, + "rad" = 0 + ) \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/siffet.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/siffet.dm new file mode 100644 index 00000000000..40ae65d3bcd --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/siffet.dm @@ -0,0 +1,61 @@ +// Somewhere between a fox and a weasel. Doesn't mess with stuff significantly bigger than it, but you don't want to get on its bad side. + +/datum/category_item/catalogue/fauna/siffet + name = "Sivian Fauna - Siffet" + desc = "Classification: S Pruinaeictis velocis\ +

    \ + The Siffet, or Sivian Frost Weasel is a small, solitary predator known for its striking ability to take down prey up to twice their size. \ + The majority of the Siffet's adult life is spent in isolation, prowling large territories in Sif's tundra regions, \ + only seeking out other individuals during the summer mating season, when deadly battles for dominance are common. \ + Though mostly docile towards adult humans and other large sapients, the Siffet has been known to target children and smaller species as prey, \ + and a provoked Siffet can be a danger to even the most experienced handler due to its quick movement and surprisingly powerful jaws. \ + The Siffet is sometimes hunted for its remarkably soft pelt, though most is obtained through fur farming." + value = CATALOGUER_REWARD_MEDIUM + +/mob/living/simple_mob/animal/sif/siffet + name = "siffet" + desc = "A small, solitary predator with silky fur. Despite its size, the Siffet is ferocious when provoked." + tt_desc = "S Pruinaeictis velocis" //Sivian frost weasel, fast + catalogue_data = list(/datum/category_item/catalogue/fauna/siffet) + + faction = "siffet" + + mob_size = MOB_SMALL + + icon_state = "siffet" + icon_living = "siffet" + icon_dead = "siffet_dead" + icon = 'icons/mob/animal.dmi' + + maxHealth = 60 + health = 60 + + movement_cooldown = 0 + + melee_damage_lower = 10 + melee_damage_upper = 15 + base_attack_cooldown = 1 SECOND + attack_sharp = 1 + attacktext = list("sliced", "snapped", "gnawed") + + say_list_type = /datum/say_list/siffet + ai_holder_type = /datum/ai_holder/simple_mob/siffet + +/datum/say_list/siffet + speak = list("Yap!", "Heh!", "Huff.") + emote_see = list("sniffs its surroundings","flicks its ears", "scratches the ground") + emote_hear = list("chatters", "huffs") + +/datum/ai_holder/simple_mob/siffet + hostile = TRUE + retaliate = TRUE + +/datum/ai_holder/simple_mob/siffet/post_melee_attack(atom/A) //Evasive + if(holder.Adjacent(A)) + holder.IMove(get_step(holder, pick(alldirs))) + holder.face_atom(A) + +/mob/living/simple_mob/animal/sif/siffet/IIsAlly(mob/living/L) + . = ..() + if(!. && L.mob_size > 10) //Attacks things it considers small enough to take on, otherwise only attacks if attacked. + return TRUE \ No newline at end of file diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm index 7de14dc6e7f..95029403437 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm @@ -64,6 +64,8 @@ pixel_x = -16 old_x = -16 + icon_expected_width = 64 + icon_expected_height = 64 meat_amount = 5 /mob/living/simple_mob/animal/space/alien/queen @@ -95,6 +97,8 @@ pixel_x = -16 old_x = -16 + icon_expected_width = 64 + icon_expected_height = 64 /mob/living/simple_mob/animal/space/alien/queen/empress/mother name = "alien mother" @@ -111,6 +115,8 @@ pixel_x = -32 old_x = -32 + icon_expected_width = 96 + icon_expected_height = 96 /mob/living/simple_mob/animal/space/alien/death() ..() diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm index ddd852f7793..52b8e369a9b 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm @@ -87,6 +87,8 @@ pixel_x = -16 default_pixel_x = -16 + icon_expected_width = 64 + icon_expected_height = 32 meat_amount = 3 @@ -108,6 +110,8 @@ pixel_y = -16 default_pixel_y = -16 + icon_expected_width = 64 + icon_expected_height = 64 meat_amount = 10 diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/phazon.dmglass.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/phazon.dmglass.dm new file mode 100644 index 00000000000..e69de29bb2d diff --git a/code/modules/mob/living/simple_mob/subtypes/occult/constructs/juggernaut.dm b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/juggernaut.dm index 8a56f08ddd4..2898eecf45a 100644 --- a/code/modules/mob/living/simple_mob/subtypes/occult/constructs/juggernaut.dm +++ b/code/modules/mob/living/simple_mob/subtypes/occult/constructs/juggernaut.dm @@ -45,7 +45,7 @@ "rad" = 100) /mob/living/simple_mob/construct/juggernaut/Life() - weakened = 0 + SetWeakened(0) ..() /mob/living/simple_mob/construct/juggernaut/bullet_act(var/obj/item/projectile/P) diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm b/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm index 8c9f08a4717..1245278421a 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm @@ -1,5 +1,5 @@ /mob/living/simple_mob/vore/horse - name = "horse" + name = "small horse" desc = "Don't look it in the mouth." tt_desc = "Equus ferus caballus" @@ -12,7 +12,7 @@ maxHealth = 60 health = 60 - movement_cooldown = 4 //horses are fast mkay. + movement_cooldown = 1.5 //horses are fast mkay. see_in_dark = 6 response_help = "pets" @@ -35,18 +35,44 @@ say_list_type = /datum/say_list/horse ai_holder_type = /datum/ai_holder/simple_mob/retaliate +/mob/living/simple_mob/vore/horse/big + name = "horse" + icon_state = "horse" + icon_living = "horse" + icon_dead = "horse-dead" + icon = 'icons/mob/vore64x64.dmi' + + maxHealth = 120 + health = 120 + + melee_damage_lower = 5 + melee_damage_upper = 15 + attacktext = list("kicked") + + meat_amount = 6 + + old_x = -16 + old_y = 0 + default_pixel_x = -16 + pixel_x = -16 + pixel_y = 0 + mount_offset_y = 22 + // Activate Noms! /mob/living/simple_mob/vore/horse vore_active = 1 vore_icons = SA_ICON_LIVING +/mob/living/simple_mob/vore/horse/big + vore_capacity = 2 + /mob/living/simple_mob/vore/horse/Login() . = ..() if(!riding_datum) riding_datum = new /datum/riding/simple_mob(src) verbs |= /mob/living/simple_mob/proc/animal_mount verbs |= /mob/living/proc/toggle_rider_reins - movement_cooldown = 3 + movement_cooldown = 1.5 /mob/living/simple_mob/vore/horse/MouseDrop_T(mob/living/M, mob/living/user) return diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm b/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm index 23c6c4b1d3d..16fa33596ab 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm @@ -5,6 +5,7 @@ icon_state = "panther" icon_living = "panther" + icon_rest = "panther-rest" icon_dead = "panther-dead" icon = 'icons/mob/vore64x64.dmi' vis_height = 64 diff --git a/code/modules/mob/living/status_indicators.dm b/code/modules/mob/living/status_indicators.dm new file mode 100644 index 00000000000..a3f386b9e6d --- /dev/null +++ b/code/modules/mob/living/status_indicators.dm @@ -0,0 +1,88 @@ +#define STATUS_INDICATOR_Y_OFFSET 2 // Offset from the edge of the icon sprite, so 32 pixels plus whatever number is here. +#define STATUS_INDICATOR_ICON_X_SIZE 16 // Don't need to care about the Y size due to the origin being on the bottom side. +#define STATUS_INDICATOR_ICON_MARGIN 2 // The space between two status indicators. + +// 'Status indicators' are icons that display over a mob's head, that visually indicate that the mob is suffering +// from some kind of effect, such as being stunned, blinded, confused, asleep, etc. +// The icons are managed automatically by the mob itself, so that their positions will shift if another indicator is added, +// and it will try to always be above the mob sprite, even for larger sprites like xenos. + +/mob/living + var/list/status_indicators = null // Will become a list as needed. + +// Adds an icon_state, or image overlay, to the list of indicators to be managed automatically. +// Also initializes the list if one doesn't exist. +/mob/living/proc/add_status_indicator(image/thing) + if(get_status_indicator(thing)) // No duplicates, please. + return + + if(!istype(thing, /image)) + thing = image(icon = 'icons/mob/status_indicators.dmi', icon_state = thing) + + LAZYADD(status_indicators, thing) + handle_status_indicators() + +// Similar to above but removes it instead, and nulls the list if it becomes empty as a result. +/mob/living/proc/remove_status_indicator(image/thing) + thing = get_status_indicator(thing) + + cut_overlay(thing) + LAZYREMOVE(status_indicators, thing) + handle_status_indicators() + +/mob/living/proc/get_status_indicator(image/thing) + if(!istype(thing, /image)) + for(var/image/I in status_indicators) + if(I.icon_state == thing) + return I + return LAZYACCESS(status_indicators, LAZYFIND(status_indicators, thing)) + +// Refreshes the indicators over a mob's head. Should only be called when adding or removing a status indicator with the above procs, +// or when the mob changes size visually for some reason. +/mob/living/proc/handle_status_indicators() + // First, get rid of all the overlays. + for(var/thing in status_indicators) + cut_overlay(thing) + + if(!LAZYLEN(status_indicators)) + return + + if(stat == DEAD) + return + + // Now put them back on in the right spot. + var/our_sprite_x = icon_expected_width * get_icon_scale_x() + var/our_sprite_y = icon_expected_height * get_icon_scale_y() + + var/x_offset = our_sprite_x // Add your own offset here later if you want. + var/y_offset = our_sprite_y + STATUS_INDICATOR_Y_OFFSET + + // Calculates how 'long' the row of indicators and the margin between them should be. + // The goal is to have the center of that row be horizontally aligned with the sprite's center. + var/expected_status_indicator_length = (STATUS_INDICATOR_ICON_X_SIZE * status_indicators.len) + (STATUS_INDICATOR_ICON_MARGIN * max(status_indicators.len - 1, 0)) + var/current_x_position = (x_offset / 2) - (expected_status_indicator_length / 2) + + // In /mob/living's `update_transform()`, the sprite is horizontally shifted when scaled up, so that the center of the sprite doesn't move to the right. + // Because of that, this adjustment needs to happen with the future indicator row as well, or it will look bad. + current_x_position -= (icon_expected_width / 2) * (get_icon_scale_y() - 1) + + // Now the indicator row can actually be built. + for(var/thing in status_indicators) + var/image/I = thing + + // This is a semi-HUD element, in a similar manner as medHUDs, in that they're 'above' everything else in the world, + // but don't pierce obfuscation layers such as blindness or darkness, unlike actual HUD elements like inventory slots. + I.plane = PLANE_STATUS + I.layer = HUD_LAYER + I.appearance_flags = PIXEL_SCALE|TILE_BOUND|NO_CLIENT_COLOR|RESET_COLOR|RESET_ALPHA|RESET_TRANSFORM|KEEP_APART + I.pixel_y = y_offset + I.pixel_x = current_x_position + add_overlay(I) + // Adding the margin space every time saves a conditional check on the last iteration, + // and it won't cause any issues since no more icons will be added, and the var is not used for anything else. + current_x_position += STATUS_INDICATOR_ICON_X_SIZE + STATUS_INDICATOR_ICON_MARGIN + + +#undef STATUS_INDICATOR_Y_OFFSET +#undef STATUS_INDICATOR_ICON_X_SIZE +#undef STATUS_INDICATOR_ICON_MARGIN diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index e83f10116a2..d6f04cd0d59 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -66,6 +66,10 @@ plane_holder.set_ao(VIS_OBJS, ao_enabled) plane_holder.set_ao(VIS_MOBS, ao_enabled) + // Status indicators + var/status_enabled = client.is_preference_enabled(/datum/client_preference/status_indicators) + plane_holder.set_vis(VIS_STATUS, status_enabled) + //set macro to normal incase it was overriden (like cyborg currently does) client.set_hotkeys_macro("macro", "hotkeymode") diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index 49ab504956c..ffaeef3c09d 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -1,5 +1,6 @@ /mob/Logout() SSnanoui.user_logout(src) // this is used to clean up (remove) this user's Nano UIs + SStgui.on_logout(src) // Cleanup any TGUIs the user has open player_list -= src disconnect_time = world.realtime //VOREStation Addition: logging when we disappear. update_client_z(null) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 2ba47726968..e4327ddc831 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -343,7 +343,7 @@ /mob/proc/set_respawn_timer(var/time) // Try to figure out what time to use - + // Special cases, can never respawn if(ticker?.mode?.deny_respawn) time = -1 @@ -351,22 +351,22 @@ time = -1 else if(!config.respawn) time = -1 - + // Special case for observing before game start else if(ticker?.current_state <= GAME_STATE_SETTING_UP) time = 1 MINUTE - + // Wasn't given a time, use the config time else if(!time) time = config.respawn_time - + var/keytouse = ckey // Try harder to find a key to use if(!keytouse && key) keytouse = ckey(key) else if(!keytouse && mind?.key) keytouse = ckey(mind.key) - + GLOB.respawn_timers[keytouse] = world.time + time /mob/observer/dead/set_respawn_timer() @@ -388,7 +388,7 @@ var/choice = alert(usr, "Returning to the menu will prevent your character from being revived in-round. Are you sure?", "Confirmation", "No, wait", "Yes, leave") if(choice == "No, wait") return - + // Beyond this point, you're going to respawn to_chat(usr, config.respawn_message) @@ -505,6 +505,11 @@ set category = "IC" if(pulling) + if(ishuman(pulling)) + var/mob/living/carbon/human/H = pulling + visible_message(SPAN_WARNING("\The [src] lets go of \the [H]."), SPAN_NOTICE("You let go of \the [H]."), exclude_mobs = list(H)) + if(!H.stat) + to_chat(H, SPAN_WARNING("\The [src] lets go of you.")) pulling.pulledby = null pulling = null if(pullin) @@ -576,6 +581,16 @@ if(ishuman(AM)) var/mob/living/carbon/human/H = AM + if(H.lying) // If they're on the ground we're probably dragging their arms to move them + visible_message(SPAN_WARNING("\The [src] leans down and grips \the [H]'s arms."), SPAN_NOTICE("You lean down and grip \the [H]'s arms."), exclude_mobs = list(H)) + if(!H.stat) + to_chat(H, SPAN_WARNING("\The [src] leans down and grips your arms.")) + else //Otherwise we're probably just holding their arm to lead them somewhere + visible_message(SPAN_WARNING("\The [src] grips \the [H]'s arm."), SPAN_NOTICE("You grip \the [H]'s arm."), exclude_mobs = list(H)) + if(!H.stat) + to_chat(H, SPAN_WARNING("\The [src] grips your arm.")) + playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 25) //Quieter than hugging/grabbing but we still want some audio feedback + if(H.pull_damage()) to_chat(src, "Pulling \the [H] in their current condition would probably be a bad idea.") diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 0b516955ef7..7be3255cbd1 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -181,6 +181,7 @@ var/status_flags = CANSTUN|CANWEAKEN|CANPARALYSE|CANPUSH //bitflags defining which status effects can be inflicted (replaces canweaken, canstun, etc) var/area/lastarea = null + var/lastareachange = null var/digitalcamo = 0 // Can they be tracked by the AI? @@ -224,4 +225,6 @@ var/registered_z - var/list/progressbars = null //for stacking do_after bars \ No newline at end of file + var/in_enclosed_vehicle = 0 //For mechs and fighters ambiance. Can be used in other cases. + + var/list/progressbars = null //VOREStation Edit diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 58d00da19fa..3de17ee8efb 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -197,7 +197,7 @@ return result // Can't control ourselves when drifting - if(isspace(loc) || my_mob.lastarea?.has_gravity == 0) + if((isspace(loc) || my_mob.lastarea?.has_gravity == 0) && !my_mob.in_enclosed_vehicle) //If(In space or last area had no gravity) or(you in vehicle) if(!my_mob.Process_Spacemove(0)) return 0 @@ -295,7 +295,7 @@ // It's just us and another person if(grablist.len == 1) var/mob/M = grablist[1] - if(!my_mob.Adjacent(M)) //Oh no, we moved away + if(M && !my_mob.Adjacent(M)) //Oh no, we moved away M.Move(pre_move_loc, get_dir(M, pre_move_loc), total_delay) //Have them step towards where we were // It's a grab chain diff --git a/code/modules/mob/mob_planes.dm b/code/modules/mob/mob_planes.dm index e1c33efe726..241840321aa 100644 --- a/code/modules/mob/mob_planes.dm +++ b/code/modules/mob/mob_planes.dm @@ -11,6 +11,7 @@ my_mob = this_guy //It'd be nice to lazy init these but some of them are important to just EXIST. Like without ghost planemaster, you can see ghosts. Go figure. + //Note, if you're adding a new plane master, please update code\modules\tgui\modules\camera.dm. // 'Utility' planes plane_masters[VIS_FULLBRIGHT] = new /obj/screen/plane_master/fullbright //Lighting system (lighting_overlay objects) @@ -29,6 +30,8 @@ plane_masters[VIS_CH_SPECIAL] = new /obj/screen/plane_master{plane = PLANE_CH_SPECIAL} //"Special" role stuff plane_masters[VIS_CH_STATUS_OOC]= new /obj/screen/plane_master{plane = PLANE_CH_STATUS_OOC} //OOC status HUD + plane_masters[VIS_STATUS] = new /obj/screen/plane_master{plane = PLANE_STATUS} //Status indicators that show over mob heads. + plane_masters[VIS_ADMIN1] = new /obj/screen/plane_master{plane = PLANE_ADMIN1} //For admin use plane_masters[VIS_ADMIN2] = new /obj/screen/plane_master{plane = PLANE_ADMIN2} //For admin use plane_masters[VIS_ADMIN3] = new /obj/screen/plane_master{plane = PLANE_ADMIN3} //For admin use diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 939856c7a2a..94c69622c47 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -451,19 +451,19 @@ character.buckled.set_dir(character.dir) ticker.mode.latespawn(character) - + if(J.mob_type & JOB_SILICON) AnnounceCyborg(character, rank, join_message, announce_channel, character.z) else AnnounceArrival(character, rank, join_message, announce_channel, character.z) data_core.manifest_inject(character) ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn - + qdel(src) // Delete new_player mob /mob/new_player/proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message, var/channel, var/zlevel) if (ticker.current_state == GAME_STATE_PLAYING) - var/list/zlevels = zlevel ? using_map.get_map_levels(zlevel, TRUE) : null + var/list/zlevels = zlevel ? using_map.get_map_levels(zlevel, TRUE, om_range = DEFAULT_OVERMAP_RANGE) : null if(character.mind.role_alt_title) rank = character.mind.role_alt_title // can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc. @@ -582,7 +582,6 @@ // Do the initial caching of the player's body icons. new_character.force_update_limbs() new_character.update_icons_body() - new_character.update_eyes() new_character.key = key //Manually transfer the key to log them in diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 2bf54878b2d..b5b1e205c7f 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -1126,23 +1126,23 @@ //Skrell 'hairstyles' skr_tentacle_veryshort - name = "Skrell Very Short Tentacles" - icon_state = "skrell_hair_veryshort" + name = "Skrell Short Tentacles" + icon_state = "skrell_hair_short" species_allowed = list(SPECIES_SKRELL) gender = MALE skr_tentacle_short - name = "Skrell Short Tentacles" - icon_state = "skrell_hair_short" - species_allowed = list(SPECIES_SKRELL) - - skr_tentacle_average name = "Skrell Average Tentacles" icon_state = "skrell_hair_average" species_allowed = list(SPECIES_SKRELL) - skr_tentacle_verylong + skr_tentacle_average name = "Skrell Long Tentacles" + icon_state = "skrell_hair_long" + species_allowed = list(SPECIES_SKRELL) + + skr_tentacle_verylong + name = "Skrell Very Long Tentacles" icon_state = "skrell_hair_verylong" species_allowed = list(SPECIES_SKRELL) gender = FEMALE @@ -1304,6 +1304,35 @@ icon_state = "teshari_mushroom" species_allowed = list(SPECIES_TESHARI) +//Tesh things ported from Ark Station + + teshari_twies + name = "Teshari Twies" + icon_state = "teshari_twies" + species_allowed = list(SPECIES_TESHARI) + + teshari_backstrafe + name = "Teshari Backstrafe" + icon_state = "teshari_backstrafe" + species_allowed = list(SPECIES_TESHARI) + + teshari_longway + name = "Teshari Long way" + icon_state = "teshari_longway" + species_allowed = list(SPECIES_TESHARI) + + teshari_tree + name = "Teshari Tree" + icon_state = "teshari_tree" + species_allowed = list(SPECIES_TESHARI) + + teshari_fluffymohawk + name = "Teshari Fluffy Mohawk" + icon_state = "teshari_fluffymohawk" + species_allowed = list(SPECIES_TESHARI) + +//bald tesh hair for FBP use + teshari_bald name = "Bald (use with FBP)" icon_state = "bald" diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 7a20d0ee8e6..7a8f2412f2b 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -118,7 +118,7 @@ return get_turf(src) -/mob/proc/say_test(var/text) +/proc/say_test(var/text) var/ending = copytext(text, length(text)) if(ending == "?") return "1" diff --git a/code/modules/modular_computers/NTNet/NTNet_relay.dm b/code/modules/modular_computers/NTNet/NTNet_relay.dm index 85daf5d03d3..9e39fe8e2e9 100644 --- a/code/modules/modular_computers/NTNet/NTNet_relay.dm +++ b/code/modules/modular_computers/NTNet/NTNet_relay.dm @@ -57,41 +57,43 @@ ntnet_global.add_log("Quantum relay switched from overload recovery mode to normal operation mode.") ..() -/obj/machinery/ntnet_relay/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) +/obj/machinery/ntnet_relay/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "NTNetRelay", src) + ui.open() + +/obj/machinery/ntnet_relay/tgui_data(mob/user) var/list/data = list() data["enabled"] = enabled data["dos_capacity"] = dos_capacity data["dos_overload"] = dos_overload data["dos_crashed"] = dos_failure - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "ntnet_relay.tmpl", "NTNet Quantum Relay", 500, 300, state = state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data /obj/machinery/ntnet_relay/attack_hand(var/mob/living/user) - ui_interact(user) + tgui_interact(user) -/obj/machinery/ntnet_relay/Topic(href, href_list) +/obj/machinery/ntnet_relay/tgui_act(action, params) if(..()) - return 1 - if(href_list["restart"]) - dos_overload = 0 - dos_failure = 0 - update_icon() - ntnet_global.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.") - return 1 - else if(href_list["toggle"]) - enabled = !enabled - ntnet_global.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].") - update_icon() - return 1 - else if(href_list["purge"]) - ntnet_global.banned_nids.Cut() - ntnet_global.add_log("Manual override: Network blacklist cleared.") - return 1 + return TRUE + + switch(action) + if("restart") + dos_overload = 0 + dos_failure = 0 + update_icon() + ntnet_global.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.") + . = TRUE + if("toggle") + enabled = !enabled + ntnet_global.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].") + update_icon() + . = TRUE + if("purge") + ntnet_global.banned_nids.Cut() + ntnet_global.add_log("Manual override: Network blacklist cleared.") + . = TRUE /obj/machinery/ntnet_relay/New() ..() diff --git a/code/modules/modular_computers/computers/modular_computer/core.dm b/code/modules/modular_computers/computers/modular_computer/core.dm index db15e841cad..97b4cfe8518 100644 --- a/code/modules/modular_computers/computers/modular_computer/core.dm +++ b/code/modules/modular_computers/computers/modular_computer/core.dm @@ -163,6 +163,7 @@ idle_threads.Add(active_program) active_program.program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs SSnanoui.close_uis(active_program.NM ? active_program.NM : active_program) + SStgui.close_uis(active_program.TM ? active_program.TM : active_program) active_program = null update_icon() if(istype(user)) @@ -202,7 +203,6 @@ minimize_program(user) if(P.run_program(user)) - active_program = P update_icon() return 1 diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index ef7eece062f..9e011f442db 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -5,8 +5,13 @@ var/required_access = null // List of required accesses to run/download the program. var/requires_access_to_run = 1 // Whether the program checks for required_access when run. var/requires_access_to_download = 1 // Whether the program checks for required_access when downloading. + // NanoModule var/datum/nano_module/NM = null // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement ui_interact. var/nanomodule_path = null // Path to nanomodule, make sure to set this if implementing new program. + // TGUIModule + var/datum/tgui_module/TM = null // If the program uses TGUIModule, put it here and it will be automagically opened. Otherwise implement tgui_interact. + var/tguimodule_path = null // Path to tguimodule, make sure to set this if implementing new program. + // Etc Program stuff var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running. var/obj/item/modular_computer/computer // Device that runs this program. var/filedesc = "Unknown Program" // User-friendly name of this program. @@ -37,6 +42,9 @@ /datum/computer_file/program/nano_host() return computer.nano_host() +/datum/computer_file/program/tgui_host() + return computer.tgui_host() + /datum/computer_file/program/clone() var/datum/computer_file/program/temp = ..() temp.required_access = required_access @@ -125,9 +133,14 @@ // When implementing new program based device, use this to run the program. /datum/computer_file/program/proc/run_program(var/mob/living/user) if(can_run(user, 1) || !requires_access_to_run) + computer.active_program = src if(nanomodule_path) NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src) NM.using_access = user.GetAccess() + if(tguimodule_path) + TM = new tguimodule_path(src) + TM.using_access = user.GetAccess() + TM.tgui_interact(user) if(requires_ntnet && network_destination) generate_network_log("Connection opened to [network_destination].") program_state = PROGRAM_STATE_ACTIVE @@ -139,9 +152,11 @@ program_state = PROGRAM_STATE_KILLED if(network_destination) generate_network_log("Connection to [network_destination] closed.") - if(NM) - qdel(NM) - NM = null + QDEL_NULL(NM) + if(TM) + SStgui.close_uis(TM) + qdel(TM) + TM = null return 1 // This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation. @@ -154,9 +169,11 @@ if(istype(NM)) NM.ui_interact(user, ui_key, null, force_open) return 0 + if(istype(TM)) + TM.tgui_interact(user) + return 0 return 1 - // CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC: // Topic calls are automagically forwarded from NanoModule this program contains. // Calls beginning with "PRG_" are reserved for programs handling. diff --git a/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm b/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm index 27e5a26c3fb..4c1b1537341 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/camera_monitor/hacked filename = "camcrypt" filedesc = "Camera Decryption Tool" - nanomodule_path = /datum/nano_module/camera_monitor/hacked + tguimodule_path = /datum/tgui_module/camera/ntos/hacked program_icon_state = "hostile" program_key_state = "security_key" program_menu_icon = "zoomin" @@ -15,25 +15,8 @@ if(program_state != PROGRAM_STATE_ACTIVE) // Background programs won't trigger alarms. return - var/datum/nano_module/camera_monitor/hacked/HNM = NM - // The program is active and connected to one of the station's networks. Has a very small chance to trigger IDS alarm every tick. - if(HNM && HNM.current_network && (HNM.current_network in using_map.station_networks) && prob(0.1)) + if(prob(0.1)) if(ntnet_global.intrusion_detection_enabled) - ntnet_global.add_log("IDS WARNING - Unauthorised access detected to camera network [HNM.current_network] by device with NID [computer.network_card.get_network_tag()]") + ntnet_global.add_log("IDS WARNING - Unauthorised access detected to camera network by device with NID [computer.network_card.get_network_tag()]") ntnet_global.intrusion_detection_alarm = 1 - - -/datum/nano_module/camera_monitor/hacked - name = "Hacked Camera Monitoring Program" - //available_to_ai = FALSE - -/datum/nano_module/camera_monitor/hacked/can_access_network(var/mob/user, var/network_access) - return 1 - -// The hacked variant has access to all commonly used networks. -/datum/nano_module/camera_monitor/hacked/modify_networks_list(var/list/networks) - networks.Add(list(list("tag" = NETWORK_MERCENARY, "has_access" = 1))) - networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1))) - networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1))) - return networks \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/engineering/alarm_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/alarm_monitor.dm index 8c03238bff8..d7f13fcbc53 100644 --- a/code/modules/modular_computers/file_system/programs/engineering/alarm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/alarm_monitor.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/alarm_monitor filename = "alarmmonitoreng" filedesc = "Alarm Monitoring (Engineering)" - nanomodule_path = /datum/nano_module/alarm_monitor/engineering + tguimodule_path = /datum/tgui_module/alarm_monitor/engineering/ntos ui_header = "alarm_green.gif" program_icon_state = "alert-green" program_key_state = "atmos_key" @@ -15,8 +15,8 @@ /datum/computer_file/program/alarm_monitor/process_tick() ..() - var/datum/nano_module/alarm_monitor/NMA = NM - if(istype(NMA) && NMA.has_major_alarms()) + var/datum/tgui_module/alarm_monitor/TMA = TM + if(istype(TMA) && TMA.has_major_alarms()) if(!has_alert) program_icon_state = "alert-red" ui_header = "alarm_red.gif" @@ -29,112 +29,3 @@ update_computer_icon() has_alert = 0 return 1 - -/datum/nano_module/alarm_monitor - name = "Alarm monitor" - var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use. - var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user. - //available_to_ai = FALSE - -/datum/nano_module/alarm_monitor/New() - ..() - alarm_handlers = list() - -/datum/nano_module/alarm_monitor/all/New() - ..() - alarm_handlers = SSalarm.all_handlers - -/datum/nano_module/alarm_monitor/engineering/New() - ..() - alarm_handlers = list(atmosphere_alarm, fire_alarm, power_alarm) - -/datum/nano_module/alarm_monitor/security/New() - ..() - alarm_handlers = list(camera_alarm, motion_alarm) - -/datum/nano_module/alarm_monitor/proc/register_alarm(var/object, var/procName) - for(var/datum/alarm_handler/AH in alarm_handlers) - AH.register_alarm(object, procName) - -/datum/nano_module/alarm_monitor/proc/unregister_alarm(var/object) - for(var/datum/alarm_handler/AH in alarm_handlers) - AH.unregister_alarm(object) - -/datum/nano_module/alarm_monitor/proc/all_alarms() - var/z = get_z(nano_host()) - var/list/all_alarms = new() - for(var/datum/alarm_handler/AH in alarm_handlers) - all_alarms += AH.visible_alarms(z) - - return all_alarms - -/datum/nano_module/alarm_monitor/proc/major_alarms() - var/z = get_z(nano_host()) - var/list/all_alarms = new() - for(var/datum/alarm_handler/AH in alarm_handlers) - all_alarms += AH.major_alarms(z) - - return all_alarms - -// Modified version of above proc that uses slightly less resources, returns 1 if there is a major alarm, 0 otherwise. -/datum/nano_module/alarm_monitor/proc/has_major_alarms() - var/z = get_z(nano_host()) - for(var/datum/alarm_handler/AH in alarm_handlers) - if(AH.has_major_alarms(z)) - return 1 - - return 0 - -/datum/nano_module/alarm_monitor/proc/minor_alarms() - var/z = get_z(nano_host()) - var/list/all_alarms = new() - for(var/datum/alarm_handler/AH in alarm_handlers) - all_alarms += AH.minor_alarms(z) - - return all_alarms - -/datum/nano_module/alarm_monitor/Topic(ref, href_list) - if(..()) - return 1 - if(href_list["switchTo"]) - var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras - if(!C) - return - - usr.switch_to_camera(C) - return 1 - -/datum/nano_module/alarm_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/list/data = host.initial_data() - - var/categories[0] - var/z = get_z(nano_host()) - for(var/datum/alarm_handler/AH in alarm_handlers) - categories[++categories.len] = list("category" = AH.category, "alarms" = list()) - for(var/datum/alarm/A in AH.visible_alarms(z)) - var/cameras[0] - var/lost_sources[0] - - if(isAI(user)) - for(var/obj/machinery/camera/C in A.cameras()) - cameras[++cameras.len] = C.nano_structure() - for(var/datum/alarm_source/AS in A.sources) - if(!AS.source) - lost_sources[++lost_sources.len] = AS.source_name - - categories[categories.len]["alarms"] += list(list( - "name" = sanitize("[A.alarm_name()]" + "[A.max_severity() > 1 ? "(MAJOR)" : ""]"), - "origin_lost" = A.origin == null, - "has_cameras" = cameras.len, - "cameras" = cameras, - "lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : "")) - data["categories"] = categories - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring Console", 800, 800, state = state) - if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. - ui.auto_update_layout = 1 - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/engineering/atmos_control.dm b/code/modules/modular_computers/file_system/programs/engineering/atmos_control.dm index bfcaadee3e9..5c25ed8315a 100644 --- a/code/modules/modular_computers/file_system/programs/engineering/atmos_control.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/atmos_control.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/atmos_control filename = "atmoscontrol" filedesc = "Atmosphere Control" - nanomodule_path = /datum/nano_module/atmos_control + tguimodule_path = /datum/tgui_module/atmos_control/ntos program_icon_state = "atmos_control" program_key_state = "atmos_key" program_menu_icon = "shuffle" @@ -12,96 +12,3 @@ requires_ntnet_feature = NTNET_SYSTEMCONTROL usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE size = 17 - -/datum/nano_module/atmos_control - name = "Atmospherics Control" - var/obj/access = new() - var/emagged = 0 - var/ui_ref - var/list/monitored_alarms = list() - -/datum/nano_module/atmos_control/New(atmos_computer, req_access, req_one_access, monitored_alarm_ids) - ..() - access.req_access = req_access - access.req_one_access = req_one_access - - if(monitored_alarm_ids) - for(var/obj/machinery/alarm/alarm in machines) - if(alarm.alarm_id && alarm.alarm_id in monitored_alarm_ids) - monitored_alarms += alarm - // machines may not yet be ordered at this point - monitored_alarms = dd_sortedObjectList(monitored_alarms) - -/datum/nano_module/atmos_control/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["alarm"]) - if(ui_ref) - var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms.len ? monitored_alarms : machines) - if(alarm) - var/datum/topic_state/TS = generate_state(alarm) - alarm.ui_interact(usr, master_ui = ui_ref, state = TS) - return 1 - -/datum/nano_module/atmos_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state) - var/list/data = host.initial_data() - var/alarms[0] - - var/z = get_z(nano_host()) - var/list/map_levels = using_map.get_map_levels(z) - data["map_levels"] = map_levels - - // TODO: Move these to a cache, similar to cameras - for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : machines)) - if(!monitored_alarms.len && alarm.alarms_hidden) - continue - if(!(alarm.z in map_levels)) - continue - alarms[++alarms.len] = list( - "name" = sanitize(alarm.name), - "ref"= "\ref[alarm]", - "danger" = max(alarm.danger_level, alarm.alarm_area.atmosalm), - "x" = alarm.x, - "y" = alarm.y, - "z" = alarm.z) - data["alarms"] = alarms - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 625, 625, state = state) - if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. - ui.auto_update_layout = 1 - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "atmos_control_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "atmos_control_map_header.tmpl") - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(0) - ui_ref = ui - -/datum/nano_module/atmos_control/proc/generate_state(air_alarm) - var/datum/topic_state/air_alarm/state = new() - state.atmos_control = src - state.air_alarm = air_alarm - return state - -/datum/topic_state/air_alarm - var/datum/nano_module/atmos_control/atmos_control = null - var/obj/machinery/alarm/air_alarm = null - -/datum/topic_state/air_alarm/can_use_topic(var/src_object, var/mob/user) - if(has_access(user)) - return STATUS_INTERACTIVE - return STATUS_UPDATE - -/datum/topic_state/air_alarm/href_list(var/mob/user) - var/list/extra_href = list() - extra_href["remote_connection"] = 1 - extra_href["remote_access"] = has_access(user) - - return extra_href - -/datum/topic_state/air_alarm/proc/has_access(var/mob/user) - return user && (isAI(user) || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO) || (access_ce in user.GetAccess())) diff --git a/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm index b5c086dc260..5df437790b1 100644 --- a/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/power_monitor.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/power_monitor filename = "powermonitor" filedesc = "Power Monitoring" - nanomodule_path = /datum/nano_module/power_monitor/ + tguimodule_path = /datum/tgui_module/power_monitor/ntos program_icon_state = "power_monitor" program_key_state = "power_key" program_menu_icon = "battery-3" @@ -15,8 +15,8 @@ /datum/computer_file/program/power_monitor/process_tick() ..() - var/datum/nano_module/power_monitor/NMA = NM - if(istype(NMA) && NMA.has_alarm()) + var/datum/tgui_module/power_monitor/TMA = TM + if(istype(TMA) && TMA.has_alarm()) if(!has_alert) program_icon_state = "power_monitor_warn" ui_header = "power_warn.gif" @@ -28,90 +28,3 @@ ui_header = "power_norm.gif" update_computer_icon() has_alert = 0 - -/datum/nano_module/power_monitor - name = "Power monitor" - var/list/grid_sensors - var/active_sensor = null //name_tag of the currently selected sensor - -/datum/nano_module/power_monitor/New() - ..() - refresh_sensors() - -// Checks whether there is an active alarm, if yes, returns 1, otherwise returns 0. -/datum/nano_module/power_monitor/proc/has_alarm() - for(var/obj/machinery/power/sensor/S in grid_sensors) - if(S.check_grid_warning()) - return 1 - return 0 - -// If PC is not null header template is loaded. Use PC.get_header_data() to get relevant nanoui data from it. All data entries begin with "PC_...." -// In future it may be expanded to other modular computer devices. -/datum/nano_module/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/list/data = host.initial_data() - - var/list/sensors = list() - // Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading. - var/obj/machinery/power/sensor/focus = null - - var/z = get_z(nano_host()) - var/list/map_levels = using_map.get_map_levels(z) - data["map_levels"] = map_levels - - // Build list of data from sensor readings. - for(var/obj/machinery/power/sensor/S in grid_sensors) - if(!(S.z in map_levels)) - continue - sensors.Add(list(list( - "name" = S.name_tag, - "alarm" = S.check_grid_warning() - ))) - if(S.name_tag == active_sensor) - focus = S - - data["all_sensors"] = sensors - if(focus) - data["focus"] = focus.return_reading_data() - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "power_monitor.tmpl", "Power Monitoring Console", 800, 500, state = state) - if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. - ui.auto_update_layout = 1 - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "power_monitor_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "power_monitor_map_header.tmpl") - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -// Refreshes list of active sensors kept on this computer. -/datum/nano_module/power_monitor/proc/refresh_sensors() - grid_sensors = list() - var/turf/T = get_turf(nano_host()) - var/list/levels = list() - if(!T) // Safety check - return - if(T) - levels += using_map.get_map_levels(T.z, FALSE) - for(var/obj/machinery/power/sensor/S in machines) - if(T && (S.loc.z == T.z) || (S.loc.z in levels) || (S.long_range)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels. - if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen! - warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z") - else - grid_sensors += S - -// Allows us to process UI clicks, which are relayed in form of hrefs. -/datum/nano_module/power_monitor/Topic(href, href_list) - if(..()) - return 1 - if( href_list["clear"] ) - active_sensor = null - . = 1 - if( href_list["refresh"] ) - refresh_sensors() - . = 1 - else if( href_list["setsensor"] ) - active_sensor = href_list["setsensor"] - . = 1 diff --git a/code/modules/modular_computers/file_system/programs/engineering/rcon_console.dm b/code/modules/modular_computers/file_system/programs/engineering/rcon_console.dm index 03f69cd9492..ded2e3922f0 100644 --- a/code/modules/modular_computers/file_system/programs/engineering/rcon_console.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/rcon_console.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/rcon_console filename = "rconconsole" filedesc = "RCON Remote Control" - nanomodule_path = /datum/nano_module/rcon + tguimodule_path = /datum/tgui_module/rcon/ntos program_icon_state = "generic" program_key_state = "rd_key" program_menu_icon = "power" @@ -12,129 +12,3 @@ requires_ntnet_feature = NTNET_SYSTEMCONTROL usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE size = 19 - -/datum/nano_module/rcon - name = "Power RCON" - var/list/known_SMESs = null - var/list/known_breakers = null - // Allows you to hide specific parts of the UI - var/hide_SMES = 0 - var/hide_SMES_details = 0 - var/hide_breakers = 0 - -/datum/nano_module/rcon/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1, var/datum/topic_state/state = default_state) - FindDevices() // Update our devices list - var/list/data = host.initial_data() - - // SMES DATA (simplified view) - var/list/smeslist[0] - for(var/obj/machinery/power/smes/buildable/SMES in known_SMESs) - smeslist.Add(list(list( - "charge" = round(SMES.Percentage()), - "input_set" = SMES.input_attempt, - "input_val" = round(SMES.input_level/1000, 0.1), - "output_set" = SMES.output_attempt, - "output_val" = round(SMES.output_level/1000, 0.1), - "output_load" = round(SMES.output_used/1000, 0.1), - "RCON_tag" = SMES.RCon_tag - ))) - - data["smes_info"] = sortByKey(smeslist, "RCON_tag") - - // BREAKER DATA (simplified view) - var/list/breakerlist[0] - for(var/obj/machinery/power/breakerbox/BR in known_breakers) - breakerlist.Add(list(list( - "RCON_tag" = BR.RCon_tag, - "enabled" = BR.on - ))) - data["breaker_info"] = breakerlist - data["hide_smes"] = hide_SMES - data["hide_smes_details"] = hide_SMES_details - data["hide_breakers"] = hide_breakers - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "rcon.tmpl", "RCON Console", 600, 400, state = state) - if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. - ui.auto_update_layout = 1 - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -// Proc: Topic() -// Parameters: 2 (href, href_list - allows us to process UI clicks) -// Description: Allows us to process UI clicks, which are relayed in form of hrefs. -/datum/nano_module/rcon/Topic(href, href_list) - if(..()) - return - - if(href_list["smes_in_toggle"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_toggle"]) - if(SMES) - SMES.toggle_input() - if(href_list["smes_out_toggle"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_toggle"]) - if(SMES) - SMES.toggle_output() - if(href_list["smes_in_set"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_set"]) - if(SMES) - var/inputset = (input(usr, "Enter new input level (0-[SMES.input_level_max/1000] kW)", "SMES Input Power Control", SMES.input_level/1000) as num) * 1000 - SMES.set_input(inputset) - if(href_list["smes_out_set"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_set"]) - if(SMES) - var/outputset = (input(usr, "Enter new output level (0-[SMES.output_level_max/1000] kW)", "SMES Output Power Control", SMES.output_level/1000) as num) * 1000 - SMES.set_output(outputset) - - if(href_list["toggle_breaker"]) - var/obj/machinery/power/breakerbox/toggle = null - for(var/obj/machinery/power/breakerbox/breaker in known_breakers) - if(breaker.RCon_tag == href_list["toggle_breaker"]) - toggle = breaker - if(toggle) - if(toggle.update_locked) - to_chat(usr, "The breaker box was recently toggled. Please wait before toggling it again.") - else - toggle.auto_toggle() - if(href_list["hide_smes"]) - hide_SMES = !hide_SMES - if(href_list["hide_smes_details"]) - hide_SMES_details = !hide_SMES_details - if(href_list["hide_breakers"]) - hide_breakers = !hide_breakers - - -// Proc: GetSMESByTag() -// Parameters: 1 (tag - RCON tag of SMES we want to look up) -// Description: Looks up and returns SMES which has matching RCON tag -/datum/nano_module/rcon/proc/GetSMESByTag(var/tag) - if(!tag) - return - - for(var/obj/machinery/power/smes/buildable/S in known_SMESs) - if(S.RCon_tag == tag) - return S - -// Proc: FindDevices() -// Parameters: None -// Description: Refreshes local list of known devices. -/datum/nano_module/rcon/proc/FindDevices() - known_SMESs = new /list() - - var/z = get_z(nano_host()) - var/list/map_levels = using_map.get_map_levels(z) - - for(var/obj/machinery/power/smes/buildable/SMES in GLOB.smeses) - if(!(SMES.z in map_levels)) - continue - if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon) - known_SMESs.Add(SMES) - - known_breakers = new /list() - for(var/obj/machinery/power/breakerbox/breaker in machines) - if(!(breaker.z in map_levels)) - continue - if(breaker.RCon_tag != "NO_TAG") - known_breakers.Add(breaker) diff --git a/code/modules/modular_computers/file_system/programs/engineering/shutoff_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/shutoff_monitor.dm index c46bb9c6676..e87991041e0 100644 --- a/code/modules/modular_computers/file_system/programs/engineering/shutoff_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/shutoff_monitor.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/shutoff_monitor filename = "shutoffmonitor" filedesc = "Shutoff Valve Monitoring" - nanomodule_path = /datum/nano_module/shutoff_monitor + tguimodule_path = /datum/tgui_module/shutoff_monitor/ntos program_icon_state = "atmos_control" program_key_state = "atmos_key" program_menu_icon = "wrench" @@ -11,53 +11,3 @@ network_destination = "shutoff valve control computer" size = 5 var/has_alert = 0 - -/datum/nano_module/shutoff_monitor - name = "Shutoff Valve Monitoring" - -/datum/nano_module/shutoff_monitor/Topic(ref, href_list) - if(..()) - return 1 - - if(href_list["toggle_enable"]) - var/obj/machinery/atmospherics/valve/shutoff/S = locate(href_list["toggle_enable"]) - if(!istype(S)) - return 0 - S.close_on_leaks = !S.close_on_leaks - return 1 - - if(href_list["toggle_open"]) - var/obj/machinery/atmospherics/valve/shutoff/S = locate(href_list["toggle_open"]) - if(!istype(S)) - return 0 - if(S.open) - S.close() - else - S.open() - return 1 - -/datum/nano_module/shutoff_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/list/data = host.initial_data() - var/list/valves = list() - - for(var/obj/machinery/atmospherics/valve/shutoff/S in GLOB.shutoff_valves) - valves.Add(list(list( - "name" = S.name, - "enabled" = S.close_on_leaks, - "open" = S.open, - "x" = S.x, - "y" = S.y, - "z" = S.z, - "ref" = "\ref[S]" - ))) - - data["valves"] = valves - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "shutoff_monitor.tmpl", "Shutoff Valve Monitoring", 627, 700, state = state) - if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI. - ui.auto_update_layout = 1 - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/engineering/supermatter_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/supermatter_monitor.dm index 421bb650474..9c3cabd3f70 100644 --- a/code/modules/modular_computers/file_system/programs/engineering/supermatter_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/supermatter_monitor.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/supermatter_monitor filename = "supmon" filedesc = "Supermatter Monitoring" - nanomodule_path = /datum/nano_module/supermatter_monitor/ + tguimodule_path = /datum/tgui_module/supermatter_monitor/ntos program_icon_state = "smmon_0" program_key_state = "tech_key" program_menu_icon = "notice" @@ -15,119 +15,11 @@ /datum/computer_file/program/supermatter_monitor/process_tick() ..() - var/datum/nano_module/supermatter_monitor/NMS = NM - var/new_status = istype(NMS) ? NMS.get_status() : 0 + var/datum/tgui_module/supermatter_monitor/TMS = TM + var/new_status = istype(TMS) ? TMS.get_status() : 0 if(last_status != new_status) last_status = new_status ui_header = "smmon_[last_status].gif" program_icon_state = "smmon_[last_status]" if(istype(computer)) computer.update_icon() - -/datum/nano_module/supermatter_monitor - name = "Supermatter monitor" - var/list/supermatters - var/obj/machinery/power/supermatter/active = null // Currently selected supermatter crystal. - -/datum/nano_module/supermatter_monitor/Destroy() - . = ..() - active = null - supermatters = null - -/datum/nano_module/supermatter_monitor/New() - ..() - refresh() - -// Refreshes list of active supermatter crystals -/datum/nano_module/supermatter_monitor/proc/refresh() - supermatters = list() - var/z = get_z(nano_host()) - if(!z) - return - var/valid_z_levels = using_map.get_map_levels(z) - for(var/obj/machinery/power/supermatter/S in machines) - // Delaminating, not within coverage, not on a tile. - if(S.grav_pulling || S.exploded || !(S.z in valid_z_levels) || !istype(S.loc, /turf/)) - continue - supermatters.Add(S) - - if(!(active in supermatters)) - active = null - -/datum/nano_module/supermatter_monitor/proc/get_status() - . = SUPERMATTER_INACTIVE - for(var/obj/machinery/power/supermatter/S in supermatters) - . = max(., S.get_status()) - -/datum/nano_module/supermatter_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/list/data = host.initial_data() - - if(istype(active)) - var/turf/T = get_turf(active) - if(!T) - active = null - return - var/datum/gas_mixture/air = T.return_air() - if(!istype(air)) - active = null - return - - data["active"] = 1 - data["SM_integrity"] = active.get_integrity() - data["SM_power"] = active.power - data["SM_ambienttemp"] = air.temperature - data["SM_ambientpressure"] = air.return_pressure() - data["SM_EPR"] = active.get_epr() - //data["SM_EPR"] = active.get_epr() - if(air.total_moles) - data["SM_gas_O2"] = round(100*air.gas["oxygen"]/air.total_moles,0.01) - data["SM_gas_CO2"] = round(100*air.gas["carbon_dioxide"]/air.total_moles,0.01) - data["SM_gas_N2"] = round(100*air.gas["nitrogen"]/air.total_moles,0.01) - data["SM_gas_PH"] = round(100*air.gas["phoron"]/air.total_moles,0.01) - data["SM_gas_N2O"] = round(100*air.gas["sleeping_agent"]/air.total_moles,0.01) - else - data["SM_gas_O2"] = 0 - data["SM_gas_CO2"] = 0 - data["SM_gas_N2"] = 0 - data["SM_gas_PH"] = 0 - data["SM_gas_N2O"] = 0 - else - var/list/SMS = list() - for(var/obj/machinery/power/supermatter/S in supermatters) - var/area/A = get_area(S) - if(!A) - continue - - SMS.Add(list(list( - "area_name" = A.name, - "integrity" = S.get_integrity(), - "uid" = S.uid - ))) - - data["active"] = 0 - data["supermatters"] = SMS - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "supermatter_monitor.tmpl", "Supermatter Monitoring", 600, 400, state = state) - if(host.update_layout()) - ui.auto_update_layout = 1 - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/datum/nano_module/supermatter_monitor/Topic(href, href_list) - if(..()) - return 1 - if( href_list["clear"] ) - active = null - return 1 - if( href_list["refresh"] ) - refresh() - return 1 - if( href_list["set"] ) - var/newuid = text2num(href_list["set"]) - for(var/obj/machinery/power/supermatter/S in supermatters) - if(S.uid == newuid) - active = S - return 1 \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/generic/camera.dm b/code/modules/modular_computers/file_system/programs/generic/camera.dm index e07d9ec293f..57948d6e8a5 100644 --- a/code/modules/modular_computers/file_system/programs/generic/camera.dm +++ b/code/modules/modular_computers/file_system/programs/generic/camera.dm @@ -30,7 +30,7 @@ /datum/computer_file/program/camera_monitor filename = "cammon" filedesc = "Camera Monitoring" - nanomodule_path = /datum/nano_module/camera_monitor + tguimodule_path = /datum/tgui_module/camera/ntos program_icon_state = "cameras" program_key_state = "generic_key" program_menu_icon = "search" @@ -39,163 +39,11 @@ available_on_ntnet = 1 requires_ntnet = 1 -/datum/nano_module/camera_monitor - name = "Camera Monitoring program" - var/obj/machinery/camera/current_camera = null - var/current_network = null - -/datum/nano_module/camera_monitor/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, state = default_state) - var/list/data = host.initial_data() - - data["current_camera"] = current_camera ? current_camera.nano_structure() : null - data["current_network"] = current_network - - var/list/all_networks[0] - for(var/network in using_map.station_networks) - if(can_access_network(user, get_camera_access(network), 1)) - all_networks.Add(list(list( - "tag" = network, - "has_access" = 1 - ))) - for(var/network in using_map.secondary_networks) - if(can_access_network(user, get_camera_access(network), 0)) - all_networks.Add(list(list( - "tag" = network, - "has_access" = 1 - ))) - - all_networks = modify_networks_list(all_networks) - - data["networks"] = all_networks - - var/list/map_levels = using_map.get_map_levels(get_z(nano_host()), TRUE) - - if(current_network) - data["cameras"] = camera_repository.cameras_in_network(current_network, map_levels) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "mod_sec_camera.tmpl", "Camera Monitoring", 900, 800) - // ui.auto_update_layout = 1 // Disabled as with suit sensors monitor - breaks the UI map. Re-enable once it's fixed somehow. - - ui.add_template("mapContent", "sec_camera_map_content.tmpl") - ui.add_template("mapHeader", "mod_sec_camera_map_header.tmpl") - ui.set_initial_data(data) - ui.open() - -// Intended to be overriden by subtypes to manually add non-station networks to the list. -/datum/nano_module/camera_monitor/proc/modify_networks_list(var/list/networks) - return networks - -/datum/nano_module/camera_monitor/proc/can_access_network(var/mob/user, var/network_access, var/station_network = 0) - // No access passed, or 0 which is considered no access requirement. Allow it. - if(!network_access) - return 1 - - if(station_network) - return check_access(user, network_access) || check_access(user, access_security) || check_access(user, access_heads) - else - return check_access(user, network_access) - -/datum/nano_module/camera_monitor/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["switch_camera"]) - var/obj/machinery/camera/C = locate(href_list["switch_camera"]) in cameranet.cameras - if(!C) - return - if(!(current_network in C.network)) - return - - switch_to_camera(usr, C) - return 1 - - else if(href_list["switch_network"]) - // Either security access, or access to the specific camera network's department is required in order to access the network. - if(can_access_network(usr, get_camera_access(href_list["switch_network"]), (href_list["switch_network"] in using_map.station_networks))) - current_network = href_list["switch_network"] - else - to_chat(usr, "\The [nano_host()] shows an \"Network Access Denied\" error message.") - return 1 - - else if(href_list["reset"]) - reset_current() - usr.reset_view(current_camera) - return 1 - -/datum/nano_module/camera_monitor/proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C) - //don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras. - if(isAI(user)) - var/mob/living/silicon/ai/A = user - // Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise. - if(!A.is_in_chassis()) - return 0 - - A.eyeobj.setLoc(get_turf(C)) - A.client.eye = A.eyeobj - return 1 - - set_current(C) - user.machine = nano_host() - user.reset_view(C) - return 1 - -/datum/nano_module/camera_monitor/proc/set_current(var/obj/machinery/camera/C) - if(current_camera == C) - return - - if(current_camera) - reset_current() - - current_camera = C - if(current_camera) - var/mob/living/L = current_camera.loc - if(istype(L)) - L.tracking_initiated() - -/datum/nano_module/camera_monitor/proc/reset_current() - if(current_camera) - var/mob/living/L = current_camera.loc - if(istype(L)) - L.tracking_cancelled() - current_camera = null - -/datum/nano_module/camera_monitor/check_eye(var/mob/user as mob) - if(!current_camera) - return 0 - var/viewflag = current_camera.check_eye(user) - if ( viewflag < 0 ) //camera doesn't work - reset_current() - return viewflag - - // ERT Variant of the program /datum/computer_file/program/camera_monitor/ert filename = "ntcammon" filedesc = "Advanced Camera Monitoring" extended_desc = "This program allows remote access to the camera system. Some camera networks may have additional access requirements. This version has an integrated database with additional encrypted keys." size = 14 - nanomodule_path = /datum/nano_module/camera_monitor/ert + tguimodule_path = /datum/tgui_module/camera/ntos/ert available_on_ntnet = 0 - -/datum/nano_module/camera_monitor/ert - name = "Advanced Camera Monitoring Program" - //available_to_ai = FALSE - -// The ERT variant has access to ERT and crescent cams, but still checks for accesses. ERT members should be able to use it. -/datum/nano_module/camera_monitor/ert/modify_networks_list(var/list/networks) - ..() - networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1))) - networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1))) - return networks - -/datum/nano_module/camera_monitor/apply_visual(mob/M) - if(current_camera) - current_camera.apply_visual(M) - else - remove_visual(M) - -/datum/nano_module/camera_monitor/remove_visual(mob/M) - if(current_camera) - current_camera.remove_visual(M) diff --git a/code/modules/modular_computers/file_system/programs/generic/uav.dm b/code/modules/modular_computers/file_system/programs/generic/uav.dm index 8e4909ab048..0e98d0e0eaa 100644 --- a/code/modules/modular_computers/file_system/programs/generic/uav.dm +++ b/code/modules/modular_computers/file_system/programs/generic/uav.dm @@ -41,13 +41,13 @@ set_current(null) else // Don't reset counter until we find a UAV that's actually in range we can stay connected to signal_test_counter = 20 - + data["current_uav"] = null if(current_uav) data["current_uav"] = list("status" = current_uav.get_status_string(), "power" = current_uav.state == 1 ? 1 : null) data["signal_strength"] = signal_strength ? signal_strength >= 2 ? "High" : "Low" : "None" data["in_use"] = LAZYLEN(viewers) - + var/list/paired_map = list() var/obj/item/modular_computer/mc_host = nano_host() if(istype(mc_host)) @@ -55,7 +55,7 @@ var/weakref/wr = puav var/obj/item/device/uav/U = wr.resolve() paired_map[++paired_map.len] = list("name" = "[U ? U.nickname : "!!Missing!!"]", "uavref" = "\ref[U]") - + data["paired_uavs"] = paired_map ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) @@ -102,7 +102,7 @@ else if(href_list["view_uav"]) if(!current_uav) return TOPIC_NOACTION - + if(current_uav.check_eye(user) < 0) to_chat(usr,"The screen freezes for a moment, before returning to the UAV selection menu. It's not able to connect to that UAV.") else @@ -139,7 +139,7 @@ signal_strength = 0 current_uav = U - + if(LAZYLEN(viewers)) for(var/weakref/W in viewers) var/M = W.resolve() @@ -172,7 +172,7 @@ return 0 var/list/zlevels_in_range = using_map.get_map_levels(their_z, FALSE) - var/list/zlevels_in_long_range = using_map.get_map_levels(their_z, TRUE) - zlevels_in_range + var/list/zlevels_in_long_range = using_map.get_map_levels(their_z, TRUE, om_range = DEFAULT_OVERMAP_RANGE) - zlevels_in_range var/their_signal = 0 for(var/relay in ntnet_global.relays) var/obj/machinery/ntnet_relay/R = relay @@ -209,7 +209,7 @@ if(!current_uav) return - + user.set_machine(nano_host()) user.reset_view(current_uav) current_uav.add_master(user) @@ -250,7 +250,7 @@ if(weakref(M) in viewers) M.overlay_fullscreen("fishbed",/obj/screen/fullscreen/fishbed) M.overlay_fullscreen("scanlines",/obj/screen/fullscreen/scanline) - + if(signal_strength <= 1) M.overlay_fullscreen("whitenoise",/obj/screen/fullscreen/noise) else diff --git a/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm b/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm index 894173ec724..9b94707eb22 100644 --- a/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm +++ b/code/modules/modular_computers/file_system/programs/medical/suit_sensors.dm @@ -1,7 +1,7 @@ /datum/computer_file/program/suit_sensors filename = "sensormonitor" filedesc = "Suit Sensors Monitoring" - nanomodule_path = /datum/nano_module/program/crew_monitor + tguimodule_path = /datum/tgui_module/crew_monitor/ntos program_icon_state = "crew" program_key_state = "med_key" program_menu_icon = "heart" @@ -10,68 +10,3 @@ requires_ntnet = 1 network_destination = "crew lifesigns monitoring system" size = 11 - - -/datum/nano_module/program/crew_monitor - name = "Crew monitor" - -/datum/nano_module/program/crew_monitor/Topic(href, href_list) - if(..()) return 1 - var/turf/T = get_turf(nano_host()) // TODO: Allow setting any using_map.contact_levels from the interface. - if (!T || !(T.z in using_map.player_levels)) - to_chat(usr, "Unable to establish a connection: You're too far away from the station!") - return 0 - if(href_list["track"]) - if(isAI(usr)) - var/mob/living/silicon/ai/AI = usr - var/mob/living/carbon/human/H = locate(href_list["track"]) in mob_list - if(hassensorlevel(H, SUIT_SENSOR_TRACKING)) - AI.ai_actual_track(H) - return 1 - -/datum/nano_module/program/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - var/list/data = host.initial_data() - - data["isAI"] = isAI(user) - - var/z = get_z(nano_host()) - var/list/map_levels = using_map.get_map_levels(z, TRUE) - data["map_levels"] = map_levels - - data["crewmembers"] = list() - for(var/zlevel in map_levels) - data["crewmembers"] += crew_repository.health_data(zlevel) - - if(!data["map_levels"].len) - to_chat(user, "The crew monitor doesn't seem like it'll work here.") - if(program) - program.kill_program() - if(ui) - ui.close() - return - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800, state = state) - - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "crew_monitor_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "crew_monitor_map_header.tmpl") - if(!(ui.map_z_level in data["map_levels"])) - ui.set_map_z_level(data["map_levels"][1]) - - ui.set_initial_data(data) - ui.open() - - // should make the UI auto-update; doesn't seem to? - ui.set_auto_update(1) - -/*/datum/nano_module/program/crew_monitor/proc/scan() - for(var/mob/living/carbon/human/H in mob_list) - if(istype(H.w_uniform, /obj/item/clothing/under)) - var/obj/item/clothing/under/C = H.w_uniform - if (C.has_sensor) - tracked |= C - return 1 -*/ \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/security/alarm_monitor.dm b/code/modules/modular_computers/file_system/programs/security/alarm_monitor.dm index 2254cc1dae9..a833573be6a 100644 --- a/code/modules/modular_computers/file_system/programs/security/alarm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/security/alarm_monitor.dm @@ -2,5 +2,5 @@ filename = "alarmmonitorsec" filedesc = "Alarm Monitoring (Security)" extended_desc = "This program provides visual interface for the security alarm system." - nanomodule_path = /datum/nano_module/alarm_monitor/security + tguimodule_path = /datum/tgui_module/alarm_monitor/security/ntos required_access = access_security \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm index 1447c5008e4..86af5d9ba0b 100644 --- a/code/modules/modular_computers/hardware/network_card.dm +++ b/code/modules/modular_computers/hardware/network_card.dm @@ -104,7 +104,7 @@ var/global/ntnet_card_uid = 1 if(!holderz) //no reception in nullspace return 0 var/list/zlevels_in_range = using_map.get_map_levels(holderz, FALSE) - var/list/zlevels_in_long_range = using_map.get_map_levels(holderz, TRUE) - zlevels_in_range + var/list/zlevels_in_long_range = using_map.get_map_levels(holderz, TRUE, om_range = DEFAULT_OVERMAP_RANGE) - zlevels_in_range var/best = 0 for(var/relay in ntnet_global.relays) var/obj/machinery/ntnet_relay/R = relay diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm deleted file mode 100644 index fd2ed900f2c..00000000000 --- a/code/modules/nano/modules/human_appearance.dm +++ /dev/null @@ -1,191 +0,0 @@ -/datum/nano_module/appearance_changer - name = "Appearance Editor" - var/flags = APPEARANCE_ALL_HAIR - var/mob/living/carbon/human/owner = null - var/list/valid_species = list() - var/list/valid_hairstyles = list() - var/list/valid_facial_hairstyles = list() - - var/check_whitelist - var/list/whitelist - var/list/blacklist - -/datum/nano_module/appearance_changer/New(var/location, var/mob/living/carbon/human/H, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list()) - ..() - owner = H - src.check_whitelist = check_species_whitelist - src.whitelist = species_whitelist - src.blacklist = species_blacklist - -/datum/nano_module/appearance_changer/Topic(ref, href_list, var/datum/topic_state/state = default_state) - if(..()) - return 1 - - if(href_list["race"]) - if(can_change(APPEARANCE_RACE) && (href_list["race"] in valid_species)) - if(owner.change_species(href_list["race"])) - cut_and_generate_data() - return 1 - if(href_list["gender"]) - if(can_change(APPEARANCE_GENDER) && (href_list["gender"] in get_genders())) - if(owner.change_gender(href_list["gender"])) - cut_and_generate_data() - return 1 - if(href_list["gender_id"]) - if(can_change(APPEARANCE_GENDER) && (href_list["gender_id"] in all_genders_define_list)) - owner.identifying_gender = href_list["gender_id"] - return 1 - if(href_list["skin_tone"]) - if(can_change_skin_tone()) - var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", -owner.s_tone + 35) as num|null - if(isnum(new_s_tone) && can_still_topic(state)) - new_s_tone = 35 - max(min( round(new_s_tone), 220),1) - return owner.change_skin_tone(new_s_tone) - if(href_list["skin_color"]) - if(can_change_skin_color()) - var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", rgb(owner.r_skin, owner.g_skin, owner.b_skin)) as color|null - if(new_skin && can_still_topic(state)) - var/r_skin = hex2num(copytext(new_skin, 2, 4)) - var/g_skin = hex2num(copytext(new_skin, 4, 6)) - var/b_skin = hex2num(copytext(new_skin, 6, 8)) - if(owner.change_skin_color(r_skin, g_skin, b_skin)) - update_dna() - return 1 - if(href_list["hair"]) - if(can_change(APPEARANCE_HAIR) && (href_list["hair"] in valid_hairstyles)) - if(owner.change_hair(href_list["hair"])) - update_dna() - return 1 - if(href_list["hair_color"]) - if(can_change(APPEARANCE_HAIR_COLOR)) - var/new_hair = input("Please select hair color.", "Hair Color", rgb(owner.r_hair, owner.g_hair, owner.b_hair)) as color|null - if(new_hair && can_still_topic(state)) - var/r_hair = hex2num(copytext(new_hair, 2, 4)) - var/g_hair = hex2num(copytext(new_hair, 4, 6)) - var/b_hair = hex2num(copytext(new_hair, 6, 8)) - if(owner.change_hair_color(r_hair, g_hair, b_hair)) - update_dna() - return 1 - if(href_list["facial_hair"]) - if(can_change(APPEARANCE_FACIAL_HAIR) && (href_list["facial_hair"] in valid_facial_hairstyles)) - if(owner.change_facial_hair(href_list["facial_hair"])) - update_dna() - return 1 - if(href_list["facial_hair_color"]) - if(can_change(APPEARANCE_FACIAL_HAIR_COLOR)) - var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(owner.r_facial, owner.g_facial, owner.b_facial)) as color|null - if(new_facial && can_still_topic(state)) - var/r_facial = hex2num(copytext(new_facial, 2, 4)) - var/g_facial = hex2num(copytext(new_facial, 4, 6)) - var/b_facial = hex2num(copytext(new_facial, 6, 8)) - if(owner.change_facial_hair_color(r_facial, g_facial, b_facial)) - update_dna() - return 1 - if(href_list["eye_color"]) - if(can_change(APPEARANCE_EYE_COLOR)) - var/new_eyes = input("Please select eye color.", "Eye Color", rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)) as color|null - if(new_eyes && can_still_topic(state)) - var/r_eyes = hex2num(copytext(new_eyes, 2, 4)) - var/g_eyes = hex2num(copytext(new_eyes, 4, 6)) - var/b_eyes = hex2num(copytext(new_eyes, 6, 8)) - if(owner.change_eye_color(r_eyes, g_eyes, b_eyes)) - update_dna() - return 1 - - return 0 - -/datum/nano_module/appearance_changer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) - - if(!owner || !owner.species) - return - - generate_data(check_whitelist, whitelist, blacklist) - var/list/data = host.initial_data() - - data["specimen"] = owner.species.name - data["gender"] = owner.gender - data["gender_id"] = owner.identifying_gender - data["change_race"] = can_change(APPEARANCE_RACE) - if(data["change_race"]) - var/species[0] - for(var/specimen in valid_species) - species[++species.len] = list("specimen" = specimen) - data["species"] = species - - data["change_gender"] = can_change(APPEARANCE_GENDER) - if(data["change_gender"]) - var/genders[0] - for(var/gender in get_genders()) - genders[++genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender) - data["genders"] = genders - var/id_genders[0] - for(var/gender in all_genders_define_list) - id_genders[++id_genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender) - data["id_genders"] = id_genders - - - data["change_skin_tone"] = can_change_skin_tone() - data["change_skin_color"] = can_change_skin_color() - data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR) - data["change_hair"] = can_change(APPEARANCE_HAIR) - if(data["change_hair"]) - var/hair_styles[0] - for(var/hair_style in valid_hairstyles) - hair_styles[++hair_styles.len] = list("hairstyle" = hair_style) - data["hair_styles"] = hair_styles - data["hair_style"] = owner.h_style - - data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR) - if(data["change_facial_hair"]) - var/facial_hair_styles[0] - for(var/facial_hair_style in valid_facial_hairstyles) - facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style) - data["facial_hair_styles"] = facial_hair_styles - data["facial_hair_style"] = owner.f_style - - data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) - data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src]", 800, 450, state = state) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/datum/nano_module/appearance_changer/proc/update_dna() - if(owner && (flags & APPEARANCE_UPDATE_DNA)) - owner.update_dna() - -/datum/nano_module/appearance_changer/proc/can_change(var/flag) - return owner && (flags & flag) - -/datum/nano_module/appearance_changer/proc/can_change_skin_tone() - return owner && (flags & APPEARANCE_SKIN) && owner.species.appearance_flags & HAS_SKIN_TONE - -/datum/nano_module/appearance_changer/proc/can_change_skin_color() - return owner && (flags & APPEARANCE_SKIN) && owner.species.appearance_flags & HAS_SKIN_COLOR - -/datum/nano_module/appearance_changer/proc/cut_and_generate_data() - // Making the assumption that the available species remain constant - valid_facial_hairstyles.Cut() - valid_facial_hairstyles.Cut() - generate_data() - -/datum/nano_module/appearance_changer/proc/generate_data() - if(!owner) - return - if(!valid_species.len) - valid_species = owner.generate_valid_species(check_whitelist, whitelist, blacklist) - if(!valid_hairstyles.len || !valid_facial_hairstyles.len) - valid_hairstyles = owner.generate_valid_hairstyles(check_gender = 0) - valid_facial_hairstyles = owner.generate_valid_facial_hairstyles() - - -/datum/nano_module/appearance_changer/proc/get_genders() - var/datum/species/S = owner.species - var/list/possible_genders = S.genders - if(!owner.internal_organs_by_name["cell"]) - return possible_genders - possible_genders = possible_genders.Copy() - possible_genders |= NEUTER - return possible_genders \ No newline at end of file diff --git a/code/modules/nifsoft/nif_softshop.dm b/code/modules/nifsoft/nif_softshop.dm index 3bb661678bc..d802abde4c6 100644 --- a/code/modules/nifsoft/nif_softshop.dm +++ b/code/modules/nifsoft/nif_softshop.dm @@ -227,11 +227,9 @@ /datum/wires/vending/no_contraband -/datum/wires/vending/no_contraband/UpdatePulsed(index) //Can't hack for contraband, need emag. - if(index != VENDING_WIRE_CONTRABAND) +/datum/wires/vending/no_contraband/on_pulse(index) //Can't hack for contraband, need emag. + if(index != WIRE_CONTRABAND) ..(index) - else - return /obj/machinery/vending/nifsoft_shop/emag_act(remaining_charges, mob/user) //Yeees, YEEES! Give me that black market tech. if(!emagged || !(categories & CAT_HIDDEN)) diff --git a/code/modules/nifsoft/software/06_screens.dm b/code/modules/nifsoft/software/06_screens.dm index 97f4c272a9b..8dadc88192e 100644 --- a/code/modules/nifsoft/software/06_screens.dm +++ b/code/modules/nifsoft/software/06_screens.dm @@ -5,7 +5,7 @@ access = access_medical cost = 625 p_drain = 0.025 - var/datum/nano_module/program/crew_monitor/arscreen + var/datum/tgui_module/crew_monitor/nif/arscreen New() ..() @@ -17,7 +17,7 @@ activate() if((. = ..())) - arscreen.ui_interact(nif.human,"main",null,1,nif_state) + arscreen.tgui_interact(nif.human) return TRUE deactivate() @@ -34,19 +34,19 @@ access = access_engine cost = 625 p_drain = 0.025 - var/datum/nano_module/alarm_monitor/engineering/arscreen + var/datum/tgui_module/alarm_monitor/engineering/nif/tgarscreen New() ..() - arscreen = new(nif) + tgarscreen = new(nif) Destroy() - QDEL_NULL(arscreen) + QDEL_NULL(tgarscreen) return ..() activate() if((. = ..())) - arscreen.ui_interact(nif.human,"main",null,1,nif_state) + tgarscreen.tgui_interact(nif.human) return TRUE deactivate() diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 931eaab0cbd..49f9d5b6a45 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -2,10 +2,13 @@ BLOOD SYSTEM ****************************************************/ //Blood levels. These are percentages based on the species blood_volume var. +//Retained for archival/reference purposes - KK +/* var/const/BLOOD_VOLUME_SAFE = 85 var/const/BLOOD_VOLUME_OKAY = 75 var/const/BLOOD_VOLUME_BAD = 60 var/const/BLOOD_VOLUME_SURVIVE = 40 +*/ var/const/CE_STABLE_THRESHOLD = 0.5 /mob/living/carbon/human/var/datum/reagents/vessel // Container for blood and BLOOD ONLY. Do not transfer other chems here. @@ -88,22 +91,22 @@ var/const/CE_STABLE_THRESHOLD = 0.5 // dmg_coef = min(1, 10/chem_effects[CE_STABLE]) //TODO: add effect for increased damage // threshold_coef = min(dmg_coef / CE_STABLE_THRESHOLD, 1) - if(blood_volume >= BLOOD_VOLUME_SAFE) + if(blood_volume_raw >= species.blood_volume*species.blood_level_safe) if(pale) pale = 0 update_icons_body() - else if(blood_volume >= BLOOD_VOLUME_OKAY) + else if(blood_volume_raw >= species.blood_volume*species.blood_level_warning) if(!pale) pale = 1 update_icons_body() - var/word = pick("dizzy","woosey","faint") - to_chat(src, "You feel [word]") + var/word = pick("dizzy","woozy","faint","disoriented","unsteady") + to_chat(src, "You feel slightly [word]") if(prob(1)) - var/word = pick("dizzy","woosey","faint") + var/word = pick("dizzy","woozy","faint","disoriented","unsteady") to_chat(src, "You feel [word]") if(getOxyLoss() < 20 * threshold_coef) adjustOxyLoss(3 * dmg_coef) - else if(blood_volume >= BLOOD_VOLUME_BAD) + else if(blood_volume_raw >= species.blood_volume*species.blood_level_danger) if(!pale) pale = 1 update_icons_body() @@ -113,13 +116,13 @@ var/const/CE_STABLE_THRESHOLD = 0.5 adjustOxyLoss(1 * dmg_coef) if(prob(15)) Paralyse(rand(1,3)) - var/word = pick("dizzy","woosey","faint") - to_chat(src, "You feel extremely [word]") - else if(blood_volume >= BLOOD_VOLUME_SURVIVE) + var/word = pick("dizzy","woozy","faint","disoriented","unsteady") + to_chat(src, "You feel dangerously [word]") + else if(blood_volume_raw >= species.blood_volume*species.blood_level_fatal) adjustOxyLoss(5 * dmg_coef) // adjustToxLoss(3 * dmg_coef) if(prob(15)) - var/word = pick("dizzy","woosey","faint") + var/word = pick("dizzy","woozy","faint","disoriented","unsteady") to_chat(src, "You feel extremely [word]") else //Not enough blood to survive (usually) if(!pale) @@ -131,7 +134,7 @@ var/const/CE_STABLE_THRESHOLD = 0.5 adjustOxyLoss(75 * dmg_coef) // 15 more than dexp fixes (also more than dex+dexp+tricord) // Without enough blood you slowly go hungry. - if(blood_volume < BLOOD_VOLUME_SAFE) + if(blood_volume_raw < species.blood_volume*species.blood_level_safe) if(nutrition >= 300) adjust_nutrition(-10) else if(nutrition >= 200) @@ -357,7 +360,7 @@ proc/blood_splatter(var/target,var/datum/reagent/blood/source,var/large) drop.drips |= drips // If there's no data to copy, call it quits here. - if(!source) + if(!istype(source)) return B // Update appearance. diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index 094d3eb32af..0412ab14706 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -98,6 +98,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) brainmob.real_name = H.real_name brainmob.dna = H.dna.Clone() brainmob.timeofhostdeath = H.timeofdeath + brainmob.ooc_notes = H.ooc_notes //VOREStation Edit // Copy modifiers. for(var/datum/modifier/M in H.modifiers) @@ -178,6 +179,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) parent_organ = BP_TORSO clone_source = TRUE flags = OPENCONTAINER + var/list/owner_flavor_text = list() /obj/item/organ/internal/brain/slime/is_open_container() return 1 @@ -191,6 +193,11 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) H = owner color = rgb(min(H.r_skin + 40, 255), min(H.g_skin + 40, 255), min(H.b_skin + 40, 255)) +/obj/item/organ/internal/brain/slime/removed(var/mob/living/user) + if(istype(owner)) + owner_flavor_text = owner.flavor_texts.Copy() + ..() + /obj/item/organ/internal/brain/slime/proc/reviveBody() var/datum/dna2/record/R = new /datum/dna2/record() R.dna = brainmob.dna @@ -200,6 +207,8 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) R.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE R.languages = brainmob.languages R.flavor = list() + if(islist(owner_flavor_text)) + R.flavor = owner_flavor_text.Copy() for(var/datum/modifier/mod in brainmob.modifiers) if(mod.flags & MODIFIER_GENETIC) R.genetic_modifiers.Add(mod.type) @@ -238,6 +247,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) if(!R.dna.real_name) //to prevent null names R.dna.real_name = "promethean ([rand(0,999)])" H.real_name = R.dna.real_name + H.ooc_notes = brainmob.ooc_notes // VOREStation Edit H.nutrition = 260 //Enough to try to regenerate ONCE. H.adjustBruteLoss(40) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 080b19b32de..8cad30e19c5 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -525,7 +525,7 @@ This function completely restores a damaged organ to perfect condition. //Burn damage can cause fluid loss due to blistering and cook-off if((damage > 5 || damage + burn_dam >= 15) && type == BURN && (robotic < ORGAN_ROBOT) && !(species.flags & NO_BLOOD)) - var/fluid_loss = 0.4 * (damage/(owner.getMaxHealth() - config.health_threshold_dead)) * owner.species.blood_volume*(1 - BLOOD_VOLUME_SURVIVE/100) + var/fluid_loss = 0.4 * (damage/(owner.getMaxHealth() - config.health_threshold_dead)) * owner.species.blood_volume*(1 - owner.species.blood_level_fatal) owner.remove_blood(fluid_loss) // first check whether we can widen an existing wound diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm index df7d81a142a..ffc9a6149be 100644 --- a/code/modules/organs/pain.dm +++ b/code/modules/organs/pain.dm @@ -42,7 +42,7 @@ mob/living/carbon/human/proc/handle_pain() maxdam = dam if(damaged_organ && chem_effects[CE_PAINKILLER] < maxdam) if(maxdam > 10 && paralysis) - paralysis = max(0, paralysis - round(maxdam/10)) + AdjustParalysis(-round(maxdam/10)) if(maxdam > 50 && prob(maxdam / 5)) drop_item() var/burning = damaged_organ.burn_dam > damaged_organ.brute_dam diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index a0ca24e9974..8a06b043d06 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -186,11 +186,10 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ unavailable_to_build = 1 /datum/robolimb/cybersolutions_alt2 - company = "Cyber Solutions - Array" - desc = "This limb is simple and functional; array of sensors on a featureless case." + company = "Cyber Solutions - Outdated" + desc = "This limb is of severely outdated design; there's no way it's comfortable or very functional to use." icon = 'icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt2.dmi' unavailable_to_build = 1 - parts = list(BP_HEAD) /datum/robolimb/cybersolutions_alt1 company = "Cyber Solutions - Wight" @@ -198,6 +197,13 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ icon = 'icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt1.dmi' unavailable_to_build = 1 +/datum/robolimb/cybersolutions_alt3 + company = "Cyber Solutions - Array" + desc = "This limb is simple and functional; array of sensors on a featureless case." + icon = 'icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt3.dmi' + unavailable_to_build = 1 + parts = list(BP_HEAD) + /datum/robolimb/einstein company = "Einstein Engines" desc = "This limb is lightweight with a sleek design." @@ -484,4 +490,4 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ species = SPECIES_ZADDAT /obj/item/weapon/disk/limb/cenilimicybernetics - company = "Cenilimi Cybernetics" \ No newline at end of file + company = "Cenilimi Cybernetics" diff --git a/code/modules/organs/robolimbs_vr.dm b/code/modules/organs/robolimbs_vr.dm index 7f85cf642d5..5182c70e558 100644 --- a/code/modules/organs/robolimbs_vr.dm +++ b/code/modules/organs/robolimbs_vr.dm @@ -49,7 +49,7 @@ // tucker0666 : Frost /datum/robolimb/zenghu_frost - company = "Zeng-Hu" + company = "Zeng-Hu (Custom)" desc = "This limb has realistic synthetic flesh covering with 'blue accents'." icon = 'icons/mob/human_races/cyberlimbs/_fluff_vr/Frosty.dmi' blood_color = "#45ccff" diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index cf1f2513072..3d12e685340 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -36,12 +36,8 @@ to_chat(user, "You put [P] in [src].") user.drop_item() P.loc = src - icon_state = "[initial(icon_state)]-open" - flick("[initial(icon_state)]-open",src) - playsound(src, 'sound/bureaucracy/filingcabinet.ogg', 50, 1) - sleep(40) - icon_state = initial(icon_state) - updateUsrDialog() + open_animation() + SStgui.update_uis(src) else if(P.is_wrench()) playsound(src, P.usesound, 50, 1) anchored = !anchored @@ -65,20 +61,12 @@ to_chat(user, "\The [src] is empty.") return - user.set_machine(src) - var/dat = "
    " - for(var/obj/item/P in src) - dat += "" - dat += "
    [P.name]
    " - user << browse("[name][dat]", "window=filingcabinet;size=350x300") - - return + tgui_interact(user) /obj/structure/filingcabinet/attack_tk(mob/user) if(anchored) - attack_self_tk(user) - else - ..() + return attack_self_tk(user) + return ..() /obj/structure/filingcabinet/attack_self_tk(mob/user) if(contents.len) @@ -91,20 +79,46 @@ return to_chat(user, "You find nothing in [src].") -/obj/structure/filingcabinet/Topic(href, href_list) - if(href_list["retrieve"]) - usr << browse("", "window=filingcabinet") // Close the menu +/obj/structure/filingcabinet/tgui_state(mob/user) + return GLOB.tgui_physical_state - //var/retrieveindex = text2num(href_list["retrieve"]) - var/obj/item/P = locate(href_list["retrieve"])//contents[retrieveindex] - if(istype(P) && (P.loc == src) && src.Adjacent(usr)) - usr.put_in_hands(P) - updateUsrDialog() - flick("[initial(icon_state)]-open",src) - playsound(src, 'sound/bureaucracy/filingcabinet.ogg', 50, 1) - spawn(0) - sleep(20) - icon_state = initial(icon_state) +/obj/structure/filingcabinet/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "FileCabinet", name) + ui.set_autoupdate(FALSE) + ui.open() + +/obj/structure/filingcabinet/tgui_data(mob/user) + var/list/data = list() + + data["contents"] = list() + for(var/obj/item/P in src) + data["contents"].Add(list(list( + "name" = P.name, + "ref" = "\ref[P]", + ))) + + return data + +/obj/structure/filingcabinet/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("retrieve") + var/obj/item/P = locate(params["ref"]) + if(istype(P) && (P.loc == src) && usr.Adjacent(src)) + usr.put_in_hands(P) + open_animation() + SStgui.update_uis(src) + +/obj/structure/filingcabinet/proc/open_animation() + flick("[initial(icon_state)]-open",src) + playsound(src, 'sound/bureaucracy/filingcabinet.ogg', 50, 1) + spawn(0) + sleep(20) + icon_state = initial(icon_state) /* * Security Record Cabinets @@ -112,7 +126,6 @@ /obj/structure/filingcabinet/security var/virgin = 1 - /obj/structure/filingcabinet/security/proc/populate() if(virgin) for(var/datum/data/record/G in data_core.general) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 8b50d0204f3..5618257494c 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -32,6 +32,8 @@ var/list/offset_y[0] //usage by the photocopier var/rigged = 0 var/spam_flag = 0 + var/age = 0 + var/last_modified_ckey var/const/deffont = "Verdana" var/const/signfont = "Times New Roman" @@ -231,6 +233,15 @@ H.lip_style = null H.update_icons_body() +/obj/item/weapon/paper/proc/set_content(text,title) + if(title) + name = title + info = html_encode(text) + info = parsepencode(text) + update_icon() + update_space(info) + updateinfolinks() + /obj/item/weapon/paper/proc/addtofield(var/id, var/text, var/links = 0) var/locid = 0 var/laststart = 1 @@ -465,6 +476,8 @@ info += t // Oh, he wants to edit to the end of the file, let him. updateinfolinks() + last_modified_ckey = usr.ckey + update_space(t) usr << browse("[name][info_links][stamps]", "window=[name]") // Update the window diff --git a/code/modules/paperwork/paper_sticky.dm b/code/modules/paperwork/paper_sticky.dm new file mode 100644 index 00000000000..5c1efb2a28c --- /dev/null +++ b/code/modules/paperwork/paper_sticky.dm @@ -0,0 +1,152 @@ +/obj/item/sticky_pad + name = "sticky note pad" + desc = "A pad of densely packed sticky notes." + description_info = "Click to remove a sticky note from the pile. Click-drag to yourself to pick up the stack. Sticky notes stuck to surfaces/objects will persist for 50 rounds." + color = COLOR_YELLOW + icon = 'icons/obj/stickynotes.dmi' + icon_state = "pad_full" + item_state = "paper" + w_class = ITEMSIZE_SMALL + + var/papers = 50 + var/written_text + var/written_by + var/paper_type = /obj/item/weapon/paper/sticky + +/obj/item/sticky_pad/update_icon() + if(papers <= 15) + icon_state = "pad_empty" + else if(papers <= 50) + icon_state = "pad_used" + else + icon_state = "pad_full" + if(written_text) + icon_state = "[icon_state]_writing" + +/obj/item/sticky_pad/attackby(var/obj/item/weapon/thing, var/mob/user) + if(istype(thing, /obj/item/weapon/pen)) + + if(jobban_isbanned(user, "Graffiti")) + to_chat(user, SPAN_WARNING("You are banned from leaving persistent information across rounds.")) + return + + var/writing_space = MAX_MESSAGE_LEN - length(written_text) + if(writing_space <= 0) + to_chat(user, SPAN_WARNING("There is no room left on \the [src].")) + return + var/text = sanitizeSafe(input("What would you like to write?") as text, writing_space) + if(!text || thing.loc != user || (!Adjacent(user) && loc != user) || user.incapacitated()) + return + user.visible_message(SPAN_NOTICE("\The [user] jots a note down on \the [src].")) + written_by = user.ckey + if(written_text) + written_text = "[written_text] [text]" + else + written_text = text + update_icon() + return + ..() + +/obj/item/sticky_pad/examine(var/mob/user) + . = ..() + if(.) + to_chat(user, SPAN_NOTICE("It has [papers] sticky note\s left.")) + +/obj/item/sticky_pad/attack_hand(var/mob/user) + var/obj/item/weapon/paper/paper = new paper_type(get_turf(src)) + paper.set_content(written_text, "sticky note") + paper.last_modified_ckey = written_by + paper.color = color + written_text = null + user.put_in_hands(paper) + to_chat(user, SPAN_NOTICE("You pull \the [paper] off \the [src].")) + papers-- + if(papers <= 0) + qdel(src) + else + update_icon() + +/obj/item/sticky_pad/MouseDrop(mob/user as mob) + if(user == usr && !(usr.restrained() || usr.stat) && (usr.contents.Find(src) || in_range(src, usr))) + if(!istype(usr, /mob/living/simple_mob)) + if( !usr.get_active_hand() ) //if active hand is empty + var/mob/living/carbon/human/H = user + var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] + + if (H.hand) + temp = H.organs_by_name["l_hand"] + if(temp && !temp.is_usable()) + to_chat(user, "You try to move your [temp.name], but cannot!") + return + + to_chat(user, "You pick up the [src].") + user.put_in_hands(src) + + return + +/obj/item/sticky_pad/random/Initialize() + . = ..() + color = pick(COLOR_YELLOW, COLOR_LIME, COLOR_CYAN, COLOR_ORANGE, COLOR_PINK) + +/obj/item/weapon/paper/sticky + name = "sticky note" + desc = "Note to self: buy more sticky notes." + icon = 'icons/obj/stickynotes.dmi' + color = COLOR_YELLOW + slot_flags = 0 + +/obj/item/weapon/paper/sticky/Initialize() + . = ..() + GLOB.moved_event.register(src, src, /obj/item/weapon/paper/sticky/proc/reset_persistence_tracking) + +/obj/item/weapon/paper/sticky/proc/reset_persistence_tracking() + SSpersistence.forget_value(src, /datum/persistent/paper/sticky) + pixel_x = 0 + pixel_y = 0 + +/obj/item/weapon/paper/sticky/Destroy() + reset_persistence_tracking() + GLOB.moved_event.unregister(src, src) + . = ..() + +/obj/item/weapon/paper/sticky/update_icon() + if(icon_state != "scrap") + icon_state = info ? "paper_words" : "paper" + +// Copied from duct tape. +/obj/item/weapon/paper/sticky/attack_hand() + . = ..() + if(!istype(loc, /turf)) + reset_persistence_tracking() + +/obj/item/weapon/paper/sticky/afterattack(var/A, var/mob/user, var/flag, var/params) + + if(!in_range(user, A) || istype(A, /obj/machinery/door) || icon_state == "scrap") + return + + var/turf/target_turf = get_turf(A) + var/turf/source_turf = get_turf(user) + + var/dir_offset = 0 + if(target_turf != source_turf) + dir_offset = get_dir(source_turf, target_turf) + if(!(dir_offset in GLOB.cardinal)) + to_chat(user, SPAN_WARNING("You cannot reach that from here.")) + return + + if(user.unEquip(src, source_turf)) + SSpersistence.track_value(src, /datum/persistent/paper/sticky) + if(params) + var/list/mouse_control = params2list(params) + if(mouse_control["icon-x"]) + pixel_x = text2num(mouse_control["icon-x"]) - 16 + if(dir_offset & EAST) + pixel_x += 32 + else if(dir_offset & WEST) + pixel_x -= 32 + if(mouse_control["icon-y"]) + pixel_y = text2num(mouse_control["icon-y"]) - 16 + if(dir_offset & NORTH) + pixel_y += 32 + else if(dir_offset & SOUTH) + pixel_y -= 32 \ No newline at end of file diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index f7a726d60de..69c14fe8b97 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -19,7 +19,7 @@ /obj/item/weapon/paper_bin/MouseDrop(mob/user as mob) - if((user == usr && (!( usr.restrained() ) && (!( usr.stat ) && (usr.contents.Find(src) || in_range(src, usr)))))) + if(user == usr && !(usr.restrained() || usr.stat) && (usr.contents.Find(src) || in_range(src, usr))) if(!istype(usr, /mob/living/simple_mob)) if( !usr.get_active_hand() ) //if active hand is empty var/mob/living/carbon/human/H = user diff --git a/code/modules/persistence/datum/datum_filth.dm b/code/modules/persistence/datum/datum_filth.dm new file mode 100644 index 00000000000..f41fffcfb7f --- /dev/null +++ b/code/modules/persistence/datum/datum_filth.dm @@ -0,0 +1,35 @@ +/datum/persistent/filth + name = "filth" + tokens_per_line = 5 + entries_expire_at = 5 + +/datum/persistent/filth/LabelTokens(var/list/tokens) + var/list/labelled_tokens = ..() + labelled_tokens["path"] = text2path(tokens[LAZYLEN(labelled_tokens)+1]) + return labelled_tokens + +/datum/persistent/filth/IsValidEntry(var/atom/entry) + . = ..() && entry.invisibility == 0 + +/datum/persistent/filth/CheckTokenSanity(var/list/tokens) + return ..() && ispath(tokens["path"]) + +/datum/persistent/filth/CheckTurfContents(var/turf/T, var/list/tokens) + var/_path = tokens["path"] + return (locate(_path) in T) ? FALSE : TRUE + +/datum/persistent/filth/CreateEntryInstance(var/turf/creating, var/list/tokens) + var/_path = tokens["path"] + new _path(creating, tokens["age"]+1) + +/datum/persistent/filth/GetEntryAge(var/atom/entry) + var/obj/effect/decal/cleanable/filth = entry + return filth.age + +/datum/persistent/filth/proc/GetEntryPath(var/atom/entry) + var/obj/effect/decal/cleanable/filth = entry + return filth.generic_filth ? /obj/effect/decal/cleanable/filth : filth.type + +/datum/persistent/filth/CompileEntry(var/atom/entry) + . = ..() + LAZYADD(., "[GetEntryPath(entry)]") \ No newline at end of file diff --git a/code/modules/persistence/datum/datum_graffiti.dm b/code/modules/persistence/datum/datum_graffiti.dm new file mode 100644 index 00000000000..b70b7f94751 --- /dev/null +++ b/code/modules/persistence/datum/datum_graffiti.dm @@ -0,0 +1,51 @@ +/datum/persistent/graffiti + name = "graffiti" + tokens_per_line = 6 + entries_expire_at = 50 + has_admin_data = TRUE + +/datum/persistent/graffiti/LabelTokens(var/list/tokens) + var/list/labelled_tokens = ..() + var/entries = LAZYLEN(labelled_tokens) + labelled_tokens["author"] = tokens[entries+1] + labelled_tokens["message"] = tokens[entries+2] + return labelled_tokens + +/datum/persistent/graffiti/GetValidTurf(var/turf/T, var/list/tokens) + var/turf/checking_turf = ..() + if(istype(checking_turf) && checking_turf.can_engrave()) + return checking_turf + +/datum/persistent/graffiti/CheckTurfContents(var/turf/T, var/list/tokens) + var/too_much_graffiti = 0 + for(var/obj/effect/decal/writing/W in .) + too_much_graffiti++ + if(too_much_graffiti >= 5) + return FALSE + return TRUE + +/datum/persistent/graffiti/CreateEntryInstance(var/turf/creating, var/list/tokens) + new /obj/effect/decal/writing(creating, tokens["age"]+1, tokens["message"], tokens["author"]) + +/datum/persistent/graffiti/IsValidEntry(var/atom/entry) + . = ..() + if(.) + var/turf/T = entry.loc + . = T.can_engrave() + +/datum/persistent/graffiti/GetEntryAge(var/atom/entry) + var/obj/effect/decal/writing/save_graffiti = entry + return save_graffiti.graffiti_age + +/datum/persistent/graffiti/CompileEntry(var/atom/entry, var/write_file) + . = ..() + var/obj/effect/decal/writing/save_graffiti = entry + LAZYADD(., "[save_graffiti.author ? save_graffiti.author : "unknown"]") + LAZYADD(., "[save_graffiti.message]") + +/datum/persistent/graffiti/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user) + var/obj/effect/decal/writing/save_graffiti = thing + if(can_modify) + . = "
[save_graffiti.message][save_graffiti.author]Destroy[save_graffiti.message][save_graffiti.author][paper.info][paper.name][paper.last_modified_ckey]Destroy[paper.info][paper.name][paper.last_modified_ckey]
[capitalize(name)]


[thing]Destroy[thing]
") + for(var/thing in notices) + LAZYADD(dat, "") + var/datum/browser/popup = new(user, "noticeboard-\ref[src]", "Noticeboard") + popup.set_content(jointext(dat, null)) + popup.open() + +/obj/structure/noticeboard/Topic(var/mob/user, var/list/href_list) + if(href_list["read"]) + var/obj/item/weapon/paper/P = locate(href_list["read"]) + if(P && P.loc == src) + P.show_content(user) + . = TOPIC_HANDLED + + if(href_list["look"]) + var/obj/item/weapon/photo/P = locate(href_list["look"]) + if(P && P.loc == src) + P.show(user) + . = TOPIC_HANDLED + + if(href_list["remove"]) + remove_paper(locate(href_list["remove"])) + add_fingerprint(user) + . = TOPIC_REFRESH + + if(href_list["write"]) + if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open + return + var/obj/item/P = locate(href_list["write"]) + if((P && P.loc == src)) //ifthe paper's on the board + var/mob/living/M = usr + if(istype(M)) + var/obj/item/weapon/pen/E = M.get_type_in_hands(/obj/item/weapon/pen) + if(E) + add_fingerprint(M) + P.attackby(E, usr) + else + to_chat(M, "You'll need something to write with!") + . = TOPIC_REFRESH + + if(. == TOPIC_REFRESH) + interact(user) + +/obj/structure/noticeboard/anomaly + notices = 5 + icon_state = "nboard05" + +/obj/structure/noticeboard/anomaly/New() + var/obj/item/weapon/paper/P = new() + P.name = "Memo RE: proper analysis procedure" + P.info = "
We keep test dummies in pens here for a reason, so standard procedure should be to activate newfound alien artifacts and place the two in close proximity. Promising items I might even approve monkey testing on." + P.stamped = list(/obj/item/weapon/stamp/rd) + P.overlays = list("paper_stamped_rd") + src.contents += P + + P = new() + P.name = "Memo RE: materials gathering" + P.info = "Corasang,
the hands-on approach to gathering our samples may very well be slow at times, but it's safer than allowing the blundering miners to roll willy-nilly over our dig sites in their mechs, destroying everything in the process. And don't forget the escavation tools on your way out there!
- R.W" + P.stamped = list(/obj/item/weapon/stamp/rd) + P.overlays = list("paper_stamped_rd") + src.contents += P + + P = new() + P.name = "Memo RE: ethical quandaries" + P.info = "Darion-

I don't care what his rank is, our business is that of science and knowledge - questions of moral application do not come into this. Sure, so there are those who would employ the energy-wave particles my modified device has managed to abscond for their own personal gain, but I can hardly see the practical benefits of some of these artifacts our benefactors left behind. Ward--" + P.stamped = list(/obj/item/weapon/stamp/rd) + P.overlays = list("paper_stamped_rd") + src.contents += P + + P = new() + P.name = "READ ME! Before you people destroy any more samples" + P.info = "how many times do i have to tell you people, these xeno-arch samples are del-i-cate, and should be handled so! careful application of a focussed, concentrated heat or some corrosive liquids should clear away the extraneous carbon matter, while application of an energy beam will most decidedly destroy it entirely - like someone did to the chemical dispenser! W, the one who signs your paychecks" + P.stamped = list(/obj/item/weapon/stamp/rd) + P.overlays = list("paper_stamped_rd") + src.contents += P + + P = new() + P.name = "Reminder regarding the anomalous material suits" + P.info = "Do you people think the anomaly suits are cheap to come by? I'm about a hair trigger away from instituting a log book for the damn things. Only wear them if you're going out for a dig, and for god's sake don't go tramping around in them unless you're field testing something, R" + P.stamped = list(/obj/item/weapon/stamp/rd) + P.overlays = list("paper_stamped_rd") + src.contents += P \ No newline at end of file diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 19b3e11074b..90ba2d1a365 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -27,9 +27,19 @@ GLOBAL_LIST_EMPTY(apcs) #define APC_UPOVERLAY_LOCKED 4096 #define APC_UPOVERLAY_OPERATING 8192 - #define APC_UPDATE_ICON_COOLDOWN 100 // 10 seconds +// main_status var +#define APC_EXTERNAL_POWER_NOTCONNECTED 0 +#define APC_EXTERNAL_POWER_NOENERGY 1 +#define APC_EXTERNAL_POWER_GOOD 2 + +// has_electronics var +#define APC_HAS_ELECTRONICS_NONE 0 +#define APC_HAS_ELECTRONICS_WIRED 1 +#define APC_HAS_ELECTRONICS_SECURED 2 + + // the Area Power Controller (APC), formerly Power Distribution Unit (PDU) // one per area, needs wire conection to power network through a terminal @@ -101,13 +111,13 @@ GLOBAL_LIST_EMPTY(apcs) var/lastused_environ = 0 var/lastused_charging = 0 var/lastused_total = 0 - var/main_status = 0 + var/main_status = APC_EXTERNAL_POWER_NOTCONNECTED var/mob/living/silicon/ai/hacker = null // Malfunction var. If set AI hacked the APC and has full control. var/wiresexposed = 0 powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :( var/debug= 0 var/autoflag= 0 // 0 = off, 1= eqp and lights off, 2 = eqp off, 3 = all on. - var/has_electronics = 0 // 0 - none, 1 - plugged in, 2 - secured by screwdriver + var/has_electronics = APC_HAS_ELECTRONICS_NONE // 0 - none, 1 - plugged in, 2 - secured by screwdriver var/beenhit = 0 // used for counting how many times it has been hit, used for Aliens at the moment var/longtermpower = 10 var/datum/wires/apc/wires = null @@ -131,7 +141,7 @@ GLOBAL_LIST_EMPTY(apcs) var/last_nightshift_switch = 0 /obj/machinery/power/apc/updateDialog() - if (stat & (BROKEN|MAINT)) + if(stat & (BROKEN|MAINT)) return ..() @@ -175,12 +185,12 @@ GLOBAL_LIST_EMPTY(apcs) // offset 24 pixels in direction of dir // this allows the APC to be embedded in a wall, yet still inside an area - if (building) + if(building) set_dir(ndir) - pixel_x = (src.dir & 3)? 0 : (src.dir == 4 ? 26 : -26) //VOREStation Edit -> 24 to 26 - pixel_y = (src.dir & 3)? (src.dir ==1 ? 26 : -26) : 0 //VOREStation Edit -> 24 to 26 - if (building==0) + pixel_x = (dir & 3)? 0 : (dir == 4 ? 26 : -26) //VOREStation Edit -> 24 to 26 + pixel_y = (dir & 3)? (dir ==1 ? 26 : -26) : 0 //VOREStation Edit -> 24 to 26 + if(building==0) init() else area = get_area(src) @@ -189,11 +199,11 @@ GLOBAL_LIST_EMPTY(apcs) operating = 0 name = "[area.name] APC" stat |= MAINT - src.update_icon() + update_icon() /obj/machinery/power/apc/Destroy() GLOB.apcs -= src - src.update() + update() area.apc = null area.power_light = 0 area.power_equip = 0 @@ -216,11 +226,11 @@ GLOBAL_LIST_EMPTY(apcs) // APCs are pixel-shifted, so they need to be updated. /obj/machinery/power/apc/set_dir(new_dir) ..() - pixel_x = (src.dir & 3)? 0 : (src.dir == 4 ? 24 : -24) - pixel_y = (src.dir & 3)? (src.dir ==1 ? 24 : -24) : 0 + pixel_x = (dir & 3)? 0 : (dir == 4 ? 24 : -24) + pixel_y = (dir & 3)? (dir ==1 ? 24 : -24) : 0 if(terminal) terminal.disconnect_from_network() - terminal.set_dir(src.dir) // Terminal has same dir as master + terminal.set_dir(dir) // Terminal has same dir as master terminal.connect_to_network() // Refresh the network the terminal is connected to. return @@ -230,25 +240,25 @@ GLOBAL_LIST_EMPTY(apcs) /obj/machinery/power/apc/proc/make_terminal() // create a terminal object at the same position as original turf loc // wires will attach to this - terminal = new/obj/machinery/power/terminal(src.loc) + terminal = new/obj/machinery/power/terminal(loc) terminal.set_dir(dir) terminal.master = src /obj/machinery/power/apc/proc/init() - has_electronics = 2 //installed and secured + has_electronics = APC_HAS_ELECTRONICS_SECURED //installed and secured // is starting with a power cell installed, create it and set its charge level if(cell_type) - src.cell = new cell_type(src) + cell = new cell_type(src) cell.charge = start_charge * cell.maxcharge / 100.0 // (convert percentage to actual value) - var/area/A = src.loc.loc + var/area/A = loc.loc //if area isn't specified use current - if(isarea(A) && src.areastring == null) - src.area = A + if(isarea(A) && !areastring) + area = A name = "\improper [area.name] APC" else - src.area = get_area_name(areastring) + area = get_area_name(areastring) name = "\improper [area.name] APC" area.apc = src @@ -260,7 +270,7 @@ GLOBAL_LIST_EMPTY(apcs) make_terminal() spawn(5) - src.update() + update() /obj/machinery/power/apc/examine(mob/user) . = ..() @@ -271,17 +281,17 @@ GLOBAL_LIST_EMPTY(apcs) else if(opened) if(has_electronics && terminal) . += "The cover is [opened == 2 ? "removed" : "open"] and [ cell ? "a power cell is installed" : "the power cell is missing"]." - else if (!has_electronics && terminal) + else if(!has_electronics && terminal) . += "The frame is wired, but the electronics are missing." - else if (has_electronics && !terminal) + else if(has_electronics && !terminal) . += "The electronics are installed, but not wired." - else /* if (!has_electronics && !terminal) */ + else /* if(!has_electronics && !terminal) */ . += "It's just an empty metal frame." else - if (wiresexposed) + if(wiresexposed) . += "The cover is closed and the wires are exposed." - else if ((locked && emagged) || hacker) //Some things can cause locked && emagged. Malf AI causes hacker. + else if((locked && emagged) || hacker) //Some things can cause locked && emagged. Malf AI causes hacker. . += "The cover is closed, but the panel is unresponsive." else if(!locked && emagged) //Normal emag does this. . += "The cover is closed, but the panel is flashing an error." @@ -292,7 +302,7 @@ GLOBAL_LIST_EMPTY(apcs) // update the APC icon to show the three base states // also add overlays for indicator lights /obj/machinery/power/apc/update_icon() - if (!status_overlays) + if(!status_overlays) status_overlays = 1 status_overlays_lock = new status_overlays_charging = new @@ -424,7 +434,7 @@ GLOBAL_LIST_EMPTY(apcs) else if(charging == 2) update_overlay |= APC_UPOVERLAY_CHARGEING2 - if (!equipment) + if(!equipment) update_overlay |= APC_UPOVERLAY_EQUIPMENT0 else if(equipment == 1) update_overlay |= APC_UPOVERLAY_EQUIPMENT1 @@ -468,35 +478,34 @@ GLOBAL_LIST_EMPTY(apcs) //attack with an item - open/close cover, insert cell, or (un)lock interface /obj/machinery/power/apc/attackby(obj/item/W, mob/user) - - if (istype(user, /mob/living/silicon) && get_dist(src,user)>1) - return src.attack_hand(user) - src.add_fingerprint(user) - if (W.is_crowbar() && opened) - if (has_electronics==1) - if (terminal) + if(issilicon(user) && get_dist(src,user) > 1) + return attack_hand(user) + add_fingerprint(user) + if(W.is_crowbar() && opened) + if(has_electronics == APC_HAS_ELECTRONICS_WIRED) + if(terminal) to_chat(user, "Disconnect the wires first.") return playsound(src, W.usesound, 50, 1) to_chat(user, "You begin to remove the power control board...") //lpeters - fixed grammar issues //Ner - grrrrrr if(do_after(user, 50 * W.toolspeed)) - if (has_electronics==1) - has_electronics = 0 - if ((stat & BROKEN)) + if(has_electronics == APC_HAS_ELECTRONICS_WIRED) + has_electronics = APC_HAS_ELECTRONICS_NONE + if((stat & BROKEN)) user.visible_message(\ - "[user.name] has broken the charred power control board inside [src.name]!",\ + "[user.name] has broken the charred power control board inside [name]!",\ "You broke the charred power control board and remove the remains.", "You hear a crack!") //ticker.mode:apcs-- //XSI said no and I agreed. -rastaf0 else user.visible_message(\ - "[user.name] has removed the power control board from [src.name]!",\ + "[user.name] has removed the power control board from [name]!",\ "You remove the power control board.") new /obj/item/weapon/module/power_control(loc) - else if (opened!=2) //cover isn't removed + else if(opened != 2) //cover isn't removed opened = 0 update_icon() - else if (W.is_crowbar() && !(stat & BROKEN) ) + else if(W.is_crowbar() && !(stat & BROKEN) ) if(coverlocked && !(stat & MAINT)) to_chat(user, "The cover is locked and cannot be opened.") return @@ -505,9 +514,9 @@ GLOBAL_LIST_EMPTY(apcs) update_icon() else if (istype(W, /obj/item/weapon/cell) && opened) // trying to put a cell inside if(cell) - to_chat(user, "The [src.name] already has a power cell installed.") + to_chat(user, "The [name] already has a power cell installed.") return - if (stat & MAINT) + if(stat & MAINT) to_chat(user, "You need to install the wiring and electronics first.") return if(W.w_class != ITEMSIZE_NORMAL) @@ -518,27 +527,27 @@ GLOBAL_LIST_EMPTY(apcs) W.forceMove(src) cell = W user.visible_message(\ - "[user.name] has inserted a power cell into [src.name]!",\ + "[user.name] has inserted a power cell into [name]!",\ "You insert the power cell.") chargecount = 0 update_icon() else if (W.is_screwdriver()) // haxing if(opened) - if (cell) + if(cell) to_chat(user, "Remove the power cell first.") return else - if (has_electronics==1 && terminal) - has_electronics = 2 + if(has_electronics == APC_HAS_ELECTRONICS_WIRED && terminal) + has_electronics = APC_HAS_ELECTRONICS_SECURED stat &= ~MAINT playsound(src, W.usesound, 50, 1) to_chat(user, "You screw the circuit electronics into place.") - else if (has_electronics==2) - has_electronics = 1 + else if(has_electronics == APC_HAS_ELECTRONICS_SECURED) + has_electronics = APC_HAS_ELECTRONICS_WIRED stat |= MAINT playsound(src, W.usesound, 50, 1) to_chat(user, "You unfasten the electronics.") - else /* has_electronics==0 */ + else /* has_electronics == APC_HAS_ELECTRONICS_NONE */ to_chat(user, "There is nothing to secure.") return update_icon() @@ -548,10 +557,10 @@ GLOBAL_LIST_EMPTY(apcs) playsound(src, W.usesound, 50, 1) update_icon() - else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card - togglelock() + else if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card + togglelock(user) - else if (istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics!=2) + else if(istype(W, /obj/item/stack/cable_coil) && !terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED) var/turf/T = loc if(istype(T) && !T.is_plating()) to_chat(user, "You must remove the floor plating in front of the APC first.") @@ -564,9 +573,9 @@ GLOBAL_LIST_EMPTY(apcs) "You start adding cables to the APC frame...") playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) if(do_after(user, 20)) - if (C.amount >= 10 && !terminal && opened && has_electronics != 2) + if(C.amount >= 10 && !terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED) var/obj/structure/cable/N = T.get_cable_node() - if (prob(50) && electrocute_mob(usr, N, N)) + if(prob(50) && electrocute_mob(usr, N, N)) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() @@ -578,7 +587,7 @@ GLOBAL_LIST_EMPTY(apcs) "You add cables to the APC frame.") make_terminal() terminal.connect_to_network() - else if (W.is_wirecutter() && terminal && opened && has_electronics!=2) + else if(W.is_wirecutter() && terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED) var/turf/T = loc if(istype(T) && !T.is_plating()) to_chat(user, "You must remove the floor plating in front of the APC first.") @@ -587,8 +596,8 @@ GLOBAL_LIST_EMPTY(apcs) "You begin to cut the cables...") playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) if(do_after(user, 50 * W.toolspeed)) - if(terminal && opened && has_electronics!=2) - if (prob(50) && electrocute_mob(usr, terminal.powernet, terminal)) + if(terminal && opened && has_electronics != APC_HAS_ELECTRONICS_SECURED) + if(prob(50) && electrocute_mob(usr, terminal.powernet, terminal)) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() @@ -597,22 +606,22 @@ GLOBAL_LIST_EMPTY(apcs) new /obj/item/stack/cable_coil(loc,10) to_chat(user, "You cut the cables and dismantle the power terminal.") qdel(terminal) - else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && !((stat & BROKEN))) + else if(istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics == APC_HAS_ELECTRONICS_NONE && !((stat & BROKEN))) user.visible_message("[user.name] inserts the power control board into [src].", \ "You start to insert the power control board into the frame...") playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) if(do_after(user, 10)) - if(has_electronics==0) - has_electronics = 1 + if(has_electronics == APC_HAS_ELECTRONICS_NONE) + has_electronics = APC_HAS_ELECTRONICS_WIRED reboot() to_chat(user, "You place the power control board inside the frame.") qdel(W) - else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && ((stat & BROKEN))) + else if(istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics == APC_HAS_ELECTRONICS_NONE && ((stat & BROKEN))) to_chat(user, "The [src] is too broken for that. Repair it first.") return - else if (istype(W, /obj/item/weapon/weldingtool) && opened && has_electronics==0 && !terminal) + else if(istype(W, /obj/item/weapon/weldingtool) && opened && has_electronics == APC_HAS_ELECTRONICS_NONE && !terminal) var/obj/item/weapon/weldingtool/WT = W - if (WT.get_fuel() < 3) + if(WT.get_fuel() < 3) to_chat(user, "You need more welding fuel to complete this task.") return user.visible_message("[user.name] begins cutting apart [src] with the [WT.name].", \ @@ -621,7 +630,7 @@ GLOBAL_LIST_EMPTY(apcs) playsound(src, WT.usesound, 25, 1) if(do_after(user, 50 * WT.toolspeed)) if(!src || !WT.remove_fuel(3, user)) return - if (emagged || (stat & BROKEN) || opened==2) + if(emagged || (stat & BROKEN) || opened==2) new /obj/item/stack/material/steel(loc) user.visible_message(\ "[src] has been cut apart by [user.name] with the [WT.name].",\ @@ -635,8 +644,8 @@ GLOBAL_LIST_EMPTY(apcs) "You hear welding.") qdel(src) return - else if (opened && ((stat & BROKEN) || hacker || emagged)) - if (istype(W, /obj/item/frame/apc) && (stat & BROKEN)) + else if(opened && ((stat & BROKEN) || hacker || emagged)) + if(istype(W, /obj/item/frame/apc) && (stat & BROKEN)) if(cell) to_chat(user, "You need to remove the power cell first.") return @@ -648,10 +657,10 @@ GLOBAL_LIST_EMPTY(apcs) qdel(W) stat &= ~BROKEN reboot() - if (opened==2) + if(opened==2) opened = 1 update_icon() - else if (istype(W, /obj/item/device/multitool) && (hacker || emagged)) + else if(istype(W, /obj/item/device/multitool) && (hacker || emagged)) if(cell) to_chat(user, "You need to remove the power cell first.") return @@ -663,12 +672,12 @@ GLOBAL_LIST_EMPTY(apcs) playsound(src, 'sound/machines/chime.ogg', 25, 1) reboot() else - if ((stat & BROKEN) \ + if((stat & BROKEN) \ && !opened \ && W.force >= 5 \ && W.w_class >= ITEMSIZE_SMALL ) - user.visible_message("The [src.name] has been hit with the [W.name] by [user.name]!", \ - "You hit the [src.name] with your [W.name]!", \ + user.visible_message("The [name] has been hit with the [W.name] by [user.name]!", \ + "You hit the [name] with your [W.name]!", \ "You hear a bang!") if(prob(20)) opened = 2 @@ -677,12 +686,12 @@ GLOBAL_LIST_EMPTY(apcs) "You hear a bang!") update_icon() else - if (istype(user, /mob/living/silicon)) - return src.attack_hand(user) - if (!opened && wiresexposed && (istype(W, /obj/item/device/multitool) || W.is_wirecutter() || istype(W, /obj/item/device/assembly/signaler))) - return src.attack_hand(user) + if(istype(user, /mob/living/silicon)) + return attack_hand(user) + if(!opened && wiresexposed && (istype(W, /obj/item/device/multitool) || W.is_wirecutter() || istype(W, /obj/item/device/assembly/signaler))) + return attack_hand(user) //Placeholder until someone can do take_damage() for APCs or something. - to_chat(user, "The [src.name] looks too sturdy to bash open with \the [W.name].") + to_chat(user, "The [name] looks too sturdy to bash open with \the [W.name].") // attack with hand - remove cell (if cover open) or interact with the APC @@ -698,7 +707,7 @@ GLOBAL_LIST_EMPTY(apcs) else if(hacker) to_chat(user, "Access denied.") else - if(src.allowed(usr) && !isWireCut(APC_WIRE_IDSCAN)) + if(allowed(user) && !wires.is_cut(WIRE_IDSCAN)) locked = !locked to_chat(user, "You [ locked ? "lock" : "unlock"] the APC interface.") update_icon() @@ -707,10 +716,10 @@ GLOBAL_LIST_EMPTY(apcs) /obj/machinery/power/apc/AltClick(mob/user) ..() - togglelock() + togglelock(user) /obj/machinery/power/apc/emag_act(var/remaining_charges, var/mob/user) - if (!(emagged || hacker)) // trying to unlock with an emag card + if(!(emagged || hacker)) // trying to unlock with an emag card if(opened) to_chat(user, "You must close the cover to do that.") else if(wiresexposed) @@ -719,7 +728,7 @@ GLOBAL_LIST_EMPTY(apcs) to_chat(user, "The [src] isn't working.") else flick("apc-spark", src) - if (do_after(user,6)) + if(do_after(user,6)) emagged = 1 locked = 0 to_chat(user, "You emag the APC interface.") @@ -727,17 +736,15 @@ GLOBAL_LIST_EMPTY(apcs) return 1 /obj/machinery/power/apc/blob_act() - if(!wires.IsAllCut()) + if(!wires.is_all_cut()) wiresexposed = TRUE - wires.CutAll() + wires.cut_all() update_icon() /obj/machinery/power/apc/attack_hand(mob/user) -// if (!can_use(user)) This already gets called in interact() and in topic() -// return if(!user) return - src.add_fingerprint(user) + add_fingerprint(user) //Human mob special interaction goes here. if(istype(user,/mob/living/carbon/human)) @@ -745,20 +752,20 @@ GLOBAL_LIST_EMPTY(apcs) if(H.species.can_shred(H)) user.setClickCooldown(user.get_attack_speed()) - user.visible_message("[user.name] slashes at the [src.name]!", "You slash at the [src.name]!") + user.visible_message("[user.name] slashes at the [name]!", "You slash at the [name]!") playsound(src, 'sound/weapons/slash.ogg', 100, 1) - var/allcut = wires.IsAllCut() + var/allcut = wires.is_all_cut() if(beenhit >= pick(3, 4) && wiresexposed != 1) wiresexposed = 1 - src.update_icon() - src.visible_message("The [src.name]'s cover flies open, exposing the wires!") + update_icon() + visible_message("The [name]'s cover flies open, exposing the wires!") else if(wiresexposed == 1 && allcut == 0) - wires.CutAll() - src.update_icon() - src.visible_message("The [src.name]'s wires are shredded!") + wires.cut_all() + update_icon() + visible_message("The [name]'s wires are shredded!") else beenhit += 1 return @@ -769,16 +776,21 @@ GLOBAL_LIST_EMPTY(apcs) cell.add_fingerprint(user) cell.update_icon() - src.cell = null - user.visible_message("[user.name] removes the power cell from [src.name]!",\ + cell = null + user.visible_message("[user.name] removes the power cell from [name]!",\ "You remove the power cell.") charging = 0 - src.update_icon() + update_icon() return if(stat & (BROKEN|MAINT)) return // do APC interaction - src.interact(user) + interact(user) + +/obj/machinery/power/apc/attack_ghost(mob/user) + if(panel_open) + return wires.Interact(user) + return tgui_interact(user) /obj/machinery/power/apc/interact(mob/user) if(!user) @@ -788,15 +800,18 @@ GLOBAL_LIST_EMPTY(apcs) wires.Interact(user) return //The panel is visibly dark when the wires are exposed, so we shouldn't be able to interact with it. - return ui_interact(user) + return tgui_interact(user) +/obj/machinery/power/apc/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "APC", name) // 510, 460 + ui.open() -/obj/machinery/power/apc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(!user) - return - +/obj/machinery/power/apc/tgui_data(mob/user) var/list/data = list( "locked" = locked, + "normallyLocked" = locked, "emagged" = emagged, "isOperating" = operating, "externalPower" = main_status, @@ -808,7 +823,7 @@ GLOBAL_LIST_EMPTY(apcs) "failTime" = failure_timer * 2, "gridCheck" = grid_check, "coverLocked" = coverlocked, - "siliconUser" = issilicon(user) || isobserver(user), //I add observer here so admins can have more control, even if it makes 'siliconUser' seem inaccurate. + "siliconUser" = issilicon(user) || (isobserver(user) && is_admin(user)), //I add observer here so admins can have more control, even if it makes 'siliconUser' seem inaccurate. "emergencyLights" = !emergency_lights, "nightshiftLights" = nightshift_lights, "nightshiftSetting" = nightshift_setting, @@ -847,18 +862,7 @@ GLOBAL_LIST_EMPTY(apcs) ) ) - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "apc.tmpl", "[area.name] - APC", 520, data["siliconUser"] ? 490 : 465) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) + return data /obj/machinery/power/apc/proc/report() return "[area.name] : [equipment]/[lighting]/[environ] ([lastused_equip+lastused_light+lastused_environ]) : [cell? cell.percent() : "N/C"] ([charging])" @@ -868,27 +872,23 @@ GLOBAL_LIST_EMPTY(apcs) area.power_light = (lighting >= POWERCHAN_ON) area.power_equip = (equipment >= POWERCHAN_ON) area.power_environ = (environ >= POWERCHAN_ON) -// if (area.name == "AI Chamber") +// if(area.name == "AI Chamber") // spawn(10) // to_world(" [area.name] [area.power_equip]") else area.power_light = 0 area.power_equip = 0 area.power_environ = 0 -// if (area.name == "AI Chamber") +// if(area.name == "AI Chamber") // to_world("[area.power_equip]") area.power_change() -/obj/machinery/power/apc/proc/isWireCut(var/wireIndex) - return wires.IsIndexCut(wireIndex) - - /obj/machinery/power/apc/proc/can_use(mob/user as mob, var/loud = 0) //used by attack_hand() and Topic() if(!user.client) return 0 - if(isobserver(user) && is_admin(user) ) //This is to allow nanoUI interaction by ghost admins. + if(isobserver(user) && is_admin(user)) //This is to allow nanoUI interaction by ghost admins. return 1 - if (user.stat) + if(user.stat) return 0 if(inoperable()) return 0 @@ -901,7 +901,7 @@ GLOBAL_LIST_EMPTY(apcs) to_chat(user, "You must stand to use [src]!") return 0 autoflag = 5 - if (istype(user, /mob/living/silicon)) + if(istype(user, /mob/living/silicon)) var/permit = 0 // Malfunction variable. If AI hacks APC it can control it even without AI control wire. var/mob/living/silicon/ai/AI = user var/mob/living/silicon/robot/robot = user @@ -916,122 +916,90 @@ GLOBAL_LIST_EMPTY(apcs) to_chat(user, "\The AI control for [src] has been disabled!") return 0 else - if (!in_range(src, user) || !istype(src.loc, /turf)) + if(!in_range(src, user) || !istype(loc, /turf)) return 0 var/mob/living/carbon/human/H = user - if (istype(H) && prob(H.getBrainLoss())) + if(istype(H) && prob(H.getBrainLoss())) to_chat(user, "You momentarily forget how to use [src].") return 0 return 1 -/obj/machinery/power/apc/Topic(href, href_list) - if(..()) - return 1 +/obj/machinery/power/apc/tgui_act(action, params) + if(..() || !can_use(usr, TRUE)) + return TRUE - if(!can_use(usr, 1)) - return 1 + // There's a handful of cases where we want to allow users to bypass the `locked` variable. + // If can_admin_interact() wasn't only defined on observers, this could just be part of a single-line + // conditional. + var/locked_exception = FALSE + if(issilicon(usr) || action == "nightshift") + locked_exception = TRUE + if(isobserver(usr)) + var/mob/observer/dead/D = usr + if(D.can_admin_interact()) + locked_exception = TRUE - if(href_list["nightshift"]) - if(last_nightshift_switch > world.time - 10 SECONDS) // don't spam... - to_chat(usr, "[src]'s night lighting circuit breaker is still cycling!") - return 0 - last_nightshift_switch = world.time - nightshift_setting = text2num(href_list["nightshift"]) - update_nightshift() - return 1 + if(locked && !locked_exception) + return - if(locked && !issilicon(usr) ) - if(isobserver(usr) ) - var/mob/observer/dead/O = usr //Added to allow admin nanoUI interactions. - if(!O.can_admin_interact() ) //NanoUI /should/ make this not needed, but better safe than sorry. - to_chat(usr, "Try as you might, your ghostly fingers can't press the buttons.") - return 1 - else - to_chat(usr, "You must unlock the panel to use this!") - return 1 - - if (href_list["lock"]) - coverlocked = !coverlocked - - else if (href_list["reboot"]) - failure_timer = 0 - update_icon() - update() - - else if (href_list["emergency_lighting"]) - emergency_lights = !emergency_lights - for(var/obj/machinery/light/L in area) - if(!initial(L.no_emergency)) //If there was an override set on creation, keep that override - L.no_emergency = emergency_lights - INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE) - CHECK_TICK - - else if (href_list["breaker"]) - toggle_breaker() - - else if (href_list["cmode"]) - chargemode = !chargemode - if(!chargemode) - charging = 0 + . = TRUE + switch(action) + if("lock") + if(locked_exception) // Yay code reuse + if(emagged || (stat & (BROKEN|MAINT))) + to_chat(usr, "The APC does not respond to the command.") + return + locked = !locked + update_icon() + if("cover") + coverlocked = !coverlocked + if("breaker") + toggle_breaker() + if("nightshift") + if(last_nightshift_switch > world.time - 10 SECONDS) // don't spam... + to_chat(usr, "[src]'s night lighting circuit breaker is still cycling!") + return 0 + last_nightshift_switch = world.time + nightshift_setting = params["nightshift"] + update_nightshift() + if("charge") + chargemode = !chargemode + if(!chargemode) + charging = 0 + update_icon() + if("channel") + if(params["eqp"]) + equipment = setsubsystem(text2num(params["eqp"])) + update_icon() + update() + else if(params["lgt"]) + lighting = setsubsystem(text2num(params["lgt"])) + update_icon() + update() + else if(params["env"]) + environ = setsubsystem(text2num(params["env"])) + update_icon() + update() + if("reboot") + failure_timer = 0 update_icon() - - else if (href_list["eqp"]) - var/val = text2num(href_list["eqp"]) - equipment = setsubsystem(val) - update_icon() - update() - - else if (href_list["lgt"]) - var/val = text2num(href_list["lgt"]) - lighting = setsubsystem(val) - update_icon() - update() - - else if (href_list["env"]) - var/val = text2num(href_list["env"]) - environ = setsubsystem(val) - update_icon() - update() - - else if (href_list["overload"]) - if(istype(usr, /mob/living/silicon)) - src.overload_lighting() - - else if (href_list["toggleaccess"]) - if(istype(usr, /mob/living/silicon)) - if(emagged || (stat & (BROKEN|MAINT))) - to_chat(usr, "The APC does not respond to the command.") - return - locked = !locked - update_icon() - - return 0 + update() + if("emergency_lighting") + emergency_lights = !emergency_lights + for(var/obj/machinery/light/L in area) + if(!initial(L.no_emergency)) //If there was an override set on creation, keep that override + L.no_emergency = emergency_lights + INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE) + CHECK_TICK + if("overload") + if(locked_exception) // Reusing for simplicity! + overload_lighting() /obj/machinery/power/apc/proc/toggle_breaker() operating = !operating - src.update() + update() update_icon() -//This isn't used for now, so might as well disable it -/* -/obj/machinery/power/apc/proc/ion_act() - if(prob(3)) - src.locked = 1 - if (src.cell.charge > 0) - src.cell.charge = 0 - cell.corrupt() - update_icon() - var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread() - smoke.set_up(3, 0, src.loc) - smoke.attach(src) - smoke.start() - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - visible_message("The [src.name] suddenly lets out a blast of smoke and some sparks!", \ - "You hear sizzling electronics.") -*/ - /obj/machinery/power/apc/surplus() if(terminal) return terminal.surplus() @@ -1087,12 +1055,12 @@ GLOBAL_LIST_EMPTY(apcs) var/excess = surplus() - if(!src.avail()) - main_status = 0 + if(!avail()) + main_status = APC_EXTERNAL_POWER_NOTCONNECTED else if(excess < 0) - main_status = 1 + main_status = APC_EXTERNAL_POWER_NOENERGY else - main_status = 2 + main_status = APC_EXTERNAL_POWER_GOOD if(debug) log_debug("Status: [main_status] - Excess: [excess] - Last Equip: [lastused_equip] - Last Light: [lastused_light] - Longterm: [longtermpower]") @@ -1126,7 +1094,7 @@ GLOBAL_LIST_EMPTY(apcs) // now trickle-charge the cell lastused_charging = 0 // Clear the variable for new use. - if(src.attempt_charging()) + if(attempt_charging()) if(excess > 0) // check to make sure we have enough to charge // Max charge is capped to % per second constant var/ch = min(excess*CELLRATE, cell.maxcharge*chargelevel) @@ -1174,7 +1142,7 @@ GLOBAL_LIST_EMPTY(apcs) force_update = 0 queue_icon_update() update() - else if (last_ch != charging) + else if(last_ch != charging) queue_icon_update() /obj/machinery/power/apc/proc/update_channels() @@ -1216,7 +1184,7 @@ GLOBAL_LIST_EMPTY(apcs) // val 0=off, 1=off(auto) 2=on 3=on(auto) // on 0=off, 1=on, 2=autooff // defines a state machine, returns the new state -obj/machinery/power/apc/proc/autoset(var/cur_state, var/on) +/obj/machinery/power/apc/proc/autoset(var/cur_state, var/on) switch(cur_state) //if(POWERCHAN_OFF); //autoset will never turn on a channel set to off if(POWERCHAN_OFF_AUTO) @@ -1257,24 +1225,24 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on) switch(severity) if(1) //set_broken() //now qdel() do what we need - if (cell) + if(cell) cell.ex_act(1) // more lags woohoo qdel(src) return if(2) - if (prob(75)) + if(prob(75)) set_broken() - if (cell && prob(50)) + if(cell && prob(50)) cell.ex_act(2) if(3) - if (prob(50)) + if(prob(50)) set_broken() - if (cell && prob(50)) + if(cell && prob(50)) cell.ex_act(3) if(4) - if (prob(25)) + if(prob(25)) set_broken() - if (cell && prob(50)) + if(cell && prob(50)) cell.ex_act(3) return @@ -1286,7 +1254,7 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on) /obj/machinery/power/apc/proc/set_broken() // Aesthetically much better! spawn(rand(2,5)) - src.visible_message("[src]'s screen flickers suddenly, then explodes in a rain of sparks and small debris!") + visible_message("[src]'s screen flickers suddenly, then explodes in a rain of sparks and small debris!") stat |= BROKEN operating = 0 update_icon() @@ -1318,7 +1286,7 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on) /obj/machinery/power/apc/proc/ai_hack(var/mob/living/silicon/ai/A = null) if(!A || !A.hacked_apcs || hacker || aidisabled || A.stat == DEAD) return 0 - src.hacker = A + hacker = A A.hacked_apcs += src locked = 1 update_icon() @@ -1410,3 +1378,11 @@ obj/machinery/power/apc/proc/autoset(var/cur_state, var/on) CHECK_TICK #undef APC_UPDATE_ICON_COOLDOWN + +#undef APC_EXTERNAL_POWER_NOTCONNECTED +#undef APC_EXTERNAL_POWER_NOENERGY +#undef APC_EXTERNAL_POWER_GOOD + +#undef APC_HAS_ELECTRONICS_NONE +#undef APC_HAS_ELECTRONICS_WIRED +#undef APC_HAS_ELECTRONICS_SECURED \ No newline at end of file diff --git a/code/modules/power/breaker_box.dm b/code/modules/power/breaker_box.dm index dc7cd0c519d..5ebf4826795 100644 --- a/code/modules/power/breaker_box.dm +++ b/code/modules/power/breaker_box.dm @@ -25,7 +25,7 @@ for(var/obj/structure/cable/C in src.loc) qdel(C) . = ..() - for(var/datum/nano_module/rcon/R in world) + for(var/datum/tgui_module/rcon/R in world) R.FindDevices() /obj/machinery/power/breakerbox/Initialize() diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 19ba3b80650..c6ad30ccc5d 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -192,58 +192,48 @@ GLOBAL_LIST_EMPTY(all_turbines) if(stat & (BROKEN|NOPOWER) || !anchored) return if(!circ1 || !circ2) //Just incase the middle part of the TEG was not wrenched last. reconnect() - ui_interact(user) + tgui_interact(user) -/obj/machinery/power/generator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/power/generator/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TEGenerator", name) + ui.open() + +/obj/machinery/power/generator/tgui_data(mob/user) // this is the data which will be sent to the ui var/vertical = 0 if (dir == NORTH || dir == SOUTH) vertical = 1 - var/data[0] - data["totalOutput"] = effective_gen/1000 - data["maxTotalOutput"] = max_power/1000 - data["thermalOutput"] = last_thermal_gen/1000 - data["circConnected"] = 0 + var/list/data = list() + data["totalOutput"] = effective_gen + data["maxTotalOutput"] = max_power + data["thermalOutput"] = last_thermal_gen + data["primary"] = list() if(circ1) //The one on the left (or top) - data["primaryDir"] = vertical ? "top" : "left" - data["primaryOutput"] = last_circ1_gen/1000 - data["primaryFlowCapacity"] = circ1.volume_capacity_used*100 - data["primaryInletPressure"] = circ1.air1.return_pressure() - data["primaryInletTemperature"] = circ1.air1.temperature - data["primaryOutletPressure"] = circ1.air2.return_pressure() - data["primaryOutletTemperature"] = circ1.air2.temperature + data["primary"]["dir"] = vertical ? "top" : "left" + data["primary"]["output"] = last_circ1_gen + data["primary"]["flowCapacity"] = circ1.volume_capacity_used*100 + data["primary"]["inletPressure"] = circ1.air1.return_pressure() + data["primary"]["inletTemperature"] = circ1.air1.temperature + data["primary"]["outletPressure"] = circ1.air2.return_pressure() + data["primary"]["outletTemperature"] = circ1.air2.temperature + data["secondary"] = list() if(circ2) //Now for the one on the right (or bottom) - data["secondaryDir"] = vertical ? "bottom" : "right" - data["secondaryOutput"] = last_circ2_gen/1000 - data["secondaryFlowCapacity"] = circ2.volume_capacity_used*100 - data["secondaryInletPressure"] = circ2.air1.return_pressure() - data["secondaryInletTemperature"] = circ2.air1.temperature - data["secondaryOutletPressure"] = circ2.air2.return_pressure() - data["secondaryOutletTemperature"] = circ2.air2.temperature + data["secondary"]["dir"] = vertical ? "bottom" : "right" + data["secondary"]["output"] = last_circ2_gen + data["secondary"]["flowCapacity"] = circ2.volume_capacity_used*100 + data["secondary"]["inletPressure"] = circ2.air1.return_pressure() + data["secondary"]["inletTemperature"] = circ2.air1.temperature + data["secondary"]["outletPressure"] = circ2.air2.return_pressure() + data["secondary"]["outletTemperature"] = circ2.air2.temperature - if(circ1 && circ2) - data["circConnected"] = 1 - else - data["circConnected"] = 0 - - - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "generator.tmpl", "Thermoelectric Generator", 450, 500) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) + return data /obj/machinery/power/generator/power_change() ..() diff --git a/code/modules/power/gravitygenerator_vr.dm b/code/modules/power/gravitygenerator_vr.dm index 6e3d784fe40..3e4767a9a9b 100644 --- a/code/modules/power/gravitygenerator_vr.dm +++ b/code/modules/power/gravitygenerator_vr.dm @@ -240,11 +240,16 @@ GLOBAL_LIST_EMPTY(gravity_generators) /obj/machinery/gravity_generator/main/attack_hand(mob/user) if((. = ..())) return - if(CanUseTopic(user, global.default_state) > STATUS_CLOSE) - ui_interact(user) - return TRUE + tgui_interact(user) + return TRUE -/obj/machinery/gravity_generator/main/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/gravity_generator/main/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "GravityGenerator", name) + ui.open() + +/obj/machinery/gravity_generator/main/tgui_data(mob/user) var/data[0] data["breaker"] = breaker @@ -253,22 +258,18 @@ GLOBAL_LIST_EMPTY(gravity_generators) data["on"] = on data["operational"] = (stat & BROKEN) ? FALSE : TRUE - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "gravity_generator.tmpl", src.name, 500, 400) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data -/obj/machinery/gravity_generator/main/Topic(href, href_list, datum/topic_state/state = default_state) - if((. = ..())) - return +/obj/machinery/gravity_generator/main/tgui_act(action, params) + if((..())) + return TRUE - if(href_list["gentoggle"]) - breaker = !breaker - investigate_log("was toggled [breaker ? "ON" : "OFF"] by [key_name(usr)].", "gravity") - set_power() - return TOPIC_REFRESH + switch(action) + if("gentoggle") + breaker = !breaker + investigate_log("was toggled [breaker ? "ON" : "OFF"] by [key_name(usr)].", "gravity") + set_power() + return TOPIC_REFRESH // Power and Icon States diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 3251aee2f95..dce52720b47 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -7,6 +7,7 @@ density = 1 anchored = 0 use_power = USE_POWER_OFF + interact_offline = TRUE var/active = 0 var/power_gen = 5000 @@ -28,13 +29,22 @@ /obj/machinery/power/port_gen/proc/handleInactive() return +/obj/machinery/power/port_gen/proc/TogglePower() + if(active) + active = FALSE + icon_state = "[initial(icon_state)]" + // soundloop.stop() + else if(HasFuel()) + active = TRUE + icon_state = "[initial(icon_state)]on" + // soundloop.start() + /obj/machinery/power/port_gen/process() if(active && HasFuel() && !IsBroken() && anchored && powernet) add_avail(power_gen * power_output) UseFuel() - src.updateDialog() else - active = 0 + active = FALSE icon_state = initial(icon_state) handleInactive() @@ -121,7 +131,7 @@ return ..() /obj/machinery/power/port_gen/pacman/dismantle() - while ( sheets > 0 ) + while( sheets > 0 ) DropFuel() return ..() @@ -212,16 +222,16 @@ /obj/machinery/power/port_gen/pacman/handleInactive() var/cooling_temperature = 20 var/datum/gas_mixture/environment = loc.return_air() - if (environment) + if(environment) var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1) var/ambient = environment.temperature - T20C cooling_temperature += ambient*ratio - if (temperature > cooling_temperature) + if(temperature > cooling_temperature) var/temp_loss = (temperature - cooling_temperature)/TEMPERATURE_DIVISOR temp_loss = between(2, round(temp_loss, 1), TEMPERATURE_CHANGE_MAX) temperature = max(temperature - temp_loss, cooling_temperature) - src.updateDialog() + updateDialog() if(overheating) overheating-- @@ -287,97 +297,77 @@ ..() if (!anchored) return - ui_interact(user) + tgui_interact(user) /obj/machinery/power/port_gen/pacman/attack_ai(mob/user as mob) - ui_interact(user) + tgui_interact(user) -/obj/machinery/power/port_gen/pacman/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/power/port_gen/tgui_status(mob/user, datum/tgui_state/state) if(IsBroken()) - return + return STATUS_CLOSE + return ..() + +/obj/machinery/power/port_gen/pacman/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PortableGenerator", name) + ui.open() + +/obj/machinery/power/port_gen/pacman/tgui_data(mob/user) + var/list/data = list() - var/data[0] data["active"] = active + if(istype(user, /mob/living/silicon/ai)) - data["is_ai"] = 1 + data["is_ai"] = TRUE else if(istype(user, /mob/living/silicon/robot) && !Adjacent(user)) - data["is_ai"] = 1 + data["is_ai"] = TRUE else - data["is_ai"] = 0 - data["output_set"] = power_output - data["output_max"] = max_power_output - data["output_safe"] = max_safe_output - data["output_watts"] = power_output * power_gen - data["temperature_current"] = src.temperature - data["temperature_max"] = src.max_temperature - data["temperature_overheat"] = overheating - // 1 sheet = 1000cm3? + data["is_ai"] = FALSE + + data["sheet_name"] = capitalize(sheet_name) data["fuel_stored"] = round((sheets * 1000) + (sheet_left * 1000)) data["fuel_capacity"] = round(max_sheets * 1000, 0.1) data["fuel_usage"] = active ? round((power_output / time_per_sheet) * 1000) : 0 - data["fuel_type"] = sheet_name + data["anchored"] = anchored + data["connected"] = (powernet == null ? 0 : 1) + data["ready_to_boot"] = anchored && HasFuel() + data["power_generated"] = DisplayPower(power_gen) + data["power_output"] = DisplayPower(power_gen * power_output) + data["unsafe_output"] = power_output > max_safe_output + data["power_available"] = (powernet == null ? 0 : DisplayPower(avail())) + data["temperature_current"] = temperature + data["temperature_max"] = max_temperature + data["temperature_overheat"] = overheating + // 1 sheet = 1000cm3? + return data - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "pacman.tmpl", src.name, 500, 560) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - - -/* -/obj/machinery/power/port_gen/pacman/interact(mob/user) - if (get_dist(src, user) > 1 ) - if (!istype(user, /mob/living/silicon/ai)) - user.unset_machine() - user << browse(null, "window=port_gen" - return - - user.set_machine(src) - - var/dat = text("[name]
") - if (active) - dat += text("Generator: On
") - else - dat += text("Generator: Off
") - dat += text("[capitalize(sheet_name)]: [sheets] - Eject
") - var/stack_percent = round(sheet_left * 100, 1) - dat += text("Current stack: [stack_percent]%
") - dat += text("Power output: - [power_gen * power_output] Watts+
") - dat += text("Power current: [(powernet == null ? "Unconnected" : "[avail()]")]
") - - var/tempstr = "Temperature: [temperature]°C
" - dat += (overheating)? "[tempstr]" : tempstr - dat += "
Close" - user << browse("[dat]", "window=port_gen") - onclose(user, "port_gen") -*/ - -/obj/machinery/power/port_gen/pacman/Topic(href, href_list) +/obj/machinery/power/port_gen/pacman/tgui_act(action, params) if(..()) return - src.add_fingerprint(usr) - if(href_list["action"]) - if(href_list["action"] == "enable") - if(!active && HasFuel() && !IsBroken()) - active = 1 - icon_state = "[initial(icon_state)]on" //VOREStation Edit - if(href_list["action"] == "disable") - if (active) - active = 0 - icon_state = initial(icon_state) //VOREStation Edit - if(href_list["action"] == "eject") + add_fingerprint(usr) + switch(action) + if("toggle_power") + TogglePower() + . = TRUE + + if("eject") if(!active) DropFuel() - if(href_list["action"] == "lower_power") - if (power_output > 1) + . = TRUE + + if("lower_power") + if(power_output > 1) power_output-- - if (href_list["action"] == "higher_power") - if (power_output < max_power_output || (emagged && power_output < round(max_power_output*2.5))) + . = TRUE + + if("higher_power") + if(power_output < max_power_output || (emagged && power_output < round(max_power_output * 2.5))) power_output++ + . = TRUE /obj/machinery/power/port_gen/pacman/super name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator" diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm index b08586a4496..1747842df99 100644 --- a/code/modules/power/powernet.dm +++ b/code/modules/power/powernet.dm @@ -5,6 +5,7 @@ var/load = 0 // the current load on the powernet, increased by each machine at processing var/newavail = 0 // what available power was gathered last tick, then becomes... var/avail = 0 //...the current available power in the powernet + var/viewavail = 0 // the availability as it appears on the power console (gradually updated) var/viewload = 0 // the load as it appears on the power console (gradually updated) var/number = 0 // Unused //TODEL @@ -134,7 +135,8 @@ S.restore(perc) //updates the viewed load (as seen on power computers) - viewload = round(load) + viewavail = round(0.8 * viewavail + 0.2 * avail) + viewload = round(0.8 * viewload + 0.2 * load) //reset the powernet load = 0 diff --git a/code/modules/power/sensors/powernet_sensor.dm b/code/modules/power/sensors/powernet_sensor.dm index bc1298d2010..6f1b53db05a 100644 --- a/code/modules/power/sensors/powernet_sensor.dm +++ b/code/modules/power/sensors/powernet_sensor.dm @@ -19,12 +19,22 @@ var/name_tag = "#UNKN#" // ID tag displayed in list of powernet sensors. Each sensor should have it's own tag! var/long_range = 0 // If 1, sensor reading will show on all computers, regardless of Zlevel + var/list/history = list() + var/record_size = 60 + var/record_interval = 50 + var/next_record = 0 + var/is_secret_monitor = FALSE + // Proc: New() // Parameters: None // Description: Automatically assigns name according to ID tag. /obj/machinery/power/sensor/New() ..() auto_set_name() +/obj/machinery/power/sensor/Initialize() + . = ..() + history["supply"] = list() + history["demand"] = list() // Proc: auto_set_name() // Parameters: None @@ -38,6 +48,8 @@ for(var/obj/machinery/computer/power_monitor/PM in machines) if(PM.power_monitor) PM.power_monitor.refresh_sensors() + history.Cut() + history = null // Proc: check_grid_warning() // Parameters: None @@ -51,10 +63,67 @@ // Proc: process() // Parameters: None -// Description: This has to be here because we need sensors to remain in Machines list. +// Description: This tracks historical usage, for TGUI power monitors /obj/machinery/power/sensor/process() + if(!powernet) + use_power = USE_POWER_IDLE + connect_to_network() + else + use_power = USE_POWER_ACTIVE + record() return 1 +// This tracks historical usage, for TGUI power monitors +/obj/machinery/power/sensor/proc/record() + if(world.time >= next_record) + next_record = world.time + record_interval + + var/datum/powernet/connected_powernet = powernet + + var/list/supply = history["supply"] + if(connected_powernet) + supply += connected_powernet.viewavail + if(supply.len > record_size) + supply.Cut(1, 2) + + var/list/demand = history["demand"] + if(connected_powernet) + demand += connected_powernet.viewload + if(demand.len > record_size) + demand.Cut(1, 2) + +/obj/machinery/power/sensor/tgui_data() + var/list/data = list() + + data["name"] = name_tag + data["stored"] = record_size + data["interval"] = record_interval / 10 + data["attached"] = !!powernet + data["history"] = history + + data["areas"] = list() + if(powernet) + for(var/obj/machinery/power/terminal/term in powernet.nodes) + if(istype(term.master, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/A = term.master + if(istype(A)) + var/cell_charge + if(!A.cell) + cell_charge = 0 + else + cell_charge = A.cell.percent() + data["areas"] += list(list( + "name" = A.area.name, + "charge" = cell_charge, + "load" = DisplayPower(A.lastused_total), + "charging" = A.charging, + "eqp" = A.equipment, + "lgt" = A.lighting, + "env" = A.environ, + )) + + return data + // Proc: reading_to_text() // Parameters: 1 (amount - Power in Watts to be converted to W, kW or MW) // Description: Helper proc that converts reading in Watts to kW or MW (returns string version of amount parameter) @@ -178,7 +247,7 @@ APC_entry["total_load"] = reading_to_text(A.lastused_total) // Hopefully removes those goddamn \improper s which are screwing up the UI var/N = A.area.name - if(findtext(N, "ÿ")) + if(findtext(N, "�")) N = copytext(N, 3) APC_entry["name"] = N // Add data into main list of APC data. diff --git a/code/modules/power/sensors/sensor_monitoring.dm b/code/modules/power/sensors/sensor_monitoring.dm index e243b7f75b7..4e6198f410f 100644 --- a/code/modules/power/sensors/sensor_monitoring.dm +++ b/code/modules/power/sensors/sensor_monitoring.dm @@ -18,7 +18,7 @@ use_power = USE_POWER_IDLE idle_power_usage = 300 active_power_usage = 300 - var/datum/nano_module/power_monitor/power_monitor + var/datum/tgui_module/power_monitor/power_monitor // Checks the sensors for alerts. If change (alerts cleared or detected) occurs, calls for icon update. /obj/machinery/computer/power_monitor/process() @@ -47,12 +47,11 @@ if(stat & (BROKEN|NOPOWER)) return - ui_interact(user) + tgui_interact(user) // Uses dark magic to operate the NanoUI of this computer. -/obj/machinery/computer/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - power_monitor.ui_interact(user, ui_key, ui, force_open) - +/obj/machinery/computer/power_monitor/tgui_interact(mob/user, var/datum/tgui/ui = null) + power_monitor.tgui_interact(user, ui) // Verifies if any warnings were registered by connected sensors. /obj/machinery/computer/power_monitor/proc/check_warnings() diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index b8281aa867d..6beda2db159 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -36,7 +36,7 @@ /obj/machinery/particle_accelerator/control_box/attack_hand(mob/user as mob) if(construction_state >= 3) - interact(user) + tgui_interact(user) else if(construction_state == 2) // Wires exposed wires.Interact(user) @@ -77,36 +77,6 @@ else icon_state = "[reference]c" -/obj/machinery/particle_accelerator/control_box/Topic(href, href_list) - ..() - //Ignore input if we are broken, !silicon guy cant touch us, or nonai controlling from super far away - if(stat & (BROKEN|NOPOWER) || (get_dist(src, usr) > 1 && !istype(usr, /mob/living/silicon)) || (get_dist(src, usr) > 8 && !istype(usr, /mob/living/silicon/ai))) - usr.unset_machine() - usr << browse(null, "window=pacontrol") - return - - if( href_list["close"] ) - usr << browse(null, "window=pacontrol") - usr.unset_machine() - return - - if(href_list["togglep"]) - if(!wires.IsIndexCut(PARTICLE_TOGGLE_WIRE)) - toggle_power() - else if(href_list["scan"]) - part_scan() - - else if(href_list["strengthup"]) - if(!wires.IsIndexCut(PARTICLE_STRENGTH_WIRE)) - add_strength() - - else if(href_list["strengthdown"]) - if(!wires.IsIndexCut(PARTICLE_STRENGTH_WIRE)) - remove_strength() - - updateDialog() - update_icon() - /obj/machinery/particle_accelerator/control_box/proc/strength_change() for(var/obj/structure/particle_accelerator/part in connected_parts) part.strength = strength @@ -230,33 +200,54 @@ part.update_icon() return 1 +/obj/machinery/particle_accelerator/control_box/proc/is_interactive(mob/user) + if(!interface_control) + to_chat(user, "ERROR: Request timed out. Check wire contacts.") + return FALSE + if(construction_state != 3) + return FALSE + return TRUE -/obj/machinery/particle_accelerator/control_box/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=pacontrol") - return - user.set_machine(src) +/obj/machinery/particle_accelerator/control_box/tgui_status(mob/user) + if(is_interactive(user)) + return ..() + return STATUS_CLOSE - var/dat = "" - dat += "Particle Accelerator Control Panel
" - dat += "Close

" - dat += "Status:
" - if(!assembled) - dat += "Unable to detect all parts!
" - dat += "Run Scan

" - else - dat += "All parts in place.

" - dat += "Power:" - if(active) - dat += "On
" - else - dat += "Off
" - dat += "Toggle Power

" - dat += "Particle Strength: [src.strength] " - dat += "--|++

" +/obj/machinery/particle_accelerator/control_box/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ParticleAccelerator", name) + ui.open() - user << browse(dat, "window=pacontrol;size=420x500") - onclose(user, "pacontrol") - return +/obj/machinery/particle_accelerator/control_box/tgui_data(mob/user) + var/list/data = list() + data["assembled"] = assembled + data["power"] = active + data["strength"] = strength + return data + +/obj/machinery/particle_accelerator/control_box/tgui_act(action, params) + if(..()) + return + + switch(action) + if("power") + if(wires.is_cut(WIRE_POWER)) + return + toggle_power() + . = TRUE + if("scan") + part_scan() + . = TRUE + if("add_strength") + if(wires.is_cut(WIRE_PARTICLE_STRENGTH)) + return + add_strength() + . = TRUE + if("remove_strength") + if(wires.is_cut(WIRE_PARTICLE_STRENGTH)) + return + remove_strength() + . = TRUE + + update_icon() diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index c05c4e15230..365fda6b50f 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -263,11 +263,11 @@ GLOBAL_LIST_EMPTY(smeses) /obj/machinery/power/smes/attack_ai(mob/user) add_hiddenprint(user) - ui_interact(user) + tgui_interact(user) /obj/machinery/power/smes/attack_hand(mob/user) add_fingerprint(user) - ui_interact(user) + tgui_interact(user) /obj/machinery/power/smes/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) @@ -344,78 +344,84 @@ GLOBAL_LIST_EMPTY(smeses) return FALSE return TRUE -/obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - - if(stat & BROKEN) - return - - // this is the data which will be sent to the ui - var/data[0] - data["nameTag"] = name_tag - data["storedCapacity"] = round(100.0*charge/capacity, 0.1) - data["storedCapacityAbs"] = round(charge/(1000*60), 0.1) - data["storedCapacityMax"] = round(capacity/(1000*60)) - data["charging"] = inputting - data["chargeMode"] = input_attempt - data["chargeLevel"] = round(input_level/1000, 0.1) - data["chargeMax"] = round(input_level_max/1000) - data["chargeLoad"] = round(input_available/1000, 0.1) - data["outputOnline"] = output_attempt - data["outputLevel"] = round(output_level/1000, 0.1) - data["outputMax"] = round(output_level_max/1000) - data["outputLoad"] = round(output_used/1000, 0.1) - data["outputting"] = outputting - - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "smes.tmpl", "SMES Unit", 540, 380) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window +/obj/machinery/power/smes/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Smes", name) ui.open() - // auto update every Master Controller tick - ui.set_auto_update(1) + +/obj/machinery/power/smes/tgui_data() + var/list/data = list( + "capacity" = capacity, + "capacityPercent" = round(100*charge/capacity, 0.1), + "charge" = charge, + "inputAttempt" = input_attempt, + "inputting" = inputting, + "inputLevel" = input_level, + "inputLevel_text" = DisplayPower(input_level), + "inputLevelMax" = input_level_max, + "inputAvailable" = input_available, + "outputAttempt" = output_attempt, + "outputting" = outputting, + "outputLevel" = output_level, + "outputLevel_text" = DisplayPower(output_level), + "outputLevelMax" = output_level_max, + "outputUsed" = output_used, + ) + return data /obj/machinery/power/smes/proc/Percentage() if(!capacity) return 0 return round(100.0*charge/capacity, 0.1) -/obj/machinery/power/smes/Topic(href, href_list) - if(..()) - return 1 - if( href_list["cmode"] ) - inputting(!input_attempt) - update_icon() - return 1 - else if( href_list["online"] ) - outputting(!output_attempt) - update_icon() - return 1 - else if( href_list["input"] ) - switch( href_list["input"] ) - if("min") - input_level = 0 - if("max") - input_level = input_level_max - if("set") - input_level = (input(usr, "Enter new input level (0-[input_level_max/1000] kW)", "SMES Input Power Control", input_level/1000) as num) * 1000 - input_level = max(0, min(input_level_max, input_level)) // clamp to range - return 1 - else if( href_list["output"] ) - switch( href_list["output"] ) - if("min") - output_level = 0 - if("max") - output_level = output_level_max - if("set") - output_level = (input(usr, "Enter new output level (0-[output_level_max/1000] kW)", "SMES Output Power Control", output_level/1000) as num) * 1000 - output_level = max(0, min(output_level_max, output_level)) // clamp to range - return 1 +/obj/machinery/power/smes/tgui_act(action, params) + if(..()) + return TRUE + switch(action) + if("tryinput") + inputting(!input_attempt) + update_icon() + . = TRUE + if("tryoutput") + outputting(!output_attempt) + update_icon() + . = TRUE + if("input") + var/target = params["target"] + var/adjust = text2num(params["adjust"]) + if(target == "min") + target = 0 + . = TRUE + else if(target == "max") + target = input_level_max + . = TRUE + else if(adjust) + target = input_level + adjust + . = TRUE + else if(text2num(target) != null) + target = text2num(target) + . = TRUE + if(.) + input_level = clamp(target, 0, input_level_max) + if("output") + var/target = params["target"] + var/adjust = text2num(params["adjust"]) + if(target == "min") + target = 0 + . = TRUE + else if(target == "max") + target = output_level_max + . = TRUE + else if(adjust) + target = output_level + adjust + . = TRUE + else if(text2num(target) != null) + target = text2num(target) + . = TRUE + if(.) + output_level = clamp(target, 0, output_level_max) /obj/machinery/power/smes/proc/inputting(var/do_input) input_attempt = do_input diff --git a/code/modules/power/smes_construction.dm b/code/modules/power/smes_construction.dm index f8bf16087e6..45b44d64f89 100644 --- a/code/modules/power/smes_construction.dm +++ b/code/modules/power/smes_construction.dm @@ -84,7 +84,7 @@ /obj/machinery/power/smes/buildable/Destroy() qdel(wires) wires = null - for(var/datum/nano_module/rcon/R in world) + for(var/datum/tgui_module/rcon/R in world) R.FindDevices() return ..() diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 27f1953b321..850bb5807ce 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -399,38 +399,32 @@ GLOBAL_LIST_EMPTY(solars_list) return /obj/machinery/power/solar_control/attack_hand(mob/user) - if(!..()) - interact(user) + if(..()) + return TRUE + tgui_interact(user) -/obj/machinery/power/solar_control/interact(mob/user) +/obj/machinery/power/solar_control/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SolarControl", name) + ui.open() - var/t = "Generated power : [round(lastgen)] W
" - t += "Star Orientation: [SSsun.sun.angle]° ([angle2text(SSsun.sun.angle)])
" - t += "Array Orientation: [rate_control(src,"cdir","[cdir]°",1,15)] ([angle2text(cdir)])
" - t += "Tracking:
" - switch(track) - if(0) - t += "Off Timed Auto
" - if(1) - t += "Off Timed Auto
" - if(2) - t += "Off Timed Auto
" +/obj/machinery/power/solar_control/tgui_data() + var/data = list() - t += "Tracking Rate: [rate_control(src,"tdir","[trackrate] deg/h ([trackrate<0 ? "CCW" : "CW"])",1,30,180)]

" + data["generated"] = round(lastgen) + data["generated_ratio"] = data["generated"] / round(max(connected_panels.len, 1) * GLOB.solar_gen_rate) - t += "Connected devices:
" + data["sun_angle"] = SSsun.sun.angle + data["array_angle"] = cdir + data["rotation_rate"] = trackrate + data["max_rotation_rate"] = 7200 + data["tracking_state"] = track - t += "Search for devices
" - t += "Solar panels : [connected_panels.len] connected
" - t += "Solar tracker : [connected_tracker ? "Found" : "Not found"]

" + data["connected_panels"] = connected_panels.len + data["connected_tracker"] = (connected_tracker ? TRUE : FALSE) - t += "Close" - - var/datum/browser/popup = new(user, "solar", name) - popup.set_content(t) - popup.open() - - return + return data /obj/machinery/power/solar_control/attackby(obj/item/I, user as mob) if(I.is_screwdriver()) @@ -481,51 +475,52 @@ GLOBAL_LIST_EMPTY(solars_list) updateDialog() -/obj/machinery/power/solar_control/Topic(href, href_list) +/obj/machinery/power/solar_control/tgui_act(action, params) if(..()) - usr << browse(null, "window=solcon") - usr.unset_machine() - return 0 - if(href_list["close"] ) - usr << browse(null, "window=solcon") - usr.unset_machine() - return 0 + return TRUE - if(href_list["rate control"]) - if(href_list["cdir"]) - src.cdir = dd_range(0,359,(360+src.cdir+text2num(href_list["cdir"]))%360) - src.targetdir = src.cdir - if(track == 2) //manual update, so losing auto-tracking - track = 0 - spawn(1) + switch(action) + if("azimuth") + var/adjust = text2num(params["adjust"]) + var/value = text2num(params["value"]) + if(adjust) + value = cdir + adjust + if(value != null) + cdir = value set_panels(cdir) - if(href_list["tdir"]) - src.trackrate = dd_range(-7200,7200,src.trackrate+text2num(href_list["tdir"])) - if(src.trackrate) nexttime = world.time + 36000/abs(trackrate) + return TRUE + return FALSE + if("azimuth_rate") + var/adjust = text2num(params["adjust"]) + var/value = text2num(params["value"]) + if(adjust) + value = trackrate + adjust + if(value != null) + trackrate = round(clamp(value, -7200, 7200), 0.01) + if(trackrate) + nexttime = world.time + 36000 / abs(trackrate) + return TRUE + return TRUE + if("tracking") + var/mode = text2num(params["mode"]) + track = mode + if(track == 2) + if(connected_tracker) + connected_tracker.set_angle(SSsun.sun.angle) + set_panels(cdir) + else if(track == 1) //begin manual tracking + targetdir = cdir + if(trackrate) + nexttime = world.time + 36000/abs(trackrate) + set_panels(targetdir) + return TRUE - if(href_list["track"]) - track = text2num(href_list["track"]) - if(track == 2) - if(connected_tracker) - connected_tracker.set_angle(SSsun.sun.angle) - set_panels(cdir) - else if (track == 1) //begin manual tracking - src.targetdir = src.cdir - if(src.trackrate) nexttime = world.time + 36000/abs(trackrate) - set_panels(targetdir) - - if(href_list["search_connected"]) - src.search_for_connected() - if(connected_tracker && track == 2) - connected_tracker.set_angle(SSsun.sun.angle) - src.set_panels(cdir) - - interact(usr) - return 1 + if("refresh") + search_for_connected() + return TRUE //rotates the panel to the passed angle /obj/machinery/power/solar_control/proc/set_panels(var/cdir) - for(var/obj/machinery/power/solar/S in connected_panels) S.adir = cdir //instantly rotates the panel S.occlusion()//and @@ -547,7 +542,7 @@ GLOBAL_LIST_EMPTY(solars_list) /obj/machinery/power/solar_control/ex_act(severity) switch(severity) if(1.0) - //SN src = null + //SN = null qdel(src) return if(2.0) @@ -565,9 +560,3 @@ GLOBAL_LIST_EMPTY(solars_list) /obj/item/weapon/paper/solar name = "paper- 'Going green! Setup your own solar array instructions.'" info = "

Welcome

At greencorps we love the environment, and space. With this package you are able to help mother nature and produce energy without any usage of fossil fuel or phoron! Singularity energy is dangerous while solar energy is safe, which is why it's better. Now here is how you setup your own solar array.

You can make a solar panel by wrenching the solar assembly onto a cable node. Adding a glass panel, reinforced or regular glass will do, will finish the construction of your solar panel. It is that easy!

Now after setting up 19 more of these solar panels you will want to create a solar tracker to keep track of our mother nature's gift, the SSsun.sun. These are the same steps as before except you insert the tracker equipment circuit into the assembly before performing the final step of adding the glass. You now have a tracker! Now the last step is to add a computer to calculate the SSsun.sun's movements and to send commands to the solar panels to change direction with the SSsun.sun. Setting up the solar computer is the same as setting up any computer, so you should have no trouble in doing that. You do need to put a wire node under the computer, and the wire needs to be connected to the tracker.

Congratulations, you should have a working solar array. If you are having trouble, here are some tips. Make sure all solar equipment are on a cable node, even the computer. You can always deconstruct your creations if you make a mistake.

That's all to it, be safe, be green!

" - -/proc/rate_control(var/S, var/V, var/C, var/Min=1, var/Max=5, var/Limit=null) //How not to name vars - var/href = "-[href]=-[Min]'>- [(C?C : 0)] [href]=[Min]'>+[href]=[Max]'>+" - if(Limit) return "[href]=-[Limit]'>-"+rate+"[href]=[Limit]'>+" - return rate diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 3d651a2a0fe..4e6c5a6cb5c 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -390,11 +390,11 @@ if(Adjacent(user)) return attack_hand(user) else - ui_interact(user) + tgui_interact(user) return /obj/machinery/power/supermatter/attack_ai(mob/user as mob) - ui_interact(user) + tgui_interact(user) /obj/machinery/power/supermatter/attack_hand(mob/user as mob) var/datum/gender/TU = gender_datums[user.get_visible_gender()] @@ -404,9 +404,15 @@ Consume(user) +/obj/machinery/power/supermatter/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AiSupermatter", name) + ui.open() + // This is purely informational UI that may be accessed by AIs or robots -/obj/machinery/power/supermatter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/power/supermatter/tgui_data(mob/user) + var/list/data = list() data["integrity_percentage"] = round(get_integrity()) var/datum/gas_mixture/env = null @@ -421,12 +427,7 @@ data["ambient_pressure"] = round(env.return_pressure()) data["detonating"] = grav_pulling - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "supermatter_crystal.tmpl", "Supermatter Crystal", 500, 300) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + return data /obj/machinery/power/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 65ec739d626..8c7e9a440b1 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -29,8 +29,8 @@ set_dir(pick(cardinal)) //spin spent casings update_icon() -/obj/item/ammo_casing/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(W.is_screwdriver()) +/obj/item/ammo_casing/attackby(obj/item/I as obj, mob/user as mob) + if(I.is_screwdriver()) if(!BB) to_chat(user, "There is no bullet in the casing to inscribe anything into.") return @@ -45,6 +45,39 @@ else to_chat(user, "You inscribe \"[label_text]\" into \the [initial(BB.name)].") BB.name = "[initial(BB.name)] (\"[label_text]\")" + else if(istype(I, /obj/item/ammo_magazine) && isturf(loc)) // Mass magazine reloading. + var/obj/item/ammo_magazine/box = I + if (!box.can_remove_ammo || box.reloading) + return ..() + + box.reloading = TRUE + var/boolets = 0 + var/turf/floor = loc + for(var/obj/item/ammo_casing/bullet in floor) + if(box.stored_ammo.len >= box.max_ammo) + break + if(box.caliber == bullet.caliber && bullet.BB) + if (boolets < 1) + to_chat(user, "You start collecting shells.") // Say it here so it doesn't get said if we don't find anything useful. + if(do_after(user,5,box)) + if(box.stored_ammo.len >= box.max_ammo) // Double check because these can change during the wait. + break + if(bullet.loc != floor) + continue + bullet.forceMove(box) + box.stored_ammo.Add(bullet) + box.update_icon() + boolets++ + else + break + + if(boolets > 0) + to_chat(user, "You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.") + else + to_chat(user, "You fail to collect anything!") + box.reloading = FALSE + else + return ..() /obj/item/ammo_casing/update_icon() if(!BB) @@ -84,6 +117,7 @@ var/initial_ammo = null var/can_remove_ammo = TRUE // Can this thing have bullets removed one-by-one? As of first implementation, only affects smart magazines + var/reloading = FALSE // Is this magazine being reloaded, currently? - Currently only useful for automatic pickups, ignored by manual reloading. var/multiple_sprites = 0 //because BYOND doesn't support numbers as keys in associative lists @@ -115,7 +149,7 @@ to_chat(user, "[src] is full!") return user.remove_from_mob(C) - C.loc = src + C.forceMove(src) stored_ammo.Add(C) update_icon() if(istype(W, /obj/item/ammo_magazine/clip)) @@ -131,7 +165,7 @@ return var/obj/item/ammo_casing/AC = L.stored_ammo[1] //select the next casing. L.stored_ammo -= AC //Remove this casing from loaded list of the clip. - AC.loc = src + AC.forceMove(src) stored_ammo.Insert(1, AC) //add it to the head of our magazine's list L.update_icon() playsound(src, 'sound/weapons/flipblade.ogg', 50, 1) diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index ced50484ce9..1d08811bae0 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -88,6 +88,10 @@ name = "magazine (.45 AP)" ammo_type = /obj/item/ammo_casing/a45/ap +/obj/item/ammo_magazine/m45/hp + name = "magazine (.45 HP)" + ammo_type = /obj/item/ammo_casing/a45/hp + /obj/item/ammo_magazine/box/emp/b45 name = "ammunition box (.45 haywire)" ammo_type = /obj/item/ammo_casing/a45/emp @@ -293,6 +297,11 @@ name = "top mounted magazine (9mm practice)" ammo_type = /obj/item/ammo_casing/a9mm/practice +/obj/item/ammo_magazine/m9mmt/ap + name = "top mounted magazine (9mm armor piercing)" + ammo_type = /obj/item/ammo_casing/a9mm/ap + matter = list(DEFAULT_WALL_MATERIAL = 1000, MAT_PLASTEEL = 2000) + /obj/item/ammo_magazine/m9mmp90 name = "large capacity top mounted magazine (9mm armor-piercing)" icon_state = "p90" @@ -534,6 +543,11 @@ icon_state = "R44" ammo_type = /obj/item/ammo_casing/a44/rubber +/obj/item/ammo_magazine/s44/rifle + name = "speedloader (.44 rifle)" + icon_state = "RI44" + ammo_type = /obj/item/ammo_casing/a44/rifle + ///////// 7.62mm ///////// /obj/item/ammo_magazine/m762 diff --git a/code/modules/projectiles/ammunition/rounds.dm b/code/modules/projectiles/ammunition/rounds.dm index 1dd8f6e149a..fa6c5d21aa8 100644 --- a/code/modules/projectiles/ammunition/rounds.dm +++ b/code/modules/projectiles/ammunition/rounds.dm @@ -67,6 +67,11 @@ projectile_type = /obj/item/projectile/bullet/pistol/rubber/strong matter = list(DEFAULT_WALL_MATERIAL = 60) +/obj/item/ammo_casing/a44/rifle + desc = "A proprietary Hedberg-Hammarstrom .44 bullet casing designed for use in revolving rifles." + projectile_type = /obj/item/projectile/bullet/rifle/a44rifle + matter = list(DEFAULT_WALL_MATERIAL = 210) + /* * .75 (aka Gyrojet Rockets, aka admin abuse) */ @@ -126,6 +131,7 @@ desc = "A .45 Armor-Piercing bullet casing." icon_state = "r-casing" projectile_type = /obj/item/projectile/bullet/pistol/medium/ap + matter = list(DEFAULT_WALL_MATERIAL = 50, MAT_PLASTEEL = 25) /obj/item/ammo_casing/a45/practice desc = "A .45 practice bullet casing." @@ -155,6 +161,7 @@ /obj/item/ammo_casing/a45/hp desc = "A .45 hollow-point bullet casing." projectile_type = /obj/item/projectile/bullet/pistol/medium/hp + matter = list(DEFAULT_WALL_MATERIAL = 60, MAT_PLASTIC = 15) /* * 10mm @@ -241,6 +248,14 @@ // projectile_type = /obj/item/projectile/bullet/shotgun/ion matter = list(DEFAULT_WALL_MATERIAL = 360, "uranium" = 240) +/obj/item/ammo_casing/a12g/flechette + name = "shotgun flechette" + desc = "A 12 gauge flechette cartidge, also known as nailshot." + icon_state = "slshell" + caliber = "12g" + projectile_type = /obj/item/projectile/scatter/flechette + matter = list(DEFAULT_WALL_MATERIAL = 360, MAT_PLASTEEL = 100) + /* * 7.62mm */ diff --git a/code/modules/projectiles/ammunition/smartmag.dm b/code/modules/projectiles/ammunition/smartmag.dm index 81a299d5eeb..c1a5fbbcd87 100644 --- a/code/modules/projectiles/ammunition/smartmag.dm +++ b/code/modules/projectiles/ammunition/smartmag.dm @@ -3,7 +3,7 @@ /obj/item/ammo_magazine/smart name = "smart magazine" icon_state = "smartmag-empty" - desc = "A Hephaistos Industries brand Smart Magazine. It uses advanced matter manipulation technology to create bullets from energy. Simply present your loaded gun or magazine to the Smart Magazine." + desc = "A Hephaestus Industries brand Smart Magazine. It uses advanced matter manipulation technology to create bullets from energy. Simply present your loaded gun or magazine to the Smart Magazine." multiple_sprites = 1 max_ammo = 5 mag_type = MAGAZINE diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 778b36694dc..44b418ac80b 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -2,6 +2,7 @@ name = "laser rifle" desc = "A Hephaestus Industries G40E rifle, designed to kill with concentrated energy blasts. This variant has the ability to \ switch between standard fire and a more efficent but weaker 'suppressive' fire." + description_fluff = "The leading arms producer in the SCG, Hephaestus typically only uses its 'top level' branding for its military-grade equipment used by armed forces across human space." icon_state = "laser" item_state = "laser" wielded_item_state = "laser-wielded" @@ -45,11 +46,22 @@ list(mode_name="suppressive", projectile_type=/obj/item/projectile/beam/practice, charge_cost = 12), ) +//Functionally identical, but slightly higher tech due to rarer. +/obj/item/weapon/gun/energy/laser/sleek + name = "\improper LR1 Shishi" + desc = "A Bishamonten Company LR1 Shishi rifle, a rare early 23rd century futurist design with a nonetheless timeless ability to kill." + description_fluff = "Bisamonten was arms company that operated from roughly 2150-2280 - the height of the first extrasolar colonisation boom - before filing for bankruptcy and selling off its assets to various companies that would go on to become today’s TSCs. \ + Focused on sleek ‘futurist’ designs which have largely fallen out of fashion but remain popular with collectors and people hoping to make some quick thalers from replica weapons. \ + Their weapons tended to be form over function - despite their flashy looks, most were completely unremarkable one way or another as weapons and used very standard firing mechanisms." + icon_state = "lrifle" + item_state = "lrifle" + origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 3) + /obj/item/weapon/gun/energy/retro name = "retro laser" icon_state = "retro" item_state = "retro" - desc = "An older model of the basic lasergun. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." + desc = "A 23rd century model of the basic lasergun. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." slot_flags = SLOT_BELT w_class = ITEMSIZE_NORMAL projectile_type = /obj/item/projectile/beam @@ -111,7 +123,10 @@ name = "antique laser gun" icon_state = "caplaser" item_state = "caplaser" - desc = "A rare weapon, handcrafted by a now defunct specialty manufacturer on Luna for a small fortune. It's certainly aged well." + desc = "A rare weapon, produced by the Lunar Arms Company around 2105 - one of humanity's first wholly extra-terrestrial weapon designs. It's certainly aged well." + description_fluff = "The Lunar Arms Company was founded to provide home-grown arms to the Selene Federation from 2101-2108 during the Second Cold War, the conflict that sparked the \ + formation of the SCG. The LAC produced the first weapons wholly designed and produced outside of Earth. Post-war, the company relocated and rebranded as MarsTech, which survives \ + to this day as a major subsidiary of Hephaestus Industries." force = 5 slot_flags = SLOT_BELT w_class = ITEMSIZE_NORMAL @@ -164,6 +179,7 @@ name = "marksman energy rifle" desc = "The HI DMR 9E is an older design of Hephaestus Industries. A designated marksman rifle capable of shooting powerful \ ionized beams, this is a weapon to kill from a distance." + description_fluff = "The leading arms producer in the SCG, Hephaestus typically only uses its 'top level' branding for its military-grade equipment used by armed forces across human space." icon_state = "sniper" item_state = "sniper" item_state_slots = list(slot_r_hand_str = "lsniper", slot_l_hand_str = "lsniper") @@ -224,7 +240,7 @@ /obj/item/weapon/gun/energy/monorifle/combat name = "combat mono-rifle" desc = "A modernized version of the mono-rifle. This one can fire twice before requiring recharging." - description_fluff = "A modern design produced by a company once working from Saint Columbia, based on the antique mono-rifle 'Rainy Day Special' design." + description_fluff = "A modern design produced by a small company operating out of Saint Columbia, based on the antique mono-rifle 'Rainy Day Special' design." icon_state = "cmono" item_state = "cshotgun" charge_cost = 1000 diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index d9d85ad92cf..7062fc3f916 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -1,6 +1,7 @@ /obj/item/weapon/gun/energy/gun name = "energy gun" - desc = "Another bestseller of Lawson Arms and "+TSC_HEPH+", the LAEP90 Perun is a versatile energy based sidearm, capable of switching between low and high capacity projectile settings. In other words: Stun or Kill." + desc = "Another bestseller of Lawson Arms, the LAEP90 Perun is a versatile energy based sidearm, capable of switching between low and high capacity projectile settings. In other words: Stun or Kill." + description_fluff = "Lawson Arms is Hephaestus Industries’ main personal-energy-weapon branding, often sold alongside MarsTech projectile weapons to security and law enforcement agencies." icon_state = "energystun100" item_state = null //so the human update icon uses the icon_state instead. fire_delay = 10 // Handguns should be inferior to two-handed weapons. @@ -14,6 +15,7 @@ list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="energykill", charge_cost = 480), ) + /obj/item/weapon/gun/energy/gun/mounted name = "mounted energy gun" self_recharge = 1 @@ -22,7 +24,8 @@ /obj/item/weapon/gun/energy/gun/burst name = "burst laser" - desc = "The FM-2t is a versatile energy based weapon, capable of switching between stun or kill with a three round burst option for both settings." + desc = "The Lawson Arms FM-2t is a versatile energy based weapon, capable of switching between stun or kill with a three round burst option for both settings." + description_fluff = "Lawson Arms is Hephaestus Industries’ main personal-energy-weapon branding, often sold alongside MarsTech projectile weapons to security and law enforcement agencies." icon_state = "fm-2tstun100" //May resprite this to be more rifley item_state = null //so the human update icon uses the icon_state instead. charge_cost = 100 @@ -46,7 +49,7 @@ /obj/item/weapon/gun/energy/gun/nuclear name = "advanced energy gun" - desc = "An energy gun with an experimental miniaturized reactor." + desc = "An energy gun with an experimental miniaturized reactor, based on a Lawson Arms platform." icon_state = "nucgunstun" projectile_type = /obj/item/projectile/beam/stun origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_POWER = 3) @@ -65,3 +68,19 @@ list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, modifystate="nucgunstun", charge_cost = 240), list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="nucgunkill", charge_cost = 480), ) + +//Functionally a Perun, but flavoured. +/obj/item/weapon/gun/energy/gun/compact + name = "personal energy weapon" + desc = "The RayZar EW20 Cygnus personal energy weapon - or PEW - is Ward-Takahasi's entry into the variable capacity energy gun market. New users are advised to 'set RayZars to stun'." + description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist energy weapons of various types and quality primarily for the civilian market." + icon_state = "PDWstun100" + + projectile_type = /obj/item/projectile/beam/stun/med + origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 3) + modifystate = "PDWstun" + + firemodes = list( + list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="PDWstun", charge_cost = 240), + list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="PDWkill", charge_cost = 480), + ) \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/phase.dm b/code/modules/projectiles/guns/energy/phase.dm index b5c06c2fc9d..ec3c7ff4385 100644 --- a/code/modules/projectiles/guns/energy/phase.dm +++ b/code/modules/projectiles/guns/energy/phase.dm @@ -2,7 +2,8 @@ /obj/item/weapon/gun/energy/phasegun name = "phase carbine" - desc = "The NT EW26 Artemis is a downsized energy weapon, specifically designed for use against wildlife." + desc = "The RayZar EW26 Artemis is a downsized energy weapon, specifically designed for use against wildlife." + description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist energy weapons of various types and quality primarily for the civilian market." icon_state = "phasecarbine" item_state = "phasecarbine" wielded_item_state = "phasecarbine-wielded" @@ -13,7 +14,7 @@ /obj/item/weapon/gun/energy/phasegun/pistol name = "phase pistol" - desc = "The NT EW15 Apollo is an energy handgun, specifically designed for self-defense against aggressive wildlife." + desc = "The RayZar EW15 Apollo is an energy handgun, specifically designed for self-defense against aggressive wildlife." icon_state = "phase" item_state = "taser" //I don't have an in-hand sprite, taser will be fine w_class = ITEMSIZE_NORMAL @@ -33,7 +34,7 @@ obj/item/weapon/gun/energy/phasegun/rifle name = "phase rifle" - desc = "The NT EW31 Orion is a specialist energy weapon, intended for use against hostile wildlife." + desc = "The RayZar EW31 Orion is a specialist energy weapon, intended for use against hostile wildlife." icon_state = "phaserifle" item_state = "phaserifle" wielded_item_state = "phaserifle-wielded" @@ -46,7 +47,7 @@ obj/item/weapon/gun/energy/phasegun/rifle /obj/item/weapon/gun/energy/phasegun/cannon name = "phase cannon" - desc = "The NT EW50 Gaia is a massive energy weapon, purpose-built for clearing land. You feel dirty just looking at it." + desc = "The RayZar EW50 Gaia is a massive energy weapon, purpose-built for clearing land. You feel dirty just looking at it." icon_state = "phasecannon" item_state = "phasecannon" wielded_item_state = "phasecannon-wielded" //TODO: New Sprites diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index d2e5edf9970..21be1ebe76b 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -28,12 +28,22 @@ /obj/item/weapon/gun/energy/pulse_rifle/destroyer/attack_self(mob/living/user as mob) to_chat(user, "[src.name] has three settings, and they are all DESTROY.") -//WHY? -/obj/item/weapon/gun/energy/pulse_rifle/M1911 - name = "\improper M1911-P" - desc = "It's not the size of the gun, it's the size of the hole it puts through people." + +//non-bus version because it looks adorable. +/obj/item/weapon/gun/energy/pulse_rifle/compact + name = "\improper LP2 Grasshopper Compact" + desc = "You feel like you're going to break the damn thing. The Bishamonten LP2 is a rare collectors item from the early 23rd century." + description_fluff = "The Bishamonten Company operated from roughly 2150-2280 - the height of the first extrasolar colonisation boom - before filing for bankruptcy and selling off its assets to various companies that would go on to become today’s TSCs. \ + Focused on sleek ‘futurist’ designs which have largely fallen out of fashion but remain popular with collectors and people hoping to make some quick thalers from replica weapons. \ + Bishamonten weapons tended to be form over function - despite their flashy looks, most were completely unremarkable one way or another as weapons and used very standard firing mechanisms.\ + The Grasshopper remains one of the smallest production laser pistols ever produced that is still capable of causing significant damage to organic tissue." slot_flags = SLOT_BELT|SLOT_HOLSTER - icon_state = "m1911-p" + icon_state = "lpistol" + charge_cost = 480 + +/obj/item/weapon/gun/energy/pulse_rifle/compact/admin + name = "\improper LP2 Grasshopper Deluxe" + desc = "It's not the size of the gun, it's the size of the hole it puts through people." charge_cost = 240 firemodes = list( diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index e5d43ca5261..7877cac7138 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -1,6 +1,7 @@ /obj/item/weapon/gun/energy/ionrifle name = "ion rifle" - desc = "The NT Mk60 EW Halicon is a man portable anti-armor weapon designed to disable mechanical threats, produced by NT. Not the best of its type." + desc = "The RayZar Mk60 EW Halicon is a man portable anti-armor weapon designed to disable mechanical threats, produced by NT. Not the best of its type." + description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist energy weapons of various types and quality primarily for the civilian market." icon_state = "ionrifle" item_state = "ionrifle" wielded_item_state = "ionrifle-wielded" @@ -18,7 +19,7 @@ /obj/item/weapon/gun/energy/ionrifle/pistol name = "ion pistol" - desc = "The NT Mk63 EW Pan is a man portable anti-armor weapon designed to disable mechanical threats, produced by NT. This model sacrifices capacity for portability." + desc = "The RayZar Mk63 EW Pan is a man portable anti-armor weapon designed to disable mechanical threats, produced by NT. This model sacrifices capacity for portability." icon_state = "ionpistol" item_state = null w_class = ITEMSIZE_NORMAL @@ -38,6 +39,7 @@ /obj/item/weapon/gun/energy/floragun name = "floral somatoray" desc = "A tool that discharges controlled radiation which induces mutation in plant cells." + description_fluff = "The floral somatoray is a relatively recent invention of the NanoTrasen corporation, turning a process that once involved transferring plants to massive mutating racks, into a remote interface. Do not look directly into the transmission end." icon_state = "floramut100" item_state = "floramut" projectile_type = /obj/item/projectile/energy/floramut diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index df90a8ac126..6fb4b272268 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -1,6 +1,7 @@ /obj/item/weapon/gun/energy/taser name = "taser gun" - desc = "The NT Mk30 NL is a small gun used for non-lethal takedowns. Produced by NT, it's actually a licensed version of a W-T design." + desc = "The NT Mk30 NL is a small gun used for non-lethal takedowns. Produced by NT, it's actually a licensed version of a W-T RayZar design." + description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist energy weapons of various types and quality primarily for the civilian market." icon_state = "taser" item_state = null //so the human update icon uses the icon_state instead. projectile_type = /obj/item/projectile/beam/stun @@ -31,7 +32,9 @@ /obj/item/weapon/gun/energy/stunrevolver name = "stun revolver" - desc = "A LAEP20 Zeus. Designed by Lawson Arms and produced under the wing of Hephaestus, several TSCs have been trying to get a hold of the blueprints for half a decade." + desc = "A LAEP20 Aktzin. Designed and produced by Lawson Arms under the wing of Hephaestus, several TSCs have been trying to get a hold of the blueprints for half a decade." + description_fluff = "Lawson Arms is Hephaestus Industries’ main personal-energy-weapon branding, often sold alongside MarsTech projectile weapons to security and law enforcement agencies. \ + The Aktzin's capsule-based stun ammunition is a closely guarded Hephaestus Industries patent, and the company has been particularly litigious towards any attempted imitators." icon_state = "stunrevolver" item_state = "stunrevolver" origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3, TECH_POWER = 2) @@ -69,7 +72,9 @@ /obj/item/weapon/gun/energy/plasmastun name = "plasma pulse projector" - desc = "The Mars Military Industries MA21 Selkie is a weapon that uses a laser pulse to ionise the local atmosphere, creating a disorienting pulse of plasma and deafening shockwave as the wave expands." + desc = "The RayZar MA21 Selkie is a weapon that uses a laser pulse to ionise the local atmosphere, creating a disorienting pulse of plasma and deafening shockwave as the wave expands." + description_fluff = "RayZar is Ward-Takahashi’s main consumer weapons brand, known for producing and licensing a wide variety of specialist energy weapons of various types and quality primarily for the civilian market. \ + Less well known are RayZar's limited-production experimental projects, often in the form of less-lethal weapon solutions." icon_state = "plasma_stun" item_state = "plasma_stun" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_POWER = 3) diff --git a/code/modules/projectiles/guns/launcher/crossbow.dm b/code/modules/projectiles/guns/launcher/crossbow.dm index 6669c5082f1..3dfae2a1a47 100644 --- a/code/modules/projectiles/guns/launcher/crossbow.dm +++ b/code/modules/projectiles/guns/launcher/crossbow.dm @@ -47,7 +47,7 @@ /obj/item/weapon/gun/launcher/crossbow name = "powered crossbow" - desc = "A 2557AD twist on an old classic. Pick up that can." + desc = "A 2320AD twist on an old classic. Pick up that can." //VOREStation Edit icon = 'icons/obj/weapons.dmi' icon_state = "crossbow" item_state = "crossbow-solid" diff --git a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm index ec677a1b143..8497207f2ef 100644 --- a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm +++ b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm @@ -1,6 +1,8 @@ /obj/item/weapon/gun/magnetic/railgun name = "railgun" desc = "The Mars Military Industries MI-76 Thunderclap. A man-portable mass driver for squad support anti-armour and destruction of fortifications and emplacements." + description_fluff = "Mars Military Industries is a Hephaestus Industries subsidiary focused on the development of new energy-ballistic hybrid weapons for use against heavy targets. \ + The distribution of MMI weapons is understandably tightly tracked and controlled." gun_unreliable = 0 icon_state = "railgun" origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_MAGNET = 4) @@ -17,7 +19,7 @@ capacitor = /obj/item/weapon/stock_parts/capacitor/adv loaded = /obj/item/weapon/rcd_ammo/large removable_components = FALSE - + var/slowdown_held = 2 var/slowdown_worn = 1 var/empty_sound = 'sound/machines/twobeep.ogg' @@ -106,6 +108,8 @@ /obj/item/weapon/gun/magnetic/railgun/flechette/pistol name = "flechette pistol" desc = "The MI-6a Ullr is a small-form-factor railgun that fires flechette rounds at high velocity. Deadly against armour, but much less effective against soft targets." + description_fluff = "Mars Military Industries is a Hephaestus Industries subsidiary focused on the development of new energy-ballistic hybrid weapons for use against heavy targets. \ + The distribution of MMI weapons is understandably tightly tracked and controlled." icon_state = "railpistol" item_state = "combatrevolver" w_class = ITEMSIZE_SMALL @@ -136,7 +140,7 @@ /obj/item/weapon/gun/magnetic/railgun/heater name = "coil rifle" desc = "A large rifle designed and produced after the Grey Hour." - description_info = "The MI-51B is a Martian weapon designed in the days after the Grey Hour, in preparation for the need for updated equipment by Solar forces.
\ + description_fluff = "The Hephaestus MI-51B is a weapon designed by Mars Military Industries - a Hephaestus subsidiary - in the days after the Grey Hour, in preparation for the need for updated equipment by Solar forces.
\ The design is based upon a larger rail-type weapon design." icon_state = "railgun_sec" item_state = "cshotgun" @@ -167,7 +171,7 @@ /obj/item/weapon/gun/magnetic/railgun/heater/pistol name = "coil pistol" desc = "A large pistol designed and produced after the Grey Hour." - description_info = "The MI-60D `Peacemaker` is a Martian weapon designed in the days after the Grey Hour, in preparation for the need for updated equipment by Solar forces.
\ + description_fluff = "The MI-60D `Peacemaker` is a weapon designed by Mars Military Industries - a Hephaestus subsidiary - in the days after the Grey Hour, in preparation for the need for updated equipment by Solar forces.
\ The design is based upon a larger rail-type hybrid weapon design, though much smaller in scale." icon_state = "peacemaker" item_state = "revolver" @@ -201,7 +205,7 @@ /obj/item/weapon/gun/magnetic/railgun/flechette/sif name = "shredder rifle" desc = "The MI-12B Kaldr is a burst fire capable coilgun that fires modified slugs intended for damaging soft targets." - description_fluff = "The Kaldr is a weapon recently deployed to various outposts on Sif, as well as local hunting guilds for the rapid dispatching of invasive wildlife." + description_fluff = "The Lawson Kaldr is a weapon recently deployed to various outposts on Sif, as well as local hunting guilds for the rapid dispatching of invasive wildlife." icon_state = "railgun_sifguard" item_state = "z8carbine" diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index d3903c21a83..626dfe56843 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -41,7 +41,8 @@ /obj/item/weapon/gun/projectile/automatic/c20r name = "submachine gun" - desc = "The C-20r is a lightweight and rapid firing SMG, for when you REALLY need someone dead. It has 'Scarborough Arms - Per falcis, per pravitas' inscribed on the stock. Uses 10mm rounds." + desc = "The C-20r is a lightweight and rapid firing SMG, for when you REALLY need someone dead. It has 'Scarborough Arms - Per falcis, per pravitas', inscribed on the stock. Uses 10mm rounds." + description_fluff = "The C-20r is produced by Scarborough Arms, a specialist high-end weapons manufacturer based out of Titan, Sol. Scarborough has resisted numerous efforts by Trans-Stellars to acquire the brand since its founding in 2511, and has gained a dedicated following among a certain flavor of private operative." icon_state = "c20r" item_state = "c20r" w_class = ITEMSIZE_NORMAL @@ -71,7 +72,11 @@ /obj/item/weapon/gun/projectile/automatic/sts35 name = "assault rifle" - desc = "The rugged STS-35 is a durable automatic weapon of a make popular on the frontier worlds. Uses 5.45mm rounds." + desc = "The rugged Jindal Arms STS-35 is a durable automatic weapon of a make popular on the frontier worlds. Uses 5.45mm rounds." + description_fluff = "A subsidiary of Hephaestus Industries, While Jindal’s rugged, affordable weapons intended for the colonial sector are a major export of Tau Ceti, \ + the Jindal Arms company is perhaps best known for its liberal sale of production licenses to just about any fledgling rimworld venture who asks, and has cash to spare. \ + While Jindal’s 'authentic' Binma-built weapons are renowned for their reliability, the same cannot be said for the hundreds of low-grade (But technically legal) \ + copies circulating the squalid habitats and smoke-filled junk ships of the frontier." icon_state = "arifle" item_state = "arifle" wielded_item_state = "arifle-wielded" @@ -126,8 +131,11 @@ return /obj/item/weapon/gun/projectile/automatic/z8 - name = "designated marksman rifle" - desc = "The Z8 Bulldog is an older model designated marksman rifle, made by the now defunct Zendai Foundries. Makes you feel like a space marine when you hold it, even though it can only hold 10 round magazines. Uses 7.62mm rounds and has an under barrel grenade launcher." + name = "battle rifle" + desc = "The Z8 Bulldog is an older model battle rifle, made by the now defunct Zendai Foundries. Makes you feel like an old-school badass when you hold it, even though it can only hold 10 round magazines. Uses 7.62mm rounds and has an under barrel grenade launcher." + description_fluff = "Zendai Foundries was a well-respected mid-sized arms company that operated until 2508, when it was acquired by Hephaestus Industries. \ + Plans to integrate the brand into wider corporate operations were brought to an abrupt halt by the SolGov-Hegemony war, and the company was left by the wayside. \ + Hephaestus still produces replacement parts for many of Zendai's most popular weapons, including the Z8 Bulldog, and a great detail remain in service." icon_state = "carbine" // This isn't a carbine. :T item_state = "z8carbine" wielded_item_state = "z8carbine-wielded" @@ -200,7 +208,8 @@ /obj/item/weapon/gun/projectile/automatic/l6_saw name = "light machine gun" - desc = "A rather traditionally made L6 SAW with a pleasantly lacquered wooden pistol grip. 'Aussec Armoury-2531' is engraved on the reciever. Uses 5.45mm rounds. It's also compatible with magazines from STS-35 assault rifles." + desc = "A rather sturdily made L6 SAW with a reassuringly ergonomic pistol grip. 'Hephaestus Industries' is engraved on the reciever. Uses 5.45mm rounds. It's also compatible with magazines from STS-35 assault rifles." + description_fluff = "The leading arms producer in the SCG, Hephaestus typically only uses its 'top level' branding for its military-grade equipment used by professional armed forces across human space." icon_state = "l6closed100" item_state = "l6closed" wielded_item_state = "genericLMG-wielded" @@ -282,7 +291,8 @@ /obj/item/weapon/gun/projectile/automatic/as24 name = "automatic shotgun" - desc = "The AS-24 is a rugged looking automatic shotgun produced for the military by Gurov Projectile Weapons LLC. For very obvious reasons, it's illegal to own in many juristictions. Uses 12g rounds." + desc = "The AS-24 is a rugged looking automatic shotgun produced exclusively for the SCG Fleet by Hephaestus Industries. For very obvious reasons, it's illegal to own in many juristictions. Uses 12g rounds." + description_fluff = "The leading arms producer in the SCG, Hephaestus typically only uses its 'top level' branding for its military-grade equipment used by professional armed forces across human space." icon_state = "ashot" item_state = null wielded_item_state = "woodarifle-wielded" //Placeholder @@ -313,8 +323,11 @@ return /obj/item/weapon/gun/projectile/automatic/mini_uzi - name = "\improper Uzi" - desc = "The iconic Uzi is a lightweight, compact, fast firing machine pistol. Cybersun Industries famously still produces these designs, which have changed little since the 20th century. Uses .45 rounds." + name = "micro-smg" + desc = "The infamous ProTek Spitz is a lightweight, compact, fast firing machine pistol. Cheaply produced under the ProTek consumer brand, the Spitz seems to find its way into every corner of the galaxy. Uses .45 rounds." + description_fluff = "Budget-grade weapons for the budget-grade consumer! Hephaestus’ low-end brand of cheaply made, low-maintenance personal defense weapons for those who just need a handgun with absolutely no frills. \ + Early ProTek weapons were notoriously unsafe and unreliable, though more recent designs have improved somewhat - they still aren’t very good. \ + Though sold for a pittance, the profit margin is too irresistible for Hephaestus to discontinue the brand." icon_state = "mini-uzi" w_class = ITEMSIZE_NORMAL load_method = MAGAZINE @@ -337,7 +350,8 @@ /obj/item/weapon/gun/projectile/automatic/p90 name = "personal defense weapon" - desc = "The H90K is a compact, large capacity submachine gun produced by Hephaestus Industries. Despite its fierce reputation, it still manages to feel like a toy. Uses 9mm rounds." + desc = "The H90K is a compact, large capacity submachine gun produced by MarsTech. Despite its fierce reputation, it still manages to feel like a toy. Uses 9mm rounds." + description_fluff = "The leading civilian-sector high-quality small arms brand of Hephaestus Industries, MarsTech has been the provider of choice for law enforcement and security forces for over 300 years." icon_state = "p90smg" item_state = "p90" w_class = ITEMSIZE_NORMAL @@ -359,6 +373,7 @@ /obj/item/weapon/gun/projectile/automatic/tommygun name = "\improper Tommy Gun" desc = "This weapon was made famous by gangsters in the 20th century. Cybersun Industries is currently reproducing these for a target market of historic gun collectors and classy criminals. Uses .45 rounds." + description_fluff = "Cybersun Industries is a minor arms manufacturer specialising in replica firearms from eras past. Though they offer a wide selection of made-to-order models, their products are seen as little more than novelty items to most serious collectors." icon_state = "tommygun" w_class = ITEMSIZE_NORMAL caliber = ".45" @@ -411,3 +426,30 @@ item_state = "bullpup-empty" if(!ignore_inhands) update_held_icon() + +//Functionally a mini-uzi with slightly less terrible burst spread. +/obj/item/weapon/gun/projectile/automatic/combatsmg + name = "\improper PP3 Ten" + desc = "The Bishamonten PP3 Ten personal defense weapon is a rare design much sought after - though more for its looks than its functionality. Uses 9mm rounds." + description_fluff = "The Bishamonten Company operated from roughly 2150-2280 - the height of the first extrasolar colonisation boom - before filing for bankruptcy and selling off its assets to various companies that would go on to become today’s TSCs. \ + Focused on sleek ‘futurist’ designs which have largely fallen out of fashion but remain popular with collectors and people hoping to make some quick thalers from replica weapons. \ + Bishamonten weapons tended to be form over function - despite their flashy looks, most were completely unremarkable one way or another as weapons and used very standard firing mechanisms." + icon_state = "combatsmg" + w_class = ITEMSIZE_NORMAL + load_method = MAGAZINE + caliber = "9mm" + origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4) + magazine_type = /obj/item/ammo_magazine/m9mmt + allowed_magazines = list(/obj/item/ammo_magazine/m9mmt) + + firemodes = list( + list(mode_name="semiauto", burst=1, fire_delay=0), + list(mode_name="3-round bursts", burst=3, burst_delay=1, fire_delay=4, move_delay=4, burst_accuracy=list(0,-15,-30), dispersion=list(0.0, 0.6, 0.6)) + ) + +/obj/item/weapon/gun/projectile/automatic/combatsmg/update_icon() + ..() + if(ammo_magazine) + icon_state = "combatsmg" + else + icon_state = "combatsmg-empty" \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/boltaction.dm b/code/modules/projectiles/guns/projectile/boltaction.dm index 15571e53c71..9e93d46b8ac 100644 --- a/code/modules/projectiles/guns/projectile/boltaction.dm +++ b/code/modules/projectiles/guns/projectile/boltaction.dm @@ -2,7 +2,9 @@ /obj/item/weapon/gun/projectile/shotgun/pump/rifle name = "bolt action rifle" - desc = "A reproduction of an almost ancient weapon design from the early 20th century. It's still popular among hunters and collectors due to its reliability. Uses 7.62mm rounds." + desc = "The Hedberg-Hammarstrom Volsung is a modern interpretation of an almost ancient weapon design. The model is popular among hunters and collectors due to its reliability. Uses 7.62mm rounds." + description_fluff = "Sif’s largest home-grown firearms manufacturer, the Hedberg-Hammarstrom company offers a range of high-quality, high-cost hunting rifles and shotguns designed with the Sivian wilderness - and its wildlife - in mind. \ + The company operates just one production plant in Kalmar, but their weapons have found popularity on garden worlds as far afield as the Tajaran homeworld due to their excellent build quality, precision, and stopping power." item_state = "boltaction" icon_state = "boltaction" fire_sound = 'sound/weapons/Gunshot_generic_rifle.ogg' @@ -50,7 +52,9 @@ //Lever actions are the same thing, but bigger. /obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever name = "lever-action rifle" - desc = "A reproduction of an almost ancient weapon design from the 19th century. This one uses a lever-action to move new rounds into the chamber. Uses 7.62mm rounds." + desc = "The Hedberg-Hammarstrom Edda is the latest version of an almost ancient weapon design from the 19th century, popular with some due to its simplistic design. This one uses a lever-action to move new rounds into the chamber. Uses 7.62mm rounds." + description_fluff = "Sif’s largest home-grown firearms manufacturer, the Hedberg-Hammarstrom company offers a range of high-quality, high-cost hunting rifles and shotguns designed with the Sivian wilderness - and its wildlife - in mind. \ + The company operates just one production plant in Kalmar, but their weapons have found popularity on garden worlds as far afield as the Tajaran homeworld due to their excellent build quality, precision, and stopping power." item_state = "leveraction" icon_state = "leveraction" max_shells = 5 diff --git a/code/modules/projectiles/guns/projectile/caseless.dm b/code/modules/projectiles/guns/projectile/caseless.dm index 8d5dd9a19c2..dc919f3a878 100644 --- a/code/modules/projectiles/guns/projectile/caseless.dm +++ b/code/modules/projectiles/guns/projectile/caseless.dm @@ -1,6 +1,8 @@ /obj/item/weapon/gun/projectile/caseless/prototype name = "prototype caseless rifle" - desc = "A rifle cooked up in NanoTrasen's R&D labs that operates with Kraut Space Magic™ clockwork internals. Uses solid phoron 5mm caseless rounds." + desc = "The GC1 is a rifle cooked up in Gilthari Exports's R&D labs that operates with barely comprehensible clockwork internals. Uses solid phoron 5mm caseless rounds." + description_fluff = "Gilthari is Sol’s premier supplier of luxury goods, specializing in extracting money from the rich and successful. \ + The GC1 is currently undergoing limited consumer trials, and is firmly aimed at a segment of the enthusiast market with more money than sense." icon_state = "caseless" item_state = "caseless" w_class = ITEMSIZE_LARGE diff --git a/code/modules/projectiles/guns/projectile/contender.dm b/code/modules/projectiles/guns/projectile/contender.dm index d5e44ae54a9..aa07a63802d 100644 --- a/code/modules/projectiles/guns/projectile/contender.dm +++ b/code/modules/projectiles/guns/projectile/contender.dm @@ -1,6 +1,8 @@ /obj/item/weapon/gun/projectile/contender - name = "Thompson Contender" - desc = "A perfect, pristine replica of an ancient one-shot hand-cannon. For when you really want to make a hole. This one has been modified to work almost like a bolt-action. Uses .357 rounds." + name = "H-H Gram" + desc = "Hedberg-Hammarstrom's flagship one-shot hand-cannon. For when you really want to make a hole. This one has been modified to work almost like a bolt-action. Uses .357 rounds." + description_fluff = "Sif’s largest home-grown firearms manufacturer, the Hedberg-Hammarstrom company offers a range of high-quality, high-cost hunting rifles and shotguns designed with the Sivian wilderness - and its wildlife - in mind. \ + The company operates just one production plant in Kalmar, but their weapons have found popularity on garden worlds as far afield as the Tajaran homeworld due to their excellent build quality, precision, and stopping power." icon_state = "pockrifle" var/icon_retracted = "pockrifle-empty" item_state = "revolver" @@ -38,6 +40,7 @@ ..() /obj/item/weapon/gun/projectile/contender/tacticool - desc = "A modified replica of an ancient one-shot hand-cannon, reinvented with a tactical look. For when you really want to make a hole. This one has been modified to work almost like a bolt-action. Uses .357 rounds." + name = "H-H Balmung" + desc = "A later model of the Hedberg-Hammarstrom Gram, reinvented with a tactical look. For when you really want to make a hole. This one has been modified to work almost like a bolt-action. Uses .357 rounds." icon_state = "pockrifle_b" icon_retracted = "pockrifle_b-empty" \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index 435260b45ee..123a1d83c81 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -1,7 +1,7 @@ /obj/item/weapon/gun/projectile/colt var/unique_reskin name = ".45 pistol" - desc = "A cheap Martian knock-off of a Colt M1911. Uses .45 rounds." + desc = "A typical modern handgun produced for law enforcement. Uses .45 rounds." magazine_type = /obj/item/ammo_magazine/m45 allowed_magazines = list(/obj/item/ammo_magazine/m45) projectile_type = /obj/item/projectile/bullet/pistol/medium @@ -23,7 +23,7 @@ icon_state = "[initial(icon_state)]-e" /obj/item/weapon/gun/projectile/colt/detective - desc = "A Martian recreation of an old pistol. Uses .45 rounds." + desc = "A standard law enforcement issue pistol. Uses .45 rounds." magazine_type = /obj/item/ammo_magazine/m45/rubber /obj/item/weapon/gun/projectile/colt/detective/verb/rename_gun() @@ -54,13 +54,13 @@ var/list/options = list() options["NT Mk. 58"] = "secguncomp" options["NT Mk. 58 Custom"] = "secgundark" - options["Colt M1911"] = "colt" - options["FiveSeven"] = "fnseven" - options["USP"] = "usp" - options["H&K VP"] = "VP78" - options["P08 Luger"] = "p08" - options["P08 Luger, Brown"] = "p08b" - options["Glock 37"] = "enforcer_black" + options["MarsTech P11 Spur"] = "colt" + options["MarsTech P59 Massif"] = "fnseven" + options["ProTek YC9"] = "usp" + options["ProTek Minx"] = "VP78" + options["Jindal T15 Chooha"] = "p08" + options["Jindal KP-45W"] = "p08b" + options["PCA-11 Tenzu"] = "enforcer_black" var/choice = input(M,"Choose your sprite!","Resprite Gun") in options if(src && choice && !M.stat && in_range(M,src)) icon_state = options[choice] @@ -78,7 +78,8 @@ /obj/item/weapon/gun/projectile/sec name = ".45 pistol" - desc = "The NT Mk58 is a cheap, ubiquitous sidearm, produced by a NanoTrasen subsidiary. Found pretty much everywhere humans are. Uses .45 rounds." + desc = "The MT Mk58 is a cheap, ubiquitous sidearm, produced by MarsTech. Found pretty much everywhere humans are. Uses .45 rounds." + description_fluff = "The leading civilian-sector high-quality small arms brand of Hephaestus Industries, MarsTech has been the provider of choice for law enforcement and security forces for over 300 years." icon_state = "secguncomp" magazine_type = /obj/item/ammo_magazine/m45/rubber allowed_magazines = list(/obj/item/ammo_magazine/m45) @@ -99,7 +100,7 @@ magazine_type = /obj/item/ammo_magazine/m45/flash /obj/item/weapon/gun/projectile/sec/wood - desc = "The NT Mk58 is a cheap, ubiquitous sidearm, produced by a NanoTrasen subsidiary. This one has a sweet wooden grip. Uses .45 rounds." + desc = "The MT Mk58 is a cheap, ubiquitous sidearm, produced by MarsTech. This one has a sweet wooden grip. Uses .45 rounds." name = "custom .45 Pistol" icon_state = "secgundark" @@ -129,8 +130,11 @@ magazine_type = null /obj/item/weapon/gun/projectile/deagle - name = "desert eagle" - desc = "The perfect handgun for shooters with a need to hit targets through a wall and behind a fridge in your neighbor's house. Uses .44 rounds." + name = "hand cannon" + desc = "The PCA-55 Rarkajar perfect handgun for shooters with a need to hit targets through a wall and behind a fridge in your neighbor's house. Uses .44 rounds." + description_fluff = "Pearlshield Consolidated Armories are far from the most cutting edge firearm manufacturer, but the Tajaran’s long tradition of war is rivaled only by humanity, \ + and the introduction of human technology to the Tajaran arms market has resulted in something of a revolution in finding new ways to kill each other at long distances with bullets. \ + Usually made with mass-production in mind, PCA weapons combine an eye for design with a great desire to make people dead." icon_state = "deagle" item_state = "deagle" force = 14.0 @@ -148,12 +152,12 @@ icon_state = "[initial(icon_state)]-e" /obj/item/weapon/gun/projectile/deagle/gold - desc = "A gold plated gun folded over a million times by superior martian gunsmiths. Uses .44 rounds." + desc = "A gold plated gun folded over a million times by superior Tajaran gunsmiths. Uses .44 rounds." icon_state = "deagleg" item_state = "deagleg" /obj/item/weapon/gun/projectile/deagle/camo - desc = "A Deagle brand Deagle for operators operating operationally. Uses .44 rounds." + desc = "An off-brand non-Deagle for operators not operating operationally. Uses .44 rounds." icon_state = "deaglecamo" item_state = "deagleg" @@ -287,8 +291,12 @@ projectile_type = /obj/item/projectile/bullet/pistol/strong /obj/item/weapon/gun/projectile/luger - name = "\improper P08 Luger" - desc = "Not some cheap scheisse Martian knockoff! This Luger is an authentic reproduction by RauMauser. Accuracy, easy handling, and its signature appearance make it popular among historic gun collectors. Uses 9mm rounds." + name = "\improper Jindal T15 Chooha" + desc = "Almost seventy percent guaranteed not to be a cheap rimworld knockoff! Accuracy, easy handling, and its distinctive appearance make it popular among gun collectors. Uses 9mm rounds." + description_fluff = "While Jindal’s rugged, affordable weapons intended for the colonial sector are a major export of Tau Ceti, \ + the Jindal Arms company is perhaps best known for its liberal sale of production licenses to just about any fledgling rimworld venture who asks, and has cash to spare. \ + While Jindal’s 'authentic' Binma-built weapons are renowned for their reliability, the same cannot be said for the hundreds of low-grade (But technically legal) \ + copies circulating the squalid habitats and smoke-filled junk ships of the frontier." icon_state = "p08" origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2) caliber = "9mm" @@ -305,11 +313,14 @@ icon_state = "[initial(icon_state)]-e" /obj/item/weapon/gun/projectile/luger/brown + name = "\improper Jindal KP-45W" + description_fluff = "While wholly owned by Hephaestus Industries, the Jindal Arms brand does not appear prominently in most company catalogues \ + (Perhaps owing to its less than prestigious image), instead being sold almost exclusively through retailers and advertising platforms targeting the 'independent roughneck' demographic." icon_state = "p08b" /obj/item/weapon/gun/projectile/p92x name = "9mm pistol" - desc = "A widespread sidearm called the P92X which is used by military, police, and security forces across the galaxy. Uses 9mm rounds." + desc = "A widespread MarsTech sidearm called the P92X which is used by military, police, and security forces across the galaxy. Uses 9mm rounds." icon_state = "p92x" origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2) caliber = "9mm" diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 3b9431c9388..acfd06426c4 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -1,6 +1,10 @@ /obj/item/weapon/gun/projectile/revolver name = "revolver" - desc = "The Lumoco Arms HE Colt is a choice revolver for when you absolutely, positively need to put a hole in the other guy. Uses .357 rounds." + desc = "The MarsTech HE Colt is a choice revolver for when you absolutely, positively need to put a hole in the other guy. Uses .357 rounds." + description_fluff = "MarsTech first made their name in the Second Cold War as the 'Lunar Arms Company' providing home-grown arms to the Selene Federation, \ + but after the formation of the SCG rebranded and relocated to Mars where they remain based to this day. \ + The company was acquired by Hephaestus in the mid 23rd century, and its branding used to present an image of historical prestige and Solar unity for their latest product line. \ + MarsTech operates production facilities out of many of the SCG’s larger colonies." icon_state = "revolver" item_state = "revolver" caliber = ".357" @@ -36,13 +40,14 @@ /obj/item/weapon/gun/projectile/revolver/mateba name = "mateba" - desc = "This unique looking handgun is named after an Italian company famous for the manufacture of these revolvers, and pasta kneading machines. Uses .357 rounds." // Yes I'm serious. -Spades + desc = "This unique looking handgun is named after an Italian company famous for the original manufacture of these revolvers, and pasta kneading machines. Uses .357 rounds." // Yes I'm serious. -Spades icon_state = "mateba" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) /obj/item/weapon/gun/projectile/revolver/detective name = "revolver" - desc = "A cheap Martian knock-off of a Smith & Wesson Model 10. Uses .38-Special rounds." + desc = "A standard MarsTech R1 snubnose revolver, popular among some law enforcement agencies for its simple, long-lasting construction. Uses .38-Special rounds." + description_fluff = "The leading civilian-sector high-quality small arms brand of Hephaestus Industries, MarsTech has been the provider of choice for law enforcement and security forces for over 300 years." icon_state = "detective" caliber = ".38" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) @@ -68,7 +73,7 @@ /obj/item/weapon/gun/projectile/revolver/detective45 name = ".45 revolver" - desc = "A fancy replica of an old revolver, modified for .45 rounds and a seven-shot cylinder." + desc = "A basic revolver, popular among some law enforcement agencies for its simple, long-lasting construction, modified for .45 rounds and a seven-shot cylinder." icon_state = "detective" caliber = ".45" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) @@ -102,15 +107,15 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun() var/mob/M = usr var/list/options = list() - options["Colt Detective Special"] = "detective" - options["Ruger GP100"] = "GP100" - options["Colt Single Action Army"] = "detective_peacemaker" - options["Colt Single Action Army, Dark"] = "detective_peacemaker_dark" - options["H&K PT"] = "detective_panther" - options["Vintage LeMat"] = "lemat_old" - options["Webley MKVI "] = "webley" + options["MarsTech R1 Snubnose"] = "detective" + options["ProTek Cowboy"] = "GP100" + options["MarsTech Frontiersman Classic"] = "detective_peacemaker" + options["MarsTech Frontiersman Shadow"] = "detective_peacemaker_dark" + options["MarsTech Panther"] = "detective_panther" + options["Jindal Duke"] = "lemat_old" + options["H-H Sindri"] = "webley" options["Lombardi Buzzard"] = "detective_buzzard" - options["Constable Deluxe 2502"] = "detective_constable" + options["Lombardi Constable Deluxe 2502"] = "detective_constable" var/choice = input(M,"Choose your sprite!","Resprite Gun") in options if(src && choice && !M.stat && in_range(M,src)) icon_state = options[choice] @@ -157,7 +162,9 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun() /obj/item/weapon/gun/projectile/revolver/judge name = "\"The Judge\"" - desc = "A revolving hand-shotgun by Cybersun Industries that packs the power of a 12 guage in the palm of your hand (if you don't break your wrist). Uses 12g rounds." + desc = "A revolving hand-shotgun by Jindal Arms that packs the power of a 12 guage in the palm of your hand (if you don't break your wrist). Uses 12g rounds." + description_fluff = "While wholly owned by Hephaestus Industries, the Jindal Arms brand does not appear prominently in most company catalogues (Perhaps owing to its less than prestigious image), \ + instead being sold almost exclusively through retailers and advertising platforms targeting the 'independent roughneck' demographic." icon_state = "judge" caliber = "12g" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 4) @@ -169,9 +176,13 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun() // ToDo: Remove accuracy debuf in exchange for slightly injuring your hand every time you fire it. /obj/item/weapon/gun/projectile/revolver/lemat - name = "LeMat Revolver" - desc = "The LeMat Revolver is a 9 shot revolver with a secondary firing barrel loading shotgun shells. For when you really need something dead. Uses .38-Special and 12g rounds depending on the barrel." - icon_state = "lemat" + name = "Mako Revolver" + desc = "The Bishamonten P100 Mako is a 9 shot revolver with a secondary firing barrel loading shotgun shells. For when you really need something dead. A rare yet deadly collector's item. Uses .38-Special and 12g rounds depending on the barrel." + description_fluff = "The Bishamonten Company operated from roughly 2150-2280 - the height of the first extrasolar colonisation boom - before filing for bankruptcy and selling off its assets to various companies that would go on to become today’s TSCs. \ + Focused on sleek ‘futurist’ designs which have largely fallen out of fashion but remain popular with collectors and people hoping to make some quick thalers from replica weapons. \ + Bishamonten weapons tended to be form over function - despite their flashy looks, most were completely unremarkable one way or another as weapons and used very standard firing mechanisms - \ + the Mako was a notable exception, and original examples are much sought after." + icon_state = "combatrevolver" item_state = "revolver" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) handle_casings = CYCLE_CASINGS @@ -261,8 +272,10 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun() //Ported from Bay /obj/item/weapon/gun/projectile/revolver/webley - name = "service revolver" - desc = "A rugged top break revolver based on the Webley Mk. VI model, with modern improvements. Uses .44 magnum rounds." + name = "patrol revolver" + desc = "A rugged top break revolver commonly issued to members of the SifGuard. Uses .44 magnum rounds." + description_fluff = "The Heberg-Hammarstrom Althing is a simple, head-wearing revolver made with an anti-corrosive alloy. \ + The Althing is advertised as being 'able to survive six months on the bottom of a frozen river and emerge full ready to save a life'. Issued as standard sidearms to SifGuard frontier patrol." icon_state = "webley2" item_state = "webley2" caliber = ".44" @@ -274,7 +287,7 @@ obj/item/weapon/gun/projectile/revolver/detective45/verb/rename_gun() /obj/item/weapon/gun/projectile/revolver/webley/auto name = "autorevolver" icon_state = "mosley" - desc = "A shiny Mosley Autococker automatic revolver, with black accents. Marketed as the 'Revolver for the Modern Era'. Uses .44 magnum rounds." + desc = "A shiny Fosbery Autococker automatic revolver, with black accents. Marketed as the 'Revolver for the Modern Era'. Uses .44 magnum rounds." fire_delay = 5.7 //Autorevolver. Also synced with the animation fire_anim = "mosley_fire" origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2) diff --git a/code/modules/projectiles/guns/projectile/semiauto.dm b/code/modules/projectiles/guns/projectile/semiauto.dm index a1dd63cf97f..1c2fc8e0e1c 100644 --- a/code/modules/projectiles/guns/projectile/semiauto.dm +++ b/code/modules/projectiles/guns/projectile/semiauto.dm @@ -1,6 +1,9 @@ /obj/item/weapon/gun/projectile/garand - name = "\improper M1 Garand" - desc = "This is the vintage semi-automatic rifle that famously helped win the second World War. What the hell it's doing aboard a space station in the 26th century, you can only imagine. Uses 7.62mm rounds." + name = "semi-automatic rifle" + desc = "A vintage styled frontier rifle by Hedberg-Hammarstrom. The distinctive 'ping' is considered traditional, though its origins are much debated.. Uses 7.62mm rounds." + description_fluff = "Sif’s largest home-grown firearms manufacturer, the Hedberg-Hammarstrom company offers a range of high-quality, high-cost hunting rifles and shotguns designed with the Sivian wilderness - and its wildlife - in mind. \ + The company operates just one production plant in Kalmar, but their weapons have found popularity on garden worlds as far afield as the Tajaran homeworld due to their excellent build quality, \ + precision, and stopping power." icon_state = "garand" item_state = "boltaction" w_class = ITEMSIZE_LARGE @@ -19,3 +22,27 @@ icon_state = initial(icon_state) else icon_state = "[initial(icon_state)]-e" + +//Bastard child of a revolver and a semi-auto rifle. +/obj/item/weapon/gun/projectile/revolvingrifle + name = "revolving rifle" + desc = "The Gungnir is a novel, antique idea brought into the modern era by Hedberg-Hammarstrom. The semi-automatic revolving mechanism offers no real advantage, but some colonists swear by it. Uses .44 magnum revolver rounds." + description_fluff = "Sif’s largest home-grown firearms manufacturer, the Hedberg-Hammarstrom company offers a range of high-quality, high-cost hunting rifles and shotguns designed with the Sivian wilderness - and its wildlife - in mind. \ + The company operates just one production plant in Kalmar, but their weapons have found popularity on garden worlds as far afield as the Tajaran homeworld due to their excellent build quality, \ + precision, and stopping power." + icon_state = "revolvingrifle" + item_state = "boltaction" + w_class = ITEMSIZE_LARGE + caliber = ".44" + origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 2) + slot_flags = SLOT_BACK + handle_casings = CYCLE_CASINGS + load_method = SINGLE_CASING|SPEEDLOADER + max_shells = 6 + ammo_type = /obj/item/ammo_casing/a44/rifle + +/obj/item/weapon/gun/projectile/revolvingrifle/update_icon() + if(ammo_magazine) + icon_state = initial(icon_state) + else + icon_state = "[initial(icon_state)]-e" \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index e0915528595..799c27ac54c 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -1,6 +1,7 @@ /obj/item/weapon/gun/projectile/shotgun/pump name = "shotgun" - desc = "The mass-produced W-T Remmington 29x shotgun is a favourite of police and security forces on many worlds. Uses 12g rounds." + desc = "The mass-produced MarsTech Meteor 29 shotgun is a favourite of police and security forces on many worlds. Uses 12g rounds." + description_fluff = "The leading civilian-sector high-quality small arms brand of Hephaestus Industries, MarsTech has been the provider of choice for law enforcement and security forces for over 300 years." icon_state = "shotgun" item_state = "shotgun" max_shells = 4 @@ -63,6 +64,7 @@ /obj/item/weapon/gun/projectile/shotgun/pump/combat name = "combat shotgun" desc = "Built for close quarters combat, the Hephaestus Industries KS-40 is widely regarded as a weapon of choice for repelling boarders. Uses 12g rounds." + description_fluff = "The leading arms producer in the SCG, Hephaestus typically only uses its 'top level' branding for its military-grade equipment used by armed forces across human space." icon_state = "cshotgun" item_state = "cshotgun" origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2) diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index 074917a5df4..c5dac83a1db 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -3,6 +3,7 @@ /obj/item/weapon/gun/projectile/heavysniper name = "anti-materiel rifle" desc = "A portable anti-armour rifle fitted with a scope, the HI PTR-7 Rifle was originally designed to used against armoured exosuits. It is capable of punching through windows and non-reinforced walls with ease. Fires armor piercing 14.5mm shells." + description_fluff = "The leading arms producer in the SCG, Hephaestus typically only uses its 'top level' branding for its military-grade equipment used by professional armed forces across human space." icon_state = "heavysniper" wielded_item_state = "heavysniper-wielded" w_class = ITEMSIZE_HUGE // So it can't fit in a backpack. @@ -75,8 +76,8 @@ ////////////// Dragunov Sniper Rifle ////////////// /obj/item/weapon/gun/projectile/SVD - name = "\improper Dragunov" - desc = "The SVD, also known as the Dragunov, is mass produced with an Optical Sniper Sight so simple that even Ivan can use it. Too bad for you that the inscriptions are written in Russian. Uses 7.62mm rounds." + name = "sniper rifle" + desc = "The PCA S19 Jalgarr, also known by its translated name the 'Dragon', is mass produced with an Optical Sniper Sight so simple that even a Tajaran can use it. Too bad for you that the inscriptions are written in Siik. Uses 7.62mm rounds." icon_state = "SVD" item_state = "SVD" wielded_item_state = "heavysniper-wielded" //Placeholder diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 5928f0db3d3..8ef1bfe2a6e 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -134,7 +134,7 @@ // This is distinct from the hitscan's "impact_type" var. var/impact_effect_type = null - var/list/impacted_mobs + var/list/impacted_mobs = list() /obj/item/projectile/proc/Range() range-- @@ -642,9 +642,6 @@ if(!istype(target_mob)) return - if(!LAZYLEN(impacted_mobs)) - impacted_mobs = list() - if(target_mob in impacted_mobs) return @@ -661,7 +658,8 @@ return FALSE // Mob deleted itself or something. // Safe to add the target to the list that is soon to be poofed. No double jeopardy, pixel projectiles. - impacted_mobs |= target_mob + if(islist(impacted_mobs)) + impacted_mobs |= target_mob if(result == PROJECTILE_FORCE_MISS) if(!silenced) diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index d1a6f22b4d8..4ce8e73c2ec 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -226,6 +226,10 @@ penetrating = 15 armor_penetration = 90 +/obj/item/projectile/bullet/rifle/a44rifle + fire_sound = 'sound/weapons/gunshot4.ogg' + damage = 50 + /* Miscellaneous */ /obj/item/projectile/bullet/suffocationbullet//How does this even work? diff --git a/code/modules/projectiles/projectile/scatter.dm b/code/modules/projectiles/projectile/scatter.dm index 4b0511d0b46..b3900f8429d 100644 --- a/code/modules/projectiles/projectile/scatter.dm +++ b/code/modules/projectiles/projectile/scatter.dm @@ -27,6 +27,10 @@ /obj/item/projectile/bullet/pellet/shotgun/flak = 3 ) +/* + * Energy + */ + /obj/item/projectile/scatter/laser damage = 40 @@ -61,6 +65,12 @@ /obj/item/projectile/bullet/shotgun/ion = 3 ) + +/* + * Flame + */ + + /obj/item/projectile/scatter/flamethrower damage = 5 submunition_spread_max = 100 @@ -70,3 +80,19 @@ submunitions = list( /obj/item/projectile/bullet/incendiary/flamethrower/tiny = 7 ) + + +/* + * Ballistic + */ + + +/obj/item/projectile/scatter/flechette + damage = 60 + + submunition_spread_max = 40 + submunition_spread_min = 10 + + submunitions = list( + /obj/item/projectile/bullet/magnetic/flechette/small = 4 + ) diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 467d7c37a92..11f6d01cdb9 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -140,6 +140,13 @@ crash_with("[my_atom] attempted to add a reagent called '[id]' which doesn't exist. ([usr])") return 0 +/datum/reagents/proc/isolate_reagent(reagent) + for(var/A in reagent_list) + var/datum/reagent/R = A + if(R.id != reagent) + del_reagent(R.id) + update_total() + /datum/reagents/proc/remove_reagent(var/id, var/amount, var/safety = 0) if(!isnum(amount)) return 0 @@ -282,6 +289,34 @@ trans_to(target, amount, multiplier, copy) +/datum/reagents/proc/trans_type_to(var/target, var/rtype, var/amount = 1) + if (!target) + return + + var/datum/reagent/transfering_reagent = get_reagent(rtype) + + if (istype(target, /atom)) + var/atom/A = target + if (!A.reagents || !A.simulated) + return + + amount = min(amount, transfering_reagent.volume) + + if(!amount) + return + + + var/datum/reagents/F = new /datum/reagents(amount) + var/tmpdata = get_data(rtype) + F.add_reagent(rtype, amount, tmpdata) + remove_reagent(rtype, amount) + + + if (istype(target, /atom)) + return F.trans_to(target, amount) // Let this proc check the atom's type + else if (istype(target, /datum/reagents)) + return F.trans_to_holder(target, amount) + /datum/reagents/proc/trans_id_to(var/atom/target, var/id, var/amount = 1) if (!target || !target.reagents) return @@ -396,3 +431,61 @@ /atom/proc/create_reagents(var/max_vol) reagents = new/datum/reagents(max_vol, src) + +// Aurora Cooking Port +/datum/reagents/proc/get_reagent(var/id) // Returns reference to reagent matching passed ID + for(var/datum/reagent/A in reagent_list) + if (A.id == id) + return A + + return null + +//Spreads the contents of this reagent holder all over the vicinity of the target turf. +/datum/reagents/proc/splash_area(var/turf/epicentre, var/range = 3, var/portion = 1.0, var/multiplier = 1, var/copy = 0) + var/list/things = dview(range, epicentre, INVISIBILITY_LIGHTING) + var/list/turfs = list() + for (var/turf/T in things) + turfs += T + if (!turfs.len) + return//Nowhere to splash to, somehow + //Create a temporary holder to hold all the amount that will be spread + var/datum/reagents/R = new /datum/reagents(total_volume * portion * multiplier) + trans_to_holder(R, total_volume * portion, multiplier, copy) + //The exact amount that will be given to each turf + var/turfportion = R.total_volume / turfs.len + for (var/turf/T in turfs) + var/datum/reagents/TR = new /datum/reagents(turfportion) + R.trans_to_holder(TR, turfportion, 1, 0) + TR.splash_turf(T) + qdel(R) + + +//Spreads the contents of this reagent holder all over the target turf, dividing among things in it. +//50% is divided between mobs, 20% between objects, and whatever is left on the turf itself +/datum/reagents/proc/splash_turf(var/turf/T, var/amount = null, var/multiplier = 1, var/copy = 0) + if (isnull(amount)) + amount = total_volume + else + amount = min(amount, total_volume) + if (amount <= 0) + return + var/list/mobs = list() + for (var/mob/M in T) + mobs += M + var/list/objs = list() + for (var/obj/O in T) + objs += O + if (objs.len) + var/objportion = (amount * 0.2) / objs.len + for (var/o in objs) + var/obj/O = o + trans_to(O, objportion, multiplier, copy) + amount = min(amount, total_volume) + if (mobs.len) + var/mobportion = (amount * 0.5) / mobs.len + for (var/m in mobs) + var/mob/M = m + trans_to(M, mobportion, multiplier, copy) + trans_to(T, total_volume, multiplier, copy) + if (total_volume <= 0) + qdel(src) \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 4b9a892881a..b5fe99b0540 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -2,6 +2,14 @@ #define LIQUID 2 #define GAS 3 +#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites +#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites +#define MAX_MULTI_AMOUNT 20 // Max number of pills/patches that can be made at once +#define MAX_UNITS_PER_PILL 60 // Max amount of units in a pill +#define MAX_UNITS_PER_PATCH 60 // Max amount of units in a patch +#define MAX_UNITS_PER_BOTTLE 60 // Max amount of units in a bottle (it's volume) +#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever + @@ -24,11 +32,11 @@ var/condi = 0 var/useramount = 15 // Last used amount var/pillamount = 10 - var/bottlesprite = "1" - var/pillsprite = "1" + var/list/bottle_styles + var/bottlesprite = 1 + var/pillsprite = 1 var/max_pill_count = 20 - var/tab = "home" - var/analyze_data[0] + var/printing = FALSE flags = OPENCONTAINER clicksound = "button" @@ -48,6 +56,9 @@ qdel(src) return +/obj/machinery/chem_master/update_icon() + icon_state = "mixer[beaker ? "1" : "0"]" + /obj/machinery/chem_master/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food)) @@ -59,7 +70,7 @@ user.drop_item() B.loc = src to_chat(user, "You add \the [B] to the machine.") - icon_state = "mixer1" + update_icon() else if(istype(B, /obj/item/weapon/storage/pill_bottle)) @@ -85,247 +96,420 @@ if(stat & BROKEN) return user.set_machine(src) - ui_interact(user) + tgui_interact(user) + +/obj/machinery/chem_master/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/chem_master), + ) + +/obj/machinery/chem_master/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ChemMaster", name) + ui.open() /** * 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) - +/obj/machinery/chem_master/tgui_data(mob/user) var/list/data = list() - data["tab"] = tab + data["condi"] = condi + data["loaded_pill_bottle"] = !!loaded_pill_bottle if(loaded_pill_bottle) - data["pillBottle"] = list("total" = loaded_pill_bottle.contents.len, "max" = loaded_pill_bottle.max_storage_space) - else - data["pillBottle"] = null + data["loaded_pill_bottle_name"] = loaded_pill_bottle.name + data["loaded_pill_bottle_contents_len"] = loaded_pill_bottle.contents.len + data["loaded_pill_bottle_storage_slots"] = loaded_pill_bottle.max_storage_space + data["beaker"] = !!beaker 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) + var/list/beaker_reagents_list = list() + data["beaker_reagents"] = beaker_reagents_list + for(var/datum/reagent/R in beaker.reagents.reagent_list) + beaker_reagents_list[++beaker_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "description" = R.description, "id" = R.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 + var/list/buffer_reagents_list = list() + data["buffer_reagents"] = buffer_reagents_list + for(var/datum/reagent/R in reagents.reagent_list) + buffer_reagents_list[++buffer_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "id" = R.id, "description" = R.description) + data["pillsprite"] = pillsprite + data["bottlesprite"] = bottlesprite data["mode"] = mode + data["printing"] = printing - 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 + // Transfer modal information if there is one + data["modal"] = tgui_modal_data(src) - data["pillSprite"] = pillsprite - data["bottleSprite"] = bottlesprite + return data - var/P[24] //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 +/** + * Called in tgui_act() to process modal actions + * + * Arguments: + * * action - The action passed by tgui + * * params - The params passed by tgui + */ +/obj/machinery/chem_master/proc/tgui_act_modal(action, params, datum/tgui/ui, datum/tgui_state/state) + . = TRUE + var/id = params["id"] // The modal's ID + var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"] + switch(tgui_modal_act(src, action, params)) + if(TGUI_MODAL_OPEN) + switch(id) + if("analyze") + var/idx = text2num(arguments["idx"]) || 0 + var/from_beaker = text2num(arguments["beaker"]) || FALSE + var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list + if(idx < 1 || idx > length(reagent_list)) + return - 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 + var/datum/reagent/R = reagent_list[idx] + var/list/result = list("idx" = idx, "name" = R.name, "desc" = R.description) + if(!condi && istype(R, /datum/reagent/blood)) + var/datum/reagent/blood/B = R + result["blood_type"] = B.data["blood_type"] + result["blood_dna"] = B.data["blood_DNA"] - ui = SSnanoui.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) + arguments["analysis"] = result + tgui_modal_message(src, id, "", null, arguments) + // if("change_pill_bottle_style") + // if(!loaded_pill_bottle) + // return + // if(!pill_bottle_wrappers) + // pill_bottle_wrappers = list( + // "CLEAR" = "Default", + // COLOR_RED = "Red", + // COLOR_GREEN = "Green", + // COLOR_PALE_BTL_GREEN = "Pale green", + // COLOR_BLUE = "Blue", + // COLOR_CYAN_BLUE = "Light blue", + // COLOR_TEAL = "Teal", + // COLOR_YELLOW = "Yellow", + // COLOR_ORANGE = "Orange", + // COLOR_PINK = "Pink", + // COLOR_MAROON = "Brown" + // ) + // var/current = pill_bottle_wrappers[loaded_pill_bottle.wrapper_color] || "Default" + // tgui_modal_choice(src, id, "Please select a pill bottle wrapper:", null, arguments, current, pill_bottle_wrappers) + if("addcustom") + if(!beaker || !beaker.reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount to transfer to buffer:", null, arguments, useramount) + if("removecustom") + if(!reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount to transfer to [mode ? "beaker" : "disposal"]:", null, arguments, useramount) + if("create_condi_pack") + if(!condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please name your new condiment pack:", null, arguments, reagents.get_master_reagent_name(), MAX_CUSTOM_NAME_LEN) + if("create_pill") + if(condi || !reagents.total_volume) + return + var/num = round(text2num(arguments["num"] || 1)) + if(!num) + return + arguments["num"] = num + var/amount_per_pill = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_PILL) + var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_pill]u)" + var/pills_text = num == 1 ? "new pill" : "[num] new pills" + tgui_modal_input(src, id, "Please name your [pills_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) + if("create_pill_multiple") + if(condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount of pills to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) + if("change_pill_style") + var/list/choices = list() + for(var/i = 1 to MAX_PILL_SPRITE) + choices += "pill[i].png" + tgui_modal_bento(src, id, "Please select the new style for pills:", null, arguments, pillsprite, choices) + if("create_patch") + if(condi || !reagents.total_volume) + return + var/num = round(text2num(arguments["num"] || 1)) + if(!num) + return + arguments["num"] = num + var/amount_per_patch = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_PATCH) + var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_patch]u)" + var/patches_text = num == 1 ? "new patch" : "[num] new patches" + tgui_modal_input(src, id, "Please name your [patches_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) + if("create_patch_multiple") + if(condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount of patches to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) + if("create_bottle") + if(condi || !reagents.total_volume) + return + var/num = round(text2num(arguments["num"] || 1)) + if(!num) + return + arguments["num"] = num + var/amount_per_bottle = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_BOTTLE) + var/default_name = "[reagents.get_master_reagent_name()]" + var/bottles_text = num == 1 ? "new bottle" : "[num] new bottles" + tgui_modal_input(src, id, "Please name your [bottles_text] ([amount_per_bottle]u in bottle):", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) + if("create_bottle_multiple") + if(condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount of bottles to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) + if("change_bottle_style") + var/list/choices = list() + for(var/i = 1 to MAX_BOTTLE_SPRITE) + choices += "bottle-[i].png" + tgui_modal_bento(src, id, "Please select the new style for bottles:", null, arguments, bottlesprite, choices) + else + return FALSE + if(TGUI_MODAL_ANSWER) + var/answer = params["answer"] + switch(id) + // if("change_pill_bottle_style") + // if(!pill_bottle_wrappers || !loaded_pill_bottle) // wat? + // return + // var/color = "CLEAR" + // for(var/col in pill_bottle_wrappers) + // var/col_name = pill_bottle_wrappers[col] + // if(col_name == answer) + // color = col + // break + // if(length(color) && color != "CLEAR") + // loaded_pill_bottle.wrapper_color = color + // loaded_pill_bottle.apply_wrap() + // else + // loaded_pill_bottle.wrapper_color = null + // loaded_pill_bottle.cut_overlays() + if("addcustom") + var/amount = isgoodnumber(text2num(answer)) + if(!amount || !arguments["id"]) + return + tgui_act("add", list("id" = arguments["id"], "amount" = amount), ui, state) + if("removecustom") + var/amount = isgoodnumber(text2num(answer)) + if(!amount || !arguments["id"]) + return + tgui_act("remove", list("id" = arguments["id"], "amount" = amount), ui, state) + if("create_condi_pack") + if(!condi || !reagents.total_volume) + return + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/obj/item/weapon/reagent_containers/pill/P = new(loc) + P.name = "[answer] pack" + P.desc = "A small condiment pack. The label says it contains [answer]." + P.icon_state = "bouilloncube"//Reskinned monkey cube + reagents.trans_to_obj(P, 10) + if("create_pill") + if(condi || !reagents.total_volume) + return + var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) + if(!count) + return -/obj/machinery/chem_master/Topic(href, href_list) - if(stat & (BROKEN|NOPOWER)) return - if(usr.stat || usr.restrained()) return - if(!in_range(src, usr)) return + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/amount_per_pill = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_PILL) + while(count--) + if(reagents.total_volume <= 0) + to_chat(usr, "Not enough reagents to create these pills!") + return - src.add_fingerprint(usr) + var/obj/item/weapon/reagent_containers/pill/P = new(loc) + P.name = "[answer] pill" + P.pixel_x = rand(-7, 7) // Random position + P.pixel_y = rand(-7, 7) + P.icon_state = "pill[pillsprite]" + if(P.icon_state in list("pill1", "pill2", "pill3", "pill4")) // if using greyscale, take colour from reagent + P.color = reagents.get_color() + reagents.trans_to_obj(P, amount_per_pill) + // Load the pills in the bottle if there's one loaded + if(istype(loaded_pill_bottle) && length(loaded_pill_bottle.contents) < loaded_pill_bottle.max_storage_space) + P.forceMove(loaded_pill_bottle) + if("create_pill_multiple") + if(condi || !reagents.total_volume) + return + tgui_act("modal_open", list("id" = "create_pill", "arguments" = list("num" = answer)), ui, state) + if("change_pill_style") + var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_PILL_SPRITE) + if(!new_style) + return + pillsprite = new_style + if("create_patch") + if(condi || !reagents.total_volume) + return + var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) + if(!count) + return + + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/amount_per_patch = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_PATCH) + // var/is_medical_patch = chemical_safety_check(reagents) + while(count--) + if(reagents.total_volume <= 0) + to_chat(usr, "Not enough reagents to create these patches!") + return + + var/obj/item/weapon/reagent_containers/pill/patch/P = new(loc) + P.name = "[answer] patch" + P.pixel_x = rand(-7, 7) // random position + P.pixel_y = rand(-7, 7) + reagents.trans_to_obj(P, amount_per_patch) + // if(is_medical_patch) + // P.instant_application = TRUE + // P.icon_state = "bandaid_med" + if("create_patch_multiple") + if(condi || !reagents.total_volume) + return + tgui_act("modal_open", list("id" = "create_patch", "arguments" = list("num" = answer)), ui, state) + if("create_bottle") + if(condi || !reagents.total_volume) + return + var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) + if(!count) + return + + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/amount_per_bottle = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_BOTTLE) + while(count--) + if(reagents.total_volume <= 0) + to_chat(usr, "Not enough reagents to create these bottles!") + return + var/obj/item/weapon/reagent_containers/glass/bottle/P = new(loc) + P.name = "[answer] bottle" + P.pixel_x = rand(-7, 7) // random position + P.pixel_y = rand(-7, 7) + P.icon_state = "bottle-[bottlesprite]" || "bottle-1" + reagents.trans_to_obj(P, amount_per_bottle) + P.update_icon() + if("create_bottle_multiple") + if(condi || !reagents.total_volume) + return + tgui_act("modal_open", list("id" = "create_bottle", "arguments" = list("num" = answer)), ui, state) + if("change_bottle_style") + var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_BOTTLE_SPRITE) + if(!new_style) + return + bottlesprite = new_style + else + return FALSE + else + return FALSE + +/obj/machinery/chem_master/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + if(tgui_act_modal(action, params, ui, state)) + return TRUE + + 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.forceMove(get_turf(src)) - - if(Adjacent(usr)) - usr.put_in_hands(loaded_pill_bottle) - - loaded_pill_bottle = null - - if(beaker) - var/datum/reagents/R = beaker.reagents - 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 - for(var/datum/reagent/F in R.reagent_list) - if(F.name == href_list["name"]) - G = F - break - 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"]) - - if(href_list["amount"]) - var/id = href_list["add"] - var/amount = CLAMP((text2num(href_list["amount"])), 0, 200) - R.trans_id_to(src, id, amount) - - else if (href_list["addcustom"]) - - var/id = href_list["addcustom"] - useramount = input("Select the amount to transfer.", 30, useramount) as num - useramount = CLAMP(useramount, 0, 200) - src.Topic(null, list("amount" = "[useramount]", "add" = "[id]")) - - else if (href_list["remove"]) - - if(href_list["amount"]) - var/id = href_list["remove"] - var/amount = CLAMP((text2num(href_list["amount"])), 0, 200) - if(mode) - reagents.trans_id_to(beaker, id, amount) - else - reagents.remove_reagent(id, amount) - - - else if (href_list["removecustom"]) - - var/id = href_list["removecustom"] - useramount = input("Select the amount to transfer.", 30, useramount) as num - useramount = CLAMP(useramount, 0, 200) - src.Topic(null, list("amount" = "[useramount]", "remove" = "[id]")) - - else if (href_list["toggle"]) + . = TRUE + switch(action) + if("toggle") mode = !mode - - else if (href_list["eject"]) - if(beaker) - beaker.forceMove(get_turf(src)) - - if(Adjacent(usr)) // So the AI doesn't get a beaker somehow. - usr.put_in_hands(beaker) - - beaker = null - reagents.clear_reagents() - icon_state = "mixer0" - else if (href_list["createpill"] || href_list["createpill_multiple"]) - var/count = 1 - - if(reagents.total_volume/count < 1) //Sanity checking. + if("ejectp") + if(loaded_pill_bottle) + loaded_pill_bottle.forceMove(get_turf(src)) + if(Adjacent(usr) && !issilicon(usr)) + usr.put_in_hands(loaded_pill_bottle) + loaded_pill_bottle = null + if("print") + if(printing || condi) return - if (href_list["createpill_multiple"]) - count = input("Select the number of pills to make.", "Max [max_pill_count]", pillamount) as null|num - if(!count) //Covers 0 and cancel - return - count = CLAMP(round(count), 1, max_pill_count) // Fix decimals input and clamp to reasonable amounts - - if(reagents.total_volume/count < 1) //Sanity checking. + var/idx = text2num(params["idx"]) || 0 + var/from_beaker = text2num(params["beaker"]) || FALSE + var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list + if(idx < 1 || idx > length(reagent_list)) return - var/amount_per_pill = reagents.total_volume/count - if (amount_per_pill > 60) amount_per_pill = 60 + var/datum/reagent/R = reagent_list[idx] - var/pill_cube = "pill" - if(condi)//For the condimaster - pill_cube = "cube" + printing = TRUE + visible_message("[src] rattles and prints out a sheet of paper.") + // playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) + + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc) + P.info = "
Chemical Analysis

" + P.info += "Time of analysis: [worldtime2stationtime(world.time)]

" + P.info += "Chemical name: [R.name]
" + if(istype(R, /datum/reagent/blood)) + var/datum/reagent/blood/B = R + P.info += "Description: N/A
Blood Type: [B.data["blood_type"]]
DNA: [B.data["blood_DNA"]]" else - pill_cube = "pill" + P.info += "Description: [R.description]" + P.info += "

Notes:
" + P.name = "Chemical Analysis - [R.name]" + spawn(50) + printing = FALSE + else + . = FALSE - var/name = sanitizeSafe(input(usr,"Name:","Name your [pill_cube]!","[reagents.get_master_reagent_name()] ([amount_per_pill]u)") as null|text, MAX_NAME_LEN) + if(. || !beaker) + return - if(!name) //Blank name (sanitized to nothing, or left empty) or cancel + . = TRUE + var/datum/reagents/R = beaker.reagents + switch(action) + if("add") + var/id = params["id"] + var/amount = text2num(params["amount"]) + if(!id || !amount) return - - - if(reagents.total_volume/count < 1) //Sanity checking. + R.trans_id_to(src, id, amount) + if("remove") + var/id = params["id"] + var/amount = text2num(params["amount"]) + if(!id || !amount) return - while(count-- > 0) // Will definitely eventually stop. - var/obj/item/weapon/reagent_containers/pill/P = new/obj/item/weapon/reagent_containers/pill(src.loc) - if(!name) name = reagents.get_master_reagent_name() - P.name = "[name] pill" - P.pixel_x = rand(-7, 7) //random position - P.pixel_y = rand(-7, 7) - if(!condi) //If normal - P.icon_state = "pill"+pillsprite - else //If condi is on - P.icon_state = "bouilloncube"//Reskinned monkey cube - P.desc = "A dissolvable cube." - - if(P.icon_state in list("pill1", "pill2", "pill3", "pill4")) // if using greyscale, take colour from reagent - P.color = reagents.get_color() - - reagents.trans_to_obj(P,amount_per_pill) - if(src.loaded_pill_bottle) - if(loaded_pill_bottle.contents.len < loaded_pill_bottle.max_storage_space) - P.loc = loaded_pill_bottle - - else if (href_list["createbottle"]) - if(!condi) - var/name = sanitizeSafe(input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()), MAX_NAME_LEN) - var/obj/item/weapon/reagent_containers/glass/bottle/P = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc) - if(!name) name = reagents.get_master_reagent_name() - P.name = "[name] bottle" - P.pixel_x = rand(-7, 7) //random position - P.pixel_y = rand(-7, 7) - P.icon_state = "bottle-"+bottlesprite - reagents.trans_to_obj(P,60) - P.update_icon() + if(mode) + reagents.trans_id_to(beaker, id, amount) 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["createpatch"]) - if(reagents.total_volume < 1) //Sanity checking. + reagents.remove_reagent(id, amount) + if("eject") + if(!beaker) return - - var/name = sanitizeSafe(input(usr,"Name:","Name your patch!","[reagents.get_master_reagent_name()] ([round(reagents.total_volume)]u)") as null|text, MAX_NAME_LEN) - - if(!name) //Blank name (sanitized to nothing, or left empty) or cancel + beaker.forceMove(get_turf(src)) + if(Adjacent(usr) && !issilicon(usr)) + usr.put_in_hands(beaker) + beaker = null + reagents.clear_reagents() + update_icon() + if("create_condi_bottle") + if(!condi || !reagents.total_volume) return + var/obj/item/weapon/reagent_containers/food/condiment/P = new(loc) + reagents.trans_to_obj(P, 50) + else + return FALSE - if(reagents.total_volume < 1) //Sanity checking. - return - var/obj/item/weapon/reagent_containers/pill/patch/P = new/obj/item/weapon/reagent_containers/pill/patch(src.loc) - if(!name) name = reagents.get_master_reagent_name() - P.name = "[name] patch" - P.pixel_x = rand(-7, 7) //random position - P.pixel_y = rand(-7, 7) +/obj/machinery/chem_master/attack_ai(mob/user) + return attack_hand(user) - reagents.trans_to_obj(P, 60) - if(src.loaded_pill_bottle) - if(loaded_pill_bottle.contents.len < loaded_pill_bottle.max_storage_space) - P.loc = loaded_pill_bottle +/obj/machinery/chem_master/proc/isgoodnumber(num) + if(isnum(num)) + if(num > 200) + num = 200 + else if(num < 0) + num = 1 + return num + else + return FALSE - else if(href_list["pill_sprite"]) - pillsprite = href_list["pill_sprite"] - else if(href_list["bottle_sprite"]) - bottlesprite = href_list["bottle_sprite"] - - SSnanoui.update_uis(src) - -/obj/machinery/chem_master/attack_ai(mob/user as mob) - return src.attack_hand(user) +// /obj/machinery/chem_master/proc/chemical_safety_check(datum/reagents/R) +// var/all_safe = TRUE +// for(var/datum/reagent/A in R.reagent_list) +// if(!GLOB.safe_chem_list.Find(A.id)) +// all_safe = FALSE +// return all_safe /obj/machinery/chem_master/condimaster name = "CondiMaster 3000" @@ -365,11 +549,41 @@ /obj/item/stack/material/glass/phoronglass = list("platinum", "silicon", "silicon", "silicon"), //5 platinum, 15 silicon, ) + var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine") + var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject") + var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind") + // var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice") + // var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix") + /obj/machinery/reagentgrinder/Initialize() . = ..() beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) default_apply_parts() +/obj/machinery/reagentgrinder/examine(mob/user) + . = ..() + if(!in_range(user, src) && !issilicon(user) && !isobserver(user)) + . += "You're too far away to examine [src]'s contents and display!" + return + + if(inuse) + . += "\The [src] is operating." + return + + if(beaker || length(holdingitems)) + . += "\The [src] contains:" + if(beaker) + . += "- \A [beaker]." + for(var/i in holdingitems) + var/obj/item/O = i + . += "- \A [O.name]." + + if(!(stat & (NOPOWER|BROKEN))) + . += "The status display reads:\n" + if(beaker) + for(var/datum/reagent/R in beaker.reagents.reagent_list) + . += "- [R.volume] units of [R.name]." + /obj/machinery/reagentgrinder/update_icon() icon_state = "juicer"+num2text(!isnull(beaker)) return @@ -450,93 +664,65 @@ user.remove_from_mob(O) O.loc = src holdingitems += O - src.updateUsrDialog() return 0 +/obj/machinery/reagentgrinder/AltClick(mob/user) + . = ..() + if(user.incapacitated() || !Adjacent(user)) + return + replace_beaker(user) + /obj/machinery/reagentgrinder/attack_hand(mob/user as mob) - user.set_machine(src) interact(user) -/obj/machinery/reagentgrinder/interact(mob/user as mob) // The microwave Menu - var/is_chamber_empty = 0 - var/is_beaker_ready = 0 - var/processing_chamber = "" - var/beaker_contents = "" - var/dat = "" +/obj/machinery/reagentgrinder/interact(mob/user as mob) // The microwave Menu //I am reasonably certain that this is not a microwave + if(inuse || user.incapacitated()) + return - if(!inuse) - for (var/obj/item/O in holdingitems) - processing_chamber += "\A [O.name]
" + var/list/options = list() - if (!processing_chamber) - is_chamber_empty = 1 - processing_chamber = "Nothing." - if (!beaker) - beaker_contents = "No beaker attached.
" - else - is_beaker_ready = 1 - beaker_contents = "The beaker contains:
" - var/anything = 0 - for(var/datum/reagent/R in beaker.reagents.reagent_list) - anything = 1 - beaker_contents += "[R.volume] - [R.name]
" - if(!anything) - beaker_contents += "Nothing
" + if(beaker || length(holdingitems)) + options["eject"] = radial_eject + if(isAI(user)) + if(stat & NOPOWER) + return + options["examine"] = radial_examine - dat = {" - Processing chamber contains:
- [processing_chamber]
- [beaker_contents]
- "} - if (is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN))) - dat += "Process the reagents
" - if(holdingitems && holdingitems.len > 0) - dat += "Eject the reagents
" - if (beaker) - dat += "Detach the beaker
" + // if there is no power or it's broken, the procs will fail but the buttons will still show + if(length(holdingitems)) + options["grind"] = radial_grind + + var/choice + if(length(options) < 1) + return + if(length(options) == 1) + for(var/key in options) + choice = key else - dat += "Please wait..." - user << browse("All-In-One Grinder[dat]", "window=reagentgrinder") - onclose(user, "reagentgrinder") - return + choice = show_radial_menu(user, src, options, require_near = !issilicon(user)) - -/obj/machinery/reagentgrinder/Topic(href, href_list) - if(..()) + // post choice verification + if(inuse || (isAI(user) && stat & NOPOWER) || user.incapacitated()) return - usr.set_machine(src) - switch(href_list["action"]) - if ("grind") - grind() + + switch(choice) if("eject") - eject() - if ("detach") - detach() - src.updateUsrDialog() - return + eject(user) + if("grind") + grind(user) + if("examine") + examine(user) -/obj/machinery/reagentgrinder/proc/detach() - - if (usr.stat != 0) +/obj/machinery/reagentgrinder/proc/eject(mob/user) + if(user.incapacitated()) return - if (!beaker) - return - beaker.loc = src.loc - beaker = null - update_icon() - -/obj/machinery/reagentgrinder/proc/eject() - - if (usr.stat != 0) - return - if (!holdingitems || holdingitems.len == 0) - return - for(var/obj/item/O in holdingitems) O.loc = src.loc holdingitems -= O holdingitems.Cut() + if(beaker) + replace_beaker(user) /obj/machinery/reagentgrinder/proc/grind() @@ -554,7 +740,6 @@ // Reset the machine. spawn(60) inuse = 0 - interact(usr) // Process. for (var/obj/item/O in holdingitems) @@ -581,13 +766,26 @@ continue if(O.reagents) - O.reagents.trans_to(beaker, min(O.reagents.total_volume, remaining_volume)) + O.reagents.trans_to_obj(beaker, min(O.reagents.total_volume, remaining_volume)) if(O.reagents.total_volume == 0) holdingitems -= O qdel(O) if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break +/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/weapon/reagent_containers/new_beaker) + if(!user) + return FALSE + if(beaker) + if(!user.incapacitated() && Adjacent(user)) + user.put_in_hands(beaker) + else + beaker.forceMove(drop_location()) + beaker = null + if(new_beaker) + beaker = new_beaker + update_icon() + return TRUE /////////////// /////////////// @@ -653,4 +851,12 @@ to_chat(user, span("notice", "Scanning of \the [I] complete.")) analyzing = FALSE update_icon() - return \ No newline at end of file + return + +#undef MAX_PILL_SPRITE +#undef MAX_BOTTLE_SPRITE +#undef MAX_MULTI_AMOUNT +#undef MAX_UNITS_PER_PILL +#undef MAX_UNITS_PER_PATCH +#undef MAX_UNITS_PER_BOTTLE +#undef MAX_CUSTOM_NAME_LEN diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index d3283bc394c..a7239281c28 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -19,7 +19,7 @@ var/dose = 0 var/max_dose = 0 var/overdose = 0 //Amount at which overdose starts - var/overdose_mod = 2 //Modifier to overdose damage + var/overdose_mod = 1 //Modifier to overdose damage var/can_overdose_touch = FALSE // Can the chemical OD when processing on touch? var/scannable = 0 // Shows up on health analyzers. var/affects_dead = 0 @@ -146,7 +146,10 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M overdose_mod *= H.species.chemOD_mod - M.adjustToxLoss(removed * overdose_mod) + // 6 damage per unit at minimum, scales with excessive reagents. Rounding should help keep damage consistent between ingest / inject, but isn't perfect. + // Hardcapped at 3.6 damage per tick, or 18 damage per unit at 0.2 metabolic rate so that you can't instakill people with overdoses by feeding them infinite periadaxon. + // Overall, max damage is slightly less effective than hydrophoron, and 1/5 as effective as cyanide. + M.adjustToxLoss(min(removed * overdose_mod * round(3 + 3 * volume / overdose), 3.6)) /datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created. if(!isnull(newdata)) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index 54e1e1bbdd3..cd011cc362e 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -180,6 +180,16 @@ L.ExtinguishMob() L.water_act(amount / 25) // Div by 25, as water_act multiplies it by 5 in order to calculate firestack modification. remove_self(needed) + // Put out cigarettes if splashed. + if(istype(L, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = L + if(H.wear_mask) + if(istype(H.wear_mask, /obj/item/clothing/mask/smokable)) + var/obj/item/clothing/mask/smokable/S = H.wear_mask + if(S.lit) + S.quench() + H.visible_message("[H]\'s [S.name] is put out.") + /* //VOREStation Edit Start. Stops slimes from dying from water. Fixes fuel affect_ingest, too. /datum/reagent/water/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_SLIME) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index 10beef463bb..7743e184d53 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -122,8 +122,8 @@ if(effective_dose >= strength * 6) // Toxic dose M.add_chemical_effect(CE_ALCOHOL_TOXIC, toxicity*3) if(effective_dose >= strength * 7) // Pass out - M.paralysis = max(M.paralysis, 60) - M.sleeping = max(M.sleeping, 90) + M.Paralyse(60) + M.Sleeping(90) if(druggy != 0) M.druggy = max(M.druggy, druggy*3) @@ -166,8 +166,8 @@ if(dose * strength_mod >= strength * 6) // Toxic dose M.add_chemical_effect(CE_ALCOHOL_TOXIC, toxicity) if(dose * strength_mod >= strength * 7) // Pass out - M.paralysis = max(M.paralysis, 20) - M.sleeping = max(M.sleeping, 30) + M.Paralyse(20) + M.Sleeping(30) if(druggy != 0) M.druggy = max(M.druggy, druggy) @@ -260,7 +260,7 @@ step(M, pick(cardinal)) if(prob(5)) M.emote(pick("twitch", "drool", "moan")) - M.adjustBrainLoss(0.1) + M.adjustBrainLoss(0.5 * removed) /datum/reagent/nitrogen name = "Nitrogen" @@ -465,7 +465,7 @@ M.Weaken(2) M.drowsyness = max(M.drowsyness, 20) else - M.sleeping = max(M.sleeping, 20) + M.Sleeping(20) M.drowsyness = max(M.drowsyness, 60) /datum/reagent/sulfur diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index d528f7bda54..43a3bf269c7 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -50,6 +50,192 @@ M.adjust_nutrition(nutriment_factor * removed) // For hunger and fatness M.add_chemical_effect(CE_BLOODRESTORE, 4 * removed) +// Aurora Cooking Port Insertion Begin + +/* + Coatings are used in cooking. Dipping food items in a reagent container with a coating in it + allows it to be covered in that, which will add a masked overlay to the sprite. + Coatings have both a raw and a cooked image. Raw coating is generally unhealthy + Generally coatings are intended for deep frying foods +*/ +/datum/reagent/nutriment/coating + nutriment_factor = 6 //Less dense than the food itself, but coatings still add extra calories + var/messaged = 0 + var/icon_raw + var/icon_cooked + var/coated_adj = "coated" + var/cooked_name = "coating" + +/datum/reagent/nutriment/coating/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + + //We'll assume that the batter isnt going to be regurgitated and eaten by someone else. Only show this once + if(data["cooked"] != 1) + if (!messaged) + to_chat(M, "Ugh, this raw [name] tastes disgusting.") + nutriment_factor *= 0.5 + messaged = 1 + + //Raw coatings will sometimes cause vomiting. 75% chance of this happening. + if(prob(75)) + M.vomit() + ..() + +/datum/reagent/nutriment/coating/initialize_data(var/newdata) // Called when the reagent is created. + ..() + if (!data) + data = list() + else + if (isnull(data["cooked"])) + data["cooked"] = 0 + return + data["cooked"] = 0 + if (holder && holder.my_atom && istype(holder.my_atom,/obj/item/weapon/reagent_containers/food/snacks)) + data["cooked"] = 1 + name = cooked_name + + //Batter which is part of objects at compiletime spawns in a cooked state + + +//Handles setting the temperature when oils are mixed +/datum/reagent/nutriment/coating/mix_data(var/newdata, var/newamount) + if (!data) + data = list() + + data["cooked"] = newdata["cooked"] + +/datum/reagent/nutriment/coating/batter + name = "batter mix" + cooked_name = "batter" + id = "batter" + color = "#f5f4e9" + reagent_state = LIQUID + icon_raw = "batter_raw" + icon_cooked = "batter_cooked" + coated_adj = "battered" + +/datum/reagent/nutriment/coating/beerbatter + name = "beer batter mix" + cooked_name = "beer batter" + id = "beerbatter" + color = "#f5f4e9" + reagent_state = LIQUID + icon_raw = "batter_raw" + icon_cooked = "batter_cooked" + coated_adj = "beer-battered" + +/datum/reagent/nutriment/coating/beerbatter/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + M.add_chemical_effect(CE_ALCOHOL, 0.02) //Very slightly alcoholic + +//========================= +//Fats +//========================= +/datum/reagent/nutriment/triglyceride + name = "triglyceride" + id = "triglyceride" + description = "More commonly known as fat, the third macronutrient, with over double the energy content of carbs and protein" + + reagent_state = SOLID + nutriment_factor = 27//The caloric ratio of carb/protein/fat is 4:4:9 + color = "#CCCCCC" + +/datum/reagent/nutriment/triglyceride/oil + //Having this base class incase we want to add more variants of oil + name = "Oil" + id = "oil" + description = "Oils are liquid fats." + reagent_state = LIQUID + color = "#c79705" + touch_met = 1.5 + var/lastburnmessage = 0 + +/datum/reagent/nutriment/triglyceride/oil/touch_turf(var/turf/simulated/T) + if(!istype(T)) + return + + var/hotspot = (locate(/obj/fire) in T) + if(hotspot && !istype(T, /turf/space)) + var/datum/gas_mixture/lowertemp = T.remove_air(T:air:total_moles) + lowertemp.temperature = max(min(lowertemp.temperature-2000, lowertemp.temperature / 2), 0) + lowertemp.react() + T.assume_air(lowertemp) + qdel(hotspot) + + if(volume >= 3) + T.wet_floor(2) + +/datum/reagent/nutriment/triglyceride/oil/initialize_data(var/newdata) // Called when the reagent is created. + ..() + if (!data) + data = list("temperature" = T20C) + +//Handles setting the temperature when oils are mixed +/datum/reagent/nutriment/triglyceride/oil/mix_data(var/newdata, var/newamount) + + if (!data) + data = list() + + var/ouramount = volume - newamount + if (ouramount <= 0 || !data["temperature"] || !volume) + //If we get here, then this reagent has just been created, just copy the temperature exactly + data["temperature"] = newdata["temperature"] + + else + //Our temperature is set to the mean of the two mixtures, taking volume into account + var/total = (data["temperature"] * ouramount) + (newdata["temperature"] * newamount) + data["temperature"] = total / volume + + return ..() + + +//Calculates a scaling factor for scalding damage, based on the temperature of the oil and creature's heat resistance +/datum/reagent/nutriment/triglyceride/oil/proc/heatdamage(var/mob/living/carbon/M) + var/threshold = 360//Human heatdamage threshold + var/datum/species/S = M.get_species(1) + if (S && istype(S)) + threshold = S.heat_level_1 + + //If temperature is too low to burn, return a factor of 0. no damage + if (data["temperature"] < threshold) + return 0 + + //Step = degrees above heat level 1 for 1.0 multiplier + var/step = 60 + if (S && istype(S)) + step = (S.heat_level_2 - S.heat_level_1)*1.5 + + . = data["temperature"] - threshold + . /= step + . = min(., 2.5)//Cap multiplier at 2.5 + +/datum/reagent/nutriment/triglyceride/oil/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + var/dfactor = heatdamage(M) + if (dfactor) + M.take_organ_damage(0, removed * 1.5 * dfactor) + data["temperature"] -= (6 * removed) / (1 + volume*0.1)//Cools off as it burns you + if (lastburnmessage+100 < world.time ) + to_chat(M, "Searing hot oil burns you, wash it off quick!") + lastburnmessage = world.time + +/datum/reagent/nutriment/triglyceride/oil/corn + name = "Corn Oil" + id = "cornoil" + description = "An oil derived from various types of corn." + taste_description = "oil" + taste_mult = 0.1 + reagent_state = LIQUID + +/datum/reagent/nutriment/triglyceride/oil/peanut + name = "Peanut Oil" + id = "peanutoil" + description = "An oil derived from various types of nuts." + taste_description = "nuts" + taste_mult = 0.3 + nutriment_factor = 15 + color = "#4F3500" + +// Aurora Cooking Port Insertion End + /datum/reagent/nutriment/glucose name = "Glucose" id = "glucose" @@ -85,6 +271,24 @@ return ..() +/datum/reagent/nutriment/protein/tofu + name = "tofu protein" + id = "tofu" + color = "#fdffa8" + taste_description = "tofu" + +/datum/reagent/nutriment/protein/seafood + name = "seafood protein" + id = "seafood" + color = "#f5f4e9" + taste_description = "fish" + +/datum/reagent/nutriment/protein/cheese // Also bad for skrell. + name = "cheese" + id = "cheese" + color = "#EDB91F" + taste_description = "cheese" + /datum/reagent/nutriment/protein/egg // Also bad for skrell. name = "egg yolk" id = "egg" @@ -123,7 +327,7 @@ M.Weaken(2) M.drowsyness = max(M.drowsyness, 20) else - M.sleeping = max(M.sleeping, 20) + M.Sleeping(20) M.drowsyness = max(M.drowsyness, 60) /datum/reagent/nutriment/mayo @@ -257,56 +461,6 @@ nutriment_factor = 1 color = "#801E28" -/datum/reagent/nutriment/cornoil - name = "Corn Oil" - id = "cornoil" - description = "An oil derived from various types of corn." - taste_description = "slime" - taste_mult = 0.1 - reagent_state = LIQUID - nutriment_factor = 20 - color = "#302000" - -/datum/reagent/nutriment/cornoil/touch_turf(var/turf/simulated/T) - if(!istype(T)) - return - - var/hotspot = (locate(/obj/fire) in T) - if(hotspot && !istype(T, /turf/space)) - var/datum/gas_mixture/lowertemp = T.remove_air(T:air:total_moles) - lowertemp.temperature = max(min(lowertemp.temperature-2000, lowertemp.temperature / 2), 0) - lowertemp.react() - T.assume_air(lowertemp) - qdel(hotspot) - - if(volume >= 3) - T.wet_floor() - -/datum/reagent/nutriment/peanutoil - name = "Peanut Oil" - id = "peanutoil" - description = "An oil derived from various types of nuts." - taste_description = "nuts" - taste_mult = 0.3 - reagent_state = LIQUID - nutriment_factor = 15 - color = "#4F3500" - -/datum/reagent/nutriment/peanutoil/touch_turf(var/turf/simulated/T) - if(!istype(T)) - return - - var/hotspot = (locate(/obj/fire) in T) - if(hotspot && !istype(T, /turf/space)) - var/datum/gas_mixture/lowertemp = T.remove_air(T:air:total_moles) - lowertemp.temperature = max(min(lowertemp.temperature-2000, lowertemp.temperature / 2), 0) - lowertemp.react() - T.assume_air(lowertemp) - qdel(hotspot) - - if(volume >= 5) - T.wet_floor() - /datum/reagent/nutriment/peanutbutter name = "Peanut Butter" id = "peanutbutter" @@ -430,6 +584,22 @@ reagent_state = LIQUID color = "#365E30" overdose = REAGENTS_OVERDOSE + +//SYNNONO MEME FOODS EXPANSION - Credit to Synnono + +/datum/reagent/spacespice + name = "Space Spice" + id = "spacespice" + description = "An exotic blend of spices for cooking. Definitely not worms." + reagent_state = SOLID + color = "#e08702" + +/datum/reagent/browniemix + name = "Brownie Mix" + id = "browniemix" + description = "A dry mix for making delicious brownies." + reagent_state = SOLID + color = "#441a03" /datum/reagent/frostoil name = "Frost Oil" @@ -475,6 +645,11 @@ /datum/reagent/capsaicin/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) return + if(alien == IS_ALRAUNE) // VOREStation Edit: It wouldn't affect plants that much. + if(prob(5)) + to_chat(M, "You feel a pleasant sensation in your mouth.") + M.bodytemperature += rand(10, 25) + return if(ishuman(M)) var/mob/living/carbon/human/H = M if(!H.can_feel_pain()) @@ -659,7 +834,7 @@ M.adjust_nutrition(nutrition * removed) M.dizziness = max(0, M.dizziness + adj_dizzy) M.drowsyness = max(0, M.drowsyness + adj_drowsy) - M.sleeping = max(0, M.sleeping + adj_sleepy) + M.AdjustSleeping(adj_sleepy) if(adj_temp > 0 && M.bodytemperature < 310) // 310 is the normal bodytemp. 310.055 M.bodytemperature = min(310, M.bodytemperature + (adj_temp * TEMPERATURE_DAMAGE_COEFFICIENT)) if(adj_temp < 0 && M.bodytemperature > 310) @@ -747,7 +922,7 @@ M.Weaken(2) M.drowsyness = max(M.drowsyness, 20) else - M.sleeping = max(M.sleeping, 20) + M.Sleeping(20) M.drowsyness = max(M.drowsyness, 60) */ @@ -1331,7 +1506,7 @@ M.Weaken(2) M.drowsyness = max(M.drowsyness, 20) else - M.sleeping = max(M.sleeping, 20) + M.Sleeping(20) M.drowsyness = max(M.drowsyness, 60) /datum/reagent/drink/milkshake/chocoshake @@ -1993,7 +2168,7 @@ ..() M.dizziness = max(0, M.dizziness - 5) M.drowsyness = max(0, M.drowsyness - 3) - M.sleeping = max(0, M.sleeping - 2) + M.AdjustSleeping(-2) if(M.bodytemperature > 310) M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT)) //if(alien == IS_TAJARA) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks_vr.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks_vr.dm index fee195bbac9..d5e2b1a8df1 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks_vr.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks_vr.dm @@ -67,6 +67,17 @@ glass_name = "Monster Tamer" glass_desc = "This looks like a vaguely-alcoholic slurry of meat. Gross." +/datum/reagent/ethanol/pink_moo + name = "Pink Moo" + id = "pinkmoo" + description = "Like a White Russian but with 100% more pink!" + taste_description = "strawberry icecream, with a coffee kick" + color = "#d789bd" + strength = 15 + + glass_name = "Pink Moo" + glass_desc = "A very familiar looking drink. ...moo?" + /datum/reagent/ethanol/monstertamer/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) ..() @@ -226,9 +237,9 @@ ..() M.Stun(2) -/datum/reagent/ethanol/lovepotion - name = "Love Potion" - id = "lovepotion" +/datum/reagent/ethanol/lovemaker + name = "The Love Maker" + id = "lovemaker" description = "A drink said to help one find true love." taste_description = "sweet fruit and honey." strength = 30 @@ -239,7 +250,7 @@ targ_temp = 360 color = "#d3785d" - glass_name = "Love Potion" + glass_name = "The Love Maker" glass_desc = "A drink said to help one find the perfect fuck." /datum/reagent/ethanol/honeyshot @@ -283,7 +294,7 @@ id = "scsatw" description = "The screwdriver's bigger cousin." taste_description = "smooth, savory booze and tangy orange juice." - strength = 0 + strength = 30 druggy = 0 halluci = 0 var/adj_dizzy = 0 diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 5a323e01c63..681929691ae 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -48,6 +48,7 @@ reagent_state = LIQUID color = "#BF0000" overdose = REAGENTS_OVERDOSE + overdose_mod = 0.25 scannable = 1 /datum/reagent/bicaridine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -214,6 +215,8 @@ reagent_state = LIQUID color = "#225722" scannable = 1 + overdose = REAGENTS_OVERDOSE * 0.5 + overdose_mod = 0 // Not used, but it shouldn't deal toxin damage anyways. Carth heals toxins! /datum/reagent/carthatoline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) @@ -234,6 +237,11 @@ if(alien == IS_SLIME) H.druggy = max(M.druggy, 5) +/datum/reagent/carthatoline/overdose(var/mob/living/carbon/M, var/alien, var/removed) + M.adjustHalLoss(2) + var/mob/living/carbon/human/H = M + H.internal_organs_by_name[O_STOMACH].take_damage(removed * 2) // Causes stomach contractions, makes sense for an overdose to make it much worse. + /datum/reagent/dexalin name = "Dexalin" id = "dexalin" @@ -267,6 +275,7 @@ reagent_state = LIQUID color = "#0040FF" overdose = REAGENTS_OVERDOSE * 0.5 + overdose_mod = 1.25 scannable = 1 /datum/reagent/dexalinp/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -391,6 +400,49 @@ M.heal_organ_damage(30 * removed, 30 * removed * chem_effective) M.adjustToxLoss(-30 * removed * chem_effective) +/datum/reagent/mortiferin + name = "Mortiferin" + id = "mortiferin" + description = "A liquid compound based upon those used in cloning. Utilized in cases of toxic shock. May cause liver damage." + taste_description = "meat" + reagent_state = LIQUID + color = "#6b4de3" + metabolism = REM * 0.5 + mrate_static = TRUE + scannable = 1 + +/datum/reagent/mortiferin/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) + if(M.stat == DEAD && M.has_modifier_of_type(/datum/modifier/bloodpump_corpse)) + affects_dead = TRUE + else + affects_dead = FALSE + + . = ..(M, alien, location) + +/datum/reagent/mortiferin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(M.bodytemperature < (T0C - 10) || (M.stat == DEAD && M.has_modifier_of_type(/datum/modifier/bloodpump_corpse))) + var/chem_effective = 1 * M.species.chem_strength_heal + if(alien == IS_SLIME) + if(prob(10)) + to_chat(M, "It's so cold. Something causes your cellular mass to solidify sporadically, resulting in uncontrollable twitching.") + chem_effective = 0.5 + M.Weaken(10) + M.silent = max(M.silent, 10) + M.make_jittery(4) + if(M.stat != DEAD) + M.adjustCloneLoss(-5 * removed * chem_effective) + M.adjustOxyLoss(-10 * removed * chem_effective) + M.adjustToxLoss(-20 * removed * chem_effective) + + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/obj/item/organ/internal/liver/L = H.internal_organs_by_name[O_LIVER] + if(istype(L) && prob(5)) + if(L.robotic >= ORGAN_ROBOT) + return + + L.take_damage(rand(1,3) * removed) + /datum/reagent/necroxadone name = "Necroxadone" id = "necroxadone" @@ -401,18 +453,11 @@ metabolism = REM * 0.5 mrate_static = TRUE scannable = 1 - -/datum/reagent/necroxadone/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) - if(M.stat == DEAD && M.has_modifier_of_type(/datum/modifier/bloodpump_corpse)) - affects_dead = TRUE - else - affects_dead = FALSE - - . = ..(M, alien, location) + affects_dead = TRUE /datum/reagent/necroxadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + var/chem_effective = 1 * M.species.chem_strength_heal if(M.bodytemperature < 170 || (M.stat == DEAD && M.has_modifier_of_type(/datum/modifier/bloodpump_corpse))) - var/chem_effective = 1 * M.species.chem_strength_heal if(alien == IS_SLIME) if(prob(10)) to_chat(M, "It's so cold. Something causes your cellular mass to harden sporadically, resulting in seizure-like twitching.") @@ -424,6 +469,12 @@ M.adjustCloneLoss(-5 * removed * chem_effective) M.adjustOxyLoss(-20 * removed * chem_effective) M.adjustToxLoss(-40 * removed * chem_effective) + M.adjustCloneLoss(-15 * removed * chem_effective) + + else + M.adjustToxLoss(-25 * removed * chem_effective) + M.adjustOxyLoss(-10 * removed * chem_effective) + M.adjustCloneLoss(-7 * removed * chem_effective) /* Painkillers */ @@ -434,7 +485,8 @@ taste_description = "bitterness" reagent_state = LIQUID color = "#C8A5DC" - overdose = 60 + overdose = REAGENTS_OVERDOSE * 2 + overdose_mod = 0.75 scannable = 1 metabolism = 0.02 mrate_static = TRUE @@ -458,7 +510,8 @@ taste_description = "sourness" reagent_state = LIQUID color = "#CB68FC" - overdose = 30 + overdose = REAGENTS_OVERDOSE + overdose_mod = 0.75 scannable = 1 metabolism = 0.02 mrate_static = TRUE @@ -482,6 +535,7 @@ reagent_state = LIQUID color = "#800080" overdose = 20 + overdose_mod = 0.75 scannable = 1 metabolism = 0.02 mrate_static = TRUE @@ -529,7 +583,7 @@ M.AdjustWeakened(-1) holder.remove_reagent("mindbreaker", 5) M.hallucination = max(0, M.hallucination - 10) - M.adjustToxLoss(5 * removed * chem_effective) // It used to be incredibly deadly due to an oversight. Not anymore! + M.adjustToxLoss(10 * removed * chem_effective) // It used to be incredibly deadly due to an oversight. Not anymore! M.add_chemical_effect(CE_PAINKILLER, 20 * chem_effective * M.species.chem_strength_pain) /datum/reagent/hyperzine @@ -540,6 +594,7 @@ reagent_state = LIQUID color = "#FF3300" overdose = REAGENTS_OVERDOSE * 0.5 + overdose_mod = 0.25 /datum/reagent/hyperzine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_TAJARA) @@ -553,6 +608,13 @@ M.emote(pick("twitch", "blink_r", "shiver")) M.add_chemical_effect(CE_SPEEDBOOST, 1) +/datum/reagent/hyperzine/overdose(var/mob/living/carbon/M, var/alien, var/removed) + ..() + if(prob(5)) // 1 in 20 + var/mob/living/carbon/human/H = M + H.internal_organs_by_name[O_HEART].take_damage(1) + to_chat(M, "Huh... Is this what a heart attack feels like?") + /datum/reagent/alkysine name = "Alkysine" id = "alkysine" @@ -609,6 +671,7 @@ reagent_state = LIQUID color = "#561EC3" overdose = 10 + overdose_mod = 1.5 scannable = 1 /datum/reagent/peridaxon/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -628,6 +691,11 @@ if(prob(33)) H.Confuse(10) +/datum/reagent/peridaxon/overdose(var/mob/living/carbon/M, var/alien, var/removed) + ..() + M.adjustHalLoss(5) + M.hallucination = max(M.hallucination, 10) + /datum/reagent/osteodaxon name = "Osteodaxon" id = "osteodaxon" @@ -636,6 +704,7 @@ color = "#C9BCE3" metabolism = REM * 0.5 overdose = REAGENTS_OVERDOSE * 0.5 + overdose_mod = 1.5 scannable = 1 /datum/reagent/osteodaxon/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -658,6 +727,7 @@ color = "#4246C7" metabolism = REM * 0.5 overdose = REAGENTS_OVERDOSE * 0.5 + overdose_mod = 1.5 scannable = 1 var/repair_strength = 3 @@ -679,6 +749,23 @@ if(W.damage <= 0) O.wounds -= W +/datum/reagent/myelamine/overdose(var/mob/living/carbon/M, var/alien, var/removed) + // Copypaste of affect_blood with slight adjustment. Heals slightly faster at the cost of high toxins + ..() + if(ishuman(M)) + var/mob/living/carbon/human/H = M + var/wound_heal = removed * repair_strength / 2 + for(var/obj/item/organ/external/O in H.bad_external_organs) + for(var/datum/wound/W in O.wounds) + if(W.bleeding()) + W.damage = max(W.damage - wound_heal, 0) + if(W.damage <= 0) + O.wounds -= W + if(W.internal) + W.damage = max(W.damage - wound_heal, 0) + if(W.damage <= 0) + O.wounds -= W + /datum/reagent/respirodaxon name = "Respirodaxon" id = "respirodaxon" @@ -688,6 +775,7 @@ color = "#4444FF" metabolism = REM * 1.5 overdose = 10 + overdose_mod = 1.75 scannable = 1 /datum/reagent/respirodaxon/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -719,6 +807,7 @@ color = "#8B4513" metabolism = REM * 1.5 overdose = 10 + overdose_mod = 1.75 scannable = 1 /datum/reagent/gastirodaxon/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -750,6 +839,7 @@ color = "#D2691E" metabolism = REM * 1.5 overdose = 10 + overdose_mod = 1.75 scannable = 1 /datum/reagent/hepanephrodaxon/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -783,6 +873,7 @@ color = "#FF4444" metabolism = REM * 1.5 overdose = 10 + overdose_mod = 1.75 scannable = 1 /datum/reagent/cordradaxon/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -810,6 +901,7 @@ reagent_state = SOLID color = "#7B4D4F" overdose = 20 + overdose_mod = 1.5 scannable = 1 /datum/reagent/immunosuprizine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -867,6 +959,7 @@ color = "#84B2B0" metabolism = REM * 0.75 overdose = 20 + overdose_mod = 1.5 scannable = 1 /datum/reagent/skrellimmuno/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -1008,6 +1101,7 @@ color = "#008000" metabolism = REM * 0.25 overdose = REAGENTS_OVERDOSE + overdose_mod = 1.25 scannable = 1 /datum/reagent/arithrazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -1056,6 +1150,7 @@ color = "#FFB0B0" mrate_static = TRUE overdose = 10 + overdose_mod = 1.5 scannable = 1 data = 0 @@ -1197,6 +1292,12 @@ for(var/obj/effect/decal/cleanable/blood/B in T) qdel(B) + //VOREstation edit. Floor polishing. + if(istype(T, /turf/simulated)) + var/turf/simulated/S = T + S.dirt = -50 + //VOREstation edit end + /datum/reagent/sterilizine/touch_mob(var/mob/living/L, var/amount) if(istype(L)) if(istype(L, /mob/living/simple_mob/slime)) @@ -1231,6 +1332,7 @@ reagent_state = SOLID color = "#669900" overdose = REAGENTS_OVERDOSE + overdose_mod = 2 scannable = 1 /datum/reagent/rezadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index dea0a6a987c..ba7dc93d639 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -197,7 +197,7 @@ M.drowsyness = 0 M.stuttering = 0 M.SetConfused(0) - M.sleeping = 0 + M.SetSleeping(0) M.jitteriness = 0 M.radiation = 0 M.ExtinguishMob() @@ -423,6 +423,16 @@ if(prob(5)) M.vomit() +/datum/reagent/space_cleaner/touch_mob(var/mob/living/L, var/amount) + if(istype(L, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = L + if(H.wear_mask) + if(istype(H.wear_mask, /obj/item/clothing/mask/smokable)) + var/obj/item/clothing/mask/smokable/S = H.wear_mask + if(S.lit) + S.quench() // No smoking in my medbay! + H.visible_message("[H]\'s [S.name] is put out.") + /datum/reagent/lube // TODO: spraying on borgs speeds them up name = "Space Lube" id = "lube" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index 7ac94215f47..e18c2e56d9f 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -46,6 +46,11 @@ color = "#792300" strength = 10 +/datum/reagent/toxin/amatoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + // Trojan horse. Waits until most of the toxin has gone through the body before dealing the bulk of it in one big strike. + if(volume < max_dose * 0.2) + M.adjustToxLoss(max_dose * strength * removed / (max_dose * 0.2)) + /datum/reagent/toxin/carpotoxin name = "Carpotoxin" id = "carpotoxin" @@ -55,6 +60,10 @@ color = "#003333" strength = 10 +/datum/reagent/toxin/carpotoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + ..() + M.adjustBrainLoss(strength / 4 * removed) + /datum/reagent/toxin/neurotoxic_protein name = "toxic protein" id = "neurotoxic_protein" @@ -170,7 +179,7 @@ /datum/reagent/toxin/cyanide/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) ..() M.adjustOxyLoss(20 * removed) - M.sleeping += 1 + M.Sleeping(1) /datum/reagent/toxin/mold name = "Mold" @@ -212,6 +221,7 @@ color = "#d0583a" metabolism = REM * 3 overdose = 10 + overdose_mod = 0.5 strength = 3 /datum/reagent/toxin/stimm/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) @@ -225,6 +235,13 @@ M.take_organ_damage(6 * removed, 0) M.add_chemical_effect(CE_SPEEDBOOST, 1) +/datum/reagent/toxin/stimm/overdose(var/mob/living/carbon/M, var/alient, var/removed) + ..() + if(prob(10)) // 1 in 10. This thing's made with welder fuel and fertilizer, what do you expect? + var/mob/living/carbon/human/H = M + H.internal_organs_by_name[O_HEART].take_damage(1) + to_chat(M, "Huh... Is this what a heart attack feels like?") + /datum/reagent/toxin/potassium_chloride name = "Potassium Chloride" id = "potassium_chloride" @@ -645,7 +662,7 @@ else M.Weaken(2) else - M.sleeping = max(M.sleeping, 20) + M.Sleeping(20) M.drowsyness = max(M.drowsyness, 60) /datum/reagent/chloralhydrate @@ -658,7 +675,7 @@ metabolism = REM * 0.5 ingest_met = REM * 1.5 overdose = REAGENTS_OVERDOSE * 0.5 - overdose_mod = 5 //For that good, lethal feeling + overdose_mod = 2 //For that good, lethal feeling // Reduced with overdose changes. Slightly stronger than before /datum/reagent/chloralhydrate/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) @@ -689,7 +706,7 @@ M.Weaken(30) M.Confuse(40) else - M.sleeping = max(M.sleeping, 30) + M.Sleeping(30) if(effective_dose > 1 * threshold) M.adjustToxLoss(removed) diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index b2591d992f7..9adb2558b9a 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -428,6 +428,14 @@ catalysts = list("phoron" = 5) result_amount = 2 +/datum/chemical_reaction/mortiferin + name = "Mortiferin" + id = "mortiferin" + result = "mortiferin" + required_reagents = list("cryptobiolin" = 1, "clonexadone" = 1, "corophizine" = 1) + result_amount = 2 + catalysts = list("phoron" = 5) + /datum/chemical_reaction/spaceacillin name = "Spaceacillin" id = "spaceacillin" @@ -1331,6 +1339,7 @@ id = "dough" result = null required_reagents = list("egg" = 3, "flour" = 10) + inhibitors = list("water" = 1, "beer" = 1) //To prevent it messing with batter recipes result_amount = 1 /datum/chemical_reaction/food/dough/on_reaction(var/datum/reagents/holder, var/created_volume) @@ -2619,3 +2628,50 @@ required_reagents = list("radium" = 1, "spidertoxin" = 1, "sifsap" = 1) catalysts = list("sifsap" = 10) result_amount = 2 + +/* +==================== + Aurora Food +==================== +*/ + +/datum/chemical_reaction/coating/batter + name = "Batter" + id = "batter" + result = "batter" + required_reagents = list("egg" = 3, "flour" = 10, "water" = 5, "sodiumchloride" = 2) + result_amount = 20 + +/datum/chemical_reaction/coating/beerbatter + name = "Beer Batter" + id = "beerbatter" + result = "beerbatter" + required_reagents = list("egg" = 3, "flour" = 10, "beer" = 5, "sodiumchloride" = 2) + result_amount = 20 + +/datum/chemical_reaction/browniemix + name = "Brownie Mix" + id = "browniemix" + result = "browniemix" + required_reagents = list("flour" = 5, "coco" = 5, "sugar" = 5) + result_amount = 15 + +/datum/chemical_reaction/butter + name = "Butter" + id = "butter" + result = null + required_reagents = list("cream" = 20, "sodiumchloride" = 1) + result_amount = 1 + +/datum/chemical_reaction/butter/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/spreads/butter(location) + return + +/datum/chemical_reaction/browniemix + name = "Brownie Mix" + id = "browniemix" + result = "browniemix" + required_reagents = list("flour" = 5, "coco" = 5, "sugar" = 5) + result_amount = 15 \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Recipes_vr.dm b/code/modules/reagents/Chemistry-Recipes_vr.dm index 0f52f298463..9a74ec4665e 100644 --- a/code/modules/reagents/Chemistry-Recipes_vr.dm +++ b/code/modules/reagents/Chemistry-Recipes_vr.dm @@ -47,6 +47,9 @@ s.start() holder.clear_reagents() +/////////////////////////////////////////////////////////////////////////////////// +/// Miscellaneous Reactions + /datum/chemical_reaction/xenolazarus name = "Discount Lazarus" id = "discountlazarus" @@ -72,6 +75,9 @@ H.visible_message("[H] twitches for a moment, but remains still.") // no nutriment +/datum/chemical_reaction/foam/softdrink + required_reagents = list("cola" = 1, "mint" = 1) + /////////////////////////////////////////////////////////////////////////////////// /// Vore Drugs @@ -206,10 +212,10 @@ required_reagents = list("whiterussian" = 5, "iron" = 1) result_amount = 6 -/datum/chemical_reaction/drinks/lovepotion - name = "Love Potion" - id = "lovepotion" - result = "lovepotion" +/datum/chemical_reaction/drinks/lovemaker + name = "The Love Maker" + id = "lovemaker" + result = "lovemaker" required_reagents = list("honey" = 1, "sexonthebeach" = 5) result_amount = 6 @@ -269,6 +275,13 @@ required_reagents = list("monstertamer" = 2, "nutriment" = 1) result_amount = 3 +/datum/chemical_reaction/drinks/pink_moo + name = "Pink Moo" + id = "pinkmoo" + result = "pinkmoo" + required_reagents = list("blackrussian" = 2, "berryshake" = 1) + result_amount = 3 + /////////////////////////////////////////////////////////////////////////////////// /// Reagent colonies. /datum/chemical_reaction/meatcolony diff --git a/code/modules/reagents/dispenser/dispenser2.dm b/code/modules/reagents/dispenser/dispenser2.dm index 9663c685296..7f2fb13f404 100644 --- a/code/modules/reagents/dispenser/dispenser2.dm +++ b/code/modules/reagents/dispenser/dispenser2.dm @@ -68,12 +68,12 @@ C.loc = src cartridges[C.label] = C cartridges = sortAssoc(cartridges) - SSnanoui.update_uis(src) + SStgui.update_uis(src) /obj/machinery/chemical_dispenser/proc/remove_cartridge(label) . = cartridges[label] cartridges -= label - SSnanoui.update_uis(src) + SStgui.update_uis(src) /obj/machinery/chemical_dispenser/attackby(obj/item/weapon/W, mob/user) if(W.is_wrench()) @@ -119,25 +119,26 @@ user.drop_from_inventory(RC) RC.loc = src to_chat(user, "You set \the [RC] on \the [src].") - SSnanoui.update_uis(src) // update all UIs attached to src - else return ..() -/obj/machinery/chemical_dispenser/ui_interact(mob/user, ui_key = "main",var/datum/nanoui/ui = null, var/force_open = 1) - if(stat & (BROKEN|NOPOWER)) return - if(user.stat || user.restrained()) return +/obj/machinery/chemical_dispenser/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ChemDispenser", ui_title) // 390, 655 + ui.open() - // this is the data which will be sent to the ui +/obj/machinery/chemical_dispenser/tgui_data(mob/user) var/data[0] data["amount"] = amount data["isBeakerLoaded"] = container ? 1 : 0 data["glass"] = accept_drinking - var beakerD[0] + + var/beakerContents[0] if(container && container.reagents && container.reagents.reagent_list.len) for(var/datum/reagent/R in container.reagents.reagent_list) - beakerD[++beakerD.len] = list("name" = R.name, "volume" = R.volume) - data["beakerContents"] = beakerD + beakerContents.Add(list(list("name" = R.name, "id" = R.id, "volume" = R.volume))) // list in a list because Byond merges the first list... + data["beakerContents"] = beakerContents if(container) data["beakerCurrentVolume"] = container.reagents.total_volume @@ -146,50 +147,59 @@ data["beakerCurrentVolume"] = null data["beakerMaxVolume"] = null - var chemicals[0] + var/chemicals[0] for(var/label in cartridges) var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] - chemicals[++chemicals.len] = list("label" = label, "amount" = C.reagents.total_volume) + chemicals.Add(list(list("title" = label, "id" = label, "amount" = C.reagents.total_volume))) // list in a list because Byond merges the first list... data["chemicals"] = chemicals + return data - // update the ui if it exists, returns null if no ui is passed/found - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "chem_disp.tmpl", ui_title, 390, 680) - ui.set_initial_data(data) - ui.open() +/obj/machinery/chemical_dispenser/tgui_act(action, params) + if(..()) + return TRUE -/obj/machinery/chemical_dispenser/Topic(href, href_list) - if(stat & (NOPOWER|BROKEN)) - return 0 // don't update UIs attached to this object + . = TRUE + switch(action) + if("amount") + amount = clamp(round(text2num(params["amount"]), 1), 0, 120) // round to nearest 1 and clamp 0 - 120 + if("dispense") + var/label = params["reagent"] + if(cartridges[label] && container && container.is_open_container()) + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] + playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1) + C.reagents.trans_to(container, amount) + if("remove") + var/amount = text2num(params["amount"]) + if(!container || !amount) + return + var/datum/reagents/R = container.reagents + var/id = params["reagent"] + if(amount > 0) + R.remove_reagent(id, amount) + else if(amount == -1) // Isolate + R.isolate_reagent(id) + if("ejectBeaker") + if(container) + container.forceMove(get_turf(src)) - if(href_list["amount"]) - amount = round(text2num(href_list["amount"]), 1) // round to nearest 1 - amount = max(0, min(120, amount)) // Since the user can actually type the commands himself, some sanity checking + if(Adjacent(usr)) // So the AI doesn't get a beaker somehow. + usr.put_in_hands(container) - else if(href_list["dispense"]) - var/label = href_list["dispense"] - if(cartridges[label] && container && container.is_open_container()) - var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] - playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1) - C.reagents.trans_to(container, amount) - - else if(href_list["ejectBeaker"]) - if(container) - container.forceMove(get_turf(src)) - - if(Adjacent(usr)) // So the AI doesn't get a beaker somehow. - usr.put_in_hands(container) - - container = null + container = null + else + return FALSE add_fingerprint(usr) - return 1 // update UIs attached to this object -/obj/machinery/chemical_dispenser/attack_ai(mob/user as mob) - src.attack_hand(user) - -/obj/machinery/chemical_dispenser/attack_hand(mob/user as mob) +/obj/machinery/chemical_dispenser/attack_ghost(mob/user) if(stat & BROKEN) return - ui_interact(user) + tgui_interact(user) + +/obj/machinery/chemical_dispenser/attack_ai(mob/user) + attack_hand(user) + +/obj/machinery/chemical_dispenser/attack_hand(mob/user) + if(stat & BROKEN) + return + tgui_interact(user) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index ee24c5b4984..742f89734c5 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -413,3 +413,27 @@ /obj/structure/reagent_dispensers/acid/Initialize() . = ..() reagents.add_reagent("sacid", 1000) + +//Cooking oil refill tank +/obj/structure/reagent_dispensers/cookingoil + name = "cooking oil tank" + desc = "A fifty-litre tank of commercial-grade corn oil, intended for use in large scale deep fryers. Store in a cool, dark place" + icon = 'icons/obj/objects.dmi' + icon_state = "oiltank" + amount_per_transfer_from_this = 120 + +/obj/structure/reagent_dispensers/cookingoil/New() + ..() + reagents.add_reagent("cornoil",5000) + +/obj/structure/reagent_dispensers/cookingoil/bullet_act(var/obj/item/projectile/Proj) + if(Proj.get_structure_damage()) + explode() + +/obj/structure/reagent_dispensers/cookingoil/ex_act() + explode() + +/obj/structure/reagent_dispensers/cookingoil/proc/explode() + reagents.splash_area(get_turf(src), 3) + visible_message(span("danger", "The [src] bursts open, spreading oil all over the area.")) + qdel(src) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index e8eaa809fe5..3437c8b5827 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -212,7 +212,6 @@ // leave the disposal /obj/machinery/disposal/proc/go_out(mob/user) - if (user.client) user.client.eye = user.client.mob user.client.perspective = MOB_PERSPECTIVE @@ -222,11 +221,11 @@ // ai as human but can't flush /obj/machinery/disposal/attack_ai(mob/user as mob) - interact(user, 1) + add_hiddenprint(user) + tgui_interact(user) // human interact with machine /obj/machinery/disposal/attack_hand(mob/user as mob) - if(stat & BROKEN) return @@ -236,91 +235,147 @@ // Clumsy folks can only flush it. if(user.IsAdvancedToolUser(1)) - interact(user, 0) + tgui_interact(user) else flush = !flush update() return // user interaction -/obj/machinery/disposal/interact(mob/user, var/ai=0) +/obj/machinery/disposal/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "DisposalBin") + ui.open() - src.add_fingerprint(user) +/obj/machinery/disposal/tgui_data(mob/user) + var/list/data = list() + + data["isAI"] = isAI(user) + data["flushing"] = flush + data["mode"] = mode + data["pressure"] = round(clamp(100* air_contents.return_pressure() / (SEND_PRESSURE), 0, 100),1) + + return data + +/obj/machinery/disposal/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + if(usr.loc == src) + to_chat(usr, "You cannot reach the controls from inside.") + return TRUE + + if(mode==-1 && action != "eject") // If the mode is -1, only allow ejection + to_chat(usr, "The disposal units power is disabled.") + return TRUE + if(stat & BROKEN) - user.unset_machine() + return TRUE + + add_fingerprint(usr) + + if(flushing) return + + if(isturf(loc)) + if(action == "pumpOn") + mode = 1 + update() + if(action == "pumpOff") + mode = 0 + update() - var/dat = "Waste Disposal UnitWaste Disposal Unit
" + if(!issilicon(usr)) + if(action == "engageHandle") + flush = 1 + update() + if(action == "disengageHandle") + flush = 0 + update() - if(!ai) // AI can't pull flush handle - if(flush) - dat += "Disposal handle: Disengage Engaged" - else - dat += "Disposal handle: Disengaged Engage" + if(action == "eject") + eject() + + return TRUE + - dat += "

Eject contents
" + // src.add_fingerprint(user) + // if(stat & BROKEN) + // user.unset_machine() + // return - if(mode <= 0) - dat += "Pump: Off On
" - else if(mode == 1) - dat += "Pump: Off On (pressurizing)
" - else - dat += "Pump: Off On (idle)
" + // var/dat = "Waste Disposal UnitWaste Disposal Unit
" - var/per = 100* air_contents.return_pressure() / (SEND_PRESSURE) + // if(!ai) // AI can't pull flush handle + // if(flush) + // dat += "Disposal handle: Disengage Engaged" + // else + // dat += "Disposal handle: Disengaged Engage" - dat += "Pressure: [round(per, 1)]%
" + // dat += "

Eject contents
" + + // if(mode <= 0) + // dat += "Pump: Off On
" + // else if(mode == 1) + // dat += "Pump: Off On (pressurizing)
" + // else + // dat += "Pump: Off On (idle)
" + + // var/per = 100* air_contents.return_pressure() / (SEND_PRESSURE) + + // dat += "Pressure: [round(per, 1)]%
" - user.set_machine(src) - user << browse(dat, "window=disposal;size=360x170") - onclose(user, "disposal") + // user.set_machine(src) + // user << browse(dat, "window=disposal;size=360x170") + // onclose(user, "disposal") // handle machine interaction -/obj/machinery/disposal/Topic(href, href_list) - if(usr.loc == src) - to_chat(usr, "You cannot reach the controls from inside.") - return +// /obj/machinery/disposal/Topic(href, href_list) +// if(usr.loc == src) +// to_chat(usr, "You cannot reach the controls from inside.") +// return - if(mode==-1 && !href_list["eject"]) // only allow ejecting if mode is -1 - to_chat(usr, "The disposal units power is disabled.") - return - if(..()) - return +// if(mode==-1 && !href_list["eject"]) // only allow ejecting if mode is -1 +// to_chat(usr, "The disposal units power is disabled.") +// return +// if(..()) +// return - if(stat & BROKEN) - return - if(usr.stat || usr.restrained() || src.flushing) - return +// if(stat & BROKEN) +// return +// if(usr.stat || usr.restrained() || src.flushing) +// return - if(istype(src.loc, /turf)) - usr.set_machine(src) +// if(istype(src.loc, /turf)) +// usr.set_machine(src) - if(href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=disposal") - return +// if(href_list["close"]) +// usr.unset_machine() +// usr << browse(null, "window=disposal") +// return - if(href_list["pump"]) - if(text2num(href_list["pump"])) - mode = 1 - else - mode = 0 - update() +// if(href_list["pump"]) +// if(text2num(href_list["pump"])) +// mode = 1 +// else +// mode = 0 +// update() - if(!isAI(usr)) - if(href_list["handle"]) - flush = text2num(href_list["handle"]) - update() +// if(!isAI(usr)) +// if(href_list["handle"]) +// flush = text2num(href_list["handle"]) +// update() - if(href_list["eject"]) - eject() - else - usr << browse(null, "window=disposal") - usr.unset_machine() - return - return +// if(href_list["eject"]) +// eject() +// else +// usr << browse(null, "window=disposal") +// usr.unset_machine() +// return +// return // eject the contents of the disposal unit /obj/machinery/disposal/proc/eject() diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index 468c7ff6bb1..d0aaebb7d89 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -16,7 +16,7 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid). var/mat_efficiency = 1 var/speed = 1 - materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, MAT_PLASTEEL = 0, "plastic" = 0, MAT_GRAPHITE, "gold" = 0, "silver" = 0, "osmium" = 0, MAT_LEAD = 0, "phoron" = 0, "uranium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0) + materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, MAT_PLASTEEL = 0, "plastic" = 0, MAT_GRAPHITE = 0, "gold" = 0, "silver" = 0, "osmium" = 0, MAT_LEAD = 0, "phoron" = 0, "uranium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0) hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER) diff --git a/code/modules/research/designs/circuits/circuits.dm b/code/modules/research/designs/circuits/circuits.dm index 4717e14bdcb..008d1f486b5 100644 --- a/code/modules/research/designs/circuits/circuits.dm +++ b/code/modules/research/designs/circuits/circuits.dm @@ -493,6 +493,8 @@ CIRCUITS BELOW name = "'Durand' central control" id = "durand_main" req_tech = list(TECH_DATA = 4) + materials = list("glass" = 2000, MAT_GRAPHITE = 1250) + chemicals = list("sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/main sort_string = "NAADA" @@ -500,6 +502,8 @@ CIRCUITS BELOW name = "'Durand' peripherals control" id = "durand_peri" req_tech = list(TECH_DATA = 4) + materials = list("glass" = 2000, MAT_GRAPHITE = 1250) + chemicals = list("sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/peripherals sort_string = "NAADB" @@ -507,6 +511,8 @@ CIRCUITS BELOW name = "'Durand' weapon control and targeting" id = "durand_targ" req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2) + materials = list("glass" = 2000, MAT_GRAPHITE = 1250) + chemicals = list("sacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/targeting sort_string = "NAADC" @@ -583,13 +589,49 @@ CIRCUITS BELOW req_tech = list(TECH_DATA = 4, TECH_BIO = 3) build_path = /obj/item/weapon/circuitboard/aicore sort_string = "XAAAA" +// Cooking Appliances +/datum/design/circuit/microwave + name = "microwave board" + id = "microwave_board" + req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/microwave + sort_string = "HACAM" + +/datum/design/circuit/oven + name = "oven board" + id = "oven_board" + req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/oven + sort_string = "HACAN" + +/datum/design/circuit/fryer + name = "deep fryer board" + id = "fryer_board" + req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/fryer + sort_string = "HACAO" + +/datum/design/circuit/cerealmaker + name = "cereal maker board" + id = "cerealmaker_board" + req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/cerealmaker + sort_string = "HACAP" + +/datum/design/circuit/candymaker + name = "candy machine board" + id = "candymachine_board" + req_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) + build_path = /obj/item/weapon/circuitboard/candymachine + sort_string = "HACAQ" /datum/design/circuit/microwave/advanced name = "deluxe microwave" id = "deluxe microwave" req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 5, TECH_BLUESPACE = 4) build_path = /obj/item/weapon/circuitboard/microwave/advanced - sort_string = "MAAAC" + sort_string = "HACAA" + /datum/design/circuit/shield_generator name = "shield generator" diff --git a/code/modules/research/designs/weapons.dm b/code/modules/research/designs/weapons.dm index 13d6036eddd..f57b2851184 100644 --- a/code/modules/research/designs/weapons.dm +++ b/code/modules/research/designs/weapons.dm @@ -100,14 +100,23 @@ sort_string = "MABBA" /datum/design/item/weapon/ballistic/ammo/stunshell - name = "stun shell" + name = "stun shells" desc = "A stunning shell for a shotgun." id = "stunshell" req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3) materials = list(DEFAULT_WALL_MATERIAL = 4000) - build_path = /obj/item/ammo_casing/a12g/stunshell + build_path = /obj/item/weapon/storage/box/stunshells sort_string = "MABBB" +/datum/design/item/weapon/ballistic/ammo/empshell + name = "emp shells" + desc = "An electromagnetic shell for a shotgun." + id = "empshell" + req_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 3) + materials = list(DEFAULT_WALL_MATERIAL = 4000, MAT_URANIUM = 1000) + build_path = /obj/item/weapon/storage/box/empshells + sort_string = "MABBC" + // Phase weapons /datum/design/item/weapon/phase/AssembleDesignName() diff --git a/code/modules/research/designs/weapons_vr.dm b/code/modules/research/designs/weapons_vr.dm index e55bbd9eb75..9f336be4724 100644 --- a/code/modules/research/designs/weapons_vr.dm +++ b/code/modules/research/designs/weapons_vr.dm @@ -26,7 +26,7 @@ sort_string = "MAAVB" /datum/design/item/weapon/energy/netgun - name = "\'Hunter\' capture gun" + desc = "The \"Varmint Catcher\" is an energy net projector designed to immobilize dangerous wildlife." id = "netgun" req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_MAGNET = 3) materials = list(DEFAULT_WALL_MATERIAL = 6000, "glass" = 3000) @@ -162,4 +162,4 @@ materials = list("unobtanium" = 9001) build_path = /obj/item/ammo_casing/microbattery/combat/final sort_string = "MAVCH" -*/ \ No newline at end of file +*/ diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm index 7316c42179a..8e7f31b7319 100644 --- a/code/modules/research/mechfab_designs.dm +++ b/code/modules/research/mechfab_designs.dm @@ -177,15 +177,15 @@ name = "Durand Chassis" id = "durand_chassis" build_path = /obj/item/mecha_parts/chassis/durand - time = 10 - materials = list(DEFAULT_WALL_MATERIAL = 18750) + time = 20 + materials = list(DEFAULT_WALL_MATERIAL = 18750, MAT_PLASTEEL = 20000) /datum/design/item/mechfab/durand/torso name = "Durand Torso" id = "durand_torso" build_path = /obj/item/mecha_parts/part/durand_torso time = 30 - materials = list(DEFAULT_WALL_MATERIAL = 41250, "glass" = 15000, "silver" = 7500) + materials = list(DEFAULT_WALL_MATERIAL = 41250, MAT_PLASTEEL = 15000, "silver" = 7500) /datum/design/item/mechfab/durand/head name = "Durand Head" @@ -227,7 +227,7 @@ id = "durand_armour" build_path = /obj/item/mecha_parts/part/durand_armour time = 60 - materials = list(DEFAULT_WALL_MATERIAL = 37500, "uranium" = 7500) + materials = list(DEFAULT_WALL_MATERIAL = 27500, MAT_PLASTEEL = 10000, "uranium" = 7500) /datum/design/item/mechfab/janus category = "Janus" @@ -569,9 +569,9 @@ materials = list(DEFAULT_WALL_MATERIAL = 7500, "gold" = 750, "silver" = 1500, "glass" = 3750) build_path = /obj/item/mecha_parts/mecha_equipment/repair_droid -/datum/design/item/mecha/shield_drone - name = "Shield Drone" - desc = "Manual shield drone. Deploys a large, familiar, and rectangular shield in one direction at a time." +/datum/design/item/mecha/combat_shield + name = "linear combat shield" + desc = "Linear shield projector. Deploys a large, familiar, and rectangular shield in one direction at a time." id = "mech_shield_droid" req_tech = list(TECH_PHORON = 3, TECH_MAGNET = 6, TECH_ILLEGAL = 4) materials = list(DEFAULT_WALL_MATERIAL = 8000, "gold" = 2000, "silver" = 3000, "phoron" = 5000, "glass" = 3750) @@ -1038,4 +1038,151 @@ time = 20 req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 5, TECH_PHORON = 3, TECH_MAGNET = 4, TECH_POWER = 6) materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 6000, "silver" = 4000) - \ No newline at end of file + +// Exosuit Internals + +/datum/design/item/mechfab/exointernal + category = "Exosuit Internals" + time = 30 + req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3) + +/datum/design/item/mechfab/exointernal/stan_armor + name = "Armor Plate (Standard)" + category = "Exosuit Internals" + id = "exo_int_armor_standard" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/mecha_parts/component/armor + +/datum/design/item/mechfab/exointernal/light_armor + name = "Armor Plate (Lightweight)" + category = "Exosuit Internals" + id = "exo_int_armor_lightweight" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 3) + materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000) + build_path = /obj/item/mecha_parts/component/armor/lightweight + +/datum/design/item/mechfab/exointernal/reinf_armor + name = "Armor Plate (Reinforced)" + category = "Exosuit Internals" + id = "exo_int_armor_reinforced" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4) + materials = list(DEFAULT_WALL_MATERIAL = 20000, MAT_PLASTEEL = 10000) + build_path = /obj/item/mecha_parts/component/armor/reinforced + +/datum/design/item/mechfab/exointernal/mining_armor + name = "Armor Plate (Blast)" + category = "Exosuit Internals" + id = "exo_int_armor_blast" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4) + materials = list(DEFAULT_WALL_MATERIAL = 20000, MAT_PLASTEEL = 10000) + build_path = /obj/item/mecha_parts/component/armor/mining + +/datum/design/item/mechfab/exointernal/gygax_armor + name = "Armor Plate (Marshal)" + category = "Exosuit Internals" + id = "exo_int_armor_gygax" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_COMBAT = 2) + materials = list(DEFAULT_WALL_MATERIAL = 40000, MAT_DIAMOND = 8000) + build_path = /obj/item/mecha_parts/component/armor/marshal + +/datum/design/item/mechfab/exointernal/darkgygax_armor + name = "Armor Plate (Blackops)" + category = "Exosuit Internals" + id = "exo_int_armor_dgygax" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_COMBAT = 4, TECH_ILLEGAL = 2) + materials = list(MAT_PLASTEEL = 20000, MAT_DIAMOND = 10000, MAT_GRAPHITE = 20000) + build_path = /obj/item/mecha_parts/component/armor/marshal/reinforced + +/datum/design/item/mechfab/exointernal/durand_armour + name = "Armor Plate (Military)" + id = "exo_int_armor_durand" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_COMBAT = 2) + materials = list(DEFAULT_WALL_MATERIAL = 40000, MAT_PLASTEEL = 9525, "uranium" = 8000) + build_path = /obj/item/mecha_parts/component/armor/military + +/datum/design/item/mechfab/exointernal/marauder_armour + name = "Armor Plate (Cutting Edge)" + id = "exo_int_armor_marauder" + req_tech = list(TECH_MATERIAL = 8, TECH_ENGINEERING = 7, TECH_COMBAT = 6, TECH_ILLEGAL = 4) + materials = list(MAT_DURASTEEL = 40000, MAT_GRAPHITE = 8000, MAT_OSMIUM = 8000) + build_path = /obj/item/mecha_parts/component/armor/military/marauder + +/datum/design/item/mechfab/exointernal/phazon_armour + name = "Armor Plate (Janus)" + id = "exo_int_armor_phazon" + req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 6, TECH_COMBAT = 6, TECH_ILLEGAL = 4) + materials = list(MAT_MORPHIUM = 40000, MAT_DURASTEEL = 8000, MAT_OSMIUM = 8000) + build_path = /obj/item/mecha_parts/component/armor/alien + +/datum/design/item/mechfab/exointernal/stan_hull + name = "Hull (Standard)" + category = "Exosuit Internals" + id = "exo_int_hull_standard" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/mecha_parts/component/hull + +/datum/design/item/mechfab/exointernal/durable_hull + name = "Hull (Durable)" + category = "Exosuit Internals" + id = "exo_int_hull_durable" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 8000, MAT_PLASTEEL = 5000) + build_path = /obj/item/mecha_parts/component/hull/durable + +/datum/design/item/mechfab/exointernal/light_hull + name = "Hull (Lightweight)" + category = "Exosuit Internals" + id = "exo_int_hull_light" + req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 4) + materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000) + build_path = /obj/item/mecha_parts/component/hull/lightweight + +/datum/design/item/mechfab/exointernal/stan_gas + name = "Life-Support (Standard)" + category = "Exosuit Internals" + id = "exo_int_lifesup_standard" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/mecha_parts/component/gas + +/datum/design/item/mechfab/exointernal/reinf_gas + name = "Life-Support (Reinforced)" + category = "Exosuit Internals" + id = "exo_int_lifesup_reinforced" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4) + materials = list(DEFAULT_WALL_MATERIAL = 8000, MAT_PLASTEEL = 8000, MAT_GRAPHITE = 1000) + build_path = /obj/item/mecha_parts/component/gas/reinforced + +/datum/design/item/mechfab/exointernal/stan_electric + name = "Electrical Harness (Standard)" + category = "Exosuit Internals" + id = "exo_int_electric_standard" + req_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 1000) + build_path = /obj/item/mecha_parts/component/electrical + +/datum/design/item/mechfab/exointernal/efficient_electric + name = "Electrical Harness (High)" + category = "Exosuit Internals" + id = "exo_int_electric_efficient" + req_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 4, TECH_DATA = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000, MAT_SILVER = 3000) + build_path = /obj/item/mecha_parts/component/electrical/high_current + +/datum/design/item/mechfab/exointernal/stan_actuator + name = "Actuator Lattice (Standard)" + category = "Exosuit Internals" + id = "exo_int_actuator_standard" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/mecha_parts/component/actuator + +/datum/design/item/mechfab/exointernal/hispeed_actuator + name = "Actuator Lattice (Overclocked)" + category = "Exosuit Internals" + id = "exo_int_actuator_overclock" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4) + materials = list(MAT_PLASTEEL = 10000, MAT_OSMIUM = 3000, MAT_GOLD = 5000) + build_path = /obj/item/mecha_parts/component/actuator/hispeed \ No newline at end of file diff --git a/code/modules/research/prosfab_designs_vr.dm b/code/modules/research/prosfab_designs_vr.dm index 02f39bd3075..094d036c91c 100644 --- a/code/modules/research/prosfab_designs_vr.dm +++ b/code/modules/research/prosfab_designs_vr.dm @@ -5,4 +5,11 @@ id = "borg_sizeshift_module" req_tech = list(TECH_BLUESPACE = 3, TECH_MATERIAL = 3, TECH_POWER = 2) materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 4000) - build_path = /obj/item/borg/upgrade/sizeshift \ No newline at end of file + build_path = /obj/item/borg/upgrade/sizeshift + +/datum/design/item/prosfab/robot_upgrade/bellysizeupgrade + name = "Size Alteration Module" + id = "borg_hound_capacity_module" + req_tech = list(TECH_BLUESPACE = 3, TECH_MATERIAL = 3, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 4000) + build_path = /obj/item/borg/upgrade/bellysizeupgrade \ No newline at end of file diff --git a/code/modules/resleeving/computers.dm b/code/modules/resleeving/computers.dm index 535c18c7a6b..e30276eebe3 100644 --- a/code/modules/resleeving/computers.dm +++ b/code/modules/resleeving/computers.dm @@ -1,3 +1,7 @@ +#define MENU_MAIN 1 +#define MENU_BODY 2 +#define MENU_MIND 3 + /obj/machinery/computer/transhuman/resleeving name = "resleeving control console" catalogue_data = list(/datum/category_item/catalogue/information/organization/khi, @@ -7,19 +11,25 @@ light_color = "#315ab4" circuit = /obj/item/weapon/circuitboard/resleeving_control req_access = list(access_heads) //Only used for record deletion right now. - var/list/pods = list() //Linked grower pods. - var/list/spods = list() - var/list/sleevers = list() //Linked resleeving booths. - var/temp = "" - var/menu = 1 //Which menu screen to display + var/list/pods = null //Linked grower pods. + var/list/spods = null + var/list/sleevers = null //Linked resleeving booths. + var/list/temp = null + var/menu = MENU_MAIN //Which menu screen to display var/datum/transhuman/body_record/active_br = null var/datum/transhuman/mind_record/active_mr = null var/organic_capable = 1 var/synthetic_capable = 1 var/obj/item/weapon/disk/transcore/disk + var/obj/machinery/clonepod/transhuman/selected_pod + var/obj/machinery/transhuman/synthprinter/selected_printer + var/obj/machinery/transhuman/resleever/selected_sleever /obj/machinery/computer/transhuman/resleeving/Initialize() . = ..() + pods = list() + spods = list() + sleevers = list() updatemodules() /obj/machinery/computer/transhuman/resleeving/Destroy() @@ -85,9 +95,9 @@ user.unEquip(W) W.forceMove(get_turf(src)) // Drop on top of us active_br = new /datum/transhuman/body_record(brDisk.stored) // Loads a COPY! - menu = 4 to_chat(user, "\The [src] loads the body record from \the [W] before ejecting it.") attack_hand(user) + view_b_rec("view_b_rec", list("ref" = "\ref[active_br]")) else ..() return @@ -103,282 +113,333 @@ return updatemodules() + tgui_interact(user) - ui_interact(user) +/obj/machinery/computer/transhuman/resleeving/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/cloning), + get_asset_datum(/datum/asset/cloning/resleeving), + ) -/obj/machinery/computer/transhuman/resleeving/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/computer/transhuman/resleeving/tgui_interact(mob/user, datum/tgui/ui = null) + if(stat & (NOPOWER|BROKEN)) + return + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ResleevingConsole", "Resleeving Console") + ui.open() + +/obj/machinery/computer/transhuman/resleeving/tgui_data(mob/user) var/data[0] + data["menu"] = menu + + var/list/temppods[0] + for(var/obj/machinery/clonepod/transhuman/pod in pods) + var/status = "idle" + if(pod.mess) + status = "mess" + else if(pod.occupant && !(pod.stat & NOPOWER)) + status = "cloning" + temppods.Add(list(list( + "pod" = "\ref[pod]", + "name" = sanitize(capitalize(pod.name)), + "biomass" = pod.get_biomass(), + "status" = status, + "progress" = (pod.occupant && pod.occupant.stat != DEAD) ? pod.get_completion() : 0 + ))) + data["pods"] = temppods.Copy() + temppods.Cut() + for(var/obj/machinery/transhuman/synthprinter/spod in spods) + temppods.Add(list(list( + "spod" = "\ref[spod]", + "name" = sanitize(capitalize(spod.name)), + "busy" = spod.busy, + "steel" = spod.stored_material[DEFAULT_WALL_MATERIAL], + "glass" = spod.stored_material["glass"] + ))) + data["spods"] = temppods.Copy() + temppods.Cut() + + for(var/obj/machinery/transhuman/resleever/resleever in sleevers) + temppods.Add(list(list( + "sleever" = "\ref[resleever]", + "name" = sanitize(capitalize(resleever.name)), + "occupied" = !!resleever.occupant, + "occupant" = resleever.occupant ? resleever.occupant.real_name : "None" + ))) + data["sleevers"] = temppods.Copy() + temppods.Cut() + + data["coredumped"] = SStranscore.core_dumped + data["emergency"] = disk + data["temp"] = temp + data["selected_pod"] = "\ref[selected_pod]" + data["selected_printer"] = "\ref[selected_printer]" + data["selected_sleever"] = "\ref[selected_sleever]" + var/bodyrecords_list_ui[0] for(var/N in SStranscore.body_scans) var/datum/transhuman/body_record/BR = SStranscore.body_scans[N] bodyrecords_list_ui[++bodyrecords_list_ui.len] = list("name" = N, "recref" = "\ref[BR]") + data["bodyrecords"] = bodyrecords_list_ui var/mindrecords_list_ui[0] for(var/N in SStranscore.backed_up) var/datum/transhuman/mind_record/MR = SStranscore.backed_up[N] mindrecords_list_ui[++mindrecords_list_ui.len] = list("name" = N, "recref" = "\ref[MR]") + data["mindrecords"] = mindrecords_list_ui - var/pods_list_ui[0] - for(var/obj/machinery/clonepod/transhuman/pod in pods) - pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.get_biomass()) + data["modal"] = tgui_modal_data(src) + return data - var/spods_list_ui[0] - for(var/obj/machinery/transhuman/synthprinter/spod in spods) - spods_list_ui[++spods_list_ui.len] = list("spod" = spod, "steel" = spod.stored_material[DEFAULT_WALL_MATERIAL], "glass" = spod.stored_material["glass"]) - - var/sleevers_list_ui[0] - for(var/obj/machinery/transhuman/resleever/resleever in sleevers) - sleevers_list_ui[++sleevers_list_ui.len] = list("sleever" = resleever, "occupant" = resleever.occupant ? resleever.occupant.real_name : "None") - - if(pods) - data["pods"] = pods_list_ui - else - data["pods"] = null - - if(spods) - data["spods"] = spods_list_ui - else - data["spods"] = null - - if(sleevers) - data["sleevers"] = sleevers_list_ui - else - data["pods"] = null - - if(bodyrecords_list_ui.len) - data["bodyrecords"] = bodyrecords_list_ui - else - data["bodyrecords"] = null - - if(mindrecords_list_ui.len) - data["mindrecords"] = mindrecords_list_ui - else - data["mindrecords"] = null - - - if(active_br) - var/can_grow_active = 1 - if(!synthetic_capable && active_br.synthetic) //Disqualified due to being synthetic in an organic only. - can_grow_active = 0 - else if(!organic_capable && !active_br.synthetic) //Disqualified for the opposite. - can_grow_active = 0 - else if(!synthetic_capable && !organic_capable) //What have you done?? - can_grow_active = 0 - else if(active_br.toocomplex) - can_grow_active = 0 - - data["activeBodyRecord"] = list("real_name" = active_br.mydna.name, \ - "speciesname" = active_br.speciesname ? active_br.speciesname : active_br.mydna.dna.species, \ - "gender" = active_br.bodygender, \ - "synthetic" = active_br.synthetic ? "Yes" : "No", \ - "locked" = active_br.locked ? "Low" : "High", \ - "cando" = can_grow_active, - "booc" = active_br.body_oocnotes) - else - data["activeRecord"] = null - - if(active_mr) - var/can_sleeve_current = 1 - if(!sleevers.len) - can_sleeve_current = 0 - data["activeMindRecord"] = list("charname" = active_mr.mindname, \ - "obviously_dead" = active_mr.dead_state == MR_DEAD ? "Past-due" : "Current", \ - "cando" = can_sleeve_current, - "mooc" = active_mr.mind_oocnotes) - else - data["activeMindRecord"] = null - - - data["menu"] = menu - data["podsLen"] = pods.len - data["spodsLen"] = spods.len - data["sleeversLen"] = sleevers.len - data["temp"] = temp - data["coredumped"] = SStranscore.core_dumped - data["emergency"] = disk ? 1 : 0 - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "sleever.tmpl", "Resleeving Control Console", 400, 450) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(5) - -/obj/machinery/computer/transhuman/resleeving/Topic(href, href_list) +/obj/machinery/computer/transhuman/resleeving/tgui_act(action, params) if(..()) - return 1 + return TRUE - else if (href_list["view_brec"]) - active_br = locate(href_list["view_brec"]) - if(active_br && istype(active_br.mydna)) - menu = 4 - else - active_br = null - temp = "ERROR: Record missing." + . = TRUE + switch(tgui_modal_act(src, action, params)) + if(TGUI_MODAL_ANSWER) + // if(params["id"] == "del_rec" && active_record) + // var/obj/item/weapon/card/id/C = usr.get_active_hand() + // if(!istype(C) && !istype(C, /obj/item/device/pda)) + // set_temp("ID not in hand.", "danger") + // return + // if(check_access(C)) + // records.Remove(active_record) + // qdel(active_record) + // set_temp("Record deleted.", "success") + // menu = MENU_RECORDS + // else + // set_temp("Access denied.", "danger") + return - else if (href_list["view_mrec"]) - active_mr = locate(href_list["view_mrec"]) - if(active_mr && istype(active_mr)) - menu = 5 - else - active_mr = null - temp = "ERROR: Record missing." - - else if (href_list["boocnotes"]) - menu = 6 - - else if (href_list["moocnotes"]) - menu = 7 - - else if (href_list["refresh"]) - updateUsrDialog() - - else if (href_list["coredump"]) - if(disk) - SStranscore.core_dump(disk) - sleep(5) - visible_message("\The [src] spits out \the [disk].") + switch(action) + if("view_b_rec") + view_b_rec(action, params) + if("view_m_rec") + var/ref = params["ref"] + if(!length(ref)) + return + active_mr = locate(ref) + if(istype(active_mr)) + if(isnull(active_mr.ckey)) + qdel(active_mr) + set_temp("Error: Record corrupt.", "danger") + else + var/can_sleeve_active = 1 + if(!LAZYLEN(sleevers)) + can_sleeve_active = 0 + set_temp("Error: Cannot sleeve due to no sleevers.", "danger") + if(!selected_sleever) + can_sleeve_active = 0 + set_temp("Error: Cannot sleeve due to no selected sleever.", "danger") + if(selected_sleever && !selected_sleever.occupant) + can_sleeve_active = 0 + set_temp("Error: Cannot sleeve due to lack of sleever occupant.", "danger") + var/list/payload = list( + activerecord = "\ref[active_mr]", + realname = sanitize(active_mr.mindname), + obviously_dead = active_mr.dead_state == MR_DEAD ? "Past-due" : "Current", + oocnotes = active_mr.mind_oocnotes ? active_mr.mind_oocnotes : "None.", + can_sleeve_active = can_sleeve_active, + ) + tgui_modal_message(src, action, "", null, payload) + else + active_mr = null + set_temp("Error: Record missing.", "danger") + if("coredump") + if(disk) + SStranscore.core_dump(disk) + sleep(5) + visible_message("\The [src] spits out \the [disk].") + disk.forceMove(get_turf(src)) + disk = null + if("ejectdisk") disk.forceMove(get_turf(src)) disk = null - else if (href_list["ejectdisk"]) - disk.forceMove(get_turf(src)) - disk = null - - else if (href_list["create"]) - if(istype(active_br)) - //Tried to grow a synth but no synth pods. - if(active_br.synthetic && !spods.len) - temp = "Error: No SynthFabs detected." - //Tried to grow an organic but no growpods. - else if(!active_br.synthetic && !pods.len) - temp = "Error: No growpods detected." - //We have the machines. We can rebuild them. Probably. - else - //We're cloning a synth. - if(active_br.synthetic) - var/obj/machinery/transhuman/synthprinter/spod = spods[1] - if (spods.len > 1) - spod = input(usr,"Select a SynthFab to use", "Printer selection") as anything in spods - - //Already doing someone. - if(spod.busy) - temp = "Error: SynthFab is currently busy." - - //Not enough steel or glass - else if(spod.stored_material[DEFAULT_WALL_MATERIAL] < spod.body_cost) - temp = "Error: Not enough [DEFAULT_WALL_MATERIAL] in SynthFab." - else if(spod.stored_material["glass"] < spod.body_cost) - temp = "Error: Not enough glass in SynthFab." - - //Gross pod (broke mid-cloning or something). - else if(spod.broken) - temp = "Error: SynthFab malfunction." - - //Do the cloning! - else if(spod.print(active_br)) - temp = "Initiating printing cycle..." - menu = 1 - else - temp = "Initiating printing cycle...
Error: Post-initialisation failed. Printing cycle aborted." - - //We're cloning an organic. + if("create") + if(istype(active_br)) + //Tried to grow a synth but no synth pods. + if(active_br.synthetic && !spods.len) + set_temp("Error: No SynthFabs detected.", "danger") + //Tried to grow an organic but no growpods. + else if(!active_br.synthetic && !pods.len) + set_temp("Error: No growpods detected.", "danger") + //We have the machines. We can rebuild them. Probably. else - var/obj/machinery/clonepod/transhuman/pod = pods[1] - if (pods.len > 1) - pod = input(usr,"Select a growing pod to use", "Pod selection") as anything in pods + //We're cloning a synth. + if(active_br.synthetic) + var/obj/machinery/transhuman/synthprinter/spod = selected_printer + if(!istype(spod)) + set_temp("Error: No SynthFab selected.", "danger") + return - //Already doing someone. - if(pod.occupant) - temp = "Error: Growpod is currently occupied." + //Already doing someone. + if(spod.busy) + set_temp("Error: SynthFab is currently busy.", "danger") + return - //Not enough materials. - else if(pod.get_biomass() < CLONE_BIOMASS) - temp = "Error: Not enough biomass." + //Not enough steel or glass + else if(spod.stored_material[DEFAULT_WALL_MATERIAL] < spod.body_cost) + set_temp("Error: Not enough [DEFAULT_WALL_MATERIAL] in SynthFab.", "danger") + return + else if(spod.stored_material["glass"] < spod.body_cost) + set_temp("Error: Not enough glass in SynthFab.", "danger") + return - //Gross pod (broke mid-cloning or something). - else if(pod.mess) - temp = "Error: Growpod malfunction." + //Gross pod (broke mid-cloning or something). + else if(spod.broken) + set_temp("Error: SynthFab malfunction.", "danger") + return - //Disabled in config. - else if(!config.revival_cloning) - temp = "Error: Unable to initiate growing cycle." + //Do the cloning! + else if(spod.print(active_br)) + set_temp("Initiating printing cycle...", "success") + menu = 1 + else + set_temp("Initiating printing cycle... Error: Post-initialisation failed. Printing cycle aborted.", "danger") + return - //Do the cloning! - else if(pod.growclone(active_br)) - temp = "Initiating growing cycle..." - menu = 1 + //We're cloning an organic. else - temp = "Initiating growing cycle...
Error: Post-initialisation failed. Growing cycle aborted." + var/obj/machinery/clonepod/transhuman/pod = selected_pod + if(!istype(pod)) + set_temp("Error: No clonepod selected.", "danger") + tgui_modal_clear(src) + return - //The body record is broken somehow. - else - temp = "Error: Data corruption." + //Already doing someone. + if(pod.occupant) + set_temp("Error: Growpod is currently occupied.", "danger") + tgui_modal_clear(src) + return - else if (href_list["sleeve"]) - if(istype(active_mr)) - if(!sleevers.len) - temp = "Error: No sleevers detected." + //Not enough materials. + else if(pod.get_biomass() < CLONE_BIOMASS) + set_temp("Error: Not enough biomass.", "danger") + tgui_modal_clear(src) + return + + //Gross pod (broke mid-cloning or something). + else if(pod.mess) + set_temp("Error: Growpod malfunction.", "danger") + tgui_modal_clear(src) + return + + //Disabled in config. + else if(!config.revival_cloning) + set_temp("Error: Unable to initiate growing cycle.", "danger") + tgui_modal_clear(src) + return + + //Do the cloning! + else if(pod.growclone(active_br)) + set_temp("Initiating growing cycle...", "success") + tgui_modal_clear(src) + else + set_temp("Initiating growing cycle... Error: Post-initialisation failed. Growing cycle aborted.", "danger") + tgui_modal_clear(src) + return + + //The body record is broken somehow. else - var/mode = text2num(href_list["sleeve"]) - var/override - var/obj/machinery/transhuman/resleever/sleever = sleevers[1] - if (sleevers.len > 1) - sleever = input(usr,"Select a resleeving pod to use", "Resleever selection") as anything in sleevers + set_temp("Error: Data corruption.", "danger") + tgui_modal_clear(src) + return - switch(mode) - if(1) //Body resleeving - //No body to sleeve into. - if(!sleever.occupant) - temp = "Error: Resleeving pod is not occupied." + if("sleeve") + if(istype(active_mr)) + if(!sleevers.len) + set_temp("Error: No sleevers detected.", "danger") + else + var/mode = text2num(params["mode"]) + var/override + var/obj/machinery/transhuman/resleever/sleever = selected_sleever + if(!istype(sleever)) + set_temp("Error: No resleeving pod selected.", "danger") + tgui_modal_clear(src) + return - //OOC body lock thing. - if(sleever.occupant.resleeve_lock && active_mr.ckey != sleever.occupant.resleeve_lock) - temp = "Error: Mind incompatible with body." + switch(mode) + if(1) //Body resleeving + //No body to sleeve into. + if(!sleever.occupant) + set_temp("Error: Resleeving pod is not occupied.", "danger") + tgui_modal_clear(src) + return - var/list/subtargets = list() - for(var/mob/living/carbon/human/H in sleever.occupant) - if(H.resleeve_lock && active_mr.ckey != H.resleeve_lock) - continue - subtargets += H - if(subtargets.len) - var/oc_sanity = sleever.occupant - override = input(usr,"Multiple bodies detected. Select target for resleeving of [active_mr.mindname] manually. Sleeving of primary body is unsafe with sub-contents, and is not listed.", "Resleeving Target") as null|anything in subtargets - if(!override || oc_sanity != sleever.occupant || !(override in sleever.occupant)) - temp = "Error: Target selection aborted." + //OOC body lock thing. + if(sleever.occupant.resleeve_lock && active_mr.ckey != sleever.occupant.resleeve_lock) + set_temp("Error: Mind incompatible with body.", "danger") + tgui_modal_clear(src) + return - if(2) //Card resleeving - if(sleever.sleevecards <= 0) - temp = "Error: No available cards in resleever." + var/list/subtargets = list() + for(var/mob/living/carbon/human/H in sleever.occupant) + if(H.resleeve_lock && active_mr.ckey != H.resleeve_lock) + continue + subtargets += H + if(subtargets.len) + var/oc_sanity = sleever.occupant + override = input(usr,"Multiple bodies detected. Select target for resleeving of [active_mr.mindname] manually. Sleeving of primary body is unsafe with sub-contents, and is not listed.", "Resleeving Target") as null|anything in subtargets + if(!override || oc_sanity != sleever.occupant || !(override in sleever.occupant)) + set_temp("Error: Target selection aborted.", "danger") + tgui_modal_clear(src) + return - //Body to sleeve into, but mind is in another living body. - if(active_mr.mind_ref.current && active_mr.mind_ref.current.stat < DEAD) //Mind is in a body already that's alive - var/answer = alert(active_mr.mind_ref.current,"Someone is attempting to restore a backup of your mind. Do you want to abandon this body, and move there? You MAY suffer memory loss! (Same rules as CMD apply)","Resleeving","No","Yes") + if(2) //Card resleeving + if(sleever.sleevecards <= 0) + set_temp("Error: No available cards in resleever.", "danger") + tgui_modal_clear(src) + return - //They declined to be moved. - if(answer == "No") - temp = "Initiating resleeving...
Error: Post-initialisation failed. Resleeving cycle aborted." - menu = 1 + //Body to sleeve into, but mind is in another living body. + if(active_mr.mind_ref.current && active_mr.mind_ref.current.stat < DEAD) //Mind is in a body already that's alive + var/answer = alert(active_mr.mind_ref.current,"Someone is attempting to restore a backup of your mind. Do you want to abandon this body, and move there? You MAY suffer memory loss! (Same rules as CMD apply)","Resleeving","No","Yes") - //They were dead, or otherwise available. - if(!temp) + //They declined to be moved. + if(answer == "No") + set_temp("Initiating resleeving... Error: Post-initialisation failed. Resleeving cycle aborted.", "danger") + tgui_modal_clear(src) + return TRUE + + //They were dead, or otherwise available. sleever.putmind(active_mr,mode,override) - temp = "Initiating resleeving..." - menu = 1 + set_temp("Initiating resleeving...") + tgui_modal_clear(src) - //IDK but it broke somehow. + if("refresh") + SStgui.update_uis(src) + if("selectpod") + var/ref = params["ref"] + if(!length(ref)) + return + var/obj/machinery/clonepod/selected = locate(ref) + if(istype(selected) && (selected in pods)) + selected_pod = selected + if("selectprinter") + var/ref = params["ref"] + if(!length(ref)) + return + var/obj/machinery/transhuman/synthprinter/selected = locate(ref) + if(istype(selected) && (selected in spods)) + selected_printer = selected + if("selectsleever") + var/ref = params["ref"] + if(!length(ref)) + return + var/obj/machinery/transhuman/resleever/selected = locate(ref) + if(istype(selected) && (selected in sleevers)) + selected_sleever = selected + if("menu") + menu = clamp(text2num(params["num"]), MENU_MAIN, MENU_MIND) + if("cleartemp") + temp = null else - temp = "Error: Data corruption." - - else if (href_list["menu"]) - menu = href_list["menu"] - temp = "" - - SSnanoui.update_uis(src) - add_fingerprint(usr) + return FALSE // In here because only relevant to computer /obj/item/weapon/cmo_disk_holder @@ -409,3 +470,53 @@ item_state = "card-id" w_class = ITEMSIZE_SMALL var/datum/transhuman/mind_record/list/stored = list() + +/** + * Sets a temporary message to display to the user + * + * Arguments: + * * text - Text to display, null/empty to clear the message from the UI + * * style - The style of the message: (color name), info, success, warning, danger + */ +/obj/machinery/computer/transhuman/resleeving/proc/set_temp(text = "", style = "info", update_now = FALSE) + temp = list(text = text, style = style) + if(update_now) + SStgui.update_uis(src) + +/obj/machinery/computer/transhuman/resleeving/proc/view_b_rec(action, params) + var/ref = params["ref"] + if(!length(ref)) + return + active_br = locate(ref) + if(istype(active_br)) + var/can_grow_active = 1 + if(!synthetic_capable && active_br.synthetic) //Disqualified due to being synthetic in an organic only. + can_grow_active = 0 + set_temp("Error: Cannot grow [active_br.mydna.name] due to lack of synthfabs.", "danger") + else if(!organic_capable && !active_br.synthetic) //Disqualified for the opposite. + can_grow_active = 0 + set_temp("Error: Cannot grow [active_br.mydna.name] due to lack of cloners.", "danger") + else if(!synthetic_capable && !organic_capable) //What have you done?? + can_grow_active = 0 + set_temp("Error: Cannot grow [active_br.mydna.name] due to lack of synthfabs and cloners.", "danger") + else if(active_br.toocomplex) + can_grow_active = 0 + set_temp("Error: Cannot grow [active_br.mydna.name] due to species complexity.", "danger") + var/list/payload = list( + activerecord = "\ref[active_br]", + realname = sanitize(active_br.mydna.name), + species = active_br.speciesname ? active_br.speciesname : active_br.mydna.dna.species, + sex = active_br.bodygender, + mind_compat = active_br.locked ? "Low" : "High", + synthetic = active_br.synthetic, + oocnotes = active_br.body_oocnotes ? active_br.body_oocnotes : "None", + can_grow_active = can_grow_active, + ) + tgui_modal_message(src, action, "", null, payload) + else + active_br = null + set_temp("Error: Record missing.", "danger") + +#undef MENU_MAIN +#undef MENU_BODY +#undef MENU_MIND \ No newline at end of file diff --git a/code/modules/resleeving/designer.dm b/code/modules/resleeving/designer.dm index 3e2aa57aab8..c09aec2aac6 100644 --- a/code/modules/resleeving/designer.dm +++ b/code/modules/resleeving/designer.dm @@ -1,6 +1,12 @@ // Little define makes it cleaner to read the tripple color values out of mobs. #define MOB_HEX_COLOR(M, V) "#[num2hex(M.r_##V, 2)][num2hex(M.g_##V, 2)][num2hex(M.b_##V, 2)]" +#define MENU_MAIN "Main" +#define MENU_BODYRECORDS "Body Records" +#define MENU_STOCKRECORDS "Stock Records" +#define MENU_SPECIFICRECORD "Specific Record" +#define MENU_OOCNOTES "OOC Notes" + /obj/machinery/computer/transhuman/designer name = "body design console" catalogue_data = list(/datum/category_item/catalogue/information/organization/khi, @@ -12,16 +18,41 @@ circuit = /obj/item/weapon/circuitboard/body_designer req_access = list(access_medical) // Used for loading people's designs var/temp = "" - var/menu = 1 //Which menu screen to display + var/menu = MENU_MAIN //Which menu screen to display var/datum/transhuman/body_record/active_br = null - var/icon/preview_icon = null + //Mob preview + var/map_name + var/obj/screen/south_preview = null + var/obj/screen/east_preview = null + var/obj/screen/west_preview = null // Mannequins are somewhat expensive to create, so cache it var/mob/living/carbon/human/dummy/mannequin/mannequin = null var/obj/item/weapon/disk/body_record/disk = null +/obj/machinery/computer/transhuman/designer/Initialize() + . = ..() + map_name = "transhuman_designer_[REF(src)]_map" + + south_preview = new + south_preview.name = "" + south_preview.assigned_map = map_name + south_preview.del_on_map_removal = FALSE + south_preview.screen_loc = "[map_name]:1,1" + + east_preview = new + east_preview.name = "" + east_preview.assigned_map = map_name + east_preview.del_on_map_removal = FALSE + east_preview.screen_loc = "[map_name]:2,1" + + west_preview = new + west_preview.name = "" + west_preview.assigned_map = map_name + west_preview.del_on_map_removal = FALSE + west_preview.screen_loc = "[map_name]:0,1" + /obj/machinery/computer/transhuman/designer/Destroy() active_br = null - preview_icon = null mannequin = null disk = null return ..() @@ -50,15 +81,24 @@ add_fingerprint(user) if(inoperable()) return - ui_interact(user) + tgui_interact(user) -/obj/machinery/computer/transhuman/designer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - // log_debug("designer.ui_interact([user], force_open = [force_open])") - user.set_machine(src) +/obj/machinery/computer/transhuman/designer/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + give_client_previews(user.client) + ui = new(user, src, "BodyDesigner", name) + ui.open() - var/data[0] +/obj/machinery/computer/transhuman/designer/tgui_static_data(mob/user) + var/list/data = ..() + data["mapRef"] = map_name + return data - if(menu == "2") +/obj/machinery/computer/transhuman/designer/tgui_data(mob/user) + var/list/data = list() + + if(menu == MENU_BODYRECORDS) var/bodyrecords_list_ui[0] for(var/N in SStranscore.body_scans) var/datum/transhuman/body_record/BR = SStranscore.body_scans[N] @@ -66,7 +106,7 @@ if(bodyrecords_list_ui.len) data["bodyrecords"] = bodyrecords_list_ui - if(menu == "3") + if(menu == MENU_STOCKRECORDS) var/stock_bodyrecords_list_ui[0] for (var/N in GLOB.all_species) var/datum/species/S = GLOB.all_species[N] @@ -86,11 +126,6 @@ "booc" = active_br.body_oocnotes, "styles" = list() ) - if(!preview_icon) - update_preview_icon() - force_open = 1 // Force a refresh to send the new image - data["previewIconUrl"] = "body_preview_icon.png" - user << browse_rsc(preview_icon, "body_preview_icon.png") var/list/styles = data["activeBodyRecord"]["styles"] var/list/temp @@ -98,6 +133,12 @@ temp = list("styleHref" = "ear_style", "style" = "Normal") if(mannequin.ear_style) temp["style"] = mannequin.ear_style.name + if(mannequin.ear_style.do_colouration) + temp["color"] = MOB_HEX_COLOR(mannequin, ears) + temp["colorHref"] = "ear_color" + if(mannequin.ear_style.extra_overlay) + temp["color2"] = MOB_HEX_COLOR(mannequin, ears2) + temp["colorHref2"] = "ear_color2" styles["Ears"] = temp temp = list("styleHref" = "tail_style", "style" = "Normal") @@ -106,6 +147,9 @@ if(mannequin.tail_style.do_colouration) temp["color"] = MOB_HEX_COLOR(mannequin, tail) temp["colorHref"] = "tail_color" + if(mannequin.tail_style.extra_overlay) + temp["color2"] = MOB_HEX_COLOR(mannequin, tail2) + temp["colorHref2"] = "tail_color2" styles["Tail"] = temp temp = list("styleHref" = "wing_style", "style" = "Normal") @@ -114,6 +158,9 @@ if(mannequin.wing_style.do_colouration) temp["color"] = MOB_HEX_COLOR(mannequin, wing) temp["colorHref"] = "wing_color" + if(mannequin.wing_style.extra_overlay) + temp["color2"] = MOB_HEX_COLOR(mannequin, wing2) + temp["colorHref2"] = "wing_color2" styles["Wing"] = temp temp = list("styleHref" = "hair_style", "style" = mannequin.h_style) @@ -143,74 +190,74 @@ data["disk"] = disk ? 1 : 0 data["diskStored"] = disk && disk.stored ? 1 : 0 - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "body_designer.tmpl", "Body Design Console", 400, 600) - ui.set_initial_data(data) - ui.open() + return data -/obj/machinery/computer/transhuman/designer/Topic(href, href_list) +/obj/machinery/computer/transhuman/designer/tgui_act(action, params) if(..()) - return 1 + return TRUE - else if(href_list["debug_load_my_body"]) - active_br = new /datum/transhuman/body_record(usr, FALSE, FALSE) - preview_icon = null + switch(action) + if("debug_load_my_body") + active_br = new /datum/transhuman/body_record(usr, FALSE, FALSE) + update_preview_icon() + menu = MENU_SPECIFICRECORD - else if (href_list["view_brec"]) - var/datum/transhuman/body_record/BR = locate(href_list["view_brec"]) - if(BR && istype(BR.mydna)) - if(allowed(usr) || BR.ckey == usr.ckey) - active_br = new /datum/transhuman/body_record(BR) // Load a COPY! - preview_icon = null - menu = 4 + if("view_brec") + var/datum/transhuman/body_record/BR = locate(params["view_brec"]) + if(BR && istype(BR.mydna)) + if(allowed(usr) || BR.ckey == usr.ckey) + active_br = new /datum/transhuman/body_record(BR) // Load a COPY! + update_preview_icon() + menu = MENU_SPECIFICRECORD + else + active_br = null + temp = "Access denied: Body records are confidential." else active_br = null - temp = "Access denied: Body records are confidential." - else - active_br = null - temp = "ERROR: Record missing." + temp = "ERROR: Record missing." - else if(href_list["view_stock_brec"]) - var/datum/species/S = GLOB.all_species[href_list["view_stock_brec"]] - if(S && (S.spawn_flags & (SPECIES_IS_WHITELISTED|SPECIES_CAN_JOIN)) == SPECIES_CAN_JOIN) - // Generate body record from species! - mannequin = new(null, S.name) - mannequin.real_name = "Stock [S.name] Body" - mannequin.name = mannequin.real_name - mannequin.dna.real_name = mannequin.real_name - active_br = new(mannequin, FALSE, FALSE) - active_br.speciesname = "Custom Sleeve" - preview_icon = null - menu = 4 - else - active_br = null - temp = "ERROR: Stock Record missing." + if("view_stock_brec") + var/datum/species/S = GLOB.all_species[params["view_stock_brec"]] + if(S && (S.spawn_flags & (SPECIES_IS_WHITELISTED|SPECIES_CAN_JOIN)) == SPECIES_CAN_JOIN) + // Generate body record from species! + mannequin = new(null, S.name) + mannequin.real_name = "Stock [S.name] Body" + mannequin.name = mannequin.real_name + mannequin.dna.real_name = mannequin.real_name + active_br = new(mannequin, FALSE, FALSE) + active_br.speciesname = "Custom Sleeve" + update_preview_icon() + menu = MENU_SPECIFICRECORD + else + active_br = null + temp = "ERROR: Stock Record missing." - else if (href_list["boocnotes"]) - menu = 6 + if("boocnotes") + menu = MENU_OOCNOTES - else if (href_list["loadfromdisk"]) - if(disk && disk.stored) - active_br = new /datum/transhuman/body_record(disk.stored) // Loads a COPY! - preview_icon = null + if("loadfromdisk") + if(disk && disk.stored) + active_br = new /datum/transhuman/body_record(disk.stored) // Loads a COPY! + update_preview_icon() + menu = MENU_SPECIFICRECORD - else if (href_list["savetodisk"]) - if(disk && active_br) - disk.stored = new /datum/transhuman/body_record(active_br) // Saves a COPY! - disk.name = "[initial(disk.name)] ([active_br.mydna.name])" + if("savetodisk") + if(disk && active_br) + disk.stored = new /datum/transhuman/body_record(active_br) // Saves a COPY! + disk.name = "[initial(disk.name)] ([active_br.mydna.name])" + disk.forceMove(get_turf(src)) + disk = null + + if("ejectdisk") disk.forceMove(get_turf(src)) disk = null - else if (href_list["ejectdisk"]) - disk.forceMove(get_turf(src)) - disk = null - - else if (href_list["menu"]) - menu = href_list["menu"] - temp = "" - else - OnTopic(href, href_list, usr) + if("menu") + menu = params["menu"] + temp = "" + + if("href_conversion") + PrefHrefMiddleware(params, usr) add_fingerprint(usr) return 1 // Return 1 to refresh UI @@ -226,24 +273,27 @@ mannequin.delete_inventory(TRUE) update_preview_mob(mannequin) + COMPILE_OVERLAYS(mannequin) + + var/mutable_appearance/MA = new(mannequin) + south_preview.appearance = MA + south_preview.dir = SOUTH + south_preview.screen_loc = "[map_name]:1,1" + south_preview.name = "" + east_preview.appearance = MA + east_preview.dir = EAST + east_preview.screen_loc = "[map_name]:2,1" + east_preview.name = "" + west_preview.appearance = MA + west_preview.dir = WEST + west_preview.screen_loc = "[map_name]:0,1" + west_preview.name = "" - preview_icon = icon('icons/effects/effects.dmi', "nothing") - preview_icon.Scale(48+32, 16+32) +/obj/machinery/computer/transhuman/designer/proc/give_client_previews(client/C) + C.register_map_obj(south_preview) + C.register_map_obj(east_preview) + C.register_map_obj(west_preview) - mannequin.dir = NORTH - var/icon/stamp = getFlatIcon(mannequin) - preview_icon.Blend(stamp, ICON_OVERLAY, 25, 17) - - mannequin.dir = WEST - stamp = getFlatIcon(mannequin) - preview_icon.Blend(stamp, ICON_OVERLAY, 1, 9) - - mannequin.dir = SOUTH - stamp = getFlatIcon(mannequin) - preview_icon.Blend(stamp, ICON_OVERLAY, 49, 1) - - preview_icon.Scale(preview_icon.Width() * 2, preview_icon.Height() * 2) // Scaling here to prevent blurring in the browser. - return preview_icon /obj/machinery/computer/transhuman/designer/proc/update_preview_mob(var/mob/living/carbon/human/H) ASSERT(!QDELETED(H)) @@ -306,15 +356,15 @@ // Problem is, those procs save their data to /datum/preferences, not a body_record. // Luckily the procs to convert from body_record to /datum/preferences and back already exist. // Its ugly, but I think its still better than duplicating and maintaining all that code. -/obj/machinery/computer/transhuman/designer/proc/OnTopic(var/href,var/list/href_list, var/mob/user) - if(!mannequin || !preview_icon || !active_br) +/obj/machinery/computer/transhuman/designer/proc/PrefHrefMiddleware(list/params, var/mob/user) + if(!mannequin || !active_br) return - if(href_list["size_multiplier"]) + if(params["target_href"] == "size_multiplier") var/new_size = input(user, "Choose your character's size, ranging from 25% to 200%", "Character Preference") as num|null if(new_size && ISINRANGE(new_size,25,200)) active_br.sizemult = (new_size/100) - preview_icon = null + update_preview_icon() return 1 // The black magic horror show begins @@ -338,26 +388,30 @@ var/datum/category_item/player_setup_item/vore/ears/E = CG.items_by_name["Appearance"] ASSERT(istype(E)) - if(href_list["bio_gender"]) + if(params["target_href"] == "bio_gender") var/new_gender = input(user, "Choose your character's biological gender:", "Character Preference", active_br.bodygender) as null|anything in G.get_genders() if(new_gender) active_br.bodygender = new_gender active_br.mydna.dna.SetUIState(DNA_UI_GENDER, new_gender!=MALE, 1) - preview_icon = null + update_preview_icon() return 1 + var/href_list = list() + href_list["src"] = "\ref[src]" + href_list["[params["target_href"]]"] = params["target_value"] + var/action = 0 - action = B.OnTopic(href, href_list, user) + action = B.OnTopic(list2params(href_list), href_list, user) if(action & TOPIC_UPDATE_PREVIEW && mannequin && active_br) B.copy_to_mob(mannequin) active_br.mydna.dna.ResetUIFrom(mannequin) - preview_icon = null + update_preview_icon() return 1 - action = E.OnTopic(href, href_list, user) + action = E.OnTopic(list2params(href_list), href_list, user) if(action & TOPIC_UPDATE_PREVIEW && mannequin && active_br) E.copy_to_mob(mannequin) active_br.mydna.dna.ResetUIFrom(mannequin) - preview_icon = null + update_preview_icon() return 1 // Fake subtype of preferences we can use to steal code from player_setup diff --git a/code/modules/resleeving/infomorph.dm b/code/modules/resleeving/infomorph.dm index 45c5d4193b3..7fd716bc96f 100644 --- a/code/modules/resleeving/infomorph.dm +++ b/code/modules/resleeving/infomorph.dm @@ -417,7 +417,7 @@ var/list/infomorph_emotions = list( desc = "Modify the settings on your integrated radio." if(radio) - radio.ui_interact(src,"main",null,1,conscious_state) + radio.tgui_interact(src) else to_chat(src, "You don't have a radio!") diff --git a/code/modules/resleeving/machines.dm b/code/modules/resleeving/machines.dm index d6505931146..706a70bedcf 100644 --- a/code/modules/resleeving/machines.dm +++ b/code/modules/resleeving/machines.dm @@ -162,6 +162,11 @@ return +/obj/machinery/clonepod/transhuman/get_completion() + if(occupant) + return 100 * ((occupant.health + abs(config.health_threshold_dead)) / (occupant.maxHealth + abs(config.health_threshold_dead))) + return 0 + //Synthetic version /obj/machinery/transhuman/synthprinter name = "SynthFab 3000" @@ -437,28 +442,40 @@ sickness_duration = (45 - (total_rating-4)*1.875) MINUTES // 45 minutes default, 30 minutes with max non-anomaly upgrades, 15 minutes with max anomaly ones /obj/machinery/transhuman/resleever/attack_hand(mob/user as mob) - user.set_machine(src) - var/health_text = "" - var/mind_text = "" - if(src.occupant) - if(src.occupant.stat >= DEAD) - health_text = "DEAD" - else if(src.occupant.health < 0) - health_text = "[round(src.occupant.health,0.1)]" - else - health_text = "[round(src.occupant.health,0.1)]" + tgui_interact(user) - if(src.occupant.mind) - mind_text = "Mind present: [occupant.mind.name]" - else - mind_text = "Mind absent." +/obj/machinery/transhuman/resleever/tgui_interact(mob/user, datum/tgui/ui = null) + if(stat & (NOPOWER|BROKEN)) + return - var/dat ="Resleever Status
" - dat +="Current occupant: [src.occupant ? "
Name: [src.occupant]
Health: [health_text]
" : "None"]
" - dat +="Mind status: [mind_text]
" - user.set_machine(src) - user << browse(dat, "window=resleever") - onclose(user, "resleever") + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ResleevingPod", "Resleever") + ui.open() + +/obj/machinery/transhuman/resleever/tgui_data(mob/user) + var/list/data = list() + + data["occupied"] = !!occupant + if(occupant) + data["name"] = occupant.name + data["health"] = occupant.health + data["maxHealth"] = occupant.maxHealth + data["stat"] = occupant.stat + data["mindStatus"] = !!occupant.mind + data["mindName"] = occupant.mind?.name + + if(occupant.has_modifier_of_type(/datum/modifier/resleeving_sickness) || occupant.has_modifier_of_type(/datum/modifier/faux_resleeving_sickness)) + data["resleeveSick"] = TRUE + else + data["resleeveSick"] = FALSE + + if(occupant.confused || occupant.eye_blurry) + data["initialSick"] = TRUE + else + data["initialSick"] = FALSE + + return data /obj/machinery/transhuman/resleever/attackby(obj/item/W as obj, mob/user as mob) src.add_fingerprint(user) diff --git a/code/modules/shieldgen/shield_capacitor.dm b/code/modules/shieldgen/shield_capacitor.dm index 2ef3f17a85f..d76a18045a4 100644 --- a/code/modules/shieldgen/shield_capacitor.dm +++ b/code/modules/shieldgen/shield_capacitor.dm @@ -18,6 +18,7 @@ use_power = USE_POWER_OFF //doesn't use APC power var/charge_rate = 100000 //100 kW var/obj/machinery/shield_gen/owned_gen + interact_offline = TRUE /obj/machinery/shield_capacitor/advanced name = "advanced shield capacitor" @@ -67,36 +68,30 @@ /obj/machinery/shield_capacitor/attack_hand(mob/user) if(stat & (BROKEN)) return - interact(user) + tgui_interact(user) -/obj/machinery/shield_capacitor/interact(mob/user) - if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN)) ) - if (!istype(user, /mob/living/silicon)) - user.unset_machine() - user << browse(null, "window=shield_capacitor") - return - var/t = "Shield Capacitor Control Console

" - if(locked) - t += "Swipe your ID card to begin." - else - t += "This capacitor is: [active ? "Online" : "Offline" ] [active ? "\[Deactivate\]" : "\[Activate\]"]
" - t += "Capacitor Status: [time_since_fail > 2 ? "OK." : "Discharging!"]
" - t += "Stored Energy: [format_SI(stored_charge, "J")] ([100 * round(stored_charge/max_charge, 0.01)]%)
" - t += "Charge Rate: \ - \[----\] \ - \[---\] \ - \[--\] \ - \[-\][format_SI(charge_rate, "W")]\ - \[+\] \ - \[++\] \ - \[+++\] \ - \[++++\]
" - t += "
" - t += "Refresh " - t += "Close
" +/obj/machinery/shield_capacitor/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ShieldCapacitor", name) + ui.open() - user << browse(t, "window=shield_capacitor;size=500x400") - user.set_machine(src) +/obj/machinery/shield_capacitor/tgui_status(mob/user) + if(stat & BROKEN) + return STATUS_CLOSE + return ..() + +/obj/machinery/shield_capacitor/tgui_data(mob/user) + var/list/data = list() + + data["active"] = active + data["time_since_fail"] = time_since_fail + data["stored_charge"] = stored_charge + data["max_charge"] = max_charge + data["charge_rate"] = charge_rate + data["max_charge_rate"] = max_charge_rate + + return data /obj/machinery/shield_capacitor/process() if (!anchored) @@ -119,21 +114,20 @@ time_since_fail = 0 //losing charge faster than we can draw from PN last_stored_charge = stored_charge -/obj/machinery/shield_capacitor/Topic(href, href_list[]) - ..() - if( href_list["close"] ) - usr << browse(null, "window=shield_capacitor") - usr.unset_machine() - return - if( href_list["toggle"] ) - if(!active && !anchored) - to_chat(usr, "The [src] needs to be firmly secured to the floor first.") - return - active = !active - if( href_list["charge_rate"] ) - charge_rate = between(10000, charge_rate + text2num(href_list["charge_rate"]), max_charge_rate) +/obj/machinery/shield_capacitor/tgui_act(action, params) + if(..()) + return TRUE - updateDialog() + switch(action) + if("toggle") + if(!active && !anchored) + to_chat(usr, "The [src] needs to be firmly secured to the floor first.") + return + active = !active + . = TRUE + if("charge_rate") + charge_rate = clamp(text2num(params["rate"]), 10000, max_charge_rate) + . = TRUE /obj/machinery/shield_capacitor/power_change() if(stat & BROKEN) diff --git a/code/modules/shieldgen/shield_gen.dm b/code/modules/shieldgen/shield_gen.dm index cdd16d24294..b87f66432fe 100644 --- a/code/modules/shieldgen/shield_gen.dm +++ b/code/modules/shieldgen/shield_gen.dm @@ -23,6 +23,7 @@ var/energy_conversion_rate = 0.0006 //how many renwicks per watt? Higher numbers equals more effiency. var/z_range = 0 // How far 'up and or down' to extend the shield to, in z-levels. Only works on MultiZ supported z-levels. use_power = USE_POWER_OFF //doesn't use APC power + interact_offline = TRUE // don't check stat & NOPOWER|BROKEN for our UI. We check BROKEN ourselves. var/id //for button usage /obj/machinery/shield_gen/advanced @@ -95,59 +96,50 @@ /obj/machinery/shield_gen/attack_hand(mob/user) if(stat & (BROKEN)) return - interact(user) + tgui_interact(user) -/obj/machinery/shield_gen/interact(mob/user) - if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN)) ) - if (!istype(user, /mob/living/silicon)) - user.unset_machine() - user << browse(null, "window=shield_generator") - return - var/t = "Shield Generator Control Console

" - if(locked) - t += "Swipe your ID card to begin." - else - t += "[capacitors.len ? "Charge capacitor(s) connected." : "Unable to locate charge capacitor!"]
" - var/i = 0 - for(var/obj/machinery/shield_capacitor/capacitor in capacitors) - i++ - t += "Capacitor #[i]: [capacitor.active ? "Online." : "Offline."] \ - Charge: [round(capacitor.stored_charge/1000, 0.1)] kJ ([100 * round(capacitor.stored_charge/capacitor.max_charge, 0.01)]%) \ - Status: [capacitor.time_since_fail > 2 ? "OK." : "Discharging!"]
" - t += "This generator is: [active ? "Online" : "Offline" ] [active ? "\[Deactivate\]" : "\[Activate\]"]
" - t += "Field Status: [time_since_fail > 2 ? "Stable" : "Unstable"]
" - t += "Coverage Radius (restart required): \ - --- \ - -- \ - - \ - [field_radius] m \ - + \ - ++ \ - +++
" - if(HasAbove(src.z) || HasBelow(src.z)) // Won't show up on maps lacking MultiZ support. - t += "Vertical Shielding (restart required): \ - - \ - [z_range] Vertical Range \ - +
" - t += "Overall Field Strength: [round(average_field_strength, 0.01)] Renwick ([target_field_strength ? round(100 * average_field_strength / target_field_strength, 0.1) : "NA"]%)
" - t += "Upkeep Power: [format_SI(round(field.len * max(average_field_strength * dissipation_rate, min_dissipation) / energy_conversion_rate), "W")]
" - t += "Charge Rate: -- \ - [strengthen_rate] Renwick/s \ - ++
" - t += "Shield Generation Power: [format_SI(round(field.len * min(strengthen_rate, target_field_strength - average_field_strength) / energy_conversion_rate), "W")]
" - t += "Maximum Field Strength: \ - \[min\] \ - -- \ - - \ - [target_field_strength] Renwick \ - + \ - ++ \ - \[max\]
" - t += "
" - t += "Refresh " - t += "Close
" - user << browse(t, "window=shield_generator;size=500x400") - user.set_machine(src) +/obj/machinery/shield_gen/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ShieldGenerator", name) + ui.open() + +/obj/machinery/shield_gen/tgui_status(mob/user) + if(stat & BROKEN) + return STATUS_CLOSE + return ..() + +/obj/machinery/shield_gen/tgui_data(mob/user) + var/list/data = list() + + data["locked"] = locked + data["lockedData"] = list() + if(!locked) + data["lockedData"]["capacitors"] = list() + for(var/obj/machinery/shield_capacitor/C in capacitors) + data["lockedData"]["capacitors"].Add(list(list( + "active" = C.active, + "stored_charge" = C.stored_charge, + "max_charge" = C.max_charge, + "failing" = (C.time_since_fail <= 2), + ))) + + data["lockedData"]["active"] = active + data["lockedData"]["failing"] = (time_since_fail <= 2) + data["lockedData"]["radius"] = field_radius + data["lockedData"]["max_radius"] = max_field_radius + data["lockedData"]["z_range"] = z_range + data["lockedData"]["max_z_range"] = 10 + data["lockedData"]["average_field_strength"] = average_field_strength + data["lockedData"]["target_field_strength"] = target_field_strength + data["lockedData"]["max_field_strength"] = max_field_strength + data["lockedData"]["shields"] = LAZYLEN(field) + data["lockedData"]["upkeep"] = round(field.len * max(average_field_strength * dissipation_rate, min_dissipation) / energy_conversion_rate) + data["lockedData"]["strengthen_rate"] = strengthen_rate + data["lockedData"]["max_strengthen_rate"] = max_strengthen_rate + data["lockedData"]["gen_power"] = round(field.len * min(strengthen_rate, target_field_strength - average_field_strength) / energy_conversion_rate) + + return data /obj/machinery/shield_gen/process() if (!anchored && active) @@ -206,30 +198,32 @@ else average_field_strength = 0 -/obj/machinery/shield_gen/Topic(href, href_list[]) - ..() - if( href_list["close"] ) - usr << browse(null, "window=shield_generator") - usr.unset_machine() - return - else if( href_list["toggle"] ) - if (!active && !anchored) - to_chat(usr, "The [src] needs to be firmly secured to the floor first.") - return - toggle() - else if( href_list["change_radius"] ) - field_radius = between(0, field_radius + text2num(href_list["change_radius"]), max_field_radius) - else if( href_list["strengthen_rate"] ) - strengthen_rate = between(0, strengthen_rate + text2num(href_list["strengthen_rate"]), max_strengthen_rate) - else if( href_list["target_field_strength"] ) - target_field_strength = between(1, target_field_strength + text2num(href_list["target_field_strength"]), max_field_strength) - else if( href_list["z_range"] ) - z_range = between(0, z_range + text2num(href_list["z_range"]), 10) // Max is extending ten z-levels up and down. Probably too big of a number but it shouldn't matter. +/obj/machinery/shield_gen/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("toggle") + if (!active && !anchored) + to_chat(usr, "The [src] needs to be firmly secured to the floor first.") + return + toggle() + . = TRUE + if("change_radius") + field_radius = clamp(text2num(params["val"]), 0, max_field_radius) + . = TRUE + if("strengthen_rate") + strengthen_rate = clamp(text2num(params["val"]), 0, max_strengthen_rate) + . = TRUE + if("target_field_strength") + target_field_strength = clamp(text2num(params["val"]), 1, max_field_strength) + . = TRUE + if("z_range") + z_range = clamp(text2num(params["val"]), 0, 10) + . = TRUE - updateDialog() /obj/machinery/shield_gen/ex_act(var/severity) - if(active) toggle() return ..() diff --git a/code/modules/shuttles/escape_pods.dm b/code/modules/shuttles/escape_pods.dm index 245b96e82e4..b1d3efdc0c7 100644 --- a/code/modules/shuttles/escape_pods.dm +++ b/code/modules/shuttles/escape_pods.dm @@ -46,73 +46,58 @@ name = "escape pod controller" program = /datum/computer/file/embedded_program/docking/simple var/datum/shuttle/autodock/ferry/escape_pod/pod + valid_actions = list("toggle_override", "force_door") -/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/tgui_data(mob/user) var/datum/computer/file/embedded_program/docking/simple/docking_program = program // Cast to proper type - data = list( + . = list( "docking_status" = docking_program.get_docking_status(), "override_enabled" = docking_program.override_enabled, - "door_state" = docking_program.memory["door_status"]["state"], - "door_lock" = docking_program.memory["door_status"]["lock"], + "exterior_status" = docking_program.memory["door_status"], "can_force" = pod.can_force() || (emergency_shuttle.departed && pod.can_launch()), //allow players to manually launch ahead of time if the shuttle leaves - "is_armed" = pod.arming_controller.armed, + "armed" = pod.arming_controller.armed, + "internalTemplateName" = "EscapePodConsole", ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - - if (!ui) - ui = new(user, src, ui_key, "escape_pod_console.tmpl", name, 470, 290) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/Topic(href, href_list) - if((. = ..())) - return - - if("manual_arm") - pod.arming_controller.arm() - return TOPIC_REFRESH - if("force_launch") - if (pod.can_force()) - pod.force_launch(src) - else if (emergency_shuttle.departed && pod.can_launch()) //allow players to manually launch ahead of time if the shuttle leaves - pod.launch(src) - return TOPIC_REFRESH - return 0 +/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/tgui_act(action, params) + if(..()) + return TRUE + switch(action) + if("manual_arm") + pod.arming_controller.arm() + . = TRUE + if("force_launch") + if(pod.can_force()) + pod.force_launch(src) + else if(emergency_shuttle.departed && pod.can_launch()) //allow players to manually launch ahead of time if the shuttle leaves + pod.launch(src) + . = TRUE //This controller is for the escape pod berth (station side) /obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth name = "escape pod berth controller" program = /datum/computer/file/embedded_program/docking/simple/escape_pod_berth + valid_actions = list("toggle_override", "force_door") -/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] +/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/tgui_data(mob/user) var/datum/computer/file/embedded_program/docking/simple/docking_program = program // Cast to proper type var/armed = null - if (istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod_berth)) + if(istype(docking_program, /datum/computer/file/embedded_program/docking/simple/escape_pod_berth)) var/datum/computer/file/embedded_program/docking/simple/escape_pod_berth/P = docking_program armed = P.armed - data = list( + . = list( "docking_status" = docking_program.get_docking_status(), "override_enabled" = docking_program.override_enabled, + "exterior_status" = docking_program.memory["door_status"], "armed" = armed, + "internalTemplateName" = "EscapePodBerthConsole", ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - - if (!ui) - ui = new(user, src, ui_key, "escape_pod_berth_console.tmpl", name, 470, 290) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - /obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth/emag_act(var/remaining_charges, var/mob/user) if (!emagged) to_chat(user, "You emag the [src], arming the escape pod!") diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 276af95ce87..acbc8655dc0 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -119,6 +119,8 @@ max_duration = 100 /datum/surgery_step/cavity/place_item/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(!istype(tool)) + return 0 if(..()) var/obj/item/organ/external/affected = target.get_organ(target_zone) if(istype(user,/mob/living/silicon/robot)) diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm index 391b83fe0c9..9ed0ce520da 100644 --- a/code/modules/surgery/limb_reattach.dm +++ b/code/modules/surgery/limb_reattach.dm @@ -28,6 +28,8 @@ max_duration = 70 /datum/surgery_step/limb/attach/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(!istype(tool)) + return 0 var/obj/item/organ/external/E = tool var/obj/item/organ/external/P = target.organs_by_name[E.parent_organ] var/obj/item/organ/external/affected = target.get_organ(target_zone) @@ -117,7 +119,7 @@ max_duration = 100 /datum/surgery_step/limb/mechanize/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) - if(..()) + if(..() && istype(tool)) var/obj/item/robot_parts/p = tool if (p.part) if (!(target_zone in p.part)) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index c09d10bebe6..a6a9a87386f 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -164,6 +164,9 @@ if (!..()) return 0 + if(!istype(tool)) + return 0 + var/obj/item/organ/external/affected = target.get_organ(target_zone) if(!(affected && !(affected.robotic >= ORGAN_ROBOT))) @@ -227,6 +230,9 @@ if (!..()) return 0 + if(!istype(tool)) + return 0 + target.op_stage.current_organ = null var/list/removable_organs = list() @@ -281,7 +287,7 @@ var/obj/item/organ/internal/O = tool var/obj/item/organ/external/affected = target.get_organ(target_zone) - if(!affected) + if(!affected || !istype(O)) return var/organ_compatible @@ -361,6 +367,9 @@ if (!..()) return 0 + if(!istype(tool)) + return 0 + target.op_stage.current_organ = null var/list/removable_organs = list() @@ -417,6 +426,9 @@ if (!..()) return 0 + if(!istype(tool)) + return 0 + target.op_stage.current_organ = null var/list/removable_organs = list() diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 0f59be6a2bf..da306fab045 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -467,8 +467,8 @@ target.languages = M.brainmob.languages spawn(0) //Name yourself on your own damn time - var/new_name = target.name - while(!new_name && target.client) + var/new_name = target.real_name + while(target.client) if(!target) return var/try_name = input(target,"Pick a name for your new form!", "New Name", target.name) var/clean_name = sanitizeName(try_name, allow_numbers = TRUE) @@ -477,6 +477,7 @@ if(okay == "Ok") new_name = clean_name + new_name = sanitizeName(new_name, allow_numbers = TRUE) target.name = new_name target.real_name = target.name diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm index 80ab93043b7..2857d022a92 100644 --- a/code/modules/tables/tables.dm +++ b/code/modules/tables/tables.dm @@ -328,6 +328,15 @@ var/list/table_icon_cache = list() qdel(src) return shards +/obj/structure/table/can_visually_connect_to(var/obj/structure/S) + if(istype(S,/obj/structure/table/bench) && !istype(src,/obj/structure/table/bench)) + return FALSE + if(istype(src,/obj/structure/table/bench) && !istype(S,/obj/structure/table/bench)) + return FALSE + if(istype(S,/obj/structure/table)) + return TRUE + ..() + /proc/get_table_image(var/icon/ticon,var/ticonstate,var/tdir,var/tcolor,var/talpha) var/icon_cache_key = "\ref[ticon]-[ticonstate]-[tdir]-[tcolor]-[talpha]" var/image/I = table_icon_cache[icon_cache_key] diff --git a/code/modules/tgui/external.dm b/code/modules/tgui/external.dm new file mode 100644 index 00000000000..19f039869e3 --- /dev/null +++ b/code/modules/tgui/external.dm @@ -0,0 +1,192 @@ +/** + * tgui external + * + * Contains all external tgui declarations. + */ + +/** + * public + * + * Used to open and update UIs. + * If this proc is not implemented properly, the UI will not update correctly. + * + * required user mob The mob who opened/is using the UI. + * optional ui datum/tgui The UI to be updated, if it exists. + * optional parent_ui datum/tgui A parent UI that, when closed, closes this UI as well. + */ + +/datum/proc/tgui_interact(mob/user, datum/tgui/ui = null, datum/tgui/parent_ui = null) + return FALSE // Not implemented. + +/** + * public + * + * Data to be sent to the UI. + * This must be implemented for a UI to work. + * + * required user mob The mob interacting with the UI. + * + * return list Data to be sent to the UI. + */ +/datum/proc/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + return list() // Not implemented. + +/** + * public + * + * Static Data to be sent to the UI. + * Static data differs from normal data in that it's large data that should be + * sent infrequently. This is implemented optionally for heavy uis that would + * be sending a lot of redundant data frequently. Gets squished into one + * object on the frontend side, but the static part is cached. + * + * required user mob The mob interacting with the UI. + * + * return list Statuic Data to be sent to the UI. + */ +/datum/proc/tgui_static_data(mob/user) + return list() + +/** + * public + * + * Forces an update on static data. Should be done manually whenever something + * happens to change static data. + * + * required user the mob currently interacting with the ui + * optional ui ui to be updated + */ +/datum/proc/update_tgui_static_data(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + // If there was no ui to update, there's no static data to update either. + if(!ui) + ui = SStgui.get_open_ui(user, src) + if(ui) + ui.send_full_update() + +/** + * public + * + * Called on a UI when the UI receieves a href. + * Think of this as Topic(). + * + * required action string The action/button that has been invoked by the user. + * required params list A list of parameters attached to the button. + * + * return bool If the UI should be updated or not. + */ +/datum/proc/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + // If UI is not interactive or usr calling Topic is not the UI user, bail. + if(!ui || ui.status != STATUS_INTERACTIVE) + return TRUE + +/** + * public + * + * Called on an object when a tgui object is being created, allowing you to + * push various assets to tgui, for examples spritesheets. + * + * return list List of asset datums or file paths. + */ +/datum/proc/ui_assets(mob/user) + return list() + +/** + * private + * + * The UI's host object (usually src_object). + * This allows modules/datums to have the UI attached to them, + * and be a part of another object. + */ +/datum/proc/tgui_host(mob/user) + return src // Default src. + +/** + * private + * + * The UI's state controller to be used for created uis + * This is a proc over a var for memory reasons + */ +/datum/proc/tgui_state(mob/user) + return GLOB.tgui_default_state + +/** + * global + * + * Associative list of JSON-encoded shared states that were set by + * tgui clients. + */ + +/datum/var/list/tgui_shared_states + +/** + * global + * + * Tracks open UIs for a user. + */ +/mob/var/list/tgui_open_uis = list() + +/** + * global + * + * Tracks open windows for a user. + */ +/client/var/list/tgui_windows = list() + +/** + * public + * + * Called on a UI's object when the UI is closed, not to be confused with + * client/verb/uiclose(), which closes the ui window + */ +/datum/proc/tgui_close(mob/user) + +/** + * verb + * + * Called by UIs when they are closed. + * Must be a verb so winset() can call it. + * + * required uiref ref The UI that was closed. + */ +/client/verb/tguiclose(window_id as text) + // Name the verb, and hide it from the user panel. + set name = "uiclose" + set hidden = TRUE + + var/mob/user = src && src.mob + if(!user) + return + // Close all tgui datums based on window_id. + SStgui.force_close_window(user, window_id) + +/** + * Middleware for /client/Topic. + * + * return bool Whether the topic is passed (TRUE), or cancelled (FALSE). + */ +/proc/tgui_Topic(href_list) + // Skip non-tgui topics + if(!href_list["tgui"]) + return TRUE + var/type = href_list["type"] + // Unconditionally collect tgui logs + if(type == "log") + log_tgui(usr, href_list["message"]) + // Locate window + var/window_id = href_list["window_id"] + var/datum/tgui_window/window + if(window_id) + window = usr.client.tgui_windows[window_id] + if(!window) + log_tgui(usr, "Error: Couldn't find the window datum, force closing.") + SStgui.force_close_window(usr, window_id) + return FALSE + // Decode payload + var/payload + if(href_list["payload"]) + payload = json_decode(href_list["payload"]) + // Pass message to window + if(window) + window.on_message(type, payload, href_list) + return FALSE diff --git a/code/modules/tgui/modal.dm b/code/modules/tgui/modal.dm new file mode 100644 index 00000000000..5fb4c4cc743 --- /dev/null +++ b/code/modules/tgui/modal.dm @@ -0,0 +1,370 @@ +/** + * tgui modals + * + * Allows creation of modals within tgui. + */ + +GLOBAL_LIST(tgui_modals) + +/** + * Call this from a proc that is called in tgui_act() to process modal actions + * + * Example: /obj/machinery/chem_master/proc/tgui_act_modal + * You can then switch based on the return value and show different + * modals depending on the answer. + * Arguments: + * * source - The source datum + * * action - The called action + * * params - The params to the action + */ +/datum/proc/tgui_modal_act(datum/source = src, action = "", params) + ASSERT(istype(source)) + + . = null + switch(action) + if("modal_open") // Params: id, arguments + return TGUI_MODAL_OPEN + if("modal_answer") // Params: id, answer, arguments + params["answer"] = tgui_modal_preprocess_answer(source, params["answer"]) + if(tgui_modal_answer(source, params["id"], params["answer"])) // If there's a current modal with a delegate that returned TRUE, no need to continue + . = TGUI_MODAL_DELEGATE + else + . = TGUI_MODAL_ANSWER + tgui_modal_clear(source) + if("modal_close") // Params: id + tgui_modal_clear(source) + return TGUI_MODAL_CLOSE + +/** + * Call this from tgui_data() to return modal information if needed + + * Arguments: + * * source - The source datum + */ +/datum/proc/tgui_modal_data(datum/source = src) + ASSERT(istype(source)) + + var/datum/tgui_modal/current = LAZYACCESS(GLOB.tgui_modals, REF(source)) + if(!current) + return null + + return current.to_data() + +/** + * Clears the current modal for a given datum + * + * Arguments: + * * source - The source datum + */ +/datum/proc/tgui_modal_clear(datum/source = src) + ASSERT(istype(source)) + + LAZYINITLIST(GLOB.tgui_modals) + var/datum/tgui_modal/previous = GLOB.tgui_modals[REF(source)] + if(!previous) + return FALSE + + for(var/i in 1 to length(GLOB.tgui_modals)) + var/key = GLOB.tgui_modals[i] + if(previous == GLOB.tgui_modals[key]) + GLOB.tgui_modals.Cut(i, i + 1) + break + + SStgui.update_uis(source) + return TRUE + +/** + * Opens a message TGUI modal + * + * Arguments: + * * source - The source datum + * * id - The ID of the modal + * * text - The text to display above the answers + * * delegate - The proc to call when closed + * * arguments - List of arguments passed to and from JS (mostly useful for chaining modals) + */ +/datum/proc/tgui_modal_message(datum/source = src, id, text = "Default modal message", delegate, arguments) + ASSERT(length(id)) + + var/datum/tgui_modal/modal = new(id, text, delegate, arguments) + return tgui_modal_new(source, modal) + +/** + * Opens a text input TGUI modal + * + * Arguments: + * * source - The source datum + * * id - The ID of the modal + * * text - The text to display above the answers + * * delegate - The proc to call when submitted + * * arguments - List of arguments passed to and from JS (mostly useful for chaining modals) + * * value - The default value of the input + * * max_length - The maximum char length of the input + */ +/datum/proc/tgui_modal_input(datum/source = src, id, text = "Default modal message", delegate, arguments, value = "", max_length = TGUI_MODAL_INPUT_MAX_LENGTH) + ASSERT(length(id)) + ASSERT(max_length > 0) + + var/datum/tgui_modal/input/modal = new(id, text, delegate, arguments, value, max_length) + return tgui_modal_new(source, modal) + +/** + * Opens a dropdown input TGUI modal + * + * Internally checks if the answer is in the list of choices. + * Arguments: + * * source - The source datum + * * id - The ID of the modal + * * text - The text to display above the answers + * * delegate - The proc to call when submitted + * * arguments - List of arguments passed to and from JS (mostly useful for chaining modals) + * * value - The default value of the dropdown + * * choices - The list of available choices in the dropdown + */ +/datum/proc/tgui_modal_choice(datum/source = src, id, text = "Default modal message", delegate, arguments, value = "", choices) + ASSERT(length(id)) + + var/datum/tgui_modal/input/choice/modal = new(id, text, delegate, arguments, value, choices) + return tgui_modal_new(source, modal) + +/** + * Opens a bento input TGUI modal + * + * Internally checks if the answer is in the list of choices. + * Arguments: + * * source - The source datum + * * id - The ID of the modal + * * text - The text to display above the answers + * * delegate - The proc to call when submitted + * * arguments - List of arguments passed to and from JS (mostly useful for chaining modals) + * * value - The default value of the bento + * * choices - The list of available choices in the bento + */ +/datum/proc/tgui_modal_bento(datum/source = src, id, text = "Default modal message", delegate, arguments, value, choices) + ASSERT(length(id)) + + var/datum/tgui_modal/input/bento/modal = new(id, text, delegate, arguments, value, choices) + return tgui_modal_new(source, modal) + +/** + * Opens a yes/no TGUI modal + * + * Arguments: + * * source - The source datum + * * id - The ID of the modal + * * text - The text to display above the answers + * * delegate - The proc to call when "Yes" is pressed + * * delegate_no - The proc to call when "No" is pressed + * * arguments - List of arguments passed to and from JS (mostly useful for chaining modals) + * * yes_text - The text to show in the "Yes" button + * * no_text - The text to show in the "No" button + */ +/datum/proc/tgui_modal_boolean(datum/source = src, id, text = "Default modal message", delegate, delegate_no, arguments, yes_text = "Yes", no_text = "No") + ASSERT(length(id)) + + var/datum/tgui_modal/boolean/modal = new(id, text, delegate, delegate_no, arguments, yes_text, no_text) + return tgui_modal_new(source, modal) + +/** + * Registers a given modal to a source. Private. + * + * Arguments: + * * source - The source datum + * * modal - The datum/tgui_modal to register + * * replace_previous - Whether any modal currently assigned to source should be replaced + * * instant_update - Whether the changes should reflect immediately + */ +/datum/proc/tgui_modal_new(datum/source = src, datum/tgui_modal/modal = null, replace_previous = TRUE, instant_update = TRUE) + ASSERT(istype(source)) + ASSERT(istype(modal)) + + var/datum/tgui_modal/previous = LAZYACCESS(GLOB.tgui_modals, REF(source)) + if(previous && !replace_previous) + return FALSE + + modal.owning_source = source + + // Previous one should get GC'd + LAZYSET(GLOB.tgui_modals, REF(source), modal) + if(instant_update) + SStgui.update_uis(source) + return TRUE + +/** + * Calls the source's currently assigned modal's (if there is one) on_answer() proc. Private. + * + * Arguments: + * * source - The source datum + * * id - The ID of the modal + * * answer - The provided answer + */ +/datum/proc/tgui_modal_answer(datum/source = src, id, answer = "") + ASSERT(istype(source)) + + var/datum/tgui_modal/current = LAZYACCESS(GLOB.tgui_modals, REF(source)) + if(!current) + return FALSE + + return current.on_answer(answer) + +/** + * Passes an answer from JS through the modal's proc. + * + * Used namely for cutting the text short if it's longer + * than an input modal's max_length. + * Arguments: + * * source - The source datum + * * answer - The provided answer + */ +/datum/proc/tgui_modal_preprocess_answer(datum/source = src, answer = "") + ASSERT(istype(source)) + + var/datum/tgui_modal/current = LAZYACCESS(GLOB.tgui_modals, REF(source)) + if(!current) + return answer + + return current.preprocess_answer(answer) + +/** + * Modal datum (contains base information for a modal) + */ +/datum/tgui_modal + var/datum/owning_source + var/id + var/text + var/delegate + var/list/arguments + var/modal_type = "message" + +/datum/tgui_modal/New(id, text, delegate, list/arguments) + src.id = id + src.text = text + src.delegate = delegate + src.arguments = arguments + +/** + * Called when it's time to pre-process the answer before using it + * + * Arguments: + * * answer - The answer, a nullable text + */ +/datum/tgui_modal/proc/preprocess_answer(answer) + return reject_bad_text(answer, TGUI_MODAL_INPUT_MAX_LENGTH) // bleh + +/** + * Called when a modal receives an answer + * + * Arguments: + * * answer - The answer, a nullable text + */ +/datum/tgui_modal/proc/on_answer(answer) + if(delegate) + return call(owning_source, delegate)(answer, arguments) + return FALSE + +/** + * Creates a list that describes a modal visually to be passed to JS + */ +/datum/tgui_modal/proc/to_data() + . = list() + .["id"] = id + .["text"] = text + .["args"] = arguments || list() + .["type"] = modal_type + +/** + * Input modal - has a text entry that can be used to enter an answer + */ +/datum/tgui_modal/input + modal_type = "input" + var/value + var/max_length + +/datum/tgui_modal/input/New(id, text, delegate, list/arguments, value, max_length) + ..(id, text, delegate, arguments) + src.value = value + src.max_length = max_length + +/datum/tgui_modal/input/preprocess_answer(answer) + . = ..(answer) + if(length(answer) > max_length) + . = copytext(., 1, max_length + 1) + +/datum/tgui_modal/input/to_data() + . = ..() + .["value"] = value + +/** + * Choice modal - has a dropdown menu that can be used to select an answer + */ +/datum/tgui_modal/input/choice + modal_type = "choice" + var/choices + +/datum/tgui_modal/input/choice/New(id, text, delegate, list/arguments, value, choices) + ..(id, text, delegate, arguments, value, TGUI_MODAL_INPUT_MAX_LENGTH) // Max length doesn't really matter in dropdowns, but whatever + src.choices = choices + +/datum/tgui_modal/input/choice/on_answer(answer) + if(answer in choices) // Make sure the answer is actually in our choices! + return ..(answer, arguments) + return FALSE + +/datum/tgui_modal/input/choice/to_data() + . = ..() + .["choices"] = choices + +/** + * Bento modal - Similar to choice, it displays the choices in a grid of images + * + * The returned answer is the index of the choice. + */ +/datum/tgui_modal/input/bento + modal_type = "bento" + var/choices + +/datum/tgui_modal/input/bento/New(id, text, delegate, list/arguments, value, choices) + ..(id, text, delegate, arguments, text2num(value), TGUI_MODAL_INPUT_MAX_LENGTH) // Max length doesn't really matter in here, but whatever + src.choices = choices + +/datum/tgui_modal/input/bento/preprocess_answer(answer) + return text2num(answer) || 0 + +/datum/tgui_modal/input/bento/on_answer(answer) + if(answer >= 1 && answer <= length(choices)) // Make sure the answer index is actually in our indexes! + return ..(answer, arguments) + return FALSE + +/datum/tgui_modal/input/bento/to_data() + . = ..() + .["choices"] = choices + +/** + * Boolean modal - has yes/no buttons that do different actions depending on which is pressed + */ +/datum/tgui_modal/boolean + modal_type = "boolean" + var/delegate_no + var/yes_text + var/no_text + +/datum/tgui_modal/boolean/New(id, text, delegate, delegate_no, list/arguments, yes_text, no_text) + ..(id, text, delegate, arguments) + src.delegate_no = delegate_no + src.yes_text = yes_text + src.no_text = no_text + +/datum/tgui_modal/boolean/preprocess_answer(answer) + return text2num(answer) || FALSE + +/datum/tgui_modal/boolean/on_answer(answer) + if(answer) + return ..(answer, arguments) + else if(delegate_no) + return call(owning_source, delegate_no)(arguments) + return FALSE + +/datum/tgui_modal/boolean/to_data() + . = ..() + .["yes_text"] = yes_text + .["no_text"] = no_text diff --git a/code/modules/tgui/modules/_base.dm b/code/modules/tgui/modules/_base.dm new file mode 100644 index 00000000000..cefe49230f8 --- /dev/null +++ b/code/modules/tgui/modules/_base.dm @@ -0,0 +1,115 @@ +/* +TGUI MODULES + +This allows for datum-based TGUIs that can be hooked into objects. +This is useful for things such as the power monitor, which needs to exist on a physical console in the world, but also as a virtual device the AI can use + +Code is pretty much ripped verbatim from nano modules, but with un-needed stuff removed +*/ +/datum/tgui_module + var/name + var/datum/host + var/list/using_access + + var/tgui_id + var/ntos = FALSE + +/datum/tgui_module/New(var/host) + src.host = host + if(ntos) + tgui_id = "Ntos" + tgui_id + +/datum/tgui_module/tgui_host() + return host ? host.tgui_host() : src + +/datum/tgui_module/tgui_close(mob/user) + if(host) + host.tgui_close(user) + +/datum/tgui_module/proc/can_still_topic(mob/user, datum/tgui_state/state) + return (tgui_status(user, state) == STATUS_INTERACTIVE) + +/datum/tgui_module/proc/check_access(mob/user, access) + if(!access) + return 1 + + if(using_access) + if(access in using_access) + return 1 + else + return 0 + + if(!istype(user)) + return 0 + + var/obj/item/weapon/card/id/I = user.GetIdCard() + if(!I) + return 0 + + if(access in I.access) + return 1 + + return 0 + +/datum/tgui_module/tgui_static_data() + . = ..() + + var/obj/item/modular_computer/host = tgui_host() + if(istype(host)) + . += host.get_header_data() + +/datum/tgui_module/tgui_act(action, params) + if(..()) + return TRUE + + var/obj/item/modular_computer/host = tgui_host() + if(istype(host)) + if(action == "PC_exit") + host.kill_program() + return TRUE + if(action == "PC_shutdown") + host.shutdown_computer() + return TRUE + if(action == "PC_minimize") + host.minimize_program(usr) + return TRUE + +// Just a nice little default interact in case the subtypes don't need any special behavior here +/datum/tgui_module/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, tgui_id, name) + ui.open() + +// This is a helper for anything that wants to render the map. +/datum/tgui_module/proc/get_plane_masters() + . = list() + // 'Utility' planes + . += new /obj/screen/plane_master/fullbright //Lighting system (lighting_overlay objects) + . += new /obj/screen/plane_master/lighting //Lighting system (but different!) + . += new /obj/screen/plane_master/ghosts //Ghosts! + . += new /obj/screen/plane_master{plane = PLANE_AI_EYE} //AI Eye! + + . += new /obj/screen/plane_master{plane = PLANE_CH_STATUS} //Status is the synth/human icon left side of medhuds + . += new /obj/screen/plane_master{plane = PLANE_CH_HEALTH} //Health bar + . += new /obj/screen/plane_master{plane = PLANE_CH_LIFE} //Alive-or-not icon + . += new /obj/screen/plane_master{plane = PLANE_CH_ID} //Job ID icon + . += new /obj/screen/plane_master{plane = PLANE_CH_WANTED} //Wanted status + . += new /obj/screen/plane_master{plane = PLANE_CH_IMPLOYAL} //Loyalty implants + . += new /obj/screen/plane_master{plane = PLANE_CH_IMPTRACK} //Tracking implants + . += new /obj/screen/plane_master{plane = PLANE_CH_IMPCHEM} //Chemical implants + . += new /obj/screen/plane_master{plane = PLANE_CH_SPECIAL} //"Special" role stuff + . += new /obj/screen/plane_master{plane = PLANE_CH_STATUS_OOC} //OOC status HUD + + . += new /obj/screen/plane_master{plane = PLANE_ADMIN1} //For admin use + . += new /obj/screen/plane_master{plane = PLANE_ADMIN2} //For admin use + . += new /obj/screen/plane_master{plane = PLANE_ADMIN3} //For admin use + + . += new /obj/screen/plane_master{plane = PLANE_MESONS} //Meson-specific things like open ceilings. + . += new /obj/screen/plane_master{plane = PLANE_BUILDMODE} //Things that only show up while in build mode + + // Real tangible stuff planes + . += new /obj/screen/plane_master/main{plane = TURF_PLANE} + . += new /obj/screen/plane_master/main{plane = OBJ_PLANE} + . += new /obj/screen/plane_master/main{plane = MOB_PLANE} + . += new /obj/screen/plane_master/cloaked //Cloaked atoms! \ No newline at end of file diff --git a/code/modules/tgui/modules/alarm.dm b/code/modules/tgui/modules/alarm.dm new file mode 100644 index 00000000000..2c0c75a6e8b --- /dev/null +++ b/code/modules/tgui/modules/alarm.dm @@ -0,0 +1,138 @@ +/datum/tgui_module/alarm_monitor + name = "Alarm monitor" + tgui_id = "StationAlertConsole" + var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use. + var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user. + +/datum/tgui_module/alarm_monitor/New() + ..() + alarm_handlers = list() + +/datum/tgui_module/alarm_monitor/all +/datum/tgui_module/alarm_monitor/all/New() + ..() + alarm_handlers = SSalarm.all_handlers + +/datum/tgui_module/alarm_monitor/all/robot +/datum/tgui_module/alarm_monitor/all/robot/tgui_state(mob/user) + return GLOB.tgui_self_state + +/datum/tgui_module/alarm_monitor/engineering +/datum/tgui_module/alarm_monitor/engineering/New() + ..() + alarm_handlers = list(atmosphere_alarm, fire_alarm, power_alarm) + +// Subtype for glasses_state +/datum/tgui_module/alarm_monitor/engineering/glasses +/datum/tgui_module/alarm_monitor/engineering/glasses/tgui_state(mob/user) + return GLOB.tgui_glasses_state + +// Subtype for nif_state +/datum/tgui_module/alarm_monitor/engineering/nif +/datum/tgui_module/alarm_monitor/engineering/nif/tgui_state(mob/user) + return GLOB.tgui_nif_state + +// Subtype for NTOS +/datum/tgui_module/alarm_monitor/engineering/ntos + ntos = TRUE + +/datum/tgui_module/alarm_monitor/security +/datum/tgui_module/alarm_monitor/security/New() + ..() + alarm_handlers = list(camera_alarm, motion_alarm) + +// Subtype for glasses_state +/datum/tgui_module/alarm_monitor/security/glasses +/datum/tgui_module/alarm_monitor/security/glasses/tgui_state(mob/user) + return GLOB.tgui_glasses_state + +// Subtype for NTOS +/datum/tgui_module/alarm_monitor/security/ntos + ntos = TRUE + +/datum/tgui_module/alarm_monitor/proc/register_alarm(var/object, var/procName) + for(var/datum/alarm_handler/AH in alarm_handlers) + AH.register_alarm(object, procName) + +/datum/tgui_module/alarm_monitor/proc/unregister_alarm(var/object) + for(var/datum/alarm_handler/AH in alarm_handlers) + AH.unregister_alarm(object) + +/datum/tgui_module/alarm_monitor/proc/all_alarms() + var/z = get_z(tgui_host()) + var/list/all_alarms = new() + for(var/datum/alarm_handler/AH in alarm_handlers) + all_alarms += AH.visible_alarms(z) + + return all_alarms + +/datum/tgui_module/alarm_monitor/proc/major_alarms() + var/z = get_z(tgui_host()) + var/list/all_alarms = new() + for(var/datum/alarm_handler/AH in alarm_handlers) + all_alarms += AH.major_alarms(z) + + return all_alarms + +// Modified version of above proc that uses slightly less resources, returns 1 if there is a major alarm, 0 otherwise. +/datum/tgui_module/alarm_monitor/proc/has_major_alarms() + var/z = get_z(tgui_host()) + for(var/datum/alarm_handler/AH in alarm_handlers) + if(AH.has_major_alarms(z)) + return 1 + + return 0 + +/datum/tgui_module/alarm_monitor/proc/minor_alarms() + var/z = get_z(tgui_host()) + var/list/all_alarms = new() + for(var/datum/alarm_handler/AH in alarm_handlers) + all_alarms += AH.minor_alarms(z) + + return all_alarms + +/datum/tgui_module/alarm_monitor/tgui_act(action, params) + if(..()) + return TRUE + + // Camera stuff is AI only. + // If you're not an AI, this is a read-only UI. + if(!isAI(usr)) + return + + switch(action) + if("switchTo") + var/obj/machinery/camera/C = locate(params["camera"]) in cameranet.cameras + if(!C) + return + + usr.switch_to_camera(C) + return 1 + +/datum/tgui_module/alarm_monitor/tgui_data(mob/user) + var/list/data = list() + + var/categories[0] + var/z = get_z(tgui_host()) + for(var/datum/alarm_handler/AH in alarm_handlers) + categories[++categories.len] = list("category" = AH.category, "alarms" = list()) + for(var/datum/alarm/A in AH.visible_alarms(z)) + var/cameras[0] + var/lost_sources[0] + + if(isAI(user)) + for(var/obj/machinery/camera/C in A.cameras()) + cameras[++cameras.len] = C.tgui_structure() + for(var/datum/alarm_source/AS in A.sources) + if(!AS.source) + lost_sources[++lost_sources.len] = AS.source_name + + categories[categories.len]["alarms"] += list(list( + "name" = "[A.alarm_name()]" + "[A.max_severity() > 1 ? "(MAJOR)" : ""]", + "origin_lost" = A.origin == null, + "has_cameras" = cameras.len, + "cameras" = cameras, + "lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : "")) + data["categories"] = categories + + return data diff --git a/code/modules/tgui/modules/appearance_changer.dm b/code/modules/tgui/modules/appearance_changer.dm new file mode 100644 index 00000000000..667fe7e0a0d --- /dev/null +++ b/code/modules/tgui/modules/appearance_changer.dm @@ -0,0 +1,358 @@ +/datum/tgui_module/appearance_changer + name = "Appearance Editor" + tgui_id = "AppearanceChanger" + var/flags = APPEARANCE_ALL_HAIR + var/mob/living/carbon/human/owner = null + var/list/valid_species = list() + var/list/valid_hairstyles = list() + var/list/valid_facial_hairstyles = list() + + var/check_whitelist + var/list/whitelist + var/list/blacklist + + var/customize_usr = FALSE + + // Stuff needed to render the map + var/map_name + var/obj/screen/map_view/cam_screen + var/list/cam_plane_masters + var/obj/screen/background/cam_background + var/obj/screen/skybox/local_skybox + // Needed for moving camera support + var/camera_diff_x = -1 + var/camera_diff_y = -1 + var/camera_diff_z = -1 + +/datum/tgui_module/appearance_changer/New( + var/host, + mob/living/carbon/human/H, + check_species_whitelist = 1, + list/species_whitelist = list(), + list/species_blacklist = list()) + . = ..() + + map_name = "appearance_changer_[REF(src)]_map" + // Initialize map objects + cam_screen = new + cam_screen.name = "screen" + cam_screen.assigned_map = map_name + cam_screen.del_on_map_removal = FALSE + cam_screen.screen_loc = "[map_name]:1,1" + + cam_plane_masters = get_plane_masters() + + for(var/plane in cam_plane_masters) + var/obj/screen/instance = plane + instance.assigned_map = map_name + instance.del_on_map_removal = FALSE + instance.screen_loc = "[map_name]:CENTER" + + local_skybox = new() + local_skybox.assigned_map = map_name + local_skybox.del_on_map_removal = FALSE + local_skybox.screen_loc = "[map_name]:CENTER,CENTER" + cam_plane_masters += local_skybox + + cam_background = new + cam_background.assigned_map = map_name + cam_background.del_on_map_removal = FALSE + reload_cameraview() + + owner = H + check_whitelist = check_species_whitelist + whitelist = species_whitelist + blacklist = species_blacklist + +/datum/tgui_module/appearance_changer/Destroy() + qdel(cam_screen) + QDEL_LIST(cam_plane_masters) + qdel(cam_background) + return ..() + +/datum/tgui_module/appearance_changer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + var/mob/living/carbon/human/target = owner + if(customize_usr) + if(!ishuman(usr)) + return TRUE + target = usr + + switch(action) + if("race") + if(can_change(APPEARANCE_RACE) && (params["race"] in valid_species)) + if(target.change_species(params["race"])) + cut_and_generate_data() + return 1 + if("gender") + if(can_change(APPEARANCE_GENDER) && (params["gender"] in get_genders())) + if(target.change_gender(params["gender"])) + cut_and_generate_data() + return 1 + if("gender_id") + if(can_change(APPEARANCE_GENDER) && (params["gender_id"] in all_genders_define_list)) + target.identifying_gender = params["gender_id"] + return 1 + if("skin_tone") + if(can_change_skin_tone()) + var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", -target.s_tone + 35) as num|null + if(isnum(new_s_tone) && can_still_topic(usr, state)) + new_s_tone = 35 - max(min( round(new_s_tone), 220),1) + return target.change_skin_tone(new_s_tone) + if("skin_color") + if(can_change_skin_color()) + var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", rgb(target.r_skin, target.g_skin, target.b_skin)) as color|null + if(new_skin && can_still_topic(usr, state)) + var/r_skin = hex2num(copytext(new_skin, 2, 4)) + var/g_skin = hex2num(copytext(new_skin, 4, 6)) + var/b_skin = hex2num(copytext(new_skin, 6, 8)) + if(target.change_skin_color(r_skin, g_skin, b_skin)) + update_dna() + return 1 + if("hair") + if(can_change(APPEARANCE_HAIR) && (params["hair"] in valid_hairstyles)) + if(target.change_hair(params["hair"])) + update_dna() + return 1 + if("hair_color") + if(can_change(APPEARANCE_HAIR_COLOR)) + var/new_hair = input("Please select hair color.", "Hair Color", rgb(target.r_hair, target.g_hair, target.b_hair)) as color|null + if(new_hair && can_still_topic(usr, state)) + var/r_hair = hex2num(copytext(new_hair, 2, 4)) + var/g_hair = hex2num(copytext(new_hair, 4, 6)) + var/b_hair = hex2num(copytext(new_hair, 6, 8)) + if(target.change_hair_color(r_hair, g_hair, b_hair)) + update_dna() + return 1 + if("facial_hair") + if(can_change(APPEARANCE_FACIAL_HAIR) && (params["facial_hair"] in valid_facial_hairstyles)) + if(target.change_facial_hair(params["facial_hair"])) + update_dna() + return 1 + if("facial_hair_color") + if(can_change(APPEARANCE_FACIAL_HAIR_COLOR)) + var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(target.r_facial, target.g_facial, target.b_facial)) as color|null + if(new_facial && can_still_topic(usr, state)) + var/r_facial = hex2num(copytext(new_facial, 2, 4)) + var/g_facial = hex2num(copytext(new_facial, 4, 6)) + var/b_facial = hex2num(copytext(new_facial, 6, 8)) + if(target.change_facial_hair_color(r_facial, g_facial, b_facial)) + update_dna() + return 1 + if("eye_color") + if(can_change(APPEARANCE_EYE_COLOR)) + var/new_eyes = input("Please select eye color.", "Eye Color", rgb(target.r_eyes, target.g_eyes, target.b_eyes)) as color|null + if(new_eyes && can_still_topic(usr, state)) + var/r_eyes = hex2num(copytext(new_eyes, 2, 4)) + var/g_eyes = hex2num(copytext(new_eyes, 4, 6)) + var/b_eyes = hex2num(copytext(new_eyes, 6, 8)) + if(target.change_eye_color(r_eyes, g_eyes, b_eyes)) + update_dna() + return 1 + return FALSE + +/datum/tgui_module/appearance_changer/tgui_interact(mob/user, datum/tgui/ui = null, datum/tgui/parent_ui = null, datum/tgui_state/custom_state = GLOB.tgui_default_state) + var/mob/living/carbon/human/target = owner + if(customize_usr) + if(!ishuman(user)) + return TRUE + target = user + + if(!target || !target.species) + return + + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + reload_cameraview() + // Register map objects + user.client.register_map_obj(cam_screen) + for(var/plane in cam_plane_masters) + user.client.register_map_obj(plane) + user.client.register_map_obj(cam_background) + // Open UI + ui = new(user, src, tgui_id, name) + ui.open() + if(custom_state) + ui.set_state(custom_state) + +/datum/tgui_module/appearance_changer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + generate_data(check_whitelist, whitelist, blacklist) + differential_check() + + var/mob/living/carbon/human/target = owner + if(customize_usr) + if(!ishuman(usr)) + return TRUE + target = usr + + data["name"] = target.name + data["specimen"] = target.species.name + data["gender"] = target.gender + data["gender_id"] = target.identifying_gender + data["change_race"] = can_change(APPEARANCE_RACE) + if(data["change_race"]) + var/species[0] + for(var/specimen in valid_species) + species[++species.len] = list("specimen" = specimen) + data["species"] = species + + data["change_gender"] = can_change(APPEARANCE_GENDER) + if(data["change_gender"]) + var/genders[0] + for(var/gender in get_genders()) + genders[++genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender) + data["genders"] = genders + var/id_genders[0] + for(var/gender in all_genders_define_list) + id_genders[++id_genders.len] = list("gender_name" = gender2text(gender), "gender_key" = gender) + data["id_genders"] = id_genders + + data["change_hair"] = can_change(APPEARANCE_HAIR) + if(data["change_hair"]) + var/hair_styles[0] + for(var/hair_style in valid_hairstyles) + hair_styles[++hair_styles.len] = list("hairstyle" = hair_style) + data["hair_styles"] = hair_styles + data["hair_style"] = target.h_style + + data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR) + if(data["change_facial_hair"]) + var/facial_hair_styles[0] + for(var/facial_hair_style in valid_facial_hairstyles) + facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style) + data["facial_hair_styles"] = facial_hair_styles + data["facial_hair_style"] = target.f_style + + data["change_skin_tone"] = can_change_skin_tone() + data["change_skin_color"] = can_change_skin_color() + if(data["change_skin_color"]) + data["skin_color"] = rgb(target.r_skin, target.g_skin, target.b_skin) + data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR) + if(data["change_eye_color"]) + data["eye_color"] = rgb(target.r_eyes, target.g_eyes, target.b_eyes) + data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) + if(data["change_hair_color"]) + data["hair_color"] = rgb(target.r_hair, target.g_hair, target.b_hair) + data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) + if(data["change_facial_hair_color"]) + data["facial_hair_color"] = rgb(target.r_facial, target.g_facial, target.b_facial) + return data + +/datum/tgui_module/appearance_changer/tgui_static_data(mob/user) + var/list/data = ..() + data["mapRef"] = map_name + return data + +/datum/tgui_module/appearance_changer/proc/differential_check() + var/turf/T = get_turf(customize_usr ? tgui_host() : owner) + if(T) + var/new_x = T.x + var/new_y = T.y + var/new_z = T.z + if((new_x != camera_diff_x) || (new_y != camera_diff_y) || (new_z != camera_diff_z)) + reload_cameraview() + +/datum/tgui_module/appearance_changer/proc/reload_cameraview() + var/turf/camTurf = get_turf(customize_usr ? tgui_host() : owner) + if(!camTurf) + return + + camera_diff_x = camTurf.x + camera_diff_y = camTurf.y + camera_diff_z = camTurf.z + + var/list/visible_turfs = list() + for(var/turf/T in range(1, camTurf)) + visible_turfs += T + + cam_screen.vis_contents = visible_turfs + cam_background.icon_state = "clear" + cam_background.fill_rect(1, 1, 3, 3) + + local_skybox.cut_overlays() + local_skybox.add_overlay(SSskybox.get_skybox(get_z(camTurf))) + local_skybox.scale_to_view(3) + local_skybox.set_position("CENTER", "CENTER", (world.maxx>>1) - camTurf.x, (world.maxy>>1) - camTurf.y) + +/datum/tgui_module/appearance_changer/proc/update_dna() + var/mob/living/carbon/human/target = owner + if(customize_usr) + if(!ishuman(usr)) + return TRUE + target = usr + + if(target && (flags & APPEARANCE_UPDATE_DNA)) + target.update_dna() + +/datum/tgui_module/appearance_changer/proc/can_change(var/flag) + var/mob/living/carbon/human/target = owner + if(customize_usr) + if(!ishuman(usr)) + return TRUE + target = usr + + return target && (flags & flag) + +/datum/tgui_module/appearance_changer/proc/can_change_skin_tone() + var/mob/living/carbon/human/target = owner + if(customize_usr) + if(!ishuman(usr)) + return TRUE + target = usr + + return target && (flags & APPEARANCE_SKIN) && target.species.appearance_flags & HAS_SKIN_TONE + +/datum/tgui_module/appearance_changer/proc/can_change_skin_color() + var/mob/living/carbon/human/target = owner + if(customize_usr) + if(!ishuman(usr)) + return TRUE + target = usr + + return target && (flags & APPEARANCE_SKIN) && target.species.appearance_flags & HAS_SKIN_COLOR + +/datum/tgui_module/appearance_changer/proc/cut_and_generate_data() + // Making the assumption that the available species remain constant + valid_facial_hairstyles.Cut() + valid_facial_hairstyles.Cut() + generate_data() + +/datum/tgui_module/appearance_changer/proc/generate_data() + var/mob/living/carbon/human/target = owner + if(customize_usr) + if(!ishuman(usr)) + return TRUE + target = usr + if(!target) + return + if(!valid_species.len) + valid_species = target.generate_valid_species(check_whitelist, whitelist, blacklist) + if(!valid_hairstyles.len || !valid_facial_hairstyles.len) + valid_hairstyles = target.generate_valid_hairstyles(check_gender = 0) + valid_facial_hairstyles = target.generate_valid_facial_hairstyles() + +/datum/tgui_module/appearance_changer/proc/get_genders() + var/mob/living/carbon/human/target = owner + if(customize_usr) + if(!ishuman(usr)) + return TRUE + target = usr + var/datum/species/S = target.species + var/list/possible_genders = S.genders + if(!target.internal_organs_by_name["cell"]) + return possible_genders + possible_genders = possible_genders.Copy() + possible_genders |= NEUTER + return possible_genders + +/datum/tgui_module/appearance_changer/mirror + name = "SalonPro Nano-Mirror™" + flags = APPEARANCE_ALL_HAIR + customize_usr = TRUE + +/datum/tgui_module/appearance_changer/mirror/coskit + name = "SalonPro Porta-Makeover Deluxe™" \ No newline at end of file diff --git a/code/modules/tgui/modules/atmos_control.dm b/code/modules/tgui/modules/atmos_control.dm new file mode 100644 index 00000000000..83d3db4d1e8 --- /dev/null +++ b/code/modules/tgui/modules/atmos_control.dm @@ -0,0 +1,110 @@ +/datum/tgui_module/atmos_control + name = "Atmospherics Control" + tgui_id = "AtmosControl" + var/obj/access = new() + var/emagged = 0 + var/ui_ref + var/list/monitored_alarms = list() + +/datum/tgui_module/atmos_control/New(atmos_computer, req_access, req_one_access, monitored_alarm_ids) + ..() + access.req_access = req_access + access.req_one_access = req_one_access + + if(monitored_alarm_ids) + for(var/obj/machinery/alarm/alarm in machines) + if(alarm.alarm_id && alarm.alarm_id in monitored_alarm_ids) + monitored_alarms += alarm + // machines may not yet be ordered at this point + monitored_alarms = dd_sortedObjectList(monitored_alarms) + +/datum/tgui_module/atmos_control/tgui_act(action, params, datum/tgui/ui) + if(..()) + return TRUE + + switch(action) + if("alarm") + if(ui_ref) + var/obj/machinery/alarm/alarm = locate(params["alarm"]) in (monitored_alarms.len ? monitored_alarms : machines) + if(alarm) + var/datum/tgui_state/TS = generate_state(alarm) + alarm.tgui_interact(usr, parent_ui = ui_ref, state = TS) + return 1 + if("setZLevel") + ui.set_map_z_level(params["mapZLevel"]) + return TRUE + +/datum/tgui_module/atmos_control/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, tgui_id, name) + ui.autoupdate = TRUE + ui.open() + ui_ref = ui + +/datum/tgui_module/atmos_control/tgui_static_data(mob/user) + . = ..() + + var/z = get_z(user) + var/list/map_levels = using_map.get_map_levels(z) + + // TODO: Move these to a cache, similar to cameras + var/alarms[0] + for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : machines)) + if(!monitored_alarms.len && alarm.alarms_hidden) + continue + if(!(alarm.z in map_levels)) + continue + alarms[++alarms.len] = list( + "name" = sanitize(alarm.name), + "ref"= "\ref[alarm]", + "danger" = max(alarm.danger_level, alarm.alarm_area.atmosalm), + "x" = alarm.x, + "y" = alarm.y, + "z" = alarm.z) + .["alarms"] = alarms + +/datum/tgui_module/atmos_control/tgui_data(mob/user) + var/list/data = list() + + var/z = get_z(user) + var/list/map_levels = using_map.get_map_levels(z) + data["map_levels"] = map_levels + + return data + +/datum/tgui_module/atmos_control/tgui_close() + . = ..() + ui_ref = null + +/datum/tgui_module/atmos_control/proc/generate_state(air_alarm) + var/datum/tgui_state/air_alarm_remote/state = new() + state.atmos_control = src + state.air_alarm = air_alarm + return state + +/datum/tgui_state/air_alarm_remote + var/datum/tgui_module/atmos_control/atmos_control = null + var/obj/machinery/alarm/air_alarm = null + +/datum/tgui_state/air_alarm_remote/can_use_topic(src_object, mob/user) + if(!atmos_control.ui_ref) + qdel(src) + return STATUS_CLOSE + if(has_access(user)) + return STATUS_INTERACTIVE + return STATUS_UPDATE + +/datum/tgui_state/air_alarm_remote/proc/has_access(var/mob/user) + return user && (isAI(user) || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO) || (access_ce in user.GetAccess())) + +/datum/tgui_state/air_alarm_remote/Destroy() + atmos_control = null + air_alarm = null + +/datum/tgui_module/atmos_control/ntos + ntos = TRUE + +/datum/tgui_module/atmos_control/robot +/datum/tgui_module/atmos_control/robot/tgui_state(mob/user) + return GLOB.tgui_self_state \ No newline at end of file diff --git a/code/modules/tgui/modules/camera.dm b/code/modules/tgui/modules/camera.dm new file mode 100644 index 00000000000..d9ac311ee36 --- /dev/null +++ b/code/modules/tgui/modules/camera.dm @@ -0,0 +1,272 @@ +/datum/tgui_module/camera + name = "Security Cameras" + tgui_id = "CameraConsole" + + var/access_based = FALSE + var/list/network = list() + var/list/additional_networks = list() + + var/obj/machinery/camera/active_camera + var/list/concurrent_users = list() + + // Stuff needed to render the map + var/map_name + var/const/default_map_size = 15 + var/obj/screen/map_view/cam_screen + /// All the plane masters that need to be applied. + var/list/cam_plane_masters + var/obj/screen/background/cam_background + var/obj/screen/background/cam_foreground + var/obj/screen/skybox/local_skybox + // Needed for moving camera support + var/camera_diff_x = -1 + var/camera_diff_y = -1 + var/camera_diff_z = -1 + +/datum/tgui_module/camera/New(host, list/network_computer) + . = ..() + if(!LAZYLEN(network_computer)) + access_based = TRUE + else + network = network_computer + map_name = "camera_console_[REF(src)]_map" + // Initialize map objects + cam_screen = new + cam_screen.name = "screen" + cam_screen.assigned_map = map_name + cam_screen.del_on_map_removal = FALSE + cam_screen.screen_loc = "[map_name]:1,1" + + cam_plane_masters = get_plane_masters() + + for(var/plane in cam_plane_masters) + var/obj/screen/instance = plane + instance.assigned_map = map_name + instance.del_on_map_removal = FALSE + instance.screen_loc = "[map_name]:CENTER" + + local_skybox = new() + local_skybox.assigned_map = map_name + local_skybox.del_on_map_removal = FALSE + local_skybox.screen_loc = "[map_name]:CENTER,CENTER" + cam_plane_masters += local_skybox + + cam_background = new + cam_background.assigned_map = map_name + cam_background.del_on_map_removal = FALSE + + var/mutable_appearance/scanlines = mutable_appearance('icons/effects/static.dmi', "scanlines") + scanlines.alpha = 50 + scanlines.layer = FULLSCREEN_LAYER + + var/mutable_appearance/noise = mutable_appearance('icons/effects/static.dmi', "1 light") + noise.layer = FULLSCREEN_LAYER + + cam_foreground = new + cam_foreground.assigned_map = map_name + cam_foreground.del_on_map_removal = FALSE + cam_foreground.plane = PLANE_FULLSCREEN + cam_foreground.add_overlay(scanlines) + cam_foreground.add_overlay(noise) + +/datum/tgui_module/camera/Destroy() + qdel(cam_screen) + QDEL_LIST(cam_plane_masters) + qdel(cam_background) + qdel(cam_foreground) + return ..() + +/datum/tgui_module/camera/tgui_interact(mob/user, datum/tgui/ui = null) + // Update UI + ui = SStgui.try_update_ui(user, src, ui) + // Show static if can't use the camera + if(!active_camera?.can_use()) + show_camera_static() + if(!ui) + var/user_ref = REF(user) + var/is_living = isliving(user) + // Ghosts shouldn't count towards concurrent users, which produces + // an audible terminal_on click. + if(is_living) + concurrent_users += user_ref + // Turn on the console + if(length(concurrent_users) == 1 && is_living) + playsound(tgui_host(), 'sound/machines/terminal_on.ogg', 25, FALSE) + // Register map objects + user.client.register_map_obj(cam_screen) + for(var/plane in cam_plane_masters) + user.client.register_map_obj(plane) + user.client.register_map_obj(cam_background) + user.client.register_map_obj(cam_foreground) + // Open UI + ui = new(user, src, tgui_id, name) + ui.open() + +/datum/tgui_module/camera/tgui_data() + var/list/data = list() + data["activeCamera"] = null + if(active_camera) + differential_check() + data["activeCamera"] = list( + name = active_camera.c_tag, + status = active_camera.status, + ) + return data + +/datum/tgui_module/camera/tgui_static_data(mob/user) + var/list/data = ..() + data["mapRef"] = map_name + var/list/cameras = get_available_cameras(user) + data["cameras"] = list() + data["allNetworks"] = list() + for(var/i in cameras) + var/obj/machinery/camera/C = cameras[i] + data["cameras"] += list(list( + name = C.c_tag, + networks = C.network + )) + data["allNetworks"] |= C.network + return data + +/datum/tgui_module/camera/tgui_act(action, params) + if(..()) + return TRUE + + if(action && !issilicon(usr)) + playsound(tgui_host(), "terminal_type", 50, 1) + + if(action == "switch_camera") + var/c_tag = params["name"] + var/list/cameras = get_available_cameras(usr) + var/obj/machinery/camera/C = cameras["[ckey(c_tag)]"] + active_camera = C + playsound(tgui_host(), get_sfx("terminal_type"), 25, FALSE) + + reload_cameraview() + + return TRUE + +/datum/tgui_module/camera/proc/differential_check() + var/turf/T = get_turf(active_camera) + if(T) + var/new_x = T.x + var/new_y = T.y + var/new_z = T.z + if((new_x != camera_diff_x) || (new_y != camera_diff_y) || (new_z != camera_diff_z)) + reload_cameraview() + +/datum/tgui_module/camera/proc/reload_cameraview() + // Show static if can't use the camera + if(!active_camera?.can_use()) + show_camera_static() + return TRUE + + var/turf/camTurf = get_turf(active_camera) + + camera_diff_x = camTurf.x + camera_diff_y = camTurf.y + camera_diff_z = camTurf.z + + var/list/visible_turfs = list() + for(var/turf/T in (active_camera.isXRay() \ + ? range(active_camera.view_range, camTurf) \ + : view(active_camera.view_range, camTurf))) + visible_turfs += T + + var/list/bbox = get_bbox_of_atoms(visible_turfs) + var/size_x = bbox[3] - bbox[1] + 1 + var/size_y = bbox[4] - bbox[2] + 1 + + cam_screen.vis_contents = visible_turfs + cam_background.icon_state = "clear" + cam_background.fill_rect(1, 1, size_x, size_y) + + cam_foreground.fill_rect(1, 1, size_x, size_y) + + local_skybox.cut_overlays() + local_skybox.add_overlay(SSskybox.get_skybox(get_z(camTurf))) + local_skybox.scale_to_view(size_x) + local_skybox.set_position("CENTER", "CENTER", (world.maxx>>1) - camTurf.x, (world.maxy>>1) - camTurf.y) + +// Returns the list of cameras accessible from this computer +// This proc operates in two distinct ways depending on the context in which the module is created. +// It can either return a list of cameras sharing the same the internal `network` variable, or +// It can scan all station networks and determine what cameras to show based on the access of the user. +/datum/tgui_module/camera/proc/get_available_cameras(mob/user) + var/list/all_networks = list() + // Access Based + if(access_based) + for(var/network in using_map.station_networks) + if(can_access_network(user, get_camera_access(network), 1)) + all_networks.Add(network) + for(var/network in using_map.secondary_networks) + if(can_access_network(user, get_camera_access(network), 0)) + all_networks.Add(network) + // Network Based + else + all_networks = network.Copy() + + if(additional_networks) + all_networks += additional_networks + + var/list/D = list() + for(var/obj/machinery/camera/C in cameranet.cameras) + if(!C.network) + stack_trace("Camera in a cameranet has no camera network") + continue + if(!(islist(C.network))) + stack_trace("Camera in a cameranet has a non-list camera network") + continue + var/list/tempnetwork = C.network & all_networks + if(tempnetwork.len) + D["[ckey(C.c_tag)]"] = C + return D + +/datum/tgui_module/camera/proc/can_access_network(mob/user, network_access, station_network = 0) + // No access passed, or 0 which is considered no access requirement. Allow it. + if(!network_access) + return 1 + + if(station_network) + return check_access(user, network_access) || check_access(user, access_security) || check_access(user, access_heads) + else + return check_access(user, network_access) + +/datum/tgui_module/camera/proc/show_camera_static() + cam_screen.vis_contents.Cut() + cam_background.icon_state = "scanline2" + cam_background.fill_rect(1, 1, default_map_size, default_map_size) + local_skybox.cut_overlays() + +/datum/tgui_module/camera/tgui_close(mob/user) + . = ..() + var/user_ref = REF(user) + var/is_living = isliving(user) + // living creature or not, we remove you anyway. + concurrent_users -= user_ref + // Unregister map objects + if(user.client) + user.client.clear_map(map_name) + // Turn off the console + if(length(concurrent_users) == 0 && is_living) + active_camera = null + playsound(tgui_host(), 'sound/machines/terminal_off.ogg', 25, FALSE) + +// NTOS Version +// Please note, this isn't a very good replacement for converting modular computers 100% to TGUI +// If/when that is done, just move all the PC_ specific data and stuff to the modular computers themselves +// instead of copying this approach here. +/datum/tgui_module/camera/ntos + ntos = TRUE + +// ERT Version provides some additional networks. +/datum/tgui_module/camera/ntos/ert + additional_networks = list(NETWORK_ERT, NETWORK_CRESCENT) + +// Hacked version also provides some additional networks, +// but we want it to show *all* the networks 24/7, so we convert it into a non-access-based UI. +/datum/tgui_module/camera/ntos/hacked + additional_networks = list(NETWORK_MERCENARY, NETWORK_ERT, NETWORK_CRESCENT) + +/datum/tgui_module/camera/ntos/hacked/New(host) + . = ..(host, using_map.station_networks.Copy()) diff --git a/code/modules/tgui/modules/crew_monitor.dm b/code/modules/tgui/modules/crew_monitor.dm new file mode 100644 index 00000000000..86e039222c6 --- /dev/null +++ b/code/modules/tgui/modules/crew_monitor.dm @@ -0,0 +1,77 @@ +/datum/tgui_module/crew_monitor + name = "Crew monitor" + tgui_id = "CrewMonitor" + +/datum/tgui_module/crew_monitor/tgui_act(action, params, datum/tgui/ui) + if(..()) + return TRUE + + if(action && !issilicon(usr)) + playsound(tgui_host(), "terminal_type", 50, 1) + + var/turf/T = get_turf(usr) + if(!T || !(T.z in using_map.player_levels)) + to_chat(usr, "Unable to establish a connection: You're too far away from the station!") + return FALSE + + switch(action) + if("track") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + var/mob/living/carbon/human/H = locate(params["track"]) in mob_list + if(hassensorlevel(H, SUIT_SENSOR_TRACKING)) + AI.ai_actual_track(H) + return TRUE + if("setZLevel") + ui.set_map_z_level(params["mapZLevel"]) + return TRUE + +/datum/tgui_module/crew_monitor/tgui_interact(mob/user, datum/tgui/ui = null) + var/z = get_z(user) + var/list/map_levels = using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE) + + if(!map_levels.len) + to_chat(user, "The crew monitor doesn't seem like it'll work here.") + if(ui) + ui.close() + return null + + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, tgui_id, name) + ui.autoupdate = TRUE + ui.open() + + +/datum/tgui_module/crew_monitor/tgui_data(mob/user) + var/data[0] + + data["isAI"] = isAI(user) + + var/z = get_z(user) + var/list/map_levels = uniquelist(using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE)) + data["map_levels"] = map_levels + + data["crewmembers"] = list() + for(var/zlevel in map_levels) + data["crewmembers"] += crew_repository.health_data(zlevel) + + return data + +/datum/tgui_module/crew_monitor/ntos + ntos = TRUE + +// Subtype for glasses_state +/datum/tgui_module/crew_monitor/glasses +/datum/tgui_module/crew_monitor/glasses/tgui_state(mob/user) + return GLOB.tgui_glasses_state + +// Subtype for self_state +/datum/tgui_module/crew_monitor/robot +/datum/tgui_module/crew_monitor/robot/tgui_state(mob/user) + return GLOB.tgui_self_state + +// Subtype for nif_state +/datum/tgui_module/crew_monitor/nif +/datum/tgui_module/crew_monitor/nif/tgui_state(mob/user) + return GLOB.tgui_nif_state diff --git a/code/modules/tgui/modules/power_monitor.dm b/code/modules/tgui/modules/power_monitor.dm new file mode 100644 index 00000000000..ec5c8205982 --- /dev/null +++ b/code/modules/tgui/modules/power_monitor.dm @@ -0,0 +1,85 @@ +/datum/tgui_module/power_monitor + name = "Power monitor" + tgui_id = "PowerMonitor" + var/list/grid_sensors + var/active_sensor = null //name_tag of the currently selected sensor + +/datum/tgui_module/power_monitor/New() + . = ..() + refresh_sensors() + +/datum/tgui_module/power_monitor/tgui_data(mob/user) + var/list/data = list() + + var/list/sensors = list() + // Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading. + var/obj/machinery/power/sensor/focus = null + + var/z = get_z(user) + var/list/map_levels = using_map.get_map_levels(z) + + // Build list of data from sensor readings. + for(var/obj/machinery/power/sensor/S in grid_sensors) + if(!(S.z in map_levels)) + continue + sensors.Add(list(list( + "name" = S.name_tag, + "alarm" = S.check_grid_warning() + ))) + if(S.name_tag == active_sensor) + focus = S + + data["all_sensors"] = sensors + if(focus) + data["focus"] = focus.tgui_data(user) + else + data["focus"] = null + + return data + +/datum/tgui_module/power_monitor/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("clear") + active_sensor = null + . = TRUE + if("refresh") + refresh_sensors() + . = TRUE + if("setsensor") + active_sensor = params["id"] + . = TRUE + +/datum/tgui_module/power_monitor/proc/has_alarm() + for(var/obj/machinery/power/sensor/S in grid_sensors) + if(S.check_grid_warning()) + return TRUE + return FALSE + +/datum/tgui_module/power_monitor/proc/refresh_sensors() + grid_sensors = list() + + // Handle ultranested programs + var/turf/T = get_turf(tgui_host()) + + var/list/levels = list() + if(!T) // Safety check + return + if(T) + levels += using_map.get_map_levels(T.z, FALSE) + for(var/obj/machinery/power/sensor/S in machines) + if(T && (S.loc.z == T.z) || (S.loc.z in levels) || (S.long_range)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels. + if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen! + warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z") + else + grid_sensors += S + +/datum/tgui_module/power_monitor/ntos + ntos = TRUE + +// Subtype for self_state +/datum/tgui_module/power_monitor/robot +/datum/tgui_module/power_monitor/robot/tgui_state(mob/user) + return GLOB.tgui_self_state diff --git a/code/modules/tgui/modules/rcon.dm b/code/modules/tgui/modules/rcon.dm new file mode 100644 index 00000000000..62cf3e5d711 --- /dev/null +++ b/code/modules/tgui/modules/rcon.dm @@ -0,0 +1,118 @@ +/datum/tgui_module/rcon + name = "Power RCON" + tgui_id = "RCON" + + var/list/known_SMESs = null + var/list/known_breakers = null + +/datum/tgui_module/rcon/tgui_data(mob/user) + FindDevices() // Update our devices list + var/list/data = ..() + + // SMES DATA (simplified view) + var/list/smeslist[0] + for(var/obj/machinery/power/smes/buildable/SMES in known_SMESs) + smeslist.Add(list(list( + "capacity" = SMES.capacity, + "capacityPercent" = round(100*SMES.charge/SMES.capacity, 0.1), + "charge" = SMES.charge, + "input_set" = SMES.input_attempt, + "input_val" = round(SMES.input_level/1000, 0.1), + "output_set" = SMES.output_attempt, + "output_val" = round(SMES.output_level/1000, 0.1), + "output_load" = round(SMES.output_used/1000, 0.1), + "RCON_tag" = SMES.RCon_tag + ))) + + data["smes_info"] = sortByKey(smeslist, "RCON_tag") + + // BREAKER DATA (simplified view) + var/list/breakerlist[0] + for(var/obj/machinery/power/breakerbox/BR in known_breakers) + breakerlist.Add(list(list( + "RCON_tag" = BR.RCon_tag, + "enabled" = BR.on + ))) + data["breaker_info"] = breakerlist + + return data + +/datum/tgui_module/rcon/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("smes_in_toggle") + var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"]) + if(SMES) + SMES.toggle_input() + . = TRUE + if("smes_out_toggle") + var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"]) + if(SMES) + SMES.toggle_output() + . = TRUE + if("smes_in_set") + var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"]) + if(SMES) + var/inputset = (input(usr, "Enter new input level (0-[SMES.input_level_max/1000] kW)", "SMES Input Power Control", SMES.input_level/1000) as num) * 1000 + SMES.set_input(inputset) + . = TRUE + if("smes_out_set") + var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(params["smes"]) + if(SMES) + var/outputset = (input(usr, "Enter new output level (0-[SMES.output_level_max/1000] kW)", "SMES Output Power Control", SMES.output_level/1000) as num) * 1000 + SMES.set_output(outputset) + . = TRUE + if("toggle_breaker") + var/obj/machinery/power/breakerbox/toggle = null + for(var/obj/machinery/power/breakerbox/breaker in known_breakers) + if(breaker.RCon_tag == params["breaker"]) + toggle = breaker + if(toggle) + if(toggle.update_locked) + to_chat(usr, "The breaker box was recently toggled. Please wait before toggling it again.") + else + toggle.auto_toggle() + . = TRUE + + +// Proc: GetSMESByTag() +// Parameters: 1 (tag - RCON tag of SMES we want to look up) +// Description: Looks up and returns SMES which has matching RCON tag +/datum/tgui_module/rcon/proc/GetSMESByTag(var/tag) + if(!tag) + return + + for(var/obj/machinery/power/smes/buildable/S in known_SMESs) + if(S.RCon_tag == tag) + return S + +// Proc: FindDevices() +// Parameters: None +// Description: Refreshes local list of known devices. +/datum/tgui_module/rcon/proc/FindDevices() + known_SMESs = new /list() + + var/z = get_z(tgui_host()) + var/list/map_levels = using_map.get_map_levels(z) + + for(var/obj/machinery/power/smes/buildable/SMES in GLOB.smeses) + if(!(SMES.z in map_levels)) + continue + if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon) + known_SMESs.Add(SMES) + + known_breakers = new /list() + for(var/obj/machinery/power/breakerbox/breaker in machines) + if(!(breaker.z in map_levels)) + continue + if(breaker.RCon_tag != "NO_TAG") + known_breakers.Add(breaker) + +/datum/tgui_module/rcon/ntos + ntos = TRUE + +/datum/tgui_module/rcon/robot +/datum/tgui_module/rcon/robot/tgui_state(mob/user) + return GLOB.tgui_self_state \ No newline at end of file diff --git a/code/modules/tgui/modules/shutoff_monitor.dm b/code/modules/tgui/modules/shutoff_monitor.dm new file mode 100644 index 00000000000..ead6502dc44 --- /dev/null +++ b/code/modules/tgui/modules/shutoff_monitor.dm @@ -0,0 +1,46 @@ +/datum/tgui_module/shutoff_monitor + name = "Shutoff Valve Monitoring" + tgui_id = "ShutoffMonitor" + +/datum/tgui_module/shutoff_monitor/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("toggle_enable") + var/obj/machinery/atmospherics/valve/shutoff/S = locate(params["valve"]) + if(!istype(S)) + return 0 + S.close_on_leaks = !S.close_on_leaks + return 1 + + if("toggle_open") + var/obj/machinery/atmospherics/valve/shutoff/S = locate(params["valve"]) + if(!istype(S)) + return 0 + if(S.open) + S.close() + else + S.open() + return 1 + +/datum/tgui_module/shutoff_monitor/tgui_data(mob/user) + var/list/data = list() + var/list/valves = list() + + for(var/obj/machinery/atmospherics/valve/shutoff/S in GLOB.shutoff_valves) + valves.Add(list(list( + "name" = S.name, + "enabled" = S.close_on_leaks, + "open" = S.open, + "x" = S.x, + "y" = S.y, + "z" = S.z, + "ref" = "\ref[S]" + ))) + + data["valves"] = valves + return data + +/datum/tgui_module/shutoff_monitor/ntos + ntos = TRUE \ No newline at end of file diff --git a/code/modules/tgui/modules/supermatter_monitor.dm b/code/modules/tgui/modules/supermatter_monitor.dm new file mode 100644 index 00000000000..0e0aed4f1be --- /dev/null +++ b/code/modules/tgui/modules/supermatter_monitor.dm @@ -0,0 +1,108 @@ + +/datum/tgui_module/supermatter_monitor + name = "Supermatter monitor" + tgui_id = "SupermatterMonitor" + var/list/supermatters + var/obj/machinery/power/supermatter/active = null // Currently selected supermatter crystal. + +/datum/tgui_module/supermatter_monitor/Destroy() + . = ..() + active = null + supermatters = null + +/datum/tgui_module/supermatter_monitor/New() + ..() + refresh() + +// Refreshes list of active supermatter crystals +/datum/tgui_module/supermatter_monitor/proc/refresh() + supermatters = list() + var/z = get_z(tgui_host()) + if(!z) + return + var/valid_z_levels = using_map.get_map_levels(z) + for(var/obj/machinery/power/supermatter/S in machines) + // Delaminating, not within coverage, not on a tile. + if(S.grav_pulling || S.exploded || !(S.z in valid_z_levels) || !istype(S.loc, /turf/)) + continue + supermatters.Add(S) + + if(!(active in supermatters)) + active = null + +/datum/tgui_module/supermatter_monitor/proc/get_status() + . = SUPERMATTER_INACTIVE + for(var/obj/machinery/power/supermatter/S in supermatters) + . = max(., S.get_status()) + +/datum/tgui_module/supermatter_monitor/tgui_data(mob/user) + var/list/data = ..() + + if(istype(active)) + var/turf/T = get_turf(active) + if(!T) + active = null + return + var/datum/gas_mixture/air = T.return_air() + if(!istype(air)) + active = null + return + + data["active"] = 1 + data["SM_area"] = get_area(active) + data["SM_integrity"] = active.get_integrity() + data["SM_power"] = active.power + data["SM_ambienttemp"] = air.temperature + data["SM_ambientpressure"] = air.return_pressure() + data["SM_EPR"] = active.get_epr() + //data["SM_EPR"] = active.get_epr() + if(air.total_moles) + data["SM_gas_O2"] = round(100*air.gas["oxygen"]/air.total_moles,0.01) + data["SM_gas_CO2"] = round(100*air.gas["carbon_dioxide"]/air.total_moles,0.01) + data["SM_gas_N2"] = round(100*air.gas["nitrogen"]/air.total_moles,0.01) + data["SM_gas_PH"] = round(100*air.gas["phoron"]/air.total_moles,0.01) + data["SM_gas_N2O"] = round(100*air.gas["sleeping_agent"]/air.total_moles,0.01) + else + data["SM_gas_O2"] = 0 + data["SM_gas_CO2"] = 0 + data["SM_gas_N2"] = 0 + data["SM_gas_PH"] = 0 + data["SM_gas_N2O"] = 0 + else + var/list/SMS = list() + for(var/obj/machinery/power/supermatter/S in supermatters) + var/area/A = get_area(S) + if(!A) + continue + + SMS.Add(list(list( + "area_name" = A.name, + "integrity" = S.get_integrity(), + "uid" = S.uid + ))) + + data["active"] = 0 + data["supermatters"] = SMS + + return data + +/datum/tgui_module/supermatter_monitor/tgui_act(action, params) + if(..()) + return TRUE + + switch(action) + if("clear") + active = null + . = TRUE + if("refresh") + refresh() + . = TRUE + if("set") + var/newuid = text2num(params["set"]) + for(var/obj/machinery/power/supermatter/S in supermatters) + if(S.uid == newuid) + active = S + . = TRUE + +/datum/tgui_module/supermatter_monitor/ntos + ntos = TRUE \ No newline at end of file diff --git a/code/modules/tgui/states.dm b/code/modules/tgui/states.dm new file mode 100644 index 00000000000..111ee9e30be --- /dev/null +++ b/code/modules/tgui/states.dm @@ -0,0 +1,125 @@ +/** + * Base state and helpers for states. Just does some sanity checks, + * implement a proper state for in-depth checks. + */ + +/** + * public + * + * Checks the UI state for a mob. + * + * required user mob The mob who opened/is using the UI. + * required state datum/ui_state The state to check. + * + * return UI_state The state of the UI. + */ +/datum/proc/tgui_status(mob/user, datum/tgui_state/state) + var/src_object = tgui_host(user) + . = STATUS_CLOSE + if(!state) + return + + if(isobserver(user)) + // // If they turn on ghost AI control, admins can always interact. + // if(user.client.advanced_admin_interaction) + // . = max(., STATUS_INTERACTIVE) + + // Regular ghosts can always at least view if in range. + if(user.client) + var/clientviewlist = getviewsize(user.client.view) + if(get_dist(src_object, user) < max(clientviewlist[1], clientviewlist[2])) + . = max(., STATUS_UPDATE) + + // Check if the state allows interaction + var/result = state.can_use_topic(src_object, user) + . = max(., result) + +/** + * private + * + * Checks if a user can use src_object's UI, and returns the state. + * Can call a mob proc, which allows overrides for each mob. + * + * required src_object datum The object/datum which owns the UI. + * required user mob The mob who opened/is using the UI. + * + * return UI_state The state of the UI. + */ +/datum/tgui_state/proc/can_use_topic(src_object, mob/user) + // Don't allow interaction by default. + return STATUS_CLOSE + +/** + * public + * + * Standard interaction/sanity checks. Different mob types may have overrides. + * + * return UI_state The state of the UI. + */ +/mob/proc/shared_tgui_interaction(src_object) + // Close UIs if mindless. + if(!client) + return STATUS_CLOSE + // Disable UIs if unconcious. + else if(stat) + return STATUS_DISABLED + // Update UIs if incapicitated but concious. + else if(incapacitated()) + return STATUS_UPDATE + return STATUS_INTERACTIVE + +/mob/living/silicon/ai/shared_tgui_interaction(src_object) + // Disable UIs if the AI is unpowered. + if(lacks_power()) + return STATUS_DISABLED + return ..() + +/mob/living/silicon/robot/shared_tgui_interaction(src_object) + // Disable UIs if the Borg is unpowered or locked. + if(!cell || cell.charge <= 0 || lockcharge) + return STATUS_DISABLED + return ..() + +/** + * public + * + * Check the distance for a living mob. + * Really only used for checks outside the context of a mob. + * Otherwise, use shared_living_ui_distance(). + * + * required src_object The object which owns the UI. + * required user mob The mob who opened/is using the UI. + * + * return UI_state The state of the UI. + */ +/atom/proc/contents_tgui_distance(src_object, mob/living/user) + // Just call this mob's check. + return user.shared_living_tgui_distance(src_object) + +/** + * public + * + * Distance versus interaction check. + * + * required src_object atom/movable The object which owns the UI. + * + * return UI_state The state of the UI. + */ +/mob/living/proc/shared_living_tgui_distance(atom/movable/src_object, viewcheck = TRUE) + // If the object is obscured, close it. + if(viewcheck && !(src_object in view(src))) + return STATUS_CLOSE + + var/dist = get_dist(src_object, src) + if(dist <= 1) // Open and interact if 1-0 tiles away. + return STATUS_INTERACTIVE + else if(dist <= 2) // View only if 2-3 tiles away. + return STATUS_UPDATE + else if(dist <= 5) // Disable if 5 tiles away. + return STATUS_DISABLED + return STATUS_CLOSE // Otherwise, we got nothing. + +/mob/living/carbon/human/shared_living_tgui_distance(atom/movable/src_object) + if((TK in mutations) && (get_dist(src, src_object) <= 2)) + return STATUS_INTERACTIVE + return ..() diff --git a/code/modules/tgui/states/admin.dm b/code/modules/tgui/states/admin.dm new file mode 100644 index 00000000000..6d1c680927a --- /dev/null +++ b/code/modules/tgui/states/admin.dm @@ -0,0 +1,12 @@ + /** + * tgui state: admin_state + * + * Checks that the user is an admin, end-of-story. + **/ + +GLOBAL_DATUM_INIT(tgui_admin_state, /datum/tgui_state/admin_state, new) + +/datum/tgui_state/admin_state/can_use_topic(src_object, mob/user) + if(check_rights_for(user.client, R_ADMIN)) + return STATUS_INTERACTIVE + return STATUS_CLOSE diff --git a/code/modules/tgui/states/always.dm b/code/modules/tgui/states/always.dm new file mode 100644 index 00000000000..30915785442 --- /dev/null +++ b/code/modules/tgui/states/always.dm @@ -0,0 +1,11 @@ + + /** + * tgui state: always_state + * + * Always grants the user UI_INTERACTIVE. Period. + **/ + +GLOBAL_DATUM_INIT(tgui_always_state, /datum/tgui_state/always_state, new) + +/datum/tgui_state/always_state/can_use_topic(src_object, mob/user) + return STATUS_INTERACTIVE diff --git a/code/modules/tgui/states/conscious.dm b/code/modules/tgui/states/conscious.dm new file mode 100644 index 00000000000..6bc0c7ec031 --- /dev/null +++ b/code/modules/tgui/states/conscious.dm @@ -0,0 +1,12 @@ + /** + * tgui state: conscious_state + * + * Only checks if the user is conscious. + **/ + +GLOBAL_DATUM_INIT(tgui_conscious_state, /datum/tgui_state/conscious_state, new) + +/datum/tgui_state/conscious_state/can_use_topic(src_object, mob/user) + if(user.stat == CONSCIOUS) + return STATUS_INTERACTIVE + return STATUS_CLOSE diff --git a/code/modules/tgui/states/contained.dm b/code/modules/tgui/states/contained.dm new file mode 100644 index 00000000000..c2fbd0b6b06 --- /dev/null +++ b/code/modules/tgui/states/contained.dm @@ -0,0 +1,12 @@ + /** + * tgui state: contained_state + * + * Checks that the user is inside the src_object. + **/ + +GLOBAL_DATUM_INIT(tgui_contained_state, /datum/tgui_state/contained_state, new) + +/datum/tgui_state/contained_state/can_use_topic(atom/src_object, mob/user) + if(!src_object.contains(user)) + return STATUS_CLOSE + return user.shared_tgui_interaction(src_object) diff --git a/code/modules/tgui/states/deep_inventory.dm b/code/modules/tgui/states/deep_inventory.dm new file mode 100644 index 00000000000..137f262a0ea --- /dev/null +++ b/code/modules/tgui/states/deep_inventory.dm @@ -0,0 +1,12 @@ + /** + * tgui state: deep_inventory_state + * + * Checks that the src_object is in the user's deep (backpack, box, toolbox, etc) inventory. + **/ + +GLOBAL_DATUM_INIT(tgui_deep_inventory_state, /datum/tgui_state/deep_inventory_state, new) + +/datum/tgui_state/deep_inventory_state/can_use_topic(src_object, mob/user) + if(!user.contains(src_object)) + return STATUS_CLOSE + return user.shared_tgui_interaction(src_object) diff --git a/code/modules/tgui/states/default.dm b/code/modules/tgui/states/default.dm new file mode 100644 index 00000000000..ba8d132e0b8 --- /dev/null +++ b/code/modules/tgui/states/default.dm @@ -0,0 +1,79 @@ + /** + * tgui state: default_state + * + * Checks a number of things -- mostly physical distance for humans and view for robots. + **/ + +GLOBAL_DATUM_INIT(tgui_default_state, /datum/tgui_state/default, new) + +/datum/tgui_state/default/can_use_topic(src_object, mob/user) + return user.default_can_use_tgui_topic(src_object) // Call the individual mob-overridden procs. + +/mob/proc/default_can_use_tgui_topic(src_object) + return STATUS_CLOSE // Don't allow interaction by default. + +/mob/living/default_can_use_tgui_topic(src_object) + . = shared_tgui_interaction(src_object) + if(. > STATUS_CLOSE && loc) + . = min(., loc.contents_tgui_distance(src_object, src)) // Check the distance... + if(. == STATUS_INTERACTIVE) // Non-human living mobs can only look, not touch. + return STATUS_UPDATE + +/mob/living/carbon/human/default_can_use_tgui_topic(src_object) + . = shared_tgui_interaction(src_object) + if(. > STATUS_CLOSE) + . = min(., shared_living_tgui_distance(src_object)) // Check the distance... + +/mob/living/silicon/robot/default_can_use_tgui_topic(src_object) + . = shared_tgui_interaction(src_object) + if(. <= STATUS_DISABLED) + return + + // Robots can interact with anything they can see. + var/list/clientviewlist = getviewsize(client.view) + if((src_object in view(src)) && (get_dist(src, src_object) <= min(clientviewlist[1],clientviewlist[2]))) + return STATUS_INTERACTIVE + return STATUS_DISABLED // Otherwise they can keep the UI open. + +/mob/living/silicon/ai/default_can_use_tgui_topic(src_object) + . = shared_tgui_interaction() + if(. != STATUS_INTERACTIVE) + return + + // Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras) + // unless it's on the same level as the object it's interacting with. + var/turf/T = get_turf(src_object) + if(!T || !(z == T.z || (T.z in using_map.player_levels))) + return STATUS_CLOSE + + // If an object is in view then we can interact with it + if(src_object in view(client.view, src)) + return STATUS_INTERACTIVE + + // If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view + if(is_in_chassis()) + //stop AIs from leaving windows open and using then after they lose vision + if(cameranet && !cameranet.checkTurfVis(get_turf(src_object))) + return STATUS_CLOSE + return STATUS_INTERACTIVE + else if(get_dist(src_object, src) <= client.view) // View does not return what one would expect while installed in an inteliCard + return STATUS_INTERACTIVE + + return STATUS_CLOSE + +/mob/living/simple_animal/default_can_use_tgui_topic(src_object) + . = shared_tgui_interaction(src_object) + if(. > STATUS_CLOSE) + . = min(., shared_living_tgui_distance(src_object)) //simple animals can only use things they're near. + +/mob/living/silicon/pai/default_can_use_tgui_topic(src_object) + // pAIs can only use themselves and the owner's radio. + if((src_object == src || src_object == radio) && !stat) + return STATUS_INTERACTIVE + else + return ..() + +/mob/observer/dead/default_can_use_tgui_topic() + if(check_rights(R_ADMIN, 0, src)) + return STATUS_INTERACTIVE // Admins are more equal + return STATUS_UPDATE // Ghosts can view updates diff --git a/code/modules/tgui/states/hands.dm b/code/modules/tgui/states/hands.dm new file mode 100644 index 00000000000..0981b5d6ec7 --- /dev/null +++ b/code/modules/tgui/states/hands.dm @@ -0,0 +1,25 @@ + /** + * tgui state: hands_state + * + * Checks that the src_object is in the user's hands. + **/ + +GLOBAL_DATUM_INIT(tgui_hands_state, /datum/tgui_state/hands_state, new) + +/datum/tgui_state/hands_state/can_use_topic(src_object, mob/user) + . = user.shared_tgui_interaction(src_object) + if(. > STATUS_CLOSE) + return min(., user.hands_can_use_tgui_topic(src_object)) + +/mob/proc/hands_can_use_tgui_topic(src_object) + return STATUS_CLOSE + +/mob/living/hands_can_use_tgui_topic(src_object) + if(src_object in get_all_held_items()) + return STATUS_INTERACTIVE + return STATUS_CLOSE + +/mob/living/silicon/robot/hands_can_use_tgui_topic(src_object) + if(activated(src_object)) + return STATUS_INTERACTIVE + return STATUS_CLOSE diff --git a/code/modules/tgui/states/human_adjacent.dm b/code/modules/tgui/states/human_adjacent.dm new file mode 100644 index 00000000000..8164d5f9cee --- /dev/null +++ b/code/modules/tgui/states/human_adjacent.dm @@ -0,0 +1,17 @@ + + /** + * tgui state: human_adjacent_state + * + * In addition to default checks, only allows interaction for a + * human adjacent user. + **/ + +GLOBAL_DATUM_INIT(tgui_human_adjacent_state, /datum/tgui_state/human_adjacent_state, new) + +/datum/tgui_state/human_adjacent_state/can_use_topic(src_object, mob/user) + . = user.default_can_use_tgui_topic(src_object) + + var/dist = get_dist(src_object, user) + if((dist > 1) || (!ishuman(user))) + // Can't be used unless adjacent and human, even with TK + . = min(., STATUS_UPDATE) diff --git a/code/modules/tgui/states/inventory.dm b/code/modules/tgui/states/inventory.dm new file mode 100644 index 00000000000..92274cc1f2e --- /dev/null +++ b/code/modules/tgui/states/inventory.dm @@ -0,0 +1,12 @@ + /** + * tgui state: inventory_state + * + * Checks that the src_object is in the user's top-level (hand, ear, pocket, belt, etc) inventory. + **/ + +GLOBAL_DATUM_INIT(tgui_inventory_state, /datum/tgui_state/inventory_state, new) + +/datum/tgui_state/inventory_state/can_use_topic(src_object, mob/user) + if(!(src_object in user)) + return STATUS_CLOSE + return user.shared_tgui_interaction(src_object) diff --git a/code/modules/tgui/states/inventory_vr.dm b/code/modules/tgui/states/inventory_vr.dm new file mode 100644 index 00000000000..b8e3ea224c2 --- /dev/null +++ b/code/modules/tgui/states/inventory_vr.dm @@ -0,0 +1,26 @@ +GLOBAL_DATUM_INIT(tgui_glasses_state, /datum/tgui_state/glasses_state, new) +/datum/tgui_state/glasses_state/can_use_topic(var/src_object, var/mob/user) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.glasses == src_object) + return user.shared_tgui_interaction() + + return STATUS_CLOSE + +GLOBAL_DATUM_INIT(tgui_nif_state, /datum/tgui_state/nif_state, new) +/datum/tgui_state/nif_state/can_use_topic(var/src_object, var/mob/user) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.nif && H.nif.stat == NIF_WORKING && src_object == H.nif) + return user.shared_tgui_interaction() + + return STATUS_CLOSE + +GLOBAL_DATUM_INIT(tgui_commlink_state, /datum/tgui_state/commlink_state, new) +/datum/tgui_state/commlink_state/can_use_topic(var/src_object, var/mob/user) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.nif && H.nif.stat == NIF_WORKING && H.nif.comm == src_object) + return user.shared_tgui_interaction() + + return STATUS_CLOSE diff --git a/code/modules/tgui/states/not_incapacitated.dm b/code/modules/tgui/states/not_incapacitated.dm new file mode 100644 index 00000000000..1185b516478 --- /dev/null +++ b/code/modules/tgui/states/not_incapacitated.dm @@ -0,0 +1,29 @@ + /** + * tgui state: not_incapacitated_state + * + * Checks that the user isn't incapacitated + **/ + +GLOBAL_DATUM_INIT(tgui_not_incapacitated_state, /datum/tgui_state/not_incapacitated_state, new) + + /** + * tgui state: not_incapacitated_turf_state + * + * Checks that the user isn't incapacitated and that their loc is a turf + **/ + +GLOBAL_DATUM_INIT(tgui_not_incapacitated_turf_state, /datum/tgui_state/not_incapacitated_state, new(no_turfs = TRUE)) + +/datum/tgui_state/not_incapacitated_state + var/turf_check = FALSE + +/datum/tgui_state/not_incapacitated_state/New(loc, no_turfs = FALSE) + ..() + turf_check = no_turfs + +/datum/tgui_state/not_incapacitated_state/can_use_topic(src_object, mob/user) + if(user.stat) + return STATUS_CLOSE + if(user.incapacitated() || (turf_check && !isturf(user.loc))) + return STATUS_DISABLED + return STATUS_INTERACTIVE diff --git a/code/modules/tgui/states/notcontained.dm b/code/modules/tgui/states/notcontained.dm new file mode 100644 index 00000000000..01811d427f2 --- /dev/null +++ b/code/modules/tgui/states/notcontained.dm @@ -0,0 +1,26 @@ + /** + * tgui state: notcontained_state + * + * Checks that the user is not inside src_object, and then makes the default checks. + **/ + +GLOBAL_DATUM_INIT(tgui_notcontained_state, /datum/tgui_state/notcontained_state, new) + +/datum/tgui_state/notcontained_state/can_use_topic(atom/src_object, mob/user) + . = user.shared_tgui_interaction(src_object) + if(. > STATUS_CLOSE) + return min(., user.notcontained_can_use_tgui_topic(src_object)) + +/mob/proc/notcontained_can_use_tgui_topic(src_object) + return STATUS_CLOSE + +/mob/living/notcontained_can_use_tgui_topic(atom/src_object) + if(src_object.contains(src)) + return STATUS_CLOSE // Close if we're inside it. + return default_can_use_tgui_topic(src_object) + +/mob/living/silicon/notcontained_can_use_tgui_topic(src_object) + return default_can_use_tgui_topic(src_object) // Silicons use default bevhavior. + +/mob/living/simple_animal/drone/notcontained_can_use_tgui_topic(src_object) + return default_can_use_tgui_topic(src_object) // Drones use default bevhavior. diff --git a/code/modules/tgui/states/observer.dm b/code/modules/tgui/states/observer.dm new file mode 100644 index 00000000000..bf98f444654 --- /dev/null +++ b/code/modules/tgui/states/observer.dm @@ -0,0 +1,15 @@ + /** + * tgui state: observer_state + * + * Checks that the user is an observer/ghost. + **/ + +GLOBAL_DATUM_INIT(tgui_observer_state, /datum/tgui_state/observer_state, new) + +/datum/tgui_state/observer_state/can_use_topic(src_object, mob/user) + if(isobserver(user)) + return STATUS_INTERACTIVE + if(check_rights(R_ADMIN, 0, src)) + return STATUS_INTERACTIVE + return STATUS_CLOSE + diff --git a/code/modules/tgui/states/physical.dm b/code/modules/tgui/states/physical.dm new file mode 100644 index 00000000000..a57a321e958 --- /dev/null +++ b/code/modules/tgui/states/physical.dm @@ -0,0 +1,24 @@ + /** + * tgui state: physical_state + * + * Short-circuits the default state to only check physical distance. + **/ + +GLOBAL_DATUM_INIT(tgui_physical_state, /datum/tgui_state/physical, new) + +/datum/tgui_state/physical/can_use_topic(src_object, mob/user) + . = user.shared_tgui_interaction(src_object) + if(. > STATUS_CLOSE) + return min(., user.physical_can_use_tgui_topic(src_object)) + +/mob/proc/physical_can_use_tgui_topic(src_object) + return STATUS_CLOSE + +/mob/living/physical_can_use_tgui_topic(src_object) + return shared_living_tgui_distance(src_object) + +/mob/living/silicon/physical_can_use_tgui_topic(src_object) + return max(STATUS_UPDATE, shared_living_tgui_distance(src_object)) // Silicons can always see. + +/mob/living/silicon/ai/physical_can_use_tgui_topic(src_object) + return STATUS_UPDATE // AIs are not physical. diff --git a/code/modules/tgui/states/self.dm b/code/modules/tgui/states/self.dm new file mode 100644 index 00000000000..109fd6ae440 --- /dev/null +++ b/code/modules/tgui/states/self.dm @@ -0,0 +1,12 @@ + /** + * tgui state: self_state + * + * Only checks that the user and src_object are the same. + **/ + +GLOBAL_DATUM_INIT(tgui_self_state, /datum/tgui_state/self_state, new) + +/datum/tgui_state/self_state/can_use_topic(src_object, mob/user) + if(src_object != user) + return STATUS_CLOSE + return user.shared_tgui_interaction(src_object) diff --git a/code/modules/tgui/states/zlevel.dm b/code/modules/tgui/states/zlevel.dm new file mode 100644 index 00000000000..a589a4b64d7 --- /dev/null +++ b/code/modules/tgui/states/zlevel.dm @@ -0,0 +1,14 @@ + /** + * tgui state: z_state + * + * Only checks that the Z-level of the user and src_object are the same. + **/ + +GLOBAL_DATUM_INIT(tgui_z_state, /datum/tgui_state/z_state, new) + +/datum/tgui_state/z_state/can_use_topic(src_object, mob/user) + var/turf/turf_obj = get_turf(src_object) + var/turf/turf_usr = get_turf(user) + if(turf_obj && turf_usr && turf_obj.z == turf_usr.z) + return STATUS_INTERACTIVE + return STATUS_CLOSE diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm new file mode 100644 index 00000000000..191078f6756 --- /dev/null +++ b/code/modules/tgui/tgui.dm @@ -0,0 +1,318 @@ +/** + * tgui + * + * /tg/station user interface library + */ + +/** + * tgui datum (represents a UI). + */ +/datum/tgui + /// The mob who opened/is using the UI. + var/mob/user + /// The object which owns the UI. + var/datum/src_object + /// The title of te UI. + var/title + /// The window_id for browse() and onclose(). + var/datum/tgui_window/window + /// Key that is used for remembering the window geometry. + var/window_key + /// Deprecated: Window size. + var/window_size + /// The interface (template) to be used for this UI. + var/interface + /// Update the UI every MC tick. + var/autoupdate = TRUE + /// If the UI has been initialized yet. + var/initialized = FALSE + /// Time of opening the window. + var/opened_at + /// Stops further updates when close() was called. + var/closing = FALSE + /// The status/visibility of the UI. + var/status = STATUS_INTERACTIVE + /// Topic state used to determine status/interactability. + var/datum/tgui_state/state = null + /// The map z-level to display. + var/map_z_level = 1 + /// The Parent UI + var/datum/tgui/parent_ui + /// Children of this UI + var/list/children = list() + +/** + * public + * + * Create a new UI. + * + * required user mob The mob who opened/is using the UI. + * required src_object datum The object or datum which owns the UI. + * required interface string The interface used to render the UI. + * optional title string The title of the UI. + * optional parent_ui datum/tgui The parent of this UI. + * optional ui_x int Deprecated: Window width. + * optional ui_y int Deprecated: Window height. + * + * return datum/tgui The requested UI. + */ +/datum/tgui/New(mob/user, datum/src_object, interface, title, datum/tgui/parent_ui, ui_x, ui_y) + src.user = user + src.src_object = src_object + src.window_key = "[REF(src_object)]-main" + src.interface = interface + if(title) + src.title = title + src.state = src_object.tgui_state() + src.parent_ui = parent_ui + if(parent_ui) + parent_ui.children += src + // Deprecated + if(ui_x && ui_y) + src.window_size = list(ui_x, ui_y) + +/** + * public + * + * Open this UI (and initialize it with data). + */ +/datum/tgui/proc/open() + if(!user.client) + return null + if(window) + return null + process_status() + if(status < STATUS_UPDATE) + return null + window = SStgui.request_pooled_window(user) + if(!window) + return null + opened_at = world.time + window.acquire_lock(src) + if(!window.is_ready()) + window.initialize(inline_assets = list( + get_asset_datum(/datum/asset/simple/tgui) + )) + else + window.send_message("ping") + window.send_asset(get_asset_datum(/datum/asset/simple/fontawesome)) + for(var/datum/asset/asset in src_object.ui_assets(user)) + window.send_asset(asset) + window.send_message("update", get_payload( + with_data = TRUE, + with_static_data = TRUE)) + SStgui.on_open(src) + +/** + * public + * + * Close the UI, and all its children. + */ +/datum/tgui/proc/close(can_be_suspended = TRUE, logout = FALSE) + if(closing) + return + closing = TRUE + for(var/datum/tgui/child in children) + child.close() + children.Cut() + // If we don't have window_id, open proc did not have the opportunity + // to finish, therefore it's safe to skip this whole block. + if(window) + // Windows you want to keep are usually blue screens of death + // and we want to keep them around, to allow user to read + // the error message properly. + window.release_lock() + window.close(can_be_suspended, logout) + src_object.tgui_close(user) + SStgui.on_close(src) + state = null + parent_ui = null + qdel(src) + +/** + * public + * + * Enable/disable auto-updating of the UI. + * + * required autoupdate bool Enable/disable auto-updating. + */ +/datum/tgui/proc/set_autoupdate(autoupdate) + src.autoupdate = autoupdate + +/** + * public + * + * Replace current ui.state with a new one. + * + * required state datum/ui_state/state Next state + */ +/datum/tgui/proc/set_state(datum/tgui_state/state) + src.state = state + +/** + * public + * + * Makes an asset available to use in tgui. + * + * required asset datum/asset + */ +/datum/tgui/proc/send_asset(datum/asset/asset) + if(!window) + CRASH("send_asset() can only be called after open().") + window.send_asset(asset) + +/** + * public + * + * Send a full update to the client (includes static data). + * + * optional custom_data list Custom data to send instead of ui_data. + * optional force bool Send an update even if UI is not interactive. + */ +/datum/tgui/proc/send_full_update(custom_data, force) + if(!user.client || !initialized || closing) + return + var/should_update_data = force || status >= STATUS_UPDATE + window.send_message("update", get_payload( + custom_data, + with_data = should_update_data, + with_static_data = TRUE)) + +/** + * public + * + * Send a partial update to the client (excludes static data). + * + * optional custom_data list Custom data to send instead of ui_data. + * optional force bool Send an update even if UI is not interactive. + */ +/datum/tgui/proc/send_update(custom_data, force) + if(!user.client || !initialized || closing) + return + var/should_update_data = force || status >= STATUS_UPDATE + window.send_message("update", get_payload( + custom_data, + with_data = should_update_data)) + +/** + * private + * + * Package the data to send to the UI, as JSON. + * + * return list + */ +/datum/tgui/proc/get_payload(custom_data, with_data, with_static_data) + var/list/json_data = list() + json_data["config"] = list( + "title" = title, + "status" = status, + "interface" = interface, + "map" = (using_map && using_map.path) ? using_map.path : "Unknown", + "mapZLevel" = map_z_level, + "window" = list( + "key" = window_key, + "size" = window_size, + "fancy" = user.client.prefs.tgui_fancy, + "locked" = user.client.prefs.tgui_lock, + ), + "user" = list( + "name" = "[user]", + "ckey" = "[user.ckey]", + "observer" = isobserver(user), + ), + ) + var/data = custom_data || with_data && src_object.tgui_data(user, src, state) + if(data) + json_data["data"] = data + var/static_data = with_static_data && src_object.tgui_static_data(user) + if(static_data) + json_data["static_data"] = static_data + if(src_object.tgui_shared_states) + json_data["shared"] = src_object.tgui_shared_states + return json_data + +/** + * private + * + * Run an update cycle for this UI. Called internally by SStgui + * every second or so. + */ +/datum/tgui/process(force = FALSE) + if(closing) + return + var/datum/host = src_object.tgui_host(user) + // If the object or user died (or something else), abort. + if(!src_object || !host || !user || !window) + close(can_be_suspended = FALSE) + return + // Validate ping + if(!initialized && world.time - opened_at > TGUI_PING_TIMEOUT) + log_tgui(user, \ + "Error: Zombie window detected, killing it with fire.\n" \ + + "window_id: [window.id]\n" \ + + "opened_at: [opened_at]\n" \ + + "world.time: [world.time]") + close(can_be_suspended = FALSE) + return + // Update through a normal call to ui_interact + if(status != STATUS_DISABLED && (autoupdate || force)) + src_object.tgui_interact(user, src, parent_ui) + return + // Update status only + var/needs_update = process_status() + if(status <= STATUS_CLOSE) + close() + return + if(needs_update) + window.send_message("update", get_payload()) + +/** + * private + * + * Updates the status, and returns TRUE if status has changed. + */ +/datum/tgui/proc/process_status() + var/prev_status = status + status = src_object.tgui_status(user, state) + if(parent_ui) + status = min(status, parent_ui.status) + return prev_status != status + +/datum/tgui/proc/log_message(message) + log_tgui("[user] ([user.ckey]) using \"[title]\":\n[message]") + +/datum/tgui/proc/set_map_z_level(nz) + map_z_level = nz + +/** + * private + * + * Handle clicks from the UI. + * Call the src_object's ui_act() if status is UI_INTERACTIVE. + * If the src_object's ui_act() returns 1, update all UIs attacked to it. + */ +/datum/tgui/proc/on_message(type, list/payload, list/href_list) + // Pass act type messages to tgui_act + if(type && copytext(type, 1, 5) == "act/") + process_status() + if(src_object.tgui_act(copytext(type, 5), payload, src, state)) + SStgui.update_uis(src_object) + return FALSE + switch(type) + if("ready") + initialized = TRUE + if("pingReply") + initialized = TRUE + if("suspend") + close(can_be_suspended = TRUE) + if("close") + close(can_be_suspended = FALSE) + if("log") + if(href_list["fatal"]) + close(can_be_suspended = FALSE) + if("setSharedState") + if(status != STATUS_INTERACTIVE) + return + LAZYINITLIST(src_object.tgui_shared_states) + src_object.tgui_shared_states[href_list["key"]] = href_list["value"] + SStgui.update_uis(src_object) \ No newline at end of file diff --git a/code/modules/tgui/tgui_window.dm b/code/modules/tgui/tgui_window.dm new file mode 100644 index 00000000000..c78eda86d37 --- /dev/null +++ b/code/modules/tgui/tgui_window.dm @@ -0,0 +1,245 @@ +/** + * Copyright (c) 2020 Aleksej Komarov + * SPDX-License-Identifier: MIT + */ + +/datum/tgui_window + var/id + var/client/client + var/pooled + var/pool_index + var/status = TGUI_WINDOW_CLOSED + var/locked = FALSE + var/datum/tgui/locked_by + var/fatally_errored = FALSE + var/message_queue + var/sent_assets = list() + +/** + * public + * + * Create a new tgui window. + * + * required client /client + * required id string A unique window identifier. + */ +/datum/tgui_window/New(client/client, id, pooled = FALSE) + src.id = id + src.client = client + src.pooled = pooled + if(pooled) + client.tgui_windows[id] = src + src.pool_index = TGUI_WINDOW_INDEX(id) + +/** + * public + * + * Initializes the window with a fresh page. Puts window into the "loading" + * state. You can begin sending messages right after initializing. Messages + * will be put into the queue until the window finishes loading. + * + * optional inline_assets list List of assets to inline into the html. + */ +/datum/tgui_window/proc/initialize(inline_assets = list()) + log_tgui(client, "[id]/initialize") + if(!client) + return + status = TGUI_WINDOW_LOADING + fatally_errored = FALSE + message_queue = null + // Build window options + var/options = "file=[id].html;can_minimize=0;auto_format=0;" + // Remove titlebar and resize handles for a fancy window + if(client.prefs.tgui_fancy) + options += "titlebar=0;can_resize=0;" + else + options += "titlebar=1;can_resize=1;" + // Generate page html + var/html = SStgui.basehtml + html = replacetextEx(html, "\[tgui:windowId]", id) + // Process inline assets + var/inline_styles = "" + var/inline_scripts = "" + for(var/datum/asset/asset in inline_assets) + var/mappings = asset.get_url_mappings() + for(var/name in mappings) + var/url = mappings[name] + // Not urlencoding since asset strings are considered safe + if(copytext(name, -4) == ".css") + inline_styles += "\n" + else if(copytext(name, -3) == ".js") + inline_scripts += "\n" + asset.send() + html = replacetextEx(html, "\n", inline_styles) + html = replacetextEx(html, "\n", inline_scripts) + // Open the window + client << browse(html, "window=[id];[options]") + // Instruct the client to signal UI when the window is closed. + winset(client, id, "on-close=\"uiclose [id]\"") + +/** + * public + * + * Checks if the window is ready to receive data. + * + * return bool + */ +/datum/tgui_window/proc/is_ready() + return status == TGUI_WINDOW_READY + +/** + * public + * + * Checks if the window can be sanely suspended. + * + * return bool + */ +/datum/tgui_window/proc/can_be_suspended() + return !fatally_errored \ + && pooled \ + && pool_index > 0 \ + && pool_index <= TGUI_WINDOW_SOFT_LIMIT \ + && status == TGUI_WINDOW_READY + +/** + * public + * + * Acquire the window lock. Pool will not be able to provide this window + * to other UIs for the duration of the lock. + * + * Can be given an optional tgui datum, which will hook its on_message + * callback into the message stream. + * + * optional ui /datum/tgui + */ +/datum/tgui_window/proc/acquire_lock(datum/tgui/ui) + locked = TRUE + locked_by = ui + +/** + * Release the window lock. + */ +/datum/tgui_window/proc/release_lock() + // Clean up assets sent by tgui datum which requested the lock + if(locked) + sent_assets = list() + locked = FALSE + locked_by = null + +/** + * public + * + * Close the UI. + * + * optional can_be_suspended bool + */ +/datum/tgui_window/proc/close(can_be_suspended = TRUE, logout = FALSE) + if(!client) + return + if(can_be_suspended && can_be_suspended()) + log_tgui(client, "[id]/close: suspending") + status = TGUI_WINDOW_READY + send_message("suspend") + // You would think that BYOND would null out client or make it stop passing istypes or, y'know, ANYTHING during + // logout, but nope! It appears to be perfectly valid to call winset by every means we can measure in Logout, + // and yet it causes a bad client runtime. To avoid that happening, we just have to know if we're in Logout or + // not. + if(!logout && client) + winset(client, null, "mapwindow.map.focus=true") + return + log_tgui(client, "[id]/close") + release_lock() + status = TGUI_WINDOW_CLOSED + message_queue = null + // Do not close the window to give user some time + // to read the error message. + if(!fatally_errored) + client << browse(null, "window=[id]") + if(!logout && client) + winset(client, null, "mapwindow.map.focus=true") +/** + * public + * + * Sends a message to tgui window. + * + * required type string Message type + * required payload list Message payload + * optional force bool Send regardless of the ready status. + */ +/datum/tgui_window/proc/send_message(type, list/payload, force) + if(!client) + return + var/message = json_encode(list( + "type" = type, + "payload" = payload, + )) + // Strip #255/improper. + message = replacetext(message, "\proper", "") + message = replacetext(message, "\improper", "") + // Pack for sending via output() + message = url_encode(message) + // Place into queue if window is still loading + if(!force && status != TGUI_WINDOW_READY) + if(!message_queue) + message_queue = list() + message_queue += list(message) + return + client << output(message, "[id].browser:update") + +/** + * public + * + * Makes an asset available to use in tgui. + * + * required asset datum/asset + */ +/datum/tgui_window/proc/send_asset(datum/asset/asset) + if(!client || !asset) + return + if(istype(asset, /datum/asset/spritesheet)) + var/datum/asset/spritesheet/spritesheet = asset + send_message("asset/stylesheet", spritesheet.css_filename()) + send_message("asset/mappings", asset.get_url_mappings()) + sent_assets += list(asset) + asset.send(client) + +/** + * private + * + * Sends queued messages if the queue wasn't empty. + */ +/datum/tgui_window/proc/flush_message_queue() + if(!client || !message_queue) + return + for(var/message in message_queue) + client << output(message, "[id].browser:update") + message_queue = null + +/** + * private + * + * Callback for handling incoming tgui messages. + */ +/datum/tgui_window/proc/on_message(type, list/payload, list/href_list) + switch(type) + if("ready") + // Status can be READY if user has refreshed the window. + if(status == TGUI_WINDOW_READY) + // Resend the assets + for(var/asset in sent_assets) + send_asset(asset) + status = TGUI_WINDOW_READY + if("log") + if(href_list["fatal"]) + fatally_errored = TRUE + // Pass message to UI that requested the lock + if(locked && locked_by) + locked_by.on_message(type, payload, href_list) + flush_message_queue() + return + // If not locked, handle these message types + switch(type) + if("suspend") + close(can_be_suspended = TRUE) + if("close") + close(can_be_suspended = FALSE) diff --git a/code/modules/turbolift/turbolift_console.dm b/code/modules/turbolift/turbolift_console.dm index d69a9b0a165..9d8b90f8027 100644 --- a/code/modules/turbolift/turbolift_console.dm +++ b/code/modules/turbolift/turbolift_console.dm @@ -143,57 +143,56 @@ /obj/structure/lift/panel/interact(var/mob/user) if(!..()) return + + tgui_interact(user) - var/dat = list() - dat += "
Lift panel
" +/obj/structure/lift/panel/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "Turbolift", name) + ui.open() - //the floors list stores levels in order of increasing Z - //therefore, to display upper levels at the top of the menu and - //lower levels at the bottom, we need to go through the list in reverse +/obj/structure/lift/panel/tgui_data(mob/user) + var/list/data = list() + + data["doors_open"] = lift.doors_are_open() + data["fire_mode"] = lift.fire_mode + + data["floors"] = list() for(var/i in lift.floors.len to 1 step -1) var/datum/turbolift_floor/floor = lift.floors[i] - var/label = floor.label? floor.label : "Level #[i]" - dat += "" - dat += "[label]: [floor.name]
" + data["floors"].Add(list(list( + "id" = i, + "ref" = "\ref[floor]", + "queued" = (floor in lift.queued_floors), + "target" = (lift.target_floor == floor), + "current" = (lift.current_floor == floor), + "label" = floor.label, + "name" = floor.name, + ))) + + return data - dat += "
" - if(lift.doors_are_open()) - dat += "Close Doors
" - else - dat += "Open Doors
" - dat += "Emergency Stop" - dat += "
" +/obj/structure/lift/panel/tgui_act(action, params) + if(..()) + return TRUE - user.set_machine(src) - var/datum/browser/popup = new(user, "turbolift_panel", "Lift Panel", 350, 320) //VOREStation Edit - Wider! - popup.set_content(jointext(dat, null)) - popup.open() - return + switch(action) + if("move_to_floor") + . = TRUE + lift.queue_move_to(locate(params["ref"])) + if("toggle_doors") + . = TRUE + if(lift.doors_are_open()) + lift.close_doors() + else + lift.open_doors() + if("emergency_stop") + . = TRUE + lift.emergency_stop() -/obj/structure/lift/panel/Topic(href, href_list) - . = ..() if(.) - return - - var/panel_interact - if(href_list["move_to_floor"]) - lift.queue_move_to(locate(href_list["move_to_floor"])) - panel_interact = 1 - if(href_list["open_doors"]) - panel_interact = 1 - lift.open_doors() - if(href_list["close_doors"]) - panel_interact = 1 - lift.close_doors() - if(href_list["emergency_stop"]) - panel_interact = 1 - lift.emergency_stop() - - if(panel_interact) pressed(usr) - updateDialog() - - return 0 /obj/structure/lift/panel/update_icon() if(lift.fire_mode) diff --git a/code/modules/vchat/css/ss13styles.css b/code/modules/vchat/css/ss13styles.css index 372c3ecf22a..98dcbc18e82 100644 --- a/code/modules/vchat/css/ss13styles.css +++ b/code/modules/vchat/css/ss13styles.css @@ -162,6 +162,7 @@ h1.alert, h2.alert {color: #000000;} .vulpkanin {color: #B97A57;} .enochian {color: #848A33; letter-spacing:-1pt; word-spacing:4pt; font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;} .daemon {color: #5E339E; letter-spacing:-1pt; word-spacing:0pt; font-family: "Courier New", Courier, monospace;} +.drudakar {color: #bb2463; word-spacing:0pt; font-family: "High Tower Text", monospace;} .bug {color: #9e9e39;} .vox {color: #AA00AA;} .promethean {color: #5A5A5A; font-family:"Comic Sans MS","Comic Sans",cursive;} diff --git a/code/modules/vchat/vchat_client.dm b/code/modules/vchat/vchat_client.dm index 25486ac554e..4a2288faac8 100644 --- a/code/modules/vchat/vchat_client.dm +++ b/code/modules/vchat/vchat_client.dm @@ -407,6 +407,7 @@ var/to_chat_src // Write the messages to the log for(var/list/result in results) o_file << "[result["message"]]
" + CHECK_TICK o_file << "" diff --git a/code/modules/vehicles/Securitrain_vr.dm b/code/modules/vehicles/Securitrain_vr.dm index bb8b0c66f05..1de6b05e369 100644 --- a/code/modules/vehicles/Securitrain_vr.dm +++ b/code/modules/vehicles/Securitrain_vr.dm @@ -166,28 +166,28 @@ else verbs += /obj/vehicle/train/security/engine/verb/stop_engine -/obj/vehicle/train/security/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/train/security/RunOver(var/mob/living/M) var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) - H.apply_effects(5, 5) + M.apply_effects(5, 5) for(var/i = 0, i < rand(1,3), i++) - H.apply_damage(rand(1,5), BRUTE, pick(parts)) + M.apply_damage(rand(1,5), BRUTE, pick(parts)) -/obj/vehicle/train/security/trolley/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/train/security/trolley/RunOver(var/mob/living/M) ..() - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey])") + attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey])") -/obj/vehicle/train/security/engine/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/train/security/engine/RunOver(var/mob/living/M) ..() if(is_train_head() && istype(load, /mob/living/carbon/human)) var/mob/living/carbon/human/D = load - to_chat(D, "You ran over \the [H]!" - visible_message("\The [src] ran over \the [H]!") - add_attack_logs(D,H,"Ran over with [src.name]") - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey]), driven by [D.name] ([D.ckey])") + to_chat(D, "You ran over \the [M]!" + visible_message("\The [src] ran over \the [M]!") + add_attack_logs(D,M,"Ran over with [src.name]") + attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey]), driven by [D.name] ([D.ckey])") else - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey])") + attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey])") //------------------------------------------- diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index 94437458cff..a118b1c2583 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -152,28 +152,28 @@ else verbs += /obj/vehicle/train/engine/verb/stop_engine -/obj/vehicle/train/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/train/RunOver(var/mob/living/M) var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) - H.apply_effects(5, 5) + M.apply_effects(5, 5) for(var/i = 0, i < rand(1,3), i++) - H.apply_damage(rand(1,5), BRUTE, pick(parts)) + M.apply_damage(rand(1,5), BRUTE, pick(parts)) -/obj/vehicle/train/trolley/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/train/trolley/RunOver(var/mob/living/M) ..() - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey])") + attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey])") -/obj/vehicle/train/engine/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/train/engine/RunOver(var/mob/living/M) ..() if(is_train_head() && istype(load, /mob/living/carbon/human)) var/mob/living/carbon/human/D = load - to_chat(D, "You ran over [H]!") - visible_message("\The [src] ran over [H]!") - add_attack_logs(D,H,"Ran over with [src.name]") - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey]), driven by [D.name] ([D.ckey])") + to_chat(D, "You ran over [M]!") + visible_message("\The [src] ran over [M]!") + add_attack_logs(D,M,"Ran over with [src.name]") + attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey]), driven by [D.name] ([D.ckey])") else - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey])") + attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey])") //------------------------------------------- diff --git a/code/modules/vehicles/quad.dm b/code/modules/vehicles/quad.dm index 657d4976f42..3524895ba27 100644 --- a/code/modules/vehicles/quad.dm +++ b/code/modules/vehicles/quad.dm @@ -142,15 +142,15 @@ add_attack_logs(D,M,"Ran over with [src.name]") -/obj/vehicle/train/engine/quadbike/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/train/engine/quadbike/RunOver(var/mob/living/M) ..() var/list/throw_dirs = list(1, 2, 4, 8, 5, 6, 9, 10) if(!emagged) throw_dirs -= dir if(tow) - throw_dirs -= get_dir(H, tow) //Don't throw it at the trailer either. - var/turf/T = get_step(H, pick(throw_dirs)) - H.throw_at(T, 1, 1, src) + throw_dirs -= get_dir(M, tow) //Don't throw it at the trailer either. + var/turf/T = get_step(M, pick(throw_dirs)) + M.throw_at(T, 1, 1, src) /* * Trailer bits and bobs. diff --git a/code/modules/vehicles/rover_vr.dm b/code/modules/vehicles/rover_vr.dm index aa2c29744c3..ff7a4a5b297 100644 --- a/code/modules/vehicles/rover_vr.dm +++ b/code/modules/vehicles/rover_vr.dm @@ -164,28 +164,28 @@ else verbs += /obj/vehicle/train/rover/engine/verb/stop_engine -/obj/vehicle/train/rover/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/train/rover/RunOver(var/mob/living/M) var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) - H.apply_effects(5, 5) + M.apply_effects(5, 5) for(var/i = 0, i < rand(1,3), i++) - H.apply_damage(rand(1,5), BRUTE, pick(parts)) + M.apply_damage(rand(1,5), BRUTE, pick(parts)) -/obj/vehicle/train/rover/trolley/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/train/rover/trolley/RunOver(var/mob/living/M) ..() - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey])") + attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey])") -/obj/vehicle/train/rover/engine/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/train/rover/engine/RunOver(var/mob/living/M) ..() if(is_train_head() && istype(load, /mob/living/carbon/human)) var/mob/living/carbon/human/D = load - to_chat(D, "You ran over \the [H]!") - visible_message("\The [src] ran over \the [H]!") - add_attack_logs(D,H,"Ran over with [src.name]") - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey]), driven by [D.name] ([D.ckey])") + to_chat(D, "You ran over \the [M]!") + visible_message("\The [src] ran over \the [M]!") + add_attack_logs(D,M,"Ran over with [src.name]") + attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey]), driven by [D.name] ([D.ckey])") else - attack_log += text("\[[time_stamp()]\] ran over [H.name] ([H.ckey])") + attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey])") //------------------------------------------- diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index e43228c4bed..44be1f6bd38 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -292,7 +292,7 @@ cell = null powercheck() -/obj/vehicle/proc/RunOver(var/mob/living/carbon/human/H) +/obj/vehicle/proc/RunOver(var/mob/living/M) return //write specifics for different vehicles //------------------------------------------- diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index 4728ed6ecf6..9f472102fdb 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -27,6 +27,9 @@ var/list/ventcrawl_machinery = list( if(!(/mob/living/proc/ventcrawl in verbs)) to_chat(src, "You don't possess the ability to ventcrawl!") return FALSE + if(pulling) + to_chat(src, "You cannot bring \the [pulling] into the vent with you!") + return FALSE if(incapacitated()) to_chat(src, "You cannot ventcrawl in your current state!") return FALSE diff --git a/code/modules/virus2/centrifuge.dm b/code/modules/virus2/centrifuge.dm index 521b74544d4..ee2385d90da 100644 --- a/code/modules/virus2/centrifuge.dm +++ b/code/modules/virus2/centrifuge.dm @@ -26,7 +26,7 @@ O.loc = src user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") - SSnanoui.update_uis(src) + SStgui.update_uis(src) src.attack_hand(user) @@ -36,27 +36,32 @@ icon_state = "centrifuge_moving" /obj/machinery/computer/centrifuge/attack_hand(var/mob/user as mob) - if(..()) return - ui_interact(user) + if(..()) + return + tgui_interact(user) -/obj/machinery/computer/centrifuge/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/computer/centrifuge/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "IsolationCentrifuge", name) + ui.open() - var/data[0] +/obj/machinery/computer/centrifuge/tgui_data(mob/user) + var/list/data = list() data["antibodies"] = null - data["pathogens"] = null + data["pathogens"] = list() data["is_antibody_sample"] = null + data["busy"] = null + data["sample_inserted"] = !!sample - if (curing) + if(curing) data["busy"] = "Isolating antibodies..." - else if (isolating) + else if(isolating) data["busy"] = "Isolating pathogens..." else - data["sample_inserted"] = !!sample - - if (sample) + if(sample) var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list - if (B) + if(B) data["antibodies"] = antigens2string(B.data["antibodies"], none=null) var/list/pathogens[0] @@ -65,8 +70,7 @@ var/datum/disease2/disease/V = virus[ID] pathogens.Add(list(list("name" = V.name(), "spread_type" = V.spreadtype, "reference" = "\ref[V]"))) - if (pathogens.len > 0) - data["pathogens"] = pathogens + data["pathogens"] = pathogens else var/datum/reagent/antibodies/A = locate(/datum/reagent/antibodies) in sample.reagents.reagent_list @@ -74,103 +78,90 @@ data["antibodies"] = antigens2string(A.data["antibodies"], none=null) data["is_antibody_sample"] = 1 - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "isolation_centrifuge.tmpl", src.name, 400, 500) - ui.set_initial_data(data) - ui.open() + return data /obj/machinery/computer/centrifuge/process() ..() - if (stat & (NOPOWER|BROKEN)) return + if(stat & (NOPOWER|BROKEN)) return - if (curing) + if(curing) curing -= 1 - if (curing == 0) + if(curing == 0) cure() - if (isolating) + if(isolating) isolating -= 1 if(isolating == 0) isolate() -/obj/machinery/computer/centrifuge/Topic(href, href_list) - if (..()) return 1 +/obj/machinery/computer/centrifuge/tgui_act(action, params) + if(..()) + return TRUE var/mob/user = usr - var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") + add_fingerprint(user) - src.add_fingerprint(user) - if (href_list["close"]) - user.unset_machine() - ui.close() - return 0 - - if (href_list["print"]) - print(user) - return 1 - - if(href_list["isolate"]) - var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list - if (B) - var/datum/disease2/disease/virus = locate(href_list["isolate"]) - virus2 = virus.getcopy() - isolating = 40 - update_icon() - return 1 - - switch(href_list["action"]) - if ("antibody") + switch(action) + if("print") + print(user) + . = TRUE + if("isolate") + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list + if(B) + var/datum/disease2/disease/virus = locate(params["isolate"]) + virus2 = virus.getcopy() + isolating = 40 + update_icon() + . = TRUE + if("antibody") var/delay = 20 var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list - if (!B) + if(!B) state("\The [src] buzzes, \"No antibody carrier detected.\"", "blue") - return 1 + return TRUE var/has_toxins = locate(/datum/reagent/toxin) in sample.reagents.reagent_list var/has_radium = sample.reagents.has_reagent("radium") - if (has_toxins || has_radium) + if(has_toxins || has_radium) state("\The [src] beeps, \"Pathogen purging speed above nominal.\"", "blue") - if (has_toxins) + if(has_toxins) delay = delay/2 - if (has_radium) + if(has_radium) delay = delay/2 curing = round(delay) playsound(src, 'sound/machines/juicer.ogg', 50, 1) update_icon() - return 1 - + . = TRUE if("sample") if(sample) sample.loc = src.loc sample = null - return 1 + . = TRUE - return 0 /obj/machinery/computer/centrifuge/proc/cure() - if (!sample) return + if(!sample) return var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list - if (!B) return + if(!B) return var/list/data = list("antibodies" = B.data["antibodies"]) var/amt= sample.reagents.get_reagent_amount("blood") sample.reagents.remove_reagent("blood", amt) sample.reagents.add_reagent("antibodies", amt, data) - SSnanoui.update_uis(src) + SStgui.update_uis(src) update_icon() ping("\The [src] pings, \"Antibody isolated.\"") /obj/machinery/computer/centrifuge/proc/isolate() - if (!sample) return + if(!sample) return var/obj/item/weapon/virusdish/dish = new/obj/item/weapon/virusdish(loc) dish.virus2 = virus2 virus2 = null - SSnanoui.update_uis(src) + SStgui.update_uis(src) update_icon() ping("\The [src] pings, \"Pathogen isolated.\"") @@ -182,20 +173,20 @@ Sample: [sample.name]
"} - if (user) + if(user) P.info += "Generated By: [user.name]
" P.info += "
" var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list - if (B) + if(B) P.info += "Antibodies: " P.info += antigens2string(B.data["antibodies"]) P.info += "
" var/list/virus = B.data["virus2"] P.info += "Pathogens:
" - if (virus.len > 0) + if(virus.len > 0) for (var/ID in virus) var/datum/disease2/disease/V = virus[ID] P.info += "[V.name()]
" @@ -204,7 +195,7 @@ else var/datum/reagent/antibodies/A = locate(/datum/reagent/antibodies) in sample.reagents.reagent_list - if (A) + if(A) P.info += "The following antibodies have been isolated from the blood sample: " P.info += antigens2string(A.data["antibodies"]) P.info += "
" diff --git a/code/modules/virus2/disease2.dm b/code/modules/virus2/disease2.dm index d62502084a0..9d37b1db291 100644 --- a/code/modules/virus2/disease2.dm +++ b/code/modules/virus2/disease2.dm @@ -245,6 +245,26 @@ var/global/list/virusDB = list() return r +/datum/disease2/disease/proc/get_tgui_info() + . = list( + "name" = name(), + "spreadtype" = spreadtype, + "antigen" = antigens2string(antigen), + "rate" = stageprob * 10, + "resistance" = resistance, + "species" = jointext(affected_species, ", "), + "symptoms" = list(), + "ref" = "\ref[src]", + ) + + for(var/datum/disease2/effectholder/E in effects) + .["symptoms"].Add(list(list( + "stage" = E.stage, + "name" = E.effect.name, + "strength" = "[E.multiplier >= 3 ? "Severe" : E.multiplier > 1 ? "Above Average" : "Average"]", + "aggressiveness" = E.chance * 15, + ))) + /datum/disease2/disease/proc/addToDB() if ("[uniqueID]" in virusDB) return 0 @@ -252,6 +272,8 @@ var/global/list/virusDB = list() v.fields["id"] = uniqueID v.fields["name"] = name() v.fields["description"] = get_info() + v.fields["tgui_description"] = get_tgui_info() + v.fields["tgui_description"]["record"] = "\ref[v]" v.fields["antigen"] = antigens2string(antigen) v.fields["spread type"] = spreadtype virusDB["[uniqueID]"] = v diff --git a/code/modules/virus2/diseasesplicer.dm b/code/modules/virus2/diseasesplicer.dm index 95657498a03..fb682f51d15 100644 --- a/code/modules/virus2/diseasesplicer.dm +++ b/code/modules/virus2/diseasesplicer.dm @@ -20,7 +20,7 @@ if(istype(I,/obj/item/weapon/virusdish)) var/mob/living/carbon/c = user - if (dish) + if(dish) to_chat(user, "\The [src] is already loaded.") return @@ -40,36 +40,46 @@ return src.attack_hand(user) /obj/machinery/computer/diseasesplicer/attack_hand(var/mob/user as mob) - if(..()) return - ui_interact(user) + if(..()) + return TRUE + tgui_interact(user) -/obj/machinery/computer/diseasesplicer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/computer/diseasesplicer/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "DiseaseSplicer", name) + ui.open() - var/data[0] +/obj/machinery/computer/diseasesplicer/tgui_data(mob/user) + var/list/data = list() data["dish_inserted"] = !!dish - data["growth"] = 0 - data["affected_species"] = null - if (memorybank) + data["buffer"] = null + if(memorybank) data["buffer"] = list("name" = (analysed ? memorybank.effect.name : "Unknown Symptom"), "stage" = memorybank.effect.stage) - if (species_buffer) + data["species_buffer"] = null + if(species_buffer) data["species_buffer"] = analysed ? jointext(species_buffer, ", ") : "Unknown Species" - if (splicing) + data["effects"] = null + data["info"] = null + data["growth"] = 0 + data["affected_species"] = null + data["busy"] = null + if(splicing) data["busy"] = "Splicing..." - else if (scanning) + else if(scanning) data["busy"] = "Scanning..." - else if (burning) + else if(burning) data["busy"] = "Copying data to disk..." - else if (dish) + else if(dish) data["growth"] = min(dish.growth, 100) - if (dish.virus2) - if (dish.virus2.affected_species) - data["affected_species"] = dish.analysed ? jointext(dish.virus2.affected_species, ", ") : "Unknown" + if(dish.virus2) + if(dish.virus2.affected_species) + data["affected_species"] = dish.analysed ? dish.virus2.affected_species : list() - if (dish.growth >= 50) + if(dish.growth >= 50) var/list/effects[0] for (var/datum/disease2/effectholder/e in dish.virus2.effects) effects.Add(list(list("name" = (dish.analysed ? e.effect.name : "Unknown"), "stage" = (e.stage), "reference" = "\ref[e]"))) @@ -81,11 +91,7 @@ else data["info"] = "No dish loaded." - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "disease_splicer.tmpl", src.name, 400, 600) - ui.set_initial_data(data) - ui.open() + return data /obj/machinery/computer/diseasesplicer/process() if(stat & (NOPOWER|BROKEN)) @@ -95,100 +101,94 @@ scanning -= 1 if(!scanning) ping("\The [src] pings, \"Analysis complete.\"") - SSnanoui.update_uis(src) + SStgui.update_uis(src) if(splicing) splicing -= 1 if(!splicing) ping("\The [src] pings, \"Splicing operation complete.\"") - SSnanoui.update_uis(src) + SStgui.update_uis(src) if(burning) burning -= 1 if(!burning) var/obj/item/weapon/diseasedisk/d = new /obj/item/weapon/diseasedisk(src.loc) d.analysed = analysed if(analysed) - if (memorybank) + if(memorybank) d.name = "[memorybank.effect.name] GNA disk (Stage: [memorybank.effect.stage])" d.effect = memorybank - else if (species_buffer) + else if(species_buffer) d.name = "[jointext(species_buffer, ", ")] GNA disk" d.species = species_buffer else - if (memorybank) + if(memorybank) d.name = "Unknown GNA disk (Stage: [memorybank.effect.stage])" d.effect = memorybank - else if (species_buffer) + else if(species_buffer) d.name = "Unknown Species GNA disk" d.species = species_buffer ping("\The [src] pings, \"Backup disk saved.\"") - SSnanoui.update_uis(src) + SStgui.update_uis(src) -/obj/machinery/computer/diseasesplicer/Topic(href, href_list) - if(..()) return 1 +/obj/machinery/computer/diseasesplicer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE var/mob/user = usr - var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") + add_fingerprint(user) - src.add_fingerprint(user) + switch(action) + if("grab") + if(dish) + memorybank = locate(params["grab"]) + species_buffer = null + analysed = dish.analysed + dish = null + scanning = 10 + . = TRUE - if (href_list["close"]) - user.unset_machine() - ui.close() - return 0 + if("affected_species") + if(dish) + memorybank = null + species_buffer = dish.virus2.affected_species + analysed = dish.analysed + dish = null + scanning = 10 + . = TRUE - if (href_list["grab"]) - if (dish) - memorybank = locate(href_list["grab"]) - species_buffer = null - analysed = dish.analysed - dish = null - scanning = 10 - return 1 + if("eject") + if(dish) + dish.loc = src.loc + dish = null + . = TRUE - if (href_list["affected_species"]) - if (dish) - memorybank = null - species_buffer = dish.virus2.affected_species - analysed = dish.analysed - dish = null - scanning = 10 - return 1 + if("splice") + if(dish) + var/target = text2num(params["splice"]) // target = 1 to 4 for effects, 5 for species + if(memorybank && 0 < target && target <= 4) + if(target < memorybank.effect.stage) return // too powerful, catching this for href exploit prevention - if(href_list["eject"]) - if (dish) - dish.loc = src.loc - dish = null - return 1 + var/datum/disease2/effectholder/target_holder + var/list/illegal_types = list() + for(var/datum/disease2/effectholder/e in dish.virus2.effects) + if(e.stage == target) + target_holder = e + else + illegal_types += e.effect.type + if(memorybank.effect.type in illegal_types) return + target_holder.effect = memorybank.effect - if(href_list["splice"]) - if(dish) - var/target = text2num(href_list["splice"]) // target = 1 to 4 for effects, 5 for species - if(memorybank && 0 < target && target <= 4) - if(target < memorybank.effect.stage) return // too powerful, catching this for href exploit prevention + else if(species_buffer && target == 5) + dish.virus2.affected_species = species_buffer - var/datum/disease2/effectholder/target_holder - var/list/illegal_types = list() - for(var/datum/disease2/effectholder/e in dish.virus2.effects) - if(e.stage == target) - target_holder = e - else - illegal_types += e.effect.type - if(memorybank.effect.type in illegal_types) return - target_holder.effect = memorybank.effect + else + return - else if(species_buffer && target == 5) - dish.virus2.affected_species = species_buffer + splicing = 10 + dish.virus2.uniqueID = rand(0,10000) + . = TRUE - else - return + if("disk") + burning = 10 + . = TRUE - splicing = 10 - dish.virus2.uniqueID = rand(0,10000) - return 1 - - if(href_list["disk"]) - burning = 10 - return 1 - - return 0 diff --git a/code/modules/virus2/dishincubator.dm b/code/modules/virus2/dishincubator.dm index 15638718a4d..9dd935247ad 100644 --- a/code/modules/virus2/dishincubator.dm +++ b/code/modules/virus2/dishincubator.dm @@ -30,7 +30,7 @@ O.loc = src user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") - SSnanoui.update_uis(src) + SStgui.update_uis(src) src.attack_hand(user) return @@ -46,17 +46,23 @@ O.loc = src user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") - SSnanoui.update_uis(src) + SStgui.update_uis(src) src.attack_hand(user) /obj/machinery/disease2/incubator/attack_hand(mob/user as mob) - if(stat & (NOPOWER|BROKEN)) return - ui_interact(user) + if(stat & (NOPOWER|BROKEN)) + return + tgui_interact(user) -/obj/machinery/disease2/incubator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/disease2/incubator/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "DishIncubator", name) + ui.set_autoupdate(FALSE) + ui.open() +/obj/machinery/disease2/incubator/tgui_data(mob/user) var/data[0] data["chemicals_inserted"] = !!beaker data["dish_inserted"] = !!dish @@ -74,23 +80,19 @@ data["can_breed_virus"] = null data["blood_already_infected"] = null - if (beaker) + if(beaker) var/datum/reagent/blood/B = locate(/datum/reagent/blood) in beaker.reagents.reagent_list data["can_breed_virus"] = dish && dish.virus2 && B - if (B) - if (!B.data["virus2"]) + if(B) + if(!B.data["virus2"]) B.data["virus2"] = list() var/list/virus = B.data["virus2"] for (var/ID in virus) data["blood_already_infected"] = virus[ID] - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "dish_incubator.tmpl", src.name, 400, 600) - ui.set_initial_data(data) - ui.open() + return data /obj/machinery/disease2/incubator/process() if(dish && on && dish.virus2) @@ -105,7 +107,7 @@ foodsupply -= 1 dish.growth += 3 - SSnanoui.update_uis(src) + SStgui.update_uis(src) if(radiation) if(radiation > 50 & prob(5)) @@ -118,90 +120,82 @@ else if(prob(5)) dish.virus2.minormutate() radiation -= 1 - SSnanoui.update_uis(src) + SStgui.update_uis(src) if(toxins && prob(5)) dish.virus2.infectionchance -= 1 - SSnanoui.update_uis(src) + SStgui.update_uis(src) if(toxins > 50) dish.growth = 0 dish.virus2 = null - SSnanoui.update_uis(src) + SStgui.update_uis(src) else if(!dish) on = 0 icon_state = "incubator" - SSnanoui.update_uis(src) + SStgui.update_uis(src) if(beaker) if(foodsupply < 100 && beaker.reagents.remove_reagent("virusfood",5)) if(foodsupply + 10 <= 100) foodsupply += 10 - SSnanoui.update_uis(src) + SStgui.update_uis(src) - if (locate(/datum/reagent/toxin) in beaker.reagents.reagent_list && toxins < 100) + if(locate(/datum/reagent/toxin) in beaker.reagents.reagent_list && toxins < 100) for(var/datum/reagent/toxin/T in beaker.reagents.reagent_list) toxins += max(T.strength,1) beaker.reagents.remove_reagent(T.id,1) if(toxins > 100) toxins = 100 break - SSnanoui.update_uis(src) + SStgui.update_uis(src) -/obj/machinery/disease2/incubator/Topic(href, href_list) - if (..()) return 1 +/obj/machinery/disease2/incubator/tgui_act(action, params) + if(..()) + return TRUE var/mob/user = usr - var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") + add_fingerprint(user) + switch(action) + if("ejectchem") + if(beaker) + beaker.loc = src.loc + beaker = null + . = TRUE - src.add_fingerprint(user) + if("power") + if(dish) + on = !on + icon_state = on ? "incubator_on" : "incubator" + . = TRUE - if (href_list["close"]) - user.unset_machine() - ui.close() - return 0 + if("ejectdish") + if(dish) + dish.loc = src.loc + dish = null + . = TRUE - if (href_list["ejectchem"]) - if(beaker) - beaker.loc = src.loc - beaker = null - return 1 + if("rad") + radiation = min(100, radiation + 10) + . = TRUE - if (href_list["power"]) - if (dish) - on = !on - icon_state = on ? "incubator_on" : "incubator" - return 1 + if("flush") + radiation = 0 + toxins = 0 + foodsupply = 0 + . = TRUE - if (href_list["ejectdish"]) - if(dish) - dish.loc = src.loc - dish = null - return 1 + if("virus") + if(!dish) + return TRUE - if (href_list["rad"]) - radiation = min(100, radiation + 10) - return 1 + var/datum/reagent/blood/B = locate(/datum/reagent/blood) in beaker.reagents.reagent_list + if(!B) + return TRUE - if (href_list["flush"]) - radiation = 0 - toxins = 0 - foodsupply = 0 - return 1 + if(!B.data["virus2"]) + B.data["virus2"] = list() - if(href_list["virus"]) - if (!dish) - return 1 + var/list/virus = list("[dish.virus2.uniqueID]" = dish.virus2.getcopy()) + B.data["virus2"] += virus - var/datum/reagent/blood/B = locate(/datum/reagent/blood) in beaker.reagents.reagent_list - if (!B) - return 1 - - if (!B.data["virus2"]) - B.data["virus2"] = list() - - var/list/virus = list("[dish.virus2.uniqueID]" = dish.virus2.getcopy()) - B.data["virus2"] += virus - - ping("\The [src] pings, \"Injection complete.\"") - return 1 - - return 0 + ping("\The [src] pings, \"Injection complete.\"") + . = TRUE diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index 790bf3cdbdc..876d0d30b69 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -404,7 +404,7 @@ stage = 2 /datum/disease2/effect/blind/activate(var/mob/living/carbon/mob,var/multiplier) - mob.eye_blind = max(mob.eye_blind, 4) + mob.SetBlinded(4) /datum/disease2/effect/cough name = "Severe Cough" diff --git a/code/modules/virus2/isolator.dm b/code/modules/virus2/isolator.dm index 2a6d39d230c..ff5e6dbcfe7 100644 --- a/code/modules/virus2/isolator.dm +++ b/code/modules/virus2/isolator.dm @@ -1,8 +1,3 @@ -// UI menu navigation -#define HOME "home" -#define LIST "list" -#define ENTRY "entry" - /obj/machinery/disease2/isolator/ name = "pathogenic isolator" desc = "Used to isolate and identify diseases, allowing for comparison with a remote database." @@ -11,9 +6,7 @@ icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit icon_state = "isolator" var/isolating = 0 - var/state = HOME var/datum/disease2/disease/virus2 = null - var/datum/data/record/entry = null var/obj/item/weapon/reagent_containers/syringe/sample = null /obj/machinery/disease2/isolator/update_icon() @@ -44,71 +37,57 @@ S.loc = src user.visible_message("[user] adds \a [O] to \the [src]!", "You add \a [O] to \the [src]!") - SSnanoui.update_uis(src) + SStgui.update_uis(src) update_icon() src.attack_hand(user) /obj/machinery/disease2/isolator/attack_hand(mob/user as mob) - if(stat & (NOPOWER|BROKEN)) return - ui_interact(user) + if(stat & (NOPOWER|BROKEN)) + return + tgui_interact(user) -/obj/machinery/disease2/isolator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - user.set_machine(src) +/obj/machinery/disease2/isolator/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PathogenicIsolator", name) + ui.open() - var/data[0] + +/obj/machinery/disease2/isolator/tgui_data(mob/user) + var/list/data = list() data["syringe_inserted"] = !!sample data["isolating"] = isolating data["pathogen_pool"] = null - data["state"] = state - data["entry"] = entry - data["can_print"] = (state != HOME || sample) && !isolating + data["can_print"] = !isolating - switch (state) - if (HOME) - if (sample) - var/list/pathogen_pool[0] - for(var/datum/reagent/blood/B in sample.reagents.reagent_list) - var/list/virus = B.data["virus2"] - for (var/ID in virus) - var/datum/disease2/disease/V = virus[ID] - var/datum/data/record/R = null - if (ID in virusDB) - R = virusDB[ID] + var/list/pathogen_pool = list() + if(sample) + for(var/datum/reagent/blood/B in sample.reagents.reagent_list) + var/list/virus = B.data["virus2"] + for (var/ID in virus) + var/datum/disease2/disease/V = virus[ID] + var/datum/data/record/R = null + if (ID in virusDB) + R = virusDB[ID] - var/mob/living/carbon/human/D = B.data["donor"] - pathogen_pool.Add(list(list(\ - "name" = "[D.get_species()] [B.name]", \ - "dna" = B.data["blood_DNA"], \ - "unique_id" = V.uniqueID, \ - "reference" = "\ref[V]", \ - "is_in_database" = !!R, \ - "record" = "\ref[R]"))) + var/mob/living/carbon/human/D = B.data["donor"] + pathogen_pool.Add(list(list(\ + "name" = "[D.get_species()] [B.name]", \ + "dna" = B.data["blood_DNA"], \ + "unique_id" = V.uniqueID, \ + "reference" = "\ref[V]", \ + "is_in_database" = !!R, \ + "record" = "\ref[R]"))) + data["pathogen_pool"] = pathogen_pool - if (pathogen_pool.len > 0) - data["pathogen_pool"] = pathogen_pool - - if (LIST) - var/list/db[0] - for (var/ID in virusDB) - var/datum/data/record/r = virusDB[ID] - db.Add(list(list("name" = r.fields["name"], "record" = "\ref[r]"))) - - if (db.len > 0) - data["database"] = db - - if (ENTRY) - if (entry) - var/desc = entry.fields["description"] - data["entry"] = list(\ - "name" = entry.fields["name"], \ - "description" = replacetext(desc, "\n", "")) - - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "pathogenic_isolator.tmpl", src.name, 400, 500) - ui.set_initial_data(data) - ui.open() + var/list/db = list() + for(var/ID in virusDB) + var/datum/data/record/r = virusDB[ID] + db.Add(list(list("name" = r.fields["name"], "record" = "\ref[r]"))) + data["database"] = db + data["modal"] = tgui_modal_data(src) + return data /obj/machinery/disease2/isolator/process() if (isolating > 0) @@ -120,62 +99,54 @@ virus2 = null ping("\The [src] pings, \"Viral strain isolated.\"") - SSnanoui.update_uis(src) + SStgui.update_uis(src) update_icon() -/obj/machinery/disease2/isolator/Topic(href, href_list) - if (..()) return 1 +/obj/machinery/disease2/isolator/tgui_act(action, list/params) + if(..()) + return TRUE var/mob/user = usr - var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") + add_fingerprint(user) + + . = TRUE + switch(tgui_modal_act(src, action, params)) + if(TGUI_MODAL_ANSWER) + return - src.add_fingerprint(user) + switch(action) + if("view_entry") + var/datum/data/record/v = locate(params["vir"]) + if(!istype(v)) + return FALSE + tgui_modal_message(src, "virus", "", null, v.fields["tgui_description"]) + return TRUE - if (href_list["close"]) - user.unset_machine() - ui.close() - return 0 + if("print") + print(user, params) + return TRUE - if (href_list[HOME]) - state = HOME - return 1 + if("isolate") + var/datum/disease2/disease/V = locate(params["isolate"]) + if (V) + virus2 = V + isolating = 20 + update_icon() + return TRUE - if (href_list[LIST]) - state = LIST - return 1 - - if (href_list[ENTRY]) - if (istype(locate(href_list["view"]), /datum/data/record)) - entry = locate(href_list["view"]) - - state = ENTRY - return 1 - - if (href_list["print"]) - print(user) - return 1 - - if(!sample) return 1 - - if (href_list["isolate"]) - var/datum/disease2/disease/V = locate(href_list["isolate"]) - if (V) - virus2 = V - isolating = 20 + if("eject") + if(!sample) + return FALSE + sample.forceMove(loc) + sample = null update_icon() - return 1 + return TRUE - if (href_list["eject"]) - sample.loc = src.loc - sample = null - update_icon() - return 1 - -/obj/machinery/disease2/isolator/proc/print(var/mob/user) +/obj/machinery/disease2/isolator/proc/print(mob/user, list/params) var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc) - switch (state) - if (HOME) + switch(params["type"]) + if("patient_diagnosis") if (!sample) return P.name = "paper - Patient Diagnostic Report" P.info = {" @@ -207,7 +178,7 @@ Additional Notes:  "} - if (LIST) + if("virus_list") P.name = "paper - Virus List" P.info = {" [virology_letterhead("Virus List")] @@ -225,11 +196,14 @@ Additional Notes:  "} - if (ENTRY) + if("virus_record") + var/datum/data/record/v = locate(params["vir"]) + if(!istype(v)) + return FALSE P.name = "paper - Viral Profile" P.info = {" [virology_letterhead("Viral Profile")] - [entry.fields["description"]] + [v.fields["description"]]
Additional Notes:  "} diff --git a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm index 876cd4afb6f..26c760efdb7 100644 --- a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm @@ -126,6 +126,8 @@ var/icon/suit_sprites = null //File for suit sprites, if any. var/icon/under_sprites = null + var/icon_sprite_tag // This is where we put stuff like _Horse, so we can assign icons easier. + var/can_ride = 1 //whether we're real rideable taur or just in that category //Could do nested lists but it started becoming a nightmare. It'd be more fun for lookups of a_intent and m_intent, but then subtypes need to @@ -167,32 +169,38 @@ icon_state = "wolf_s" under_sprites = 'icons/mob/taursuits_wolf_vr.dmi' suit_sprites = 'icons/mob/taursuits_wolf_vr.dmi' + icon_sprite_tag = "wolf" //TFF 22/11/19 - CHOMPStation port of fat taur sprites /datum/sprite_accessory/tail/taur/fatwolf name = "Fat Wolf (Taur)" icon_state = "fatwolf_s" + icon_sprite_tag = "wolf" //This could be modified later. /datum/sprite_accessory/tail/taur/wolf/wolf_2c name = "Wolf dual-color (Taur)" icon_state = "wolf_s" extra_overlay = "wolf_markings" + //icon_sprite_tag = "wolf2c" //TFF 22/11/19 - CHOMPStation port of fat taur sprites /datum/sprite_accessory/tail/taur/wolf/fatwolf_2c name = "Fat Wolf dual-color (Taur)" icon_state = "fatwolf_s" extra_overlay = "fatwolf_markings" + //icon_sprite_tag = "fatwolf2c" /datum/sprite_accessory/tail/taur/wolf/synthwolf name = "SynthWolf dual-color (Taur)" icon_state = "synthwolf_s" extra_overlay = "synthwolf_markings" + //icon_sprite_tag = "synthwolf" /datum/sprite_accessory/tail/taur/naga name = "Naga (Taur)" icon_state = "naga_s" suit_sprites = 'icons/mob/taursuits_naga_vr.dmi' + //icon_sprite_tag = "naga" msg_owner_help_walk = "You carefully slither around %prey." msg_prey_help_walk = "%owner's huge tail slithers past beside you!" @@ -225,12 +233,14 @@ name = "Naga dual-color (Taur)" icon_state = "naga_s" extra_overlay = "naga_markings" + //icon_sprite_tag = "naga2c" /datum/sprite_accessory/tail/taur/horse name = "Horse (Taur)" icon_state = "horse_s" under_sprites = 'icons/mob/taursuits_horse_vr.dmi' suit_sprites = 'icons/mob/taursuits_horse_vr.dmi' + icon_sprite_tag = "horse" msg_owner_disarm_run = "You quickly push %prey to the ground with your hoof!" msg_prey_disarm_run = "%owner pushes you down to the ground with their hoof!" @@ -251,11 +261,13 @@ name = "SynthHorse dual-color (Taur)" icon_state = "synthhorse_s" extra_overlay = "synthhorse_markings" + //icon_sprite_tag = "synthhorse" /datum/sprite_accessory/tail/taur/cow name = "Cow (Taur)" icon_state = "cow_s" suit_sprites = 'icons/mob/taursuits_cow_vr.dmi' + icon_sprite_tag = "cow" msg_owner_disarm_run = "You quickly push %prey to the ground with your hoof!" msg_prey_disarm_run = "%owner pushes you down to the ground with their hoof!" @@ -277,6 +289,7 @@ icon_state = "deer_s" extra_overlay = "deer_markings" suit_sprites = 'icons/mob/taursuits_deer_vr.dmi' + icon_sprite_tag = "deer" msg_owner_disarm_run = "You quickly push %prey to the ground with your hoof!" msg_prey_disarm_run = "%owner pushes you down to the ground with their hoof!" @@ -297,21 +310,25 @@ name = "Lizard (Taur)" icon_state = "lizard_s" suit_sprites = 'icons/mob/taursuits_lizard_vr.dmi' + icon_sprite_tag = "lizard" /datum/sprite_accessory/tail/taur/lizard/lizard_2c name = "Lizard dual-color (Taur)" icon_state = "lizard_s" extra_overlay = "lizard_markings" + //icon_sprite_tag = "lizard2c" /datum/sprite_accessory/tail/taur/lizard/synthlizard name = "SynthLizard dual-color (Taur)" icon_state = "synthlizard_s" extra_overlay = "synthlizard_markings" + //icon_sprite_tag = "synthlizard" /datum/sprite_accessory/tail/taur/spider name = "Spider (Taur)" icon_state = "spider_s" suit_sprites = 'icons/mob/taursuits_spider_vr.dmi' + icon_sprite_tag = "spider" msg_owner_disarm_run = "You quickly push %prey to the ground with your leg!" msg_prey_disarm_run = "%owner pushes you down to the ground with their leg!" @@ -331,6 +348,7 @@ /datum/sprite_accessory/tail/taur/tents name = "Tentacles (Taur)" icon_state = "tent_s" + icon_sprite_tag = "tentacle" can_ride = 0 msg_prey_stepunder = "You run between %prey's tentacles." @@ -358,11 +376,13 @@ name = "Feline (Taur)" icon_state = "feline_s" suit_sprites = 'icons/mob/taursuits_feline_vr.dmi' + icon_sprite_tag = "feline" //TFF 22/11/19 - CHOMPStation port of fat taur sprites /datum/sprite_accessory/tail/taur/fatfeline name = "Fat Feline (Taur)" icon_state = "fatfeline_s" + //icon_sprite_tag = "fatfeline" /datum/sprite_accessory/tail/taur/fatfeline_wag name = "Fat Feline (Taur) (vwag)" @@ -373,22 +393,26 @@ name = "Feline dual-color (Taur)" icon_state = "feline_s" extra_overlay = "feline_markings" + //icon_sprite_tag = "feline2c" //TFF 22/11/19 - CHOMPStation port of fat taur sprites /datum/sprite_accessory/tail/taur/feline/fatfeline_2c name = "Fat Feline dual-color (Taur)" icon_state = "fatfeline_s" extra_overlay = "fatfeline_markings" + //icon_sprite_tag = "fatfeline2c" /datum/sprite_accessory/tail/taur/feline/synthfeline name = "SynthFeline dual-color (Taur)" icon_state = "synthfeline_s" extra_overlay = "synthfeline_markings" + //icon_sprite_tag = "synthfeline" /datum/sprite_accessory/tail/taur/slug name = "Slug (Taur)" icon_state = "slug_s" suit_sprites = 'icons/mob/taursuits_slug_vr.dmi' + icon_sprite_tag = "slug" msg_owner_help_walk = "You carefully slither around %prey." msg_prey_help_walk = "%owner's huge tail slithers past beside you!" @@ -420,11 +444,13 @@ /datum/sprite_accessory/tail/taur/frog name = "Frog (Taur)" icon_state = "frog_s" + icon_sprite_tag = "frog" /datum/sprite_accessory/tail/taur/thicktentacles name = "Thick Tentacles (Taur)" icon_state = "tentacle_s" can_ride = 0 + icon_sprite_tag = "thick_tentacles" msg_prey_stepunder = "You run between %prey's tentacles." msg_owner_stepunder = "%owner runs between your tentacles." @@ -452,12 +478,14 @@ icon_state = "drake_s" extra_overlay = "drake_markings" suit_sprites = 'icons/mob/taursuits_drake_vr.dmi' + icon_sprite_tag = "drake" /datum/sprite_accessory/tail/taur/otie name = "Otie (Taur)" icon_state = "otie_s" extra_overlay = "otie_markings" suit_sprites = 'icons/mob/taursuits_otie_vr.dmi' + icon_sprite_tag = "otie" /datum/sprite_accessory/tail/taur/alraune/alraune_2c name = "Alraune (dual color)" @@ -468,12 +496,14 @@ extra_overlay = "alraunecolor_markings" extra_overlay_w = "alraunecolor_closed_markings" clip_mask_state = "taur_clip_mask_alraune" + icon_sprite_tag = "alraune" /datum/sprite_accessory/tail/taur/wasp name = "Wasp (dual color)" icon_state = "wasp_s" extra_overlay = "wasp_markings" clip_mask_state = "taur_clip_mask_wasp" + icon_sprite_tag = "wasp" msg_owner_disarm_run = "You quickly push %prey to the ground with your leg!" msg_prey_disarm_run = "%owner pushes you down to the ground with their leg!" @@ -494,6 +524,7 @@ name = "Mermaid (Taur)" icon_state = "mermaid_s" can_ride = 0 + icon_sprite_tag = "mermaid" msg_owner_help_walk = "You carefully slither around %prey." msg_prey_help_walk = "%owner's huge tail slithers past beside you!" diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm index d5b6d1cbc89..2f2c55b85a5 100644 --- a/code/modules/vore/eating/belly_obj_vr.dm +++ b/code/modules/vore/eating/belly_obj_vr.dm @@ -329,7 +329,7 @@ if(!P.absorbed) //This is required first, in case there's a person absorbed and not absorbed in a stomach. total_bulge += P.size_multiplier if(total_bulge >= bulge_size && bulge_size != 0) - return("[formatted_message]
") + return("[formatted_message]") else return "" @@ -721,4 +721,4 @@ return dupe /obj/belly/container_resist(mob/M) - return relay_resist(M) \ No newline at end of file + return relay_resist(M) diff --git a/code/modules/vore/eating/bellymodes_datum_vr.dm b/code/modules/vore/eating/bellymodes_datum_vr.dm index 19deb666211..04f96becd40 100644 --- a/code/modules/vore/eating/bellymodes_datum_vr.dm +++ b/code/modules/vore/eating/bellymodes_datum_vr.dm @@ -165,12 +165,16 @@ GLOBAL_LIST_INIT(digest_modes, list()) B.change_tail_nocolor(H) B.change_wing_nocolor(H) B.change_species(H, 1, 1) // ,1) preserves coloring + H.species.create_organs(H) + H.sync_organ_dna() return null if(changes_ears_tail_wing_color && (B.check_ears(H) || B.check_tail(H) || B.check_wing(H) || B.check_species(H))) B.change_ears(H) B.change_tail(H) B.change_wing(H) B.change_species(H, 1, 2) // ,2) does not preserve coloring. + H.species.create_organs(H) + H.sync_organ_dna() return null if(changes_gender && B.check_gender(H, changes_gender_to)) B.change_gender(H, changes_gender_to, 1) diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index 9ffb5d96275..05707440283 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -13,11 +13,12 @@ var/weight = 137 // Weight for mobs for weightgain system var/weight_gain = 1 // How fast you gain weight var/weight_loss = 0.5 // How fast you lose weight - var/vore_egg_type = "egg" // Default egg type. + var/vore_egg_type = "egg" // Default egg type. var/feral = 0 // How feral the mob is, if at all. Does nothing for non xenochimera at the moment. var/revive_ready = REVIVING_READY // Only used for creatures that have the xenochimera regen ability, so far. var/metabolism = 0.0015 var/vore_taste = null // What the character tastes like + var/vore_smell = null // What the character smells like var/no_vore = FALSE // If the character/mob can vore. var/noisy = FALSE // Toggle audible hunger. var/absorbing_prey = 0 // Determines if the person is using the succubus drain or not. See station_special_abilities_vr. @@ -38,10 +39,11 @@ /hook/living_new/proc/vore_setup(mob/living/M) M.verbs += /mob/living/proc/escapeOOC M.verbs += /mob/living/proc/lick + M.verbs += /mob/living/proc/smell M.verbs += /mob/living/proc/switch_scaling if(M.no_vore) //If the mob isn't supposed to have a stomach, let's not give it an insidepanel so it can make one for itself, or a stomach. return TRUE - M.vorePanel = new + M.vorePanel = new(M) M.verbs += /mob/living/proc/insidePanel //Tries to load prefs if a client is present otherwise gives freebie stomach @@ -231,6 +233,7 @@ P.digest_leave_remains = src.digest_leave_remains P.allowmobvore = src.allowmobvore P.vore_taste = src.vore_taste + P.vore_smell = src.vore_smell P.permit_healbelly = src.permit_healbelly P.can_be_drop_prey = src.can_be_drop_prey P.can_be_drop_pred = src.can_be_drop_pred @@ -261,6 +264,7 @@ digest_leave_remains = P.digest_leave_remains allowmobvore = P.allowmobvore vore_taste = P.vore_taste + vore_smell = P.vore_smell permit_healbelly = P.permit_healbelly can_be_drop_prey = P.can_be_drop_prey can_be_drop_pred = P.can_be_drop_pred @@ -356,6 +360,43 @@ var/datum/reagent/R = H.touching.reagent_list[1] taste_message += " You also get the flavor of [R.taste_description] from something on them" return taste_message + + + +//This is just the above proc but switched about. +/mob/living/proc/smell(mob/living/smelled in living_mobs(1)) + set name = "Smell" + set category = "IC" + set desc = "Smell someone nearby!" + set popup_menu = FALSE + + if(!istype(smelled)) + return + if(!checkClickCooldown() || incapacitated(INCAPACITATION_ALL)) + return + + setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + visible_message("[src] smells [smelled]!","You smell [smelled]. They smell like [smelled.get_smell_message()].","Sniff!") + +/mob/living/proc/get_smell_message(allow_generic = 1) + if(!vore_smell && !allow_generic) + return FALSE + + var/smell_message = "" + if(vore_smell && (vore_smell != "")) + smell_message += "[vore_smell]" + else + if(ishuman(src)) + var/mob/living/carbon/human/H = src + smell_message += "a normal [H.custom_species ? H.custom_species : H.species.name]" + else + smell_message += "a plain old normal [src]" + + return smell_message + + + + // // OOC Escape code for pref-breaking or AFK preds // @@ -599,7 +640,7 @@ to_chat(src, "You can taste the flavor of spicy cardboard.") else if(istype(I,/obj/item/device/flashlight/glowstick)) to_chat(src, "You found out the glowy juice only tastes like regret.") - else if(istype(I,/obj/item/weapon/cigbutt)) + else if(istype(I,/obj/item/trash/cigbutt)) to_chat(src, "You can taste the flavor of bitter ash. Classy.") else if(istype(I,/obj/item/clothing/mask/smokable)) var/obj/item/clothing/mask/smokable/C = I diff --git a/code/modules/vore/eating/vore_vr.dm b/code/modules/vore/eating/vore_vr.dm index 9aaa4b0cefe..416a125f492 100644 --- a/code/modules/vore/eating/vore_vr.dm +++ b/code/modules/vore/eating/vore_vr.dm @@ -51,6 +51,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE var/allowmobvore = TRUE var/list/belly_prefs = list() var/vore_taste = "nothing in particular" + var/vore_smell = "nothing in particular" var/permit_healbelly = TRUE var/can_be_drop_prey = FALSE var/can_be_drop_pred = FALSE @@ -123,6 +124,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE digest_leave_remains = json_from_file["digest_leave_remains"] allowmobvore = json_from_file["allowmobvore"] vore_taste = json_from_file["vore_taste"] + vore_smell = json_from_file["vore_smell"] permit_healbelly = json_from_file["permit_healbelly"] can_be_drop_prey = json_from_file["can_be_drop_prey"] can_be_drop_pred = json_from_file["can_be_drop_pred"] @@ -166,6 +168,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE "digest_leave_remains" = digest_leave_remains, "allowmobvore" = allowmobvore, "vore_taste" = vore_taste, + "vore_smell" = vore_smell, "permit_healbelly" = permit_healbelly, "can_be_drop_prey" = can_be_drop_prey, "can_be_drop_pred" = can_be_drop_pred, diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm index 78d18a2edf8..de776e002b9 100644 --- a/code/modules/vore/eating/vorepanel_vr.dm +++ b/code/modules/vore/eating/vorepanel_vr.dm @@ -17,1014 +17,804 @@ if(!vorePanel) log_debug("[src] ([type], \ref[src]) didn't have a vorePanel and tried to use the verb.") - vorePanel = new + vorePanel = new(src) - vorePanel.selected = vore_selected - vorePanel.show(src) + vorePanel.tgui_interact(src) /mob/living/proc/updateVRPanel() //Panel popup update call from belly events. - if(!vorePanel) - log_debug("[src] ([type], \ref[src]) didn't have a vorePanel and something tried to update it.") - vorePanel = new - - if(vorePanel.open) - vorePanel.selected = vore_selected - vorePanel.show(src) + SStgui.update_uis(vorePanel) // // Callback Handler for the Inside form // /datum/vore_look - var/datum/browser/popup - var/obj/belly/selected - var/show_interacts = 0 - var/open = FALSE + var/mob/living/host // Note, we do this in case we ever want to allow people to view others vore panels + var/unsaved_changes = FALSE -/datum/vore_look/Destroy() - selected = null - QDEL_NULL(popup) +/datum/vore_look/New(mob/living/new_host) + if(istype(new_host)) + host = new_host . = ..() -/datum/vore_look/Topic(href,href_list[]) - if(vp_interact(href, href_list) && popup) - popup.set_content(gen_ui(usr)) - usr << output(popup.get_content(), "insidePanel.browser") +/datum/vore_look/Destroy() + host = null + . = ..() -/datum/vore_look/proc/show(mob/living/user) - if(popup) - QDEL_NULL(popup) - popup = new(user, "insidePanel", "Inside!", 450, 700, src) - popup.set_content(gen_ui(user)) - popup.open() - open = TRUE +/datum/vore_look/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "VorePanel", "Inside!") + ui.open() -/datum/vore_look/proc/gen_ui(var/mob/living/user) - var/list/dat = list() +// This looks weird, but all tgui_host is used for is state checking +// So this allows us to use the self_state just fine. +/datum/vore_look/tgui_host(mob/user) + return host - var/atom/userloc = user.loc - if(isbelly(userloc)) - var/obj/belly/inside_belly = userloc - var/mob/living/eater = inside_belly.owner +// Note, in order to allow others to look at others vore panels, this state would need +// to be changed to tgui_always_state, and a custom tgui_status() implemented for true "rights" management. +/datum/vore_look/tgui_state(mob/user) + return GLOB.tgui_self_state - dat += "You are currently [user.absorbed ? "absorbed into " : "inside "] [eater]'s [inside_belly.name]!

" +/datum/vore_look/var/static/list/nom_icons +/datum/vore_look/proc/cached_nom_icon(atom/target) + LAZYINITLIST(nom_icons) - if(inside_belly.desc) - dat += "[inside_belly.desc]

" //Extra br - - if(inside_belly.contents.len > 1) - dat += "You can see the following around you:
" - var/list/belly_contents = list() - for (var/atom/movable/O in inside_belly) - if(istype(O,/mob/living)) - var/mob/living/M = O - //That's just you - if(M == user) - continue - - //That's an absorbed person you're checking - if(M.absorbed) - if(user.absorbed) - belly_contents += "[O]" - continue - else - continue - - //Anything else - dat += "[O]​" - - //Zero-width space, for wrapping - dat += "​" - - dat += jointext(belly_contents, null) //Add in belly contents to main running list + var/key = "" + if(isobj(target)) + key = "[target.type]" + else if(ismob(target)) + var/mob/M = target + key = "\ref[target][M.real_name]" + if(nom_icons[key]) + . = nom_icons[key] else - dat += "You aren't inside anyone." + . = icon2base64(getFlatIcon(target,defdir=SOUTH,no_anim=TRUE)) + nom_icons[key] = . - var/list/belly_list = list("
    ") - for(var/belly in user.vore_organs) - var/obj/belly/B = belly - if(B == selected) - belly_list += "
  1. [B.name]" - else - belly_list += "
  2. [B.name]" - var/spanstyle - switch(B.digest_mode) - if(DM_HOLD) - spanstyle = "" - if(DM_DIGEST) - spanstyle = "color:red;" - if(DM_ABSORB) - spanstyle = "color:purple;" - if(DM_DRAIN) - spanstyle = "color:purple;" - if(DM_HEAL) - spanstyle = "color:green;" - if(DM_SHRINK) - spanstyle = "color:purple;" - if(DM_GROW) - spanstyle = "color:purple;" - if(DM_SIZE_STEAL) - spanstyle = "color:purple;" - if(DM_TRANSFORM_MALE) - spanstyle = "color:purple;" - if(DM_TRANSFORM_HAIR_AND_EYES) - spanstyle = "color:purple;" - if(DM_TRANSFORM_FEMALE) - spanstyle = "color:purple;" - if(DM_TRANSFORM_KEEP_GENDER) - spanstyle = "color:purple;" - if(DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR) - spanstyle = "color:purple;" - if(DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG) - spanstyle = "color:purple;" - if(DM_TRANSFORM_REPLICA) - spanstyle = "color:purple;" - if(DM_TRANSFORM_REPLICA_EGG) - spanstyle = "color:purple;" - if(DM_TRANSFORM_KEEP_GENDER_EGG) - spanstyle = "color:purple;" - if(DM_TRANSFORM_MALE_EGG) - spanstyle = "color:purple;" - if(DM_TRANSFORM_FEMALE_EGG) - spanstyle = "color:purple;" - if(DM_EGG) - spanstyle = "color:purple;" +/datum/vore_look/tgui_data(mob/user) + var/list/data = list() - belly_list += " ([B.contents.len])
  3. " + if(!host) + return data - if(user.vore_organs.len < BELLIES_MAX) - belly_list += "
  4. New+
  5. " - belly_list += "

" + data["unsaved_changes"] = unsaved_changes - dat += jointext(belly_list, null) //Add in belly list to main running list + data["inside"] = list() + var/atom/hostloc = host.loc + if(isbelly(hostloc)) + var/obj/belly/inside_belly = hostloc + var/mob/living/pred = inside_belly.owner - // Selected Belly (contents, configuration) - if(!selected) - dat += "No belly selected. Click one to select it." - else - var/list/belly_contents = list() - if(selected.contents.len) - belly_contents += "Contents: " - for(var/O in selected) - - //Mobs can be absorbed, so treat them separately from everything else - if(istype(O,/mob/living)) - var/mob/living/M = O - - //Absorbed gets special color OOoOOOOoooo - if(M.absorbed) - belly_contents += "[O]" - continue - - //Anything else - belly_contents += "[O]" - - //Zero-width space, for wrapping - belly_contents += "​" - - //If there's more than one thing, add an [All] button - if(selected.contents.len > 1) - belly_contents += "\[All\]" - - belly_contents += "
" - - if(belly_contents.len) - dat += jointext(belly_contents, null) - - //Belly Name Button - dat += "
Name: '[selected.name]'" - - //Belly Type button - dat += "
Is this belly fleshy: [selected.is_wet ? "Yes" : "No"]" - if(selected.is_wet) - dat += "
Internal loop for prey?: [selected.wet_loop ? "Yes" : "No"]" - - //Digest Mode Button - var/mode = selected.digest_mode - dat += "
Belly Mode: [mode]" - - //Mode addons button - var/list/flag_list = list() - for(var/flag_name in selected.mode_flag_list) - if(selected.mode_flags & selected.mode_flag_list[flag_name]) - flag_list += flag_name - if(flag_list.len) - dat += "
Mode Addons: [english_list(flag_list)]" - else - dat += "
Mode Addons: None" - - //Item Digest Mode Button - dat += "
Item Mode: [selected.item_digest_mode]" - - //Will it contaminate contents? - dat += "
Contaminates: [selected.contaminates ? "Yes" : "No"]" - - if(selected.contaminates) - //Contamination descriptors - dat += "
Contamination Flavor: [selected.contamination_flavor]" - //Contamination color - dat += "
Contamination Color: [selected.contamination_color]" - - //Belly verb - dat += "
Vore Verb: '[selected.vore_verb]'" - - //Inside flavortext - dat += "
Flavor Text: '[selected.desc]'" - - //Belly Sound Fanciness - dat += "
Use Fancy Sounds: [selected.fancy_vore ? "Yes" : "No"]" - - //Belly sound - dat += "
Vore Sound: [selected.vore_sound] Test" - - //Release sound - dat += "
Release Sound: [selected.release_sound] Test" - - //Belly messages - dat += "
Belly Messages" - - //Can belly taste? - dat += "
Can Taste: [selected.can_taste ? "Yes" : "No"]" - - //Nutritional percentage - dat += "
Nutritional Gain: [selected.nutrition_percent]%" - - //How much brute damage - dat += "
Digest Brute Damage: [selected.digest_brute]" - - //How much burn damage - dat += "
Digest Burn Damage: [selected.digest_burn]" - - //Minimum size prey must be to show up. - dat += "
Required examine size: [selected.bulge_size*100]%" - - //Size that prey will be grown/shrunk to. - dat += "
Shrink/Grow size: [selected.shrink_grow_size*100]%" - - //Belly escapability - dat += "
Belly Interactions ([selected.escapable ? "On" : "Off"])" - if(selected.escapable) - dat += "[show_interacts ? "Hide" : "Show"]" - - if(show_interacts && selected.escapable) - var/list/interacts = list() - interacts += "
" - interacts += "Interaction Settings ?" - interacts += "
Set Belly Escape Chance" - interacts += " [selected.escapechance]%" - - interacts += "
Set Belly Escape Time" - interacts += " [selected.escapetime/10]s" - - //Special
here to add a gap - interacts += "
" - interacts += "
Set Belly Transfer Chance" - interacts += " [selected.transferchance]%" - - interacts += "
Set Belly Transfer Location" - interacts += " [selected.transferlocation ? selected.transferlocation : "Disabled"]" - - //Special
here to add a gap - interacts += "
" - interacts += "
Set Belly Absorb Chance" - interacts += " [selected.absorbchance]%" - - interacts += "
Set Belly Digest Chance" - interacts += " [selected.digestchance]%" - interacts += "
" - dat += jointext(interacts, null) - - //Delete button - dat += "Delete Belly" - - dat += "
" - - var/list/nightmare_list = list() - switch(user.digestable) - if(TRUE) - nightmare_list += "Toggle Digestable (Currently: ON)" - if(FALSE) - nightmare_list += "Toggle Digestable (Currently: OFF)" - switch(user.devourable) - if(TRUE) - nightmare_list += "Toggle Devourable (Currently: ON)" - if(FALSE) - nightmare_list += "Toggle Devourable (Currently: OFF)" - switch(user.feeding) - if(TRUE) - nightmare_list += "
Toggle Feeding (Currently: ON)" - if(FALSE) - nightmare_list += "
Toggle Feeding (Currently: OFF)" - switch(user.absorbable) - if(TRUE) - nightmare_list += "Toggle Absorbtion Permission (Currently: ON)" - if(FALSE) - nightmare_list += "Toggle Absorbtion Permission (Currently: OFF)" - switch(user.digest_leave_remains) - if(TRUE) - nightmare_list += "Toggle Leaving Remains (Currently: ON)" - if(FALSE) - nightmare_list += "Toggle Leaving Remains (Currently: OFF)" - switch(user.allowmobvore) - if(TRUE) - nightmare_list += "
Toggle Mob Vore (Currently: ON)" - if(FALSE) - nightmare_list += "
Toggle Mob Vore (Currently: OFF)" - switch(user.permit_healbelly) - if(TRUE) - nightmare_list += "Toggle Healbelly Permission (Currently: ON)" - if(FALSE) - nightmare_list += "Toggle Healbelly Permission (Currently: OFF)" - - switch(user.can_be_drop_prey) - if(TRUE) - nightmare_list += "
Toggle Prey Spontaneous Vore (Currently: ON)" - if(FALSE) - nightmare_list += "
Toggle Prey Spontaneous Vore (Currently: OFF)" - - switch(user.can_be_drop_pred) - if(TRUE) - nightmare_list += "Toggle Pred Spontaneous Vore (Currently: ON)" - if(FALSE) - nightmare_list += "Toggle Pred Spontaneous Vore (Currently: OFF)" - - dat += jointext(nightmare_list, null) //AAAA - - dat += "
Set Your Taste" - dat += "
Toggle Hunger Noises" - - //Under the last HR, save and stuff. - dat += "
Save Prefs" - dat += "
Refresh" - dat += "
Reload Slot Prefs" - - //Returns the dat html to the vore_look - return jointext(dat, null) - -/datum/vore_look/proc/vp_interact(href, href_list) - var/mob/living/user = usr - if(href_list["close"]) - open = FALSE - QDEL_NULL(popup) - return - - if(href_list["show_int"]) - show_interacts = !show_interacts - return TRUE //Force update - - if(href_list["int_help"]) - alert("These control how your belly responds to someone using 'resist' while inside you. The percent chance to trigger each is listed below, \ - and you can change them to whatever you see fit. Setting them to 0% will disable the possibility of that interaction. \ - These only function as long as interactions are turned on in general. Keep in mind, the 'belly mode' interactions (digest/absorb) \ - will affect all prey in that belly, if one resists and triggers digestion/absorption. If multiple trigger at the same time, \ - only the first in the order of 'Escape > Transfer > Absorb > Digest' will occur.","Interactions Help") - return FALSE //Force update - - if(href_list["outsidepick"]) - var/atom/movable/tgt = locate(href_list["outsidepick"]) - var/obj/belly/OB = locate(href_list["outsidebelly"]) - if(!(tgt in OB)) //Aren't here anymore, need to update menu. - return TRUE - var/intent = "Examine" - - if(istype(tgt,/mob/living)) - var/mob/living/M = tgt - intent = alert("What do you want to do to them?","Query","Examine","Help Out","Devour") - switch(intent) - if("Examine") //Examine a mob inside another mob - var/list/results = M.examine(user) - if(!results || !results.len) - results = list("You were unable to examine that. Tell a developer!") - to_chat(user, jointext(results, "
")) - return FALSE - - if("Help Out") //Help the inside-mob out - if(user.stat || user.absorbed || M.absorbed) - to_chat(user,"You can't do that in your state!") - return TRUE - - to_chat(user,"You begin to push [M] to freedom!") - to_chat(M,"[usr] begins to push you to freedom!") - to_chat(M.loc,"Someone is trying to escape from inside you!") - sleep(50) - if(prob(33)) - OB.release_specific_contents(M) - to_chat(usr,"You manage to help [M] to safety!") - to_chat(M,"[user] pushes you free!") - to_chat(OB.owner,"[M] forces free of the confines of your body!") - else - to_chat(user,"[M] slips back down inside despite your efforts.") - to_chat(M," Even with [user]'s help, you slip back inside again.") - to_chat(OB.owner,"Your body efficiently shoves [M] back where they belong.") - - if("Devour") //Eat the inside mob - if(user.absorbed || user.stat) - to_chat(user,"You can't do that in your state!") - return TRUE - - if(!user.vore_selected) - to_chat(user,"Pick a belly on yourself first!") - return TRUE - - var/obj/belly/TB = user.vore_selected - to_chat(user,"You begin to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!") - to_chat(M,"[user] begins to [lowertext(TB.vore_verb)] you into their [lowertext(TB.name)]!") - to_chat(OB.owner,"Someone inside you is eating someone else!") - - sleep(TB.nonhuman_prey_swallow_time) //Can't do after, in a stomach, weird things abound. - if((user in OB) && (M in OB)) //Make sure they're still here. - to_chat(user,"You manage to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!") - to_chat(M,"[user] manages to [lowertext(TB.vore_verb)] you into their [lowertext(TB.name)]!") - to_chat(OB.owner,"Someone inside you has eaten someone else!") - TB.nom_mob(M) - - else if(istype(tgt,/obj/item)) - var/obj/item/T = tgt - if(!(tgt in OB)) - //Doesn't exist anymore, update. - return TRUE - intent = alert("What do you want to do to that?","Query","Examine","Use Hand") - switch(intent) - if("Examine") - var/list/results = T.examine(user) - if(!results || !results.len) - results = list("You were unable to examine that. Tell a developer!") - to_chat(user, jointext(results, "
")) - return FALSE - - if("Use Hand") - if(user.stat) - to_chat(user,"You can't do that in your state!") - return TRUE - - user.ClickOn(T) - sleep(5) //Seems to exit too fast for the panel to update - - if(href_list["insidepick"]) - var/intent - - //Handle the [All] choice. Ugh inelegant. Someone make this pretty. - if(href_list["pickall"]) - intent = alert("Eject all, Move all?","Query","Eject all","Cancel","Move all") - switch(intent) - if("Cancel") - return FALSE - - if("Eject all") - if(user.stat) - to_chat(user,"You can't do that in your state!") - return FALSE - - selected.release_all_contents() - - if("Move all") - if(user.stat) - to_chat(user,"You can't do that in your state!") - return FALSE - - var/obj/belly/choice = input("Move all where?","Select Belly") as null|anything in user.vore_organs - if(!choice) - return FALSE - - for(var/atom/movable/tgt in selected) - to_chat(tgt,"You're squished from [user]'s [lowertext(selected)] to their [lowertext(choice.name)]!") - selected.transfer_contents(tgt, choice, 1) - - var/atom/movable/tgt = locate(href_list["insidepick"]) - if(!(tgt in selected)) //Old menu, needs updating because they aren't really there. - return TRUE //Forces update - intent = "Examine" - intent = alert("Examine, Eject, Move? Examine if you want to leave this box.","Query","Examine","Eject","Move") - switch(intent) - if("Examine") - var/list/results = tgt.examine(user) - if(!results || !results.len) - results = list("You were unable to examine that. Tell a developer!") - to_chat(user, jointext(results, "
")) - return FALSE - - if("Eject") - if(user.stat) - to_chat(user,"You can't do that in your state!") - return FALSE - - selected.release_specific_contents(tgt) - - if("Move") - if(user.stat) - to_chat(user,"You can't do that in your state!") - return FALSE - - var/obj/belly/choice = input("Move [tgt] where?","Select Belly") as null|anything in user.vore_organs - if(!choice || !(tgt in selected)) - return FALSE - - to_chat(tgt,"You're squished from [user]'s [lowertext(selected.name)] to their [lowertext(choice.name)]!") - selected.transfer_contents(tgt, choice) - - if(href_list["newbelly"]) - if(user.vore_organs.len >= BELLIES_MAX) - return FALSE - - var/new_name = html_encode(input(usr,"New belly's name:","New Belly") as text|null) - - var/failure_msg - if(length(new_name) > BELLIES_NAME_MAX || length(new_name) < BELLIES_NAME_MIN) - failure_msg = "Entered belly name length invalid (must be longer than [BELLIES_NAME_MIN], no more than than [BELLIES_NAME_MAX])." - // else if(whatever) //Next test here. - else - for(var/belly in user.vore_organs) - var/obj/belly/B = belly - if(lowertext(new_name) == lowertext(B.name)) - failure_msg = "No duplicate belly names, please." - break - - if(failure_msg) //Something went wrong. - alert(user,failure_msg,"Error!") - return FALSE - - var/obj/belly/NB = new(user) - NB.name = new_name - selected = NB - - if(href_list["bellypick"]) - selected = locate(href_list["bellypick"]) - user.vore_selected = selected - - //// - //Please keep these the same order they are on the panel UI for ease of coding - //// - if(href_list["b_name"]) - var/new_name = html_encode(input(usr,"Belly's new name:","New Name") as text|null) - - var/failure_msg - if(length(new_name) > BELLIES_NAME_MAX || length(new_name) < BELLIES_NAME_MIN) - failure_msg = "Entered belly name length invalid (must be longer than [BELLIES_NAME_MIN], no more than than [BELLIES_NAME_MAX])." - // else if(whatever) //Next test here. - else - for(var/belly in user.vore_organs) - var/obj/belly/B = belly - if(lowertext(new_name) == lowertext(B.name)) - failure_msg = "No duplicate belly names, please." - break - - if(failure_msg) //Something went wrong. - alert(user,failure_msg,"Error!") - return FALSE - - selected.name = new_name - - if(href_list["b_wetness"]) - selected.is_wet = !selected.is_wet - - if(href_list["b_wetloop"]) - selected.wet_loop = !selected.wet_loop - - if(href_list["b_mode"]) - var/list/menu_list = selected.digest_modes.Copy() - if(istype(usr,/mob/living/carbon/human)) - menu_list += DM_TRANSFORM - - var/new_mode = input("Choose Mode (currently [selected.digest_mode])") as null|anything in menu_list - if(!new_mode) - return FALSE - - if(new_mode == DM_TRANSFORM) //Snowflek submenu - var/list/tf_list = selected.transform_modes - var/new_tf_mode = input("Choose TF Mode (currently [selected.digest_mode])") as null|anything in tf_list - if(!new_tf_mode) - return FALSE - selected.digest_mode = new_tf_mode - return - - selected.digest_mode = new_mode - //selected.items_preserved.Cut() //Re-evaltuate all items in belly on belly-mode change //Handled with item modes now - - if(href_list["b_addons"]) - var/list/menu_list = selected.mode_flag_list.Copy() - var/toggle_addon = input("Toggle Addon") as null|anything in menu_list - if(!toggle_addon) - return FALSE - selected.mode_flags ^= selected.mode_flag_list[toggle_addon] - selected.items_preserved.Cut() //Re-evaltuate all items in belly on addon toggle - - if(href_list["b_item_mode"]) - var/list/menu_list = selected.item_digest_modes.Copy() - - var/new_mode = input("Choose Mode (currently [selected.item_digest_mode])") as null|anything in menu_list - if(!new_mode) - return FALSE - - selected.item_digest_mode = new_mode - selected.items_preserved.Cut() //Re-evaltuate all items in belly on belly-mode change - - if(href_list["b_contaminates"]) - selected.contaminates = !selected.contaminates - - if(href_list["b_contamination_flavor"]) - var/list/menu_list = contamination_flavors.Copy() - var/new_flavor = input("Choose Contamination Flavor Text Type (currently [selected.contamination_flavor])") as null|anything in menu_list - if(!new_flavor) - return FALSE - selected.contamination_flavor = new_flavor - - if(href_list["b_contamination_color"]) - var/list/menu_list = contamination_colors.Copy() - var/new_color = input("Choose Contamination Color (currently [selected.contamination_color])") as null|anything in menu_list - if(!new_color) - return FALSE - selected.contamination_color = new_color - selected.items_preserved.Cut() //To re-contaminate for new color - - if(href_list["b_desc"]) - var/new_desc = html_encode(input(usr,"Belly Description ([BELLIES_DESC_MAX] char limit):","New Description",selected.desc) as message|null) - - if(new_desc) - new_desc = readd_quotes(new_desc) - if(length(new_desc) > BELLIES_DESC_MAX) - alert("Entered belly desc too long. [BELLIES_DESC_MAX] character limit.","Error") - return FALSE - selected.desc = new_desc - else //Returned null - return FALSE - - if(href_list["b_msgs"]) - var/list/messages = list( - "Digest Message (to prey)", - "Digest Message (to you)", - "Struggle Message (outside)", - "Struggle Message (inside)", - "Examine Message (when full)", - "Reset All To Default" + data["inside"] = list( + "absorbed" = host.absorbed, + "belly_name" = inside_belly.name, + "belly_mode" = inside_belly.digest_mode, + "desc" = inside_belly.desc || "No description.", + "pred" = pred, + "ref" = "\ref[inside_belly]", ) - alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max 150 characters per message, max 10 messages per topic.","Really, don't.") - var/choice = input(user,"Select a type to modify. Messages from each topic are pulled at random when needed.","Pick Type") as null|anything in messages - var/help = " Press enter twice to separate messages. '%pred' will be replaced with your name. '%prey' will be replaced with the prey's name. '%belly' will be replaced with your belly's name." + data["inside"]["contents"] = list() + for(var/atom/movable/O in inside_belly) + if(O == host) + continue - switch(choice) - if("Digest Message (to prey)") - var/new_message = input(user,"These are sent to prey when they expire. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Digest Message (to prey)",selected.get_messages("dmp")) as message - if(new_message) - selected.set_messages(new_message,"dmp") + var/list/info = list( + "name" = "[O]", + "icon" = cached_nom_icon(O), + "absorbed" = FALSE, + "stat" = 0, + "ref" = "\ref[O]", + "outside" = FALSE, + ) + if(isliving(O)) + var/mob/living/M = O + info["stat"] = M.stat + if(M.absorbed) + info["absorbed"] = TRUE + data["inside"]["contents"].Add(list(info)) - if("Digest Message (to you)") - var/new_message = input(user,"These are sent to you when prey expires in you. Write them in 2nd person ('you feel X'). Avoid using %pred in this type."+help,"Digest Message (to you)",selected.get_messages("dmo")) as message - if(new_message) - selected.set_messages(new_message,"dmo") + data["our_bellies"] = list() + for(var/belly in host.vore_organs) + var/obj/belly/B = belly + data["our_bellies"].Add(list(list( + "selected" = (B == host.vore_selected), + "name" = B.name, + "ref" = "\ref[B]", + "digest_mode" = B.digest_mode, + "contents" = LAZYLEN(B.contents), + ))) - if("Struggle Message (outside)") - var/new_message = input(user,"These are sent to those nearby when prey struggles. Write them in 3rd person ('X's Y bulges')."+help,"Struggle Message (outside)",selected.get_messages("smo")) as message - if(new_message) - selected.set_messages(new_message,"smo") + data["selected"] = null + if(host.vore_selected) + var/obj/belly/selected = host.vore_selected + data["selected"] = list( + "belly_name" = selected.name, + "is_wet" = selected.is_wet, + "wet_loop" = selected.wet_loop, + "mode" = selected.digest_mode, + "item_mode" = selected.item_digest_mode, + "verb" = selected.vore_verb, + "desc" = selected.desc, + "fancy" = selected.fancy_vore, + "sound" = selected.vore_sound, + "release_sound" = selected.release_sound, + // "messages" // TODO + "can_taste" = selected.can_taste, + "nutrition_percent" = selected.nutrition_percent, + "digest_brute" = selected.digest_brute, + "digest_burn" = selected.digest_burn, + "bulge_size" = selected.bulge_size, + "shrink_grow_size" = selected.shrink_grow_size, + ) - if("Struggle Message (inside)") - var/new_message = input(user,"These are sent to prey when they struggle. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Struggle Message (inside)",selected.get_messages("smi")) as message - if(new_message) - selected.set_messages(new_message,"smi") + data["selected"]["addons"] = list() + for(var/flag_name in selected.mode_flag_list) + if(selected.mode_flags & selected.mode_flag_list[flag_name]) + data["selected"]["addons"].Add(flag_name) - if("Examine Message (when full)") - var/new_message = input(user,"These are sent to people who examine you when this belly has contents. Write them in 3rd person ('Their %belly is bulging')."+help,"Examine Message (when full)",selected.get_messages("em")) as message - if(new_message) - selected.set_messages(new_message,"em") + data["selected"]["contaminates"] = selected.contaminates + data["selected"]["contaminate_flavor"] = null + data["selected"]["contaminate_color"] = null + if(selected.contaminates) + data["selected"]["contaminate_flavor"] = selected.contamination_flavor + data["selected"]["contaminate_color"] = selected.contamination_color - if("Reset All To Default") - var/confirm = alert(user,"This will delete any custom messages. Are you sure?","Confirmation","DELETE","Cancel") - if(confirm == "DELETE") - selected.digest_messages_prey = initial(selected.digest_messages_prey) - selected.digest_messages_owner = initial(selected.digest_messages_owner) - selected.struggle_messages_outside = initial(selected.struggle_messages_outside) - selected.struggle_messages_inside = initial(selected.struggle_messages_inside) + data["selected"]["escapable"] = selected.escapable + data["selected"]["interacts"] = list() + if(selected.escapable) + data["selected"]["interacts"]["escapechance"] = selected.escapechance + data["selected"]["interacts"]["escapetime"] = selected.escapetime + data["selected"]["interacts"]["transferchance"] = selected.transferchance + data["selected"]["interacts"]["transferlocation"] = selected.transferlocation + data["selected"]["interacts"]["absorbchance"] = selected.absorbchance + data["selected"]["interacts"]["digestchance"] = selected.digestchance - if(href_list["b_verb"]) - var/new_verb = html_encode(input(usr,"New verb when eating (infinitive tense, e.g. nom or swallow):","New Verb") as text|null) + data["selected"]["contents"] = list() + for(var/O in selected) + var/list/info = list( + "name" = "[O]", + "icon" = cached_nom_icon(O), + "absorbed" = FALSE, + "stat" = 0, + "ref" = "\ref[O]", + "outside" = TRUE, + ) + if(isliving(O)) + var/mob/living/M = O + info["stat"] = M.stat + if(M.absorbed) + info["absorbed"] = TRUE + data["selected"]["contents"].Add(list(info)) - if(length(new_verb) > BELLIES_NAME_MAX || length(new_verb) < BELLIES_NAME_MIN) - alert("Entered verb length invalid (must be longer than [BELLIES_NAME_MIN], no longer than [BELLIES_NAME_MAX]).","Error") - return FALSE + data["prefs"] = list( + "digestable" = host.digestable, + "devourable" = host.devourable, + "feeding" = host.feeding, + "absorbable" = host.absorbable, + "digest_leave_remains" = host.digest_leave_remains, + "allowmobvore" = host.allowmobvore, + "permit_healbelly" = host.permit_healbelly, + "can_be_drop_prey" = host.can_be_drop_prey, + "can_be_drop_pred" = host.can_be_drop_pred, + "noisy" = host.noisy, + ) - selected.vore_verb = new_verb + return data - if(href_list["b_fancy_sound"]) - selected.fancy_vore = !selected.fancy_vore - selected.vore_sound = "Gulp" - selected.release_sound = "Splatter" - // defaults as to avoid potential bugs +/datum/vore_look/tgui_act(action, params) + if(..()) + return TRUE - if(href_list["b_release"]) - var/choice - if(selected.fancy_vore) - choice = input(user,"Currently set to [selected.release_sound]","Select Sound") as null|anything in fancy_release_sounds - else - choice = input(user,"Currently set to [selected.release_sound]","Select Sound") as null|anything in classic_release_sounds + switch(action) + if("int_help") + alert("These control how your belly responds to someone using 'resist' while inside you. The percent chance to trigger each is listed below, \ + and you can change them to whatever you see fit. Setting them to 0% will disable the possibility of that interaction. \ + These only function as long as interactions are turned on in general. Keep in mind, the 'belly mode' interactions (digest/absorb) \ + will affect all prey in that belly, if one resists and triggers digestion/absorption. If multiple trigger at the same time, \ + only the first in the order of 'Escape > Transfer > Absorb > Digest' will occur.","Interactions Help") + return TRUE - if(!choice) - return FALSE + // Host is inside someone else, and is trying to interact with something else inside that person. + if("pick_from_inside") + return pick_from_inside(usr, params) + + // Host is trying to interact with something in host's belly. + if("pick_from_outside") + return pick_from_outside(usr, params) - selected.release_sound = choice - - if(href_list["b_releasesoundtest"]) - var/sound/releasetest - if(selected.fancy_vore) - releasetest = fancy_release_sounds[selected.release_sound] - else - releasetest = classic_release_sounds[selected.release_sound] - - if(releasetest) - SEND_SOUND(user, releasetest) - - if(href_list["b_sound"]) - var/choice - if(selected.fancy_vore) - choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") as null|anything in fancy_vore_sounds - else - choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") as null|anything in classic_vore_sounds - - if(!choice) - return FALSE - - selected.vore_sound = choice - - if(href_list["b_soundtest"]) - var/sound/voretest - if(selected.fancy_vore) - voretest = fancy_vore_sounds[selected.vore_sound] - else - voretest = classic_vore_sounds[selected.vore_sound] - if(voretest) - SEND_SOUND(user, voretest) - - if(href_list["b_tastes"]) - selected.can_taste = !selected.can_taste - - if(href_list["b_bulge_size"]) - var/new_bulge = input(user, "Choose the required size prey must be to show up on examine, ranging from 25% to 200% Set this to 0 for no text on examine.", "Set Belly Examine Size.") as num|null - if(new_bulge == null) - return - if(new_bulge == 0) //Disable. - selected.bulge_size = 0 - to_chat(user,"Your stomach will not be seen on examine.") - else if (!ISINRANGE(new_bulge,25,200)) - selected.bulge_size = 0.25 //Set it to the default. - to_chat(user,"Invalid size.") - else if(new_bulge) - selected.bulge_size = (new_bulge/100) - - if(href_list["b_grow_shrink"]) - var/new_grow = input(user, "Choose the size that prey will be grown/shrunk to, ranging from 25% to 200%", "Set Growth Shrink Size.", selected.shrink_grow_size) as num|null - if (new_grow == null) - return - if (!ISINRANGE(new_grow,25,200)) - selected.shrink_grow_size = 1 //Set it to the default - to_chat(user,"Invalid size.") - else if(new_grow) - selected.shrink_grow_size = (new_grow*0.01) - - if(href_list["b_nutritionpercent"]) - var/new_damage = input(user, "Choose the nutrition gain percentage you will recieve per tick from prey. Ranges from 0.01 to 100.", "Set Nutrition Gain Percentage.", selected.digest_brute) as num|null - if(new_damage == null) - return - var/new_new_damage = CLAMP(new_damage, 0.01, 100) - selected.nutrition_percent = new_new_damage - - if(href_list["b_burn_dmg"]) - var/new_damage = input(user, "Choose the amount of burn damage prey will take per tick. Ranges from 0 to 6.", "Set Belly Burn Damage.", selected.digest_burn) as num|null - if(new_damage == null) - return - var/new_new_damage = CLAMP(new_damage, 0, 6) - selected.digest_burn = new_new_damage - - if(href_list["b_brute_dmg"]) - var/new_damage = input(user, "Choose the amount of brute damage prey will take per tick. Ranges from 0 to 6", "Set Belly Brute Damage.", selected.digest_brute) as num|null - if(new_damage == null) - return - var/new_new_damage = CLAMP(new_damage, 0, 6) - selected.digest_brute = new_new_damage - - if(href_list["b_escapable"]) - if(selected.escapable == 0) //Possibly escapable and special interactions. - selected.escapable = 1 - to_chat(usr,"Prey now have special interactions with your [lowertext(selected.name)] depending on your settings.") - else if(selected.escapable == 1) //Never escapable. - selected.escapable = 0 - to_chat(usr,"Prey will not be able to have special interactions with your [lowertext(selected.name)].") - show_interacts = 0 //Force the hiding of the panel - else - alert("Something went wrong. Your stomach will now not have special interactions. Press the button enable them again and tell a dev.","Error") //If they somehow have a varable that's not 0 or 1 - selected.escapable = 0 - show_interacts = 0 //Force the hiding of the panel - - if(href_list["b_escapechance"]) - var/escape_chance_input = input(user, "Set prey escape chance on resist (as %)", "Prey Escape Chance") as num|null - if(!isnull(escape_chance_input)) //These have to be 'null' because both cancel and 0 are valid, separate options - selected.escapechance = sanitize_integer(escape_chance_input, 0, 100, initial(selected.escapechance)) - - if(href_list["b_escapetime"]) - var/escape_time_input = input(user, "Set number of seconds for prey to escape on resist (1-60)", "Prey Escape Time") as num|null - if(!isnull(escape_time_input)) - selected.escapetime = sanitize_integer(escape_time_input*10, 10, 600, initial(selected.escapetime)) - - if(href_list["b_transferchance"]) - var/transfer_chance_input = input(user, "Set belly transfer chance on resist (as %). You must also set the location for this to have any effect.", "Prey Escape Time") as num|null - if(!isnull(transfer_chance_input)) - selected.transferchance = sanitize_integer(transfer_chance_input, 0, 100, initial(selected.transferchance)) - - if(href_list["b_transferlocation"]) - var/obj/belly/choice = input("Where do you want your [lowertext(selected.name)] to lead if prey resists?","Select Belly") as null|anything in (user.vore_organs + "None - Remove" - selected) - - if(!choice) //They cancelled, no changes - return FALSE - else if(choice == "None - Remove") - selected.transferlocation = null - else - selected.transferlocation = choice.name - - if(href_list["b_absorbchance"]) - var/absorb_chance_input = input(user, "Set belly absorb mode chance on resist (as %)", "Prey Absorb Chance") as num|null - if(!isnull(absorb_chance_input)) - selected.absorbchance = sanitize_integer(absorb_chance_input, 0, 100, initial(selected.absorbchance)) - - if(href_list["b_digestchance"]) - var/digest_chance_input = input(user, "Set belly digest mode chance on resist (as %)", "Prey Digest Chance") as num|null - if(!isnull(digest_chance_input)) - selected.digestchance = sanitize_integer(digest_chance_input, 0, 100, initial(selected.digestchance)) - - if(href_list["b_del"]) - var/alert = alert("Are you sure you want to delete your [lowertext(selected.name)]?","Confirmation","Delete","Cancel") - if(!(alert == "Delete")) - return FALSE - - var/failure_msg = "" - - var/dest_for //Check to see if it's the destination of another vore organ. - for(var/belly in user.vore_organs) - var/obj/belly/B = belly - if(B.transferlocation == selected) - dest_for = B.name - failure_msg += "This is the destiantion for at least '[dest_for]' belly transfers. Remove it as the destination from any bellies before deleting it. " - break - - if(selected.contents.len) - failure_msg += "You cannot delete bellies with contents! " //These end with spaces, to be nice looking. Make sure you do the same. - if(selected.immutable) - failure_msg += "This belly is marked as undeletable. " - if(user.vore_organs.len == 1) - failure_msg += "You must have at least one belly. " - - if(failure_msg) - alert(user,failure_msg,"Error!") - return FALSE - - qdel(selected) - selected = user.vore_organs[1] - user.vore_selected = user.vore_organs[1] - - if(href_list["saveprefs"]) - if(!user.save_vore_prefs()) - alert("ERROR: Virgo-specific preferences failed to save!","Error") - else - to_chat(user,"Virgo-specific preferences saved!") - - if(href_list["applyprefs"]) - var/alert = alert("Are you sure you want to reload character slot preferences? This will remove your current vore organs and eject their contents.","Confirmation","Reload","Cancel") - if(alert != "Reload") - return FALSE - if(!user.apply_vore_prefs()) - alert("ERROR: Virgo-specific preferences failed to apply!","Error") - else - to_chat(user,"Virgo-specific preferences applied from active slot!") - - if(href_list["setflavor"]) - var/new_flavor = html_encode(input(usr,"What your character tastes like (40ch limit). This text will be printed to the pred after 'X tastes of...' so just put something like 'strawberries and cream':","Character Flavor",user.vore_taste) as text|null) - if(!new_flavor) - return FALSE - - new_flavor = readd_quotes(new_flavor) - if(length(new_flavor) > FLAVOR_MAX) - alert("Entered flavor/taste text too long. [FLAVOR_MAX] character limit.","Error!") - return FALSE - user.vore_taste = new_flavor - - if(href_list["toggle_dropnom_pred"]) - var/choice = alert(user, "This toggle is for spontaneous, environment related vore as a predator, including drop-noms, teleporters, etc. You are currently [user.can_be_drop_pred ? " able to eat prey that you encounter by environmental actions." : "avoiding eating prey encountered in the environment."]", "", "Be Pred", "Cancel", "Don't be Pred") - switch(choice) - if("Cancel") + if("newbelly") + if(host.vore_organs.len >= BELLIES_MAX) return FALSE - if("Be Pred") - user.can_be_drop_pred = TRUE - if("Don't be Pred") - user.can_be_drop_pred = FALSE - if(href_list["toggle_dropnom_prey"]) - var/choice = alert(user, "This toggle is for spontaneous, environment related vore as a prey, including drop-noms, teleporters, etc. You are currently [user.can_be_drop_prey ? "able to be eaten by environmental actions." : "not able to be eaten by environmental actions."]", "", "Be Prey", "Cancel", "Don't Be Prey") - switch(choice) - if("Cancel") + var/new_name = html_encode(input(usr,"New belly's name:","New Belly") as text|null) + + var/failure_msg + if(length(new_name) > BELLIES_NAME_MAX || length(new_name) < BELLIES_NAME_MIN) + failure_msg = "Entered belly name length invalid (must be longer than [BELLIES_NAME_MIN], no more than than [BELLIES_NAME_MAX])." + // else if(whatever) //Next test here. + else + for(var/belly in host.vore_organs) + var/obj/belly/B = belly + if(lowertext(new_name) == lowertext(B.name)) + failure_msg = "No duplicate belly names, please." + break + + if(failure_msg) //Something went wrong. + alert(usr, failure_msg, "Error!") + return TRUE + + var/obj/belly/NB = new(host) + NB.name = new_name + host.vore_selected = NB + unsaved_changes = TRUE + return TRUE + + if("bellypick") + host.vore_selected = locate(params["bellypick"]) + return TRUE + + if("set_attribute") + return set_attr(usr, params) + + if("saveprefs") + if(!host.save_vore_prefs()) + alert("ERROR: Virgo-specific preferences failed to save!","Error") + else + to_chat(usr, "Virgo-specific preferences saved!") + unsaved_changes = FALSE + return TRUE + if("reloadprefs") + var/alert = alert("Are you sure you want to reload character slot preferences? This will remove your current vore organs and eject their contents.","Confirmation","Reload","Cancel") + if(alert != "Reload") return FALSE - if("Be Prey") - user.can_be_drop_prey = TRUE - if("Don't Be Prey") - user.can_be_drop_prey = FALSE - - if(href_list["toggledg"]) - var/choice = alert(user, "This button is for those who don't like being digested. It can make you undigestable. Digesting you is currently: [user.digestable ? "Allowed" : "Prevented"]", "", "Allow Digestion", "Cancel", "Prevent Digestion") - switch(choice) - if("Cancel") + if(!host.apply_vore_prefs()) + alert("ERROR: Virgo-specific preferences failed to apply!","Error") + else + to_chat(usr,"Virgo-specific preferences applied from active slot!") + unsaved_changes = FALSE + return TRUE + if("setflavor") + var/new_flavor = html_encode(input(usr,"What your character tastes like (40ch limit). This text will be printed to the pred after 'X tastes of...' so just put something like 'strawberries and cream':","Character Flavor",host.vore_taste) as text|null) + if(!new_flavor) return FALSE - if("Allow Digestion") - user.digestable = TRUE - if("Prevent Digestion") - user.digestable = FALSE - if(user.client.prefs_vr) - user.client.prefs_vr.digestable = user.digestable - - if(href_list["toggleddevour"]) - var/choice = alert(user, "This button is to toggle your ability to be devoured by others. Devouring is currently: [user.devourable ? "Allowed" : "Prevented"]", "", "Be Devourable", "Cancel", "Prevent being Devoured") - switch(choice) - if("Cancel") + new_flavor = readd_quotes(new_flavor) + if(length(new_flavor) > FLAVOR_MAX) + alert("Entered flavor/taste text too long. [FLAVOR_MAX] character limit.","Error!") return FALSE - if("Be Devourable") - user.devourable = TRUE - if("Prevent being Devoured") - user.devourable = FALSE - - if(user.client.prefs_vr) - user.client.prefs_vr.devourable = user.devourable - - if(href_list["toggledfeed"]) - var/choice = alert(user, "This button is to toggle your ability to be fed to or by others vorishly. Force Feeding is currently: [user.feeding ? "Allowed" : "Prevented"]", "", "Allow Feeding", "Cancel", "Prevent Feeding") - switch(choice) - if("Cancel") + host.vore_taste = new_flavor + unsaved_changes = TRUE + return TRUE + if("setsmell") + var/new_smell = html_encode(input(usr,"What your character smells like (40ch limit). This text will be printed to the pred after 'X smells of...' so just put something like 'strawberries and cream':","Character Smell",host.vore_smell) as text|null) + if(!new_smell) return FALSE - if("Allow Feeding") - user.feeding = TRUE - if("Prevent Feeding") - user.feeding = FALSE - if(user.client.prefs_vr) - user.client.prefs_vr.feeding = user.feeding - - if(href_list["toggleabsorbable"]) - var/choice = alert(user, "This button allows preds to know whether you prefer or don't prefer to be absorbed. Currently you are [user.absorbable? "" : "not"] giving permission.", "", "Allow absorption", "Cancel", "Disallow absorption") - switch(choice) - if("Cancel") + new_smell = readd_quotes(new_smell) + if(length(new_smell) > FLAVOR_MAX) + alert("Entered perfume/smell text too long. [FLAVOR_MAX] character limit.","Error!") return FALSE - if("Allow absorption") - user.absorbable = TRUE - if("Disallow absorption") - user.absorbable = FALSE + host.vore_smell = new_smell + unsaved_changes = TRUE + return TRUE + if("toggle_dropnom_pred") + host.can_be_drop_pred = !host.can_be_drop_pred + if(host.client.prefs_vr) + host.client.prefs_vr.can_be_drop_pred = host.can_be_drop_pred + unsaved_changes = TRUE + return TRUE + if("toggle_dropnom_prey") + host.can_be_drop_prey = !host.can_be_drop_prey + if(host.client.prefs_vr) + host.client.prefs_vr.can_be_drop_prey = host.can_be_drop_prey + unsaved_changes = TRUE + return TRUE + if("toggle_digest") + host.digestable = !host.digestable + if(host.client.prefs_vr) + host.client.prefs_vr.digestable = host.digestable + unsaved_changes = TRUE + return TRUE + if("toggle_devour") + host.devourable = !host.devourable + if(host.client.prefs_vr) + host.client.prefs_vr.devourable = host.devourable + unsaved_changes = TRUE + return TRUE + if("toggle_feed") + host.feeding = !host.feeding + if(host.client.prefs_vr) + host.client.prefs_vr.feeding = host.feeding + unsaved_changes = TRUE + return TRUE + if("toggle_absorbable") + host.absorbable = !host.absorbable + if(host.client.prefs_vr) + host.client.prefs_vr.absorbable = host.absorbable + unsaved_changes = TRUE + return TRUE + if("toggle_leaveremains") + host.digest_leave_remains = !host.digest_leave_remains + if(host.client.prefs_vr) + host.client.prefs_vr.digest_leave_remains = host.digest_leave_remains + unsaved_changes = TRUE + return TRUE + if("toggle_mobvore") + host.allowmobvore = !host.allowmobvore + if(host.client.prefs_vr) + host.client.prefs_vr.allowmobvore = host.allowmobvore + unsaved_changes = TRUE + return TRUE + if("toggle_healbelly") + host.permit_healbelly = !host.permit_healbelly + if(host.client.prefs_vr) + host.client.prefs_vr.permit_healbelly = host.permit_healbelly + unsaved_changes = TRUE + return TRUE + if("toggle_noisy") + host.noisy = !host.noisy + unsaved_changes = TRUE + return TRUE - if(user.client.prefs_vr) - user.client.prefs_vr.absorbable = user.absorbable +/datum/vore_look/proc/pick_from_inside(mob/user, params) + var/atom/movable/target = locate(params["pick"]) + var/obj/belly/OB = locate(params["belly"]) - if(href_list["toggledlm"]) - var/choice = alert(user, "This button allows preds to have your remains be left in their belly after you are digested. This will only happen if pred sets their belly to do so. Remains consist of skeletal parts. Currently you are [user.digest_leave_remains? "" : "not"] leaving remains.", "", "Allow Post-digestion Remains", "Cancel", "Disallow Post-digestion Remains") - switch(choice) + if(!(target in OB)) + return TRUE // Aren't here anymore, need to update menu + + var/intent = "Examine" + if(isliving(target)) + intent = alert("What do you want to do to them?","Query","Examine","Help Out","Devour") + + else if(istype(target, /obj/item)) + intent = alert("What do you want to do to that?","Query","Examine","Use Hand") + + switch(intent) + if("Examine") //Examine a mob inside another mob + var/list/results = target.examine(host) + if(!results || !results.len) + results = list("You were unable to examine that. Tell a developer!") + to_chat(user, jointext(results, "
")) + return TRUE + + if("Use Hand") + if(host.stat) + to_chat(user, "You can't do that in your state!") + return TRUE + + host.ClickOn(target) + return TRUE + + if(!isliving(target)) + return + + var/mob/living/M = target + switch(intent) + if("Help Out") //Help the inside-mob out + if(host.stat || host.absorbed || M.absorbed) + to_chat(user, "You can't do that in your state!") + return TRUE + + to_chat(user,"You begin to push [M] to freedom!") + to_chat(M,"[host] begins to push you to freedom!") + to_chat(M.loc,"Someone is trying to escape from inside you!") + sleep(50) + if(prob(33)) + OB.release_specific_contents(M) + to_chat(user,"You manage to help [M] to safety!") + to_chat(M,"[host] pushes you free!") + to_chat(OB.owner,"[M] forces free of the confines of your body!") + else + to_chat(user,"[M] slips back down inside despite your efforts.") + to_chat(M," Even with [host]'s help, you slip back inside again.") + to_chat(OB.owner,"Your body efficiently shoves [M] back where they belong.") + return TRUE + + if("Devour") //Eat the inside mob + if(host.absorbed || host.stat) + to_chat(user,"You can't do that in your state!") + return TRUE + + if(!host.vore_selected) + to_chat(user,"Pick a belly on yourself first!") + return TRUE + + var/obj/belly/TB = host.vore_selected + to_chat(user,"You begin to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!") + to_chat(M,"[host] begins to [lowertext(TB.vore_verb)] you into their [lowertext(TB.name)]!") + to_chat(OB.owner,"Someone inside you is eating someone else!") + + sleep(TB.nonhuman_prey_swallow_time) //Can't do after, in a stomach, weird things abound. + if((host in OB) && (M in OB)) //Make sure they're still here. + to_chat(user,"You manage to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!") + to_chat(M,"[host] manages to [lowertext(TB.vore_verb)] you into their [lowertext(TB.name)]!") + to_chat(OB.owner,"Someone inside you has eaten someone else!") + TB.nom_mob(M) + +/datum/vore_look/proc/pick_from_outside(mob/user, params) + var/intent + + //Handle the [All] choice. Ugh inelegant. Someone make this pretty. + if(params["pickall"]) + intent = alert("Eject all, Move all?","Query","Eject all","Cancel","Move all") + switch(intent) if("Cancel") + return TRUE + + if("Eject all") + if(host.stat) + to_chat(user,"You can't do that in your state!") + return TRUE + + host.vore_selected.release_all_contents() + return TRUE + + if("Move all") + if(host.stat) + to_chat(user,"You can't do that in your state!") + return TRUE + + var/obj/belly/choice = input("Move all where?","Select Belly") as null|anything in host.vore_organs + if(!choice) + return FALSE + + for(var/atom/movable/target in host.vore_selected) + to_chat(target,"You're squished from [host]'s [lowertext(host.vore_selected)] to their [lowertext(choice.name)]!") + host.vore_selected.transfer_contents(target, choice, 1) + return TRUE + return + + var/atom/movable/target = locate(params["pick"]) + if(!(target in host.vore_selected)) + return TRUE // Not in our X anymore, update UI + intent = "Examine" + intent = alert("Examine, Eject, Move? Examine if you want to leave this box.","Query","Examine","Eject","Move") + switch(intent) + if("Examine") + var/list/results = target.examine(host) + if(!results || !results.len) + results = list("You were unable to examine that. Tell a developer!") + to_chat(user, jointext(results, "
")) + return TRUE + + if("Eject") + if(host.stat) + to_chat(user,"You can't do that in your state!") + return TRUE + + host.vore_selected.release_specific_contents(target) + + if("Move") + if(host.stat) + to_chat(user,"You can't do that in your state!") + return TRUE + + var/obj/belly/choice = input("Move [target] where?","Select Belly") as null|anything in host.vore_organs + if(!choice || !(target in host.vore_selected)) + return TRUE + + to_chat(target,"You're squished from [host]'s [lowertext(host.vore_selected.name)] to their [lowertext(choice.name)]!") + host.vore_selected.transfer_contents(target, choice) + +/datum/vore_look/proc/set_attr(mob/user, params) + if(!host.vore_selected) + alert("No belly selected to modify.") + return FALSE + + var/attr = params["attribute"] + switch(attr) + if("b_name") + var/new_name = html_encode(input(usr,"Belly's new name:","New Name") as text|null) + + var/failure_msg + if(length(new_name) > BELLIES_NAME_MAX || length(new_name) < BELLIES_NAME_MIN) + failure_msg = "Entered belly name length invalid (must be longer than [BELLIES_NAME_MIN], no more than than [BELLIES_NAME_MAX])." + // else if(whatever) //Next test here. + else + for(var/belly in host.vore_organs) + var/obj/belly/B = belly + if(lowertext(new_name) == lowertext(B.name)) + failure_msg = "No duplicate belly names, please." + break + + if(failure_msg) //Something went wrong. + alert(user,failure_msg,"Error!") return FALSE - if("Allow Post-digestion Remains") - user.digest_leave_remains = TRUE - if("Disallow Post-digestion Remains") - user.digest_leave_remains = FALSE - if(user.client.prefs_vr) - user.client.prefs_vr.digest_leave_remains = user.digest_leave_remains + host.vore_selected.name = new_name + . = TRUE + if("b_wetness") + host.vore_selected.is_wet = !host.vore_selected.is_wet + . = TRUE + if("b_wetloop") + host.vore_selected.wet_loop = !host.vore_selected.wet_loop + . = TRUE + if("b_mode") + var/list/menu_list = host.vore_selected.digest_modes.Copy() + if(istype(usr,/mob/living/carbon/human)) + menu_list += DM_TRANSFORM - if(href_list["togglemv"]) - var/choice = alert(user, "This button is for those who don't like being eaten by mobs. Mobs are currently: [user.allowmobvore ? "Allowed to eat" : "Prevented from eating"] you.", "", "Allow Mob Predation", "Cancel", "Prevent Mob Predation") - switch(choice) - if("Cancel") + var/new_mode = input("Choose Mode (currently [host.vore_selected.digest_mode])") as null|anything in menu_list + if(!new_mode) return FALSE - if("Allow Mob Predation") - user.allowmobvore = TRUE - if("Prevent Mob Predation") - user.allowmobvore = FALSE - if(user.client.prefs_vr) - user.client.prefs_vr.allowmobvore = user.allowmobvore + if(new_mode == DM_TRANSFORM) //Snowflek submenu + var/list/tf_list = host.vore_selected.transform_modes + var/new_tf_mode = input("Choose TF Mode (currently [host.vore_selected.digest_mode])") as null|anything in tf_list + if(!new_tf_mode) + return FALSE + host.vore_selected.digest_mode = new_tf_mode + return - if(href_list["togglehealbelly"]) - var/choice = alert(user, "This button is for those who don't like healbelly used on them as a mechanic. It does not affect anything, but is displayed under mechanical prefs for ease of quick checks. You are currently: [user.allowmobvore ? "Okay" : "Not Okay"] with players using healbelly on you.", "", "Allow Healing Belly", "Cancel", "Disallow Healing Belly") - switch(choice) - if("Cancel") + host.vore_selected.digest_mode = new_mode + . = TRUE + if("b_addons") + var/list/menu_list = host.vore_selected.mode_flag_list.Copy() + var/toggle_addon = input("Toggle Addon") as null|anything in menu_list + if(!toggle_addon) return FALSE - if("Allow Healing Belly") - user.permit_healbelly = TRUE - if("Disallow Healing Belly") - user.permit_healbelly = FALSE + host.vore_selected.mode_flags ^= host.vore_selected.mode_flag_list[toggle_addon] + host.vore_selected.items_preserved.Cut() //Re-evaltuate all items in belly on + . = TRUE + if("b_item_mode") + var/list/menu_list = host.vore_selected.item_digest_modes.Copy() - if(user.client.prefs_vr) - user.client.prefs_vr.permit_healbelly = user.permit_healbelly - - if(href_list["togglenoisy"]) - var/choice = alert(user, "Toggle audible hunger noises. Currently: [user.noisy ? "Enabled" : "Disabled"]", "", "Enable audible hunger", "Cancel", "Disable audible hunger") - switch(choice) - if("Cancel") + var/new_mode = input("Choose Mode (currently [host.vore_selected.item_digest_mode])") as null|anything in menu_list + if(!new_mode) return FALSE - if("Enable audible hunger") - user.noisy = TRUE - if("Disable audible hunger") - user.noisy = FALSE - //Refresh when interacted with, returning 1 makes vore_look.Topic update - return TRUE + host.vore_selected.item_digest_mode = new_mode + host.vore_selected.items_preserved.Cut() //Re-evaltuate all items in belly on belly-mode change + . = TRUE + if("b_contaminates") + host.vore_selected.contaminates = !host.vore_selected.contaminates + . = TRUE + if("b_contamination_flavor") + var/list/menu_list = contamination_flavors.Copy() + var/new_flavor = input("Choose Contamination Flavor Text Type (currently [host.vore_selected.contamination_flavor])") as null|anything in menu_list + if(!new_flavor) + return FALSE + host.vore_selected.contamination_flavor = new_flavor + . = TRUE + if("b_contamination_color") + var/list/menu_list = contamination_colors.Copy() + var/new_color = input("Choose Contamination Color (currently [host.vore_selected.contamination_color])") as null|anything in menu_list + if(!new_color) + return FALSE + host.vore_selected.contamination_color = new_color + host.vore_selected.items_preserved.Cut() //To re-contaminate for new color + . = TRUE + if("b_desc") + var/new_desc = html_encode(input(usr,"Belly Description ([BELLIES_DESC_MAX] char limit):","New Description",host.vore_selected.desc) as message|null) + + if(new_desc) + new_desc = readd_quotes(new_desc) + if(length(new_desc) > BELLIES_DESC_MAX) + alert("Entered belly desc too long. [BELLIES_DESC_MAX] character limit.","Error") + return FALSE + host.vore_selected.desc = new_desc + . = TRUE + if("b_msgs") + alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max 150 characters per message, max 10 messages per topic.","Really, don't.") + var/help = " Press enter twice to separate messages. '%pred' will be replaced with your name. '%prey' will be replaced with the prey's name. '%belly' will be replaced with your belly's name." + switch(params["msgtype"]) + if("dmp") + var/new_message = input(user,"These are sent to prey when they expire. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Digest Message (to prey)",host.vore_selected.get_messages("dmp")) as message + if(new_message) + host.vore_selected.set_messages(new_message,"dmp") + + if("dmo") + var/new_message = input(user,"These are sent to you when prey expires in you. Write them in 2nd person ('you feel X'). Avoid using %pred in this type."+help,"Digest Message (to you)",host.vore_selected.get_messages("dmo")) as message + if(new_message) + host.vore_selected.set_messages(new_message,"dmo") + + if("smo") + var/new_message = input(user,"These are sent to those nearby when prey struggles. Write them in 3rd person ('X's Y bulges')."+help,"Struggle Message (outside)",host.vore_selected.get_messages("smo")) as message + if(new_message) + host.vore_selected.set_messages(new_message,"smo") + + if("smi") + var/new_message = input(user,"These are sent to prey when they struggle. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Struggle Message (inside)",host.vore_selected.get_messages("smi")) as message + if(new_message) + host.vore_selected.set_messages(new_message,"smi") + + if("em") + var/new_message = input(user,"These are sent to people who examine you when this belly has contents. Write them in 3rd person ('Their %belly is bulging')."+help,"Examine Message (when full)",host.vore_selected.get_messages("em")) as message + if(new_message) + host.vore_selected.set_messages(new_message,"em") + + if("reset") + var/confirm = alert(user,"This will delete any custom messages. Are you sure?","Confirmation","DELETE","Cancel") + if(confirm == "DELETE") + host.vore_selected.digest_messages_prey = initial(host.vore_selected.digest_messages_prey) + host.vore_selected.digest_messages_owner = initial(host.vore_selected.digest_messages_owner) + host.vore_selected.struggle_messages_outside = initial(host.vore_selected.struggle_messages_outside) + host.vore_selected.struggle_messages_inside = initial(host.vore_selected.struggle_messages_inside) + . = TRUE + if("b_verb") + var/new_verb = html_encode(input(usr,"New verb when eating (infinitive tense, e.g. nom or swallow):","New Verb") as text|null) + + if(length(new_verb) > BELLIES_NAME_MAX || length(new_verb) < BELLIES_NAME_MIN) + alert("Entered verb length invalid (must be longer than [BELLIES_NAME_MIN], no longer than [BELLIES_NAME_MAX]).","Error") + return FALSE + + host.vore_selected.vore_verb = new_verb + . = TRUE + if("b_fancy_sound") + host.vore_selected.fancy_vore = !host.vore_selected.fancy_vore + host.vore_selected.vore_sound = "Gulp" + host.vore_selected.release_sound = "Splatter" + // defaults as to avoid potential bugs + . = TRUE + if("b_release") + var/choice + if(host.vore_selected.fancy_vore) + choice = input(user,"Currently set to [host.vore_selected.release_sound]","Select Sound") as null|anything in fancy_release_sounds + else + choice = input(user,"Currently set to [host.vore_selected.release_sound]","Select Sound") as null|anything in classic_release_sounds + + if(!choice) + return FALSE + + host.vore_selected.release_sound = choice + . = TRUE + if("b_releasesoundtest") + var/sound/releasetest + if(host.vore_selected.fancy_vore) + releasetest = fancy_release_sounds[host.vore_selected.release_sound] + else + releasetest = classic_release_sounds[host.vore_selected.release_sound] + + if(releasetest) + SEND_SOUND(user, releasetest) + . = TRUE + if("b_sound") + var/choice + if(host.vore_selected.fancy_vore) + choice = input(user,"Currently set to [host.vore_selected.vore_sound]","Select Sound") as null|anything in fancy_vore_sounds + else + choice = input(user,"Currently set to [host.vore_selected.vore_sound]","Select Sound") as null|anything in classic_vore_sounds + + if(!choice) + return FALSE + + host.vore_selected.vore_sound = choice + . = TRUE + if("b_soundtest") + var/sound/voretest + if(host.vore_selected.fancy_vore) + voretest = fancy_vore_sounds[host.vore_selected.vore_sound] + else + voretest = classic_vore_sounds[host.vore_selected.vore_sound] + if(voretest) + SEND_SOUND(user, voretest) + . = TRUE + if("b_tastes") + host.vore_selected.can_taste = !host.vore_selected.can_taste + . = TRUE + if("b_bulge_size") + var/new_bulge = input(user, "Choose the required size prey must be to show up on examine, ranging from 25% to 200% Set this to 0 for no text on examine.", "Set Belly Examine Size.") as num|null + if(new_bulge == null) + return FALSE + if(new_bulge == 0) //Disable. + host.vore_selected.bulge_size = 0 + to_chat(user,"Your stomach will not be seen on examine.") + else if (!ISINRANGE(new_bulge,25,200)) + host.vore_selected.bulge_size = 0.25 //Set it to the default. + to_chat(user,"Invalid size.") + else if(new_bulge) + host.vore_selected.bulge_size = (new_bulge/100) + . = TRUE + if("b_grow_shrink") + var/new_grow = input(user, "Choose the size that prey will be grown/shrunk to, ranging from 25% to 200%", "Set Growth Shrink Size.", host.vore_selected.shrink_grow_size) as num|null + if (new_grow == null) + return FALSE + if (!ISINRANGE(new_grow,25,200)) + host.vore_selected.shrink_grow_size = 1 //Set it to the default + to_chat(user,"Invalid size.") + else if(new_grow) + host.vore_selected.shrink_grow_size = (new_grow*0.01) + . = TRUE + if("b_nutritionpercent") + var/new_nutrition = input(user, "Choose the nutrition gain percentage you will recieve per tick from prey. Ranges from 0.01 to 100.", "Set Nutrition Gain Percentage.", host.vore_selected.nutrition_percent) as num|null + if(new_nutrition == null) + return FALSE + var/new_new_nutrition = CLAMP(new_nutrition, 0.01, 100) + host.vore_selected.nutrition_percent = new_new_nutrition + . = TRUE + if("b_burn_dmg") + var/new_damage = input(user, "Choose the amount of burn damage prey will take per tick. Ranges from 0 to 6.", "Set Belly Burn Damage.", host.vore_selected.digest_burn) as num|null + if(new_damage == null) + return FALSE + var/new_new_damage = CLAMP(new_damage, 0, 6) + host.vore_selected.digest_burn = new_new_damage + . = TRUE + if("b_brute_dmg") + var/new_damage = input(user, "Choose the amount of brute damage prey will take per tick. Ranges from 0 to 6", "Set Belly Brute Damage.", host.vore_selected.digest_brute) as num|null + if(new_damage == null) + return FALSE + var/new_new_damage = CLAMP(new_damage, 0, 6) + host.vore_selected.digest_brute = new_new_damage + . = TRUE + if("b_escapable") + if(host.vore_selected.escapable == 0) //Possibly escapable and special interactions. + host.vore_selected.escapable = 1 + to_chat(usr,"Prey now have special interactions with your [lowertext(host.vore_selected.name)] depending on your settings.") + else if(host.vore_selected.escapable == 1) //Never escapable. + host.vore_selected.escapable = 0 + to_chat(usr,"Prey will not be able to have special interactions with your [lowertext(host.vore_selected.name)].") + else + alert("Something went wrong. Your stomach will now not have special interactions. Press the button enable them again and tell a dev.","Error") //If they somehow have a varable that's not 0 or 1 + host.vore_selected.escapable = 0 + . = TRUE + if("b_escapechance") + var/escape_chance_input = input(user, "Set prey escape chance on resist (as %)", "Prey Escape Chance") as num|null + if(!isnull(escape_chance_input)) //These have to be 'null' because both cancel and 0 are valid, separate options + host.vore_selected.escapechance = sanitize_integer(escape_chance_input, 0, 100, initial(host.vore_selected.escapechance)) + . = TRUE + if("b_escapetime") + var/escape_time_input = input(user, "Set number of seconds for prey to escape on resist (1-60)", "Prey Escape Time") as num|null + if(!isnull(escape_time_input)) + host.vore_selected.escapetime = sanitize_integer(escape_time_input*10, 10, 600, initial(host.vore_selected.escapetime)) + . = TRUE + if("b_transferchance") + var/transfer_chance_input = input(user, "Set belly transfer chance on resist (as %). You must also set the location for this to have any effect.", "Prey Escape Time") as num|null + if(!isnull(transfer_chance_input)) + host.vore_selected.transferchance = sanitize_integer(transfer_chance_input, 0, 100, initial(host.vore_selected.transferchance)) + . = TRUE + if("b_transferlocation") + var/obj/belly/choice = input("Where do you want your [lowertext(host.vore_selected.name)] to lead if prey resists?","Select Belly") as null|anything in (host.vore_organs + "None - Remove" - host.vore_selected) + + if(!choice) //They cancelled, no changes + return FALSE + else if(choice == "None - Remove") + host.vore_selected.transferlocation = null + else + host.vore_selected.transferlocation = choice.name + . = TRUE + if("b_absorbchance") + var/absorb_chance_input = input(user, "Set belly absorb mode chance on resist (as %)", "Prey Absorb Chance") as num|null + if(!isnull(absorb_chance_input)) + host.vore_selected.absorbchance = sanitize_integer(absorb_chance_input, 0, 100, initial(host.vore_selected.absorbchance)) + . = TRUE + if("b_digestchance") + var/digest_chance_input = input(user, "Set belly digest mode chance on resist (as %)", "Prey Digest Chance") as num|null + if(!isnull(digest_chance_input)) + host.vore_selected.digestchance = sanitize_integer(digest_chance_input, 0, 100, initial(host.vore_selected.digestchance)) + . = TRUE + if("b_del") + var/alert = alert("Are you sure you want to delete your [lowertext(host.vore_selected.name)]?","Confirmation","Delete","Cancel") + if(!(alert == "Delete")) + return FALSE + + var/failure_msg = "" + + var/dest_for //Check to see if it's the destination of another vore organ. + for(var/belly in host.vore_organs) + var/obj/belly/B = belly + if(B.transferlocation == host.vore_selected) + dest_for = B.name + failure_msg += "This is the destiantion for at least '[dest_for]' belly transfers. Remove it as the destination from any bellies before deleting it. " + break + + if(host.vore_selected.contents.len) + failure_msg += "You cannot delete bellies with contents! " //These end with spaces, to be nice looking. Make sure you do the same. + if(host.vore_selected.immutable) + failure_msg += "This belly is marked as undeletable. " + if(host.vore_organs.len == 1) + failure_msg += "You must have at least one belly. " + + if(failure_msg) + alert(user,failure_msg,"Error!") + return FALSE + + qdel(host.vore_selected) + host.vore_selected = host.vore_organs[1] + . = TRUE + + if(.) + unsaved_changes = TRUE \ No newline at end of file diff --git a/code/modules/vore/fluffstuff/custom_boxes_vr.dm b/code/modules/vore/fluffstuff/custom_boxes_vr.dm index 489cab17f55..4b16e1d66fc 100644 --- a/code/modules/vore/fluffstuff/custom_boxes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_boxes_vr.dm @@ -93,7 +93,6 @@ desc = "A small box containing Yonra's personal effects" has_items = list( /obj/item/weapon/melee/fluff/holochain/mass, - /obj/item/weapon/implanter/reagent_generator/yonra, /obj/item/clothing/accessory/medal/silver/unity) //ivymoomoo:Ivy Baladeva @@ -281,35 +280,19 @@ Swimsuits, for general use, to avoid arriving to work with your swimsuit. /obj/item/weapon/storage/box/monkeycubes/sobakacubes name = "sobaka cube box" desc = "Drymate brand sobaka cubes. Just add water!" - -/obj/item/weapon/storage/box/monkeycubes/sobakacubes/New() - ..() - for(var/i = 1 to 4) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/sobakacube(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/sobakacube = 4) /obj/item/weapon/storage/box/monkeycubes/sarucubes name = "saru cube box" desc = "Drymate brand saru cubes. Just add water!" - -/obj/item/weapon/storage/box/monkeycubes/sarucubes/New() - ..() - for(var/i = 1 to 4) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/sarucube(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/sarucube = 4) /obj/item/weapon/storage/box/monkeycubes/sparracubes name = "sparra cube box" desc = "Drymate brand sparra cubes. Just add water!" - -/obj/item/weapon/storage/box/monkeycubes/sparracubes/New() - ..() - for(var/i = 1 to 4) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/sparracube(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/sparracube = 4) /obj/item/weapon/storage/box/monkeycubes/wolpincubes name = "wolpin cube box" desc = "Drymate brand wolpin cubes. Just add water!" - -/obj/item/weapon/storage/box/monkeycubes/wolpincubes/New() - ..() - for(var/i = 1 to 4) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/wolpincube(src) + starts_with = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/wolpincube = 4) diff --git a/code/modules/vore/fluffstuff/custom_implants_vr.dm b/code/modules/vore/fluffstuff/custom_implants_vr.dm new file mode 100644 index 00000000000..8647c9d68f2 --- /dev/null +++ b/code/modules/vore/fluffstuff/custom_implants_vr.dm @@ -0,0 +1,547 @@ + +//WickedTempest: Chakat Tempest +/obj/item/weapon/implant/reagent_generator/tempest + generated_reagents = list("milk" = 2) + reagent_name = "milk" + usable_volume = 1000 + + empty_message = list("Your breasts are almost completely drained!") + full_message = list("Your teats feel heavy and swollen!") + emote_descriptor = list("squeezes milk", "tugs on Tempest's breasts, milking them") + self_emote_descriptor = list("squeeze") + random_emote = list("moos quietly") + verb_name = "Milk" + verb_desc = "Grab Tempest's nipples and milk them into a container! May cause blushing and groaning." + +/obj/item/weapon/implanter/reagent_generator/tempest + implant_type = /obj/item/weapon/implant/reagent_generator/tempest + + +//Hottokeeki: Belle Day +/obj/item/weapon/implant/reagent_generator/belle + generated_reagents = list("milk" = 2) + reagent_name = "milk" + usable_volume = 5000 + + empty_message = list("Your breasts and or udder feel almost completely drained!", "You're feeling a liittle on the empty side...") + full_message = list("You're due for a milking; your breasts and or udder feel heavy and swollen!", "Looks like you've got some full tanks!") + emote_descriptor = list("squeezes milk", "tugs on Belle's breasts/udders, milking them", "extracts milk") + self_emote_descriptor = list("squeeze", "extract") + random_emote = list("moos", "mrours", "groans softly") + verb_name = "Milk" + verb_desc = "Obtain Belle's milk and put it into a container! May cause blushing and groaning, or arousal." + +/obj/item/weapon/implanter/reagent_generator/belle + implant_type = /obj/item/weapon/implant/reagent_generator/belle + +//Gowst: Eldi Moljir +//Eldi iz coolest elf-dorf. +/obj/item/weapon/implant/reagent_generator/eldi + name = "lactation implant" + desc = "This is an implant that allows the user to lactate." + generated_reagents = list("milk" = 2) + reagent_name = "milk" + usable_volume = 1000 + + empty_message = list("Your breasts feel unusually empty.", "Your chest feels lighter - your milk supply is empty!", "Your milk reserves have run dry.", "Your grateful nipples ache as the last of your milk leaves them.") + full_message = list("Your breasts ache badly - they are swollen and feel fit to burst!", "You need to be milked! Your breasts feel bloated, eager for release.", "Your milky breasts are starting to leak...") + emote_descriptor = list("squeezes Eldi's nipples, milking them", "milks Eldi's breasts", "extracts milk") + self_emote_descriptor = list("squeeze out", "extract") + random_emote = list("surpresses a moan", "gasps sharply", "bites her lower lip") + verb_name = "Milk" + verb_desc = "Grab Eldi's breasts and milk her, storing her fresh, warm milk in a container. This will undoubtedly turn her on." + +/obj/item/weapon/implanter/reagent_generator/eldi + implant_type = /obj/item/weapon/implant/reagent_generator/eldi + +//Vorrarkul: Theodora Lindt +/obj/item/weapon/implant/reagent_generator/vorrarkul + generated_reagents = list("chocolate_milk" = 2) + reagent_name = "chocalate milk" + usable_volume = 1000 + + empty_message = list("Your nipples are sore from being milked!") + full_message = list("Your breasts are full, their sweet scent emanating from your chest!") + emote_descriptor = list("squeezes chocolate milk from Theodora", "tugs on Theodora's nipples, milking them", "kneads Theodora's breasts, milking them") + self_emote_descriptor = list("squeeze", "knead") + random_emote = list("moans softly", "gives an involuntary squeal") + verb_name = "Milk" + verb_desc = "Grab Theodora's breasts and extract delicious chocolate milk from them!" + +/obj/item/weapon/implanter/reagent_generator/vorrarkul + implant_type = /obj/item/weapon/implant/reagent_generator/vorrarkul + +//Lycanthorph: Savannah Dixon +/obj/item/weapon/implant/reagent_generator/savannah + generated_reagents = list("milk" = 2) + reagent_name = "milk" + usable_volume = 1000 + + empty_message = list("Your nipples are sore from being milked!", "Your breasts feel drained, milk is no longer leaking from your nipples!") + full_message = list("Your breasts are full, their sweet scent emanating from your chest!", "Your breasts feel full, milk is starting to leak from your nipples, filling the air with it's sweet scent!") + emote_descriptor = list("squeezes sweet milk from Savannah", "tugs on Savannah's nipples, milking them", "kneads Savannah's breasts, milking them") + self_emote_descriptor = list("squeeze", "knead") + random_emote = list("lets out a soft moan", "gives an involuntary squeal") + verb_name = "Milk" + verb_desc = "Grab Savannah's breasts and extract sweet milk from them!" + +/obj/item/weapon/implanter/reagent_generator/savannah + implant_type = /obj/item/weapon/implant/reagent_generator/savannah + +//SpoopyLizz: Roiz Lizden +//I made this! Woo! +//implant +//-------------------- +/obj/item/weapon/implant/reagent_generator/roiz + name = "egg laying implant" + desc = "This is an implant that allows the user to lay eggs." + generated_reagents = list("egg" = 2) + usable_volume = 500 + transfer_amount = 50 + + empty_message = list("Your lower belly feels smooth and empty. Sorry, we're out of eggs!", "The reduced pressure in your lower belly tells you there are no more eggs.") + full_message = list("Your lower belly looks swollen with irregular bumps, and it feels heavy.", "Your lower abdomen feels really heavy, making it a bit hard to walk.") + emote_descriptor = list("an egg right out of Roiz's lower belly!", "into Roiz' belly firmly, forcing him to lay an egg!", "Roiz really tight, who promptly lays an egg!") + var/verb_descriptor = list("squeezes", "pushes", "hugs") + var/self_verb_descriptor = list("squeeze", "push", "hug") + var/short_emote_descriptor = list("lays", "forces out", "pushes out") + self_emote_descriptor = list("lay", "force out", "push out") + random_emote = list("hisses softly with a blush on his face", "yelps in embarrassment", "grunts a little") + assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_roiz + +/obj/item/weapon/implant/reagent_generator/roiz/post_implant(mob/living/carbon/source) + START_PROCESSING(SSobj, src) + to_chat(source, "You implant [source] with \the [src].") + source.verbs |= assigned_proc + return 1 + +/obj/item/weapon/implanter/reagent_generator/roiz + implant_type = /obj/item/weapon/implant/reagent_generator/roiz + +/mob/living/carbon/human/proc/use_reagent_implant_roiz() + set name = "Lay Egg" + set desc = "Force Roiz to lay an egg by squeezing into his lower body! This makes the lizard extremely embarrassed, and it looks funny." + set category = "Object" + set src in view(1) + + //do_reagent_implant(usr) + if(!isliving(usr) || !usr.checkClickCooldown()) + return + + if(usr.incapacitated() || usr.stat > CONSCIOUS) + return + + var/obj/item/weapon/implant/reagent_generator/roiz/rimplant + for(var/obj/item/organ/external/E in organs) + for(var/obj/item/weapon/implant/I in E.implants) + if(istype(I, /obj/item/weapon/implant/reagent_generator)) + rimplant = I + break + if (rimplant) + if(rimplant.reagents.total_volume <= rimplant.transfer_amount) + to_chat(src, "[pick(rimplant.empty_message)]") + return + + new /obj/item/weapon/reagent_containers/food/snacks/egg/roiz(get_turf(src)) + + var/index = rand(0,3) + + if (usr != src) + var/emote = rimplant.emote_descriptor[index] + var/verb_desc = rimplant.verb_descriptor[index] + var/self_verb_desc = rimplant.self_verb_descriptor[index] + usr.visible_message("[usr] [verb_desc] [emote]", + "You [self_verb_desc] [emote]") + else + visible_message("[src] [pick(rimplant.short_emote_descriptor)] an egg.", + "You [pick(rimplant.self_emote_descriptor)] an egg.") + if(prob(15)) + visible_message("[src] [pick(rimplant.random_emote)].") // M-mlem. + + rimplant.reagents.remove_any(rimplant.transfer_amount) + +//Cameron653: Jasmine Lizden +/obj/item/weapon/implant/reagent_generator/jasmine + name = "egg laying implant" + desc = "This is an implant that allows the user to lay eggs." + generated_reagents = list("egg" = 2) + usable_volume = 500 + transfer_amount = 50 + + empty_message = list("Your lower belly feels flat, empty, and somewhat rough!", "Your lower belly feels completely empty, no more bulges visible... At least, for the moment!") + full_message = list("Your lower belly is stretched out, smooth,and heavy, small bulges visible from within!", "It takes considerably more effort to move yourself, the large bulges within your gut most likely the cause!") + emote_descriptor = list("an egg from Jasmine's tauric belly!", "into Jasmine's gut, forcing her to lay a considerably large egg!", "Jasmine with a considerable amount of force, causing an egg to slip right out of her!") + var/verb_descriptor = list("squeezes", "pushes", "hugs") + var/self_verb_descriptor = list("squeeze", "push", "hug") + var/short_emote_descriptor = list("lays", "forces out", "pushes out") + self_emote_descriptor = list("lay", "force out", "push out") + random_emote = list("hisses softly with a blush on her face", "bites down on her lower lip", "lets out a light huff") + assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_jasmine + +/obj/item/weapon/implant/reagent_generator/jasmine/post_implant(mob/living/carbon/source) + START_PROCESSING(SSobj, src) + to_chat(source, "You implant [source] with \the [src].") + source.verbs |= assigned_proc + return 1 + +/obj/item/weapon/implanter/reagent_generator/jasmine + implant_type = /obj/item/weapon/implant/reagent_generator/jasmine + +/mob/living/carbon/human/proc/use_reagent_implant_jasmine() + set name = "Lay Egg" + set desc = "Cause Jasmine to lay an egg by squeezing her tauric belly!" + set category = "Object" + set src in view(1) + + //do_reagent_implant(usr) + if(!isliving(usr) || !usr.checkClickCooldown()) + return + + if(usr.incapacitated() || usr.stat > CONSCIOUS) + return + + var/obj/item/weapon/implant/reagent_generator/jasmine/rimplant + for(var/obj/item/organ/external/E in organs) + for(var/obj/item/weapon/implant/I in E.implants) + if(istype(I, /obj/item/weapon/implant/reagent_generator)) + rimplant = I + break + if (rimplant) + if(rimplant.reagents.total_volume <= rimplant.transfer_amount) + to_chat(src, "[pick(rimplant.empty_message)]") + return + + new /obj/item/weapon/reagent_containers/food/snacks/egg/roiz(get_turf(src)) + + var/index = rand(0,3) + + if (usr != src) + var/emote = rimplant.emote_descriptor[index] + var/verb_desc = rimplant.verb_descriptor[index] + var/self_verb_desc = rimplant.self_verb_descriptor[index] + usr.visible_message("[usr] [verb_desc] [emote]", + "You [self_verb_desc] [emote]") + else + visible_message("[src] [pick(rimplant.short_emote_descriptor)] an egg.", + "You [pick(rimplant.self_emote_descriptor)] an egg.") + if(prob(15)) + visible_message("[src] [pick(rimplant.random_emote)].") + + rimplant.reagents.remove_any(rimplant.transfer_amount) + +//Draycu: Schae Yonra +/obj/item/weapon/implant/reagent_generator/yonra + name = "egg laying implant" + desc = "This is an implant that allows the user to lay eggs." + generated_reagents = list("egg" = 2) + usable_volume = 500 + transfer_amount = 50 + + empty_message = list("Your feathery lower belly feels smooth and empty. For now...", "The lack of clacking eggs in your abdomen lets you know you're free to continue your day as normal.", "The reduced pressure in your lower belly tells you there are no more eggs.", "With a soft sigh, you can feel your lower body is empty. You know it will only be a matter of time before another batch fills you up again, however.") + full_message = list("Your feathery lower belly looks swollen with irregular bumps, and feels very heavy.", "Your feathery covered lower abdomen feels really heavy, making it a bit hard to walk.", "The added weight from your collection of eggs constantly reminds you that you'll have to lay soon!", "The sounds of eggs clacking as you walk reminds you that you will have to lay soon!") + emote_descriptor = list("an egg right out of Yonra's feathery crotch!", "into Yonra's belly firmly, forcing her to lay an egg!", ", making Yonra gasp and softly moan while an egg slides out.") + var/verb_descriptor = list("squeezes", "pushes", "hugs") + var/self_verb_descriptor = list("squeeze", "push", "hug") + var/short_emote_descriptor = list("lays", "forces out", "pushes out") + self_emote_descriptor = list("lay", "force out", "push out") + random_emote = list("hisses softly with a blush on her face", "yelps in embarrassment", "grunts a little") + assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_yonra + +/obj/item/weapon/implant/reagent_generator/yonra/post_implant(mob/living/carbon/source) + START_PROCESSING(SSobj, src) + to_chat(source, "You implant [source] with \the [src].") + source.verbs |= assigned_proc + return 1 + +/obj/item/weapon/implanter/reagent_generator/yonra + implant_type = /obj/item/weapon/implant/reagent_generator/yonra + +/mob/living/carbon/human/proc/use_reagent_implant_yonra() + set name = "Lay Egg" + set desc = "Force Yonra to lay an egg by squeezing into her lower body! This makes the Teshari stop whatever she is doing at the time, greatly embarassing her." + set category = "Object" + set src in view(1) + + //do_reagent_implant(usr) + if(!isliving(usr) || !usr.checkClickCooldown()) + return + + if(usr.incapacitated() || usr.stat > CONSCIOUS) + return + + var/obj/item/weapon/implant/reagent_generator/yonra/rimplant + for(var/obj/item/organ/external/E in organs) + for(var/obj/item/weapon/implant/I in E.implants) + if(istype(I, /obj/item/weapon/implant/reagent_generator)) + rimplant = I + break + if (rimplant) + if(rimplant.reagents.total_volume <= rimplant.transfer_amount) + to_chat(src, "[pick(rimplant.empty_message)]") + return + + new /obj/item/weapon/reagent_containers/food/snacks/egg/teshari(get_turf(src)) + + var/index = rand(0,3) + + if (usr != src) + var/emote = rimplant.emote_descriptor[index] + var/verb_desc = rimplant.verb_descriptor[index] + var/self_verb_desc = rimplant.self_verb_descriptor[index] + usr.visible_message("[usr] [verb_desc] [emote]", + "You [self_verb_desc] [emote]") + else + visible_message("[src] [pick(rimplant.short_emote_descriptor)] an egg.", + "You [pick(rimplant.self_emote_descriptor)] an egg.") + if(prob(15)) + visible_message("[src] [pick(rimplant.random_emote)].") + + rimplant.reagents.remove_any(rimplant.transfer_amount) + +/obj/item/weapon/reagent_containers/food/snacks/egg/teshari + name = "teshari egg" + desc = "It's a large teshari egg." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "tesh_egg" + filling_color = "#FDFFD1" + volume = 12 + +/obj/item/weapon/reagent_containers/food/snacks/egg/teshari/New() + ..() + reagents.add_reagent("egg", 10) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/egg/teshari/tesh2 + icon_state = "tesh_egg_2" + +//Konabird: Rischi +/obj/item/weapon/implant/reagent_generator/rischi + name = "egg laying implant" + desc = "This is an implant that allows the user to lay eggs." + generated_reagents = list("egg" = 2) + usable_volume = 3000 //They requested 1 egg every ~30 minutes. + transfer_amount = 3000 + + empty_message = list("Your abdomen feels normal and taught, like usual.", "The lack of eggs in your abdomen leaves your belly flat and smooth.", "The reduced pressure in your belly tells you there are no more eggs.", "With a soft sigh, you can feel your body is empty of eggs. You know it will only be a matter of time before an egg forms once again, however.") + full_message = list("Your lower abdomen feels a bit swollen", "You feel a pressure within your abdomen, and a broody mood slowly creeps over you.", "You can feel the egg inside of you shift as you move, the needy feeling to lay slowly growing stronger!", "You can feel the egg inside of you, swelling out your normally taught abdomen considerably. You'll definitely need to lay soon!") + emote_descriptor = list("Rischi, causing the small female to squeak and wriggle, an egg falling from between her legs!", "Rischi's midsection, forcing her to lay an egg!", "Rischi, the Teshari huffing and grunting as an egg is squeezed from her body!") + var/verb_descriptor = list("squeezes", "squashes", "hugs") + var/self_verb_descriptor = list("squeeze", "push", "hug") + var/short_emote_descriptor = list("lays", "forces out", "pushes out") + self_emote_descriptor = list("lay", "force out", "push out") + random_emote = list("trembles and huffs, panting from the exertion.", "sees what has happened and covers her face with both hands!", "whimpers softly, her legs shivering, knees pointed inward from the feeling.") + assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_rischi + +/obj/item/weapon/implant/reagent_generator/rischi/post_implant(mob/living/carbon/source) + START_PROCESSING(SSobj, src) + to_chat(source, "You implant [source] with \the [src].") + source.verbs |= assigned_proc + return 1 + +/obj/item/weapon/implanter/reagent_generator/rischi + implant_type = /obj/item/weapon/implant/reagent_generator/rischi + +/mob/living/carbon/human/proc/use_reagent_implant_rischi() + set name = "Lay Egg" + set desc = "Force Rischi to lay an egg by squeezing her! What a terribly rude thing to do!" + set category = "Object" + set src in view(1) + + //do_reagent_implant(usr) + if(!isliving(usr) || !usr.checkClickCooldown()) + return + + if(usr.incapacitated() || usr.stat > CONSCIOUS) + return + + var/obj/item/weapon/implant/reagent_generator/rischi/rimplant + for(var/obj/item/organ/external/E in organs) + for(var/obj/item/weapon/implant/I in E.implants) + if(istype(I, /obj/item/weapon/implant/reagent_generator)) + rimplant = I + break + if (rimplant) + if(rimplant.reagents.total_volume <= rimplant.transfer_amount) + to_chat(src, "[pick(rimplant.empty_message)]") + return + + new /obj/item/weapon/reagent_containers/food/snacks/egg/teshari/tesh2(get_turf(src)) + + var/index = rand(0,3) + + if (usr != src) + var/emote = rimplant.emote_descriptor[index] + var/verb_desc = rimplant.verb_descriptor[index] + var/self_verb_desc = rimplant.self_verb_descriptor[index] + usr.visible_message("[usr] [verb_desc] [emote]", + "You [self_verb_desc] [emote]") + else + visible_message("[src] falls to her knees as the urge to lay overwhelms her, letting out a whimper as she [pick(rimplant.short_emote_descriptor)] an egg from between her legs.", + "You fall to your knees as the urge to lay overwhelms you, letting out a whimper as you [pick(rimplant.self_emote_descriptor)] an egg from between your legs.") + if(prob(15)) + visible_message("[src] [pick(rimplant.random_emote)].") + + rimplant.reagents.remove_any(rimplant.transfer_amount) + +/* +/obj/item/weapon/implant/reagent_generator/pumila_nectar //Bugged. Two implants at once messes things up. + generated_reagents = list("honey" = 2) + reagent_name = "honey" + usable_volume = 5000 + + empty_message = list("You appear to be all out of nectar", "You feel as though you are lacking a majority of your nectar.") + full_message = list("You appear to be full of nectar.", "You feel as though you are full of nectar!") + emote_descriptor = list("squeezes nectar", "extracts nectar") + self_emote_descriptor = list("squeeze", "extract") + verb_name = "Extract Honey" + verb_desc = "Obtain pumila's nectar and put it into a container!" + +/obj/item/weapon/implanter/reagent_generator/pumila_nectar + implant_type = /obj/item/weapon/implant/reagent_generator/pumila_nectar +*/ +//Egg item +//------------- +/obj/item/weapon/reagent_containers/food/snacks/egg/roiz + name = "lizard egg" + desc = "It's a large lizard egg." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "egg_roiz" + filling_color = "#FDFFD1" + volume = 12 + +/obj/item/weapon/reagent_containers/food/snacks/egg/roiz/New() + ..() + reagents.add_reagent("egg", 9) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/egg/roiz/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype( W, /obj/item/weapon/pen/crayon )) + var/obj/item/weapon/pen/crayon/C = W + var/clr = C.colourName + + if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) + to_chat(user, "The egg refuses to take on this color!") + return + + to_chat(user, "You color \the [src] [clr]") + icon_state = "egg_roiz_[clr]" + desc = "It's a large lizard egg. It has been colored [clr]!" + if (clr == "rainbow") + var/number = rand(1,4) + icon_state = icon_state + num2text(number, 0) + else + ..() + +/obj/item/weapon/reagent_containers/food/snacks/friedegg/roiz + name = "fried lizard egg" + desc = "A large, fried lizard egg, with a touch of salt and pepper. It looks rather chewy." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "friedegg" + volume = 12 + +/obj/item/weapon/reagent_containers/food/snacks/friedegg/roiz/New() + ..() + reagents.add_reagent("protein", 9) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/boiledegg/roiz + name = "boiled lizard egg" + desc = "A hard boiled lizard egg. Be careful, a lizard detective may hatch!" + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "egg_roiz" + volume = 12 + +/obj/item/weapon/reagent_containers/food/snacks/boiledegg/roiz/New() + ..() + reagents.add_reagent("protein", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/chocolateegg/roiz + name = "chocolate lizard egg" + desc = "Such huge, sweet, fattening food. You feel gluttonous just looking at it." + icon = 'icons/vore/custom_items_vr.dmi' + icon_state = "chocolateegg_roiz" + filling_color = "#7D5F46" + nutriment_amt = 3 + nutriment_desc = list("chocolate" = 5) + volume = 18 + +/obj/item/weapon/reagent_containers/food/snacks/chocolateegg/roiz/New() + ..() + reagents.add_reagent("sugar", 6) + reagents.add_reagent("coco", 6) + reagents.add_reagent("milk", 2) + bitesize = 2 + +//SilverTalisman: Evian +/obj/item/weapon/implant/reagent_generator/evian + emote_descriptor = list("an egg right out of Evian's lower belly!", "into Evian' belly firmly, forcing him to lay an egg!", "Evian really tight, who promptly lays an egg!") + var/verb_descriptor = list("squeezes", "pushes", "hugs") + var/self_verb_descriptor = list("squeeze", "push", "hug") + var/short_emote_descriptor = list("lays", "forces out", "pushes out") + self_emote_descriptor = list("lay", "force out", "push out") + random_emote = list("hisses softly with a blush on his face", "yelps in embarrassment", "grunts a little") + assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_evian + +/obj/item/weapon/implant/reagent_generator/evian/post_implant(mob/living/carbon/source) + START_PROCESSING(SSobj, src) + to_chat(source, "You implant [source] with \the [src].") + source.verbs |= assigned_proc + return 1 + +/obj/item/weapon/implanter/reagent_generator/evian + implant_type = /obj/item/weapon/implant/reagent_generator/evian + +/mob/living/carbon/human/proc/use_reagent_implant_evian() + set name = "Lay Egg" + set desc = "Force Evian to lay an egg by squeezing into his lower body! This makes the lizard extremely embarrassed, and it looks funny." + set category = "Object" + set src in view(1) + + //do_reagent_implant(usr) + if(!isliving(usr) || !usr.checkClickCooldown()) + return + + if(usr.incapacitated() || usr.stat > CONSCIOUS) + return + + var/obj/item/weapon/implant/reagent_generator/evian/rimplant + for(var/obj/item/organ/external/E in organs) + for(var/obj/item/weapon/implant/I in E.implants) + if(istype(I, /obj/item/weapon/implant/reagent_generator)) + rimplant = I + break + if (rimplant) + if(rimplant.reagents.total_volume <= rimplant.transfer_amount) + to_chat(src, "[pick(rimplant.empty_message)]") + return + + new /obj/item/weapon/reagent_containers/food/snacks/egg/roiz/evian(get_turf(src)) //Roiz/evian so it gets all the functionality + + var/index = rand(0,3) + + if (usr != src) + var/emote = rimplant.emote_descriptor[index] + var/verb_desc = rimplant.verb_descriptor[index] + var/self_verb_desc = rimplant.self_verb_descriptor[index] + usr.visible_message("[usr] [verb_desc] [emote]", + "You [self_verb_desc] [emote]") + else + visible_message("[src] [pick(rimplant.short_emote_descriptor)] an egg.", + "You [pick(rimplant.self_emote_descriptor)] an egg.") + if(prob(15)) + visible_message("[src] [pick(rimplant.random_emote)].") // M-mlem. + + rimplant.reagents.remove_any(rimplant.transfer_amount) + +/obj/item/weapon/reagent_containers/food/snacks/egg/roiz/evian + name = "dragon egg" + desc = "A quite large dragon egg!" + icon_state = "egg_roiz_yellow" + + +/obj/item/weapon/reagent_containers/food/snacks/egg/roiz/evian/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype( W, /obj/item/weapon/pen/crayon)) //No coloring these ones! + return + else + ..() diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm index 8482c919b8f..e445cda2fc4 100644 --- a/code/modules/vore/fluffstuff/custom_items_vr.dm +++ b/code/modules/vore/fluffstuff/custom_items_vr.dm @@ -765,480 +765,6 @@ mid_length = 20 volume = 25 -//WickedTempest: Chakat Tempest -/obj/item/weapon/implant/reagent_generator/tempest - generated_reagents = list("milk" = 2) - reagent_name = "milk" - usable_volume = 1000 - - empty_message = list("Your breasts are almost completely drained!") - full_message = list("Your teats feel heavy and swollen!") - emote_descriptor = list("squeezes milk", "tugs on Tempest's breasts, milking them") - self_emote_descriptor = list("squeeze") - random_emote = list("moos quietly") - verb_name = "Milk" - verb_desc = "Grab Tempest's nipples and milk them into a container! May cause blushing and groaning." - -/obj/item/weapon/implanter/reagent_generator/tempest - implant_type = /obj/item/weapon/implant/reagent_generator/tempest - - -//Hottokeeki: Belle Day -/obj/item/weapon/implant/reagent_generator/belle - generated_reagents = list("milk" = 2) - reagent_name = "milk" - usable_volume = 5000 - - empty_message = list("Your breasts and or udder feel almost completely drained!", "You're feeling a liittle on the empty side...") - full_message = list("You're due for a milking; your breasts and or udder feel heavy and swollen!", "Looks like you've got some full tanks!") - emote_descriptor = list("squeezes milk", "tugs on Belle's breasts/udders, milking them", "extracts milk") - self_emote_descriptor = list("squeeze", "extract") - random_emote = list("moos", "mrours", "groans softly") - verb_name = "Milk" - verb_desc = "Obtain Belle's milk and put it into a container! May cause blushing and groaning, or arousal." - -/obj/item/weapon/implanter/reagent_generator/belle - implant_type = /obj/item/weapon/implant/reagent_generator/belle - -//Gowst: Eldi Moljir -//Eldi iz coolest elf-dorf. -/obj/item/weapon/implant/reagent_generator/eldi - name = "lactation implant" - desc = "This is an implant that allows the user to lactate." - generated_reagents = list("milk" = 2) - reagent_name = "milk" - usable_volume = 1000 - - empty_message = list("Your breasts feel unusually empty.", "Your chest feels lighter - your milk supply is empty!", "Your milk reserves have run dry.", "Your grateful nipples ache as the last of your milk leaves them.") - full_message = list("Your breasts ache badly - they are swollen and feel fit to burst!", "You need to be milked! Your breasts feel bloated, eager for release.", "Your milky breasts are starting to leak...") - emote_descriptor = list("squeezes Eldi's nipples, milking them", "milks Eldi's breasts", "extracts milk") - self_emote_descriptor = list("squeeze out", "extract") - random_emote = list("surpresses a moan", "gasps sharply", "bites her lower lip") - verb_name = "Milk" - verb_desc = "Grab Eldi's breasts and milk her, storing her fresh, warm milk in a container. This will undoubtedly turn her on." - -/obj/item/weapon/implanter/reagent_generator/eldi - implant_type = /obj/item/weapon/implant/reagent_generator/eldi - -//Vorrarkul: Theodora Lindt -/obj/item/weapon/implant/reagent_generator/vorrarkul - generated_reagents = list("chocolate_milk" = 2) - reagent_name = "chocalate milk" - usable_volume = 1000 - - empty_message = list("Your nipples are sore from being milked!") - full_message = list("Your breasts are full, their sweet scent emanating from your chest!") - emote_descriptor = list("squeezes chocolate milk from Theodora", "tugs on Theodora's nipples, milking them", "kneads Theodora's breasts, milking them") - self_emote_descriptor = list("squeeze", "knead") - random_emote = list("moans softly", "gives an involuntary squeal") - verb_name = "Milk" - verb_desc = "Grab Theodora's breasts and extract delicious chocolate milk from them!" - -/obj/item/weapon/implanter/reagent_generator/vorrarkul - implant_type = /obj/item/weapon/implant/reagent_generator/vorrarkul - -//Lycanthorph: Savannah Dixon -/obj/item/weapon/implant/reagent_generator/savannah - generated_reagents = list("milk" = 2) - reagent_name = "milk" - usable_volume = 1000 - - empty_message = list("Your nipples are sore from being milked!", "Your breasts feel drained, milk is no longer leaking from your nipples!") - full_message = list("Your breasts are full, their sweet scent emanating from your chest!", "Your breasts feel full, milk is starting to leak from your nipples, filling the air with it's sweet scent!") - emote_descriptor = list("squeezes sweet milk from Savannah", "tugs on Savannah's nipples, milking them", "kneads Savannah's breasts, milking them") - self_emote_descriptor = list("squeeze", "knead") - random_emote = list("lets out a soft moan", "gives an involuntary squeal") - verb_name = "Milk" - verb_desc = "Grab Savannah's breasts and extract sweet milk from them!" - -/obj/item/weapon/implanter/reagent_generator/savannah - implant_type = /obj/item/weapon/implant/reagent_generator/savannah - -//SpoopyLizz: Roiz Lizden -//I made this! Woo! -//implant -//-------------------- -/obj/item/weapon/implant/reagent_generator/roiz - name = "egg laying implant" - desc = "This is an implant that allows the user to lay eggs." - generated_reagents = list("egg" = 2) - usable_volume = 500 - transfer_amount = 50 - - empty_message = list("Your lower belly feels smooth and empty. Sorry, we're out of eggs!", "The reduced pressure in your lower belly tells you there are no more eggs.") - full_message = list("Your lower belly looks swollen with irregular bumps, and it feels heavy.", "Your lower abdomen feels really heavy, making it a bit hard to walk.") - emote_descriptor = list("an egg right out of Roiz's lower belly!", "into Roiz' belly firmly, forcing him to lay an egg!", "Roiz really tight, who promptly lays an egg!") - var/verb_descriptor = list("squeezes", "pushes", "hugs") - var/self_verb_descriptor = list("squeeze", "push", "hug") - var/short_emote_descriptor = list("lays", "forces out", "pushes out") - self_emote_descriptor = list("lay", "force out", "push out") - random_emote = list("hisses softly with a blush on his face", "yelps in embarrassment", "grunts a little") - assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_roiz - -/obj/item/weapon/implant/reagent_generator/roiz/post_implant(mob/living/carbon/source) - START_PROCESSING(SSobj, src) - to_chat(source, "You implant [source] with \the [src].") - source.verbs |= assigned_proc - return 1 - -/obj/item/weapon/implanter/reagent_generator/roiz - implant_type = /obj/item/weapon/implant/reagent_generator/roiz - -/mob/living/carbon/human/proc/use_reagent_implant_roiz() - set name = "Lay Egg" - set desc = "Force Roiz to lay an egg by squeezing into his lower body! This makes the lizard extremely embarrassed, and it looks funny." - set category = "Object" - set src in view(1) - - //do_reagent_implant(usr) - if(!isliving(usr) || !usr.checkClickCooldown()) - return - - if(usr.incapacitated() || usr.stat > CONSCIOUS) - return - - var/obj/item/weapon/implant/reagent_generator/roiz/rimplant - for(var/obj/item/organ/external/E in organs) - for(var/obj/item/weapon/implant/I in E.implants) - if(istype(I, /obj/item/weapon/implant/reagent_generator)) - rimplant = I - break - if (rimplant) - if(rimplant.reagents.total_volume <= rimplant.transfer_amount) - to_chat(src, "[pick(rimplant.empty_message)]") - return - - new /obj/item/weapon/reagent_containers/food/snacks/egg/roiz(get_turf(src)) - - var/index = rand(0,3) - - if (usr != src) - var/emote = rimplant.emote_descriptor[index] - var/verb_desc = rimplant.verb_descriptor[index] - var/self_verb_desc = rimplant.self_verb_descriptor[index] - usr.visible_message("[usr] [verb_desc] [emote]", - "You [self_verb_desc] [emote]") - else - visible_message("[src] [pick(rimplant.short_emote_descriptor)] an egg.", - "You [pick(rimplant.self_emote_descriptor)] an egg.") - if(prob(15)) - visible_message("[src] [pick(rimplant.random_emote)].") // M-mlem. - - rimplant.reagents.remove_any(rimplant.transfer_amount) - -//Cameron653: Jasmine Lizden -/obj/item/weapon/implant/reagent_generator/jasmine - name = "egg laying implant" - desc = "This is an implant that allows the user to lay eggs." - generated_reagents = list("egg" = 2) - usable_volume = 500 - transfer_amount = 50 - - empty_message = list("Your lower belly feels flat, empty, and somewhat rough!", "Your lower belly feels completely empty, no more bulges visible... At least, for the moment!") - full_message = list("Your lower belly is stretched out, smooth,and heavy, small bulges visible from within!", "It takes considerably more effort to move yourself, the large bulges within your gut most likely the cause!") - emote_descriptor = list("an egg from Jasmine's tauric belly!", "into Jasmine's gut, forcing her to lay a considerably large egg!", "Jasmine with a considerable amount of force, causing an egg to slip right out of her!") - var/verb_descriptor = list("squeezes", "pushes", "hugs") - var/self_verb_descriptor = list("squeeze", "push", "hug") - var/short_emote_descriptor = list("lays", "forces out", "pushes out") - self_emote_descriptor = list("lay", "force out", "push out") - random_emote = list("hisses softly with a blush on her face", "bites down on her lower lip", "lets out a light huff") - assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_jasmine - -/obj/item/weapon/implant/reagent_generator/jasmine/post_implant(mob/living/carbon/source) - START_PROCESSING(SSobj, src) - to_chat(source, "You implant [source] with \the [src].") - source.verbs |= assigned_proc - return 1 - -/obj/item/weapon/implanter/reagent_generator/jasmine - implant_type = /obj/item/weapon/implant/reagent_generator/jasmine - -/mob/living/carbon/human/proc/use_reagent_implant_jasmine() - set name = "Lay Egg" - set desc = "Cause Jasmine to lay an egg by squeezing her tauric belly!" - set category = "Object" - set src in view(1) - - //do_reagent_implant(usr) - if(!isliving(usr) || !usr.checkClickCooldown()) - return - - if(usr.incapacitated() || usr.stat > CONSCIOUS) - return - - var/obj/item/weapon/implant/reagent_generator/jasmine/rimplant - for(var/obj/item/organ/external/E in organs) - for(var/obj/item/weapon/implant/I in E.implants) - if(istype(I, /obj/item/weapon/implant/reagent_generator)) - rimplant = I - break - if (rimplant) - if(rimplant.reagents.total_volume <= rimplant.transfer_amount) - to_chat(src, "[pick(rimplant.empty_message)]") - return - - new /obj/item/weapon/reagent_containers/food/snacks/egg/roiz(get_turf(src)) - - var/index = rand(0,3) - - if (usr != src) - var/emote = rimplant.emote_descriptor[index] - var/verb_desc = rimplant.verb_descriptor[index] - var/self_verb_desc = rimplant.self_verb_descriptor[index] - usr.visible_message("[usr] [verb_desc] [emote]", - "You [self_verb_desc] [emote]") - else - visible_message("[src] [pick(rimplant.short_emote_descriptor)] an egg.", - "You [pick(rimplant.self_emote_descriptor)] an egg.") - if(prob(15)) - visible_message("[src] [pick(rimplant.random_emote)].") - - rimplant.reagents.remove_any(rimplant.transfer_amount) - -//Draycu: Schae Yonra -/obj/item/weapon/implant/reagent_generator/yonra - name = "egg laying implant" - desc = "This is an implant that allows the user to lay eggs." - generated_reagents = list("egg" = 2) - usable_volume = 500 - transfer_amount = 50 - - empty_message = list("Your feathery lower belly feels smooth and empty. For now...", "The lack of clacking eggs in your abdomen lets you know you're free to continue your day as normal.", "The reduced pressure in your lower belly tells you there are no more eggs.", "With a soft sigh, you can feel your lower body is empty. You know it will only be a matter of time before another batch fills you up again, however.") - full_message = list("Your feathery lower belly looks swollen with irregular bumps, and feels very heavy.", "Your feathery covered lower abdomen feels really heavy, making it a bit hard to walk.", "The added weight from your collection of eggs constantly reminds you that you'll have to lay soon!", "The sounds of eggs clacking as you walk reminds you that you will have to lay soon!") - emote_descriptor = list("an egg right out of Yonra's feathery crotch!", "into Yonra's belly firmly, forcing her to lay an egg!", ", making Yonra gasp and softly moan while an egg slides out.") - var/verb_descriptor = list("squeezes", "pushes", "hugs") - var/self_verb_descriptor = list("squeeze", "push", "hug") - var/short_emote_descriptor = list("lays", "forces out", "pushes out") - self_emote_descriptor = list("lay", "force out", "push out") - random_emote = list("hisses softly with a blush on her face", "yelps in embarrassment", "grunts a little") - assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_yonra - -/obj/item/weapon/implant/reagent_generator/yonra/post_implant(mob/living/carbon/source) - START_PROCESSING(SSobj, src) - to_chat(source, "You implant [source] with \the [src].") - source.verbs |= assigned_proc - return 1 - -/obj/item/weapon/implanter/reagent_generator/yonra - implant_type = /obj/item/weapon/implant/reagent_generator/yonra - -/mob/living/carbon/human/proc/use_reagent_implant_yonra() - set name = "Lay Egg" - set desc = "Force Yonra to lay an egg by squeezing into her lower body! This makes the Teshari stop whatever she is doing at the time, greatly embarassing her." - set category = "Object" - set src in view(1) - - //do_reagent_implant(usr) - if(!isliving(usr) || !usr.checkClickCooldown()) - return - - if(usr.incapacitated() || usr.stat > CONSCIOUS) - return - - var/obj/item/weapon/implant/reagent_generator/yonra/rimplant - for(var/obj/item/organ/external/E in organs) - for(var/obj/item/weapon/implant/I in E.implants) - if(istype(I, /obj/item/weapon/implant/reagent_generator)) - rimplant = I - break - if (rimplant) - if(rimplant.reagents.total_volume <= rimplant.transfer_amount) - to_chat(src, "[pick(rimplant.empty_message)]") - return - - new /obj/item/weapon/reagent_containers/food/snacks/egg/teshari(get_turf(src)) - - var/index = rand(0,3) - - if (usr != src) - var/emote = rimplant.emote_descriptor[index] - var/verb_desc = rimplant.verb_descriptor[index] - var/self_verb_desc = rimplant.self_verb_descriptor[index] - usr.visible_message("[usr] [verb_desc] [emote]", - "You [self_verb_desc] [emote]") - else - visible_message("[src] [pick(rimplant.short_emote_descriptor)] an egg.", - "You [pick(rimplant.self_emote_descriptor)] an egg.") - if(prob(15)) - visible_message("[src] [pick(rimplant.random_emote)].") - - rimplant.reagents.remove_any(rimplant.transfer_amount) - -/obj/item/weapon/reagent_containers/food/snacks/egg/teshari - name = "teshari egg" - desc = "It's a large teshari egg." - icon = 'icons/vore/custom_items_vr.dmi' - icon_state = "tesh_egg" - filling_color = "#FDFFD1" - volume = 12 - -/obj/item/weapon/reagent_containers/food/snacks/egg/teshari/New() - ..() - reagents.add_reagent("egg", 10) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/egg/teshari/tesh2 - icon_state = "tesh_egg_2" - -//Konabird: Rischi -/obj/item/weapon/implant/reagent_generator/rischi - name = "egg laying implant" - desc = "This is an implant that allows the user to lay eggs." - generated_reagents = list("egg" = 2) - usable_volume = 3000 //They requested 1 egg every ~30 minutes. - transfer_amount = 3000 - - empty_message = list("Your abdomen feels normal and taught, like usual.", "The lack of eggs in your abdomen leaves your belly flat and smooth.", "The reduced pressure in your belly tells you there are no more eggs.", "With a soft sigh, you can feel your body is empty of eggs. You know it will only be a matter of time before an egg forms once again, however.") - full_message = list("Your lower abdomen feels a bit swollen", "You feel a pressure within your abdomen, and a broody mood slowly creeps over you.", "You can feel the egg inside of you shift as you move, the needy feeling to lay slowly growing stronger!", "You can feel the egg inside of you, swelling out your normally taught abdomen considerably. You'll definitely need to lay soon!") - emote_descriptor = list("Rischi, causing the small female to squeak and wriggle, an egg falling from between her legs!", "Rischi's midsection, forcing her to lay an egg!", "Rischi, the Teshari huffing and grunting as an egg is squeezed from her body!") - var/verb_descriptor = list("squeezes", "squashes", "hugs") - var/self_verb_descriptor = list("squeeze", "push", "hug") - var/short_emote_descriptor = list("lays", "forces out", "pushes out") - self_emote_descriptor = list("lay", "force out", "push out") - random_emote = list("trembles and huffs, panting from the exertion.", "sees what has happened and covers her face with both hands!", "whimpers softly, her legs shivering, knees pointed inward from the feeling.") - assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_rischi - -/obj/item/weapon/implant/reagent_generator/rischi/post_implant(mob/living/carbon/source) - START_PROCESSING(SSobj, src) - to_chat(source, "You implant [source] with \the [src].") - source.verbs |= assigned_proc - return 1 - -/obj/item/weapon/implanter/reagent_generator/rischi - implant_type = /obj/item/weapon/implant/reagent_generator/rischi - -/mob/living/carbon/human/proc/use_reagent_implant_rischi() - set name = "Lay Egg" - set desc = "Force Rischi to lay an egg by squeezing her! What a terribly rude thing to do!" - set category = "Object" - set src in view(1) - - //do_reagent_implant(usr) - if(!isliving(usr) || !usr.checkClickCooldown()) - return - - if(usr.incapacitated() || usr.stat > CONSCIOUS) - return - - var/obj/item/weapon/implant/reagent_generator/rischi/rimplant - for(var/obj/item/organ/external/E in organs) - for(var/obj/item/weapon/implant/I in E.implants) - if(istype(I, /obj/item/weapon/implant/reagent_generator)) - rimplant = I - break - if (rimplant) - if(rimplant.reagents.total_volume <= rimplant.transfer_amount) - to_chat(src, "[pick(rimplant.empty_message)]") - return - - new /obj/item/weapon/reagent_containers/food/snacks/egg/teshari/tesh2(get_turf(src)) - - var/index = rand(0,3) - - if (usr != src) - var/emote = rimplant.emote_descriptor[index] - var/verb_desc = rimplant.verb_descriptor[index] - var/self_verb_desc = rimplant.self_verb_descriptor[index] - usr.visible_message("[usr] [verb_desc] [emote]", - "You [self_verb_desc] [emote]") - else - visible_message("[src] falls to her knees as the urge to lay overwhelms her, letting out a whimper as she [pick(rimplant.short_emote_descriptor)] an egg from between her legs.", - "You fall to your knees as the urge to lay overwhelms you, letting out a whimper as you [pick(rimplant.self_emote_descriptor)] an egg from between your legs.") - if(prob(15)) - visible_message("[src] [pick(rimplant.random_emote)].") - - rimplant.reagents.remove_any(rimplant.transfer_amount) - -/* -/obj/item/weapon/implant/reagent_generator/pumila_nectar //Bugged. Two implants at once messes things up. - generated_reagents = list("honey" = 2) - reagent_name = "honey" - usable_volume = 5000 - - empty_message = list("You appear to be all out of nectar", "You feel as though you are lacking a majority of your nectar.") - full_message = list("You appear to be full of nectar.", "You feel as though you are full of nectar!") - emote_descriptor = list("squeezes nectar", "extracts nectar") - self_emote_descriptor = list("squeeze", "extract") - verb_name = "Extract Honey" - verb_desc = "Obtain pumila's nectar and put it into a container!" - -/obj/item/weapon/implanter/reagent_generator/pumila_nectar - implant_type = /obj/item/weapon/implant/reagent_generator/pumila_nectar -*/ -//Egg item -//------------- -/obj/item/weapon/reagent_containers/food/snacks/egg/roiz - name = "lizard egg" - desc = "It's a large lizard egg." - icon = 'icons/vore/custom_items_vr.dmi' - icon_state = "egg_roiz" - filling_color = "#FDFFD1" - volume = 12 - -/obj/item/weapon/reagent_containers/food/snacks/egg/roiz/New() - ..() - reagents.add_reagent("egg", 9) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/egg/roiz/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype( W, /obj/item/weapon/pen/crayon )) - var/obj/item/weapon/pen/crayon/C = W - var/clr = C.colourName - - if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) - to_chat(user, "The egg refuses to take on this color!") - return - - to_chat(user, "You color \the [src] [clr]") - icon_state = "egg_roiz_[clr]" - desc = "It's a large lizard egg. It has been colored [clr]!" - if (clr == "rainbow") - var/number = rand(1,4) - icon_state = icon_state + num2text(number, 0) - else - ..() - -/obj/item/weapon/reagent_containers/food/snacks/friedegg/roiz - name = "fried lizard egg" - desc = "A large, fried lizard egg, with a touch of salt and pepper. It looks rather chewy." - icon = 'icons/vore/custom_items_vr.dmi' - icon_state = "friedegg" - volume = 12 - -/obj/item/weapon/reagent_containers/food/snacks/friedegg/roiz/New() - ..() - reagents.add_reagent("protein", 9) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/boiledegg/roiz - name = "boiled lizard egg" - desc = "A hard boiled lizard egg. Be careful, a lizard detective may hatch!" - icon = 'icons/vore/custom_items_vr.dmi' - icon_state = "egg_roiz" - volume = 12 - -/obj/item/weapon/reagent_containers/food/snacks/boiledegg/roiz/New() - ..() - reagents.add_reagent("protein", 6) - bitesize = 2 - -/obj/item/weapon/reagent_containers/food/snacks/chocolateegg/roiz - name = "chocolate lizard egg" - desc = "Such huge, sweet, fattening food. You feel gluttonous just looking at it." - icon = 'icons/vore/custom_items_vr.dmi' - icon_state = "chocolateegg_roiz" - filling_color = "#7D5F46" - nutriment_amt = 3 - nutriment_desc = list("chocolate" = 5) - volume = 18 - -/obj/item/weapon/reagent_containers/food/snacks/chocolateegg/roiz/New() - ..() - reagents.add_reagent("sugar", 6) - reagents.add_reagent("coco", 6) - reagents.add_reagent("milk", 2) - bitesize = 2 - //PontifexMinimus: Lucius/Lucia Null /obj/item/weapon/fluff/dragor_dot name = "supplemental battery" @@ -1447,80 +973,6 @@ name = "Malady's riding crop" desc = "An infernum made riding crop with Malady Blanche engraved in the shaft. It's a little worn from how many butts it has spanked." - -//SilverTalisman: Evian -/obj/item/weapon/implant/reagent_generator/evian - emote_descriptor = list("an egg right out of Evian's lower belly!", "into Evian' belly firmly, forcing him to lay an egg!", "Evian really tight, who promptly lays an egg!") - var/verb_descriptor = list("squeezes", "pushes", "hugs") - var/self_verb_descriptor = list("squeeze", "push", "hug") - var/short_emote_descriptor = list("lays", "forces out", "pushes out") - self_emote_descriptor = list("lay", "force out", "push out") - random_emote = list("hisses softly with a blush on his face", "yelps in embarrassment", "grunts a little") - assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_evian - -/obj/item/weapon/implant/reagent_generator/evian/post_implant(mob/living/carbon/source) - START_PROCESSING(SSobj, src) - to_chat(source, "You implant [source] with \the [src].") - source.verbs |= assigned_proc - return 1 - -/obj/item/weapon/implanter/reagent_generator/evian - implant_type = /obj/item/weapon/implant/reagent_generator/evian - -/mob/living/carbon/human/proc/use_reagent_implant_evian() - set name = "Lay Egg" - set desc = "Force Evian to lay an egg by squeezing into his lower body! This makes the lizard extremely embarrassed, and it looks funny." - set category = "Object" - set src in view(1) - - //do_reagent_implant(usr) - if(!isliving(usr) || !usr.checkClickCooldown()) - return - - if(usr.incapacitated() || usr.stat > CONSCIOUS) - return - - var/obj/item/weapon/implant/reagent_generator/evian/rimplant - for(var/obj/item/organ/external/E in organs) - for(var/obj/item/weapon/implant/I in E.implants) - if(istype(I, /obj/item/weapon/implant/reagent_generator)) - rimplant = I - break - if (rimplant) - if(rimplant.reagents.total_volume <= rimplant.transfer_amount) - to_chat(src, "[pick(rimplant.empty_message)]") - return - - new /obj/item/weapon/reagent_containers/food/snacks/egg/roiz/evian(get_turf(src)) //Roiz/evian so it gets all the functionality - - var/index = rand(0,3) - - if (usr != src) - var/emote = rimplant.emote_descriptor[index] - var/verb_desc = rimplant.verb_descriptor[index] - var/self_verb_desc = rimplant.self_verb_descriptor[index] - usr.visible_message("[usr] [verb_desc] [emote]", - "You [self_verb_desc] [emote]") - else - visible_message("[src] [pick(rimplant.short_emote_descriptor)] an egg.", - "You [pick(rimplant.self_emote_descriptor)] an egg.") - if(prob(15)) - visible_message("[src] [pick(rimplant.random_emote)].") // M-mlem. - - rimplant.reagents.remove_any(rimplant.transfer_amount) - -/obj/item/weapon/reagent_containers/food/snacks/egg/roiz/evian - name = "dragon egg" - desc = "A quite large dragon egg!" - icon_state = "egg_roiz_yellow" - - -/obj/item/weapon/reagent_containers/food/snacks/egg/roiz/evian/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype( W, /obj/item/weapon/pen/crayon)) //No coloring these ones! - return - else - ..() - //jacknoir413:Areax Third /obj/item/weapon/melee/baton/fluff/stunstaff name = "Electrostaff" diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm index 07d3a7831f6..ea7ec4c5cd8 100644 --- a/code/modules/vore/resizing/resize_vr.dm +++ b/code/modules/vore/resizing/resize_vr.dm @@ -243,10 +243,18 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 if(a_intent == I_HELP) // Theoretically not possible, but just in case. return FALSE + if(tmob.a_intent != I_HELP && prob(35)) + to_chat(pred, "[prey] dodges out from under your foot!") + to_chat(prey, "You narrowly avoid [pred]'s foot!") + return FALSE + now_pushing = 0 forceMove(tmob.loc) if(a_intent == I_GRAB || a_intent == I_DISARM) - tmob.resting = 1 + if(tmob.a_intent == I_HELP) + tmob.resting = 1 + else + tmob.Weaken(1) var/size_damage_multiplier = size_multiplier - tmob.size_multiplier // This technically means that I_GRAB will set this value to the same as I_HARM, but @@ -311,7 +319,7 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 message_pred = STEP_TEXT_OWNER(tail.msg_owner_disarm_walk) message_prey = STEP_TEXT_PREY(tail.msg_prey_disarm_walk) add_attack_logs(pred, prey, "Pinned underfoot (walk, about [damage] halloss)") - tmob.apply_damage(damage, HALLOSS) + tmob.Weaken(2) //Removed halloss because it was being abused if(I_HURT) message_pred = "You methodically place your foot down upon [prey]'s body, slowly applying pressure, crushing them against the floor below!" message_prey = "[pred] methodically places their foot upon your body, slowly applying pressure, crushing you against the floor below!" diff --git a/code/modules/xenoarcheaology/finds/special.dm b/code/modules/xenoarcheaology/finds/special.dm index 93bfa10966c..2a7f149dfa4 100644 --- a/code/modules/xenoarcheaology/finds/special.dm +++ b/code/modules/xenoarcheaology/finds/special.dm @@ -194,7 +194,7 @@ 'sound/hallucinations/turn_around1.ogg',\ 'sound/hallucinations/turn_around2.ogg',\ ), 50, 1, -3) - M.sleeping = max(M.sleeping,rand(5,10)) + M.Sleeping(rand(5, 10)) src.loc = null else STOP_PROCESSING(SSobj, src) diff --git a/code/modules/xenoarcheaology/manuals.dm b/code/modules/xenoarcheaology/manuals.dm index 63bcce9218b..da2a9fb0dc0 100644 --- a/code/modules/xenoarcheaology/manuals.dm +++ b/code/modules/xenoarcheaology/manuals.dm @@ -2,6 +2,7 @@ /obj/item/weapon/book/manual/excavation name = "Out on the Dig" icon_state = "excavation" + item_state = "book6" author = "Professor Patrick Mason, Curator of the Antiquities Museum on Ichar VII" title = "Out on the Dig" dat = {" @@ -115,6 +116,7 @@ /obj/item/weapon/book/manual/mass_spectrometry name = "High Power Mass Spectrometry: A Comprehensive Guide" icon_state = "analysis" + item_state = "book6" author = "Winton Rice, Chief Mass Spectrometry Technician at the Institute of Applied Sciences on Arcadia" title = "High powered mass spectrometry, a comprehensive guide" dat = {" @@ -186,6 +188,7 @@ /obj/item/weapon/book/manual/anomaly_spectroscopy name = "Spectroscopy: Analysing the Anomalies of the Cosmos" icon_state = "anomaly" + item_state = "book6" author = "Doctor Martin Boyle, Director Research at the Lower Hydrolian Sector Listening Array" title = "Spectroscopy: Analysing the Anomalies of the Cosmos" dat = {" @@ -211,6 +214,7 @@ /obj/item/weapon/book/manual/materials_chemistry_analysis name = "Materials Analysis and the Chemical Implications" icon_state = "chemistry" + item_state = "book6" author = "Jasper Pascal, Senior Lecturer in Materials Analysis at the University of Jol'Nar" title = "Materials Analysis and the Chemical Implications" dat = {" @@ -238,6 +242,7 @@ /obj/item/weapon/book/manual/anomaly_testing name = "Anomalous Materials and Energies" icon_state = "triangulate" + item_state = "book6" author = "Norman York, formerly of the Tyrolion Institute on Titan" title = "Anomalous Materials and Energies" dat = {" @@ -316,6 +321,7 @@ /obj/item/weapon/book/manual/stasis name = "Cellular Suspension, the New Cryogenics?" icon_state = "stasis" + item_state = "book6" author = "Elvin Schmidt" title = "Cellular Suspension, the New Cryogenics?" dat = {" diff --git a/code/modules/xenoarcheaology/misc.dm b/code/modules/xenoarcheaology/misc.dm index f6005c3f172..3ef15cbc3c5 100644 --- a/code/modules/xenoarcheaology/misc.dm +++ b/code/modules/xenoarcheaology/misc.dm @@ -1,43 +1,3 @@ -/obj/structure/noticeboard/anomaly - notices = 5 - icon_state = "nboard05" - -/obj/structure/noticeboard/anomaly/New() - var/obj/item/weapon/paper/P = new() - P.name = "Memo RE: proper analysis procedure" - P.info = "
We keep test dummies in pens here for a reason, so standard procedure should be to activate newfound alien artifacts and place the two in close proximity. Promising items I might even approve monkey testing on." - P.stamped = list(/obj/item/weapon/stamp/rd) - P.overlays = list("paper_stamped_rd") - src.contents += P - - P = new() - P.name = "Memo RE: materials gathering" - P.info = "Corasang,
the hands-on approach to gathering our samples may very well be slow at times, but it's safer than allowing the blundering miners to roll willy-nilly over our dig sites in their mechs, destroying everything in the process. And don't forget the escavation tools on your way out there!
- R.W" - P.stamped = list(/obj/item/weapon/stamp/rd) - P.overlays = list("paper_stamped_rd") - src.contents += P - - P = new() - P.name = "Memo RE: ethical quandaries" - P.info = "Darion-

I don't care what his rank is, our business is that of science and knowledge - questions of moral application do not come into this. Sure, so there are those who would employ the energy-wave particles my modified device has managed to abscond for their own personal gain, but I can hardly see the practical benefits of some of these artifacts our benefactors left behind. Ward--" - P.stamped = list(/obj/item/weapon/stamp/rd) - P.overlays = list("paper_stamped_rd") - src.contents += P - - P = new() - P.name = "READ ME! Before you people destroy any more samples" - P.info = "how many times do i have to tell you people, these xeno-arch samples are del-i-cate, and should be handled so! careful application of a focussed, concentrated heat or some corrosive liquids should clear away the extraneous carbon matter, while application of an energy beam will most decidedly destroy it entirely - like someone did to the chemical dispenser! W, the one who signs your paychecks" - P.stamped = list(/obj/item/weapon/stamp/rd) - P.overlays = list("paper_stamped_rd") - src.contents += P - - P = new() - P.name = "Reminder regarding the anomalous material suits" - P.info = "Do you people think the anomaly suits are cheap to come by? I'm about a hair trigger away from instituting a log book for the damn things. Only wear them if you're going out for a dig, and for god's sake don't go tramping around in them unless you're field testing something, R" - P.stamped = list(/obj/item/weapon/stamp/rd) - P.overlays = list("paper_stamped_rd") - src.contents += P - /obj/structure/bookcase/manuals/xenoarchaeology name = "Xenoarchaeology Manuals bookcase" diff --git a/code/modules/xenoarcheaology/tools/suspension_generator.dm b/code/modules/xenoarcheaology/tools/suspension_generator.dm index f4a60f1bfd1..561ac1028fd 100644 --- a/code/modules/xenoarcheaology/tools/suspension_generator.dm +++ b/code/modules/xenoarcheaology/tools/suspension_generator.dm @@ -21,7 +21,7 @@ var/turf/T = get_turf(suspension_field) for(var/mob/living/M in T) - M.weakened = max(M.weakened, 3) + M.Weaken(3) cell.charge -= power_use if(prob(5)) to_chat(M, "[pick("You feel tingly","You feel like floating","It is hard to speak","You can barely move")].") @@ -208,7 +208,7 @@ for(var/mob/living/M in T) to_chat(M, "You no longer feel like floating.") - M.weakened = min(M.weakened, 3) + M.Weaken(3) src.visible_message("[bicon(src)] [src] deactivates with a gentle shudder.") qdel(suspension_field) diff --git a/code/modules/xenobio/items/extracts.dm b/code/modules/xenobio/items/extracts.dm index 6368f68e15c..159bb0f1516 100644 --- a/code/modules/xenobio/items/extracts.dm +++ b/code/modules/xenobio/items/extracts.dm @@ -616,7 +616,7 @@ /obj/item/slime_extract/pink name = "pink slime extract" icon_state = "pink slime extract" - description_info = "This extract will create 20u of blood clotting agent if injected with blood. It can also create 20u of bone binding agent if injected \ + description_info = "This extract will create 30u of blood clotting agent if injected with blood. It can also create 30u of bone binding agent if injected \ with phoron. When injected with water, it will create an organ-mending agent. The slime medications have a very low threshold for overdosage, however." diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm index c6b21e5d36b..0c74449d2d3 100644 --- a/code/unit_tests/mob_tests.dm +++ b/code/unit_tests/mob_tests.dm @@ -27,3 +27,120 @@ qdel(H) return 1 + + +/datum/modifier/unit_test + +/datum/unit_test/modifier + name = "modifier test template" + var/mob/living/subject = null + var/subject_type = /mob/living/carbon/human + var/list/inputs = list(1.00, 0.75, 0.50, 0.25, 0.00, -0.50, -1.0, -2.0) + var/list/expected_outputs = list(1.00, 0.75, 0.50, 0.25, 0.00, -0.50, -1.0, -2.0) + var/datum/modifier/test_modifier = null + var/issues = 0 + +/datum/unit_test/modifier/start_test() + // Arrange. + subject = new subject_type(get_standard_turf()) + subject.add_modifier(/datum/modifier/unit_test) + test_modifier = subject.get_modifier_of_type(/datum/modifier/unit_test) + + // Act, + for(var/i = 1 to inputs.len) + set_tested_variable(test_modifier, inputs[i]) + var/actual = round(get_test_value(subject), 0.01) // Rounding because floating point schannigans. + if(actual != expected_outputs[i]) + issues++ + log_bad("Input '[inputs[i]]' did not match expected output '[expected_outputs[i]]', but was instead '[actual]'.") + + // Assert. + if(issues) + fail("[issues] issues were found.") + else + pass("No issues found.") + qdel(subject) + return TRUE + +// Override for subtypes. +/datum/unit_test/modifier/proc/set_tested_variable(datum/modifier/M, new_value) + return + +/datum/unit_test/modifier/proc/get_test_value(mob/living/L) + return + + +/datum/unit_test/modifier/heat_protection + name = "MOB: human mob heat protection is calculated correctly" + +/datum/unit_test/modifier/heat_protection/set_tested_variable(datum/modifier/M, new_value) + M.heat_protection = new_value + +/datum/unit_test/modifier/heat_protection/get_test_value(mob/living/L) + return L.get_heat_protection(1000) + +/datum/unit_test/modifier/heat_protection/simple_mob + name = "MOB: simple mob heat protection is calculated correctly" + subject_type = /mob/living/simple_mob + + +/datum/unit_test/modifier/cold_protection + name = "MOB: human mob cold protection is calculated correctly" + +/datum/unit_test/modifier/cold_protection/set_tested_variable(datum/modifier/M, new_value) + M.cold_protection = new_value + +/datum/unit_test/modifier/cold_protection/get_test_value(mob/living/L) + return L.get_cold_protection(50) + +/datum/unit_test/modifier/cold_protection/simple_mob + name = "MOB: simple mob cold protection is calculated correctly" + subject_type = /mob/living/simple_mob + + +/datum/unit_test/modifier/shock_protection + name = "MOB: human mob shock protection is calculated correctly" + inputs = list(3.00, 2.00, 1.50, 1.00, 0.75, 0.50, 0.25, 0.00) + expected_outputs = list(-2.00, -1.00, -0.50, 0.00, 0.25, 0.50, 0.75, 1.00) + +/datum/unit_test/modifier/shock_protection/set_tested_variable(datum/modifier/M, new_value) + M.siemens_coefficient = new_value + +/datum/unit_test/modifier/shock_protection/get_test_value(mob/living/L) + return L.get_shock_protection() + +/datum/unit_test/modifier/shock_protection/simple_mob + name = "MOB: simple mob shock protection is calculated correctly" + subject_type = /mob/living/simple_mob + + +/datum/unit_test/modifier/percentage_armor + name = "MOB: human mob percentage armor is calculated correctly" + inputs = list(100, 75, 50, 25, 0) + expected_outputs = list(100, 75, 50, 25, 0) + +/datum/unit_test/modifier/percentage_armor/set_tested_variable(datum/modifier/M, new_value) + M.armor_percent = list("melee" = new_value) + +/datum/unit_test/modifier/percentage_armor/get_test_value(mob/living/L) + return L.getarmor(null, "melee") + +/datum/unit_test/modifier/percentage_armor/simple_mob + name = "MOB: simple mob percentage armor is calculated correctly" + subject_type = /mob/living/simple_mob + + +/datum/unit_test/modifier/percentage_flat + name = "MOB: human mob flat armor is calculated correctly" + inputs = list(100, 75, 50, 25, 0) + expected_outputs = list(100, 75, 50, 25, 0) + +/datum/unit_test/modifier/percentage_flat/set_tested_variable(datum/modifier/M, new_value) + M.armor_flat = list("melee" = new_value) + +/datum/unit_test/modifier/percentage_flat/get_test_value(mob/living/L) + return L.getsoak(null, "melee") + +/datum/unit_test/modifier/percentage_flat/simple_mob + name = "MOB: simple mob flat armor is calculated correctly" + subject_type = /mob/living/simple_mob diff --git a/config/alienwhitelist.txt b/config/alienwhitelist.txt index 49e93a20dd0..c87dcf2bd4b 100644 --- a/config/alienwhitelist.txt +++ b/config/alienwhitelist.txt @@ -8,23 +8,34 @@ aruis - Diona aruis - Xenochimera amarewolf - Xenochimera azmodan412 - Xenochimera +alphaprime1 - Protean bothnevarbackwards - Diona +bricker98 - Protean crossexonar - Protean chillyfang - Black-Eyed Shadekin +cgr - Protean +draycu - Vox flaktual - Vox funnyman2003 - Xenochimera +flurriee - Protean hawkerthegreat - Vox hollifex - Diona inuzari - Diona jademanique - Xenochimera jemli - Gutter ktccd - Diona +khanivore - Protean +lunarfleet - Gutter mewchild - Diona mewchild - Vox mrsebbi - Xenochimera natje - Xenochimera +nerdass - Protean +ontejbjoav - Diona oreganovulgaris - Xenochimera paradoxspace - Xenochimera +pearlprophet - Protean +phoenixx0 - Vox rapidvalj - Vox rapidvalj - Common Skrellian rapidvalj - High Skrellian @@ -32,30 +43,28 @@ rikaru19xjenkins - Xenochimera rixunie - Diona rixunie - Gutter rykkastormheart - Xenochimera +rubyflamewing - Protean +radiantaurora - Protean +ryumi - Protean seiga - Vox sepulchre - Vox silvertalismen - Diona silvertalismen - Vox silvertalismen - Xenochimera singo - Gutter +storesund97 - Protean +sharplight - Protean tastypred - Black-Eyed Shadekin tastypred - Xenochimera +tastypred - Protean timidvi - Diona varonis - Xenochimera verkister - Xenochimera +vitoras - Protean +voidalynx - Protean wickedtemp - Shadekin Empathy xioen - Diona xioen - Xenochimera +xonkon - Protean zalvine - Shadekin Empathy zammyman215 - Vox -bricker98 - Protean -cgr - Protean -storesund97 - Protean -tastypred - Protean -vitoras - Protean -voidalynx - Protean -nerdass - Protean -xonkon - Protean -phoenixx0 - Vox -rubyflamewing - Protean -radiantaurora - Protean diff --git a/config/custom_sprites.txt b/config/custom_sprites.txt index db3930a4ae2..b99307d173f 100644 --- a/config/custom_sprites.txt +++ b/config/custom_sprites.txt @@ -1 +1,3 @@ -ckey-state \ No newline at end of file +ckey|state +lunarfleet|Clea-Nor +jademanique|B.A.U-Kingside \ No newline at end of file diff --git a/config/example/config.txt b/config/example/config.txt index eaff2461945..50ee910f8d2 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -545,4 +545,4 @@ ENABLE_NIGHT_SHIFTS # Uncomment to allow links of the following kinds. # # ALLOW_BYOND_LINKS # ALLOW_DISCORD_LINKS -ALLOW_URL_LINKS +ALLOW_URL_LINKS \ No newline at end of file diff --git a/guides/Guide to Dream Maker.md b/guides/Guide to Dream Maker.md new file mode 100644 index 00000000000..fbac2b7ef27 --- /dev/null +++ b/guides/Guide to Dream Maker.md @@ -0,0 +1,46 @@ +Guide to the Dream Maker +To begin: We’ll need to open Dream Maker, of course. Locate the dreammaker.exe in your BYOND/bin file and run that (or launch it from Start, however you prefer.) + +You’ll be greeted with this: +https://i.imgur.com/aJXB9sN.png + +We’re going to go to File, Open Environment, like so: +https://i.imgur.com/F8K8Nmz.png + +You’ll then locate your VOREStation folder, and the .dme inside. Shown is mine: +https://i.imgur.com/tvTDBWp.png + +Choose “Open†+You will be greeted with: +https://i.imgur.com/oAbOjwR.png + +If you’d prefer to skip right to codestuff/the wiki, this is a good start. Otherwise, continue below: +https://wiki.vore-station.net/Basics_of_Coding_in_BYOND + +MAPPERS: +If you are looking to MAP, the first thing we need to do is go to the top of the screen, choose “Buildâ€, and Compile. + +Tether is located in /maps/tether/, and each level of the station is Tether 01-07. 08 is the Mining Outpost and 09 is Toxins/Xenoarch and Solars. +Submaps are in the /submaps/ folder, and, for instance, if you are looking to add new submaps to the Underdark, you’ll expand underdark_pois and create a new .dmm in the folder by clicking on it, and then going to New. Example here: +https://i.imgur.com/Q1Cqfll.png + +If you are adding a submap, ensure you add it to _templates.dm, a small snippet is here: +https://i.imgur.com/Ek9jaCe.png + +Cost is how much the POI system has to spend to spawn that .dmm, and name/mappath are self-explanatory. + +If you have questions, ask in Discord in #dev-general! <3 + +SPRITERS: +If you are looking to edit icons, skip that, and just go to “icons†(expand it by hitting the +), and then find the icon file you’re looking for. Most people go to adding new drinks + foods for their first foray into DM, so: +If you want to add a new drink, VOREStation-specific drinks are in icons/obj/drinks_vr.dmi, and VOREStation-specific food is icons/obj/food_vr.dmi. + +If you have questions, ask in Discord in #dev-general! <3 + +CODERS: +Refer to the pins in #dev-general for Visual Studio Code, but you can still code in Dream Maker (Although it’s not a very good interface for it, and it’s WHY Visual Studio Code is recommended). + +Coding is fairly self-explanatory, find the things you want to change and change it. There’s no robust tutorial to coding, but we have a coding tutorial of sorts and explanation on our wiki: +https://wiki.vore-station.net/Basics_of_Coding_in_BYOND + +As with spriters/mappers, if you have questions, ask in Discord in #dev-general! <3 \ No newline at end of file diff --git a/guides/Guide to Opening Your First PR.md b/guides/Guide to Opening Your First PR.md new file mode 100644 index 00000000000..4449bc684eb --- /dev/null +++ b/guides/Guide to Opening Your First PR.md @@ -0,0 +1,91 @@ +Guide to Opening Your First PR +This guide is intended for newbie developers who have never touched BYOND .dm code, Github, or other things. If you already know github, you can safely skip a good portion of the below information. + +Beginning: +In order to go anywhere, we’re going to need our own Repository (the thing you get the code from) to make changes to. Luckily, this is a one-button-job. Go to https://github.com/VOREStation/VOREStation and click Fork, as shown here: +https://i.imgur.com/tIbXmGN.png + +In the top left, you will see: +https://i.imgur.com/sieji75.png + +(Replace Rykka-Stormheart with your own username, ofc.) If you see this, and the “this repository is forked from VOREStation), you are part of the way there! + +Git Clients +Everyone has their own preferred Github clients - I use Gitkraken because it’s exceedingly easy to use for newbies, and it’s a very visually-focused client. There are others, of course, links here: +**Gitkraken:** https://www.gitkraken.com/ +**SourceTree:** https://www.sourcetreeapp.com/ +**Github Desktop:** https://desktop.github.com/ + +I recommend Gitkraken as it’s very good at handling things for you, and it comes with built-in darkmode. It DOES have paid features, but you don’t need them. + +Cloning your Repo: AKA “Progress bar time†+I’ll give these instructions in relevance to Gitkraken as that’s what I use, but they should be relatively applicable to other platforms. + +You’re going to open Gitkraken and be met with this: +https://i.imgur.com/oXYqeZy.png + +Choose “Clone a Repoâ€, and then choose Github.com. You can then choose where you want your repo installed (I usually do a master folder, Devwork, and then each repo is cloned inside: Devwork/VOREStation, Devwork/Polaris) +https://i.imgur.com/y15Qir2.png +https://i.imgur.com/bsw8p18.png + + + +Opening your Repo for the first time: +Once your repo is cloned, you’ll be greeted with a screen SIMILAR to this (Note that mine has a lot of branches and repos): +https://i.imgur.com/Ei6QZOh.png + +On the top left is your **local/remote**, those are the two important things we want to focus on. +Local is stuff that’s locally on YOUR PC, and remote is the fork that you made (and the other things we add). + +Before we go further, we’ll want to add VOREStation as a remote so we can keep you up to date. Don’t worry, it’s easy. +Follow the picture instructions: +https://i.imgur.com/0aBRaoq.png +https://i.imgur.com/OaNNWjK.png +https://i.imgur.com/U7Maetj.png + +And you should see: +https://i.imgur.com/Vlwn8R9.png + +If you see the VOREStation_Master ahead of your master, **don’t panic.** Right click on ‘master’ and choose “fast-forwardâ€. You’ll see the local computer icon jump to meet Master, and then you go to the top and hit “Push†- Push sends your changes up to your repo/remote. + +Creating Your Branch: +Now that that’s done, we’re going to create our branch. +Go to master, right click, and choose “create branch hereâ€. +https://i.imgur.com/Qqld0WI.png + +You’ll see this popup in the bottom left (It goes away quickly, so don’t worry if you miss it) +https://i.imgur.com/uFR2qjP.png + +Next, hit “pushâ€. You’ll see a thing pop up at the top asking where to push/pull from. Just leave it at origin, and your branch name. +https://i.imgur.com/f3Gnw1Z.png + +You’ll see this afterwards: +https://i.imgur.com/E36fYga.png + +Making Changes + PR’ing: +Now, we’ve got our branch made, and it’s on both our repo and local PC. We’re all set to make changes. Now, do whatever changes you like to the files, and then you’ll come back to Gitkraken and see: +https://i.imgur.com/kMB7bKs.png + +What this is is your changes, unstaged. You’ll need to stage them, and then type a message in to commit. The first part of the commit is the “Headerâ€, the name that appears in the main branch/tree, and the text underneath is a description. +An example of commit title is here: https://i.imgur.com/dCiXsZX.png +Once that’s done, hit “Commit changes to x filesâ€, and you’ll see the above image! + +Now, hit “pushâ€, to send the changes up to your repo’s branch. + +Then, right click on your branch under “Localâ€, and choose “Start a pull request to x from xâ€: +https://i.imgur.com/lroAj8X.png + +You’ll see this pop out: +https://i.imgur.com/21D6qt9.png + +If the TO repo doesn’t autofill, don’t panic. Just choose VOREStation/VOREStation, branch master. + +Then type the NAME of your PR, and a description underneath, then hit “Create Pull Requestâ€! + +And that’s it! + +**You’ve now successfully made your first PR!** + +Any further issues or changes, maintainers will assist you with! If you have any questions or run into any snags during this tutorial, feel free to @ a maintainer (The blue names on the sidebar) in #dev-general or just ask for help and someone should be with you momentarily! + +**Good luck, and thank you for contributing to VORE. Your efforts are what keeps us all going! <3** diff --git a/guides/New Mapper Mapmerge Readme.md b/guides/New Mapper Mapmerge Readme.md new file mode 100644 index 00000000000..1903be81556 --- /dev/null +++ b/guides/New Mapper Mapmerge Readme.md @@ -0,0 +1,7 @@ +If you're making a PR to Github, or are a new mapper and have been told to "mapmerge": + +Run dmm2tgm.bat, find the map you edited, and type it in. For instance, as of this date/writing, Tether Surface 2 is 163. + +If Tether Surface 2 is still 163, type in 163 and hit enter, it will run mapmerge. This reduces the filediff for easier Git merging. + +NOTE that this is not "merging" two maps together. ALL YOU ARE DOING IS REDUCING FILEDIFF. IF YOU NEED TO MAPMERGE PROPERLY, @ A DEVELOPER OR SOMEONE WITH MAPPING EXPERIENCE. \ No newline at end of file diff --git a/html/changelog.html b/html/changelog.html index e3ea40755bf..39c9522a1d7 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,52 @@ -->
+

06 August 2020

+

Cerebulon updated:

+
    +
  • Added new mobs Fire Bugs, Ice Hares, Tymisian Moths and Siffets to surface spawnlists. Also added a new dog breed, woof.
  • +
+

ForFoxSake updated:

+
    +
  • Ported tgstation styled magazine restocking. Hit a bullet on a table or floor with a partially empty magazine to start restocking.
  • +
+

Mechoid updated:

+
    +
  • Exosuits now have internal components, mostly like borgs, but larger.
  • +
  • Autolathes can use plastic and plasteel.
  • +
  • Autolathes can have tiered recipes, based on their manipulator rating.
  • +
  • Exosuit base health has been lowered due to the changes to damage processing.
  • +
+

Rykka Stormheart updated:

+
    +
  • Blast Doors will now crush people, if they are on the same turf when it closes, and throw them to an adjacent open turf.
  • +
  • The damage should be delayed enough that you can walk out of the door before the sprite animation finishes and you will be safe. The delay is being reviewed, and will likely be adjusted after sufficient feedback is gathered.
  • +
  • Blast doors and shutters (the types that go on bar/kitchen/etc) will also throw items on their tiles.
  • +
+ +

03 August 2020

+

Cerebulon updated:

+
    +
  • Added new book sprites, replaced old book sprites.
  • +
  • Added sticky notes, orderable from cargo
  • +
  • You can now carve graffiti into suitable walls/floors with sharp objects.
  • +
  • Trash, graffiti, dirt (Not blood), noticeboards and stickynotes are now persistent across rounds. This is admin-toggleable.
  • +
+

Mechoid updated:

+
    +
  • Adds a glass jar subtype, the glass tank, that can be used to hold live fish. Remember to add water!
  • +
+

Rykka Stormheart updated:

+
    +
  • Ported over Aurora Cooking from AuroraStation and Citadel-RP!
  • +
  • Recipes are separate per appliance, and all appliances have a use!
  • +
  • Please take note, Chefs, to pre-heat you appliances at the start of your shift.
  • +
  • Fryer Recipes require batter before they can be made!
  • +
  • Fire alarms will go off if you burn food!
  • +
  • The largest change - Cooking takes TIME. Around 6 minutes for the largest recipes in the game.
  • +
  • Too many other changes to list - refer to PR #7344 https://github.com/PolarisSS13/Polaris/pull/7344
  • +
+

21 June 2020

Arokha updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 796fa0aa3be..0ca89eb0666 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -5200,3 +5200,43 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - tweak: Ports color_square() from Paradise for colour previews, cleaning up pref. code & correct alignment issue w/ nested tables. - tweak: Markings are now properly aligned within a table. +2020-08-03: + Cerebulon: + - imageadd: Added new book sprites, replaced old book sprites. + - rscadd: Added sticky notes, orderable from cargo + - rscadd: You can now carve graffiti into suitable walls/floors with sharp objects. + - rscadd: Trash, graffiti, dirt (Not blood), noticeboards and stickynotes are now + persistent across rounds. This is admin-toggleable. + Mechoid: + - rscadd: Adds a glass jar subtype, the glass tank, that can be used to hold live + fish. Remember to add water! + Rykka Stormheart: + - rscadd: Ported over Aurora Cooking from AuroraStation and Citadel-RP! + - rscadd: Recipes are separate per appliance, and all appliances have a use! + - rscadd: Please take note, Chefs, to pre-heat you appliances at the start of your + shift. + - rscadd: Fryer Recipes require batter before they can be made! + - rscadd: Fire alarms will go off if you burn food! + - rscadd: The largest change - Cooking takes TIME. Around 6 minutes for the largest + recipes in the game. + - rscadd: 'Too many other changes to list - refer to PR #7344 https://github.com/PolarisSS13/Polaris/pull/7344' +2020-08-06: + Cerebulon: + - rscadd: Added new mobs Fire Bugs, Ice Hares, Tymisian Moths and Siffets to surface + spawnlists. Also added a new dog breed, woof. + ForFoxSake: + - rscadd: Ported tgstation styled magazine restocking. Hit a bullet on a table or + floor with a partially empty magazine to start restocking. + Mechoid: + - rscadd: Exosuits now have internal components, mostly like borgs, but larger. + - rscadd: Autolathes can use plastic and plasteel. + - rscadd: Autolathes can have tiered recipes, based on their manipulator rating. + - tweak: Exosuit base health has been lowered due to the changes to damage processing. + Rykka Stormheart: + - rscadd: Blast Doors will now crush people, if they are on the same turf when it + closes, and throw them to an adjacent open turf. + - rscadd: The damage should be delayed enough that you can walk out of the door + before the sprite animation finishes and you will be safe. The delay is being + reviewed, and will likely be adjusted after sufficient feedback is gathered. + - rscadd: Blast doors and shutters (the types that go on bar/kitchen/etc) will also + throw items on their tiles. diff --git a/html/changelogs/billybangles-chessboard.yml b/html/changelogs/BlinsKot - strafing.yml similarity index 52% rename from html/changelogs/billybangles-chessboard.yml rename to html/changelogs/BlinsKot - strafing.yml index f51e69fc67e..f99f20e104e 100644 --- a/html/changelogs/billybangles-chessboard.yml +++ b/html/changelogs/BlinsKot - strafing.yml @@ -20,8 +20,17 @@ # spellcheck (typo fixes) # experiment ################################# - -author: Billy Bangles + +# Your name. +author: Blinskot + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. delete-after: True - - rscadd: "Adds a chessboard holodeck program and a set of chess pieces" - - imageadd: "Adds a set of small floor decals numbered 1 to 8 and letters A to H" + +# 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: + - rscadd: "You can now alt click to toggle strafing in mechs." diff --git a/html/changelogs/Kot-Washing.yml b/html/changelogs/Kot-Washing.yml new file mode 100644 index 00000000000..0da4b507c5d --- /dev/null +++ b/html/changelogs/Kot-Washing.yml @@ -0,0 +1,36 @@ +################################ +# 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: BlinsKot + +# 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: + - rscadd: "You pansies can now alt click to turn on the washing machine." \ No newline at end of file diff --git a/html/changelogs/SubberTheFabulous-PR-7467.yml b/html/changelogs/SubberTheFabulous-PR-7467.yml new file mode 100644 index 00000000000..a5adf1f8872 --- /dev/null +++ b/html/changelogs/SubberTheFabulous-PR-7467.yml @@ -0,0 +1,36 @@ +################################ +# 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: Subber + +# 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: + - rscadd: "Added a new prosthetic sprite set: Cyber Solutions - Outdated." diff --git a/html/changelogs/mechoid - mortiferin.yml b/html/changelogs/mechoid - mortiferin.yml new file mode 100644 index 00000000000..00ce2ca033a --- /dev/null +++ b/html/changelogs/mechoid - mortiferin.yml @@ -0,0 +1,37 @@ +################################ +# 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: Mechoid + +# 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: + - rscadd: "Mortiferin added in place of old Necroxadone as a normal chem recipe." + - tweak: "Necroxadone changed to a more powerful alternative to Mortiferin which works even on corpses without bloodflow." diff --git a/html/font-awesome/README.MD b/html/font-awesome/README.MD new file mode 100644 index 00000000000..7d693c36f03 --- /dev/null +++ b/html/font-awesome/README.MD @@ -0,0 +1,6 @@ +Due to the fact browse_rsc can't create subdirectories, every time you update font-awesome you'll need to change relative webfont references in all.min.css +eg ../webfonts/fa-regular-400.ttf => fa-regular-400.ttf (or whatever you call it in asset datum) + +Second change is ripping out file types other than woff and eot(ie8) from the css + +Finally, removing brand related css. \ No newline at end of file diff --git a/html/font-awesome/css/all.min.css b/html/font-awesome/css/all.min.css new file mode 100644 index 00000000000..a5e67e693dd --- /dev/null +++ b/html/font-awesome/css/all.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-bacteria:before{content:"\e059"}.fa-bacterium:before{content:"\e05a"}.fa-bahai:before{content:"\f666"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-box-tissue:before{content:"\e05b"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caravan:before{content:"\f8ff"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-alt:before{content:"\f422"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-cotton-bureau:before{content:"\f89e"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-disease:before{content:"\f7fa"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-alt:before{content:"\f424"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-faucet:before{content:"\e005"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-medical:before{content:"\e05c"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-holding-water:before{content:"\f4c1"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-sparkles:before{content:"\e05d"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-hands-wash:before{content:"\e05e"}.fa-handshake:before{content:"\f2b5"}.fa-handshake-alt-slash:before{content:"\e05f"}.fa-handshake-slash:before{content:"\e060"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-cowboy:before{content:"\f8c0"}.fa-hat-cowboy-side:before{content:"\f8c1"}.fa-hat-wizard:before{content:"\f6e8"}.fa-hdd:before{content:"\f0a0"}.fa-head-side-cough:before{content:"\e061"}.fa-head-side-cough-slash:before{content:"\e062"}.fa-head-side-mask:before{content:"\e063"}.fa-head-side-virus:before{content:"\e064"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hospital-user:before{content:"\f80d"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-house-user:before{content:"\e065"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-ideal:before{content:"\e013"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-house:before{content:"\e066"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lungs:before{content:"\f604"}.fa-lungs-virus:before{content:"\e067"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microblog:before{content:"\e01a"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse:before{content:"\f8cc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-arrows:before{content:"\e068"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-plane-slash:before{content:"\e069"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pump-medical:before{content:"\e06a"}.fa-pump-soap:before{content:"\e06b"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-record-vinyl:before{content:"\f8d9"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-rust:before{content:"\e07a"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-shield-virus:before{content:"\e06c"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopify:before{content:"\e057"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sink:before{content:"\e06d"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-soap:before{content:"\e06e"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-stopwatch-20:before{content:"\e06f"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-store-alt-slash:before{content:"\e070"}.fa-store-slash:before{content:"\e071"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swift:before{content:"\f8e1"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-tiktok:before{content:"\e07b"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toilet-paper-slash:before{content:"\e072"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-trailer:before{content:"\e041"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-users-slash:before{content:"\e073"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-virus:before{content:"\e074"}.fa-virus-slash:before{content:"\e075"}.fa-viruses:before{content:"\e076"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:auto;src:url(fa-regular-400.eot);src:url(fa-regular-400.eot?#iefix) format("embedded-opentype"),url(fa-regular-400.woff) format("woff")}.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(fa-solid-900.eot);src:url(fa-solid-900.eot?#iefix) format("embedded-opentype"),url(fa-solid-900.woff) format("woff")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/html/font-awesome/css/v4-shims.min.css b/html/font-awesome/css/v4-shims.min.css new file mode 100644 index 00000000000..ee29a2c92db --- /dev/null +++ b/html/font-awesome/css/v4-shims.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa.fa-glass:before{content:"\f000"}.fa.fa-meetup{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-star-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-o:before{content:"\f005"}.fa.fa-close:before,.fa.fa-remove:before{content:"\f00d"}.fa.fa-gear:before{content:"\f013"}.fa.fa-trash-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-trash-o:before{content:"\f2ed"}.fa.fa-file-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-o:before{content:"\f15b"}.fa.fa-clock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-clock-o:before{content:"\f017"}.fa.fa-arrow-circle-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-down:before{content:"\f358"}.fa.fa-arrow-circle-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-up:before{content:"\f35b"}.fa.fa-play-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-play-circle-o:before{content:"\f144"}.fa.fa-repeat:before,.fa.fa-rotate-right:before{content:"\f01e"}.fa.fa-refresh:before{content:"\f021"}.fa.fa-list-alt{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-dedent:before{content:"\f03b"}.fa.fa-video-camera:before{content:"\f03d"}.fa.fa-picture-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-picture-o:before{content:"\f03e"}.fa.fa-photo{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-photo:before{content:"\f03e"}.fa.fa-image{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-image:before{content:"\f03e"}.fa.fa-pencil:before{content:"\f303"}.fa.fa-map-marker:before{content:"\f3c5"}.fa.fa-pencil-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-pencil-square-o:before{content:"\f044"}.fa.fa-share-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-share-square-o:before{content:"\f14d"}.fa.fa-check-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-check-square-o:before{content:"\f14a"}.fa.fa-arrows:before{content:"\f0b2"}.fa.fa-times-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-circle-o:before{content:"\f057"}.fa.fa-check-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-check-circle-o:before{content:"\f058"}.fa.fa-mail-forward:before{content:"\f064"}.fa.fa-expand:before{content:"\f424"}.fa.fa-compress:before{content:"\f422"}.fa.fa-eye,.fa.fa-eye-slash{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-warning:before{content:"\f071"}.fa.fa-calendar:before{content:"\f073"}.fa.fa-arrows-v:before{content:"\f338"}.fa.fa-arrows-h:before{content:"\f337"}.fa.fa-bar-chart{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bar-chart:before{content:"\f080"}.fa.fa-bar-chart-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bar-chart-o:before{content:"\f080"}.fa.fa-facebook-square,.fa.fa-twitter-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-gears:before{content:"\f085"}.fa.fa-thumbs-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-thumbs-o-up:before{content:"\f164"}.fa.fa-thumbs-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-thumbs-o-down:before{content:"\f165"}.fa.fa-heart-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-heart-o:before{content:"\f004"}.fa.fa-sign-out:before{content:"\f2f5"}.fa.fa-linkedin-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-linkedin-square:before{content:"\f08c"}.fa.fa-thumb-tack:before{content:"\f08d"}.fa.fa-external-link:before{content:"\f35d"}.fa.fa-sign-in:before{content:"\f2f6"}.fa.fa-github-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-lemon-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-lemon-o:before{content:"\f094"}.fa.fa-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-square-o:before{content:"\f0c8"}.fa.fa-bookmark-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bookmark-o:before{content:"\f02e"}.fa.fa-facebook,.fa.fa-twitter{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook:before{content:"\f39e"}.fa.fa-facebook-f{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook-f:before{content:"\f39e"}.fa.fa-github{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-credit-card{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-feed:before{content:"\f09e"}.fa.fa-hdd-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hdd-o:before{content:"\f0a0"}.fa.fa-hand-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-right:before{content:"\f0a4"}.fa.fa-hand-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-left:before{content:"\f0a5"}.fa.fa-hand-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-up:before{content:"\f0a6"}.fa.fa-hand-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-o-down:before{content:"\f0a7"}.fa.fa-arrows-alt:before{content:"\f31e"}.fa.fa-group:before{content:"\f0c0"}.fa.fa-chain:before{content:"\f0c1"}.fa.fa-scissors:before{content:"\f0c4"}.fa.fa-files-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-files-o:before{content:"\f0c5"}.fa.fa-floppy-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-floppy-o:before{content:"\f0c7"}.fa.fa-navicon:before,.fa.fa-reorder:before{content:"\f0c9"}.fa.fa-google-plus,.fa.fa-google-plus-square,.fa.fa-pinterest,.fa.fa-pinterest-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus:before{content:"\f0d5"}.fa.fa-money{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-money:before{content:"\f3d1"}.fa.fa-unsorted:before{content:"\f0dc"}.fa.fa-sort-desc:before{content:"\f0dd"}.fa.fa-sort-asc:before{content:"\f0de"}.fa.fa-linkedin{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-linkedin:before{content:"\f0e1"}.fa.fa-rotate-left:before{content:"\f0e2"}.fa.fa-legal:before{content:"\f0e3"}.fa.fa-dashboard:before,.fa.fa-tachometer:before{content:"\f3fd"}.fa.fa-comment-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-comment-o:before{content:"\f075"}.fa.fa-comments-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-comments-o:before{content:"\f086"}.fa.fa-flash:before{content:"\f0e7"}.fa.fa-clipboard,.fa.fa-paste{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-paste:before{content:"\f328"}.fa.fa-lightbulb-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-lightbulb-o:before{content:"\f0eb"}.fa.fa-exchange:before{content:"\f362"}.fa.fa-cloud-download:before{content:"\f381"}.fa.fa-cloud-upload:before{content:"\f382"}.fa.fa-bell-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bell-o:before{content:"\f0f3"}.fa.fa-cutlery:before{content:"\f2e7"}.fa.fa-file-text-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-text-o:before{content:"\f15c"}.fa.fa-building-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-building-o:before{content:"\f1ad"}.fa.fa-hospital-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hospital-o:before{content:"\f0f8"}.fa.fa-tablet:before{content:"\f3fa"}.fa.fa-mobile-phone:before,.fa.fa-mobile:before{content:"\f3cd"}.fa.fa-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-circle-o:before{content:"\f111"}.fa.fa-mail-reply:before{content:"\f3e5"}.fa.fa-github-alt{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-folder-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-folder-o:before{content:"\f07b"}.fa.fa-folder-open-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-folder-open-o:before{content:"\f07c"}.fa.fa-smile-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-smile-o:before{content:"\f118"}.fa.fa-frown-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-frown-o:before{content:"\f119"}.fa.fa-meh-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-meh-o:before{content:"\f11a"}.fa.fa-keyboard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-keyboard-o:before{content:"\f11c"}.fa.fa-flag-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-flag-o:before{content:"\f024"}.fa.fa-mail-reply-all:before{content:"\f122"}.fa.fa-star-half-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-o:before{content:"\f089"}.fa.fa-star-half-empty{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-empty:before{content:"\f089"}.fa.fa-star-half-full{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-star-half-full:before{content:"\f089"}.fa.fa-code-fork:before{content:"\f126"}.fa.fa-chain-broken:before{content:"\f127"}.fa.fa-shield:before{content:"\f3ed"}.fa.fa-calendar-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-o:before{content:"\f133"}.fa.fa-css3,.fa.fa-html5,.fa.fa-maxcdn{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ticket:before{content:"\f3ff"}.fa.fa-minus-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-minus-square-o:before{content:"\f146"}.fa.fa-level-up:before{content:"\f3bf"}.fa.fa-level-down:before{content:"\f3be"}.fa.fa-pencil-square:before{content:"\f14b"}.fa.fa-external-link-square:before{content:"\f360"}.fa.fa-compass{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-down:before{content:"\f150"}.fa.fa-toggle-down{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-down:before{content:"\f150"}.fa.fa-caret-square-o-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-up:before{content:"\f151"}.fa.fa-toggle-up{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-up:before{content:"\f151"}.fa.fa-caret-square-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-right:before{content:"\f152"}.fa.fa-toggle-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-right:before{content:"\f152"}.fa.fa-eur:before,.fa.fa-euro:before{content:"\f153"}.fa.fa-gbp:before{content:"\f154"}.fa.fa-dollar:before,.fa.fa-usd:before{content:"\f155"}.fa.fa-inr:before,.fa.fa-rupee:before{content:"\f156"}.fa.fa-cny:before,.fa.fa-jpy:before,.fa.fa-rmb:before,.fa.fa-yen:before{content:"\f157"}.fa.fa-rouble:before,.fa.fa-rub:before,.fa.fa-ruble:before{content:"\f158"}.fa.fa-krw:before,.fa.fa-won:before{content:"\f159"}.fa.fa-bitcoin,.fa.fa-btc{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bitcoin:before{content:"\f15a"}.fa.fa-file-text:before{content:"\f15c"}.fa.fa-sort-alpha-asc:before{content:"\f15d"}.fa.fa-sort-alpha-desc:before{content:"\f881"}.fa.fa-sort-amount-asc:before{content:"\f160"}.fa.fa-sort-amount-desc:before{content:"\f884"}.fa.fa-sort-numeric-asc:before{content:"\f162"}.fa.fa-sort-numeric-desc:before{content:"\f886"}.fa.fa-xing,.fa.fa-xing-square,.fa.fa-youtube,.fa.fa-youtube-play,.fa.fa-youtube-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-youtube-play:before{content:"\f167"}.fa.fa-adn,.fa.fa-bitbucket,.fa.fa-bitbucket-square,.fa.fa-dropbox,.fa.fa-flickr,.fa.fa-instagram,.fa.fa-stack-overflow{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bitbucket-square:before{content:"\f171"}.fa.fa-tumblr,.fa.fa-tumblr-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-long-arrow-down:before{content:"\f309"}.fa.fa-long-arrow-up:before{content:"\f30c"}.fa.fa-long-arrow-left:before{content:"\f30a"}.fa.fa-long-arrow-right:before{content:"\f30b"}.fa.fa-android,.fa.fa-apple,.fa.fa-dribbble,.fa.fa-foursquare,.fa.fa-gittip,.fa.fa-gratipay,.fa.fa-linux,.fa.fa-skype,.fa.fa-trello,.fa.fa-windows{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-gittip:before{content:"\f184"}.fa.fa-sun-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-sun-o:before{content:"\f185"}.fa.fa-moon-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-moon-o:before{content:"\f186"}.fa.fa-pagelines,.fa.fa-renren,.fa.fa-stack-exchange,.fa.fa-vk,.fa.fa-weibo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-arrow-circle-o-right{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-right:before{content:"\f35a"}.fa.fa-arrow-circle-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-arrow-circle-o-left:before{content:"\f359"}.fa.fa-caret-square-o-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-caret-square-o-left:before{content:"\f191"}.fa.fa-toggle-left{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-toggle-left:before{content:"\f191"}.fa.fa-dot-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-dot-circle-o:before{content:"\f192"}.fa.fa-vimeo-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-try:before,.fa.fa-turkish-lira:before{content:"\f195"}.fa.fa-plus-square-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-plus-square-o:before{content:"\f0fe"}.fa.fa-openid,.fa.fa-slack,.fa.fa-wordpress{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bank:before,.fa.fa-institution:before{content:"\f19c"}.fa.fa-mortar-board:before{content:"\f19d"}.fa.fa-delicious,.fa.fa-digg,.fa.fa-drupal,.fa.fa-google,.fa.fa-joomla,.fa.fa-pied-piper-alt,.fa.fa-pied-piper-pp,.fa.fa-reddit,.fa.fa-reddit-square,.fa.fa-stumbleupon,.fa.fa-stumbleupon-circle,.fa.fa-yahoo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-spoon:before{content:"\f2e5"}.fa.fa-behance,.fa.fa-behance-square,.fa.fa-steam,.fa.fa-steam-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-automobile:before{content:"\f1b9"}.fa.fa-envelope-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-envelope-o:before{content:"\f0e0"}.fa.fa-deviantart,.fa.fa-soundcloud,.fa.fa-spotify{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-file-pdf-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-pdf-o:before{content:"\f1c1"}.fa.fa-file-word-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-word-o:before{content:"\f1c2"}.fa.fa-file-excel-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-excel-o:before{content:"\f1c3"}.fa.fa-file-powerpoint-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-powerpoint-o:before{content:"\f1c4"}.fa.fa-file-image-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-image-o:before{content:"\f1c5"}.fa.fa-file-photo-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-photo-o:before{content:"\f1c5"}.fa.fa-file-picture-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-picture-o:before{content:"\f1c5"}.fa.fa-file-archive-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-archive-o:before{content:"\f1c6"}.fa.fa-file-zip-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-zip-o:before{content:"\f1c6"}.fa.fa-file-audio-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-audio-o:before{content:"\f1c7"}.fa.fa-file-sound-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-sound-o:before{content:"\f1c7"}.fa.fa-file-video-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-video-o:before{content:"\f1c8"}.fa.fa-file-movie-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-movie-o:before{content:"\f1c8"}.fa.fa-file-code-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-file-code-o:before{content:"\f1c9"}.fa.fa-codepen,.fa.fa-jsfiddle,.fa.fa-vine{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-life-bouy,.fa.fa-life-ring{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-bouy:before{content:"\f1cd"}.fa.fa-life-buoy{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-buoy:before{content:"\f1cd"}.fa.fa-life-saver{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-life-saver:before{content:"\f1cd"}.fa.fa-support{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-support:before{content:"\f1cd"}.fa.fa-circle-o-notch:before{content:"\f1ce"}.fa.fa-ra,.fa.fa-rebel{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ra:before{content:"\f1d0"}.fa.fa-resistance{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-resistance:before{content:"\f1d0"}.fa.fa-empire,.fa.fa-ge{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-ge:before{content:"\f1d1"}.fa.fa-git,.fa.fa-git-square,.fa.fa-hacker-news,.fa.fa-y-combinator-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-y-combinator-square:before{content:"\f1d4"}.fa.fa-yc-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-yc-square:before{content:"\f1d4"}.fa.fa-qq,.fa.fa-tencent-weibo,.fa.fa-wechat,.fa.fa-weixin{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-wechat:before{content:"\f1d7"}.fa.fa-send:before{content:"\f1d8"}.fa.fa-paper-plane-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-paper-plane-o:before{content:"\f1d8"}.fa.fa-send-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-send-o:before{content:"\f1d8"}.fa.fa-circle-thin{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-circle-thin:before{content:"\f111"}.fa.fa-header:before{content:"\f1dc"}.fa.fa-sliders:before{content:"\f1de"}.fa.fa-futbol-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-futbol-o:before{content:"\f1e3"}.fa.fa-soccer-ball-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-soccer-ball-o:before{content:"\f1e3"}.fa.fa-slideshare,.fa.fa-twitch,.fa.fa-yelp{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-newspaper-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-newspaper-o:before{content:"\f1ea"}.fa.fa-cc-amex,.fa.fa-cc-discover,.fa.fa-cc-mastercard,.fa.fa-cc-paypal,.fa.fa-cc-stripe,.fa.fa-cc-visa,.fa.fa-google-wallet,.fa.fa-paypal{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-bell-slash-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-bell-slash-o:before{content:"\f1f6"}.fa.fa-trash:before{content:"\f2ed"}.fa.fa-copyright{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-eyedropper:before{content:"\f1fb"}.fa.fa-area-chart:before{content:"\f1fe"}.fa.fa-pie-chart:before{content:"\f200"}.fa.fa-line-chart:before{content:"\f201"}.fa.fa-angellist,.fa.fa-ioxhost,.fa.fa-lastfm,.fa.fa-lastfm-square{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-cc{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-cc:before{content:"\f20a"}.fa.fa-ils:before,.fa.fa-shekel:before,.fa.fa-sheqel:before{content:"\f20b"}.fa.fa-meanpath{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-meanpath:before{content:"\f2b4"}.fa.fa-buysellads,.fa.fa-connectdevelop,.fa.fa-dashcube,.fa.fa-forumbee,.fa.fa-leanpub,.fa.fa-sellsy,.fa.fa-shirtsinbulk,.fa.fa-simplybuilt,.fa.fa-skyatlas{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-diamond{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-diamond:before{content:"\f3a5"}.fa.fa-intersex:before{content:"\f224"}.fa.fa-facebook-official{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-facebook-official:before{content:"\f09a"}.fa.fa-pinterest-p,.fa.fa-whatsapp{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-hotel:before{content:"\f236"}.fa.fa-medium,.fa.fa-viacoin,.fa.fa-y-combinator,.fa.fa-yc{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-yc:before{content:"\f23b"}.fa.fa-expeditedssl,.fa.fa-opencart,.fa.fa-optin-monster{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-battery-4:before,.fa.fa-battery:before{content:"\f240"}.fa.fa-battery-3:before{content:"\f241"}.fa.fa-battery-2:before{content:"\f242"}.fa.fa-battery-1:before{content:"\f243"}.fa.fa-battery-0:before{content:"\f244"}.fa.fa-object-group,.fa.fa-object-ungroup,.fa.fa-sticky-note-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-sticky-note-o:before{content:"\f249"}.fa.fa-cc-diners-club,.fa.fa-cc-jcb{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-clone,.fa.fa-hourglass-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hourglass-o:before{content:"\f254"}.fa.fa-hourglass-1:before{content:"\f251"}.fa.fa-hourglass-2:before{content:"\f252"}.fa.fa-hourglass-3:before{content:"\f253"}.fa.fa-hand-rock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-rock-o:before{content:"\f255"}.fa.fa-hand-grab-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-grab-o:before{content:"\f255"}.fa.fa-hand-paper-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-paper-o:before{content:"\f256"}.fa.fa-hand-stop-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-stop-o:before{content:"\f256"}.fa.fa-hand-scissors-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-scissors-o:before{content:"\f257"}.fa.fa-hand-lizard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-lizard-o:before{content:"\f258"}.fa.fa-hand-spock-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-spock-o:before{content:"\f259"}.fa.fa-hand-pointer-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-pointer-o:before{content:"\f25a"}.fa.fa-hand-peace-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-hand-peace-o:before{content:"\f25b"}.fa.fa-registered{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-chrome,.fa.fa-creative-commons,.fa.fa-firefox,.fa.fa-get-pocket,.fa.fa-gg,.fa.fa-gg-circle,.fa.fa-internet-explorer,.fa.fa-odnoklassniki,.fa.fa-odnoklassniki-square,.fa.fa-opera,.fa.fa-safari,.fa.fa-tripadvisor,.fa.fa-wikipedia-w{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-television:before{content:"\f26c"}.fa.fa-500px,.fa.fa-amazon,.fa.fa-contao{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-calendar-plus-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-plus-o:before{content:"\f271"}.fa.fa-calendar-minus-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-minus-o:before{content:"\f272"}.fa.fa-calendar-times-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-times-o:before{content:"\f273"}.fa.fa-calendar-check-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-calendar-check-o:before{content:"\f274"}.fa.fa-map-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-map-o:before{content:"\f279"}.fa.fa-commenting:before{content:"\f4ad"}.fa.fa-commenting-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-commenting-o:before{content:"\f4ad"}.fa.fa-houzz,.fa.fa-vimeo{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-vimeo:before{content:"\f27d"}.fa.fa-black-tie,.fa.fa-edge,.fa.fa-fonticons,.fa.fa-reddit-alien{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-credit-card-alt:before{content:"\f09d"}.fa.fa-codiepie,.fa.fa-fort-awesome,.fa.fa-mixcloud,.fa.fa-modx,.fa.fa-product-hunt,.fa.fa-scribd,.fa.fa-usb{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-pause-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-pause-circle-o:before{content:"\f28b"}.fa.fa-stop-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-stop-circle-o:before{content:"\f28d"}.fa.fa-bluetooth,.fa.fa-bluetooth-b,.fa.fa-envira,.fa.fa-gitlab,.fa.fa-wheelchair-alt,.fa.fa-wpbeginner,.fa.fa-wpforms{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-wheelchair-alt:before{content:"\f368"}.fa.fa-question-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-question-circle-o:before{content:"\f059"}.fa.fa-volume-control-phone:before{content:"\f2a0"}.fa.fa-asl-interpreting:before{content:"\f2a3"}.fa.fa-deafness:before,.fa.fa-hard-of-hearing:before{content:"\f2a4"}.fa.fa-glide,.fa.fa-glide-g{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-signing:before{content:"\f2a7"}.fa.fa-first-order,.fa.fa-google-plus-official,.fa.fa-pied-piper,.fa.fa-snapchat,.fa.fa-snapchat-ghost,.fa.fa-snapchat-square,.fa.fa-themeisle,.fa.fa-viadeo,.fa.fa-viadeo-square,.fa.fa-yoast{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus-official:before{content:"\f2b3"}.fa.fa-google-plus-circle{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-google-plus-circle:before{content:"\f2b3"}.fa.fa-fa,.fa.fa-font-awesome{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-fa:before{content:"\f2b4"}.fa.fa-handshake-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-handshake-o:before{content:"\f2b5"}.fa.fa-envelope-open-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-envelope-open-o:before{content:"\f2b6"}.fa.fa-linode{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-address-book-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-address-book-o:before{content:"\f2b9"}.fa.fa-vcard:before{content:"\f2bb"}.fa.fa-address-card-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-address-card-o:before{content:"\f2bb"}.fa.fa-vcard-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-vcard-o:before{content:"\f2bb"}.fa.fa-user-circle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-user-circle-o:before{content:"\f2bd"}.fa.fa-user-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-user-o:before{content:"\f007"}.fa.fa-id-badge{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-drivers-license:before{content:"\f2c2"}.fa.fa-id-card-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-id-card-o:before{content:"\f2c2"}.fa.fa-drivers-license-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-drivers-license-o:before{content:"\f2c2"}.fa.fa-free-code-camp,.fa.fa-quora,.fa.fa-telegram{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-thermometer-4:before,.fa.fa-thermometer:before{content:"\f2c7"}.fa.fa-thermometer-3:before{content:"\f2c8"}.fa.fa-thermometer-2:before{content:"\f2c9"}.fa.fa-thermometer-1:before{content:"\f2ca"}.fa.fa-thermometer-0:before{content:"\f2cb"}.fa.fa-bathtub:before,.fa.fa-s15:before{content:"\f2cd"}.fa.fa-window-maximize,.fa.fa-window-restore{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-rectangle:before{content:"\f410"}.fa.fa-window-close-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-window-close-o:before{content:"\f410"}.fa.fa-times-rectangle-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-times-rectangle-o:before{content:"\f410"}.fa.fa-bandcamp,.fa.fa-eercast,.fa.fa-etsy,.fa.fa-grav,.fa.fa-imdb,.fa.fa-ravelry{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-eercast:before{content:"\f2da"}.fa.fa-snowflake-o{font-family:"Font Awesome 5 Free";font-weight:400}.fa.fa-snowflake-o:before{content:"\f2dc"}.fa.fa-superpowers,.fa.fa-wpexplorer{font-family:"Font Awesome 5 Brands";font-weight:400}.fa.fa-cab:before{content:"\f1ba"} \ No newline at end of file diff --git a/html/font-awesome/webfonts/fa-regular-400.eot b/html/font-awesome/webfonts/fa-regular-400.eot new file mode 100644 index 00000000000..479b32cecc2 Binary files /dev/null and b/html/font-awesome/webfonts/fa-regular-400.eot differ diff --git a/html/font-awesome/webfonts/fa-regular-400.woff b/html/font-awesome/webfonts/fa-regular-400.woff new file mode 100644 index 00000000000..c390c60e2b0 Binary files /dev/null and b/html/font-awesome/webfonts/fa-regular-400.woff differ diff --git a/html/font-awesome/webfonts/fa-solid-900.eot b/html/font-awesome/webfonts/fa-solid-900.eot new file mode 100644 index 00000000000..52883b93c83 Binary files /dev/null and b/html/font-awesome/webfonts/fa-solid-900.eot differ diff --git a/html/font-awesome/webfonts/fa-solid-900.woff b/html/font-awesome/webfonts/fa-solid-900.woff new file mode 100644 index 00000000000..aff125d6584 Binary files /dev/null and b/html/font-awesome/webfonts/fa-solid-900.woff differ diff --git a/icons/effects/actions_mecha.dmi b/icons/effects/actions_mecha.dmi new file mode 100644 index 00000000000..882ceb534f6 Binary files /dev/null and b/icons/effects/actions_mecha.dmi differ diff --git a/icons/effects/map_effects.dmi b/icons/effects/map_effects.dmi index 4f5bff755dd..0f28f9d2da8 100644 Binary files a/icons/effects/map_effects.dmi and b/icons/effects/map_effects.dmi differ diff --git a/icons/effects/writing.dmi b/icons/effects/writing.dmi new file mode 100644 index 00000000000..bbf4055bcea Binary files /dev/null and b/icons/effects/writing.dmi differ diff --git a/icons/mecha/mech_component.dmi b/icons/mecha/mech_component.dmi new file mode 100644 index 00000000000..c23c2d81e14 Binary files /dev/null and b/icons/mecha/mech_component.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 0c0dce59bc4..f265594a8d6 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/back_vr.dmi b/icons/mob/back_vr.dmi index dad66ba3c3e..21eb4cfdd21 100644 Binary files a/icons/mob/back_vr.dmi and b/icons/mob/back_vr.dmi differ diff --git a/icons/mob/custom_synthetic.dmi b/icons/mob/custom_synthetic.dmi index e69de29bb2d..7854fabe2bf 100644 Binary files a/icons/mob/custom_synthetic.dmi and b/icons/mob/custom_synthetic.dmi differ diff --git a/icons/mob/custom_synthetic_vr.dmi b/icons/mob/custom_synthetic_vr.dmi new file mode 100644 index 00000000000..8c9cd318f75 Binary files /dev/null and b/icons/mob/custom_synthetic_vr.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index d2a5879eebb..63e7f120cee 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/mob/head_vr.dmi b/icons/mob/head_vr.dmi index da75092bd0f..8823243859d 100644 Binary files a/icons/mob/head_vr.dmi and b/icons/mob/head_vr.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index baffef6647b..1e6b13982a9 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/icons/mob/human_face_m.dmi b/icons/mob/human_face_m.dmi index 2a6586d3d21..b2a245ad878 100644 Binary files a/icons/mob/human_face_m.dmi and b/icons/mob/human_face_m.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt2.dmi b/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt2.dmi index d2f9c44e911..a1a7a461229 100644 Binary files a/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt2.dmi and b/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt2.dmi differ diff --git a/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt3.dmi b/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt3.dmi new file mode 100644 index 00000000000..d2f9c44e911 Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/cybersolutions/cybersolutions_alt3.dmi differ diff --git a/icons/mob/items/lefthand_balls_vr.dmi b/icons/mob/items/lefthand_balls_vr.dmi new file mode 100644 index 00000000000..2f65e0969a5 Binary files /dev/null and b/icons/mob/items/lefthand_balls_vr.dmi differ diff --git a/icons/mob/items/lefthand_books.dmi b/icons/mob/items/lefthand_books.dmi new file mode 100644 index 00000000000..4b9d9fe481f Binary files /dev/null and b/icons/mob/items/lefthand_books.dmi differ diff --git a/icons/mob/items/lefthand_holder.dmi b/icons/mob/items/lefthand_holder.dmi index d629c657cec..14cd2406f09 100644 Binary files a/icons/mob/items/lefthand_holder.dmi and b/icons/mob/items/lefthand_holder.dmi differ diff --git a/icons/mob/items/righthand_balls_vr.dmi b/icons/mob/items/righthand_balls_vr.dmi new file mode 100644 index 00000000000..ba2bccac389 Binary files /dev/null and b/icons/mob/items/righthand_balls_vr.dmi differ diff --git a/icons/mob/items/righthand_books.dmi b/icons/mob/items/righthand_books.dmi new file mode 100644 index 00000000000..666e304aad8 Binary files /dev/null and b/icons/mob/items/righthand_books.dmi differ diff --git a/icons/mob/items/righthand_holder.dmi b/icons/mob/items/righthand_holder.dmi index c1e0563ec44..19bb1967f60 100644 Binary files a/icons/mob/items/righthand_holder.dmi and b/icons/mob/items/righthand_holder.dmi differ diff --git a/icons/mob/map_backgrounds.dmi b/icons/mob/map_backgrounds.dmi new file mode 100644 index 00000000000..dc6e3e46b16 Binary files /dev/null and b/icons/mob/map_backgrounds.dmi differ diff --git a/icons/mob/mouthball_vr.dmi b/icons/mob/mouthball_vr.dmi new file mode 100644 index 00000000000..f3c605ab56e Binary files /dev/null and b/icons/mob/mouthball_vr.dmi differ diff --git a/icons/mob/pai_vr.dmi b/icons/mob/pai_vr.dmi index a631425ae98..f03ad0ce42a 100644 Binary files a/icons/mob/pai_vr.dmi and b/icons/mob/pai_vr.dmi differ diff --git a/icons/mob/spacesuit_vr.dmi b/icons/mob/spacesuit_vr.dmi index 4196b2055e9..836b3a623de 100644 Binary files a/icons/mob/spacesuit_vr.dmi and b/icons/mob/spacesuit_vr.dmi differ diff --git a/icons/mob/species/akula/suit_vr.dmi b/icons/mob/species/akula/suit_vr.dmi index 3abd100eeef..d8ff65f802f 100644 Binary files a/icons/mob/species/akula/suit_vr.dmi and b/icons/mob/species/akula/suit_vr.dmi differ diff --git a/icons/mob/species/sergal/suit_vr.dmi b/icons/mob/species/sergal/suit_vr.dmi index 2cfc9891217..03adea85fcb 100644 Binary files a/icons/mob/species/sergal/suit_vr.dmi and b/icons/mob/species/sergal/suit_vr.dmi differ diff --git a/icons/mob/species/seromi/belt.dmi b/icons/mob/species/seromi/belt.dmi index 19a4a78cd92..fa68573c104 100644 Binary files a/icons/mob/species/seromi/belt.dmi and b/icons/mob/species/seromi/belt.dmi differ diff --git a/icons/mob/species/seromi/ears.dmi b/icons/mob/species/seromi/ears.dmi index 8730afe6d0a..fb2d0a13f5e 100644 Binary files a/icons/mob/species/seromi/ears.dmi and b/icons/mob/species/seromi/ears.dmi differ diff --git a/icons/mob/species/seromi/head.dmi b/icons/mob/species/seromi/head.dmi index f5222773f78..bf346475d3d 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 5b6fb68f694..638e79027ad 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/teshari_uniform.dmi b/icons/mob/species/seromi/teshari_uniform.dmi index 17cbd1b567d..627a03f2010 100644 Binary files a/icons/mob/species/seromi/teshari_uniform.dmi and b/icons/mob/species/seromi/teshari_uniform.dmi differ diff --git a/icons/mob/species/seromi/ties.dmi b/icons/mob/species/seromi/ties.dmi index bd88c2dedd8..ad23d77e2bf 100644 Binary files a/icons/mob/species/seromi/ties.dmi and b/icons/mob/species/seromi/ties.dmi differ diff --git a/icons/mob/species/seromi/uniform.dmi b/icons/mob/species/seromi/uniform.dmi index c2122bd177b..63acfcca494 100644 Binary files a/icons/mob/species/seromi/uniform.dmi and b/icons/mob/species/seromi/uniform.dmi differ diff --git a/icons/mob/species/skrell/helmet.dmi b/icons/mob/species/skrell/helmet.dmi index b35e996d8ad..8cda9900851 100644 Binary files a/icons/mob/species/skrell/helmet.dmi and b/icons/mob/species/skrell/helmet.dmi differ diff --git a/icons/mob/species/skrell/helmet_vr.dmi b/icons/mob/species/skrell/helmet_vr.dmi index b9806b4a582..be0c1ce344f 100644 Binary files a/icons/mob/species/skrell/helmet_vr.dmi and b/icons/mob/species/skrell/helmet_vr.dmi differ diff --git a/icons/mob/species/skrell/suit.dmi b/icons/mob/species/skrell/suit.dmi index e72ef3e002d..1185d99d7f2 100644 Binary files a/icons/mob/species/skrell/suit.dmi and b/icons/mob/species/skrell/suit.dmi differ diff --git a/icons/mob/species/skrell/suit_vr.dmi b/icons/mob/species/skrell/suit_vr.dmi index f6ca26a4288..ab071d50698 100644 Binary files a/icons/mob/species/skrell/suit_vr.dmi and b/icons/mob/species/skrell/suit_vr.dmi differ diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi index 54ef3ec4362..4003c1b508d 100644 Binary files a/icons/mob/species/tajaran/helmet.dmi and b/icons/mob/species/tajaran/helmet.dmi differ diff --git a/icons/mob/species/tajaran/helmet_vr.dmi b/icons/mob/species/tajaran/helmet_vr.dmi index c2092f4d203..49cbece23f4 100644 Binary files a/icons/mob/species/tajaran/helmet_vr.dmi and b/icons/mob/species/tajaran/helmet_vr.dmi differ diff --git a/icons/mob/species/tajaran/suit.dmi b/icons/mob/species/tajaran/suit.dmi index f9677e5e898..2453efcbaf4 100644 Binary files a/icons/mob/species/tajaran/suit.dmi and b/icons/mob/species/tajaran/suit.dmi differ diff --git a/icons/mob/species/tajaran/suit_vr.dmi b/icons/mob/species/tajaran/suit_vr.dmi index 738585d622a..c20178dacb8 100644 Binary files a/icons/mob/species/tajaran/suit_vr.dmi and b/icons/mob/species/tajaran/suit_vr.dmi differ diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi index eb0165e3e51..dc98094bb55 100644 Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ diff --git a/icons/mob/species/unathi/helmet_vr.dmi b/icons/mob/species/unathi/helmet_vr.dmi index 1c26c6271c9..e10d5b31ae2 100644 Binary files a/icons/mob/species/unathi/helmet_vr.dmi and b/icons/mob/species/unathi/helmet_vr.dmi differ diff --git a/icons/mob/species/unathi/suit.dmi b/icons/mob/species/unathi/suit.dmi index a05c73928ea..08f1ed49387 100644 Binary files a/icons/mob/species/unathi/suit.dmi and b/icons/mob/species/unathi/suit.dmi differ diff --git a/icons/mob/species/unathi/suit_vr.dmi b/icons/mob/species/unathi/suit_vr.dmi index 9cc3bc89d59..f1625306a74 100644 Binary files a/icons/mob/species/unathi/suit_vr.dmi and b/icons/mob/species/unathi/suit_vr.dmi differ diff --git a/icons/mob/species/vox/suit.dmi b/icons/mob/species/vox/suit.dmi index 9260e300877..fa391eb6439 100644 Binary files a/icons/mob/species/vox/suit.dmi and b/icons/mob/species/vox/suit.dmi differ diff --git a/icons/mob/species/vox/uniform.dmi b/icons/mob/species/vox/uniform.dmi index 6e33c45b5e5..fe53df15ed5 100644 Binary files a/icons/mob/species/vox/uniform.dmi and b/icons/mob/species/vox/uniform.dmi differ diff --git a/icons/mob/species/vulpkanin/helmet.dmi b/icons/mob/species/vulpkanin/helmet.dmi index 1d85465f776..ee1721cc37c 100644 Binary files a/icons/mob/species/vulpkanin/helmet.dmi and b/icons/mob/species/vulpkanin/helmet.dmi differ diff --git a/icons/mob/species/vulpkanin/helmet_vr.dmi b/icons/mob/species/vulpkanin/helmet_vr.dmi index d0c2f42d324..7ccdf2a14cc 100644 Binary files a/icons/mob/species/vulpkanin/helmet_vr.dmi and b/icons/mob/species/vulpkanin/helmet_vr.dmi differ diff --git a/icons/mob/species/vulpkanin/suit.dmi b/icons/mob/species/vulpkanin/suit.dmi index 6e54a4662bf..d8e5ee51333 100644 Binary files a/icons/mob/species/vulpkanin/suit.dmi and b/icons/mob/species/vulpkanin/suit.dmi differ diff --git a/icons/mob/species/vulpkanin/suit_vr.dmi b/icons/mob/species/vulpkanin/suit_vr.dmi index 81229b4f403..e0c20b6092f 100644 Binary files a/icons/mob/species/vulpkanin/suit_vr.dmi and b/icons/mob/species/vulpkanin/suit_vr.dmi differ diff --git a/icons/mob/status_indicators.dmi b/icons/mob/status_indicators.dmi new file mode 100644 index 00000000000..64103b82ff4 Binary files /dev/null and b/icons/mob/status_indicators.dmi differ diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi index a9e2f8eb92c..e3edb23202c 100644 Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ diff --git a/icons/mob/uniform_1.dmi b/icons/mob/uniform_1.dmi index cd1b4d1e4ea..20749c8afc8 100644 Binary files a/icons/mob/uniform_1.dmi and b/icons/mob/uniform_1.dmi differ diff --git a/icons/mob/vore64x64.dmi b/icons/mob/vore64x64.dmi index 50251e22cc0..a1042a6fd9d 100644 Binary files a/icons/mob/vore64x64.dmi and b/icons/mob/vore64x64.dmi differ diff --git a/icons/mob/widerobot_vr.dmi b/icons/mob/widerobot_vr.dmi index bf7c205d1fc..33381425cdb 100644 Binary files a/icons/mob/widerobot_vr.dmi and b/icons/mob/widerobot_vr.dmi differ diff --git a/icons/obj/aibots.dmi b/icons/obj/aibots.dmi index 87f78139699..a7d9e3b79fd 100644 Binary files a/icons/obj/aibots.dmi and b/icons/obj/aibots.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index 1a78788c3c5..bc7116f5d78 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/balls_vr.dmi b/icons/obj/balls_vr.dmi new file mode 100644 index 00000000000..994be4ab974 Binary files /dev/null and b/icons/obj/balls_vr.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 8f887eeb929..fb8c8d2c3dc 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/closets/bases/crate.dmi b/icons/obj/closets/bases/crate.dmi index e8946f3b358..83500acb3bd 100644 Binary files a/icons/obj/closets/bases/crate.dmi and b/icons/obj/closets/bases/crate.dmi differ diff --git a/icons/obj/closets/bases/large_crate.dmi b/icons/obj/closets/bases/large_crate.dmi index 1cdac277834..fd3400ed729 100644 Binary files a/icons/obj/closets/bases/large_crate.dmi and b/icons/obj/closets/bases/large_crate.dmi differ diff --git a/icons/obj/closets/decals/crate.dmi b/icons/obj/closets/decals/crate.dmi index 67a12301ed8..1fce07d8820 100644 Binary files a/icons/obj/closets/decals/crate.dmi and b/icons/obj/closets/decals/crate.dmi differ diff --git a/icons/obj/closets/decals/large_crate.dmi b/icons/obj/closets/decals/large_crate.dmi index 48765702659..2a9ff643805 100644 Binary files a/icons/obj/closets/decals/large_crate.dmi and b/icons/obj/closets/decals/large_crate.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index 31ec945739e..19d7de134f1 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/hats_vr.dmi b/icons/obj/clothing/hats_vr.dmi index 8a1d7143c6f..8f9ad629a71 100644 Binary files a/icons/obj/clothing/hats_vr.dmi and b/icons/obj/clothing/hats_vr.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 03a5e7fb09e..998d31b2f8b 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/species/seromi/uniform.dmi b/icons/obj/clothing/species/seromi/uniform.dmi index f2dc52a9133..e1c6e2f464c 100644 Binary files a/icons/obj/clothing/species/seromi/uniform.dmi and b/icons/obj/clothing/species/seromi/uniform.dmi differ diff --git a/icons/obj/clothing/suits_vr.dmi b/icons/obj/clothing/suits_vr.dmi index 6c685554d87..a02c4756df5 100644 Binary files a/icons/obj/clothing/suits_vr.dmi and b/icons/obj/clothing/suits_vr.dmi differ diff --git a/icons/obj/clothing/ties.dmi b/icons/obj/clothing/ties.dmi index 0bc7a9fcb2e..21d8bbff1d7 100644 Binary files a/icons/obj/clothing/ties.dmi and b/icons/obj/clothing/ties.dmi differ diff --git a/icons/obj/clothing/uniforms_1.dmi b/icons/obj/clothing/uniforms_1.dmi index 35eb06f7a2c..32a55ec9c20 100644 Binary files a/icons/obj/clothing/uniforms_1.dmi and b/icons/obj/clothing/uniforms_1.dmi differ diff --git a/icons/obj/cooking_machines.dmi b/icons/obj/cooking_machines.dmi index 666a31b9d09..4009cb62249 100644 Binary files a/icons/obj/cooking_machines.dmi and b/icons/obj/cooking_machines.dmi differ diff --git a/icons/obj/curtain.dmi b/icons/obj/curtain.dmi index 69b7de1dc06..dcf4cf0bcdc 100644 Binary files a/icons/obj/curtain.dmi and b/icons/obj/curtain.dmi differ diff --git a/icons/obj/custom_books.dmi b/icons/obj/custom_books.dmi index 2be098e848e..f60a15fc1aa 100644 Binary files a/icons/obj/custom_books.dmi and b/icons/obj/custom_books.dmi differ diff --git a/icons/obj/drinks_vr.dmi b/icons/obj/drinks_vr.dmi index 36506bca17c..0f383a823f2 100644 Binary files a/icons/obj/drinks_vr.dmi and b/icons/obj/drinks_vr.dmi differ diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi index 64f4753b7b9..efe9039a410 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 index 4057be39939..ee26eb7777e 100644 Binary files a/icons/obj/food_custom.dmi and b/icons/obj/food_custom.dmi differ diff --git a/icons/obj/food_syn.dmi b/icons/obj/food_syn.dmi new file mode 100644 index 00000000000..1104d4ddbf9 Binary files /dev/null and b/icons/obj/food_syn.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index c8ca467a513..a211d0e9f1f 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/icons/obj/gun2.dmi b/icons/obj/gun2.dmi index 56014ea32e1..38a4148c20f 100644 Binary files a/icons/obj/gun2.dmi and b/icons/obj/gun2.dmi differ diff --git a/icons/obj/janitor.dmi b/icons/obj/janitor.dmi index 349c8a40304..3b7f9b4f603 100644 Binary files a/icons/obj/janitor.dmi and b/icons/obj/janitor.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 5bc1d782abd..df5a8757be2 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/machines/floodlight.dmi b/icons/obj/machines/floodlight.dmi index 8dea4dc8b67..45c5ec6c67c 100644 Binary files a/icons/obj/machines/floodlight.dmi and b/icons/obj/machines/floodlight.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index 6973896c3ca..5b19f0d43b8 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/icons/obj/status_display.dmi b/icons/obj/status_display.dmi index 842a379ddce..5dbaae994d4 100644 Binary files a/icons/obj/status_display.dmi and b/icons/obj/status_display.dmi differ diff --git a/icons/obj/stickynotes.dmi b/icons/obj/stickynotes.dmi new file mode 100644 index 00000000000..8ca70a41493 Binary files /dev/null and b/icons/obj/stickynotes.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 9b7ad90e8f0..dbd17cc7f49 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/toy_vr.dmi b/icons/obj/toy_vr.dmi index 6e927e0f8b9..9333c6b938f 100644 Binary files a/icons/obj/toy_vr.dmi and b/icons/obj/toy_vr.dmi differ diff --git a/icons/obj/trash.dmi b/icons/obj/trash.dmi index e55d92293da..436ebe657d0 100644 Binary files a/icons/obj/trash.dmi and b/icons/obj/trash.dmi differ diff --git a/icons/obj/virology.dmi b/icons/obj/virology.dmi index 02a426049bb..224c4c90148 100644 Binary files a/icons/obj/virology.dmi and b/icons/obj/virology.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index faee20d4426..a76004a1be6 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -880,6 +880,31 @@ menu "menu" category = "&Icons" can-check = true saved-params = "is-checked" + elem + name = "&Scaling" + command = "" + saved-params = "is-checked" + elem "nearest-neighbor" + name = "&Nearest Neighbor" + command = ".winset \"mapwindow.map.zoom-mode=distort\"" + category = "&Scaling" + can-check = true + group = "scale" + saved-params = "is-checked" + elem "point-sample" + name = "&Point Sampling" + command = ".winset \"mapwindow.map.zoom-mode=normal\"" + category = "&Scaling" + can-check = true + group = "scale" + saved-params = "is-checked" + elem "blur" + name = "&Blur" + command = ".winset \"mapwindow.map.zoom-mode=blur\"" + category = "&Scaling" + can-check = true + group = "scale" + saved-params = "is-checked" elem name = "&Help" command = "" @@ -1120,6 +1145,7 @@ window "mainwindow" anchor1 = none anchor2 = none is-visible = false + auto-format = false saved-params = "" elem "hotkey_toggle" type = BUTTON diff --git a/maps/northern_star/polaris-1.dmm b/maps/northern_star/polaris-1.dmm index e6740cebd48..8c75ee31edd 100644 --- a/maps/northern_star/polaris-1.dmm +++ b/maps/northern_star/polaris-1.dmm @@ -4612,12 +4612,12 @@ "bKJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hydroponics) "bKK" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/table/marble,/obj/item/weapon/book/manual/chef_recipes,/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/camera/network/civilian{c_tag = "CIV - Kitchen Port"; dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bKL" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = 28},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"bKM" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/fryer,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"bKN" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/grill,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"bKM" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/appliance/cooker/fryer,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"bKN" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/appliance/cooker/grill,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bKO" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/closet/secure_closet/freezer/fridge,/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bKP" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{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/crew_quarters/kitchen) "bKQ" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/sink/kitchen{pixel_y = 28},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"bKR" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/oven,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"bKR" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/appliance/cooker/oven,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bKS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/crew_quarters/kitchen) "bKT" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/tiled,/area/hallway/primary/central_two) "bKU" = (/turf/simulated/wall/r_wall,/area/medical/chemistry) @@ -4716,7 +4716,7 @@ "bMJ" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/landmark/start{name = "Chef"},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bMK" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bML" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/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) -"bMM" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/candy,/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"bMM" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/appliance/mixer/candy,/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bMN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/crew_quarters/kitchen) "bMO" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled,/area/hallway/primary/central_two) "bMP" = (/obj/structure/extinguisher_cabinet{pixel_x = 25},/turf/simulated/floor/tiled,/area/hallway/primary/central_two) @@ -4817,7 +4817,7 @@ "bOG" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/table/marble,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bOH" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bOI" = (/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,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"bOJ" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/cereal,/obj/machinery/camera/network/civilian{c_tag = "CIV - Kitchen Starboard"; dir = 8},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"bOJ" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/appliance/mixer/cereal,/obj/machinery/camera/network/civilian{c_tag = "CIV - Kitchen Starboard"; dir = 8},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bOK" = (/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/structure/table/reinforced,/obj/machinery/button/remote/blast_door{id = "chemcounter"; name = "Pharmacy Counter Lockdown Control"; pixel_y = 14},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/effect/floor_decal/corner/beige{dir = 9},/turf/simulated/floor/tiled/white,/area/medical/chemistry) "bOL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/tiled/white,/area/medical/chemistry) "bOM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/tiled/white,/area/medical/chemistry) diff --git a/maps/southern_cross/datums/supplypacks/munitions.dm b/maps/southern_cross/datums/supplypacks/munitions.dm index fa24358cebc..ee51fc4f0c3 100644 --- a/maps/southern_cross/datums/supplypacks/munitions.dm +++ b/maps/southern_cross/datums/supplypacks/munitions.dm @@ -10,7 +10,7 @@ /obj/item/ammo_magazine/clip/c762/hunter = 6 ) cost = 50 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/hedberg containername = "Hunting Rifle crate" access = access_explorer @@ -20,7 +20,7 @@ /obj/item/weapon/gun/energy/phasegun = 2, ) cost = 25 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/ward containername = "Phase Carbine crate" access = access_explorer @@ -30,6 +30,6 @@ /obj/item/weapon/gun/energy/phasegun/rifle = 2, ) cost = 50 - containertype = /obj/structure/closet/crate/secure/weapon + containertype = /obj/structure/closet/crate/secure/ward containername = "Phase Rifle crate" access = access_explorer \ No newline at end of file diff --git a/maps/southern_cross/overmap/sectors.dm b/maps/southern_cross/overmap/sectors.dm index 5d569cb05d9..6bfc3edfa1f 100644 --- a/maps/southern_cross/overmap/sectors.dm +++ b/maps/southern_cross/overmap/sectors.dm @@ -36,7 +36,8 @@ start_x = 10 start_y = 10 map_z = list(Z_LEVEL_STATION_ONE, Z_LEVEL_STATION_TWO, Z_LEVEL_STATION_THREE) + extra_z_levels = list(Z_LEVEL_TRANSIT) // Hopefully temporary, so arrivals announcements work. /obj/effect/overmap/visitable/planet/Sif/Initialize() . = ..() - docking_codes = null \ No newline at end of file + docking_codes = null diff --git a/maps/southern_cross/southern_cross-1.dmm b/maps/southern_cross/southern_cross-1.dmm index b276f58b451..1bf367399d3 100644 --- a/maps/southern_cross/southern_cross-1.dmm +++ b/maps/southern_cross/southern_cross-1.dmm @@ -302,7 +302,7 @@ "afP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) "afQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) "afR" = (/obj/machinery/atmospherics/valve/shutoff{name = "Deck 1 Fore Starboard automatic shutoff valve"},/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) -"afS" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/closet/crate,/obj/item/weapon/toy/xmas_cracker,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) +"afS" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/weapon/toy/xmas_cracker,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) "afT" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/item/device/paicard,/turf/simulated/floor/plating,/area/construction/firstdeck/construction5) "afU" = (/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/obj/item/weapon/tool/wirecutters,/turf/simulated/floor/tiled,/area/construction/firstdeck/construction5) "afV" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = -1},/obj/structure/curtain/open/shower,/turf/simulated/floor/tiled/freezer,/area/crew_quarters/toilet/firstdeck) @@ -318,8 +318,8 @@ "agf" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "agg" = (/obj/structure/filingcabinet/security{name = "Security Records"},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "agh" = (/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) -"agi" = (/obj/structure/closet/crate,/obj/item/weapon/storage/backpack,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/assembly/prox_sensor,/obj/item/device/flashlight,/obj/random/maintenance/engineering,/obj/random/maintenance/engineering,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) -"agj" = (/obj/structure/closet/crate,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/clean,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/obj/item/toy/xmastree,/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) +"agi" = (/obj/item/weapon/storage/backpack,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/assembly/prox_sensor,/obj/item/device/flashlight,/obj/random/maintenance/engineering,/obj/random/maintenance/engineering,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) +"agj" = (/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/clean,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/obj/item/toy/xmastree,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) "agk" = (/obj/structure/table/rack,/obj/item/weapon/flame/lighter/random,/obj/random/maintenance/clean,/obj/random/cigarettes,/obj/random/maintenance/clean,/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/random/cash,/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) "agl" = (/obj/effect/floor_decal/rust,/turf/simulated/floor/plating,/area/hangar/three) "agm" = (/turf/simulated/floor/reinforced,/area/hangar/three) @@ -350,7 +350,7 @@ "agL" = (/obj/structure/closet/crate,/obj/item/stack/material/gold,/obj/item/weapon/storage/belt/champion,/obj/item/stack/material/gold,/obj/item/stack/material/gold,/obj/item/stack/material/gold,/obj/item/stack/material/gold,/obj/item/stack/material/gold,/obj/item/stack/material/silver,/obj/item/stack/material/silver,/obj/item/stack/material/silver,/obj/item/stack/material/silver,/obj/item/stack/material/silver,/obj/item/stack/material/silver,/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "agM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/hologram/holopad,/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) "agN" = (/obj/structure/filingcabinet/medical{desc = "A large cabinet with hard copy medical records."; name = "Medical Records"},/turf/simulated/floor/tiled/dark,/area/security/nuke_storage) -"agO" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/closet/crate,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) +"agO" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) "agP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) "agQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) "agR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) @@ -531,7 +531,7 @@ "akk" = (/obj/structure/bed/chair{dir = 1},/obj/structure/closet/walllocker/emerglocker{pixel_x = -28},/obj/effect/shuttle_landmark/southern_cross/escape_pod1/station{base_area = /area/hallway/primary/firstdeck/auxdockfore},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod1/station) "akl" = (/obj/machinery/door/airlock/voidcraft/vertical{frequency = 1380; id_tag = "shuttle1_outer"; name = "External Access"},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "shuttle1_shuttle"; name = "exterior access button"; pixel_x = 0; pixel_y = 26; req_access = null},/turf/simulated/shuttle/floor/black,/area/shuttle/shuttle1/start) "akm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/firstdeck/foreport) -"akn" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/random/maintenance/cargo,/obj/structure/closet/crate,/obj/random/maintenance/cargo,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/turf/simulated/floor,/area/maintenance/firstdeck/foreport) +"akn" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/obj/random/crate,/turf/simulated/floor,/area/maintenance/firstdeck/foreport) "ako" = (/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fpcenter) "akp" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fpcenter) "akq" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/tiled/monotile,/area/hallway/primary/firstdeck/fpcenter) @@ -564,7 +564,7 @@ "akR" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1380; id_tag = "shuttle1_pump"},/obj/structure/closet/emcloset,/turf/simulated/shuttle/floor/black,/area/shuttle/shuttle1/start) "akS" = (/obj/machinery/shuttle_sensor{dir = 5; id_tag = "shuttle1sens_exp"},/turf/simulated/shuttle/wall/voidcraft/blue,/area/shuttle/shuttle1/start) "akT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light/spot{dir = 4},/obj/machinery/camera/network/first_deck{c_tag = "Hangar One - Aft Starboard"; dir = 8},/turf/simulated/floor/tiled/monotile,/area/hangar/one) -"akU" = (/obj/structure/closet/crate,/obj/random/action_figure,/obj/random/action_figure,/obj/random/action_figure,/obj/random/action_figure,/obj/random/maintenance/clean,/obj/random/toy,/obj/item/weapon/toy/xmas_cracker,/turf/simulated/floor,/area/maintenance/firstdeck/foreport) +"akU" = (/obj/random/action_figure,/obj/random/action_figure,/obj/random/action_figure,/obj/random/action_figure,/obj/random/maintenance/clean,/obj/random/toy,/obj/item/weapon/toy/xmas_cracker,/obj/random/crate,/turf/simulated/floor,/area/maintenance/firstdeck/foreport) "akV" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fpcenter) "akW" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fpcenter) "akX" = (/obj/effect/floor_decal/borderfloor,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/floor_decal/corner/green/border,/obj/effect/floor_decal/borderfloor/corner2,/obj/effect/floor_decal/corner/green/bordercorner2,/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fpcenter) @@ -584,7 +584,7 @@ "all" = (/obj/effect/floor_decal/borderfloor,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/floor_decal/corner/green/border,/obj/effect/floor_decal/borderfloor/corner2{dir = 9},/obj/effect/floor_decal/corner/green/bordercorner2{dir = 9},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fscenter) "alm" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fscenter) "aln" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fscenter) -"alo" = (/obj/random/powercell,/obj/random/powercell,/obj/random/powercell,/obj/random/powercell,/obj/random/toolbox,/obj/effect/decal/cleanable/molten_item,/obj/structure/closet/crate,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/structure/catwalk,/turf/simulated/floor,/area/maintenance/firstdeck/forestarboard) +"alo" = (/obj/random/powercell,/obj/random/powercell,/obj/random/powercell,/obj/random/powercell,/obj/random/toolbox,/obj/effect/decal/cleanable/molten_item,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/structure/catwalk,/obj/random/crate,/turf/simulated/floor,/area/maintenance/firstdeck/forestarboard) "alp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light/spot{dir = 8},/obj/machinery/camera/network/first_deck{c_tag = "Hangar Three - Aft Port"; dir = 4},/turf/simulated/floor/tiled/monotile,/area/hangar/three) "alq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light/spot{dir = 4},/obj/machinery/camera/network/first_deck{c_tag = "Hangar Three - Aft Starboard"; dir = 8},/turf/simulated/floor/tiled/monotile,/area/hangar/three) "alr" = (/turf/simulated/wall/r_wall,/area/maintenance/firstdeck/centralstarboard) @@ -661,8 +661,8 @@ "amK" = (/turf/simulated/wall,/area/tcomm/computer) "amL" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/tiled/dark,/area/hallway/primary/firstdeck/fscenter) "amM" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fscenter) -"amN" = (/obj/structure/closet/crate/medical,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/clean,/turf/simulated/floor,/area/maintenance/firstdeck/forestarboard) -"amO" = (/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/green/border{dir = 8},/obj/structure/closet/crate,/turf/simulated/floor/tiled,/area/hangar/three) +"amN" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle1/start) +"amO" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle1/start) "amP" = (/obj/structure/extinguisher_cabinet{pixel_x = 25},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/turf/simulated/floor/tiled,/area/hangar/three) "amQ" = (/turf/simulated/floor/airless,/area/rnd/xenobiology/xenoflora) "amR" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/vending/wallmed1{layer = 3.3; name = "Emergency NanoMed"; pixel_x = -28; pixel_y = 0},/turf/simulated/shuttle/floor/white,/area/shuttle/large_escape_pod2/station) @@ -693,7 +693,7 @@ "anq" = (/obj/structure/cable/cyan{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"},/obj/structure/catwalk,/turf/simulated/floor/plating,/area/tcomm/computer) "anr" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fscenter) "ans" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/fscenter) -"ant" = (/obj/structure/closet/crate,/obj/item/weapon/tank/emergency/oxygen/engi,/obj/item/weapon/tank/emergency/oxygen/double,/obj/random/maintenance/engineering,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) +"ant" = (/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/clean,/obj/random/crate,/turf/simulated/floor,/area/maintenance/firstdeck/forestarboard) "anu" = (/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/green/border{dir = 8},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/machinery/space_heater,/turf/simulated/floor/tiled,/area/hangar/three) "anv" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/monotile,/area/hangar/three) "anw" = (/obj/effect/floor_decal/borderfloorblack/corner{dir = 4},/obj/effect/floor_decal/industrial/danger/corner{dir = 4},/turf/simulated/floor/tiled,/area/hangar/three) @@ -704,7 +704,7 @@ "anB" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; pressure_checks = 1; pressure_checks_default = 1; use_power = 1},/turf/simulated/floor/airless,/area/rnd/xenobiology/xenoflora) "anC" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora_isolation) "anD" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "large_escape_pod_2_hatch"; locked = 1; name = "Large Escape Pod Hatch 2"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/large_escape_pod2/station) -"anE" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle1/start) +"anE" = (/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/green/border{dir = 8},/obj/random/crate,/turf/simulated/floor/tiled,/area/hangar/three) "anF" = (/obj/machinery/space_heater,/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/green/border{dir = 8},/turf/simulated/floor/tiled,/area/hangar/one) "anG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/tiled/monotile,/area/hangar/one) "anH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/monotile,/area/hangar/one) @@ -726,7 +726,7 @@ "anX" = (/obj/machinery/telecomms/bus/preset_two/southerncross,/turf/simulated/floor/tiled/dark{nitrogen = 100; oxygen = 0; temperature = 80},/area/tcomm/chamber) "anY" = (/obj/machinery/telecomms/relay/preset/southerncross/d1,/turf/simulated/floor/tiled/dark{nitrogen = 100; oxygen = 0; temperature = 80},/area/tcomm/chamber) "anZ" = (/turf/simulated/floor/tiled/dark{nitrogen = 100; oxygen = 0; temperature = 80},/area/tcomm/chamber) -"aoa" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle1/start) +"aoa" = (/obj/item/weapon/tank/emergency/oxygen/engi,/obj/item/weapon/tank/emergency/oxygen/double,/obj/random/maintenance/engineering,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/firstdeck/forestarboard) "aob" = (/obj/machinery/telecomms/bus/preset_four,/turf/simulated/floor/tiled/dark{nitrogen = 100; oxygen = 0; temperature = 80},/area/tcomm/chamber) "aoc" = (/obj/machinery/telecomms/processor/preset_four,/turf/simulated/floor/tiled/dark{nitrogen = 100; oxygen = 0; temperature = 80},/area/tcomm/chamber) "aod" = (/obj/machinery/atmospherics/pipe/simple/hidden/black,/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcomm/chamber) @@ -847,7 +847,7 @@ "aqo" = (/turf/simulated/floor/plating,/area/construction/firstdeck/construction4) "aqp" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/wood,/area/construction/firstdeck/construction4) "aqq" = (/turf/simulated/floor/wood,/area/construction/firstdeck/construction4) -"aqr" = (/obj/random/drinkbottle,/obj/structure/closet/crate,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/drinkbottle,/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/turf/simulated/floor/wood,/area/construction/firstdeck/construction4) +"aqr" = (/obj/random/drinkbottle,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/drinkbottle,/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/obj/random/crate,/turf/simulated/floor/wood,/area/construction/firstdeck/construction4) "aqs" = (/obj/structure/closet/emcloset,/obj/machinery/ai_status_display{pixel_y = 32},/obj/effect/floor_decal/borderfloor{dir = 9},/obj/effect/floor_decal/corner/red/border{dir = 9},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_starboard1) "aqt" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/white/border{dir = 1},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_starboard1) "aqu" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/red/border{dir = 1},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_starboard1) @@ -1286,7 +1286,7 @@ "ayL" = (/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor/tiled/dark,/area/hallway/primary/firstdeck/starboard) "ayM" = (/obj/turbolift_map_holder/southern_cross/starboard,/turf/unsimulated/mask,/area/hallway/primary/firstdeck/starboard) "ayN" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/firstdeck/centralstarboard) -"ayO" = (/obj/structure/closet/crate,/obj/item/weapon/tank/emergency/oxygen/engi,/obj/item/weapon/tank/emergency/oxygen/double,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/firstdeck/centralport) +"ayO" = (/obj/item/weapon/tank/emergency/oxygen/engi,/obj/item/weapon/tank/emergency/oxygen/double,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/structure/catwalk,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/firstdeck/centralport) "ayP" = (/obj/structure/closet/emcloset,/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/firstdeck/centralport) "ayQ" = (/obj/random/obstruction,/turf/simulated/floor/plating,/area/construction/firstdeck/construction2) "ayR" = (/turf/simulated/floor/plating,/area/construction/firstdeck/construction2) @@ -1301,7 +1301,7 @@ "aza" = (/obj/item/frame,/obj/machinery/light_construct,/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/steel_dirty,/area/maintenance/firstdeck/aftport) "azb" = (/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/steel_dirty,/area/maintenance/firstdeck/aftport) "azc" = (/obj/random/obstruction,/turf/simulated/floor/plating,/area/maintenance/firstdeck/aftport) -"azd" = (/obj/structure/closet/crate,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/assembly/prox_sensor,/obj/item/device/flashlight,/obj/item/weapon/storage/backpack,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/turf/simulated/floor/plating,/area/maintenance/firstdeck/aftport) +"azd" = (/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/assembly/prox_sensor,/obj/item/device/flashlight,/obj/item/weapon/storage/backpack,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/firstdeck/aftport) "aze" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor,/area/maintenance/firstdeck/aftport) "azf" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor,/area/maintenance/firstdeck/aftport) "azg" = (/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/firstdeck/aftport) @@ -1415,7 +1415,7 @@ "aBk" = (/obj/structure/door_assembly/door_assembly_ext,/turf/simulated/floor/plating,/area/maintenance/firstdeck/centralport) "aBl" = (/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/random/maintenance/clean,/obj/random/tech_supply,/obj/random/tech_supply,/obj/item/weapon/airlock_electronics,/obj/item/stack/cable_coil/random,/turf/simulated/floor/plating,/area/maintenance/firstdeck/centralport) "aBm" = (/obj/machinery/door/blast/regular{density = 0; dir = 1; icon_state = "pdoor0"; id = "crglockdown"; name = "Cargo Lockdown"; opacity = 0},/turf/simulated/floor/plating,/area/maintenance/firstdeck/centralport) -"aBn" = (/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/construction/firstdeck/construction2) +"aBn" = (/obj/item/device/flashlight,/obj/random/crate,/turf/simulated/floor/plating,/area/construction/firstdeck/construction2) "aBo" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor/plating,/area/construction/firstdeck/construction2) "aBp" = (/obj/structure/table/steel,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tool/powermaint,/turf/simulated/floor,/area/construction/firstdeck/construction2) "aBq" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/table/steel,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/turf/simulated/floor/plating,/area/construction/firstdeck/construction2) @@ -1459,7 +1459,7 @@ "aCc" = (/obj/machinery/computer/crew{dir = 8},/turf/simulated/floor/tiled/techmaint,/area/medical/first_aid_station/firstdeck) "aCd" = (/obj/structure/table/reinforced,/obj/machinery/alarm{dir = 8; pixel_x = 22; pixel_y = 0},/turf/simulated/floor/tiled,/area/hangar/twocontrol) "aCe" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/structure/table/steel,/turf/simulated/floor/plating,/area/construction/firstdeck/construction3) -"aCf" = (/obj/item/clothing/head/soft/mime,/obj/item/clothing/mask/gas/mime,/obj/item/clothing/shoes/mime,/obj/item/clothing/under/mime,/obj/structure/closet/crate,/turf/simulated/floor,/area/construction/firstdeck/construction3) +"aCf" = (/obj/item/clothing/head/soft/mime,/obj/item/clothing/mask/gas/mime,/obj/item/clothing/shoes/mime,/obj/item/clothing/under/mime,/obj/random/crate,/turf/simulated/floor,/area/construction/firstdeck/construction3) "aCg" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor/plating,/area/construction/firstdeck/construction3) "aCh" = (/obj/structure/table/steel,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/maintenance/engineering,/turf/simulated/floor/tiled/steel,/area/construction/firstdeck/construction3) "aCi" = (/obj/structure/closet/emcloset,/obj/machinery/ai_status_display{pixel_y = -32},/obj/effect/floor_decal/borderfloor{dir = 10},/obj/effect/floor_decal/corner/red/border{dir = 10},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_starboard2) @@ -1531,9 +1531,9 @@ "aDw" = (/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 4},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 9},/turf/simulated/floor/tiled,/area/quartermaster/storage) "aDx" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/effect/floor_decal/borderfloor/corner{dir = 4},/obj/effect/floor_decal/corner/brown/bordercorner{dir = 4},/turf/simulated/floor/tiled,/area/quartermaster/storage) "aDy" = (/obj/machinery/light/spot{dir = 1},/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/brown/border{dir = 1},/turf/simulated/floor/tiled,/area/quartermaster/storage) -"aDz" = (/obj/structure/extinguisher_cabinet{pixel_y = 30},/obj/structure/closet/crate,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/brown/border{dir = 1},/turf/simulated/floor/tiled,/area/quartermaster/storage) -"aDA" = (/obj/structure/closet/crate,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/brown/border{dir = 1},/turf/simulated/floor/tiled,/area/quartermaster/storage) -"aDB" = (/obj/machinery/firealarm{pixel_y = 24},/obj/structure/closet/crate/freezer,/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/brown/border{dir = 1},/turf/simulated/floor/tiled,/area/quartermaster/storage) +"aDz" = (/obj/structure/extinguisher_cabinet{pixel_y = 30},/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/brown/border{dir = 1},/obj/random/crate,/turf/simulated/floor/tiled,/area/quartermaster/storage) +"aDA" = (/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/brown/border{dir = 1},/obj/random/crate,/turf/simulated/floor/tiled,/area/quartermaster/storage) +"aDB" = (/obj/machinery/firealarm{pixel_y = 24},/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/brown/border{dir = 1},/obj/random/crate,/turf/simulated/floor/tiled,/area/quartermaster/storage) "aDC" = (/obj/structure/table/steel_reinforced,/obj/machinery/cell_charger,/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/brown/border{dir = 1},/turf/simulated/floor/tiled,/area/quartermaster/storage) "aDD" = (/obj/structure/table/steel_reinforced,/obj/item/clothing/accessory/armband/cargo,/obj/item/device/retail_scanner/cargo,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_x = 0; pixel_y = 28},/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/brown/border{dir = 1},/turf/simulated/floor/tiled,/area/quartermaster/storage) "aDE" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/stamp{pixel_x = -3; pixel_y = 3},/obj/item/weapon/stamp/cargo,/obj/effect/floor_decal/borderfloor{dir = 5},/obj/effect/floor_decal/corner/brown/border{dir = 5},/turf/simulated/floor/tiled,/area/quartermaster/storage) @@ -1690,7 +1690,7 @@ "aGz" = (/obj/machinery/computer/telecomms/monitor{dir = 4; network = "tcommsat"},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/black{dir = 4},/turf/simulated/floor/tiled/dark,/area/tcomm/computer) "aGA" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8; icon_state = "propulsion_l"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) "aGB" = (/obj/effect/floor_decal/borderfloorblack{dir = 8},/obj/effect/floor_decal/industrial/danger{dir = 8},/turf/simulated/floor/tiled,/area/hangar/two) -"aGC" = (/obj/structure/extinguisher_cabinet{pixel_x = 25},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/obj/structure/closet/crate,/turf/simulated/floor/tiled,/area/hangar/two) +"aGC" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) "aGD" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/floor,/area/shuttle/large_escape_pod1/station) "aGE" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor/white,/area/shuttle/large_escape_pod1/station) "aGF" = (/obj/structure/grille,/obj/structure/shuttle/window,/turf/simulated/shuttle/plating,/area/shuttle/large_escape_pod1/station) @@ -1723,7 +1723,7 @@ "aHg" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/ascenter) "aHh" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/tiled,/area/hallway/primary/firstdeck/ascenter) "aHi" = (/obj/machinery/floodlight,/turf/simulated/floor,/area/maintenance/firstdeck/aftstarboard) -"aHj" = (/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/green/border{dir = 8},/obj/structure/closet/crate,/turf/simulated/floor/tiled,/area/hangar/two) +"aHj" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle2/start) "aHk" = (/turf/simulated/shuttle/wall/voidcraft/no_join,/area/shuttle/shuttle2/start) "aHl" = (/turf/simulated/shuttle/wall/voidcraft,/area/shuttle/shuttle2/start) "aHm" = (/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/obj/structure/closet/emcloset,/turf/simulated/floor/tiled/steel,/area/hangar/two) @@ -1758,7 +1758,7 @@ "aHP" = (/turf/simulated/floor/tiled,/area/tcomm/entrance) "aHQ" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/shuttle/wall/voidcraft/hard_corner,/area/shuttle/shuttle2/start) "aHR" = (/obj/machinery/teleport/station,/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled/techfloor,/area/tcomm/entrance) -"aHS" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) +"aHS" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle2/start) "aHT" = (/obj/machinery/teleport/hub,/obj/effect/floor_decal/industrial/hatch/yellow,/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/tiled/techfloor,/area/tcomm/entrance) "aHU" = (/turf/simulated/shuttle/wall/voidcraft/hard_corner,/area/shuttle/shuttle2/start) "aHV" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/shuttle/plating,/area/shuttle/shuttle2/start) @@ -1929,7 +1929,7 @@ "aLe" = (/obj/machinery/light/small{dir = 8},/obj/structure/ore_box,/turf/simulated/floor/plating,/area/maintenance/substation/firstdeck/cargo) "aLf" = (/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/plating,/area/maintenance/substation/firstdeck/cargo) "aLg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/floor_decal/industrial/warning,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/alarm{dir = 8; pixel_x = 22; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/substation/firstdeck/cargo) -"aLh" = (/obj/structure/closet/crate,/obj/item/weapon/storage/box/lights/mixed,/obj/item/stack/cable_coil/random,/obj/machinery/light_construct,/obj/machinery/light_construct,/turf/simulated/floor/plating,/area/maintenance/firstdeck/aftport) +"aLh" = (/obj/structure/extinguisher_cabinet{pixel_x = 25},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/obj/random/crate,/turf/simulated/floor/tiled,/area/hangar/two) "aLi" = (/obj/machinery/door/airlock{name = "Emergency Storage"},/turf/simulated/floor/plating,/area/maintenance/firstdeck/aftport) "aLj" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{req_access = list(12)},/turf/simulated/floor/plating,/area/storage/emergency_storage/firstdeck/ap_emergency) "aLk" = (/obj/structure/catwalk,/turf/simulated/floor/plating,/area/storage/emergency_storage/firstdeck/ap_emergency) @@ -1993,7 +1993,7 @@ "aMq" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/powered/scrubber,/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/steel_dirty,/area/engineering/auxiliary_engineering) "aMr" = (/obj/machinery/atmospherics/pipe/simple/hidden/red{dir = 10; icon_state = "intact"},/obj/machinery/alarm{pixel_y = 22},/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/steel_dirty,/area/engineering/auxiliary_engineering) "aMs" = (/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/steel_dirty,/area/engineering/auxiliary_engineering) -"aMt" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle2/start) +"aMt" = (/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/green/border{dir = 8},/obj/random/crate,/turf/simulated/floor/tiled,/area/hangar/two) "aMu" = (/obj/machinery/space_heater,/turf/simulated/floor/tiled/steel_dirty,/area/engineering/auxiliary_engineering) "aMv" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/machinery/atmospherics/portables_connector,/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/tiled/white,/area/rnd/xenobiology/xenoflora_isolation) "aMw" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"},/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/steel_dirty,/area/engineering/auxiliary_engineering) @@ -2027,7 +2027,7 @@ "aMY" = (/obj/machinery/atmospherics/pipe/manifold/hidden/red,/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/steel_dirty,/area/engineering/auxiliary_engineering) "aMZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/red{icon_state = "intact"; dir = 4},/obj/structure/bed/chair/office/dark{dir = 4},/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/steel_dirty,/area/engineering/auxiliary_engineering) "aNa" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/red{icon_state = "intact"; dir = 4},/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/engineering/auxiliary_engineering) -"aNb" = (/turf/simulated/floor/reinforced,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 1},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/shuttle2/start) +"aNb" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8; icon_state = "propulsion_r"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) "aNc" = (/obj/machinery/atmospherics/pipe/simple/visible/red{icon_state = "intact"; dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor/tiled/steel_dirty,/area/engineering/auxiliary_engineering) "aNd" = (/obj/machinery/atmospherics/pipe/simple/visible/red{icon_state = "intact"; dir = 4},/obj/machinery/space_heater,/turf/simulated/floor/tiled/steel_dirty,/area/engineering/auxiliary_engineering) "aNe" = (/obj/machinery/atmospherics/pipe/simple/visible/red{icon_state = "intact"; dir = 10},/obj/effect/floor_decal/rust,/turf/simulated/floor/tiled/steel_dirty,/area/engineering/auxiliary_engineering) @@ -2271,7 +2271,7 @@ "aRI" = (/turf/simulated/floor/airless,/area/hallway/secondary/escape/firstdeck/ep_aftport) "aRJ" = (/turf/simulated/shuttle/wall,/area/shuttle/escape_pod3/station) "aRK" = (/turf/simulated/shuttle/wall/no_join{base_state = "orange"; icon = 'icons/turf/shuttle_orange.dmi'; icon_state = "orange"},/area/shuttle/escape_pod3/station) -"aRL" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{dir = 8; icon_state = "propulsion_r"},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/large_escape_pod1/station) +"aRL" = (/obj/item/weapon/storage/box/lights/mixed,/obj/item/stack/cable_coil/random,/obj/machinery/light_construct,/obj/machinery/light_construct,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/firstdeck/aftport) "aRM" = (/turf/simulated/wall,/area/hallway/secondary/escape/firstdeck/ep_aftport) "aRN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 8},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 9},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_aftport) "aRO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 9},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/firstdeck/ep_aftport) @@ -3510,7 +3510,7 @@ "bpz" = (/obj/machinery/atmospherics/valve/digital/open,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "bpA" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "bpB" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"},/obj/machinery/portable_atmospherics/powered/pump/filled,/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"bpC" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 4},/obj/machinery/meter,/obj/structure/closet/crate,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/random/maintenance/research,/obj/random/maintenance/cargo,/obj/random/maintenance/security,/obj/random/maintenance/security,/turf/simulated/floor/plating,/area/maintenance/security_starboard) +"bpC" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 4},/obj/machinery/meter,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/random/maintenance/research,/obj/random/maintenance/cargo,/obj/random/maintenance/security,/obj/random/maintenance/security,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "bpD" = (/obj/effect/floor_decal/corner/black/full,/obj/machinery/camera/network/engineering{c_tag = "Atmospherics Tank - Carbon Dioxide"; dir = 4},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/reinforced/carbon_dioxide,/area/engineering/atmos) "bpE" = (/obj/effect/floor_decal/corner/black/full{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "co2_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0; use_power = 1},/turf/simulated/floor/reinforced/carbon_dioxide,/area/engineering/atmos) "bpF" = (/obj/machinery/atmospherics/pipe/simple/visible/green{icon_state = "intact"; dir = 4},/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/obj/machinery/meter,/obj/machinery/door/blast/regular{density = 0; dir = 1; icon_state = "pdoor0"; id = "atmoslockdown"; name = "Atmospherics Lockdown"; opacity = 0},/turf/simulated/floor,/area/engineering/atmos) @@ -4027,7 +4027,7 @@ "bzw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/monotile,/area/hallway/primary/seconddeck/fore) "bzx" = (/obj/effect/floor_decal/borderfloor/corner{dir = 4},/obj/effect/floor_decal/corner/red/bordercorner{dir = 4},/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/fore) "bzy" = (/obj/machinery/door/firedoor/glass,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass_medical{name = "First-Aid Station"; req_one_access = list(5,12,19)},/turf/simulated/floor/tiled/white,/area/medical/first_aid_station/seconddeck/fore) -"bzz" = (/obj/structure/closet/crate,/obj/random/maintenance/research,/obj/random/maintenance/research,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor/plating,/area/maintenance/research) +"bzz" = (/obj/random/maintenance/research,/obj/random/maintenance/research,/obj/random/medical,/obj/random/medical/lite,/obj/random/bomb_supply,/obj/random/bomb_supply,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/research) "bzA" = (/obj/structure/closet/jcloset,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/weapon/soap/nanotrasen,/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/purple/border{dir = 8},/turf/simulated/floor/tiled,/area/janitor) "bzB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/tiled,/area/janitor) "bzC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/janitor) @@ -4115,7 +4115,7 @@ "bBg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/research) "bBh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research) "bBi" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor/plating,/area/maintenance/research) -"bBj" = (/obj/structure/closet/crate/plastic,/obj/random/maintenance/research,/obj/random/maintenance/research,/obj/random/medical,/obj/random/medical/lite,/obj/random/bomb_supply,/obj/random/bomb_supply,/turf/simulated/floor/plating,/area/maintenance/research) +"bBj" = (/obj/random/maintenance/research,/obj/random/maintenance/research,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/research) "bBk" = (/obj/structure/closet,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/random/maintenance/security,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/research,/turf/simulated/floor/plating,/area/maintenance/research) "bBl" = (/turf/simulated/wall/r_wall,/area/crew_quarters/heads/sc/hor) "bBm" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/research) @@ -5131,7 +5131,7 @@ "bUI" = (/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/navbeacon/patrol{location = "CH11"; next_patrol = "CH12"},/turf/simulated/floor/tiled/dark,/area/hallway/primary/seconddeck/fscenter) "bUJ" = (/obj/structure/flora/ausbushes/sparsegrass,/obj/structure/flora/ausbushes/brflowers,/turf/simulated/floor/grass,/area/hallway/primary/seconddeck/fscenter) "bUK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/research) -"bUL" = (/obj/structure/closet/crate,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/research,/obj/random/maintenance/research,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/turf/simulated/floor/plating,/area/maintenance/research) +"bUL" = (/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/research,/obj/random/maintenance/research,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/research) "bUM" = (/obj/machinery/r_n_d/protolathe,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/rnd/lab) "bUN" = (/turf/simulated/floor/tiled,/area/rnd/lab) "bUO" = (/obj/machinery/r_n_d/destructive_analyzer,/obj/effect/floor_decal/industrial/outline/yellow,/turf/simulated/floor/tiled,/area/rnd/lab) @@ -5501,7 +5501,7 @@ "cbO" = (/obj/structure/flora/ausbushes/fullgrass,/turf/simulated/floor/grass,/area/hallway/primary/seconddeck/fscenter) "cbP" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/machinery/camera/network/second_deck{c_tag = "Second Deck - Center Two"; dir = 8},/turf/simulated/floor/grass,/area/hallway/primary/seconddeck/fscenter) "cbQ" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/maintenance/research) -"cbR" = (/obj/structure/closet/crate,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/powercell,/obj/random/powercell,/obj/random/powercell,/turf/simulated/floor/plating,/area/maintenance/research) +"cbR" = (/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/powercell,/obj/random/powercell,/obj/random/powercell,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/research) "cbS" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/clipboard,/obj/item/weapon/folder/white,/obj/item/weapon/pen,/obj/machinery/newscaster{pixel_x = -30; pixel_y = 0},/obj/structure/table/glass,/obj/effect/floor_decal/borderfloorwhite{dir = 10},/obj/effect/floor_decal/corner/purple/border{dir = 10},/turf/simulated/floor/tiled/white,/area/rnd/lab) "cbT" = (/obj/item/weapon/folder/white,/obj/item/weapon/disk/tech_disk{pixel_x = 0; pixel_y = 0},/obj/item/weapon/disk/tech_disk{pixel_x = 0; pixel_y = 0},/obj/item/weapon/disk/design_disk,/obj/item/weapon/disk/design_disk,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/structure/table/glass,/obj/effect/floor_decal/borderfloorwhite,/obj/effect/floor_decal/corner/purple/border,/turf/simulated/floor/tiled/white,/area/rnd/lab) "cbU" = (/obj/machinery/recharger{pixel_y = 0},/obj/item/weapon/stock_parts/console_screen,/obj/item/weapon/stock_parts/console_screen,/obj/item/weapon/stock_parts/console_screen,/obj/item/weapon/stock_parts/matter_bin,/obj/item/weapon/stock_parts/matter_bin,/obj/item/weapon/stock_parts/micro_laser,/obj/item/weapon/stock_parts/micro_laser,/obj/machinery/ai_status_display{pixel_y = -32},/obj/structure/table/glass,/obj/effect/floor_decal/borderfloorwhite,/obj/effect/floor_decal/corner/purple/border,/turf/simulated/floor/tiled/white,/area/rnd/lab) @@ -5582,13 +5582,13 @@ "cdr" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/machinery/recharge_station,/obj/machinery/camera/network/research{c_tag = "SCI - Mech Bay"; dir = 8},/obj/structure/extinguisher_cabinet{pixel_y = -30},/obj/machinery/ai_status_display{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/tiled/techmaint,/area/assembly/chargebay) "cds" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/maintenance/research_medical) "cdt" = (/turf/simulated/wall/r_wall,/area/maintenance/research_medical) -"cdu" = (/obj/structure/closet/crate,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/random/powercell,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tool,/turf/simulated/floor/plating,/area/maintenance/research_medical) +"cdu" = (/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/item/stack/tile/floor/white,/obj/random/powercell,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tool,/turf/simulated/floor/plating,/area/maintenance/research_medical) "cdv" = (/turf/simulated/floor/plating,/area/maintenance/research_medical) "cdw" = (/obj/item/stack/cable_coil,/turf/simulated/floor/plating,/area/maintenance/research_medical) "cdx" = (/obj/structure/table/rack{dir = 1},/obj/random/maintenance/research,/obj/random/maintenance/research,/obj/random/maintenance/clean,/obj/item/stack/cable_coil,/obj/item/weapon/coin/silver,/turf/simulated/floor/plating,/area/maintenance/research_medical) "cdy" = (/obj/structure/table/rack{dir = 1},/obj/random/maintenance/research,/obj/random/maintenance/research,/obj/random/maintenance/clean,/turf/simulated/floor/plating,/area/maintenance/research_medical) "cdz" = (/obj/structure/table/glass,/obj/machinery/alarm{dir = 4; pixel_x = -22; pixel_y = 0},/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/purple/border{dir = 8},/turf/simulated/floor/tiled/white,/area/rnd/research/firstdeck/hallway) -"cdA" = (/obj/structure/closet/crate,/obj/random/bomb_supply,/obj/random/bomb_supply,/obj/random/bomb_supply,/obj/random/tech_supply,/obj/random/technology_scanner,/obj/random/tool,/turf/simulated/floor/plating,/area/maintenance/research_medical) +"cdA" = (/obj/random/bomb_supply,/obj/random/bomb_supply,/obj/random/bomb_supply,/obj/random/tech_supply,/obj/random/technology_scanner,/obj/random/tool,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/research_medical) "cdB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/tiled/white,/area/rnd/research/firstdeck/hallway) "cdC" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/white,/area/rnd/research/firstdeck/hallway) "cdD" = (/obj/machinery/camera/network/research{c_tag = "SCI - Research Hallway Aft"; dir = 8},/obj/effect/floor_decal/borderfloorwhite/corner{dir = 4},/obj/effect/floor_decal/corner/purple/bordercorner{dir = 4},/turf/simulated/floor/tiled/white,/area/rnd/research) @@ -5634,7 +5634,7 @@ "cer" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/machinery/door/blast/regular{density = 0; dir = 1; icon_state = "pdoor0"; id = "englockdown"; name = "Engineering Lockdown"; opacity = 0},/obj/structure/sign/warning/secure_area{pixel_x = 32},/turf/simulated/floor/tiled/dark,/area/hallway/primary/seconddeck/port) "ces" = (/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/engineering) "cet" = (/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/maintenance/engineering) -"ceu" = (/obj/structure/closet/crate,/obj/item/weapon/tank/emergency/oxygen/engi,/obj/item/weapon/tank/emergency/oxygen/double,/obj/random/maintenance/engineering,/obj/random/maintenance/engineering,/obj/random/maintenance/engineering,/obj/random/maintenance/engineering,/turf/simulated/floor/plating,/area/maintenance/engineering) +"ceu" = (/obj/item/weapon/tank/emergency/oxygen/engi,/obj/item/weapon/tank/emergency/oxygen/double,/obj/random/maintenance/engineering,/obj/random/maintenance/engineering,/obj/random/maintenance/engineering,/obj/random/maintenance/engineering,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/engineering) "cev" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/engineering{name = "Utility Down"; req_one_access = list(11,24)},/turf/simulated/floor/plating,/area/maintenance/engineering) "cew" = (/obj/structure/disposalpipe/broken{dir = 1},/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/engineering) "cex" = (/obj/machinery/vending/coffee{dir = 4},/turf/simulated/floor/tiled/hydro,/area/hallway/primary/seconddeck/fpcenter) @@ -6354,7 +6354,7 @@ "csj" = (/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/apcenter) "csk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/monotile,/area/hallway/primary/seconddeck/apcenter) "csl" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/apcenter) -"csm" = (/obj/machinery/atmospherics/pipe/simple/visible/universal,/obj/effect/decal/cleanable/dirt,/obj/structure/closet/crate,/obj/random/maintenance/medical,/obj/random/maintenance/research,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/cargo,/turf/simulated/floor/plating,/area/maintenance/central) +"csm" = (/obj/machinery/atmospherics/pipe/simple/visible/universal,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/medical,/obj/random/maintenance/research,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/cargo,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/central) "csn" = (/obj/machinery/atmospherics/pipe/simple/visible/universal,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/central) "cso" = (/obj/machinery/lapvend,/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/stairwell) "csp" = (/obj/structure/table/glass,/obj/machinery/firealarm{pixel_y = 24},/obj/machinery/recharger{pixel_y = 0},/obj/machinery/camera/network/second_deck{c_tag = "Second Deck - Center Stair Access"; dir = 2},/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/stairwell) @@ -6809,7 +6809,7 @@ "cAW" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/tiled,/area/quartermaster/qm) "cAX" = (/obj/machinery/disposal,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/obj/structure/disposalpipe/trunk,/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/brown/border{dir = 4},/turf/simulated/floor/tiled,/area/quartermaster/qm) "cAY" = (/obj/random/obstruction,/turf/simulated/floor/plating,/area/maintenance/bar) -"cAZ" = (/obj/structure/closet/crate,/obj/item/weapon/tank/emergency/oxygen/engi,/obj/item/weapon/tank/emergency/oxygen/double,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/bar) +"cAZ" = (/obj/item/weapon/tank/emergency/oxygen/engi,/obj/item/weapon/tank/emergency/oxygen/double,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/machinery/light/small{dir = 1},/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/bar) "cBa" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/bar) "cBb" = (/turf/simulated/floor/plating,/area/maintenance/bar) "cBc" = (/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor/plating,/area/maintenance/bar) @@ -6888,7 +6888,7 @@ "cCx" = (/obj/effect/floor_decal/borderfloor/corner{dir = 8},/obj/effect/floor_decal/corner/brown/bordercorner{dir = 8},/turf/simulated/floor/tiled,/area/quartermaster/qm) "cCy" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled,/area/quartermaster/qm) "cCz" = (/obj/structure/closet/secure_closet/quartermaster,/obj/structure/disposalpipe/segment,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 22},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/brown/border{dir = 4},/turf/simulated/floor/tiled,/area/quartermaster/qm) -"cCA" = (/obj/structure/closet/crate,/obj/item/clothing/gloves/boxing/green,/obj/item/clothing/gloves/boxing,/turf/simulated/floor/plating,/area/maintenance/bar) +"cCA" = (/obj/item/clothing/gloves/boxing/green,/obj/item/clothing/gloves/boxing,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/bar) "cCB" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/table/steel,/obj/random/medical,/obj/random/medical/lite,/obj/random/medical/lite,/turf/simulated/floor/plating,/area/maintenance/bar) "cCC" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/bar) "cCD" = (/obj/structure/flora/ausbushes/lavendergrass,/obj/structure/flora/ausbushes/brflowers,/turf/simulated/floor/grass,/area/hallway/primary/seconddeck/apcenter) @@ -6912,7 +6912,7 @@ "cCV" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/obj/machinery/navbeacon/patrol{location = "CH8"; next_patrol = "CH9"},/turf/simulated/floor/tiled/dark,/area/hallway/primary/seconddeck/ascenter) "cCW" = (/obj/effect/floor_decal/borderfloor/corner,/obj/effect/floor_decal/corner/green/bordercorner,/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/ascenter) "cCX" = (/obj/structure/flora/ausbushes/fullgrass,/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/grass,/area/hallway/primary/seconddeck/ascenter) -"cCY" = (/obj/structure/closet/crate,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/medical,/obj/random/medical,/turf/simulated/floor/plating,/area/maintenance/medbay) +"cCY" = (/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/random/medical,/obj/random/medical,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/medbay) "cCZ" = (/obj/structure/closet/secure_closet/medical1,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/machinery/light_switch{pixel_x = -36},/obj/random/medical,/obj/random/medical,/obj/random/medical,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/status_display{pixel_x = 0; pixel_y = -32},/turf/simulated/floor/tiled/dark,/area/medical/medbay_emt_bay) "cDa" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/effect/floor_decal/borderfloorwhite{dir = 8},/obj/effect/floor_decal/corner/pink/border{dir = 8},/obj/effect/floor_decal/borderfloorwhite/corner2{dir = 10},/obj/effect/floor_decal/corner/pink/bordercorner2{dir = 10},/turf/simulated/floor/tiled/white,/area/medical/medbay_emt_bay) "cDb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/floor_decal/borderfloorwhite{dir = 4},/obj/effect/floor_decal/corner/pink/border{dir = 4},/obj/effect/floor_decal/borderfloorwhite/corner2{dir = 5},/obj/effect/floor_decal/corner/pink/bordercorner2{dir = 5},/turf/simulated/floor/tiled/white,/area/medical/medbay_emt_bay) @@ -7037,12 +7037,12 @@ "cFq" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Disposal Access"; req_access = list(12)},/turf/simulated/floor,/area/maintenance/disposal) "cFr" = (/obj/structure/disposalpipe/segment,/obj/machinery/vending/medical,/turf/simulated/wall,/area/medical/medbay_primary_storage) "cFs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/turf/simulated/floor,/area/maintenance/cargo) -"cFt" = (/obj/structure/closet/crate,/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/turf/simulated/floor,/area/maintenance/cargo) +"cFt" = (/obj/random/maintenance/engineering,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/crate,/turf/simulated/floor,/area/maintenance/cargo) "cFu" = (/obj/random/obstruction,/turf/simulated/floor/plating,/area/maintenance/cargo) "cFv" = (/obj/effect/floor_decal/corner/brown/full{dir = 8},/obj/structure/table/rack{dir = 8; layer = 2.9},/turf/simulated/floor/tiled/steel,/area/maintenance/cargo) "cFw" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/turf/simulated/floor/tiled/steel,/area/maintenance/cargo) "cFx" = (/turf/simulated/floor/tiled/steel,/area/maintenance/cargo) -"cFy" = (/obj/structure/disposalpipe/sortjunction/untagged{dir = 1},/obj/effect/decal/cleanable/cobweb,/obj/structure/closet/crate,/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/brown/border{dir = 8},/turf/simulated/floor/tiled/steel,/area/quartermaster/warehouse) +"cFy" = (/obj/structure/disposalpipe/sortjunction/untagged{dir = 1},/obj/effect/decal/cleanable/cobweb,/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/brown/border{dir = 8},/obj/random/crate,/turf/simulated/floor/tiled/steel,/area/quartermaster/warehouse) "cFz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 9},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 4},/turf/simulated/floor/tiled/steel,/area/quartermaster/warehouse) "cFA" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/alarm{pixel_y = 23},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/brown/border{dir = 4},/turf/simulated/floor/tiled/steel,/area/quartermaster/warehouse) "cFB" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/quartermaster/delivery) @@ -7118,7 +7118,7 @@ "cGT" = (/turf/simulated/wall,/area/maintenance/cargo) "cGU" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/effect/floor_decal/corner/brown/full{dir = 8},/turf/simulated/floor/tiled/steel,/area/maintenance/cargo) "cGV" = (/obj/effect/floor_decal/corner/brown{dir = 1},/turf/simulated/floor/tiled/steel,/area/maintenance/cargo) -"cGW" = (/obj/structure/disposalpipe/tagger/partial{dir = 1; name = "Sorting Office"; sort_tag = "Sorting Office"},/obj/structure/closet/crate,/obj/structure/extinguisher_cabinet{pixel_x = -28; pixel_y = 0},/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/brown/border{dir = 8},/turf/simulated/floor/tiled,/area/quartermaster/warehouse) +"cGW" = (/obj/structure/disposalpipe/tagger/partial{dir = 1; name = "Sorting Office"; sort_tag = "Sorting Office"},/obj/structure/extinguisher_cabinet{pixel_x = -28; pixel_y = 0},/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/brown/border{dir = 8},/obj/random/crate,/turf/simulated/floor/tiled,/area/quartermaster/warehouse) "cGX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/steel,/area/quartermaster/warehouse) "cGY" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/effect/floor_decal/borderfloor/corner{dir = 4},/obj/effect/floor_decal/corner/brown/bordercorner{dir = 4},/turf/simulated/floor/tiled/steel,/area/quartermaster/warehouse) "cGZ" = (/obj/machinery/light/small{dir = 1},/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/brown/border{dir = 1},/turf/simulated/floor/tiled/steel,/area/quartermaster/warehouse) @@ -7213,7 +7213,7 @@ "cIK" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/cargo) "cIL" = (/obj/effect/floor_decal/corner/brown{dir = 1},/obj/item/frame/light/small,/turf/simulated/floor/tiled,/area/maintenance/cargo) "cIM" = (/turf/simulated/floor/plating,/area/maintenance/cargo) -"cIN" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/closet/crate,/obj/machinery/camera/network/cargo{c_tag = "CRG - Cargo Warehouse"; dir = 4; name = "security camera"},/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/brown/border{dir = 8},/turf/simulated/floor/tiled,/area/quartermaster/warehouse) +"cIN" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/camera/network/cargo{c_tag = "CRG - Cargo Warehouse"; dir = 4; name = "security camera"},/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/brown/border{dir = 8},/obj/random/crate,/turf/simulated/floor/tiled,/area/quartermaster/warehouse) "cIO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/tiled,/area/quartermaster/warehouse) "cIP" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled,/area/quartermaster/warehouse) "cIQ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/tiled,/area/quartermaster/warehouse) @@ -7448,7 +7448,7 @@ "cNl" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plating,/area/maintenance/substation/cargo) "cNm" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/power/sensor{name = "Powernet Sensor - Cargo Subgrid"; name_tag = "Cargo Subgrid"},/obj/machinery/alarm{pixel_y = 22},/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/plating,/area/maintenance/substation/cargo) "cNn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/effect/floor_decal/industrial/warning,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/obj/structure/railing,/turf/simulated/floor/plating,/area/maintenance/substation/cargo) -"cNo" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/obj/structure/closet/crate,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/item/weapon/material/knife,/obj/item/weapon/storage/mre/random,/turf/simulated/floor/plating,/area/maintenance/bar) +"cNo" = (/obj/random/contraband,/obj/random/contraband,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/cargo) "cNp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/table/steel,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/maintenance/engineering,/obj/random/tool/powermaint,/turf/simulated/floor/tiled/steel,/area/construction/seconddeck/construction1) "cNq" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/maintenance/engineering) "cNr" = (/obj/machinery/door/firedoor/border_only,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock{name = "Emergency Storage"},/turf/simulated/floor/plating,/area/storage/emergency_storage/seconddeck/ap_emergency) @@ -7569,7 +7569,7 @@ "cPC" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor,/area/maintenance/cargo) "cPD" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "crg_aft_pump"},/obj/machinery/light/small{dir = 4; pixel_y = 0},/obj/effect/floor_decal/industrial/warning{dir = 6},/turf/simulated/floor,/area/maintenance/cargo) "cPE" = (/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor/plating,/area/maintenance/cargo) -"cPF" = (/obj/structure/closet/crate,/obj/random/contraband,/obj/random/contraband,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/turf/simulated/floor/plating,/area/maintenance/cargo) +"cPF" = (/obj/random/toy,/obj/random/plushie,/obj/random/plushie,/obj/random/action_figure,/obj/machinery/alarm{pixel_y = 22},/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/medbay) "cPG" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Cargo Maintenance"; req_access = list(50)},/turf/simulated/floor/plating,/area/quartermaster/office) "cPH" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/machinery/navbeacon/delivery/north{location = "QM #1"},/mob/living/bot/mulebot,/turf/simulated/floor/tiled,/area/quartermaster/office) "cPI" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/machinery/navbeacon/delivery/north{location = "QM #2"},/mob/living/bot/mulebot,/turf/simulated/floor/tiled,/area/quartermaster/office) @@ -7599,7 +7599,7 @@ "cQg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/medbay) "cQh" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/inflatable/door/torn,/turf/simulated/floor/plating,/area/maintenance/engineering) "cQi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor/plating,/area/maintenance/engineering) -"cQj" = (/obj/structure/closet/crate,/obj/random/toy,/obj/random/plushie,/obj/random/plushie,/obj/random/action_figure,/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor/plating,/area/maintenance/medbay) +"cQj" = (/obj/random/drinkbottle,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/action_figure,/obj/random/plushie,/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/bar) "cQk" = (/obj/structure/table/steel,/obj/item/device/t_scanner,/obj/random/tech_supply,/obj/random/tech_supply,/obj/machinery/alarm{pixel_y = 23},/obj/random/cash,/turf/simulated/floor/plating,/area/maintenance/bar) "cQl" = (/obj/structure/table/steel,/obj/item/weapon/storage/box/lights/mixed,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/turf/simulated/floor/plating,/area/maintenance/medbay) "cQm" = (/obj/structure/closet/hydrant{pixel_y = -32},/obj/item/clothing/glasses/meson,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/storage/emergency_storage/seconddeck/as_emergency) @@ -7634,7 +7634,7 @@ "cQP" = (/obj/structure/table/steel,/obj/machinery/cell_charger,/obj/item/clothing/head/soft,/obj/item/clothing/head/soft,/obj/machinery/light,/turf/simulated/floor/tiled/dark,/area/quartermaster/office) "cQQ" = (/obj/structure/table/steel,/obj/machinery/recharger,/obj/item/weapon/stamp{pixel_x = -3; pixel_y = 3},/obj/item/weapon/hand_labeler,/turf/simulated/floor/tiled/dark,/area/quartermaster/office) "cQR" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/glass_medical{name = "Patient Ward"},/turf/simulated/floor/tiled/steel_grid,/area/medical/patient_wing) -"cQS" = (/obj/structure/closet/crate,/obj/random/drinkbottle,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/action_figure,/obj/random/plushie,/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/turf/simulated/floor/plating,/area/maintenance/bar) +"cQS" = (/obj/random/maintenance/cargo,/obj/random/maintenance,/obj/random/maintenance,/obj/random/maintenance/clean,/obj/structure/catwalk,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/bar) "cQT" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor/plating,/area/maintenance/bar) "cQU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/turf/simulated/floor/plating,/area/maintenance/bar) "cQV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/bar) @@ -7646,7 +7646,7 @@ "cRb" = (/obj/structure/closet/gmcloset{name = "formal wardrobe"},/obj/item/glass_jar,/obj/item/device/retail_scanner/civilian,/obj/item/device/retail_scanner/civilian,/obj/machinery/camera/network/civilian{c_tag = "CIV - Bar Storage"; dir = 2},/obj/machinery/firealarm{pixel_y = 24},/obj/item/clothing/head/that{pixel_x = 4; pixel_y = 6},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/wood,/area/crew_quarters/bar) "cRc" = (/obj/machinery/smartfridge/drinks,/obj/machinery/light{dir = 1},/turf/simulated/floor/lino,/area/crew_quarters/bar) "cRd" = (/obj/machinery/light/small,/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/bar) -"cRe" = (/obj/structure/closet/crate,/obj/random/maintenance/cargo,/obj/random/maintenance,/obj/random/maintenance,/obj/random/maintenance/clean,/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/bar) +"cRe" = (/obj/effect/floor_decal/industrial/warning/corner{icon_state = "warningcorner"; dir = 1},/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/item/weapon/material/knife,/obj/item/weapon/storage/mre/random,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/bar) "cRf" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 8},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 5},/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/apcenter) "cRg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light,/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/apcenter) "cRh" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 8},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 5},/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/apcenter) @@ -7874,7 +7874,7 @@ "cVv" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_medical{name = "Patient Ward"; req_access = list(5)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/steel_grid,/area/medical/patient_wing) "cVw" = (/turf/simulated/wall/r_wall,/area/medical/patient_wing) "cVx" = (/obj/structure/closet/wardrobe/grey,/obj/item/weapon/storage/backpack,/obj/item/weapon/storage/backpack,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/turf/simulated/floor/plating,/area/maintenance/cargo) -"cVy" = (/obj/structure/closet/crate,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/drinkbottle,/turf/simulated/floor/plating,/area/maintenance/cargo) +"cVy" = (/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/drinkbottle,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/cargo) "cVz" = (/obj/item/weapon/material/ashtray/glass,/obj/structure/table/steel,/turf/simulated/floor/plating,/area/maintenance/cargo) "cVA" = (/obj/structure/bed/chair/comfy/beige,/turf/simulated/floor/plating,/area/maintenance/cargo) "cVB" = (/obj/structure/table/steel,/obj/item/weapon/reagent_containers/food/drinks/glass2/rocks,/obj/item/weapon/reagent_containers/food/drinks/glass2/rocks,/turf/simulated/floor/plating,/area/maintenance/cargo) @@ -7964,7 +7964,7 @@ "cXh" = (/obj/structure/disposalpipe/segment,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable,/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/green/border{dir = 8},/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/aft) "cXi" = (/obj/structure/extinguisher_cabinet{pixel_x = 28; pixel_y = 0},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/aft) "cXj" = (/obj/item/weapon/stool/padded,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/carpet,/area/crew_quarters/sleep/vistor_room_1) -"cXk" = (/obj/random/contraband,/obj/random/contraband,/obj/structure/closet/crate,/obj/random/contraband,/turf/simulated/floor/plating,/area/maintenance/medbay) +"cXk" = (/obj/random/contraband,/obj/random/contraband,/obj/random/contraband,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/medbay) "cXl" = (/obj/machinery/meter,/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/medbay) "cXm" = (/obj/effect/floor_decal/industrial/warning{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 1},/turf/simulated/floor/plating,/area/maintenance/medbay) "cXn" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "medbayquar"; name = "Medbay Emergency Lockdown Shutters"; opacity = 0},/obj/machinery/atmospherics/valve{dir = 4},/turf/simulated/floor/plating,/area/maintenance/medbay) @@ -8032,7 +8032,7 @@ "cYx" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock{name = "Unisex Restrooms"},/obj/structure/cable/green{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/steel_grid,/area/crew_quarters/locker/locker_toilet) "cYy" = (/obj/item/device/radio/intercom{desc = "Talk... listen through this."; dir = 2; name = "Station Intercom (Brig Radio)"; pixel_x = 0; pixel_y = -21; wires = 7},/obj/structure/closet/secure_closet/personal,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/carpet,/area/crew_quarters/sleep/vistor_room_1) "cYz" = (/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,/turf/simulated/floor/carpet,/area/crew_quarters/sleep/vistor_room_1) -"cYA" = (/obj/structure/closet/crate,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/contraband,/turf/simulated/floor/plating,/area/maintenance/medbay) +"cYA" = (/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/contraband,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/medbay) "cYB" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 1; start_pressure = 4559.63},/obj/machinery/light/small,/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/medbay) "cYC" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/closet/secure_closet/personal,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/light_switch{pixel_x = 11; pixel_y = -24},/turf/simulated/floor/carpet,/area/crew_quarters/sleep/vistor_room_1) "cYD" = (/obj/item/device/radio/intercom{desc = "Talk... listen through this."; dir = 2; name = "Station Intercom (Brig Radio)"; pixel_x = 0; pixel_y = -21; wires = 7},/obj/structure/closet/secure_closet/personal,/obj/item/clothing/head/kitty,/obj/item/clothing/head/kitty,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/carpet,/area/crew_quarters/sleep/vistor_room_2) @@ -8095,7 +8095,7 @@ "cZI" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/tiled/steel_grid,/area/crew_quarters/locker) "cZJ" = (/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/green/border{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on,/obj/effect/floor_decal/borderfloor/corner2{dir = 4},/obj/effect/floor_decal/corner/green/bordercorner2{dir = 4},/turf/simulated/floor/tiled,/area/crew_quarters/locker) "cZK" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"cZL" = (/obj/machinery/cooker/fryer,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"cZL" = (/obj/machinery/appliance/cooker/fryer,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "cZM" = (/obj/effect/floor_decal/borderfloor/corner{dir = 1},/obj/effect/floor_decal/corner/green/bordercorner{dir = 1},/obj/machinery/firealarm{dir = 2; layer = 3.3; pixel_x = 0; pixel_y = 26},/turf/simulated/floor/tiled,/area/crew_quarters/locker) "cZN" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 4},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 9},/turf/simulated/floor/tiled,/area/crew_quarters/locker) "cZO" = (/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/green/border{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor/tiled,/area/crew_quarters/locker) @@ -8130,7 +8130,7 @@ "dar" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{req_access = null; req_one_access = list(5,12,25,27,28,35)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/crew_quarters/locker) "das" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/locker) "dat" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/locker) -"dau" = (/obj/machinery/cooker/candy,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"dau" = (/obj/machinery/appliance/mixer/candy,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "dav" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "daw" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/closet,/obj/random/maintenance,/obj/random/maintenance,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/turf/simulated/floor/plating,/area/maintenance/bar) "dax" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/crew_quarters/kitchen) @@ -8186,7 +8186,7 @@ "dbv" = (/obj/effect/floor_decal/borderfloor,/obj/effect/floor_decal/corner/green/border,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/effect/floor_decal/borderfloor/corner2{dir = 9},/obj/effect/floor_decal/corner/green/bordercorner2{dir = 9},/turf/simulated/floor/tiled,/area/crew_quarters/locker) "dbw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/bar) "dbx" = (/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/bar) -"dby" = (/obj/machinery/cooker/cereal,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/ai_status_display{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"dby" = (/obj/machinery/appliance/mixer/cereal,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/ai_status_display{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "dbz" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 10; icon_state = "intact"},/obj/machinery/floodlight,/turf/simulated/floor/plating,/area/maintenance/bar) "dbA" = (/obj/item/weapon/stool/padded,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/effect/landmark/start{name = "Chef"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "dbB" = (/obj/structure/table/marble,/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 = 4},/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 5},/obj/item/weapon/reagent_containers/food/condiment/enzyme,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) @@ -8257,7 +8257,7 @@ "dcO" = (/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/crew_quarters/locker) "dcP" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 9},/turf/simulated/floor/plating,/area/maintenance/bar) "dcQ" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/reagentgrinder,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"dcR" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/obj/machinery/light/small{dir = 4; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 4},/obj/structure/closet/crate,/obj/item/weapon/reagent_containers/food/drinks/flask/barflask,/obj/random/powercell,/obj/random/maintenance,/obj/random/maintenance/clean,/turf/simulated/floor/plating,/area/maintenance/bar) +"dcR" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/item/weapon/storage/mre/random,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/locker) "dcS" = (/obj/machinery/light,/obj/effect/floor_decal/borderfloorwhite,/obj/effect/floor_decal/corner/paleblue/border,/obj/structure/closet/medical_wall{pixel_x = 0; pixel_y = -31},/obj/item/roller,/obj/item/bodybag/cryobag,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/pill_bottle/spaceacillin,/turf/simulated/floor/tiled/white,/area/medical/first_aid_station/seconddeck/fore) "dcT" = (/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},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "dcU" = (/obj/machinery/washing_machine,/turf/simulated/floor/tiled/dark,/area/crew_quarters/locker) @@ -8316,7 +8316,7 @@ "ddV" = (/obj/machinery/ai_status_display{pixel_y = -32},/obj/effect/floor_decal/borderfloorwhite,/obj/effect/floor_decal/corner/pink/border,/turf/simulated/floor/tiled/white,/area/medical/surgery2) "ddW" = (/obj/machinery/camera/network/medbay{c_tag = "MED - Operating Theatre 2"; dir = 1},/obj/machinery/vending/wallmed1{pixel_y = -30},/obj/effect/floor_decal/borderfloorwhite{dir = 6},/obj/effect/floor_decal/corner/pink/border{dir = 6},/obj/structure/closet/secure_closet/medical_wall/anesthetics{pixel_x = 32},/turf/simulated/floor/tiled/white,/area/medical/surgery2) "ddX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/bar) -"ddY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/closet/crate/plastic,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/item/weapon/storage/mre/random,/turf/simulated/floor/plating,/area/maintenance/locker) +"ddY" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/obj/machinery/light/small{dir = 4; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 4},/obj/item/weapon/reagent_containers/food/drinks/flask/barflask,/obj/random/powercell,/obj/random/maintenance,/obj/random/maintenance/clean,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/bar) "ddZ" = (/turf/simulated/floor/reinforced{name = "Holodeck Projector Floor"},/area/holodeck/alphadeck) "dea" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/catwalk,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/locker) "deb" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/camera/network/civilian{c_tag = "CIV - Cafeteria Port"; dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/cafeteria) @@ -8345,11 +8345,11 @@ "dey" = (/obj/effect/floor_decal/borderfloor/corner{dir = 4},/obj/effect/floor_decal/corner/green/bordercorner{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled,/area/crew_quarters/locker) "dez" = (/obj/effect/floor_decal/borderfloor{dir = 1},/obj/effect/floor_decal/corner/green/border{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor/tiled,/area/crew_quarters/locker) "deA" = (/obj/effect/floor_decal/borderfloor/corner{dir = 1},/obj/effect/floor_decal/corner/green/bordercorner{dir = 1},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/tiled,/area/crew_quarters/locker) -"deB" = (/obj/structure/closet/crate/plastic,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/turf/simulated/floor/plating,/area/maintenance/bar) -"deC" = (/obj/machinery/cooker/grill,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"deB" = (/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/bar) +"deC" = (/obj/machinery/appliance/cooker/grill,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "deD" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "deE" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 5},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 8},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"deF" = (/obj/machinery/cooker/oven,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/light,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"deF" = (/obj/machinery/appliance/cooker/oven,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/light,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "deG" = (/obj/structure/closet/lasertag/red,/obj/item/stack/flag/red,/obj/structure/window/reinforced,/turf/simulated/floor/tiled/dark,/area/crew_quarters/locker) "deH" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/wood,/area/crew_quarters/cafeteria) "deI" = (/obj/structure/flora/pottedplant,/obj/machinery/computer/guestpass{pixel_x = 0; pixel_y = -30},/turf/simulated/floor/wood,/area/crew_quarters/cafeteria) @@ -8361,7 +8361,7 @@ "deO" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/segment,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor,/area/maintenance/substation/command) "deP" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 1},/obj/effect/floor_decal/steeldecal/steel_decals4{dir = 6},/turf/simulated/floor/tiled,/area/crew_quarters/locker) "deQ" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/effect/floor_decal/borderfloor/corner{dir = 1},/obj/effect/floor_decal/corner/green/bordercorner{dir = 1},/turf/simulated/floor/tiled,/area/hallway/primary/seconddeck/aft) -"deR" = (/obj/structure/closet/crate/hydroponics,/obj/random/maintenance,/obj/random/maintenance,/obj/random/maintenance,/turf/simulated/floor/plating,/area/maintenance/bar) +"deR" = (/obj/random/maintenance,/obj/random/maintenance,/obj/random/maintenance,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/bar) "deS" = (/obj/machinery/smartfridge,/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/hydroponics) "deT" = (/turf/simulated/wall,/area/hydroponics) "deU" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/hydroponics) @@ -8907,7 +8907,7 @@ "dpo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/light{dir = 1},/obj/item/weapon/camera_assembly,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) "dpp" = (/obj/machinery/floodlight,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) "dpq" = (/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) -"dpr" = (/obj/item/clothing/gloves/rainbow,/obj/item/clothing/head/soft/rainbow,/obj/item/clothing/shoes/rainbow,/obj/item/clothing/under/color/rainbow,/obj/item/weapon/bedsheet/rainbow,/obj/item/weapon/pen/crayon/rainbow,/obj/structure/closet/crate,/turf/simulated/floor,/area/construction/seconddeck/construction2) +"dpr" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/cryo/station) "dps" = (/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"},/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/chapel) "dpt" = (/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod{frequency = 1380; id_tag = "cryostorage_shuttle"; name = "cryostorage controller"; pixel_x = -26; pixel_y = 0; req_access = list(19); tag_door = "cryostorage_shuttle_hatch"},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/shuttle/floor,/area/shuttle/cryo/station) "dpu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/green/border{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/docking_hallway2) @@ -8955,7 +8955,7 @@ "dqk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) "dql" = (/obj/structure/table/standard,/obj/item/weapon/towel,/obj/item/weapon/towel,/turf/simulated/floor/tiled/freezer,/area/construction/seconddeck/construction2) "dqm" = (/obj/structure/extinguisher_cabinet{pixel_x = 28; pixel_y = 0},/turf/simulated/floor/tiled/freezer,/area/construction/seconddeck/construction2) -"dqn" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/cryo/station) +"dqn" = (/obj/item/clothing/gloves/rainbow,/obj/item/clothing/head/soft/rainbow,/obj/item/clothing/shoes/rainbow,/obj/item/clothing/under/color/rainbow,/obj/item/weapon/bedsheet/rainbow,/obj/item/weapon/pen/crayon/rainbow,/obj/random/crate,/turf/simulated/floor,/area/construction/seconddeck/construction2) "dqo" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled/monotile,/area/hallway/primary/seconddeck/aft) "dqp" = (/obj/item/weapon/stool/padded,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) "dqq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/item/weapon/stool,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) @@ -9013,7 +9013,7 @@ "drq" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/tiled,/area/storage/primary) "drr" = (/obj/structure/table/standard,/obj/machinery/recharger{pixel_y = 0},/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/tiled,/area/storage/primary) "drs" = (/obj/machinery/computer/secure_data{dir = 4},/obj/item/device/radio/intercom/department/security{dir = 4; icon_override = "secintercom"; pixel_x = -21},/obj/effect/floor_decal/borderfloor{dir = 8},/obj/effect/floor_decal/corner/red/border{dir = 8},/turf/simulated/floor/tiled,/area/security/checkpoint2) -"drt" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/cryo/station) +"drt" = (/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/item/clothing/suit/storage/hazardvest,/obj/random/crate,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) "dru" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/hologram/holopad,/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled,/area/security/checkpoint2) "drv" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/red/border{dir = 4},/turf/simulated/floor/tiled,/area/security/checkpoint2) "drw" = (/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor/westleft{name = "Security Checkpoint"; req_access = list(1)},/obj/machinery/door/firedoor/glass,/turf/simulated/floor/tiled,/area/security/checkpoint2) @@ -9048,7 +9048,7 @@ "drZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled,/area/security/checkpoint2) "dsa" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/tool/crowbar,/obj/item/weapon/pen,/obj/item/device/flash,/obj/machinery/camera/network/security{c_tag = "SEC - Arrival Checkpoint"; dir = 8},/obj/machinery/light{dir = 4},/obj/effect/floor_decal/borderfloor{dir = 4},/obj/effect/floor_decal/corner/red/border{dir = 4},/turf/simulated/floor/tiled,/area/security/checkpoint2) "dsb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table/gamblingtable,/obj/item/weapon/deck/cards,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) -"dsc" = (/obj/structure/closet/crate,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/random/maintenance/clean,/obj/item/clothing/suit/storage/hazardvest,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) +"dsc" = (/turf/simulated/floor/airless,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 4},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/cryo/station) "dsd" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air/airlock,/obj/effect/floor_decal/industrial/outline/yellow,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/chapel) "dse" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/turf/simulated/floor/plating,/area/maintenance/chapel) "dsf" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Firefighting equipment"; req_access = list(12)},/turf/simulated/floor/plating,/area/maintenance/chapel) @@ -9578,7 +9578,7 @@ "dCj" = (/obj/machinery/alarm{pixel_y = 22},/obj/machinery/portable_atmospherics/powered/pump/filled,/turf/simulated/floor/plating,/area/maintenance/thirddeck/foreport) "dCk" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor/plating,/area/maintenance/thirddeck/foreport) "dCl" = (/turf/simulated/floor/plating,/area/maintenance/thirddeck/foreport) -"dCm" = (/obj/structure/closet/crate,/obj/item/weapon/storage/box/lights/mixed,/obj/random/maintenance/security,/obj/random/maintenance/security,/obj/random/maintenance/security,/turf/simulated/floor/plating,/area/maintenance/thirddeck/foreport) +"dCm" = (/obj/item/clothing/head/soft/mime,/obj/item/clothing/mask/gas/mime,/obj/item/clothing/shoes/mime,/obj/item/clothing/under/mime,/obj/random/crate,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) "dCn" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/reinforced/airless,/area/thirddeck/roof) "dCo" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/reinforced/airless,/area/thirddeck/roof) "dCp" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/wall/r_wall,/area/ai) @@ -9843,7 +9843,7 @@ "dHo" = (/obj/structure/table/standard,/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/folder/white_rd,/obj/item/weapon/pen/multi,/obj/machinery/computer/security/telescreen/entertainment{icon_state = "frame"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/carpet,/area/crew_quarters/heads/sc/hor/quarters) "dHp" = (/obj/structure/bed/chair/office/dark{dir = 1},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/carpet,/area/crew_quarters/heads/sc/hor/quarters) "dHq" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/light_switch{pixel_x = 36; pixel_y = -6},/obj/machinery/button/windowtint{id = "rdquarters"; pixel_x = 36; pixel_y = 6},/turf/simulated/floor/carpet,/area/crew_quarters/heads/sc/hor/quarters) -"dHr" = (/obj/structure/closet/crate,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/research,/obj/random/maintenance/research,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/turf/simulated/floor/plating,/area/maintenance/thirddeck/forestarboard) +"dHr" = (/obj/item/weapon/storage/box/lights/mixed,/obj/random/maintenance/security,/obj/random/maintenance/security,/obj/random/maintenance/security,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/thirddeck/foreport) "dHs" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/thirddeck/forestarboard) "dHt" = (/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{name = "Maintenance Access"; req_one_access = list(12,19)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/maintenance/thirddeck/foreport) "dHu" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/machinery/alarm{dir = 4; pixel_x = -22; pixel_y = 0},/obj/structure/dogbed,/turf/simulated/floor/carpet,/area/crew_quarters/heads/sc/hop/quarters) @@ -10206,7 +10206,7 @@ "dOn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock{name = "Bathroom"},/turf/simulated/floor/tiled/steel_grid,/area/crew_quarters/heads/sc/sd) "dOo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/heads/sc/sd) "dOp" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/heads/sc/sd) -"dOq" = (/obj/structure/closet/crate,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/thirddeck/aftstarboard) +"dOq" = (/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/research,/obj/random/maintenance/research,/obj/random/maintenance/cargo,/obj/random/maintenance/cargo,/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/thirddeck/forestarboard) "dOr" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/thirddeck/aftstarboard) "dOs" = (/obj/structure/table/steel,/obj/random/maintenance/engineering,/turf/simulated/floor/plating,/area/maintenance/thirddeck/aftport) "dOt" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/maintenance/thirddeck/aftport) @@ -10237,7 +10237,7 @@ "dOS" = (/obj/structure/toilet{dir = 1},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/heads/sc/sd) "dOT" = (/obj/machinery/shower{dir = 1},/obj/structure/curtain/open/shower,/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/machinery/door/window/northright,/obj/item/weapon/bikehorn/rubberducky,/turf/simulated/floor/tiled/freezer,/area/crew_quarters/heads/sc/sd) "dOU" = (/obj/machinery/door/firedoor/border_only,/obj/effect/wingrille_spawn/reinforced,/turf/simulated/floor/plating,/area/maintenance/thirddeck/aftstarboard) -"dOV" = (/obj/structure/closet/crate,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/wirecutters,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/maintenance/thirddeck/aftstarboard) +"dOV" = (/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/effect/decal/cleanable/dirt,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/random/crate,/turf/simulated/floor/plating,/area/maintenance/thirddeck/aftstarboard) "dOW" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/thirddeck/aftstarboard) "dOX" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green,/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/catwalk,/turf/simulated/floor/plating,/area/maintenance/thirddeck/aftport) "dOY" = (/obj/structure/table/steel,/obj/random/tech_supply,/turf/simulated/floor/plating,/area/maintenance/thirddeck/aftport) @@ -10557,7 +10557,7 @@ "dVa" = (/obj/item/weapon/camera_assembly,/turf/simulated/floor/tiled,/area/construction/seconddeck/construction2) "dVb" = (/obj/machinery/light,/obj/item/stack/material/plastic,/obj/item/stack/material/plastic,/obj/item/stack/material/plastic,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) "dVc" = (/obj/machinery/computer/security/telescreen/entertainment{icon_state = "frame"; pixel_x = 0; pixel_y = -32},/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) -"dVd" = (/obj/item/clothing/head/soft/mime,/obj/item/clothing/mask/gas/mime,/obj/item/clothing/shoes/mime,/obj/item/clothing/under/mime,/obj/structure/closet/crate,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) +"dVd" = (/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/wirecutters,/obj/random/maintenance/medical,/obj/random/maintenance/medical,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/random/crate,/turf/simulated/floor,/area/maintenance/thirddeck/aftstarboard) "dVe" = (/obj/item/frame/light,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) "dVf" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/turf/simulated/floor/plating,/area/construction/seconddeck/construction2) "dVg" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/universal,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/airlock/maintenance{req_access = null; req_one_access = list(12,25,27,28,35)},/turf/simulated/floor/plating,/area/maintenance/chapel) @@ -11021,7 +11021,7 @@ "edW" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/folder/yellow,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/engineering/foyer) "edX" = (/obj/machinery/atmospherics/pipe/manifold/hidden/red{dir = 8},/turf/simulated/floor/tiled,/area/engineering/foyer) "edY" = (/obj/machinery/atmospherics/pipe/simple/hidden/red{dir = 5; icon_state = "intact"},/turf/simulated/floor/tiled,/area/engineering/foyer) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11141,8 +11141,8 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakLakLakLakLakLakLakLakLakLakLakLakLakLaeFaeFakMakgafFafGalzakOakNakNakPakQakRakSafFafKakTaeFaeFaeFaioakUadlaaaaaaaaaaaaajpajpakoakVakWakWakXakYakZalaalbalcaldalealfalgalhalialjalkallalmalmalnakIajxajxaaaaaaaaaaaaadFaloaiyaeZaeZaeZalpaiAagmagmagmagmagmagmagmagmagmagmagmagValqaeZaeZdVQdVSdVRapiaqzdVUdVTdVVdVTdVVdVWdVYdVXdWadVZdVVdVVdVVdVVdWbbmqdWddWcdWedWcdWcdWfdWgaowaafaafaafaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalsalsaltaltaltalualtaltalualtaltaltalvaeFalwalxakgafFafGalAalBaAxalCaAyalBaDdafGafFafKalDalEaeFahcaioadladlaaaaaaaaaajpajpakoakoalFakoalGalHalHalHalHalHalHalHalHalHalHalHalHalIalIalIalJakIalKakIakIajxajxaaaaaaaaaadFadFaiyaikaeZalLalMaiAagmagmagmagmagmagmagmagmagmagmagmagValNaijaeZambdfZcYadWibmqdWkdWjdWmdWldWodWndWqdWpdWsdWrdWudWtdWwdWvdWxbmqdWzdWydWBdWAbHAdWCdWDaowaaaaaaaaaaaaaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalsaltalRalSalTalUalValWalXalYalZamaamraeFamcajEafEafFaiDaiDahBafFafFafFahBaiDaiDafFafKajEamdaeFameaioadLaaaaaaaaaaaaajpakoakVakWamfamgalHalHalHalHalHalHalHalHalHalHalHalHalHalIalIalIalIamhamialmalnakIajxaaaaaaaaaaaaaejaiyamjaeZaiSamkaiAagmagmagmagmagmagmagmagmagmagmagmagVakfagpaeZamsdWGdWFdWHbmqdWIarMdWJarMbmqbmqdWLdWKdWNdWMbmqarMdWJarMdWObmqdWQdWPdWSdWRdWUdWTdWVaowaaaaaaaaaaaaaafaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalsammamnamoamoamoamoamoamoamoampamaamraeFamqajEafEafFanEaoaafFafFafFafFafFanEaoaafFafKajEamtaeFamudWWadLaaaaaaaaaajoajoamvalFakoamwamxalHalHalHamyamzamAamBamCamDamEamBamFamGamHamIamJalIamKamLakIalKamMajwajwaaaaaaaaaaejaiyamNaeZamOamkaiAagmagmagmagmagmagmagmagmagmagmagmagVakfamPaeZapTdWZdWYdXbdXadXddXcdXbdXbdXfdXedXhdXgdXjdXidXkdXbdXmdXldXnaSNdXodXodXodXodXodXodXodXodXoaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalsaltalRamRamSamTaSjamUamVamWamXamaamraeFamYamZanaanbanbanbanbanbanbanbanbanbanbanbancandaneaeFanfaioadLaaaaaaaaaajoanganhalFalGanianianialHalHanjanjanjanjanjankanlanmanmannanoanpanqalIalIalIalJalKanransajwaaaaaaaaaaejaiyantaeZanuanvanwanxanxanxanxanxanxanxanxanxanxanxanyanzanAaeZdXpdXrdXqdXqdXsdXudXtdXwdXvdXxdXvdXzdXydXBdXAdXDdXCdXFdXEdXHdXGdXodXIdXKdXJdXMdXLdXKdXNdXobhgbhgaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalsammamnamoamoamoamoamoamoamoampamaamraeFamqajEafEafFamNamOafFafFafFafFafFamNamOafFafKajEamtaeFamudWWadLaaaaaaaaaajoajoamvalFakoamwamxalHalHalHamyamzamAamBamCamDamEamBamFamGamHamIamJalIamKamLakIalKamMajwajwaaaaaaaaaaejaiyantaeZanEamkaiAagmagmagmagmagmagmagmagmagmagmagmagVakfamPaeZapTdWZdWYdXbdXadXddXcdXbdXbdXfdXedXhdXgdXjdXidXkdXbdXmdXldXnaSNdXodXodXodXodXodXodXodXodXoaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalsaltalRamRamSamTaSjamUamVamWamXamaamraeFamYamZanaanbanbanbanbanbanbanbanbanbanbanbancandaneaeFanfaioadLaaaaaaaaaajoanganhalFalGanianianialHalHanjanjanjanjanjankanlanmanmannanoanpanqalIalIalIalJalKanransajwaaaaaaaaaaejaiyaoaaeZanuanvanwanxanxanxanxanxanxanxanxanxanxanxanyanzanAaeZdXpdXrdXqdXqdXsdXudXtdXwdXvdXxdXvdXzdXydXBdXAdXDdXCdXFdXEdXHdXGdXodXIdXKdXJdXMdXLdXKdXNdXobhgbhgaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalsalsaltaltaltaluanDanDalualtaltaltaoTaeFanFanGanHanHanIanHanHanJanKanLanManNanNanNanNanOamtaeFanPaioadladlaaaaaaajpanQanRanSanianiaoJaoKanialHanVanWanXanYanZanZaEyaobaocaodaoealIaofalIaogalIalIaohaoiaojajxaaaaaaadFadFaiyaokaeZaolaomaonaonaonaonaooaopaoqaoraosaosaotaosaosaouaovaeZdXOdXQdXPdXRapiatLdXSapidXUdXWdXVdXXaSNaSNdXYaSNaZYdXZcfodXHdYadXodYbdYcdXJdXMdXLdXKdYddXodXodYfdYedXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaakLatTatTakLakLakLakLaoxaoxaoyaoyaoyaoyaoyaeFaeFaeFaeFaeFaeFaeFaeFaozahcaoAaeFaoBaoBaoBaeFaeFaeFaeFafMaoCaoDadlaaaaaaajpaoEaoFaoGaoHaoIapOarganialHanjaoLaoMaoNaxjanZaoOaoPaoQaoRaoSaGeaoUaoVaoWaoXalIaoYaoZapaajxaaaaaaadFapbapcapdaeZaeZaeZaikapeapeapeaikapfaikapgaikaeZaeZaeZaeZaeZaeZaeZaphaphaphaphaphdYgdYgalralralralralralrdYidYhalralrdXZdYjdYkdWHdXodYldXKdXJdXMdXLdXKdYldXodYmdYodYndXodXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaafaafaafakLakLapjapkaplapmapnakLapoapoappapqaprapsaptapuapvapwapxapyapyapzapuapAapAapBapCapDapEapFapCapGafMadlapHapIapJadlaaaaaaajpapKapLapManiapNaNGaNHanialHanjanjanjanjanjapPapQapQapQapRapSaGzapUapVapWapXalIapYapZaqaajxaaaaaaadFaqbaghaqcaqdaqeaqfaqgaqhaqiaqjaqgaqkaqlaqlaqmaqnaqoaqoaqpaqqaqraqmaqsaqtaquaqvaqwaqxaqxalraqydYpaqAaqBaqCalOdYqatMalrdYtdYsdXodXodXodYudYwdYvdYydYxdYAdYzdXodYBdYDdYCdYFdYEdYGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11158,16 +11158,16 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaafaafakLakLaBfaBfaBgaBhaBiaBjaBkaBlaxTaBmaBmaBmaxVayQaBnayRaBoayRaBpaBqaxVaBraBsaBsaBtaBtaBtaBtaBtaBtaBtaBtaBuaBvaBwaybaaaaaaaBxaByaBzaBAaBDaAqaAmaBCaBBaBGaBHaBIaBJaBJaBKaBJaBEaBFaAvaCWaBOaBPaBQaBRaBSaBTaAzaBUaBVaBWaBXaaaaaaayxaBYazBaAIaBZaCaaCaayyaCbaFDaCdayyaqkaqlaqlayDaCeaCfayDaCgaARaChayDaCiaCjaCkaClaCmaCnaCnalraCoalOaCpaCqaCralralraafaaaaaaaaadXodXodXoeaVeaXeaWdYyeaYebaeaZdXodZbdZbdZbebbdXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaakLakLaBfaCsaCsaCsaCsaCtaCtaCsaCsaCuaCsaCsaCsaCsaCsaCsaCsaCsaCsaCvaCwaCxaCyaBtaCzaCAaCBaCCaCDaCEaBtaybaCFaCGaybaaaaaaaBxaCHaCIaCJauAaBLaBMaCZaCKaCLaCPaCQaCRaCSaCTaCUaCVaCXaAvaGpaCYaDbaDadVsaDcaHbaAzaDeaDfaDgaBXaaaaaaayxaDhaDiaAIaDjaDjaDjaDkaDlaDlaDlaDkaDmaDkaDnaDkaDjaDjaDjaDjaDjaDjaDjazUazUazUazUazUaDoaDoalralralralravpavpalraaaaaaaaaaaaaaaaaaaaadXodYldXKdXKdYydXKdXKdYldXoebcebeebddXodXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaDpaDqaDraDsaDtaDuaDvaDwaDxaDtaDyaDzaDAaDBaDCaDDaDEaDFaDGaDHaDIaDJaDKaDLaDMaDMaDMaDNaBtaDOaDPaybaybaaaaaaaBxaDQaCMaDSaCNaCNaykaykaykaykaDUaDVaDWaDXaDYaDZaEaaEbaEcaEdaEeaEfaAzaEgaEhaAzaAzaEiaEjaEkaBXaaaaaaayxayxaElaEmaDjaEnaEoaEpaEpaEpaEpaEqaEraEsaEtaEuaEuaEvaEuaEuaEwaExaDjaGAaEzaEzaEzaEAaEBaEBaECaEzaEzaEzaEDaEDaaaaaaaaaaaaaaaaaaaaaaaadXodYbdZBdXKdYydXKdXKdYddXodXodYfdYedXoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaEFaEGaEHaEHaEIaEJaEJaEKaELaEMaENaENaEOaEPaEQaERaESaETaEUaEVaEWaEXaEYaEZaDMaDMaFaaFbaDOaDPaFcaaaaaaaaaaAeaFdaFeaFfaFgauHauHaFhaFhaDTaFiaFjaCUaCUaCUaFkaCVaFlaFmaFnaFoaFpaAzaAzaAzaAzaFqaFraFsaFtaAGaaaaaaaaaaFuaElaFvaDjaFwaFxaFyaFzaFzaFzaFzaFzaFzaFzaFzaFzaFzaFzaFAaFBaFCaDjaHSaFEaFFaFGaFHaFIaSBaFKaFLaFMaFNaEzaEDaaaaaaaaaaaaaaaaaaaaaaaadXoebfdXKdXKdYydXKdXKebgdXobhgbhgaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaFOaFPaFPaFPaFPaFPaFPaFPaFRaFSaEPaEPaFTaEPaEPaFUaFVaFWaFXaFYaFZaGaaDMaGbaGcaGdaHYaBtaDOaDPaFcaaaaaaaaaaAeaAeaGfaFfaFfaGgaDTauHaFhaDTaGhaGiaGjaGkaCUaGlaGmaGnaAvaHdaHcaHPaGqaAzaGraGsaGtaFraGuaAGaAGaaaaaaaaaaFuaElaGvaDjaEnaGwaGxaGyaMtaNbaGyaGyaGyaGyaGyaMtaNbaGyaGBaGwaGCaDjaHSaFEaGDaFJaFJaFJaFJaFJaFJaFJaGEaGFaEDaaaaaaaaaaaaaaaaaaaaaaaadXodXodXodXodXodXodXodXodXoaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaFOaFPaFPaFPaFPaFPaFPaFPaFRaGGaEPaEPaFTaEPaEPaGHaCxaGIaGJaGKaGLaGMaGNaGOaGPaGQaGRaBtaybaGSaFcaaaaaaaaaaaaaBxaFfaFfaFfaFfaGTauHauHauHaGUauHaGVaGWaGXaCUaGYaGZaHaaOeaHRaHTaAvaAvaHeaHfaHgaHhaGtaBXaaaaaaaaaaaaaFuaElaHiaDjaHjaGwaGxaGyaHkaHkaHlaGyaGyaGyaHlaHkaHkaGyaGBaGwaHmaDjaHSaFEaHnaHoaHpaHqaHraHsaHtaHuaFNaEzaEDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaHvaFOaFPaFPaFPaFPaFPaFPaFPaHwaHxaHxaHxaFTaEPaEPaHyaCxaHzaHAaHBaEWaEWaGLaHCaEWaEWaEWaEWaHDazhaybaybaaaaaaaaaaBxaBxaFfaFfaFfaFfaFgaHEaHFaHFaHFaHGaHHaHIaHJaHKaHLaAvaAvaAvaAvaAvaFqaGtaFraGtaGtaBXaBXaaaaaaaaaayxayxaElaDkaDjaHMaHNaGxaGyaHOaHVaHQbqBaMzbskaHQbsmaHOaGyaGBaHWaHXaDjaRLaEzaEzaEzaEAaEzaEzaECaEzaEzaEzaEDaEDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaEFaEGaEHaEHaEIaEJaEJaEKaELaEMaENaENaEOaEPaEQaERaESaETaEUaEVaEWaEXaEYaEZaDMaDMaFaaFbaDOaDPaFcaaaaaaaaaaAeaFdaFeaFfaFgauHauHaFhaFhaDTaFiaFjaCUaCUaCUaFkaCVaFlaFmaFnaFoaFpaAzaAzaAzaAzaFqaFraFsaFtaAGaaaaaaaaaaFuaElaFvaDjaFwaFxaFyaFzaFzaFzaFzaFzaFzaFzaFzaFzaFzaFzaFAaFBaFCaDjaGCaFEaFFaFGaFHaFIaSBaFKaFLaFMaFNaEzaEDaaaaaaaaaaaaaaaaaaaaaaaadXoebfdXKdXKdYydXKdXKebgdXobhgbhgaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaFOaFPaFPaFPaFPaFPaFPaFPaFRaFSaEPaEPaFTaEPaEPaFUaFVaFWaFXaFYaFZaGaaDMaGbaGcaGdaHYaBtaDOaDPaFcaaaaaaaaaaAeaAeaGfaFfaFfaGgaDTauHaFhaDTaGhaGiaGjaGkaCUaGlaGmaGnaAvaHdaHcaHPaGqaAzaGraGsaGtaFraGuaAGaAGaaaaaaaaaaFuaElaGvaDjaEnaGwaGxaGyaHjaHSaGyaGyaGyaGyaGyaHjaHSaGyaGBaGwaLhaDjaGCaFEaGDaFJaFJaFJaFJaFJaFJaFJaGEaGFaEDaaaaaaaaaaaaaaaaaaaaaaaadXodXodXodXodXodXodXodXodXoaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaEEaFOaFPaFPaFPaFPaFPaFPaFPaFRaGGaEPaEPaFTaEPaEPaGHaCxaGIaGJaGKaGLaGMaGNaGOaGPaGQaGRaBtaybaGSaFcaaaaaaaaaaaaaBxaFfaFfaFfaFfaGTauHauHauHaGUauHaGVaGWaGXaCUaGYaGZaHaaOeaHRaHTaAvaAvaHeaHfaHgaHhaGtaBXaaaaaaaaaaaaaFuaElaHiaDjaMtaGwaGxaGyaHkaHkaHlaGyaGyaGyaHlaHkaHkaGyaGBaGwaHmaDjaGCaFEaHnaHoaHpaHqaHraHsaHtaHuaFNaEzaEDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxTalsaCtaHvaFOaFPaFPaFPaFPaFPaFPaFPaHwaHxaHxaHxaFTaEPaEPaHyaCxaHzaHAaHBaEWaEWaGLaHCaEWaEWaEWaEWaHDazhaybaybaaaaaaaaaaBxaBxaFfaFfaFfaFfaFgaHEaHFaHFaHFaHGaHHaHIaHJaHKaHLaAvaAvaAvaAvaAvaFqaGtaFraGtaGtaBXaBXaaaaaaaaaayxayxaElaDkaDjaHMaHNaGxaGyaHOaHVaHQbqBaMzbskaHQbsmaHOaGyaGBaHWaHXaDjaNbaEzaEzaEzaEAaEzaEzaECaEzaEzaEzaEDaEDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakLakLaCsaEEaFOaFPaFPaFPaFPaFPaFPaFPaHZaHZaHZaIaaFTaEPaEPaIbaESaIcaHAaIdaIeaIfaDHaIgaESaDOaIhaIiaAcazhaIjaybaaaaaaaaaaaaaBxaBxaFfaFfaFfaFfaIkaIlaImaInazlaIoaIpaIqaIraIsaItaIuaIvaIwaIxaHgaHgaHhaGtaBXaBXaaaaaaaaaaaaayxaIyaElaDjaDjaDjaIzaGxaGyaIAaIBaICaIDaIEaIEaIFbwsaHOaGyaGBaIGaDjaDjalralralralralralralralralralralralralraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCOaEEaFOaFPaFPaFPaFPaFPaFPaFPaIHaIIaIJaIIaIKaENaENaILaIMaINaIOaIPaIQaIRaIQaISaITaDOaIhaAcaAcaIUaIVaybaaaaaaaaaaaaaaaaBxaBxaFfaIWaIXaIYaIZaJaaJbaJcaJdaJeaJfaJgaJhaJiaJjaJkaJlaJmaJnaJoaGtaBXaBXaaaaaaaaaaaaaaaayxaJpaJqaDkaDjaJraGwaGxaGyaJsaTJaJuaJvaJwaJwaJwaJwaJxaGyaGBaGwaJyaDjaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaDRaJzaFOaFPaFPaFPaFPaFPaUcaFPaFRaEPaEPaJAaFTaJBaJCaJDaJEaJFaJGaJHaJIaJJaJKaJLaESaDOaJMaJNaAcazhaJOaybaaaaaaaaaaabaaaaaaaBxaBxaAeaJPaJQaJRaJSaInazlaIoaJTaJUaJVaJWaJXaJYaJZaKaaKbaKcaAGaBXaBXaaaaaaaabaaaaaaaaaayxaKdaElaKeaDjaJraGwaGxaGyaHOaKfaKgaKhaJwaKiaKjaKkaKlaGyaGBaGwaJyaDjaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaKmaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaCOaEEaFOaFPaFPaFPaFPaFPaFPaFPaHwaHxaKnaHxaKoaCsaCsaCsaCvaCvaCvaKpaKqaKraKqaKqaESaybaybaybaybazhaKsaKtaKtaKtaaaaaaaaaaaaaaaaaaaAeaAeaBxaBxaBxaAeaAeaKuaKvaJUaKwaKxaAGaAGaBXaBXaBXaAGaAGaaaaaaaaaaaaaaaaaaaKyaKyaKyaKzaElaKAaDjaKBaKCaGxaGyaHOaHOaHlaHkaKDaKhaHlaHOaHOaGyaGBaKEaKFaDjaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaafaafaafaCsaEEaFOaFPaFPaFPaFPaFPaFPaFPaKGaKGaKGaKHaKIaCsaKJaKJaKJaKJaKJaKpaKKaKLaKMaKqaKNaKNaKNaKNaybazhaKsaKOaKPaKtaKtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKQaKRaKSaJUaKTaKUaKQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKyaKyaKVaKWaKzaElaKXaDjaJraKYaGxaGyaGyaHOaKZaLaaJwaLbaLcaHOaGyaGyaGBaKYaJyaDjaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaCsaEEaFOaFPaFPaFPaFPaFPaFPaFPaIHaIIaIIaIIaFTaLdaKJaKJaKJaKJaKJaKpaLeaLfaLgaKqaLhaAcaAcaAcaLiazhaLjaLkaLlaLmaKtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKQaLnaLoaLpaLqaLraKQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKyaLsaLtaLuaLvaElaLwaDjaJraLxaGxaGyaGyaHkaLyaJwaJwaJwaLzaHkaGyaGyaGBaLxaJyaDjaDkaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaCsaEEaFOaFPaFPaFPaFPaFPaFPaFPaIHaIIaIIaIIaFTaLdaKJaKJaKJaKJaKJaKpaLeaLfaLgaKqaRLaAcaAcaAcaLiazhaLjaLkaLlaLmaKtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKQaLnaLoaLpaLqaLraKQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaKyaLsaLtaLuaLvaElaLwaDjaJraLxaGxaGyaGyaHkaLyaJwaJwaJwaLzaHkaGyaGyaGBaLxaJyaDjaDkaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaCsaLAaFOaFPaFPaFPaFPaFPaFPaFPaFRaEPaEPaEPaLBaLCaKJaKJaKJaKJaKJaKpaLDaLEaLFaKqaAcaAcaAcaLGaybaLHaKsaLIaLlaLJaKtaaaaaaaaaaaaaLKaLLaLMaLLaLNaaaaaaaLOaLOaLPaJUaLQaLRaLRaLRaLRaLRaLRaLSaLSaLSaLRaLRaLRaLRaKyaLTaLtaLUaKzaElaDkaDjaDjaLVaLWaGyaGyaKhaLXaLXaJwaLXaLXaKhaGyaGyaGBaLYaDjaDjaDjaafaafaafaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaCsaEEaFOaFPaFPaFPaFPaFPaFPaFPaFRaLZaEPaEPaFTaMaaKJaKJaKJaKJaKJaKpaKqaMbaKqaKqaMcaMdaMeaMfaMfaMgaKsaMhaLlaMiaKtaaaaaaaaaaaaaMjaMkaMlaMmaMjaaaaaaaaaaLOaMnaJUaMoaMpaMqaMraMsaSbaLSaMuebhaMwaMxaMybCFaLRaMAaMBaLtaLuaKzaMCaDjaDjaMDaMEaLWaGyaGyaHOaMFaKhaMGaKhaHlaHOaGyaGyaGBaMHaMIaDjaDkaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaCsaEEaFOaFPaFPaFPaFPaFPaFPaFPaFRaMJaMKaMLaMMaCsaMNaKJaKJaKJaKJaMfaDOaDOaDOaybaybaybaybaMfaMOaLHaKsaKsaMPaKsaKtaMQaMQaMQaMRaMjaMSaMTaMUaMjaMVaMQaMQaMQaMWaMXaMWaLRaMqaMYaMZaTgaNaaNdaNcaNfaNeaNgbCFaLRaKzaKzaNhaKzaKzaNiaDkaDjaNjaNkaLWaGyaGyaKhaNlaNmaJwaNmaNnaKhaGyaGyaGBaNkaJyaDjaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11386,9 +11386,9 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadJaaaaaaaaabgvbsRbZMbsSbpFbpGbtibxTbxWbxUbxUbxVbxYbxZbwwbxXbycbydbyabybbyfbygbyebwBbzebuwbyhbwObwPbwQbwRbCqbYsbwUbwUbwUbwUbwUbwUbwVbwWbwXbrbbwYbvNbwZbvNbvPbrbbvNbxabrbbvNbxbbrbbvNbxcbrbbxdbxebxfbxgbxhclfclgcnebuWbxkbxlbxmbxnbxobuWbxpbxqbxrbxsbxtbuZbxubxvbvZbxwbxibxxbvgaaaaaaaaaaaaaaabvgbvgbvibvibvibvgbxybxzbxAbxBbxCbxDbxEbxFcePccVcdkbxHbxHbxIbxIaafaafaafbhgaafaafaafaafbxJbxKbxLbhgbxMbxNbxObxPbxQaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgvbgvbgvbgvbgvaaabqCbumbqEbzhbzfbzgbzjbAnbzibAqbArbAsbTHbXDbzibnLbAtbAubBQbuwbAvbyibyjbuwbvCbxGcozbuxbuxbuxbuxbuxbuxbuxbymbynbrbbyobvNbypbyqbvPbrbbyrbysbrbbyrbytbrbbyrbyubrbbyvbywbyxbxgbxhcnfcoUcJZbuWbyybyzbyAbyBbyCbuWbyDbxqbyEbxqbyFbuZbyGbxvbvZbvZbyHbvZbvZbvgbvgbvgbvgbvgbvgebsbyIbyJbyKbyKbyLbyMbyMbyLbyNcePbyOcqUcyVcqTbyTbxHbyUbyVbxIbxIaaaaaabhgaaaaaaaaaaafbyWbyXbyYbyZbzabyZbyWbzbbyWaafaafaafaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaabkHbzcbzdbBRbkAbkAbBTbBVbzkbuvbBWbzlbwwbuvbuvbDpbBYbDobqIbuwbuwbzmbuwbuwbuxbAObzobzpbuxbzqbzrbzsbztbuxbymbynbrbbrbbrbbrbbrbbrbbrbbrbbrbbrbbrbbrbbrbbrbbrbbrbbzubzvbzwbzxbxhcOBdcSdfrbuWbzAbzBbzCbzDbzEbuWbzFbzGbzHbxqbzIbuZbzJbzKbzLbzMbzNbzNbzNbzNbzNbzNbzObzNbzNbzNbzNbzPbzQbzRbzSbzTbzUbzVbzWbyObyPcHvbyObzYbzZbAabAbbAcbAdbxIaaaaaabhgaaaaaaaaaaaabyWbAebFdbAfbAgbAhbyWbAibyWaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaabAjbAjbAjbAjaaaaaaaaabAjaaaaaaaaaaaaaaabAjaaaaaaaaabAjbAjbAjbAjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabAkbAkbAkbAkbAkbAkbAkbAkbAkbAlbAmbDvbDqbApbETbFhbELbEMbAwbGFbGmbEMbAxbAybAzbAAbABbACbvCcKMbAEbAFbuxbDJbymbymbymbAGbAHbAIbwUbAJbAKbALbAMbwUbwUbwUbwUcNqcOFcQhcOEcOFcQibAQbuxbARbASbATbxhbxhbxhbxhbuWbAVbAWbAXbAYbAZbuWbBabBbbBcbBdbBebuZbBfbxibBgbBhbBibBjbBkbxibxibBlbBlbBlbBlbBlbBlbBlbBmbBnbBobBpbBqbBrbBrbBrbBrbBsbBsbBsbBsbBsbBtbBubBvbBwbBwbBxbBwbBxbBwbBxbBwbBwbBybBzbBAbBBbBCbyWbBDbyWbyWaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaabAjbAjbAjbAjaaaaaaaaabAjaaaaaaaaaaaaaaabAjaaaaaaaaabAjbAjbAjbAjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabAkbAkbAkbAkbAkbAkbAkbAkbAkbAlbAmbDvbDqbApbETbFhbELbEMbAwbGFbGmbEMbAxbAybAzbAAbABbACbvCcKMbAEbAFbuxbDJbymbymbymbAGbAHbAIbwUbAJbAKbALbAMbwUbwUbwUbwUcNqcOFcQhcOEcOFcQibAQbuxbARbASbATbxhbxhbxhbxhbuWbAVbAWbAXbAYbAZbuWbBabBbbBcbBdbBebuZbBfbxibBgbBhbBibzzbBkbxibxibBlbBlbBlbBlbBlbBlbBlbBmbBnbBobBpbBqbBrbBrbBrbBrbBsbBsbBsbBsbBsbBtbBubBvbBwbBwbBxbBwbBxbBwbBxbBwbBwbBybBzbBAbBBbBCbyWbBDbyWbyWaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaabAjbAjbAjbAjaaaaaaaaabAjbAjbAjbAjbAjbAjbAjaaaaaaaaabAjecAbAjbAjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaafaafaaaaaabBEbBFbBGbBHbAkbBIbBJbBKbBLbBMbBMbBNbAkbBObBPbIobGJbBSbJSbBSbIqbBSbLjbBXbJUbBZbCabCbbCcbCdbCebCfbvCbCgbzobChbuxbCibCjbymbymbuxbCkbClbymbCmbCnbuxbuxbCobuxbuxbCpcRncgecSBcRocSBcSEbuxbuxbCsbCtbCubvZbvZbCvbyJbuWbCwbCxbuWbuWbuWbuWbuZbuZbCybuZbuZbuZbBfbxibCzbCAbBibwnbCBbCCbCDbBlbCEcaRbCGbCHbCIbBlbCJbCJbCKbCJbCJbBrbCLbCMebubBsbCObBsbCPbBsbCQbCRbCSbBwbCTbCUbCVbCVbCWbCXbCYbBwbCZbDabDbbDcbDdbDebDfbDgbyWaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaabAjbAjbAjbAjaaaaaabAjbAjbAjbAjbAjbAjbAjbAjbAjaaaaaabAjbAjbAjbAjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaadaadaaaaabaaaaaaaaabBEbDhbDhbDibAkbDjbDjbDjbDkbBMbDlbDmbAkbDnbNkbPTbLlbDrbDsbDtbCfbDuedNbDwecRbDubDybDybDzbDAbDBbDybuxbDCbDDbFebuxbuxbuxbDFbymbuxbCrbDGbDGbDHbDGbDGbDIbymbImbuxbDKbymbDLbuxbvFbymbCrbymbuxbDMbDNbDObvZbxibxibzzbDPbxibDQbAUbAUbAUbAUbBgbDRbDSbDTbDUbDVbDWbDXbDYbvZbDZbDZbDZbDZbEabBlbEbbEcbEdbEebEfbFMbEhebvbEjbEkbElbBrebwbEndgGbBsbEpbBsbEqbBsbBsbErbEsbEtbEubEvbCVbEwbExbEybEzbBwbEAbEAbEAbFUbEAbEAbEAbEAbEAbEAaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaabAjbAjbAjbAjaaaaaabAjbAjbAjbAjbAjbAjbAjbAjbAjaaaaaabAjbAjbAjbAjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaadaadaaaaabaaaaaaaaabBEbDhbDhbDibAkbDjbDjbDjbDkbBMbDlbDmbAkbDnbNkbPTbLlbDrbDsbDtbCfbDuedNbDwecRbDubDybDybDzbDAbDBbDybuxbDCbDDbFebuxbuxbuxbDFbymbuxbCrbDGbDGbDHbDGbDGbDIbymbImbuxbDKbymbDLbuxbvFbymbCrbymbuxbDMbDNbDObvZbxibxibBjbDPbxibDQbAUbAUbAUbAUbBgbDRbDSbDTbDUbDVbDWbDXbDYbvZbDZbDZbDZbDZbEabBlbEbbEcbEdbEebEfbFMbEhebvbEjbEkbElbBrebwbEndgGbBsbEpbBsbEqbBsbBsbErbEsbEtbEubEvbCVbEwbExbEybEzbBwbEAbEAbEAbFUbEAbEAbEAbEAbEAbEAaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaabAjbAjbAjbAjaaaaaabAjbAjbAjbAjbAjbAjbAjbAjbAjaaaaaabAjbAjbAjbAjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaagaadaadaadaagaafaaaaafaaaaaaaaaaaaaaaaaaaaabBEbECbEDbEEbAkbEFbEGbEGbEHbEGbEIbEJbAkbEKbNkedObENbEObEPbEQbERbESbOXbEUedPbEWbEXbEYbEZbFabFbbFcbuxbGSbGTbFfbFgcbEbuxbvGbvFbuxbFibDGbFjbFkbFlbDGbFmbFnbChbuxbzpbymbFobuxbvGbymbFpbFqbFrbFsbFtbFubFvbDTbFwbDTbFxbDTbFybDTbDTbDTbDTbFzbFAbFBbFBbFBbFBbFBbFBbFCbFDbDZbFEebxbFGbEabFHbFIbFJbFKbFLbFVbFMbFNbFObFPbEjbHxbKtebzebybFTbGbbGibFWbFXbFYbBsbFZbGabHybGcbGdbGebGdbGfbGgbGhbKrbGjbGkbGlbGpbGqbGnbGobJpbGrbGsaaaaaaaaaabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaabAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaaafaaaaaaaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaabBEbGtbGubGvbAkbGwbEGbEGbGxbGybGzbGAbGBbGCbGDedRedQcFcbGGbGHbERbGIbXNbGKedSbGMbEXbGNbGObGPbGQbGRbuxbGUbVfbuxbGVcbEbuxbAQbAQbuxbGWbDGbGXbFkbGYbDGbuxbuxbuxbuxbGZbGZbGZbuxbuxbuxbuxbuxbHabHbbHcbHdbHabvZbvZbvZbvZbvZbvibvibvibvZbvZbvZbvZbFBbHebHfbHgbHhbFBbHibHjbHkbHlbHmbHnbEabHobHpbEcbHqbHrbHsbEgbHtebBebCebAbFQbBrebFebDebEbBsbHCbHDbHEbHFbBsbHGbHHbBwbHIbHJbHKbHJbHKbHJbHLebGbHMbHNbHObHPbHQbHRbHSbHTbHUbHVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaabAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjbAjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaafaaaaaaaaaaaaaafaaabHWbHWbHWbHWbHWbHWbHWbHXbHXbBEbHYbHZbDibAkbIabIabIbbIcbIdbIebIfbAkbIgbIhbIibIjbIkbIlccMbCfbInedUbIpedTbIrbDybIsbItbIubIvbIwbIxbIxbIybIxbIxbIxbIxbuxbuxbuxbIzbDGbIAbIBbICbDGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabIDbIEbIFbIGbIHbIIbIDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabFBbIJbIKbILbILbIMbINbBqbDZbIObIPbIQbEabIRbISbITbIUbIVbIWbEgbEjebIbIXebHbIZbBrbBrbBrbBrbBsbJdbJebJfbJgbBsbJhbJibBwbBwbJjbJkbJlbJjbJmbJjbBxbJnbJobKFbJqbJrbJsbJtbJqbJubJvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11427,9 +11427,9 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaafaafaafcLzcLAcDHcLBcLCcLDcDHcKqcLEcLFcLGcLHcLIcLJcLKcLLcGTcLMcIMcIMcDUcLNcLOcKzcLPcLQcDUcLRcLScHgecoecpecpecpcLScLVcKGcLWcLWcLWcLWcLWcLXcLYcLYcLZcLYcoVcoVcoVedbedccKNcMacMbcMccKNcKNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactUcMdcMecMfcMgcMhctUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKRcKRcMicMjcKRcMkcKVcMlcMmcMncKTcMocMpcMqcMrcMscKZcMtcMucMvcMwcMxcLbcMycMzcMAcMBcMCcLhcMDcMEcMFcMGcMHcMIcMJcMKcMLcMMcMNcMOcMOcMOcMOcMOcMOcMPcMQcMRcMScMTcMUcMVaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaacMWcDHcFpcFpcDHcDHcMXcMYcMYcMXcMZcNacMXcMXcLLcGTcIMcIMcIMcDUcNbcNccNdcNecNfcDUcNgcHgcHgcNhcNicHgcHgcHgcNjcNkcLWcLWcLWcLWcLWcLXcNlcNmcNncLYcCwcQkcoVcTDedgcNrcNscNscNtcNucKNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactUcNvcNwcNxcNycNzctUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKRcNAcNBcNCcKRcNDcKVcNEcNFcNGcKTcNHcNIcNJcNKcNLcNMcNNcNOcNPcNQcNRcLccNScNTcNUcNVcNWcNXcNYcNZcOacObcOccLhcOdcOecOfcOgcOhcMOcOicOjcOkcPucMOcOmcOncLucOocOpcOqcLyaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaacMXcOrcOscOtcMXcLLcGTcIMcIMcIMcDUcDUcDUcDUcDUcDUcDUcOucOvcHgcHgcOwcOwcOwcHgcOxcOycLWcLWcLWcLWcLWcLXcOzcOAdUVcLYcOCcBbcODedhedicKNcPVcOHcOIcOJcKNcoVcoVcoVcoVczlczlczlcoVcoVcoVcoVcoVcOKcOLcMfcOMcOKcpkcpkcpkcpkcpkczCczCczCcpkcpkcpkcpkcKRcONcOOcOPcKRecqcKVcORcOScOTcKTcOUcOVcOWcOXcOYcKZcOZcPacPbcPccPdcLfcNScNTcPecPfcPgcPhcPicPjcPkcPlcPmcLhcPncPocPpcPqcPrcMOcPscPtcPtcSLcMOcPvcPwcPxcPycPzcPAcKlaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaacMXcPBcPCcPDcMXcLLcGTcGTcPEcIMcFucFucIMcIMcIMcPFcGTcEacPGcEacEacPHcPIcPJcPKcPLcPMcLWcLWcLWcLWcLWcLXcPNcPOcPPcLYcPQcPRcoVcPScPTcKNcKNcKNcKNcKNcKNcPWcHwcHwcQacQacPYcQacQacQacQacQacQacQbcQccQdcQecQfcQgcQgcQgcQgcQgcQgcURcTHcpkcQjcSpcQlcKRcQmcOOcQncKRcQocKVcKVcQpcKVcKTcQqcQrcQscQtcQucKXcQvcQwcQxcQycPdcLccNScQzcQAcQBcQCcQDcQEcQFcQGcQHcQIcLhcLlcLlcLlcLlcLlcMOcPscQJcQKcSLcMOcQLcQMcKlcKlcKlcKlcKlaafaafaafaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaafaaaaaaaaaaaacMXcQNcQNcMXcMXcLLcIMcGTcGTcFucFucGTcGTcGTcGTcGTcGTcQOcQOcQOcEacEacEacEacQPcQQcKGcLWcLWcLWcLWcLWcLXcLYcKUcLYcLYcoVcoVcoVcQScQTcQUcHwcQVcQWcQXcHwcHxcBbcBbcBbcBbcQYcQZcAYcPUcPUcRdcRecoVcRfcRgcRhcpkcRicRjcRicRkcRlcRmcWecWcedmedpedpedocKRcKRcRpcKRcKRcQocpkcGjcRqcRrcLacRscRtcUgcRvcRwcKZcRxcRycRzcRAcRBcLbcRCcRDcREcRFcRGcRHcRIcRJcRKcRLcRMcRNcROcRPcRQcRRcRScMOcRTcRUcPtcRVcMOcRWcRXcpwaaaaaaaaaaaaaaaaaaaaaabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcaadaadaaaaaaaaacMXcRYcRZcSacMXcSbcKvecscSdcSecSfcSgcShcIMcSicIMcSjcSkcSkcSkcSlcSmcSmcEacEacEacKGcKGcKGcKGcKGcKGcKGcQOcSncQOcGTcSocGTdTdcBbcFUcBbcSqcSrcPScNocBbcSucSvcSwcSucSucSucSucSucSucSucSucSucSucSxcSycSzcSAcSAcSAcSKcSAcSAcSAcSAdaMedvedredvedtcSFcSGcSHcSDcSDcSIcSJcTucTycSMcLacLacLacLacLacLacLacSNcLbcLbcLbcSOcLbcSPcSQcSRcSScSPcLhcSTcLhcLhcLhcMIcSUcSVcSWcSXcSYcSZcTacPtcTbcTccTdcTecTfcTgcpwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaacMXcPBcPCcPDcMXcLLcGTcGTcPEcIMcFucFucIMcIMcIMcNocGTcEacPGcEacEacPHcPIcPJcPKcPLcPMcLWcLWcLWcLWcLWcLXcPNcPOcPPcLYcPQcPRcoVcPScPTcKNcKNcKNcKNcKNcKNcPWcHwcHwcQacQacPYcQacQacQacQacQacQacQbcQccQdcQecQfcQgcQgcQgcQgcQgcQgcURcTHcpkcPFcSpcQlcKRcQmcOOcQncKRcQocKVcKVcQpcKVcKTcQqcQrcQscQtcQucKXcQvcQwcQxcQycPdcLccNScQzcQAcQBcQCcQDcQEcQFcQGcQHcQIcLhcLlcLlcLlcLlcLlcMOcPscQJcQKcSLcMOcQLcQMcKlcKlcKlcKlcKlaafaafaafaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaafaaaaaaaaaaaacMXcQNcQNcMXcMXcLLcIMcGTcGTcFucFucGTcGTcGTcGTcGTcGTcQOcQOcQOcEacEacEacEacQPcQQcKGcLWcLWcLWcLWcLWcLXcLYcKUcLYcLYcoVcoVcoVcQjcQTcQUcHwcQVcQWcQXcHwcHxcBbcBbcBbcBbcQYcQZcAYcPUcPUcRdcQScoVcRfcRgcRhcpkcRicRjcRicRkcRlcRmcWecWcedmedpedpedocKRcKRcRpcKRcKRcQocpkcGjcRqcRrcLacRscRtcUgcRvcRwcKZcRxcRycRzcRAcRBcLbcRCcRDcREcRFcRGcRHcRIcRJcRKcRLcRMcRNcROcRPcRQcRRcRScMOcRTcRUcPtcRVcMOcRWcRXcpwaaaaaaaaaaaaaaaaaaaaaabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcaadaadaaaaaaaaacMXcRYcRZcSacMXcSbcKvecscSdcSecSfcSgcShcIMcSicIMcSjcSkcSkcSkcSlcSmcSmcEacEacEacKGcKGcKGcKGcKGcKGcKGcQOcSncQOcGTcSocGTdTdcBbcFUcBbcSqcSrcPScRecBbcSucSvcSwcSucSucSucSucSucSucSucSucSucSucSxcSycSzcSAcSAcSAcSKcSAcSAcSAcSAdaMedvedredvedtcSFcSGcSHcSDcSDcSIcSJcTucTycSMcLacLacLacLacLacLacLacSNcLbcLbcLbcSOcLbcSPcSQcSRcSScSPcLhcSTcLhcLhcLhcMIcSUcSVcSWcSXcSYcSZcTacPtcTbcTccTdcTecTfcTgcpwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfGaafaafaafaafaaaaaaaaacMXcMXcSbcKucKucKucThcTicTicTicTjcTicTicTicTkcKucKucKucKucThcKucKucKucKucKucKucKucKucTlcTmcTncTocTpcKucTqcTrcTscTtcTJcTJcTJcTJcTJcVYcSucTvcTwcRbcRacSucStcTxcUCcRccSscTEcSucTzcTAcXacSAcTGcTIcUucUvcUvcUMcSAcUNcSAcpkcpkcpkcpkcpkcpkcpkcpkcpkcTKcsFcTLcTMcTNcTOcTPcTQcTQcTRcTScTTcTUcTVcTWcTXcSRcTYcTZcUacUbcUccSRcUdcTWcTVcTUcUecSUcUfcXCcUhcUicUjcMOcUkcUlcUmcUncUocUpcUqcpwaaaaaaaaaabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaafaaaaaaaaaaaacMXcMXcMYcMYcMYcMXcMXcMXcMYcMYcMYcMXcMXcMXcMXcMXcMXcMXcMXcIMcIMcIMecucIMcIMcIMcIMcIMcIMcIMcMXcMXcMXcMXcUrdaPcUtcTJcUycUwcUxcUYcUZcSucUzcTwcUDcUAcUBcUGcUHcUEcUFcUIcUScSucUJcUKdfkcSAcSAcSAcUOcUPcUQcUTcSAcUUcUXcVacVbcVccWdcWfcWkcWncWocpkcpkcpkcTLcVfcVhcVdcVecVgcWbcGjcTScVicUacVjcVkcVlcSRcVmcVncVocVpcVqcSRcVrcVkcVjcUacVscSUcSUcSUcSUcVtcSUcMOcMOcMOcMOcMOcMOcVucVvcVwaafaafaafabcaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaacMXcMXcVxcVycVzcVAcVBcVCcVDcVEcVFcMXcMXaaaaaaaaaczledbcVHcVKcVIcVIcVJcVNcVOcSucVLcVQcVRcVPcSucVTcVUcVScVMcWacUVcSucVVcVWcVXcSAcWpcWqcWrcWWcXbcXccXdcXecXfcVacXgcXjcYrcWfcYscYtcYvcpkcXkcpkcTLcWlcWmcWmcWlcXlcXmcXncXocWscWtcWucWvcWwcWxcWycWzcWAcWycWycWxcWAcWBcWCcWycWDcWEcQRcWGcWHcWIcWJcWKcWLcWMcWNcWOcWPcWQcWRcWSaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11437,9 +11437,9 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaabaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaacUrcVGcXrcTJcTJcTJcTJcXucTJcTJcXscXxcYjcXvcXwcYncYocYkcYmcYpcYqddAcYucUKddzdhacZwcZzcZBdhacYFcYGcSAcUNcSAcVacVacZCcVacWfcWfcZDcWfcpkdmFdmFcZEcYLcYMcYNcYOczCczCcTRcTScTScYPcYQcYRcYScYRcSPcYTcYUcYVcSPcYWcYXcYYcYZcYYcZacZbcZbcZbcZccZdcZccZecZfcZgcZfcZhcZicZjcZicWSaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaagaadaadabcaagaagaadaadaadaadaafaaeaaaaafaagaadaadaadaadaadaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaacUrcUscZkcZncTJcYIcZPcZmcYJcWhcZlcZqcZrcYmcZpcZtcZucZscYqcZvcYqddAcZxcZycZAdaQdaRdaSdaTdhacZFcYGcZGcZHcZIcZJcZMcZNcZGcZOcZQcZRdaqdardasdasdatcTRcZTcZTcTRaaaaafaaaaaaaaacYPcZUcZVcZWcZXcZYcZYcZZcZYcZYdaadabdacdaddaedafdagdahcZbdaidajdakcZedaldamdancZhcWScYicWScVwaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaacUrdaodapdawdaxdaudavdaAdavdaydazdaGdaHdaBdaCdaKdaLdaIdaJdaNdaOdfUdaDdaEdaFdcIdcJdcMddrdhadaUdaVdaYdbvdbMdbOdbPdbQdbPdbRdbSdbYdbZcYHdiUdnMdcEcTRdaWdaXdcHaaaaafaaaaaaaaacYPdaZdbadbbdbcdbddbedbfdbgdbhdbidbjdbkdblcYYdbmdbndbocZbdbpdbqdbrcZedbsdbtdbucZhaaaaaaaaaaafaafaafaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafabcaagaadaafaaaaaaaaaaadaadaadaaaaaaaaaaaaaaacUrdbwdbxdbzcTJdbyddFdbBdbCdbAcZKdbDdbEcYmcZpdbGdbHcYqdbFdbJcYqdkmdbKcUKddzdaQddwdegdexdhadcNcYGdcOdcUdcZddsddBddCddDddEddDddDddDcYHddMddYdeadmGaaaaaaaaaaaaaafaaaaaaaaacYPdcadcbdccdcddbddcedcfdcgdbhdchdcidcjdckcYYdcldcmdcncZbdcodcpdcqcZedcrdcsdctcZhaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafabcaagaadaafaaaaaaaaaaadaadaadaaaaaaaaaaaaaaacUrdbwdbxdbzcTJdbyddFdbBdbCdbAcZKdbDdbEcYmcZpdbGdbHcYqdbFdbJcYqdkmdbKcUKddzdaQddwdegdexdhadcNcYGdcOdcUdcZddsddBddCddDddEddDddDddDcYHddMdcRdeadmGaaaaaaaaaaaaaafaaaaaaaaacYPdcadcbdccdcddbddcedcfdcgdbhdchdcidcjdckcYYdcldcmdcncZbdcodcpdcqcZedcrdcsdctcZhaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaaaaaaacUrdcudbTdbWcTJdbNcZKdbUdcVdbXcZKdbDdcvcYmcZpdczdcAdcwdcxdcCdcDdcBdcKdcLdefdhadhadfcdaQdhadeccYGdcOdeecYHcYHcYHdehcYHcYHcYHcYHdeicYHcYHcYHdejdmGaaaaaaaaaaaaaafaaaaaaaaacYPddaddbddcddddbdddeddfdcgdbhddgddhddiddjcYWddkddkddkddkddlddmddlddnddoddpddocZhaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaadaafaafaafaafcUrddXdcPdcRcTJdcFdbVdcQdcTcZlcZKcZqdcWcYmcZpdcYddtcYqdcXdduddvddAddycUKdewdfHcYHdetdeydezdeAcYGdcOdeGdeMddZddZddZddZddZddZddZddZddZddZdeMdejdnfaaaaaaaaaaaaaafaafaafaafcYPcYPddNddOddPddQddRddSddTddQddUddVddWcYWcYWaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaagabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaadaafaafaafaafcUrddXdcPddYcTJdcFdbVdcQdcTcZlcZKcZqdcWcYmcZpdcYddtcYqdcXdduddvddAddycUKdewdfHcYHdetdeydezdeAcYGdcOdeGdeMddZddZddZddZddZddZddZddZddZddZdeMdejdnfaaaaaaaaaaaaaafaafaafaafcYPcYPddNddOddPddQddRddSddTddQddUddVddWcYWcYWaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaagabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaacUrddXddGecMcTJddxddJddHddIddKddLcTJdebcYqcZpcYqcYqcYqcYqcYqcYqddAddycUKdfkdgddeNdePdfadfbdfddfjdfodfpdeMddZddZddZddZddZddZddZddZddZddZdfsdcEdnfaaaaaaaaaaadaagaaaaaaaaaaafcYPcYPcYPcYPddQddQddQddQddQcYWcYWcYWcYWaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUrddqcoVcoVcTJdekcZKcZKcZKcZldeldjFdemdemdendbHderdepdeqdeudevcYwdescVWdfydipdftdfudfvdfwdfIcYGdfNdfTdeMddZddZddZddZddZddZddZddZddZddZdeMdcEdnfaaaaaaaagaadaaaaaaaaaaaaaagaaaaaaaaaaaaaafaaaaaaaaaaafaaaaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcaaaaaaaaaaaacUrddXdeBcAYcTJcZLdeCdeFdeddeDdeEcXpdeIcYqdeHdeKcYwdeJddAddAdeLcYwdeQcUKdgcdgvcYHdfVcYGdfWdfYcYGdfNdgadgbddZddZddZddZddZddZddZddZddZddZdgedcEdmGaafaafaadaaaaabaaaaaaaaaaadaaaaaaaaaaaaaafaaaaaaaaaaafaaaaaaaaaaafaaaaaaaafaafaadaadaadaafaaeaagaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11458,17 +11458,17 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUrdkTdmddiMdmOdmfdmOdmgdjsdjsdkYdmidiRdlxdmjdlUdjsdmkdmldmmdmndmodmOdmqcUKdlidhudhxdmrdmtdmudmvdmwdmxdjYdjXdjYdjYdjZdkadkbdkcdkddkbdkbdkedkfdkgdkhdkiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUrcAYdjjdkldlDdmydlDdlDdmzdmAdmBdmAdmAdmAdmAdmCdmDdmVdmldmWdmYdmodmOdfkcUKdmsdlEdlFdlGdlJdlKdlLdlYdlZdkHdmEdkJdkHdkKdkLdkMdkNdkOdkNdkNdkPdkQdkRdkSdkiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUrcUrcUrcUrcUrcUrcUrdmediMdiMdkrdksdnJdnKdmZdoodoqdoudoudnLdmhdoxdoydozdoAdoAdlHdmOdfkdncdowdixdixdmUdixdixdixdixdmXdixdixdixdlmdixdlndixdlodlpdlqdhxdnadhxdnbdixdjAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdmHdmHdmIdmHdmHdqndmKdmLdmMdiMdmNdmOdmOdmPdmQdiMdiMdiMdiMdiMdiMdiMdiMdiMdmOdmOdmOdmRdmSdcLdmTdnednhdnhdnxdnhdnydnDdnednednednednEdnFdnGdixdnHdnHdnIdnNdnOdhxdordosdotaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdmHdmHdmIdmHdmHdprdmKdmLdmMdiMdmNdmOdmOdmPdmQdiMdiMdiMdiMdiMdiMdiMdiMdiMdmOdmOdmOdmRdmSdcLdmTdnednhdnhdnxdnhdnydnDdnednednednednEdnFdnGdixdnHdnHdnIdnNdnOdhxdordosdotaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdngdrgdrgdrgdnidnidmKdnjdnkdnkdnldnkdnmdnndnodnpdnqdnrdnsdntdnudnvdnwdpNdpOdnzdnAdnBdfkcUKdVAdnedovdovdoCdoDdpkdoFdnedpcdpcdnedixdixdixdixdixdixdixdixdmadixdixdixdjAaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmIdnPdnQdnRdnRdnSdmIdnTdnUdnVdnWdnXdnYdnZdoadobdocdoddoedofdogdohdoidojdokdoldomdomdomdondqodopdnednednedpedpfdpgdphdpidpjdsRdnedpldpmdpndpodppdpqdprdnedpsdcGdpLdpMdpPaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmIdnPdnQdnRdnRdnSdmIdnTdnUdnVdnWdnXdnYdnZdoadobdocdoddoedofdogdohdoidojdokdoldomdomdomdondqodopdnednednedpedpfdpgdphdpidpjdsRdnedpldpmdpndpodppdpqdqndnedpsdcGdpLdpMdpPaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdngdoGdoHdoHecTdoJdmcdoLdoMdoNdoOdoPdoQdoRdoPdoPdoOdoSdoTdoUdoVdoWdoXdoYdoZdpadpbdoYdfkcUKdpddnedpQdpRdpUdqkdqldqmdnedoEdoEdnedqOdqpdpqdqqdqrdqsdqtdnedqudqvdcGdqwdpPaafaafaafaafaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdngdptdoHdoHdoIdoJdmcdoLdpudpvdoOdpwdpxdpydpzdpAdoOdpBdpBdpCdpBdpDdpEdpFdpGdpFdpHdpIdpJcUKdpKdnednednednedqxdnednhdnednednednedqydqzdpqdsbdqAdpqdqtdnedqBdcGcZScZScZScZSaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmIdpSdoKdpTdpTdnSdmIdmKdpVdpudpWdoPdpXdpYdpZdpXdpXdqadqbdqcdqddqcdqedpEdqfdqgdqhdpFdqidfkcUKdqjdqCdqSdqTdqUdqVdqWdqXdqYdqZdradrbdrcdrddredrfdrydrydrydrzdrAdrBdhhdrCdrDdpPaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdngdqDdqDdqDdnidnidmKdqEdpudqFdoPdqGdqHdqIdqJdqKdoOdqLdqMdqNdqcdqPdpEdrsdqQdqRdpFdqidfkdsLdqjdqCdqSdrEdpqdpqdrFdrGdrGdrHdrGdrIdrJdrKdrGdrLdrGdrMdscdnedsddsedsfdcGdsgdpPaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdmHdmHdmIdmHdmHdrtdmKdrhdridrjdoOdrkdrldrmdrndrodoOdrpdrqdrrdqcdrXdpEdrYdrudrvdrwdrxdfkdtrdtsdsidsjdskdsldsmdrGdrGdsndnDdpqdsodnednednedspdnednednednedsEdsFdhhdsGdsHdpPaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdngdqDdqDdqDdnidnidmKdqEdpudqFdoPdqGdqHdqIdqJdqKdoOdqLdqMdqNdqcdqPdpEdrsdqQdqRdpFdqidfkdsLdqjdqCdqSdrEdpqdpqdrFdrGdrGdrHdrGdrIdrJdrKdrGdrLdrGdrMdrtdnedsddsedsfdcGdsgdpPaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmHdmHdmHdmIdmHdmHdscdmKdrhdridrjdoOdrkdrldrmdrndrodoOdrpdrqdrrdqcdrXdpEdrYdrudrvdrwdrxdfkdtrdtsdsidsjdskdsldsmdrGdrGdsndnDdpqdsodnednednedspdnednednednedsEdsFdhhdsGdsHdpPaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmKdmKdmKdmKdmKdmKdmKdrNdrOdpWdoPdrPdrQdrRdrSdrTdoOdrUdqcdrVdrWdCFdpEdCZdrZdsadpFdqidfkcUKdXTdsIdsJdsKdsMdsNdrGdrGdsndpqdpqdsOdsPdnedpqdsQdshdnedsSdnedtkdtldhhdhhcZScZSaafaafaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmKdsqdsrdqFdoPdssdpxdssdstdsudoOdsvdqcdswdqcdsxdpEdsydszdsAdpFdsBdsCcTAdsDdsIdtmdtndtodsNdrGdrGdsndpqdtpdpqdpqdnhdpmdtqdttdnedtudnedtvdFLcZSaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsTdsTdsTdsTdsTaaaaaaaaaaaaaaaaaadmKdsUdsVdoXdoOdsWdsXdsYdssdsZdtadtbdtcdtddtcdtedpEdpEdpEdpEdtfdtgdthdtidtjdtgdHddUXdUYdUZdVadrGdsndpqdpqdVbdVcdnhdVddVedVfdnedsSdnedVgdVtcZSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsTdsTdsTdsTdsTaaaaaaaaaaaaaaaaaadmKdsUdsVdoXdoOdsWdsXdsYdssdsZdtadtbdtcdtddtcdtedpEdpEdpEdpEdtfdtgdthdtidtjdtgdHddUXdUYdUZdVadrGdsndpqdpqdVbdVcdnhdCmdVedVfdnedsSdnedVgdVtcZSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsTdsTdsTdsTdsTdsTdsTaaaaaaaaaaaadtgdtgdtwdtxdtydoOdoOdoPdoPdoPdoOdoOdtzdpBdpBdpBdtzdtAdtBdtCdtydtDdtCdtxdtEdtwdtFdtgdtAedledledledldtAdnednednednednednednednednednednedtHdtIdtgdtgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsTdsTdsTdsTdsTdsTdsTaaaaaaaaaaaadtgdtJdtKdtLdtLdtGdtMdtNdtOdtPdtQdtPdtRdtSdtTdtUdtTdtVdtKdtLdtLdtWdtLdtXdtYdtKdtLdtWdtLdtXdtLdtZdtTdtPdtTdtSduadtUdtQdtPdubdtNdtMdtGdtLducdudduedtgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadufdufaaaaaaaaaaaaaaadufdufaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsTdsTdsTdsTdsTdsTdsTaaaaaaaaaaaadtgdugduhduidujdukdulduldumdulduldujdundulduldumduldulduodulduldukduldupduqduoduldukduldumduldulduldujduldurdusdumdulduldujdulduldukdujdutduuduvdtgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadufdufdufaaaaaaaaadufdufdufaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11647,7 +11647,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaafaaaaaaaaaaaaaaaaafdAVdAVdAVdAVdAVdAVdAVdAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdBadAVdAVdAVdAVdBcdBcdBcdBIdBJdBKdBLdBLdBLdCedBmdBNdBcdBcdBcdAVdAVdAVdAVdBadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBraaaaaadBrdBrdBrdBrdBrdBrdBrdBrdBraaaaaadBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaafaafaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdBPdBcdBcdBQdBRdBSdBTdBUdBVdBWdBXdBYdBZdCadBcdBcdCbdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBraaaaaadBrdBrdBrdBrdBrdBrdBrdBrdBraaaaaadBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaadaadaaaaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdCcdCcdCcdCcdCcdCcdCcdAVdAVdAVdAVdAVdAVdAVdBcdBcdBcdBIdBJdBKdBLdCddBLdCedBmdBNdBcdBcdBcdAVdAVdAVdAVdAVdAVdAVdCfdCfdCfdCfdCfdCfdCfdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaagaafaaaaafaaaaaaaaaaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdAVdAVdAVdAVdAVdCgdChdChdChdChdCidCjdCkdCldCmdCcdAVdAVdAVdAVdAVdCndCodCodCpdCpdCqdCrdCsdBLdBLdBLdBAdCtdCudBcdBcdAVdAVdAVdAVdAVdAVdAVdAVdCfdCvdCwdCxdCydCzdCAdCAdCAdCAdCBdAVdAVdAVdAVdAVdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaagaafaaaaafaaaaaaaaaaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdBGdBHdBudAVdAVdAVdAVdAVdAVdCgdChdChdChdChdCidCjdCkdCldHrdCcdAVdAVdAVdAVdAVdCndCodCodCpdCpdCqdCrdCsdBLdBLdBLdBAdCtdCudBcdBcdAVdAVdAVdAVdAVdAVdAVdAVdCfdCvdCwdCxdCydCzdCAdCAdCAdCAdCBdAVdAVdAVdAVdAVdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdBDdBOdBFdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdCCdAVdAVdAVdCCdAVdAVdAVdCCdAVdAVdAVdCCdAVdAVdAVdCCdAVdAVdCDdAVdCEdCEdCEdCgdFMdCGdCHdCIdCJdCldCldCldCKdCcdAVdAVdAVdAVdAVdCLdAVdAVdBcdBcdBcdCMdCNdCOdDvdCOdCQdCRdBcdBcdBcdAVdAVdAVdAVdAVdAVdAVdAVdCfdCSdCTdCUdCUdCVdCWdCXdCYdFYdCBdDadDadDadAVdAVdAVdAVdDbdAVdAVdAVdDbdAVdAVdAVdDbdAVdAVdAVdDbdAVdAVdAVdDbdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaafaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdDcdDddDddDddDedDddDddDddDedDddDddDddDedDddDddDddDedDddDddDddDedDddDddDfdDgdDhdDidDjdDkdDldDmdDndDodDpdDqdDrdDsdDtdCcaaaaaaaaaaaaaaadDuaaaaaadBcdBcdBcdBjdIqdDwdDxdDydDzdBedBcdBcdBcaaaaaadDAaaaaaaaaaaaaaaadCfdDBdDCdDDdDDdDEdDFdDGdDHdDIdDJdDKdDLdDMdDNdDOdDPdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDQdDRdDSdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdCCdAVdAVdAVdCCdAVdAVdAVdCCdAVdAVdAVdCCdAVdAVdAVdCCdAVdAVdAVdAVdCEdDTdDUdDVdDWdDXdDYdCIdDZdCldEadEbdCcdCcaaaaaaaaaaaaaaadDuaaaaaaaaaaaadBcdBcdBcdBcdEcdBcdBcdBcdBcaaaaaaaaaaaadDAaaaaaaaaaaaaaaadCfdCfdEddEedCUdEfdCWdEgdEhdEidEjdEkdEldDadAVdAVdAVdAVdEmdAVdAVdAVdEmdAVdAVdAVdEmdAVdAVdAVdEmdAVdAVdAVdEmdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11661,7 +11661,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadEnedxdEndEndE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadEndEndEndEndEndEndEndEndEndEndEnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdCcdFKdVudFoaaaaaadAVdAVdAVdAVdAVdAVdCLdAVdFpdOgdFNdFOdFPdFQdFRdFSdFTdFUdFVdFWdFXdOJdFsdAVdAVdAVdAVdAVdAVdAVdAVaaaaaadFudFZdGadCfdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadEndEndEndEndEndEndEndEndEndEndEnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdCcdGbecCdCcaaaaaadGddGedGfdGedGgdGgdGhdGgdGgdGidGjdGkdGldFpdGmdGndGmdFsdGodGpdGqdGrdGsdGtdGudGtdGsdGvdGwdGvdGxaaaaaadCfecDdGzdCfdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBrdBrdBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadEndEndEndEndEndEndEndEndEnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdCcdGAdCldCcaaaaaadGddGBdGCdGDdGEedAedzedBdGgdFpdFpdFpdGIdGJdGKdGLdGMdGNdGOdFsdFsdFsdGsdGPdGQdGRdGSdGTdGUdGVdGxaaaaaadCfdCUdGWdCfdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaafaafaafaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadBrdBrdBrdBrdBrdBrdBraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadEndEndEndEndEndEndEnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaafaafaafaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdCcdGXdGYdCcaaaaaadGddGZdHadHbdGEdeoedCedEdGgdHfdHgdHgdHhdHgdHgdHidHgdHgdHjdHgdHgdHkdGsdHldHmdHndGSdHodHpdHqdGxaaaaaadCfdHrdHsdCfdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadEndEndEndEndEndEndEnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaafaafaafaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdCcdGXdGYdCcaaaaaadGddGZdHadHbdGEdeoedCedEdGgdHfdHgdHgdHhdHgdHgdHidHgdHgdHjdHgdHgdHkdGsdHldHmdHndGSdHodHpdHqdGxaaaaaadCfdOqdHsdCfdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadEndEndEndEndEnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdCcdCcdHtdEqdCcaaaaaadGddHudHvdHwdGEdeOdHyedGdGgdHAdHBdHCdHDdHEdHFdHGdHEdHEdHHdHIdHBdHAdGsdHJdHKdHLdGSdHMdHNdHOdGxaaaaaadCfdEvdHPdCfdCfdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdHQdHQdHRdHSdHTdHUdHVdHWdHXdHYdHYdGddHZdIadIbdGgdfqdGEedIdIddHAdHCdIedIedIedIedIedIedIedIedIedIfdHAdIgdIhdIidGSdGsdIjdIkdIldGxdImdImdIndIodIpdKwdIrdIsdItdIudIudAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdIvdIwdIxdIydIzdIAdIBdICdIDdIEdIFdIGdIHdIIdIJdIKedJdIMedKdIOdIPdIQdIRdIedISdISdISdISdISdIedITdIUdIVdIWdIXdIYdIZdJadJbdIYdJcdJddJedJfdIWdJgdJhdJidJjdJkdJldJmdJndAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11673,8 +11673,8 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdMxdMxdMxdMxdMxdMxdMydMzdKHdMAdMBdMCdMDdMDdMEdKLdMFdMGdMHdKKdMIdMJdMKdMLdMMdMNdMNdMNdMOdMPdMQdMNdMRdKWdMSdMTdMUdKVdMVdMWdMXdLaaaaaaadMYdMZdNadMYdMYdMYdMYdMYdMYdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaadabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaafaafaafaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdMxdNbdNcdKHdKHdKHdKHdKHdKHdKHdKKdKKdKKdKKdKKdNddNedNfdVBdNhdNhdNidNjdNkdNldNmdNndNodKWdKWdKWdKWdKWdLadLadLadLaaaaaaadMYdNpdNqdMYdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdMxdNrdNsdMxaaaaaadNtdNudNvdNwdNxdNydNzdNAdNtdNBdNCdNDdNEdNFdNGdNHdNGdNEdNEdNDdNIdNJdNKdNLdNMdNNdNOdNKdNPdNQdNKaaaaaadMYdNRdNSdMYdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaafaafaafaadaXGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdMxdNbdNTdMxaaaaaadNtdNUdNVdNWdNXdNYdNZdOadNtdObdOcdIedOddOedHBdHAdHBdOfdRfdIedOhdOidNKdOjdOkdOldOmdOndOodOpdNKaaaaaadMYdOqdOrdMYdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdMxdNbdOsdOtaaaaaadOudNydOvdOwdOxdOydOzdOAdOBdOCdODdOEdOddOFdOGdOHdOIdHBdRgdOKdOLdOMdONdOOdOPdOQdORdNKdOSdOTdNKaaaaaadOUdOVdOWdMYdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdMxdNbdNTdMxaaaaaadNtdNUdNVdNWdNXdNYdNZdOadNtdObdOcdIedOddOedHBdHAdHBdOfdRfdIedOhdOidNKdOjdOkdOldOmdOndOodOpdNKaaaaaadMYdOVdOrdMYdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdMxdNbdOsdOtaaaaaadOudNydOvdOwdOxdOydOzdOAdOBdOCdODdOEdOddOFdOGdOHdOIdHBdRgdOKdOLdOMdONdOOdOPdOQdORdNKdOSdOTdNKaaaaaadOUdVddOWdMYdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdMxdOXdOYdOtaaaaaaecEdPadPbdPcdPddPcdPedPfdNtdPgdPhdIedPidPjdPkdPldPmdPndPodIedPpdPqdNKdNKdNKdPrdNKdNKdNKdNKdNKaaaaaadOUdPsdPtdMYdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaaaaaaaaaaafaafdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdMxdPudPvdOtaaaaaadPwdPxdNydNydPydNydNydPzdNtdObdOcdPAdPAdPAdPBdPCdPDdPAdPAdPAdOhdOidNKdPEdPFdPGdPHdPIdUWdPKdNKaaaaaadOUdPLdPMdMYdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaafaaaaaaaaadAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdPNdPOdPPdAVdPNdPOdPPdAVdPNdPOdPPdAVdPNdPOdPPdAVdPNdPOdPPdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdMxdPudPQdMxaaaaaadPRdPSdPTdNydPUdPVdPWdPXdPYdPZdQadQbdQcdQddQedQfdQgdQhdQidQjdQkdQldQmdQndQodQpdQqdQrdQsdQtdNKaaaaaadMYdQudPMdMYdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdQvdQwdQxdAVdQvdQwdQxdAVdQvdQwdQxdAVdQvdQwdQxdAVdQvdQwdQxdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVdAVaafaafaafabcaafaaaaaaaagaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11795,4 +11795,3 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa dUOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} - diff --git a/maps/southern_cross/southern_cross-3.dmm b/maps/southern_cross/southern_cross-3.dmm index 433197e556c..3cf78444ea1 100644 --- a/maps/southern_cross/southern_cross-3.dmm +++ b/maps/southern_cross/southern_cross-3.dmm @@ -1,12 +1,12 @@ "aa" = (/turf/unsimulated/wall/planetary/sif,/area/surface/outside/plains/mountains) "ab" = (/turf/unsimulated/wall/planetary/sif{icon_state = "rock-dark"},/area/surface/outside/plains/mountains) -"ac" = (/turf/simulated/wall/dungeon,/area/surface/outside/path/plains) -"ad" = (/obj/effect/step_trigger/teleporter/mine/to_mining,/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/surface/outside/path/plains) -"ae" = (/obj/effect/step_trigger/teleporter/mine/to_mining,/turf/simulated/floor/water{outdoors = 0},/area/surface/outside/plains/mountains) +"ac" = (/obj/effect/map_effect/perma_light/concentrated/incandescent,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/exterior) +"ad" = (/turf/simulated/wall/dungeon,/area/surface/outpost/mining_main/exterior) +"ae" = (/obj/effect/map_effect/portal/line/side_a,/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/surface/outpost/mining_main/exterior) "af" = (/turf/simulated/mineral/sif,/area/surface/outside/plains/mountains) "ag" = (/obj/effect/zone_divider,/turf/simulated/mineral/sif,/area/surface/outside/plains/mountains) "ah" = (/turf/simulated/mineral/ignore_mapgen/sif,/area/surface/outside/plains/mountains) -"ai" = (/obj/structure/cable/ender{icon_state = "1-2"; id = "surface_cave"},/obj/effect/overlay/snow/floor,/turf/simulated/floor/tiled/steel/sif/planetuse,/area/surface/outside/path/plains) +"ai" = (/obj/effect/map_effect/portal/master/side_a/plains_to_caves,/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/surface/outpost/mining_main/exterior) "aj" = (/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/surface/outside/path/plains) "ak" = (/turf/simulated/floor/water{outdoors = 0},/area/surface/outside/plains/mountains) "al" = (/turf/simulated/floor/outdoors/snow/sif/planetuse,/area/surface/outside/plains/outpost) @@ -364,7 +364,7 @@ "gZ" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/turf/simulated/floor/tiled/steel_dirty,/area/surface/outpost/main/security) "ha" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/turf/simulated/floor/tiled/steel_dirty,/area/surface/outpost/main/security) "hb" = (/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/item/device/gps/explorer{pixel_x = -5; pixel_y = -5},/obj/item/device/gps/explorer{pixel_x = -3; pixel_y = -3},/obj/item/device/gps,/obj/item/device/gps{pixel_x = 3; pixel_y = 3},/obj/effect/floor_decal/borderfloor,/obj/effect/floor_decal/corner/green/border,/turf/simulated/floor/tiled,/area/surface/outpost/main/security) -"hc" = (/obj/structure/closet/crate,/obj/item/stack/material/phoron{amount = 25},/turf/simulated/floor/plating,/area/surface/outpost/mining_main/gen_room) +"hc" = (/obj/item/stack/material/phoron{amount = 25},/obj/random/crate,/turf/simulated/floor/plating,/area/surface/outpost/mining_main/gen_room) "hd" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/structure/closet/secure_closet/explorer,/obj/effect/floor_decal/borderfloor,/obj/effect/floor_decal/corner/green/border,/obj/item/device/binoculars,/turf/simulated/floor/tiled,/area/surface/outpost/main/security) "he" = (/obj/structure/closet/secure_closet/explorer,/obj/effect/floor_decal/borderfloor,/obj/effect/floor_decal/corner/green/border,/turf/simulated/floor/tiled,/area/surface/outpost/main/security) "hf" = (/obj/structure/closet/secure_closet/explorer,/obj/machinery/ai_status_display{pixel_y = -32},/obj/effect/floor_decal/borderfloor,/obj/effect/floor_decal/corner/green/border,/turf/simulated/floor/tiled,/area/surface/outpost/main/security) @@ -1567,12 +1567,19 @@ "Eg" = (/obj/effect/shuttle_landmark{landmark_tag = "syndie_planet"; name = "Sif Surface West"},/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/syndicate_station/planet) "Eh" = (/obj/effect/shuttle_landmark{landmark_tag = "skipjack_planet"; name = "Sif Surface South"},/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/skipjack_station/planet) "Ei" = (/obj/effect/overmap/visitable/planet/Sif,/turf/simulated/mineral/sif,/area/surface/outside/plains/mountains) +"Ej" = (/obj/random/crate,/turf/simulated/floor/tiled/steel_grid,/area/surface/outpost/main/garage) +"Ek" = (/obj/effect/map_effect/portal/line/side_a,/turf/simulated/floor/water{outdoors = 0},/area/surface/outside/plains/mountains) +"El" = (/obj/effect/map_effect/portal/master/side_a/plains_to_caves/river,/turf/simulated/floor/water{outdoors = 0},/area/surface/outside/plains/mountains) +"Em" = (/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/surface/outpost/mining_main/exterior) +"En" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/surface/outpost/mining_main/exterior) +"Eo" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/surface/outpost/mining_main/exterior) +"Ep" = (/obj/effect/overlay/snow/floor,/obj/structure/cable/ender{icon_state = "1-2"; id = "surface_cave"},/turf/simulated/floor/tiled/steel/sif/planetuse,/area/surface/outside/path/plains) (1,1,1) = {" -aaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacadadadabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaeaeaeababababababababab -aaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahaiajajajahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafakakakafafafafafafafafaa -aaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafahahahalalalalalalalalalalalalalalalalalalalahahahahalalalalalalalahahahahalalahahahahamajajajananananalalalalalalalalalalahahahahahahahahahahahahalalalalahahahahahahahahahahahahahahahahahahahahahafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafakakakafafafafafafafafaa -aaafafafafafalalalafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalahahalalalalalalalamajajajaoapaqanalalalalalalalalalalalahahahahahahahahahahalalalalalalahahahahahahahahahahahahahahahahahahahahafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafakakakafafafafafafafafaa +aaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababanacacacanabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababafakakakafabababababababab +aaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahadaiaeaeanahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafElEkEkafafafafafafafafaa +aaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafahahahalalalalalalalalalalalalalalalalalalalahahahahalalalalalalalahahahahalalahahahahadEnEmEoananananalalalalalalalalalalahahahahahahahahahahahahalalalalahahahahahahahahahahahahahahahahahahahahahafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafakakakafafafafafafafafaa +aaafafafafafalalalafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalahahalalalalalalalEpajajajaoapaqanalalalalalalalalalalalahahahahahahahahahahalalalalalalahahahahahahahahahahahahahahahahahahahahafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafakakakafafafafafafafafaa aaafafafalalalalalalalafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalamajajajarasatanalalalalalalalalalalalalalahahahahahahalalalalalalalalalahahahahahahahahahahahahahahahahahahahafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafakakakafafafafafafafafaa aaafafafalalalalalalalalafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalauavavavawaxayanalalalalalalalalalalalalalalalalalalalalalalalalalalalalalahahahahahahahahahahahahahahahahahahafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafakakakafafafafafafafafaa aaafafafalalalalalalalalalafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalazajajajananananalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalahahahahahahahahahahahahahahahahahafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafakakakafafafafafafafafaa @@ -1606,7 +1613,7 @@ aaafafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalctctctctctct aaafafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalctctctctctctctctctalalalalalalalalalalalalalalalalalalalalaFalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalajajgIgIhshthuhvhwhxhyhzhyhAgIgIgIgIgIgIgIalalalalamajajajajajalalalalalalbHhBhBhBhBhBhChChChChChDhihEhFhFhFhFhFhGhGhGhFhFalalalalalalalalalalalafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaAaAaAaAaCaJaDaDaDaDaDaDcUcUcUcUcUcUcUcUcUcUcUcUcUaM aaafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalctctctctctctctalalalalalalalalalalalalalalalalalalalalalaFalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalajajajgIhHhIhyhJhKhLhMhNhOhPhQhRhShShTgIalalalalalamajajajajalalalalalalalalhBhUhVhWhBhYiahZizibhDhihEhFicidieifigihiiijhFalalalalalalalalalalalafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaAaAaAaAaAaGaDaDaDaDaDaDaDcUcUcUcUcUcUcUcUcUcUcUcUcUaM aaafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalctctctctctalalalalalalalalalalalalalalalalalalalalalalaFalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalajajajgIikhIhyiliminioipiqirisisitiuivgIalalalalalamajajajalalalalalalalalalhBiwixiyhBiAiYiBjmhCiCiDiEhFiFiGiGiGiHiHiGiIhFalalalalalalalalalalalafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaAaAaAaAaCaJaDaDaDaDaDaDcUcUcUcUcUcUcUcUcUcUcUcUcUcUaM -aaafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalaFalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalajajgIiJiKiLhJhyiMiNiOiPiQiRiSiTiUiVgIalalalalalamajajajalalalalalalalalalhBhBiWhBhBiXjEiZjahChDhijbhFiHiHjciiiiiHiHiGhGalalalalalalalalalalalafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaAaAaAaAaGaDaDaDaDaDaDcUcUcUcUcUcUcUcUcUcUcUcUcUcUcUaM +aaafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalaFalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalajajgIiJiKiLhJhyiMiNiOiPiQiRiSiTiUiVgIalalalalalamajajajalalalalalalalalalhBhBiWhBhBiXjEiZjahChDhijbhFiHiHjciiiiiHiHEjhGalalalalalalalalalalalafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaAaAaAaAaGaDaDaDaDaDaDcUcUcUcUcUcUcUcUcUcUcUcUcUcUcUaM aaafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalaFalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalajajgIgIjdjejfjggIgIjhgIgIjijjjkjkgIgIalalalalalamajajajalalalalalalalalaljlmMjnjojphChCjqhChCjrhijshGjtiHjujvjwiGiHiHhGalalalalalalalalalalalafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaAaAaAaAaGaDaDaDaDaDaDcUcUcUcUcUcUcUcUcUcUcUcUcUcUcUaM aaafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalaFalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalajajajgIgIgIgIjxgIjyjzjygIgIgIgIgIgIalalalalalalamajajajalalalalalalalalaljljAjWjCjDjHjFjGjKjIfYhijJhGqUiHjLiHiGiGiHiHhGaljMjMalalalalalalalalafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaAaAaCaJaDaDaDaDaDcUcUcUcUcUcUcUcUcUcUcUcUcUcUcUcUaM aaafalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalaFalalalalalalalalalalalalalalalalalalalalalalalalalalalalajajajalalalalajajajjNjOjOjOjPjOjOjQjRjRjRjRjRjRjRjRjRjRjRjRjRjSjRjRjRjTjTjTjTjTjTjTjTjTjUjVlSjXjYjZkakbkakckakdkekfkgkhkikhkhkjiHiHhGalaljMalalalalalalalalafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaAaAaAaGaDaDaDaDaDaDcUcUcUcUcUcUcUcUcUcUcUcUcUcUcUcUaM diff --git a/maps/southern_cross/southern_cross-4.dmm b/maps/southern_cross/southern_cross-4.dmm index 6329f2a1ec0..b91bcc7f33d 100644 --- a/maps/southern_cross/southern_cross-4.dmm +++ b/maps/southern_cross/southern_cross-4.dmm @@ -124,10 +124,10 @@ "ct" = (/obj/structure/table/standard,/obj/item/device/flashlight/lamp,/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_a) "cu" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/isolation_a) "cv" = (/turf/simulated/wall/r_wall,/area/surface/outpost/mining_main/cave) -"cw" = (/obj/effect/step_trigger/teleporter/wild/to_wild,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"cw" = (/obj/effect/map_effect/perma_light/concentrated/incandescent,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) "cx" = (/turf/simulated/shuttle/wall/voidcraft,/area/surface/outpost/wall/checkpoint) -"cy" = (/obj/structure/showcase/sign{pixel_y = -5},/turf/simulated/wall/dungeon,/area/surface/cave/unexplored/deep) -"cz" = (/obj/effect/step_trigger/teleporter/wild/to_wild,/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/deep) +"cy" = (/turf/simulated/wall/dungeon,/area/surface/cave/unexplored/deep) +"cz" = (/obj/effect/map_effect/portal/master/side_a/caves_to_wilderness,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) "cA" = (/turf/simulated/wall/r_wall,/area/surface/outpost/research/xenoarcheology/medical) "cB" = (/obj/machinery/sleeper{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) "cC" = (/obj/machinery/sleep_console,/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/medical) @@ -213,7 +213,7 @@ "ee" = (/obj/machinery/door/blast/regular{id = "xenoarch_cell2"},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) "ef" = (/turf/simulated/shuttle/wall/voidcraft/hard_corner,/area/surface/outpost/wall/checkpoint) "eg" = (/obj/structure/showcase/sign{pixel_y = -5},/turf/simulated/shuttle/wall/voidcraft,/area/surface/outpost/wall/checkpoint) -"eh" = (/obj/item/weapon/banner/nt,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"eh" = (/obj/effect/map_effect/portal/line/side_a,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) "ei" = (/obj/item/weapon/banner/nt,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) "ej" = (/obj/structure/sign/greencross{desc = "White cross in a green field, you can get medical aid here."; name = "First-Aid"},/turf/simulated/wall,/area/surface/outpost/research/xenoarcheology/medical) "ek" = (/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor/tiled/neutral,/area/surface/outpost/research/xenoarcheology) @@ -229,7 +229,7 @@ "eu" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) "ev" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 10},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) "ew" = (/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor/reinforced,/area/surface/outpost/research/xenoarcheology/isolation_b) -"ex" = (/obj/machinery/light/small{dir = 1},/obj/item/weapon/banner/virgov,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"ex" = (/obj/structure/showcase/sign{pixel_y = -5},/turf/simulated/wall/dungeon,/area/surface/cave/explored/deep) "ey" = (/obj/structure/table/steel,/obj/item/weapon/tool/screwdriver,/obj/item/weapon/tool/crowbar,/obj/item/weapon/tool/wrench,/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 1},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) "ez" = (/obj/effect/floor_decal/industrial/warning{dir = 9},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) "eA" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 5},/obj/machinery/camera/network/research_outpost{c_tag = "OPR - Xenoarch Airlock 1"; dir = 8},/turf/simulated/floor/tiled,/area/surface/outpost/research/xenoarcheology) @@ -418,38 +418,60 @@ "ib" = (/obj/machinery/radiocarbon_spectrometer,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/tiled/dark,/area/surface/outpost/research/xenoarcheology/analysis) "ic" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/emergency,/obj/item/clothing/accessory/armband/science,/obj/item/clothing/glasses/science,/obj/item/device/suit_cooling_unit,/obj/item/weapon/extinguisher,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/emergencystorage) "id" = (/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/outpost/research/xenoarcheology) -"ie" = (/turf/simulated/wall/dungeon,/area/surface/cave/unexplored/normal) +"ie" = (/obj/effect/map_effect/portal/line/side_a,/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/deep) "if" = (/obj/item/stack/flag/green,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) "ig" = (/obj/item/stack/flag/red{amount = 1},/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) "ih" = (/obj/structure/table/standard,/obj/item/weapon/flame/lighter/random,/obj/item/weapon/tool/crowbar,/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{dir = 8},/turf/simulated/floor/tiled/white,/area/surface/outpost/research/xenoarcheology/anomaly) "ii" = (/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 8},/obj/machinery/light/small,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"ij" = (/obj/structure/cable/heavyduty{icon_state = "2-8"},/obj/structure/cable/heavyduty{icon_state = "2-4"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) +"ij" = (/obj/effect/map_effect/portal/master/side_a/caves_to_wilderness/river,/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/deep) "ik" = (/obj/machinery/light/small,/obj/effect/floor_decal/industrial/warning/dust{icon_state = "warning_dust"; dir = 4},/obj/structure/cable/heavyduty{icon_state = "4-8"},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) "il" = (/obj/structure/cable/heavyduty{icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) "im" = (/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) -"in" = (/obj/structure/cable/heavyduty{icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) +"in" = (/obj/item/weapon/banner/nt,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/cave/explored/deep) "io" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{icon_state = "intact"; dir = 6},/turf/simulated/floor/plating,/area/surface/outpost/research/xenoarcheology/smes) -"ip" = (/obj/structure/cable/ender{icon_state = "1-2"; id = "surface_cave"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/cave/explored/normal) +"ip" = (/obj/item/weapon/banner/virgov,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/cave/explored/deep) +"iq" = (/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/unexplored/deep) "ir" = (/obj/machinery/mining/brace,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) "is" = (/obj/machinery/mining/drill,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) "it" = (/obj/vehicle/train/engine,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) "iu" = (/obj/vehicle/train/trolley,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"iv" = (/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/cave/explored/deep) "iw" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/heavyduty{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) "ix" = (/obj/structure/cable/heavyduty{icon_state = "4-8"},/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +"iy" = (/obj/structure/cable/heavyduty{icon_state = "2-8"},/obj/structure/cable/heavyduty{icon_state = "2-4"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/outpost/mining_main/cave) "iz" = (/obj/effect/floor_decal/industrial/warning/dust,/obj/structure/ore_box,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) +<<<<<<< HEAD "iA" = (/obj/effect/step_trigger/teleporter/mine/from_mining,/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/cave/explored/normal) "iB" = (/obj/effect/step_trigger/teleporter/mine/from_mining,/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/normal) +======= +"iA" = (/obj/structure/cable/heavyduty{icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/outpost/mining_main/cave) +"iB" = (/turf/simulated/mineral/sif,/area/surface/cave/explored/normal) +"iC" = (/turf/simulated/wall,/area/surface/cave/explored/normal) +"iD" = (/obj/structure/cable/ender{icon_state = "1-2"; id = "surface_cave"},/turf/simulated/floor/plating{icon_state = "asteroidplating2"},/area/surface/outpost/mining_main/cave) +"iE" = (/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/outpost/mining_main/cave) +"iF" = (/turf/simulated/wall,/area/surface/outpost/mining_main/cave) +"iG" = (/turf/simulated/wall/dungeon,/area/surface/outpost/mining_main/cave) +"iH" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/outpost/mining_main/cave) +"iI" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/outpost/mining_main/cave) +"iJ" = (/obj/effect/map_effect/portal/line/side_b{icon_state = "portal_line_side_b"; dir = 1},/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/outpost/mining_main/cave) +"iK" = (/obj/effect/map_effect/portal/master/side_b/caves_to_plains{icon_state = "portal_side_b"; dir = 1},/turf/simulated/mineral/floor/ignore_mapgen/sif,/area/surface/outpost/mining_main/cave) +"iL" = (/obj/effect/map_effect/portal/line/side_b{icon_state = "portal_line_side_b"; dir = 1},/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/normal) +"iM" = (/obj/effect/map_effect/portal/master/side_b/caves_to_plains/river{icon_state = "portal_side_b"; dir = 1},/turf/simulated/floor/water{outdoors = 0},/area/surface/cave/explored/normal) +"iN" = (/turf/unsimulated/wall/planetary/sif,/area/surface/cave/explored/normal) +"iO" = (/obj/effect/map_effect/perma_light/concentrated,/turf/simulated/floor/tiled/asteroid_steel,/area/surface/outpost/mining_main/cave) + +>>>>>>> 0abf36f... Merge pull request #7378 from Neerti/portals (1,1,1) = {" -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxcwcwcwcxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyczczczaaaaaaaaaaaaaaaaaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcxcXcZcYcxababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsababababababababaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxcwcwcwcxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacydsdsdsabaaaaaaaaaaaaaaaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcxczehehcxababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababexijieieababababababababaa aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcxcZcZcZcxababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacdsdsdsacabababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababefdtegdtefabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacdsdsdsacacababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacehcZcZcZexacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacaccZcZcZacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsabacababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacgoabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgoacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa -aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcxcXcZcYcxabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacdsdsdsacacababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacefdtegdtefacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacincZcZcZipacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsabacababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababiqacivivivacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababiqiqacacacacacacgoabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababiqgoacacacacacacababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa +aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababiqacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacacababababababaa aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsacabababababababaa aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdsdsdsababababababababaa @@ -685,14 +707,15 @@ adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimiugtafafafidamfkflamfmfnfofpfqfrfsftaxfudkdkfvfwfxfyfzfAfBfCafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsirisirimimgtafafafeifDfDfDfDfEfFfGfHfDfIfJfKfLfMfNfOfPfQesfRfSfTfUfCafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegsimimimimimgtafafafaffDfVfWfXfYfZgagbgcgdgegdavgfggghgibNgjgkglgmgnfCafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiiimimiwixixikijilililgugvgwgwgxgygzgAgdgBgCgDgEgFgGgFgFgHgIgJgKgKgKgKafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaecvizizcvizizcvinafafaffDgNgwgOgPgQgRgSgdgTgUgVgdgWgXgYgZhahbhchdhehfgKaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafaffDhggwgOhhhihjhkgdhlhmhngdhohphqhrhshthuhvhwhxgKaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafaffDhygwiohAhBhChDgdhEhFhGgdhHhIhJhKhLhMhLhdhNhOgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafaffDfDhPhQhRhShThUfDgEgEgEgJhVhWhXhYhZiaibhdicgKgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafafaefDfDfDfDfDfDfDfDaeaeaegJgJgFgJgJgFgJgJgKgKgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeinafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeipafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead -adadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadieiAiAiAadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadiBiBiBadadadadadadadadad +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiiimimiwixixikiyilililgugvgwgwgxgygzgAgdgBgCgDgEgFgGgFgFgHgIgJgKgKgKgKafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaecvizizcvizizcviAafafaffDgNgwgOgPgQgRgSgdgTgUgVgdgWgXgYgZhahbhchdhehfgKaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiAafafaffDhggwgOhhhihjhkgdhlhmhngdhohphqhrhshthuhvhwhxgKaeafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiAafafaffDhygwiohAhBhChDgdhEhFhGgdhHhIhJhKhLhMhLhdhNhOgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiBiAafafaffDfDhPhQhRhShThUfDgEgEgEgJhVhWhXhYhZiaibhdicgKgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafgLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiBiAafafafiCfDfDfDfDfDfDfDfDaeaeaegJgJgFgJgJgFgJgJgKgKgKaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiBiDiEiEiEiFaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiBiGiHiEiIiGaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafafafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaegLgLgLaeaeaeaeaeaeaeaead +adaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiBiGiKiJiJiGaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeiMiLiLaeaeaeaeaeaeaeaead +adadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadiNiFiOiOiOiFadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadadaegLgLgLaeadadadadadadadad "} + diff --git a/maps/southern_cross/southern_cross-6.dmm b/maps/southern_cross/southern_cross-6.dmm index 8d40ebf0329..b7a4a729f46 100644 --- a/maps/southern_cross/southern_cross-6.dmm +++ b/maps/southern_cross/southern_cross-6.dmm @@ -644,7 +644,7 @@ "mt" = (/obj/item/weapon/stool/padded,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "mu" = (/obj/machinery/biogenerator,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "mv" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) -"mw" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cooker/fryer,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mw" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/appliance/cooker/fryer,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "mx" = (/obj/machinery/computer/card/centcom{dir = 4},/obj/item/weapon/card/id/centcom,/turf/unsimulated/floor{dir = 2; icon_state = "dark"},/area/centcom/creed) "my" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) "mz" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/response_ship/start) @@ -660,7 +660,7 @@ "mJ" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeobserve) "mK" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/main_hall) "mL" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/closet/secure_closet/freezer/fridge,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) -"mM" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cooker/grill,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mM" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/appliance/cooker/grill,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "mN" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/sink/kitchen{pixel_y = 28},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "mO" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) "mP" = (/obj/machinery/button/remote/blast_door{id = "crescent_thunderdome"; name = "Thunderdome Access"; pixel_x = 6; pixel_y = -24; req_access = list(101)},/obj/machinery/button/remote/blast_door{id = "crescent_vip_shuttle"; name = "VIP Shuttle Access"; pixel_x = 6; pixel_y = -34; req_access = list(101)},/obj/machinery/button/remote/blast_door{id = "crescent_checkpoint_access"; name = "Crescent Checkpoint Access"; pixel_x = -6; pixel_y = -24; req_access = list(101)},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) @@ -668,7 +668,7 @@ "mR" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/response_ship/start) "mS" = (/turf/space,/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"; dir = 8},/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/response_ship/start) "mT" = (/obj/machinery/computer/pod{id = "thunderdomegen"; name = "Thunderdome General Supply"},/turf/unsimulated/floor{icon_state = "lino"},/area/tdome/tdomeadmin) -"mU" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cooker/oven,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"mU" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/appliance/cooker/oven,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "mV" = (/obj/structure/table/standard{name = "plastic table frame"},/obj/item/weapon/material/knife/machete/hatchet,/obj/item/weapon/material/knife/machete/hatchet,/obj/item/weapon/material/minihoe,/obj/item/weapon/material/minihoe,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "mW" = (/obj/machinery/smartfridge/drying_rack,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "mX" = (/obj/structure/table/standard{name = "plastic table frame"},/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) @@ -704,7 +704,7 @@ "nB" = (/obj/machinery/flasher{id = "flash"; name = "Thunderdome Flash"},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) "nC" = (/obj/machinery/seed_extractor,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "nD" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) -"nE" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cooker/candy,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"nE" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/appliance/mixer/candy,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "nF" = (/obj/machinery/door/blast/regular{id = "CentComPort"; name = "Security Doors"},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) "nG" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/main_hall) "nH" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/command) @@ -730,7 +730,7 @@ "ob" = (/obj/structure/table/marble,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/material/kitchen/rollingpin,/obj/effect/floor_decal/corner/white/diagonal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "oc" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "od" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/structure/table/marble,/obj/item/weapon/reagent_containers/food/condiment/enzyme,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) -"oe" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/cooker/cereal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) +"oe" = (/obj/effect/floor_decal/corner/white/diagonal,/obj/machinery/appliance/mixer/cereal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/bar) "of" = (/obj/structure/table/reinforced,/obj/item/weapon/card/id/gold/captain/spare,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) "og" = (/obj/structure/table/reinforced,/obj/item/device/pda/captain,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/command) "oh" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_bay_door"; locked = 1},/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/centcom/command) @@ -2174,7 +2174,7 @@ "PP" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/machinery/computer/station_alert{dir = 4},/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) "PQ" = (/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/obj/machinery/computer/security{dir = 8},/turf/simulated/shuttle/floor/voidcraft/light,/area/ninja_dojo/start) "PR" = (/obj/structure/closet/crate/freezer/rations,/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start) -"PS" = (/obj/item/weapon/cigbutt,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) +"PS" = (/obj/item/trash/cigbutt,/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) "PT" = (/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start) "PU" = (/obj/machinery/light{dir = 1},/obj/structure/table/steel,/obj/item/roller,/obj/item/roller,/obj/item/roller,/obj/item/device/defib_kit/compact/combat/loaded,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) "PV" = (/obj/structure/closet/secure_closet/medical_wall{pixel_y = 32; req_access = list(150)},/obj/item/bodybag,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/glass/bottle/antitoxin{pixel_x = -4; pixel_y = 8},/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline{pixel_x = 4; pixel_y = 7},/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/storage/firstaid/combat,/obj/item/weapon/storage/firstaid/clotting,/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start) @@ -2319,7 +2319,7 @@ "SE" = (/obj/effect/floor_decal/sign/small_g,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_chess) "SF" = (/obj/effect/floor_decal/sign/small_f,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_chess) "SG" = (/obj/effect/floor_decal/sign/small_h,/turf/simulated/floor/holofloor/wood,/area/holodeck/source_chess) - + (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/maps/southern_cross/southern_cross-8.dmm b/maps/southern_cross/southern_cross-8.dmm index bfbedbcfdfe..cc706e90981 100644 --- a/maps/southern_cross/southern_cross-8.dmm +++ b/maps/southern_cross/southern_cross-8.dmm @@ -62,15 +62,15 @@ "bj" = (/obj/structure/table/steel,/obj/machinery/cell_charger,/turf/simulated/floor/plating/external,/area/surface/outpost/shelter) "bk" = (/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/surface/outside/wilderness/mountains) "bl" = (/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"bm" = (/obj/item/weapon/banner/nt,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"bn" = (/obj/item/weapon/banner/virgov,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"bm" = (/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outside/path/wilderness) +"bn" = (/obj/item/weapon/banner/nt,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outside/path/wilderness) "bo" = (/turf/simulated/shuttle/wall/voidcraft/hard_corner,/area/surface/outpost/wall/checkpoint) "bp" = (/obj/machinery/door/airlock/voidcraft{name = "Wilderness Containment"},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) "bq" = (/turf/simulated/shuttle/wall/voidcraft,/area/surface/outpost/wall/checkpoint) "br" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) "bs" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"bt" = (/obj/effect/step_trigger/teleporter/wild/from_wild,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) -"bu" = (/obj/effect/step_trigger/teleporter/wild/from_wild,/turf/simulated/floor/water,/area/surface/outside/ocean) +"bt" = (/obj/item/weapon/banner/virgov,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outside/path/wilderness) +"bu" = (/obj/effect/map_effect/portal/master/side_b/wilderness_to_caves{icon_state = "portal_side_b"; dir = 1},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) "bv" = (/obj/structure/closet/crate,/obj/random/powercell,/obj/item/weapon/tool/screwdriver,/turf/simulated/floor/plating/external,/area/surface/outpost/shelter) "bw" = (/obj/random/junk,/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "mining_dock_1"; name = "shuttle bay controller"; pixel_x = 0; pixel_y = -26; tag_door = "mining_dock_1_door"},/turf/simulated/floor/plating/external,/area/surface/outpost/shelter) "bx" = (/obj/item/weapon/banner/virgov,/turf/simulated/floor/plating/external,/area/surface/outpost/shelter) @@ -78,6 +78,10 @@ "bz" = (/obj/machinery/space_heater,/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "mining_dock_2"; name = "shuttle bay controller"; pixel_x = 0; pixel_y = -26; tag_door = "mining_dock_2_door"},/turf/simulated/floor/plating/external,/area/surface/outpost/shelter) "bA" = (/obj/effect/shuttle_landmark{docking_controller = "mining_dock_2"; landmark_tag = "shuttle2_mining"; name = "Wilderness Landing Site"},/turf/simulated/floor/outdoors/grass/sif/planetuse{tree_chance = 0},/area/shuttle/shuttle2/mining) "bB" = (/obj/effect/shuttle_landmark{docking_controller = "mining_dock_1"; landmark_tag = "shuttle1_mining"; name = "Wilderness Landing Site"},/turf/simulated/floor/outdoors/dirt/sif/planetuse,/area/shuttle/shuttle1/mining) +"bC" = (/obj/effect/map_effect/portal/line/side_b{icon_state = "portal_line_side_b"; dir = 1},/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) +"bD" = (/obj/effect/map_effect/portal/line/side_b{icon_state = "portal_line_side_b"; dir = 1},/turf/simulated/floor/water,/area/surface/outside/ocean) +"bE" = (/obj/effect/map_effect/portal/master/side_b/wilderness_to_caves/river{icon_state = "portal_side_b"; dir = 1},/turf/simulated/floor/water,/area/surface/outside/ocean) +"bF" = (/obj/effect/map_effect/perma_light/concentrated/incandescent,/turf/simulated/shuttle/floor/voidcraft/external,/area/surface/outpost/wall/checkpoint) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaaaaaaaaaaaaababaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -327,12 +331,13 @@ aaacacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatat aaacacacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataDatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataGatatatatatataGaGaGaGaGaGaGaGaGaGaGaGaGaGapapaGaGaGaGaGaWaWaWaWaWaWaWaWaWaGaGaGaWaWaWaWaGaGaGaGaGaGaGaGaGaGbaaZbabcbaaZbaaGaWaWaWaGaWaWaWaWaWaWaWaGaWaWaWaWaWaWaWaGaGaWaWaWaWaGaGaGaHaWaWaWaWaWaWaWaWaWaWaWaWaWaWaWaGaGaGaGaGaGaGaGaGaGaGaGaGaGaMaMaMaKaKaKaKaKaKaKaKaKaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaL aaacacacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataDatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaWaWaWaWaWaWaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGbabdbfbebebebaaGaGaGaGaGaGaGaWaWaWaWaGaGaGaGaGaGaGaGaGaGaGaGaGaGaWaWaWaWbbaWaGaGaWaWaWaWaWaWaWaWaWaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaMaMaMaMaKaKaKaKaKaKaKaKaKaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaL aaacacacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataDatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataGatataGaGatataGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaWaWaWaWaWaWaWaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGbabgbhbebebibaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaHaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaMaMaMaKaKaKaKaKaKaKaKaKaKaKaNaNaNaNaNaNaNaNaNaNaKaKaKaKaKaKaL -aaacacacacacacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataDatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataGaGatataGatataGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaWaWaWaWaWaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGbabjbebebebvbaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaHaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaMaMaMaKaKaKaKaKaKaKaKaKaKaKaKaKaNaNaNaNaNaNaNaKaKaKaKaKaKaKaL -aaacacacacacacacacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataDatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataGatataGatataGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaWaWaWaWaWaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGbabwbybxbebzbaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaHaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaMaMaMaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaL -aaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataDatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataGaGatataGataGaGaGaGaGaGaGacacacacacacacbkaWblblblaWbkacacacaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGbababababababaaGaGaGacacacacacacacacacacaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaHaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGacacacacacacacacaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaL -aaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacatatatatatatatatatatatatatatatacacacacadacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatacacacacacacacacacacacacacacacacacacbmblblblbnacacacacacacacacacacacacacacacaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaGaGaGadacacacacacacacacaGaGaGaGaGaGaGaGaGaGaGaGaGaGacacacacacacacacacacacacacacacacaKaKaKacacacacaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaL -aaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacatatatatatatatatatatatatatatatatatacacacacacacacacacacacacacacacacacacacacacacacacbobpbqbpboacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaKaKaKaKaKaKaKaKaKaKaKacacaKaL +aaacacacacacacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataDatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataGaGatataGatataGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGapaWaWaWaWaWaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGbabjbebebebvbaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaHaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaMaMaMaKaKaKaKaKaKaKaKaKaKaKaKaKaNaNaNaNaNaNaNaKaKaKaKaKaKaKaL +aaacacacacacacacacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataDatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataGatataGatataGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaWbmbmbmaWaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGbabwbybxbebzbaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaHaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaMaMaMaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaL +aaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataDatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatataGaGatataGataGaGaGaGaGaGaGacacacacacacacbkbnblblblbtbkacacacaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGbababababababaaGaGaGacacacacacacacacacacaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaHaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGacacacacacacacacaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaL +aaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacatatatatatatatatatatatatatatatacacacacadacacacacacacatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatatacacacacacacacacacacacacacacacacacacbobpbqbpboacacacacacacacacacacacacacacacaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaGaGaGadacacacacacacacacaGaGaGaGaGaGaGaGaGaGaGaGaGaGacacacacacacacacacacacacacacacacaKaKaKacacacacaKaKaKaKaKaKaKaKaKaKaKaKaKaKaKaL +aaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacatatatatatatatatatatatatatatatatatacacacacacacacacacacacacacacacacacacacacacacacacbqbrblbsbqacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaKaKaKaKaKaKaKaKaKaKaKacacaKaL aaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacbqblblblbqacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaKaKaKaKaKaKaKacacacacacacaa -aaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacbqbrblbsbqacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacaKaKaKacacacacacacacacaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqbtbtbtbqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabububuaaaaaaaaaaaaaaaaaa +aaacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacbqbubCbCbqacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacadacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacacbEbDbDacacacacacacacacaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqbFbFbFbqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaKaKaKacaaaaaaaaaaaaaaaa "} + diff --git a/maps/southern_cross/southern_cross_areas.dm b/maps/southern_cross/southern_cross_areas.dm index bd7cca429ee..471e70c6f9a 100644 --- a/maps/southern_cross/southern_cross_areas.dm +++ b/maps/southern_cross/southern_cross_areas.dm @@ -60,6 +60,7 @@ /area/surface/outside ambience = AMBIENCE_SIF always_unpowered = TRUE + flags = AREA_FLAG_IS_NOT_PERSISTENT // The area near the outpost, so POIs don't show up right next to the outpost. /area/surface/outside/plains/outpost @@ -123,7 +124,7 @@ /area/surface/cave - flags = RAD_SHIELDED + flags = RAD_SHIELDED | AREA_FLAG_IS_NOT_PERSISTENT always_unpowered = TRUE /area/surface/cave @@ -398,7 +399,7 @@ icon_state = "shuttle" requires_power = 0 dynamic_lighting = 1 - flags = RAD_SHIELDED + flags = RAD_SHIELDED | AREA_FLAG_IS_NOT_PERSISTENT /area/turbolift/start name = "\improper Turbolift Start" @@ -753,11 +754,13 @@ name = "\improper Command - HoP's Office" icon_state = "head_quarters" holomap_color = HOLOMAP_AREACOLOR_COMMAND + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/crew_quarters/heads/sc/hor name = "\improper Research - RD's Office" icon_state = "head_quarters" holomap_color = HOLOMAP_AREACOLOR_SCIENCE + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/crew_quarters/heads/sc/chief name = "\improper Engineering - CE's Office" @@ -773,6 +776,7 @@ name = "\improper Medbay - CMO's Office" icon_state = "head_quarters" holomap_color = HOLOMAP_AREACOLOR_MEDICAL + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/engineering/engineer_eva name = "\improper Engineering EVA" @@ -1052,6 +1056,7 @@ area/crew_quarters/heads/sc/hop/quarters name = "\improper Third Deck Plating" dynamic_lighting = 0 ambience = AMBIENCE_SPACE + flags = AREA_FLAG_IS_NOT_PERSISTENT // Shuttles diff --git a/maps/southern_cross/southern_cross_defines.dm b/maps/southern_cross/southern_cross_defines.dm index bf916f23197..bc8ea8e3838 100644 --- a/maps/southern_cross/southern_cross_defines.dm +++ b/maps/southern_cross/southern_cross_defines.dm @@ -93,10 +93,11 @@ Z_LEVEL_STATION_TWO, Z_LEVEL_STATION_THREE, Z_LEVEL_SURFACE, - Z_LEVEL_SURFACE_MINE, - Z_LEVEL_SURFACE_WILD + Z_LEVEL_SURFACE_MINE ) +// Commented out due to causing a lot of bugs. The base proc plus overmap achieves this functionality anyways. +/* // Short range computers see only the six main levels, others can see the surrounding surface levels. /datum/map/southern_cross/get_map_levels(var/srcz, var/long_range = TRUE) if (long_range && (srcz in map_levels)) @@ -117,7 +118,7 @@ ) else return list(srcz) //prevents runtimes when using CMC. any Z-level not defined above will be 'isolated' and only show to GPSes/CMCs on that same Z (e.g. CentCom). - +*/ /datum/map/southern_cross/perform_map_generation() // First, place a bunch of submaps. This comes before tunnel/forest generation as to not interfere with the submap. @@ -186,19 +187,19 @@ /datum/map_z_level/southern_cross/surface z = Z_LEVEL_SURFACE name = "Plains" - flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED + flags = MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED|MAP_LEVEL_CONSOLES base_turf = /turf/simulated/floor/outdoors/rocks /datum/map_z_level/southern_cross/surface_mine z = Z_LEVEL_SURFACE_MINE name = "Mountains" - flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED + flags = MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED|MAP_LEVEL_CONSOLES base_turf = /turf/simulated/floor/outdoors/rocks /datum/map_z_level/southern_cross/surface_wild z = Z_LEVEL_SURFACE_WILD name = "Wilderness" - flags = MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED + flags = MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED|MAP_LEVEL_CONTACT|MAP_LEVEL_CONSOLES base_turf = /turf/simulated/floor/outdoors/rocks /datum/map_z_level/southern_cross/misc @@ -249,8 +250,7 @@ expected_z_levels = list( Z_LEVEL_SURFACE, Z_LEVEL_SURFACE_MINE, - Z_LEVEL_SURFACE_WILD, - Z_LEVEL_TRANSIT + Z_LEVEL_SURFACE_WILD ) /obj/effect/step_trigger/teleporter/bridge/east_to_west/Initialize() @@ -289,6 +289,31 @@ teleport_z = src.z return ..() +/obj/effect/map_effect/portal/master/side_a/plains_to_caves + portal_id = "plains_caves-normal" + +/obj/effect/map_effect/portal/master/side_b/caves_to_plains + portal_id = "plains_caves-normal" + +/obj/effect/map_effect/portal/master/side_a/plains_to_caves/river + portal_id = "plains_caves-river" + +/obj/effect/map_effect/portal/master/side_b/caves_to_plains/river + portal_id = "plains_caves-river" + + +/obj/effect/map_effect/portal/master/side_a/caves_to_wilderness + portal_id = "caves_wilderness-normal" + +/obj/effect/map_effect/portal/master/side_b/wilderness_to_caves + portal_id = "caves_wilderness-normal" + +/obj/effect/map_effect/portal/master/side_a/caves_to_wilderness/river + portal_id = "caves_wilderness-river" + +/obj/effect/map_effect/portal/master/side_b/wilderness_to_caves/river + portal_id = "caves_wilderness-river" + //Suit Storage Units /obj/machinery/suit_cycler/exploration @@ -300,4 +325,4 @@ name = "Pilot suit cycler" model_text = "Pilot" req_access = null - req_one_access = list(access_pilot,access_explorer) \ No newline at end of file + req_one_access = list(access_pilot,access_explorer) diff --git a/maps/southern_cross/structures/closets/research.dm b/maps/southern_cross/structures/closets/research.dm index 00331364ef3..e118515b1fb 100644 --- a/maps/southern_cross/structures/closets/research.dm +++ b/maps/southern_cross/structures/closets/research.dm @@ -6,7 +6,7 @@ /obj/structure/closet/secure_closet/RD_wardrobe name = "research director's locker" req_access = list(access_rd) - closet_appearance = /decl/closet_appearance/secure_closet/rd + closet_appearance = /decl/closet_appearance/secure_closet/science/rd starts_with = list( /obj/item/clothing/under/rank/research_director, diff --git a/maps/submaps/engine_submaps/engine_tesla.dmm b/maps/submaps/engine_submaps/engine_tesla.dmm index 8a34a5a3996..05e3a7d202e 100644 --- a/maps/submaps/engine_submaps/engine_tesla.dmm +++ b/maps/submaps/engine_submaps/engine_tesla.dmm @@ -288,14 +288,8 @@ dir = 1 }, /obj/structure/table/standard, -/obj/item/weapon/circuitboard/grounding_rod{ - pixel_x = 2; - pixel_y = 2 - }, -/obj/item/weapon/circuitboard/grounding_rod{ - pixel_x = -2; - pixel_y = -2 - }, +/obj/item/weapon/circuitboard/tesla_coil, +/obj/item/weapon/circuitboard/tesla_coil, /turf/simulated/floor, /area/engineering/engine_gas) "aB" = ( @@ -700,16 +694,16 @@ /turf/simulated/wall/r_wall, /area/submap/pa_room) "bj" = ( -/obj/structure/cable/yellow{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/power/tesla_coil, /obj/structure/cable/yellow{ d2 = 4; icon_state = "0-4" }, +/obj/structure/cable/yellow{ + d1 = 0; + d2 = 8; + icon_state = "0-8" + }, /turf/simulated/floor/airless, /area/space) "bk" = ( @@ -1137,16 +1131,12 @@ /turf/simulated/floor/tiled, /area/submap/pa_room) "bZ" = ( -/obj/structure/cable/yellow{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, /obj/structure/cable/yellow{ d2 = 2; icon_state = "0-2" }, /obj/machinery/power/tesla_coil, +/obj/structure/cable/yellow, /turf/simulated/floor/airless, /area/space) "ca" = ( @@ -1584,13 +1574,12 @@ /turf/simulated/floor, /area/engineering/engine_room) "cF" = ( -/obj/structure/cable/yellow{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, /obj/structure/cable/yellow, /obj/machinery/power/tesla_coil, +/obj/structure/cable/yellow{ + d2 = 2; + icon_state = "0-2" + }, /turf/simulated/floor/airless, /area/space) "cG" = ( diff --git a/maps/submaps/surface_submaps/mountains/deadBeacon.dmm b/maps/submaps/surface_submaps/mountains/deadBeacon.dmm index 2a32fb4f644..253b4c53c9f 100644 --- a/maps/submaps/surface_submaps/mountains/deadBeacon.dmm +++ b/maps/submaps/surface_submaps/mountains/deadBeacon.dmm @@ -27,7 +27,7 @@ "A" = (/obj/item/weapon/circuitboard/broken,/turf/simulated/mineral/floor/ignore_mapgen,/area/submap/cave/deadBeacon) "B" = (/obj/structure/grille/broken,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/submap/cave/deadBeacon) "C" = (/obj/structure/loot_pile/maint/junk,/turf/simulated/floor/plating,/area/submap/cave/deadBeacon) -"D" = (/obj/item/weapon/cigbutt,/obj/item/weapon/tool/wrench,/obj/machinery/light,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/cave/deadBeacon) +"D" = (/obj/item/trash/cigbutt,/obj/item/weapon/tool/wrench,/obj/machinery/light,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/cave/deadBeacon) "E" = (/obj/item/weapon/material/shard,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/cave/deadBeacon) "F" = (/obj/machinery/recharge_station,/turf/simulated/floor/tiled/asteroid_steel,/area/submap/cave/deadBeacon) "G" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/submap/cave/deadBeacon) diff --git a/maps/submaps/surface_submaps/mountains/mountains.dm b/maps/submaps/surface_submaps/mountains/mountains.dm index c6a7a2f6849..e36bb1a5bae 100644 --- a/maps/submaps/surface_submaps/mountains/mountains.dm +++ b/maps/submaps/surface_submaps/mountains/mountains.dm @@ -39,6 +39,7 @@ #include "Geyser3.dmm" #include "Cliff1.dmm" #include "excavation1.dmm" +#include "spatial_anomaly.dmm" #endif // The 'mountains' is the mining z-level, and has a lot of caves. @@ -347,3 +348,10 @@ desc = "An abandoned mining site." mappath = 'maps/submaps/surface_submaps/mountains/excavation1.dmm' cost = 20 + +/datum/map_template/surface/mountains/deep/spatial_anomaly + name = "spatial anomaly" + desc = "A strange section of the caves that seems twist and turn in ways that shouldn't be physically possible." + mappath = 'maps/submaps/surface_submaps/mountains/spatial_anomaly.dmm' + cost = 20 + fixed_orientation = TRUE diff --git a/maps/submaps/surface_submaps/mountains/mountains_areas.dm b/maps/submaps/surface_submaps/mountains/mountains_areas.dm index a6968fac98b..04c85685130 100644 --- a/maps/submaps/surface_submaps/mountains/mountains_areas.dm +++ b/maps/submaps/surface_submaps/mountains/mountains_areas.dm @@ -139,3 +139,7 @@ /area/submap/Excavation name = "POI - Excavation Site" ambience = AMBIENCE_FOREBODING + +/area/submap/spatial_anomaly + name = "POI - Spatial Anomaly" + ambience = AMBIENCE_FOREBODING diff --git a/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm b/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm index 390589daac0..7da857ef053 100644 --- a/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm +++ b/maps/submaps/surface_submaps/mountains/quarantineshuttle.dmm @@ -25,7 +25,7 @@ "ay" = (/obj/effect/decal/remains/xeno,/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/submap/cave/qShuttle) "az" = (/obj/item/trash/syndi_cakes,/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/submap/cave/qShuttle) "aA" = (/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/submap/cave/qShuttle) -"aB" = (/obj/item/weapon/cigbutt,/obj/item/weapon/tank/emergency/oxygen,/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/submap/cave/qShuttle) +"aB" = (/obj/item/trash/cigbutt,/obj/item/weapon/tank/emergency/oxygen,/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/submap/cave/qShuttle) "aC" = (/obj/item/weapon/material/knife/tacknife/boot,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/submap/cave/qShuttle) "aD" = (/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/submap/cave/qShuttle) "aE" = (/obj/item/trash/sosjerky,/obj/item/weapon/storage/box/donut/empty,/obj/item/weapon/reagent_containers/food/drinks/sillycup,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/submap/cave/qShuttle) @@ -50,7 +50,7 @@ "aX" = (/obj/item/device/paicard,/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/submap/cave/qShuttle) "aY" = (/obj/machinery/door/blast/regular{name = "Cargo Door"},/obj/item/tape/medical{dir = 4; icon_state = "tape_door_0"; layer = 3.4},/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/submap/cave/qShuttle) "aZ" = (/obj/effect/decal/remains/human,/obj/item/clothing/under/mbill{desc = "A uniform belonging to Major Bill's Transportation, a shipping megacorporation. This looks at least a few decades out of date."; name = "\improper old Major Bill's uniform"},/obj/item/clothing/head/soft/mbill{desc = "It's a ballcap bearing the colors of Major Bill's Shipping. This one looks at least a few decades out of date."; name = "old shipping cap"},/turf/simulated/shuttle/floor,/area/submap/cave/qShuttle) -"ba" = (/obj/item/weapon/cigbutt,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/submap/cave/qShuttle) +"ba" = (/obj/item/trash/cigbutt,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/submap/cave/qShuttle) "bb" = (/obj/machinery/door/airlock/command{icon_state = "door_locked"; locked = 1},/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/submap/cave/qShuttle) "bc" = (/obj/item/weapon/tank/emergency/oxygen/engi,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{icon_state = "floor_white"},/area/submap/cave/qShuttle) "bd" = (/obj/effect/decal/remains/human,/obj/item/clothing/suit/space/emergency,/obj/item/clothing/head/helmet/space/emergency,/obj/effect/decal/cleanable/dirt,/turf/simulated/shuttle/floor{icon_state = "floor_yellow"},/area/submap/cave/qShuttle) diff --git a/maps/submaps/surface_submaps/mountains/spatial_anomaly.dmm b/maps/submaps/surface_submaps/mountains/spatial_anomaly.dmm new file mode 100644 index 00000000000..0adb4b8937d --- /dev/null +++ b/maps/submaps/surface_submaps/mountains/spatial_anomaly.dmm @@ -0,0 +1,82 @@ +"a" = (/turf/simulated/wall/solidrock,/area/submap/spatial_anomaly) +"b" = (/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"c" = (/obj/effect/map_effect/portal/master/side_a{dir = 4; icon_state = "portal_side_a"; portal_id = "spatial_anomaly_5"},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"d" = (/obj/effect/map_effect/portal/master/side_b{dir = 8; icon_state = "portal_side_b"; portal_id = "spatial_anomaly_5"},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"e" = (/obj/structure/barricade,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"f" = (/turf/template_noop,/area/template_noop) +"g" = (/obj/effect/map_effect/portal/master/side_b{portal_id = "spatial_anomaly_4"},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"h" = (/obj/effect/map_effect/portal/line/side_a{icon_state = "portal_line_side_a"; dir = 4},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"i" = (/obj/effect/map_effect/portal/line/side_b{icon_state = "portal_line_side_b"; dir = 8},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"j" = (/turf/simulated/floor/lava,/area/submap/spatial_anomaly) +"k" = (/obj/item/weapon/disposable_teleporter/slime,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"l" = (/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"m" = (/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/plating/external,/area/submap/spatial_anomaly) +"n" = (/obj/effect/map_effect/portal/master/side_a{dir = 4; icon_state = "portal_side_a"; portal_id = "spatial_anomaly_3"},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"o" = (/obj/effect/map_effect/portal/master/side_a{dir = 1; icon_state = "portal_side_a"; portal_id = "spatial_anomaly_4"},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"p" = (/obj/effect/map_effect/portal/master/side_b{dir = 8; icon_state = "portal_side_b"; portal_id = "spatial_anomaly_3"},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"q" = (/obj/effect/map_effect/portal/master/side_b{portal_id = "spatial_anomaly_2"},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"r" = (/obj/effect/map_effect/portal/line/side_b,/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"s" = (/obj/machinery/crystal/lava,/turf/simulated/floor/lava,/area/submap/spatial_anomaly) +"t" = (/turf/simulated/floor/plating/external,/area/submap/spatial_anomaly) +"u" = (/obj/effect/map_effect/portal/master/side_a{portal_id = "spatial_anomaly_1"},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"v" = (/obj/item/weapon/stool/padded,/turf/simulated/floor/plating/external,/area/submap/spatial_anomaly) +"w" = (/obj/structure/table/steel_reinforced,/obj/item/device/xenoarch_multi_tool,/turf/simulated/floor/plating/external,/area/submap/spatial_anomaly) +"x" = (/turf/simulated/wall/solidrock,/area/template_noop) +"y" = (/obj/random/technology_scanner,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"z" = (/obj/structure/table/steel_reinforced,/obj/random/unidentified_medicine/scientific,/turf/simulated/floor/plating/external,/area/submap/spatial_anomaly) +"A" = (/obj/structure/table/steel_reinforced,/obj/random/tool/power,/turf/simulated/floor/plating/external,/area/submap/spatial_anomaly) +"B" = (/obj/structure/table/steel_reinforced,/obj/item/weapon/ore/diamond,/turf/simulated/floor/plating/external,/area/submap/spatial_anomaly) +"C" = (/obj/structure/sign/warning/lava,/turf/simulated/wall,/area/submap/spatial_anomaly) +"D" = (/obj/effect/map_effect/portal/line/side_a,/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"E" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe/jackhammer,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"F" = (/obj/effect/map_effect/portal/master/side_a{dir = 1; icon_state = "portal_side_a"; portal_id = "spatial_anomaly_2"},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"G" = (/obj/effect/map_effect/portal/line/side_a{icon_state = "portal_line_side_a"; dir = 1},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"H" = (/turf/unsimulated/wall,/area/template_noop) +"I" = (/obj/effect/map_effect/portal/master/side_b{dir = 1; icon_state = "portal_side_b"; portal_id = "spatial_anomaly_1"},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"J" = (/obj/effect/map_effect/portal/line/side_b{icon_state = "portal_line_side_b"; dir = 1},/obj/effect/map_effect/perma_light/brighter{light_color = "#ff00ff"},/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"K" = (/obj/item/weapon/mining_scanner,/obj/structure/table/rack,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"L" = (/obj/item/weapon/storage/belt/archaeology,/obj/effect/decal/remains/human,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"M" = (/obj/structure/bookcase/manuals/xenoarchaeology,/turf/simulated/floor/plating/external,/area/submap/spatial_anomaly) +"N" = (/obj/item/weapon/pickaxe/brush,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"O" = (/obj/item/weapon/pickaxe/one_pick,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"P" = (/obj/item/weapon/pickaxe/four_pick,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"Q" = (/obj/effect/decal/remains/human,/turf/simulated/floor/plating/external,/area/submap/spatial_anomaly) +"R" = (/obj/item/weapon/pickaxe/five_pick,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"S" = (/obj/item/weapon/pickaxe/six_pick,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"T" = (/obj/item/weapon/pickaxe/two_pick,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"U" = (/obj/item/device/measuring_tape,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"X" = (/obj/item/weapon/pickaxe/three_pick,/turf/simulated/floor/outdoors/rocks/caves,/area/submap/spatial_anomaly) +"Y" = (/obj/item/weapon/pickaxe/excavationdrill,/turf/simulated/floor/plating/external,/area/submap/spatial_anomaly) + +(1,1,1) = {" +ffffffffffffffffffffffffffffff +fffffffffffffxxxxxxfffffffffff +fffffxxxxxxxxaaaaaaxxxxxffffff +ffffxaaaaaaaaaaaaaaaaaaaxfffff +ffffaataatcbbbbjjjsjkbdtaxffff +fffxaagaathbbbbbjjjjbbitaaffff +fffaaabaaaaaabCbbsaaaaaaaaffff +fffaaaObaaaabbNbbaaaaaaaaaxfff +ffxaaabbblbbbybbaabPbbblaaafff +ffaaaaaaaaabbbtmaabbaaabaaafff +ffaaaaaaaaatttttaabaaaabaaafff +ffaalbbbbbaatvtQaalaaaabaaafff +ffaabaaaabaaBwzAaabaaaabaaffff +ffaabaaaabaaaaaaaabatnbbaaHHHf +ffxabaaaaoaaaaaaabbaaaaaaaffHf +ffxabaaaataatttaabbaaaaaaaffHf +ffxabRbptaaaqrraabSaatttaaHHaf +ffxaaaaaaaaabbbaabbaauDDablbaf +fffaaaaaaaaabbbaablaabbbaeeaaf +fffaaaalbbbabbbaabbaabbbblbaaf +ffffaabbaabababbbbbaaUbbbEKaff +ffffaaTbbabXbabbLbYaabbbaaaaff +ffffaabbbabbbabbmttaaFGGaaafff +ffffaaIJJablbabtttMaatttaaffff +fffffatttaaaaaaaaaaaaaaaafffff +fffffaaaaaaaaaaaaaaaaaaaffffff +fffffaaaaffaaaaaaaafffffffffff +ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffff +"} diff --git a/maps/submaps/surface_submaps/plains/Diner.dmm b/maps/submaps/surface_submaps/plains/Diner.dmm index d8c6d2d7e47..69f2b63996c 100644 --- a/maps/submaps/surface_submaps/plains/Diner.dmm +++ b/maps/submaps/surface_submaps/plains/Diner.dmm @@ -1,1132 +1,1132 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/template_noop, -/area/template_noop) -"ab" = ( -/turf/template_noop, -/area/submap/Diner) -"ac" = ( -/turf/simulated/floor/outdoors/dirt, -/area/submap/Diner) -"ad" = ( -/turf/simulated/wall, -/area/submap/Diner) -"ae" = ( -/obj/structure/window/reinforced/full, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"af" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ag" = ( -/obj/structure/table/standard, -/obj/machinery/microwave, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ah" = ( -/obj/structure/table/standard, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ai" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/enzyme, -/obj/item/weapon/reagent_containers/glass/beaker, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aj" = ( -/obj/structure/table/standard, -/obj/machinery/light{ - dir = 1 - }, -/obj/item/weapon/material/knife/butch, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ak" = ( -/obj/machinery/vending/cola, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"al" = ( -/obj/machinery/vending/dinnerware, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"am" = ( -/obj/structure/sink/kitchen, -/turf/simulated/wall, -/area/submap/Diner) -"an" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/submap/Diner) -"ao" = ( -/obj/structure/bed/chair/wood{ - dir = 1 - }, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ap" = ( -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aq" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ar" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, -/obj/item/weapon/material/kitchen/utensil/fork, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"as" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"at" = ( -/obj/machinery/light{ - dir = 8; - icon_state = "tube1"; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"au" = ( -/obj/structure/table/standard, -/obj/item/weapon/book/manual/chef_recipes, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"av" = ( -/obj/structure/table/standard, -/obj/item/weapon/material/kitchen/rollingpin, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aw" = ( -/obj/machinery/cooker/cereal, -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ax" = ( -/obj/structure/bed/chair/wood, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ay" = ( -/obj/structure/closet/secure_closet/freezer/fridge, -/obj/item/weapon/storage/fancy/egg_box, -/obj/item/weapon/storage/fancy/egg_box, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/obj/item/weapon/reagent_containers/food/condiment/sugar, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"az" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aA" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"aB" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aC" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, -/obj/effect/floor_decal/corner/red/diagonal, -/obj/item/weapon/material/kitchen/utensil/fork, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aD" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aE" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/item/weapon/stool/padded, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aF" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aG" = ( -/turf/simulated/floor/tiled, -/area/submap/Diner) -"aH" = ( -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aI" = ( -/obj/structure/closet/crate/freezer, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aJ" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/red/diagonal, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aK" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aL" = ( -/obj/machinery/light/small{ - brightness_color = "#DA0205"; - brightness_power = 1; - brightness_range = 5; - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"aM" = ( -/obj/machinery/light/small{ - brightness_color = "#DA0205"; - brightness_power = 1; - brightness_range = 5; - dir = 8 - }, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aN" = ( -/obj/structure/closet/crate/freezer, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aO" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/red/diagonal, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aP" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/table/standard, -/obj/machinery/microwave, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aQ" = ( -/obj/structure/closet/crate/freezer, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aR" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/coatrack, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aS" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/table/standard, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aT" = ( -/obj/structure/closet/crate/freezer, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aU" = ( -/obj/machinery/gibber, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aV" = ( -/obj/machinery/light/small, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aW" = ( -/obj/machinery/cooker/fryer, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aX" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Diner) -"aY" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/light{ - dir = 8; - icon_state = "tube1"; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aZ" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/cooker/grill, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ba" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"bb" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"bc" = ( -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bd" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/closet/secure_closet/freezer/fridge, -/obj/item/weapon/storage/fancy/egg_box, -/obj/item/weapon/storage/fancy/egg_box, -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"be" = ( -/obj/structure/table/standard, -/obj/machinery/chemical_dispenser/bar_coffee, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bf" = ( -/obj/item/frame/apc, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bg" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/lamp, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bh" = ( -/obj/structure/bed/chair/office/light, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bi" = ( -/turf/simulated/floor/lino, -/area/submap/Diner) -"bk" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bl" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/cell/high, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bm" = ( -/obj/structure/table/woodentable, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bn" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bo" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bp" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/windoor_assembly{ - icon_state = "l_windoor_assembly01"; - dir = 2 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bq" = ( -/obj/structure/bookcase, -/turf/simulated/floor/lino, -/area/submap/Diner) -"br" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/space_heater, -/obj/machinery/light, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bs" = ( -/obj/structure/sink{ - icon_state = "sink"; - dir = 8; - pixel_x = -12; - pixel_y = 2 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bt" = ( -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bu" = ( -/obj/structure/toilet, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bv" = ( -/obj/structure/bed/chair/wood{ - dir = 4 - }, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bw" = ( -/obj/structure/bed/chair/wood{ - dir = 8 - }, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bx" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"by" = ( -/obj/structure/mirror{ - dir = 4; - pixel_x = -32; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bz" = ( -/obj/machinery/light/small, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bA" = ( -/obj/structure/table/standard, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) - -(1,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} -(2,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -an -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(3,1,1) = {" -aa -ab -ab -an -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -an -ab -aa -"} -(4,1,1) = {" -aa -ab -ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ab -ab -ab -aa -"} -(5,1,1) = {" -aa -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ab -ab -aa -"} -(6,1,1) = {" -aa -ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ab -ab -ab -aa -"} -(7,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ac -ac -aX -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(8,1,1) = {" -aa -ab -ab -ab -ad -ad -ae -ae -ae -ad -ad -az -ad -ae -ae -ae -ad -ae -ae -ae -ad -ab -ab -ab -aa -"} -(9,1,1) = {" -aa -ab -ab -ad -ad -af -ax -aC -ao -af -ad -aV -ad -ax -aC -ao -ax -aC -ao -af -ad -ad -ab -ab -aa -"} -(10,1,1) = {" -aa -ab -ad -ad -aq -af -ax -aD -ao -af -ad -az -ad -ax -aD -ao -ax -aD -ao -af -br -ad -ad -ab -aa -"} -(11,1,1) = {" -aa -ad -ad -af -af -af -af -af -af -af -aR -af -aY -af -af -af -af -af -af -af -af -af -ad -ad -aa -"} -(12,1,1) = {" -aa -ae -af -ax -ar -ao -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ad -aa -"} -(13,1,1) = {" -aa -ae -af -ax -as -ao -af -aE -aE -aE -aE -aE -aE -aE -aE -aE -aE -aE -aE -af -af -bv -bv -ae -aa -"} -(14,1,1) = {" -aa -ad -ad -ad -ad -ad -ad -aF -aJ -aO -aF -aF -aF -aF -aF -aF -aO -aJ -aF -af -af -aD -aC -ae -aa -"} -(15,1,1) = {" -aa -ad -ag -ap -at -ap -az -af -af -af -af -af -af -af -af -af -af -af -ah -af -af -bw -bw -ae -aa -"} -(16,1,1) = {" -aa -ad -ah -ap -ap -ap -az -af -aK -aP -aS -aW -aZ -bc -bd -be -ah -aK -bp -af -af -af -af -ad -aa -"} -(17,1,1) = {" -aa -ad -ai -ap -au -ap -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -bx -ad -ad -aa -"} -(18,1,1) = {" -aa -ad -aj -ap -ah -ap -aA -aG -aL -aG -aG -aG -aG -ba -ba -aG -aG -aL -aG -ad -bs -bt -by -ad -aa -"} -(19,1,1) = {" -aa -ad -ak -ap -av -ap -ad -ad -ad -ad -ad -ad -ba -ba -ad -ad -ad -bo -ad -ad -bt -bt -bz -ad -aa -"} -(20,1,1) = {" -aa -ad -al -ap -ap -ap -ad -aH -aM -aQ -aT -ad -bb -ba -ad -bf -bk -bi -bi -ad -bu -bt -bA -ad -aa -"} -(21,1,1) = {" -aa -ad -am -ap -ap -ap -aB -aH -aH -aH -aH -ad -aG -ba -ad -bg -bl -bi -bi -ad -ad -ad -ad -ad -aa -"} -(22,1,1) = {" -aa -ab -ad -ad -aw -ap -ad -aH -aH -aH -aH -ad -aA -aA -ad -bh -bm -bi -bq -ad -ad -ad -ad -ab -aa -"} -(23,1,1) = {" -aa -ab -ab -ad -ad -ay -ad -aI -aN -aH -aU -ad -bb -aG -ad -bi -bn -bi -bq -ad -ad -ad -ab -ab -aa -"} -(24,1,1) = {" -aa -ab -ab -ab -ad -ad -ad -ad -ad -ad -ad -ad -aA -aA -ad -ad -ad -ad -ad -ad -ad -ab -ab -ab -aa -"} -(25,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/template_noop, +/area/template_noop) +"ab" = ( +/turf/template_noop, +/area/submap/Diner) +"ac" = ( +/turf/simulated/floor/outdoors/dirt, +/area/submap/Diner) +"ad" = ( +/turf/simulated/wall, +/area/submap/Diner) +"ae" = ( +/obj/structure/window/reinforced/full, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"af" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ag" = ( +/obj/structure/table/standard, +/obj/machinery/microwave, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ah" = ( +/obj/structure/table/standard, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ai" = ( +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/enzyme, +/obj/item/weapon/reagent_containers/glass/beaker, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aj" = ( +/obj/structure/table/standard, +/obj/machinery/light{ + dir = 1 + }, +/obj/item/weapon/material/knife/butch, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ak" = ( +/obj/machinery/vending/cola, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"al" = ( +/obj/machinery/vending/dinnerware, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"am" = ( +/obj/structure/sink/kitchen, +/turf/simulated/wall, +/area/submap/Diner) +"an" = ( +/obj/structure/flora/tree/sif, +/turf/template_noop, +/area/submap/Diner) +"ao" = ( +/obj/structure/bed/chair/wood{ + dir = 1 + }, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ap" = ( +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aq" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ar" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, +/obj/item/weapon/material/kitchen/utensil/fork, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"as" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, +/obj/machinery/light{ + icon_state = "tube1"; + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"at" = ( +/obj/machinery/light{ + dir = 8; + icon_state = "tube1"; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"au" = ( +/obj/structure/table/standard, +/obj/item/weapon/book/manual/chef_recipes, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"av" = ( +/obj/structure/table/standard, +/obj/item/weapon/material/kitchen/rollingpin, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aw" = ( +/obj/machinery/appliance/mixer/cereal, +/obj/machinery/light{ + icon_state = "tube1"; + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ax" = ( +/obj/structure/bed/chair/wood, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ay" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/item/weapon/storage/fancy/egg_box, +/obj/item/weapon/storage/fancy/egg_box, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/obj/item/weapon/reagent_containers/food/condiment/sugar, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"az" = ( +/obj/structure/simple_door/wood, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aA" = ( +/obj/structure/simple_door/wood, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"aB" = ( +/obj/structure/simple_door/wood, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aC" = ( +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, +/obj/effect/floor_decal/corner/red/diagonal, +/obj/item/weapon/material/kitchen/utensil/fork, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aD" = ( +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aE" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/item/weapon/stool/padded, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aF" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aG" = ( +/turf/simulated/floor/tiled, +/area/submap/Diner) +"aH" = ( +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aI" = ( +/obj/structure/closet/crate/freezer, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aJ" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/corner/red/diagonal, +/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aK" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/light{ + icon_state = "tube1"; + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aL" = ( +/obj/machinery/light/small{ + brightness_color = "#DA0205"; + brightness_power = 1; + brightness_range = 5; + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"aM" = ( +/obj/machinery/light/small{ + brightness_color = "#DA0205"; + brightness_power = 1; + brightness_range = 5; + dir = 8 + }, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aN" = ( +/obj/structure/closet/crate/freezer, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aO" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/corner/red/diagonal, +/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aP" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/table/standard, +/obj/machinery/microwave, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aQ" = ( +/obj/structure/closet/crate/freezer, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aR" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/coatrack, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aS" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/table/standard, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aT" = ( +/obj/structure/closet/crate/freezer, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aU" = ( +/obj/machinery/gibber, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aV" = ( +/obj/machinery/light/small, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aW" = ( +/obj/machinery/appliance/cooker/fryer, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aX" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/outdoors/dirt, +/area/submap/Diner) +"aY" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/light{ + dir = 8; + icon_state = "tube1"; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aZ" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/appliance/cooker/grill, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ba" = ( +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"bb" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"bc" = ( +/obj/machinery/light{ + icon_state = "tube1"; + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bd" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/item/weapon/storage/fancy/egg_box, +/obj/item/weapon/storage/fancy/egg_box, +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"be" = ( +/obj/structure/table/standard, +/obj/machinery/chemical_dispenser/bar_coffee, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bf" = ( +/obj/item/frame/apc, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bg" = ( +/obj/structure/table/woodentable, +/obj/item/device/flashlight/lamp, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bh" = ( +/obj/structure/bed/chair/office/light, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bi" = ( +/turf/simulated/floor/lino, +/area/submap/Diner) +"bk" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bl" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/cell/high, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bm" = ( +/obj/structure/table/woodentable, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bn" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bo" = ( +/obj/structure/simple_door/wood, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bp" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/windoor_assembly{ + icon_state = "l_windoor_assembly01"; + dir = 2 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bq" = ( +/obj/structure/bookcase, +/turf/simulated/floor/lino, +/area/submap/Diner) +"br" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/space_heater, +/obj/machinery/light, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bs" = ( +/obj/structure/sink{ + icon_state = "sink"; + dir = 8; + pixel_x = -12; + pixel_y = 2 + }, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bt" = ( +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bu" = ( +/obj/structure/toilet, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bv" = ( +/obj/structure/bed/chair/wood{ + dir = 4 + }, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bw" = ( +/obj/structure/bed/chair/wood{ + dir = 8 + }, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bx" = ( +/obj/structure/simple_door/wood, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"by" = ( +/obj/structure/mirror{ + dir = 4; + pixel_x = -32; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bz" = ( +/obj/machinery/light/small, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bA" = ( +/obj/structure/table/standard, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +an +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +"} +(3,1,1) = {" +aa +ab +ab +an +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +an +ab +aa +"} +(4,1,1) = {" +aa +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +aa +"} +(5,1,1) = {" +aa +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +aa +"} +(6,1,1) = {" +aa +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +aa +"} +(7,1,1) = {" +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +aX +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +"} +(8,1,1) = {" +aa +ab +ab +ab +ad +ad +ae +ae +ae +ad +ad +az +ad +ae +ae +ae +ad +ae +ae +ae +ad +ab +ab +ab +aa +"} +(9,1,1) = {" +aa +ab +ab +ad +ad +af +ax +aC +ao +af +ad +aV +ad +ax +aC +ao +ax +aC +ao +af +ad +ad +ab +ab +aa +"} +(10,1,1) = {" +aa +ab +ad +ad +aq +af +ax +aD +ao +af +ad +az +ad +ax +aD +ao +ax +aD +ao +af +br +ad +ad +ab +aa +"} +(11,1,1) = {" +aa +ad +ad +af +af +af +af +af +af +af +aR +af +aY +af +af +af +af +af +af +af +af +af +ad +ad +aa +"} +(12,1,1) = {" +aa +ae +af +ax +ar +ao +af +af +af +af +af +af +af +af +af +af +af +af +af +af +af +af +af +ad +aa +"} +(13,1,1) = {" +aa +ae +af +ax +as +ao +af +aE +aE +aE +aE +aE +aE +aE +aE +aE +aE +aE +aE +af +af +bv +bv +ae +aa +"} +(14,1,1) = {" +aa +ad +ad +ad +ad +ad +ad +aF +aJ +aO +aF +aF +aF +aF +aF +aF +aO +aJ +aF +af +af +aD +aC +ae +aa +"} +(15,1,1) = {" +aa +ad +ag +ap +at +ap +az +af +af +af +af +af +af +af +af +af +af +af +ah +af +af +bw +bw +ae +aa +"} +(16,1,1) = {" +aa +ad +ah +ap +ap +ap +az +af +aK +aP +aS +aW +aZ +bc +bd +be +ah +aK +bp +af +af +af +af +ad +aa +"} +(17,1,1) = {" +aa +ad +ai +ap +au +ap +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +bx +ad +ad +aa +"} +(18,1,1) = {" +aa +ad +aj +ap +ah +ap +aA +aG +aL +aG +aG +aG +aG +ba +ba +aG +aG +aL +aG +ad +bs +bt +by +ad +aa +"} +(19,1,1) = {" +aa +ad +ak +ap +av +ap +ad +ad +ad +ad +ad +ad +ba +ba +ad +ad +ad +bo +ad +ad +bt +bt +bz +ad +aa +"} +(20,1,1) = {" +aa +ad +al +ap +ap +ap +ad +aH +aM +aQ +aT +ad +bb +ba +ad +bf +bk +bi +bi +ad +bu +bt +bA +ad +aa +"} +(21,1,1) = {" +aa +ad +am +ap +ap +ap +aB +aH +aH +aH +aH +ad +aG +ba +ad +bg +bl +bi +bi +ad +ad +ad +ad +ad +aa +"} +(22,1,1) = {" +aa +ab +ad +ad +aw +ap +ad +aH +aH +aH +aH +ad +aA +aA +ad +bh +bm +bi +bq +ad +ad +ad +ad +ab +aa +"} +(23,1,1) = {" +aa +ab +ab +ad +ad +ay +ad +aI +aN +aH +aU +ad +bb +aG +ad +bi +bn +bi +bq +ad +ad +ad +ab +ab +aa +"} +(24,1,1) = {" +aa +ab +ab +ab +ad +ad +ad +ad +ad +ad +ad +ad +aA +aA +ad +ad +ad +ad +ad +ad +ad +ab +ab +ab +aa +"} +(25,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} diff --git a/maps/submaps/surface_submaps/plains/Diner_vr.dmm b/maps/submaps/surface_submaps/plains/Diner_vr.dmm index 8967f9bff74..7264e054dde 100644 --- a/maps/submaps/surface_submaps/plains/Diner_vr.dmm +++ b/maps/submaps/surface_submaps/plains/Diner_vr.dmm @@ -1,1154 +1,1154 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/template_noop, -/area/template_noop) -"ab" = ( -/turf/template_noop, -/area/submap/Diner) -"ac" = ( -/turf/simulated/floor/outdoors/dirt, -/area/submap/Diner) -"ad" = ( -/turf/simulated/wall, -/area/submap/Diner) -"ae" = ( -/obj/structure/window/reinforced/full, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"af" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ag" = ( -/obj/structure/table/standard, -/obj/machinery/microwave, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ah" = ( -/obj/structure/table/standard, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ai" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/enzyme, -/obj/item/weapon/reagent_containers/glass/beaker, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aj" = ( -/obj/structure/table/standard, -/obj/machinery/light{ - dir = 1 - }, -/obj/item/weapon/material/knife/butch, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ak" = ( -/obj/machinery/vending/cola, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"al" = ( -/obj/machinery/vending/dinnerware, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"am" = ( -/obj/structure/sink/kitchen, -/turf/simulated/wall, -/area/submap/Diner) -"an" = ( -/obj/structure/flora/tree/sif, -/turf/template_noop, -/area/submap/Diner) -"ao" = ( -/obj/structure/bed/chair/wood, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ap" = ( -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aq" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ar" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, -/obj/item/weapon/material/kitchen/utensil/fork, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"as" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"at" = ( -/obj/machinery/light{ - dir = 8; - icon_state = "tube1"; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"au" = ( -/obj/structure/table/standard, -/obj/item/weapon/book/manual/chef_recipes, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"av" = ( -/obj/structure/table/standard, -/obj/item/weapon/material/kitchen/rollingpin, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aw" = ( -/obj/machinery/cooker/cereal, -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ax" = ( -/obj/structure/bed/chair/wood{ - dir = 1 - }, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"ay" = ( -/obj/structure/closet/secure_closet/freezer/fridge, -/obj/item/weapon/storage/fancy/egg_box, -/obj/item/weapon/storage/fancy/egg_box, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/obj/item/weapon/reagent_containers/food/condiment/sugar, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"az" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aA" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"aB" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aC" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, -/obj/effect/floor_decal/corner/red/diagonal, -/obj/item/weapon/material/kitchen/utensil/fork, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aD" = ( -/obj/structure/table/standard, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aE" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/item/weapon/stool/padded, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aF" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aG" = ( -/turf/simulated/floor/tiled, -/area/submap/Diner) -"aH" = ( -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aI" = ( -/obj/structure/closet/crate/freezer, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aJ" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/red/diagonal, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aK" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aL" = ( -/obj/machinery/light/small{ - brightness_color = "#DA0205"; - brightness_power = 1; - brightness_range = 5; - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"aM" = ( -/obj/machinery/light/small{ - brightness_color = "#DA0205"; - brightness_power = 1; - brightness_range = 5; - dir = 8 - }, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aN" = ( -/obj/structure/closet/crate/freezer, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/obj/item/weapon/reagent_containers/food/snacks/meat, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aO" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/red/diagonal, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aP" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/table/standard, -/obj/machinery/microwave, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aQ" = ( -/obj/structure/closet/crate/freezer, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/obj/item/weapon/reagent_containers/food/condiment/flour, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aR" = ( -/obj/machinery/gibber, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aS" = ( -/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/tram, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aT" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/coatrack, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aU" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/table/standard, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aV" = ( -/obj/structure/closet/crate/freezer, -/turf/simulated/floor/tiled/freezer, -/area/submap/Diner) -"aW" = ( -/obj/machinery/light/small, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aX" = ( -/obj/machinery/cooker/fryer, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"aY" = ( -/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/tram, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"aZ" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/outdoors/dirt, -/area/submap/Diner) -"ba" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/light{ - dir = 8; - icon_state = "tube1"; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bb" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/cooker/grill, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bc" = ( -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"bd" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"be" = ( -/obj/machinery/light{ - icon_state = "tube1"; - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bf" = ( -/obj/machinery/light/small, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"bg" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/closet/secure_closet/freezer/fridge, -/obj/item/weapon/storage/fancy/egg_box, -/obj/item/weapon/storage/fancy/egg_box, -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, -/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bh" = ( -/obj/structure/table/standard, -/obj/machinery/chemical_dispenser/bar_coffee, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bi" = ( -/obj/item/frame/apc, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bj" = ( -/obj/structure/table/woodentable, -/obj/item/device/flashlight/lamp, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bk" = ( -/obj/structure/bed/chair/office/light, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bl" = ( -/turf/simulated/floor/lino, -/area/submap/Diner) -"bm" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bn" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/cell/high, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bo" = ( -/obj/structure/table/woodentable, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bp" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bq" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/lino, -/area/submap/Diner) -"br" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/structure/windoor_assembly{ - icon_state = "l_windoor_assembly01"; - dir = 2 - }, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bs" = ( -/obj/structure/bookcase, -/turf/simulated/floor/lino, -/area/submap/Diner) -"bt" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/space_heater, -/obj/machinery/light, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bu" = ( -/obj/structure/sink{ - icon_state = "sink"; - dir = 8; - pixel_x = -12; - pixel_y = 2 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bv" = ( -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bw" = ( -/obj/structure/toilet, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bx" = ( -/obj/structure/bed/chair/wood{ - dir = 4 - }, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"by" = ( -/obj/structure/bed/chair/wood{ - dir = 8 - }, -/obj/effect/floor_decal/corner/red/diagonal, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) -"bz" = ( -/obj/structure/simple_door/wood, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bA" = ( -/obj/structure/mirror{ - dir = 4; - pixel_x = -32; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bB" = ( -/obj/machinery/light/small, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"bC" = ( -/obj/structure/table/standard, -/turf/simulated/floor/tiled/hydro, -/area/submap/Diner) -"gw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/portable_atmospherics/canister/air, -/turf/simulated/floor/tiled, -/area/submap/Diner) -"lT" = ( -/obj/effect/floor_decal/corner/red/diagonal, -/obj/machinery/portable_atmospherics/canister/air, -/turf/simulated/floor/tiled/white, -/area/submap/Diner) - -(1,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} -(2,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -an -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(3,1,1) = {" -aa -ab -ab -an -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -an -ab -aa -"} -(4,1,1) = {" -aa -ab -ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ab -ab -ab -aa -"} -(5,1,1) = {" -aa -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -ab -ab -aa -"} -(6,1,1) = {" -aa -ab -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac -aZ -ac -ac -ac -ac -ac -ac -ac -ac -ab -ab -ab -aa -"} -(7,1,1) = {" -aa -ab -ab -ab -ab -ab -ab -ab -ab -ad -ad -az -ad -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -"} -(8,1,1) = {" -aa -ab -ab -ab -ad -ad -ae -ae -ae -ad -aS -ap -ad -ae -ae -ae -ad -ae -ae -ae -ad -ab -ab -ab -aa -"} -(9,1,1) = {" -aa -ab -ab -ad -ad -af -ao -aC -ax -ad -aS -aW -ad -ao -aC -ax -ao -aC -ax -af -ad -ad -ab -ab -aa -"} -(10,1,1) = {" -aa -ab -ad -ad -aq -af -ao -aD -ax -ad -ad -az -ad -ao -aD -ax -ao -aD -ax -af -bt -ad -ad -ab -aa -"} -(11,1,1) = {" -aa -ad -ad -af -af -af -af -af -af -af -aT -af -ba -af -af -af -af -af -af -af -af -af -ad -ad -aa -"} -(12,1,1) = {" -aa -ae -af -ao -ar -ax -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -af -ad -aa -"} -(13,1,1) = {" -aa -ae -af -ao -as -ax -lT -aE -aE -aE -aE -aE -aE -aE -aE -aE -aE -aE -aE -af -af -bx -bx -ae -aa -"} -(14,1,1) = {" -aa -ad -ad -ad -ad -ad -ad -aF -aJ -aO -aF -aF -aF -aF -aF -aF -aO -aJ -aF -af -af -aD -aC -ae -aa -"} -(15,1,1) = {" -aa -ad -ag -ap -at -ap -az -af -af -af -af -af -af -af -af -af -af -af -ah -af -af -by -by -ae -aa -"} -(16,1,1) = {" -aa -ad -ah -ap -ap -ap -az -af -aK -aP -aU -aX -bb -be -bg -bh -ah -aK -br -af -af -af -af -ad -aa -"} -(17,1,1) = {" -aa -ad -ai -ap -au -ap -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -ad -bz -ad -ad -aa -"} -(18,1,1) = {" -aa -ad -aj -ap -ah -ap -aA -aG -aL -aG -aG -aG -aG -bc -bc -aG -aG -aL -aG -ad -bu -bv -bA -ad -aa -"} -(19,1,1) = {" -aa -ad -ak -ap -av -ap -ad -ad -ad -ad -ad -ad -bc -gw -ad -ad -ad -bq -ad -ad -bv -bv -bB -ad -aa -"} -(20,1,1) = {" -aa -ad -al -ap -ap -ap -ad -aH -aM -aQ -aV -ad -bd -bc -ad -bi -bm -bl -bl -ad -bw -bv -bC -ad -aa -"} -(21,1,1) = {" -aa -ad -am -ap -ap -ap -aB -aH -aH -aH -ad -ad -aA -aA -ad -bj -bn -bl -bl -ad -ad -ad -ad -ad -aa -"} -(22,1,1) = {" -aa -ab -ad -ad -aw -ap -ad -aH -aH -aH -ad -aY -aG -aG -ad -bk -bo -bl -bs -ad -ad -ad -ad -ab -aa -"} -(23,1,1) = {" -aa -ab -ab -ad -ad -ay -ad -aI -aN -aR -ad -aY -aG -bf -ad -bl -bp -bl -bs -ad -ad -ad -ab -ab -aa -"} -(24,1,1) = {" -aa -ab -ab -ab -ad -ad -ad -ad -ad -ad -ad -ad -aA -aA -ad -ad -ad -ad -ad -ad -ad -ab -ab -ab -aa -"} -(25,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -"} +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/template_noop, +/area/template_noop) +"ab" = ( +/turf/template_noop, +/area/submap/Diner) +"ac" = ( +/turf/simulated/floor/outdoors/dirt, +/area/submap/Diner) +"ad" = ( +/turf/simulated/wall, +/area/submap/Diner) +"ae" = ( +/obj/structure/window/reinforced/full, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"af" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ag" = ( +/obj/structure/table/standard, +/obj/machinery/microwave, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ah" = ( +/obj/structure/table/standard, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ai" = ( +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/enzyme, +/obj/item/weapon/reagent_containers/glass/beaker, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aj" = ( +/obj/structure/table/standard, +/obj/machinery/light{ + dir = 1 + }, +/obj/item/weapon/material/knife/butch, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ak" = ( +/obj/machinery/vending/cola, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"al" = ( +/obj/machinery/vending/dinnerware, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"am" = ( +/obj/structure/sink/kitchen, +/turf/simulated/wall, +/area/submap/Diner) +"an" = ( +/obj/structure/flora/tree/sif, +/turf/template_noop, +/area/submap/Diner) +"ao" = ( +/obj/structure/bed/chair/wood, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ap" = ( +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aq" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ar" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, +/obj/item/weapon/material/kitchen/utensil/fork, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"as" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, +/obj/machinery/light{ + icon_state = "tube1"; + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"at" = ( +/obj/machinery/light{ + dir = 8; + icon_state = "tube1"; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"au" = ( +/obj/structure/table/standard, +/obj/item/weapon/book/manual/chef_recipes, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"av" = ( +/obj/structure/table/standard, +/obj/item/weapon/material/kitchen/rollingpin, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aw" = ( +/obj/machinery/appliance/mixer/cereal, +/obj/machinery/light{ + icon_state = "tube1"; + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ax" = ( +/obj/structure/bed/chair/wood{ + dir = 1 + }, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"ay" = ( +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/item/weapon/storage/fancy/egg_box, +/obj/item/weapon/storage/fancy/egg_box, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/obj/item/weapon/reagent_containers/food/condiment/sugar, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"az" = ( +/obj/structure/simple_door/wood, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aA" = ( +/obj/structure/simple_door/wood, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"aB" = ( +/obj/structure/simple_door/wood, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aC" = ( +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, +/obj/effect/floor_decal/corner/red/diagonal, +/obj/item/weapon/material/kitchen/utensil/fork, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aD" = ( +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aE" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/item/weapon/stool/padded, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aF" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aG" = ( +/turf/simulated/floor/tiled, +/area/submap/Diner) +"aH" = ( +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aI" = ( +/obj/structure/closet/crate/freezer, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aJ" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/corner/red/diagonal, +/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aK" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/light{ + icon_state = "tube1"; + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aL" = ( +/obj/machinery/light/small{ + brightness_color = "#DA0205"; + brightness_power = 1; + brightness_range = 5; + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"aM" = ( +/obj/machinery/light/small{ + brightness_color = "#DA0205"; + brightness_power = 1; + brightness_range = 5; + dir = 8 + }, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aN" = ( +/obj/structure/closet/crate/freezer, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/obj/item/weapon/reagent_containers/food/snacks/meat, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aO" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/corner/red/diagonal, +/obj/item/weapon/reagent_containers/food/condiment/small/peppermill, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aP" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/table/standard, +/obj/machinery/microwave, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aQ" = ( +/obj/structure/closet/crate/freezer, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/obj/item/weapon/reagent_containers/food/condiment/flour, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aR" = ( +/obj/machinery/gibber, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aS" = ( +/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/tram, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aT" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/coatrack, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aU" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/table/standard, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aV" = ( +/obj/structure/closet/crate/freezer, +/turf/simulated/floor/tiled/freezer, +/area/submap/Diner) +"aW" = ( +/obj/machinery/light/small, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aX" = ( +/obj/machinery/appliance/cooker/fryer, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"aY" = ( +/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/tram, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"aZ" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/outdoors/dirt, +/area/submap/Diner) +"ba" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/light{ + dir = 8; + icon_state = "tube1"; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bb" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/appliance/cooker/grill, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bc" = ( +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"bd" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"be" = ( +/obj/machinery/light{ + icon_state = "tube1"; + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bf" = ( +/obj/machinery/light/small, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"bg" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/item/weapon/storage/fancy/egg_box, +/obj/item/weapon/storage/fancy/egg_box, +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, +/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/milk, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/obj/item/weapon/reagent_containers/food/drinks/bottle/cream, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bh" = ( +/obj/structure/table/standard, +/obj/machinery/chemical_dispenser/bar_coffee, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bi" = ( +/obj/item/frame/apc, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bj" = ( +/obj/structure/table/woodentable, +/obj/item/device/flashlight/lamp, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bk" = ( +/obj/structure/bed/chair/office/light, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bl" = ( +/turf/simulated/floor/lino, +/area/submap/Diner) +"bm" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bn" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/cell/high, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bo" = ( +/obj/structure/table/woodentable, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bp" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bq" = ( +/obj/structure/simple_door/wood, +/turf/simulated/floor/lino, +/area/submap/Diner) +"br" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/structure/windoor_assembly{ + icon_state = "l_windoor_assembly01"; + dir = 2 + }, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bs" = ( +/obj/structure/bookcase, +/turf/simulated/floor/lino, +/area/submap/Diner) +"bt" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/space_heater, +/obj/machinery/light, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bu" = ( +/obj/structure/sink{ + icon_state = "sink"; + dir = 8; + pixel_x = -12; + pixel_y = 2 + }, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bv" = ( +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bw" = ( +/obj/structure/toilet, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bx" = ( +/obj/structure/bed/chair/wood{ + dir = 4 + }, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"by" = ( +/obj/structure/bed/chair/wood{ + dir = 8 + }, +/obj/effect/floor_decal/corner/red/diagonal, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) +"bz" = ( +/obj/structure/simple_door/wood, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bA" = ( +/obj/structure/mirror{ + dir = 4; + pixel_x = -32; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bB" = ( +/obj/machinery/light/small, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"bC" = ( +/obj/structure/table/standard, +/turf/simulated/floor/tiled/hydro, +/area/submap/Diner) +"gw" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/portable_atmospherics/canister/air, +/turf/simulated/floor/tiled, +/area/submap/Diner) +"lT" = ( +/obj/effect/floor_decal/corner/red/diagonal, +/obj/machinery/portable_atmospherics/canister/air, +/turf/simulated/floor/tiled/white, +/area/submap/Diner) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +an +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +"} +(3,1,1) = {" +aa +ab +ab +an +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +an +ab +aa +"} +(4,1,1) = {" +aa +ab +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +aa +"} +(5,1,1) = {" +aa +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +aa +"} +(6,1,1) = {" +aa +ab +ac +ac +ac +ac +ac +ac +ac +ac +ac +ac +aZ +ac +ac +ac +ac +ac +ac +ac +ac +ab +ab +ab +aa +"} +(7,1,1) = {" +aa +ab +ab +ab +ab +ab +ab +ab +ab +ad +ad +az +ad +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +"} +(8,1,1) = {" +aa +ab +ab +ab +ad +ad +ae +ae +ae +ad +aS +ap +ad +ae +ae +ae +ad +ae +ae +ae +ad +ab +ab +ab +aa +"} +(9,1,1) = {" +aa +ab +ab +ad +ad +af +ao +aC +ax +ad +aS +aW +ad +ao +aC +ax +ao +aC +ax +af +ad +ad +ab +ab +aa +"} +(10,1,1) = {" +aa +ab +ad +ad +aq +af +ao +aD +ax +ad +ad +az +ad +ao +aD +ax +ao +aD +ax +af +bt +ad +ad +ab +aa +"} +(11,1,1) = {" +aa +ad +ad +af +af +af +af +af +af +af +aT +af +ba +af +af +af +af +af +af +af +af +af +ad +ad +aa +"} +(12,1,1) = {" +aa +ae +af +ao +ar +ax +af +af +af +af +af +af +af +af +af +af +af +af +af +af +af +af +af +ad +aa +"} +(13,1,1) = {" +aa +ae +af +ao +as +ax +lT +aE +aE +aE +aE +aE +aE +aE +aE +aE +aE +aE +aE +af +af +bx +bx +ae +aa +"} +(14,1,1) = {" +aa +ad +ad +ad +ad +ad +ad +aF +aJ +aO +aF +aF +aF +aF +aF +aF +aO +aJ +aF +af +af +aD +aC +ae +aa +"} +(15,1,1) = {" +aa +ad +ag +ap +at +ap +az +af +af +af +af +af +af +af +af +af +af +af +ah +af +af +by +by +ae +aa +"} +(16,1,1) = {" +aa +ad +ah +ap +ap +ap +az +af +aK +aP +aU +aX +bb +be +bg +bh +ah +aK +br +af +af +af +af +ad +aa +"} +(17,1,1) = {" +aa +ad +ai +ap +au +ap +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +ad +bz +ad +ad +aa +"} +(18,1,1) = {" +aa +ad +aj +ap +ah +ap +aA +aG +aL +aG +aG +aG +aG +bc +bc +aG +aG +aL +aG +ad +bu +bv +bA +ad +aa +"} +(19,1,1) = {" +aa +ad +ak +ap +av +ap +ad +ad +ad +ad +ad +ad +bc +gw +ad +ad +ad +bq +ad +ad +bv +bv +bB +ad +aa +"} +(20,1,1) = {" +aa +ad +al +ap +ap +ap +ad +aH +aM +aQ +aV +ad +bd +bc +ad +bi +bm +bl +bl +ad +bw +bv +bC +ad +aa +"} +(21,1,1) = {" +aa +ad +am +ap +ap +ap +aB +aH +aH +aH +ad +ad +aA +aA +ad +bj +bn +bl +bl +ad +ad +ad +ad +ad +aa +"} +(22,1,1) = {" +aa +ab +ad +ad +aw +ap +ad +aH +aH +aH +ad +aY +aG +aG +ad +bk +bo +bl +bs +ad +ad +ad +ad +ab +aa +"} +(23,1,1) = {" +aa +ab +ab +ad +ad +ay +ad +aI +aN +aR +ad +aY +aG +bf +ad +bl +bp +bl +bs +ad +ad +ad +ab +ab +aa +"} +(24,1,1) = {" +aa +ab +ab +ab +ad +ad +ad +ad +ad +ad +ad +ad +aA +aA +ad +ad +ad +ad +ad +ad +ad +ab +ab +ab +aa +"} +(25,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} diff --git a/maps/submaps/surface_submaps/wilderness/Manor1.dmm b/maps/submaps/surface_submaps/wilderness/Manor1.dmm index 691311bc688..4d561d54029 100644 --- a/maps/submaps/surface_submaps/wilderness/Manor1.dmm +++ b/maps/submaps/surface_submaps/wilderness/Manor1.dmm @@ -1,188 +1,188 @@ -"aa" = (/turf/template_noop,/area/submap/Manor1) -"ab" = (/turf/simulated/wall/wood,/area/submap/Manor1) -"ac" = (/obj/structure/window/reinforced/full,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ad" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 4},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ae" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"af" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 8},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ag" = (/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ah" = (/obj/structure/flora/pottedplant/dead,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ai" = (/obj/structure/flora/pottedplant/drooping,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aj" = (/obj/structure/table/woodentable,/obj/item/clothing/mask/smokable/cigarette/cigar,/obj/item/weapon/material/ashtray/glass,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ak" = (/obj/structure/flora/pottedplant/dead,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"al" = (/obj/structure/table/woodentable,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"am" = (/obj/structure/table/woodentable,/obj/item/device/flashlight,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"an" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ao" = (/obj/structure/mopbucket,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ap" = (/obj/structure/sink,/turf/simulated/wall/wood,/area/submap/Manor1) -"aq" = (/turf/simulated/floor/carpet/bcarpet,/area/submap/Manor1) -"ar" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/bcarpet,/area/submap/Manor1) -"as" = (/obj/structure/simple_door/wood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"at" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/obj/effect/decal/cleanable/blood/gibs/robot,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"au" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/effect/decal/cleanable/blood/oil,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"av" = (/obj/structure/janitorialcart,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aw" = (/obj/structure/table/woodentable,/obj/item/weapon/mop,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ax" = (/obj/structure/closet/cabinet,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ay" = (/obj/effect/decal/cleanable/blood/gibs/robot/limb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"az" = (/obj/structure/table/woodentable,/obj/item/trash/candle,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aA" = (/obj/effect/decal/cleanable/dirt,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aB" = (/obj/effect/decal/cleanable/dirt,/obj/effect/spider/stickyweb,/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aC" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/maglight,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aD" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aE" = (/obj/structure/closet/cabinet,/obj/effect/decal/cleanable/cobweb2,/obj/item/clothing/head/hood/winter,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/suit/storage/hooded/wintercoat,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aF" = (/obj/structure/table/woodentable,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aG" = (/obj/structure/table/woodentable,/obj/item/weapon/paper,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aH" = (/obj/structure/table/woodentable,/obj/item/weapon/pen,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aI" = (/obj/structure/flora/pottedplant/dead,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aJ" = (/obj/effect/spider/stickyweb,/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aK" = (/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aL" = (/obj/structure/fireplace,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aM" = (/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aN" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aO" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aP" = (/obj/structure/bed/chair/wood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aQ" = (/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) -"aR" = (/obj/structure/table/standard,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aS" = (/obj/structure/table/standard,/obj/machinery/microwave,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aT" = (/obj/structure/closet/cabinet,/obj/random/projectile/shotgun,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aU" = (/obj/structure/bookcase,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aV" = (/obj/structure/table/woodentable,/obj/item/weapon/material/kitchen/utensil/fork,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aW" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/peppermill,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aX" = (/obj/structure/table/standard,/obj/item/weapon/material/knife,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aY" = (/obj/machinery/cooker/oven,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"aZ" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ba" = (/obj/machinery/cooker/grill,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bb" = (/obj/structure/table/standard,/obj/item/weapon/tray,/obj/item/weapon/tray,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bc" = (/obj/structure/table/standard,/obj/item/weapon/material/knife/butch,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bd" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"be" = (/obj/random/trash,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bf" = (/obj/structure/closet/cabinet,/obj/item/clothing/head/hood/winter,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/random/contraband,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bg" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bh" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 1},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bi" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken0"},/area/submap/Manor1) -"bj" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bk" = (/obj/random/plushielarge,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bl" = (/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) -"bm" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/accessory/sweater/blue,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) -"bn" = (/obj/structure/window/reinforced/full,/turf/template_noop,/area/submap/Manor1) -"bo" = (/obj/item/weapon/material/twohanded/baseballbat/metal,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) -"bp" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) -"bq" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"br" = (/obj/structure/bed/chair/comfy/purp{icon_state = "comfychair_preview"; dir = 4},/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken5"},/area/submap/Manor1) -"bs" = (/obj/structure/table,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bt" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bu" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 8},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bv" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/sugar,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bw" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) -"bx" = (/obj/structure/bed/chair/comfy/purp{icon_state = "comfychair_preview"; dir = 4},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"by" = (/obj/structure/closet/cabinet,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/item/clothing/head/hood/winter,/obj/item/clothing/shoes/boots/winter,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bz" = (/obj/structure/table/woodentable,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bA" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/utensil/fork,/obj/item/weapon/material/kitchen/utensil/fork,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bB" = (/obj/structure/closet/secure_closet/freezer/fridge,/obj/item/weapon/reagent_containers/food/snacks/stew,/obj/item/weapon/reagent_containers/food/snacks/stew,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bC" = (/obj/item/weapon/shovel,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bD" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bE" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/utensil/spoon,/obj/item/weapon/material/kitchen/utensil/spoon,/obj/item/weapon/material/kitchen/utensil/spoon,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bF" = (/obj/structure/table/standard,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bG" = (/obj/structure/closet/secure_closet/freezer/fridge,/obj/item/weapon/reagent_containers/food/snacks/sausage,/obj/item/weapon/reagent_containers/food/snacks/sausage,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bH" = (/obj/effect/decal/cleanable/dirt,/obj/structure/flora/pottedplant/drooping,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bI" = (/obj/effect/decal/cleanable/dirt,/obj/structure/flora/pottedplant/dead,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bJ" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/rollingpin,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bK" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bL" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/fancy/candle_box,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bM" = (/obj/machinery/papershredder,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bN" = (/obj/structure/simple_door/wood,/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) -"bO" = (/obj/machinery/icecream_vat,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bP" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) -"bQ" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bR" = (/obj/effect/decal/cleanable/cobweb,/obj/structure/table/woodentable,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bS" = (/obj/structure/flora/pottedplant/subterranean,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bT" = (/obj/item/weapon/material/minihoe,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) -"bU" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) -"bV" = (/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken6"},/area/submap/Manor1) -"bW" = (/obj/machinery/washing_machine,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bX" = (/obj/structure/table/woodentable,/obj/structure/bedsheetbin,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bY" = (/obj/structure/table/rack,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"bZ" = (/obj/structure/closet/crate,/obj/item/stack/cable_coil/random_belt,/obj/random/cash,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ca" = (/obj/structure/table/woodentable,/obj/item/weapon/melee/umbrella/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cb" = (/obj/structure/closet/cabinet,/obj/random/gun/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cc" = (/obj/structure/closet/cabinet,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/obj/random/medical,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cd" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ce" = (/obj/structure/bed/double,/obj/item/weapon/bedsheet/rddouble,/obj/structure/curtain/open/bed,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cf" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/wallet/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cg" = (/obj/structure/flora/pottedplant/dead,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ch" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/accessory/sweater,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) -"ci" = (/obj/structure/closet/crate,/obj/item/weapon/flame/lighter/random,/obj/random/powercell,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cj" = (/obj/structure/closet/cabinet,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/item/clothing/head/hood/winter,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ck" = (/obj/effect/decal/cleanable/spiderling_remains,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cl" = (/turf/simulated/floor/carpet/turcarpet,/area/submap/Manor1) -"cm" = (/obj/effect/decal/cleanable/blood,/obj/structure/bed/chair/comfy/purp{icon_state = "comfychair_preview"; dir = 4},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cn" = (/obj/structure/closet/crate,/obj/item/weapon/storage/wallet/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"co" = (/obj/structure/coatrack,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cp" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/suit/storage/hooded/wintercoat,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cq" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/under/suit_jacket,/obj/item/clothing/shoes/black,/obj/random/projectile/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cr" = (/obj/structure/simple_door/wood,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) -"cs" = (/obj/item/weapon/material/twohanded/spear,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"ct" = (/obj/structure/closet/cabinet{opened = 1},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cu" = (/obj/effect/decal/remains,/obj/item/weapon/material/knife/tacknife/combatknife,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cv" = (/obj/structure/sink{pixel_y = 30},/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cw" = (/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cx" = (/obj/structure/table/standard,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cy" = (/obj/structure/table/standard,/obj/item/weapon/towel/random,/obj/item/weapon/towel/random,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cz" = (/obj/effect/decal/cleanable/cobweb2,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cA" = (/obj/item/weapon/paper/crumpled,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cB" = (/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken3"},/area/submap/Manor1) -"cC" = (/obj/effect/decal/cleanable/spiderling_remains,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cD" = (/obj/structure/closet/crate,/obj/item/clothing/suit/armor/vest,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cE" = (/obj/structure/closet/crate,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cF" = (/obj/structure/simple_door/wood,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cG" = (/obj/structure/toilet{icon_state = "toilet00"; dir = 8},/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cH" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cI" = (/obj/item/stack/material/wood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cJ" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/obj/random/soap,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cK" = (/obj/structure/table/standard,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cL" = (/obj/structure/toilet{icon_state = "toilet00"; dir = 1},/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) -"cM" = (/obj/structure/table/woodentable,/obj/item/modular_computer/laptop/preset/custom_loadout/cheap,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) -"cN" = (/turf/template_noop,/area/template_noop) -"cO" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/Manor1) - -(1,1,1) = {" -cNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcN -cNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacababacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacN -cNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababadaeafagahaiagadajafababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacN -cNaaaaaaaaaaaaaaaaababababababababababababagagagagagagagagagagagagababababababababababababababaaaaaaaaaaaacN -cNaaaacOaaaaaaaaabababakagagagalamalagananagagagagananananagagagagagagagagalalalagagagaiabaoapabaaaacOaaaacN -cNaaaaaaaaaaaaababalabagaqaqaqaqarararararararaqarararararararaqaqaqaqaqaqaqaqaqaqaqaqagasagagababaaaaaaaacN -cNaaaaaaaaaaababatauabagaqaqaqaqaqaqaqarararararararararararararaqaqaqaqaqaqaqaqaqaqaqagabavagawababaaaaaacN -cNaaaaaaaaaaabaxagayabagaqagagazalalaganananaAaBaAagananagagagagagagagagagalalaCagagaqagababababababaaaaaacN -cNaaaaaaaaaaababasababagaqagabababababababababababababababababababababababababababagaqagabaDagagaEabaaaaaacN -cNaaaaaacOaaabagagagasagaqagabaFaGagalaHabaIaJaKagagaLaLagagagagahabagaMagagagaNabagaqagabaOagagalabaaaaaacN -cNaaaaaaaaaaabasabababagaqagabagagagagagabaKaKaPaPagaQaQagaPaPagagabaRagaRaRagaSabagaqagabababasababaaaaaacN -cNaaaaaaaaaaabagagaTabagaqagabagaUagaUagabagadalaVafaQaQadaValafagabaRagaWaXagaYabalaqagasagagagagabaaaaaacN -cNaaaaaaaaaaabagagaMabagaqagabagaUagaUagabagadalalafaQaQadalalafagabaRagaZaRagbaabagaqagabababasababaaaaaacN -cNaaaaaaaaaaabaDalaOabagaqagabagaUagaUagabagadalalafaQaQadalalafagabbbagaRbcagbdabagaqagabaOagagalabaaaaaacN -cNaaaaaaaaaaabababababagaqagabagagagaganabagadalalafaQaQadalalafagabagagagagagagabagaqagabaDbeagbfabaaaaaacN -cNaaaaaaaaaaabaDalbgabalaqagabagaUagaUanabagadalalafaQaQadalalafagabagagagagagagabagaqagababababababaaaaaacN -cNaaaaaaaaababagbhagabazaqagasagaUagaUanabagadaGalafaQaQadalalafagabagagagagagagabagaqagabbiagagagababaaaacN -cNaaaaaaababbjagagbkabalaqagabagaUanaUanabagadalalafaQaQadalalafagabagagagagagagabagaqagabagblbmagagababaacN -cNaaaaaabnagagagagaOabagaqanabanananananabanadalalafaQaQadalalafagasagagagagagagasagaqagasagbobpbqbrbsacaacN -cNaaaaaabnagagagagalabagaranabagaUanaUagabanbtalalafaQaQadalalbuanabagagaRbvagagabagaqagabagblbwagbxbsacaacN -cNaaaaaaababagagagbyabanaranabagaUanaUagabanbtalalafaQaQadalbzbuanabagagbAaRagbBabagaqagabagblblagbCababaacN -cNaaaaaaaaababagagagabanaragabagaUanaUagabananbhbhagaQaQagbhbDananabagagbEbFagbGabagaqagabalblblagababaaaacN -cNaaaaaaaaaaabagagagabagaragabagaganagagabbHananagagaQaQaganananbIabagagbFbJagbKabagaqagabaDblblalabaaaaaacN -cNaaaaaaaaaaabagagagasagaqagabaGbLbMagaiababababababbNbNababababababbOaKaKaKagagabagaqagabalblblalabaaaaaacN -cNaaaaaaaaaaabazalagabagaqagababababasabababababalalaQaQalalabababababababababababagaqagabalbwbPalabaaaaaacN -cNaaaaaaaaaaabababababbQaqagagananananananananasagagaQaQagagasagagagagagagagagagagagaqagabazblbPalabaaaaaacN -cNaaaaaaaaababbRazbSabbqaqagagagagananananananasagagaQaQagagasagagagagagagagagagagagaqagabalblbTagababaaaacN -cNaaaaaaababagagagagabagaqagababababasabababababalagbUaQagalabababababababababababagaqagabagblblbVagababaacN -cNaaaaaaacagagagagbqasbqaqagabbWbXabagabbYagbZabalagbUbUagcaabcbccagcdcecfagagcgabagaqagasagbpchagbxbsacaacN -cNaacOaaacagagagbqagabagaqagabagagasagabagagciabcjckbUbUagcjabagclclclclclclclaDabagaqagabbqbwblagcmagacaacN -cNaaaaaaababagbQbQagabahaqagabbWazabagasagagcnababcobUbUcoababagclclclclclclclalabahaqahabagbwblagcpababaacN -cNaaaaaaaaababcqagagababasabababababagabagagagaKababcrcrababagagclclclclclclclalababasababcsblbwagababaaaacN -cNaaaaaaaaaaabctagcuabcvcwcxabcycwasagabbYagaKaKczabbUbUabazafagclclclclclclclagagagagahabagcAcBagabaaaaaacN -cNaaaaaaaaaaababalagabcwabababcwcwabagabbYcCaJcDcEabbUbUabalagagagagagclclclclclclclclagabcAbqagababaaaaaacN -cNaaaaaaaaaaaaababalabcwcFcGabcwcHabasabababababababbNbNabababababahagclclclclclclclclagabagcIababaaaaaaaacN -cNaaaaaaaaaaaaaaabababcwabababcwcHabcwcvababaaaaaaaaaaaaaaaaaaaaababalclclclclclclclclagabcIababaaaaaaaaaacN -cNaaaaaaaaaaaaaaaaababcwcFcGabcwcJabcKcLabaaaaaaaaaaaaaaaaaaaaaaaaabcMalalagagagagagagahabababaaaaaacOaaaacN -cNaaaaaacOaaaaaaaaaaabababababababababababaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababaaaaaaaaaaaaaacN -cNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacN -cNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcN -"} \ No newline at end of file +"aa" = (/turf/template_noop,/area/submap/Manor1) +"ab" = (/turf/simulated/wall/wood,/area/submap/Manor1) +"ac" = (/obj/structure/window/reinforced/full,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ad" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 4},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ae" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"af" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 8},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ag" = (/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ah" = (/obj/structure/flora/pottedplant/dead,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ai" = (/obj/structure/flora/pottedplant/drooping,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aj" = (/obj/structure/table/woodentable,/obj/item/clothing/mask/smokable/cigarette/cigar,/obj/item/weapon/material/ashtray/glass,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ak" = (/obj/structure/flora/pottedplant/dead,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"al" = (/obj/structure/table/woodentable,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"am" = (/obj/structure/table/woodentable,/obj/item/device/flashlight,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"an" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ao" = (/obj/structure/mopbucket,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ap" = (/obj/structure/sink,/turf/simulated/wall/wood,/area/submap/Manor1) +"aq" = (/turf/simulated/floor/carpet/bcarpet,/area/submap/Manor1) +"ar" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/bcarpet,/area/submap/Manor1) +"as" = (/obj/structure/simple_door/wood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"at" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/obj/effect/decal/cleanable/blood/gibs/robot,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"au" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/effect/decal/cleanable/blood/oil,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"av" = (/obj/structure/janitorialcart,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aw" = (/obj/structure/table/woodentable,/obj/item/weapon/mop,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ax" = (/obj/structure/closet/cabinet,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ay" = (/obj/effect/decal/cleanable/blood/gibs/robot/limb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"az" = (/obj/structure/table/woodentable,/obj/item/trash/candle,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aA" = (/obj/effect/decal/cleanable/dirt,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aB" = (/obj/effect/decal/cleanable/dirt,/obj/effect/spider/stickyweb,/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aC" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/maglight,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aD" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aE" = (/obj/structure/closet/cabinet,/obj/effect/decal/cleanable/cobweb2,/obj/item/clothing/head/hood/winter,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/suit/storage/hooded/wintercoat,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aF" = (/obj/structure/table/woodentable,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aG" = (/obj/structure/table/woodentable,/obj/item/weapon/paper,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aH" = (/obj/structure/table/woodentable,/obj/item/weapon/pen,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aI" = (/obj/structure/flora/pottedplant/dead,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aJ" = (/obj/effect/spider/stickyweb,/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aK" = (/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aL" = (/obj/structure/fireplace,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aM" = (/mob/living/simple_mob/animal/giant_spider/lurker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aN" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aO" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aP" = (/obj/structure/bed/chair/wood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aQ" = (/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) +"aR" = (/obj/structure/table/standard,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aS" = (/obj/structure/table/standard,/obj/machinery/microwave,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aT" = (/obj/structure/closet/cabinet,/obj/random/projectile/shotgun,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aU" = (/obj/structure/bookcase,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aV" = (/obj/structure/table/woodentable,/obj/item/weapon/material/kitchen/utensil/fork,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aW" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/peppermill,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aX" = (/obj/structure/table/standard,/obj/item/weapon/material/knife,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aY" = (/obj/machinery/appliance/cooker/oven,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"aZ" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ba" = (/obj/machinery/appliance/cooker/grill,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bb" = (/obj/structure/table/standard,/obj/item/weapon/tray,/obj/item/weapon/tray,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bc" = (/obj/structure/table/standard,/obj/item/weapon/material/knife/butch,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bd" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"be" = (/obj/random/trash,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bf" = (/obj/structure/closet/cabinet,/obj/item/clothing/head/hood/winter,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/random/contraband,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bg" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bh" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 1},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bi" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken0"},/area/submap/Manor1) +"bj" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bk" = (/obj/random/plushielarge,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bl" = (/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bm" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/accessory/sweater/blue,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bn" = (/obj/structure/window/reinforced/full,/turf/template_noop,/area/submap/Manor1) +"bo" = (/obj/item/weapon/material/twohanded/baseballbat/metal,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bp" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bq" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"br" = (/obj/structure/bed/chair/comfy/purp{icon_state = "comfychair_preview"; dir = 4},/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken5"},/area/submap/Manor1) +"bs" = (/obj/structure/table,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bt" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bu" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 8},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bv" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/food/condiment/small/sugar,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bw" = (/obj/effect/decal/cleanable/blood/drip,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bx" = (/obj/structure/bed/chair/comfy/purp{icon_state = "comfychair_preview"; dir = 4},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"by" = (/obj/structure/closet/cabinet,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/item/clothing/head/hood/winter,/obj/item/clothing/shoes/boots/winter,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bz" = (/obj/structure/table/woodentable,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bA" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/utensil/fork,/obj/item/weapon/material/kitchen/utensil/fork,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bB" = (/obj/structure/closet/secure_closet/freezer/fridge,/obj/item/weapon/reagent_containers/food/snacks/stew,/obj/item/weapon/reagent_containers/food/snacks/stew,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bC" = (/obj/item/weapon/shovel,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bD" = (/obj/structure/bed/chair/wood{icon_state = "wooden_chair"; dir = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bE" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/utensil/spoon,/obj/item/weapon/material/kitchen/utensil/spoon,/obj/item/weapon/material/kitchen/utensil/spoon,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bF" = (/obj/structure/table/standard,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bG" = (/obj/structure/closet/secure_closet/freezer/fridge,/obj/item/weapon/reagent_containers/food/snacks/sausage,/obj/item/weapon/reagent_containers/food/snacks/sausage,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bH" = (/obj/effect/decal/cleanable/dirt,/obj/structure/flora/pottedplant/drooping,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bI" = (/obj/effect/decal/cleanable/dirt,/obj/structure/flora/pottedplant/dead,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bJ" = (/obj/structure/table/standard,/obj/item/weapon/material/kitchen/rollingpin,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bK" = (/obj/structure/table/standard,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bL" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/fancy/candle_box,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bM" = (/obj/machinery/papershredder,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bN" = (/obj/structure/simple_door/wood,/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) +"bO" = (/obj/machinery/icecream_vat,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bP" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bQ" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bR" = (/obj/effect/decal/cleanable/cobweb,/obj/structure/table/woodentable,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bS" = (/obj/structure/flora/pottedplant/subterranean,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bT" = (/obj/item/weapon/material/minihoe,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"bU" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) +"bV" = (/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken6"},/area/submap/Manor1) +"bW" = (/obj/machinery/washing_machine,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bX" = (/obj/structure/table/woodentable,/obj/structure/bedsheetbin,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bY" = (/obj/structure/table/rack,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"bZ" = (/obj/structure/closet/crate,/obj/item/stack/cable_coil/random_belt,/obj/random/cash,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ca" = (/obj/structure/table/woodentable,/obj/item/weapon/melee/umbrella/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cb" = (/obj/structure/closet/cabinet,/obj/random/gun/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cc" = (/obj/structure/closet/cabinet,/obj/item/weapon/cell/device/weapon,/obj/item/weapon/cell/device/weapon,/obj/random/medical,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cd" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ce" = (/obj/structure/bed/double,/obj/item/weapon/bedsheet/rddouble,/obj/structure/curtain/open/bed,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cf" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/wallet/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cg" = (/obj/structure/flora/pottedplant/dead,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ch" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/accessory/sweater,/turf/simulated/floor/carpet/blucarpet,/area/submap/Manor1) +"ci" = (/obj/structure/closet/crate,/obj/item/weapon/flame/lighter/random,/obj/random/powercell,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cj" = (/obj/structure/closet/cabinet,/obj/item/clothing/shoes/boots/winter,/obj/item/clothing/suit/storage/hooded/wintercoat,/obj/item/clothing/head/hood/winter,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ck" = (/obj/effect/decal/cleanable/spiderling_remains,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cl" = (/turf/simulated/floor/carpet/turcarpet,/area/submap/Manor1) +"cm" = (/obj/effect/decal/cleanable/blood,/obj/structure/bed/chair/comfy/purp{icon_state = "comfychair_preview"; dir = 4},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cn" = (/obj/structure/closet/crate,/obj/item/weapon/storage/wallet/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"co" = (/obj/structure/coatrack,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cp" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/suit/storage/hooded/wintercoat,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cq" = (/obj/structure/loot_pile/surface/bones,/obj/item/clothing/under/suit_jacket,/obj/item/clothing/shoes/black,/obj/random/projectile/random,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cr" = (/obj/structure/simple_door/wood,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/carpet/purcarpet,/area/submap/Manor1) +"cs" = (/obj/item/weapon/material/twohanded/spear,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"ct" = (/obj/structure/closet/cabinet{opened = 1},/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cu" = (/obj/effect/decal/remains,/obj/item/weapon/material/knife/tacknife/combatknife,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cv" = (/obj/structure/sink{pixel_y = 30},/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cw" = (/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cx" = (/obj/structure/table/standard,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cy" = (/obj/structure/table/standard,/obj/item/weapon/towel/random,/obj/item/weapon/towel/random,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cz" = (/obj/effect/decal/cleanable/cobweb2,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cA" = (/obj/item/weapon/paper/crumpled,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cB" = (/turf/simulated/floor/holofloor/wood{icon_state = "wood_broken3"},/area/submap/Manor1) +"cC" = (/obj/effect/decal/cleanable/spiderling_remains,/obj/effect/spider/stickyweb,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cD" = (/obj/structure/closet/crate,/obj/item/clothing/suit/armor/vest,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cE" = (/obj/structure/closet/crate,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cF" = (/obj/structure/simple_door/wood,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cG" = (/obj/structure/toilet{icon_state = "toilet00"; dir = 8},/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cH" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cI" = (/obj/item/stack/material/wood,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cJ" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/curtain/open/shower,/obj/random/soap,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cK" = (/obj/structure/table/standard,/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cL" = (/obj/structure/toilet{icon_state = "toilet00"; dir = 1},/turf/simulated/floor/tiled/hydro,/area/submap/Manor1) +"cM" = (/obj/structure/table/woodentable,/obj/item/modular_computer/laptop/preset/custom_loadout/cheap,/turf/simulated/floor/holofloor/wood,/area/submap/Manor1) +"cN" = (/turf/template_noop,/area/template_noop) +"cO" = (/obj/structure/flora/tree/sif,/turf/template_noop,/area/submap/Manor1) + +(1,1,1) = {" +cNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcN +cNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacababacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacN +cNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababadaeafagahaiagadajafababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacN +cNaaaaaaaaaaaaaaaaababababababababababababagagagagagagagagagagagagababababababababababababababaaaaaaaaaaaacN +cNaaaacOaaaaaaaaabababakagagagalamalagananagagagagananananagagagagagagagagalalalagagagaiabaoapabaaaacOaaaacN +cNaaaaaaaaaaaaababalabagaqaqaqaqarararararararaqarararararararaqaqaqaqaqaqaqaqaqaqaqaqagasagagababaaaaaaaacN +cNaaaaaaaaaaababatauabagaqaqaqaqaqaqaqarararararararararararararaqaqaqaqaqaqaqaqaqaqaqagabavagawababaaaaaacN +cNaaaaaaaaaaabaxagayabagaqagagazalalaganananaAaBaAagananagagagagagagagagagalalaCagagaqagababababababaaaaaacN +cNaaaaaaaaaaababasababagaqagabababababababababababababababababababababababababababagaqagabaDagagaEabaaaaaacN +cNaaaaaacOaaabagagagasagaqagabaFaGagalaHabaIaJaKagagaLaLagagagagahabagaMagagagaNabagaqagabaOagagalabaaaaaacN +cNaaaaaaaaaaabasabababagaqagabagagagagagabaKaKaPaPagaQaQagaPaPagagabaRagaRaRagaSabagaqagabababasababaaaaaacN +cNaaaaaaaaaaabagagaTabagaqagabagaUagaUagabagadalaVafaQaQadaValafagabaRagaWaXagaYabalaqagasagagagagabaaaaaacN +cNaaaaaaaaaaabagagaMabagaqagabagaUagaUagabagadalalafaQaQadalalafagabaRagaZaRagbaabagaqagabababasababaaaaaacN +cNaaaaaaaaaaabaDalaOabagaqagabagaUagaUagabagadalalafaQaQadalalafagabbbagaRbcagbdabagaqagabaOagagalabaaaaaacN +cNaaaaaaaaaaabababababagaqagabagagagaganabagadalalafaQaQadalalafagabagagagagagagabagaqagabaDbeagbfabaaaaaacN +cNaaaaaaaaaaabaDalbgabalaqagabagaUagaUanabagadalalafaQaQadalalafagabagagagagagagabagaqagababababababaaaaaacN +cNaaaaaaaaababagbhagabazaqagasagaUagaUanabagadaGalafaQaQadalalafagabagagagagagagabagaqagabbiagagagababaaaacN +cNaaaaaaababbjagagbkabalaqagabagaUanaUanabagadalalafaQaQadalalafagabagagagagagagabagaqagabagblbmagagababaacN +cNaaaaaabnagagagagaOabagaqanabanananananabanadalalafaQaQadalalafagasagagagagagagasagaqagasagbobpbqbrbsacaacN +cNaaaaaabnagagagagalabagaranabagaUanaUagabanbtalalafaQaQadalalbuanabagagaRbvagagabagaqagabagblbwagbxbsacaacN +cNaaaaaaababagagagbyabanaranabagaUanaUagabanbtalalafaQaQadalbzbuanabagagbAaRagbBabagaqagabagblblagbCababaacN +cNaaaaaaaaababagagagabanaragabagaUanaUagabananbhbhagaQaQagbhbDananabagagbEbFagbGabagaqagabalblblagababaaaacN +cNaaaaaaaaaaabagagagabagaragabagaganagagabbHananagagaQaQaganananbIabagagbFbJagbKabagaqagabaDblblalabaaaaaacN +cNaaaaaaaaaaabagagagasagaqagabaGbLbMagaiababababababbNbNababababababbOaKaKaKagagabagaqagabalblblalabaaaaaacN +cNaaaaaaaaaaabazalagabagaqagababababasabababababalalaQaQalalabababababababababababagaqagabalbwbPalabaaaaaacN +cNaaaaaaaaaaabababababbQaqagagananananananananasagagaQaQagagasagagagagagagagagagagagaqagabazblbPalabaaaaaacN +cNaaaaaaaaababbRazbSabbqaqagagagagananananananasagagaQaQagagasagagagagagagagagagagagaqagabalblbTagababaaaacN +cNaaaaaaababagagagagabagaqagababababasabababababalagbUaQagalabababababababababababagaqagabagblblbVagababaacN +cNaaaaaaacagagagagbqasbqaqagabbWbXabagabbYagbZabalagbUbUagcaabcbccagcdcecfagagcgabagaqagasagbpchagbxbsacaacN +cNaacOaaacagagagbqagabagaqagabagagasagabagagciabcjckbUbUagcjabagclclclclclclclaDabagaqagabbqbwblagcmagacaacN +cNaaaaaaababagbQbQagabahaqagabbWazabagasagagcnababcobUbUcoababagclclclclclclclalabahaqahabagbwblagcpababaacN +cNaaaaaaaaababcqagagababasabababababagabagagagaKababcrcrababagagclclclclclclclalababasababcsblbwagababaaaacN +cNaaaaaaaaaaabctagcuabcvcwcxabcycwasagabbYagaKaKczabbUbUabazafagclclclclclclclagagagagahabagcAcBagabaaaaaacN +cNaaaaaaaaaaababalagabcwabababcwcwabagabbYcCaJcDcEabbUbUabalagagagagagclclclclclclclclagabcAbqagababaaaaaacN +cNaaaaaaaaaaaaababalabcwcFcGabcwcHabasabababababababbNbNabababababahagclclclclclclclclagabagcIababaaaaaaaacN +cNaaaaaaaaaaaaaaabababcwabababcwcHabcwcvababaaaaaaaaaaaaaaaaaaaaababalclclclclclclclclagabcIababaaaaaaaaaacN +cNaaaaaaaaaaaaaaaaababcwcFcGabcwcJabcKcLabaaaaaaaaaaaaaaaaaaaaaaaaabcMalalagagagagagagahabababaaaaaacOaaaacN +cNaaaaaacOaaaaaaaaaaabababababababababababaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababaaaaaaaaaaaaaacN +cNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacN +cNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcNcN +"} diff --git a/maps/submaps/surface_submaps/wilderness/wilderness_areas.dm b/maps/submaps/surface_submaps/wilderness/wilderness_areas.dm index 4f41a473f8a..c33096f9f73 100644 --- a/maps/submaps/surface_submaps/wilderness/wilderness_areas.dm +++ b/maps/submaps/surface_submaps/wilderness/wilderness_areas.dm @@ -5,6 +5,7 @@ ambience = AMBIENCE_RUINS secret_name = TRUE forbid_events = TRUE + flags = AREA_FLAG_IS_NOT_PERSISTENT /area/submap/event //To be used for Events not for regular PoIs name = "Unknown" diff --git a/maps/tether/submaps/_tether_submaps.dm b/maps/tether/submaps/_tether_submaps.dm index 9cc1a6daaa0..03ed7864853 100644 --- a/maps/tether/submaps/_tether_submaps.dm +++ b/maps/tether/submaps/_tether_submaps.dm @@ -460,18 +460,28 @@ var/turf/T = get_turf(src) var/datum/gas_mixture/env = T.return_air() if(env) - my_mob.minbodytemp = env.temperature * 0.8 - my_mob.maxbodytemp = env.temperature * 1.2 + if(my_mob.minbodytemp > env.temperature) + my_mob.minbodytemp = env.temperature * 0.8 + if(my_mob.maxbodytemp < env.temperature) + my_mob.maxbodytemp = env.temperature * 1.2 var/list/gaslist = env.gas - my_mob.min_oxy = gaslist["oxygen"] * 0.8 - my_mob.min_tox = gaslist["phoron"] * 0.8 - my_mob.min_n2 = gaslist["nitrogen"] * 0.8 - my_mob.min_co2 = gaslist["carbon_dioxide"] * 0.8 - my_mob.max_oxy = gaslist["oxygen"] * 1.2 - my_mob.max_tox = gaslist["phoron"] * 1.2 - my_mob.max_n2 = gaslist["nitrogen"] * 1.2 - my_mob.max_co2 = gaslist["carbon_dioxide"] * 1.2 + if(my_mob.min_oxy) + my_mob.min_oxy = gaslist["oxygen"] * 0.8 + if(my_mob.min_tox) + my_mob.min_tox = gaslist["phoron"] * 0.8 + if(my_mob.min_n2) + my_mob.min_n2 = gaslist["nitrogen"] * 0.8 + if(my_mob.min_co2) + my_mob.min_co2 = gaslist["carbon_dioxide"] * 0.8 + if(my_mob.max_oxy) + my_mob.max_oxy = gaslist["oxygen"] * 1.2 + if(my_mob.max_tox) + my_mob.max_tox = gaslist["phoron"] * 1.2 + if(my_mob.max_n2) + my_mob.max_n2 = gaslist["nitrogen"] * 1.2 + if(my_mob.max_co2) + my_mob.max_co2 = gaslist["carbon_dioxide"] * 1.2 /* //VORESTATION AI TEMPORARY REMOVAL if(guard) my_mob.returns_home = TRUE diff --git a/maps/tether/submaps/admin_use/dhael_centcom.dmm b/maps/tether/submaps/admin_use/dhael_centcom.dmm index 195605f7c47..44cfa83aa7a 100644 --- a/maps/tether/submaps/admin_use/dhael_centcom.dmm +++ b/maps/tether/submaps/admin_use/dhael_centcom.dmm @@ -3607,7 +3607,7 @@ /obj/effect/floor_decal/corner/grey/diagonal{ dir = 4 }, -/obj/machinery/cooker/cereal, +/obj/machinery/appliance/mixer/cereal, /turf/unsimulated/floor/steel{ icon_state = "white" }, @@ -3635,7 +3635,7 @@ /obj/effect/floor_decal/corner/grey/diagonal{ dir = 4 }, -/obj/machinery/cooker/oven, +/obj/machinery/appliance/cooker/oven, /obj/machinery/camera/network/crescent{ dir = 10 }, @@ -3647,7 +3647,7 @@ /obj/effect/floor_decal/corner/grey/diagonal{ dir = 4 }, -/obj/machinery/cooker/grill, +/obj/machinery/appliance/cooker/grill, /turf/unsimulated/floor/steel{ icon_state = "white" }, @@ -3656,7 +3656,7 @@ /obj/effect/floor_decal/corner/grey/diagonal{ dir = 4 }, -/obj/machinery/cooker/fryer, +/obj/machinery/appliance/cooker/fryer, /turf/unsimulated/floor/steel{ icon_state = "white" }, @@ -14562,7 +14562,7 @@ /obj/effect/floor_decal/corner/grey/diagonal{ dir = 4 }, -/obj/machinery/cooker/cereal, +/obj/machinery/appliance/mixer/cereal, /turf/unsimulated/floor/steel{ icon_state = "white" }, @@ -14571,7 +14571,7 @@ /obj/effect/floor_decal/corner/grey/diagonal{ dir = 4 }, -/obj/machinery/cooker/oven, +/obj/machinery/appliance/cooker/oven, /turf/unsimulated/floor/steel{ icon_state = "white" }, @@ -14580,7 +14580,7 @@ /obj/effect/floor_decal/corner/grey/diagonal{ dir = 4 }, -/obj/machinery/cooker/grill, +/obj/machinery/appliance/cooker/grill, /turf/unsimulated/floor/steel{ icon_state = "white" }, @@ -14589,7 +14589,7 @@ /obj/effect/floor_decal/corner/grey/diagonal{ dir = 4 }, -/obj/machinery/cooker/fryer, +/obj/machinery/appliance/cooker/fryer, /turf/unsimulated/floor/steel{ icon_state = "white" }, diff --git a/maps/tether/submaps/admin_use/ert.dmm b/maps/tether/submaps/admin_use/ert.dmm index b453af29306..6c095544288 100644 --- a/maps/tether/submaps/admin_use/ert.dmm +++ b/maps/tether/submaps/admin_use/ert.dmm @@ -1305,6 +1305,18 @@ /obj/machinery/light, /obj/structure/table/standard, /obj/item/weapon/soap, +/obj/item/weapon/soap, +/obj/item/weapon/soap, +/obj/item/weapon/soap, +/obj/item/weapon/towel{ + color = "#0000FF" + }, +/obj/item/weapon/towel{ + color = "#0000FF" + }, +/obj/item/weapon/towel{ + color = "#0000FF" + }, /obj/item/weapon/towel{ color = "#0000FF" }, @@ -1315,16 +1327,22 @@ name = "custodial" }, /obj/item/weapon/reagent_containers/spray/cleaner, +/obj/item/weapon/reagent_containers/spray/cleaner, +/obj/item/weapon/reagent_containers/spray/cleaner, +/obj/item/weapon/reagent_containers/spray/cleaner, +/obj/item/weapon/reagent_containers/glass/bucket, +/obj/item/weapon/reagent_containers/glass/bucket, +/obj/item/weapon/reagent_containers/glass/bucket, /obj/item/weapon/reagent_containers/glass/bucket, /obj/item/weapon/mop, +/obj/item/weapon/mop, +/obj/item/weapon/mop, +/obj/item/weapon/mop, /obj/item/weapon/rig/ert/janitor, -/turf/simulated/shuttle/floor/black, -/area/shuttle/specops/centcom) -"cG" = ( -/obj/machinery/door/airlock/multi_tile/glass{ - dir = 2; - req_access = list(103) - }, +/obj/item/device/lightreplacer, +/obj/item/device/lightreplacer, +/obj/item/weapon/storage/box/lights/mixed, +/obj/item/weapon/storage/box/lights/mixed, /turf/simulated/shuttle/floor/black, /area/shuttle/specops/centcom) "cH" = ( @@ -2114,6 +2132,12 @@ /obj/item/device/suit_cooling_unit, /turf/simulated/shuttle/floor/black, /area/shuttle/specops/centcom) +"zV" = ( +/obj/machinery/door/airlock/glass_command{ + req_one_access = list(103) + }, +/turf/simulated/shuttle/floor/black, +/area/shuttle/specops/centcom) "HG" = ( /obj/structure/closet/walllocker/emerglocker{ pixel_y = -32 @@ -2133,6 +2157,18 @@ /obj/item/clothing/suit/space/void/responseteam/security, /turf/simulated/shuttle/floor/black, /area/shuttle/specops/centcom) +"WJ" = ( +/obj/structure/table/rack/steel, +/obj/item/clothing/suit/space/void/responseteam/janitor, +/obj/item/clothing/suit/space/void/responseteam/janitor, +/obj/item/clothing/suit/space/void/responseteam/janitor, +/obj/item/clothing/suit/space/void/responseteam/janitor, +/obj/item/weapon/storage/belt/janitor, +/obj/item/weapon/storage/belt/janitor, +/obj/item/weapon/storage/belt/janitor, +/obj/item/weapon/storage/belt/janitor, +/turf/simulated/shuttle/floor/black, +/area/shuttle/specops/centcom) (1,1,1) = {" aa @@ -2800,7 +2836,7 @@ ap am bZ aH -aH +WJ ap ap ap @@ -2837,8 +2873,8 @@ ap ap ap ap -aH -cG +zV +ap am ap da diff --git a/maps/tether/submaps/aerostat/submaps/Manor1.dmm b/maps/tether/submaps/aerostat/submaps/Manor1.dmm index b9815492897..2401898eb82 100644 --- a/maps/tether/submaps/aerostat/submaps/Manor1.dmm +++ b/maps/tether/submaps/aerostat/submaps/Manor1.dmm @@ -219,7 +219,7 @@ /turf/simulated/floor/holofloor/wood, /area/submap/virgo2/Manor1) "aY" = ( -/obj/machinery/cooker/oven, +/obj/machinery/appliance/cooker/oven, /turf/simulated/floor/holofloor/wood, /area/submap/virgo2/Manor1) "aZ" = ( @@ -228,7 +228,7 @@ /turf/simulated/floor/holofloor/wood, /area/submap/virgo2/Manor1) "ba" = ( -/obj/machinery/cooker/grill, +/obj/machinery/appliance/cooker/grill, /turf/simulated/floor/holofloor/wood, /area/submap/virgo2/Manor1) "bb" = ( diff --git a/maps/tether/submaps/gateway/snow_outpost.dmm b/maps/tether/submaps/gateway/snow_outpost.dmm index e5964e01141..6dfd70f91fe 100644 --- a/maps/tether/submaps/gateway/snow_outpost.dmm +++ b/maps/tether/submaps/gateway/snow_outpost.dmm @@ -238,7 +238,9 @@ }, /area/awaymission/snow_outpost/powered) "aR" = ( -/obj/mecha/combat/marauder/mauler, +/obj/mecha/combat/marauder/mauler{ + operation_req_access = newlist() + }, /turf/simulated/floor/bluegrid{ name = "Mainframe Base"; nitrogen = 100; @@ -2606,20 +2608,6 @@ "iN" = ( /turf/simulated/floor/water/deep, /area/awaymission/snow_outpost/dark) -"iP" = ( -/obj/machinery/atmospherics/unary/vent_pump, -/obj/item/weapon/cell/slime, -/turf/simulated/floor/tiled/white, -/area/awaymission/snow_outpost/powered) -"iQ" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/cyan{ - dir = 5; - icon_state = "intact" - }, -/obj/item/weapon/cell/infinite, -/obj/item/weapon/cat_box, -/turf/simulated/floor/tiled/white, -/area/awaymission/snow_outpost/powered) "iR" = ( /obj/machinery/atmospherics/unary/vent_pump{ dir = 8; @@ -9181,8 +9169,8 @@ uy uy aO as -iP -iQ +by +aA aS yM bH diff --git a/maps/tether/submaps/offmap/talon.dm b/maps/tether/submaps/offmap/talon.dm index c530e24b08a..b05b7ec13ab 100644 --- a/maps/tether/submaps/offmap/talon.dm +++ b/maps/tether/submaps/offmap/talon.dm @@ -28,6 +28,10 @@ var/global/list/latejoin_talon = list() on_store_visible_message_1 = "hums and hisses as it moves" on_store_visible_message_2 = "into cryogenic storage." +/obj/machinery/cryopod/robot/talon + announce_channel = "Talon" + on_store_name = "ITV Talon Robotic Storage" + /obj/effect/landmark/map_data/talon height = 2 @@ -386,7 +390,7 @@ Once in open space, consider disabling nonessential power-consuming electronics filedesc = "Helmet Camera Monitoring (Talon)" extended_desc = "This program allows remote access to Talon helmet camera systems." size = 4 //Smaller because limited scope - nanomodule_path = /datum/nano_module/camera_monitor/talon_helmet + tguimodule_path = /datum/tgui_module/camera/ntos/talon_helmet required_access = access_talon // Talon ship cameras @@ -395,23 +399,18 @@ Once in open space, consider disabling nonessential power-consuming electronics filedesc = "Ship Camera Monitoring (Talon)" extended_desc = "This program allows remote access to the Talon's camera system." size = 10 //Smaller because limited scope - nanomodule_path = /datum/nano_module/camera_monitor/talon_ship + tguimodule_path = /datum/tgui_module/camera/ntos/talon_ship required_access = access_talon -/datum/nano_module/camera_monitor/talon_ship +/datum/tgui_module/camera/ntos/talon_ship name = "Talon Ship Camera Monitor" -/datum/nano_module/camera_monitor/talon_ship/modify_networks_list(var/list/networks) - networks.Cut() - networks.Add(list(list("tag" = NETWORK_TALON_SHIP, "has_access" = 1))) - networks.Add(list(list("tag" = NETWORK_THUNDER, "has_access" = 1))) //THUNDERRRRR - return networks +/datum/nano_module/camera_monitor/talon_ship/New(host) + . = ..(host, list(NETWORK_TALON_SHIP, NETWORK_THUNDER)) -/datum/nano_module/camera_monitor/talon_helmet +/datum/tgui_module/camera/ntos/talon_helmet name = "Talon Helmet Camera Monitor" -/datum/nano_module/camera_monitor/talon_helmet/modify_networks_list(var/list/networks) - networks.Cut() - networks.Add(list(list("tag" = NETWORK_TALON_HELMETS, "has_access" = 1))) - return networks +/datum/tgui_module/camera/ntos/talon_helmet/New(host) + . = ..(host, list(NETWORK_TALON_HELMETS)) /datum/computer_file/program/power_monitor/talon filename = "tpowermonitor" diff --git a/maps/tether/submaps/offmap/talon1.dmm b/maps/tether/submaps/offmap/talon1.dmm index 1a94cb2e9ab..5cbf638bde6 100644 --- a/maps/tether/submaps/offmap/talon1.dmm +++ b/maps/tether/submaps/offmap/talon1.dmm @@ -23,6 +23,19 @@ }, /turf/simulated/floor/hull/airless, /area/space) +"ae" = ( +/obj/machinery/door/blast/regular/open{ + dir = 4; + id = "talon_windows" + }, +/obj/structure/lattice, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/space, +/area/talon/deckone/bridge) "af" = ( /obj/structure/lattice, /obj/structure/cable/green{ @@ -52,13 +65,8 @@ id = "talon_windows" }, /obj/structure/lattice, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, /turf/space, -/area/space) +/area/talon/deckone/bridge) "aj" = ( /obj/machinery/light{ dir = 8; @@ -68,13 +76,24 @@ /turf/simulated/floor/tiled/eris/dark/brown_perforated, /area/talon/deckone/port_eng) "ak" = ( -/obj/machinery/door/blast/regular/open{ - dir = 4; - id = "talon_windows" +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/obj/structure/lattice, -/turf/space, -/area/space) +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/structure/table/standard, +/obj/item/weapon/paper_bin, +/obj/item/weapon/pen, +/obj/machinery/alarm/talon{ + dir = 8; + pixel_x = 22; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/eris/steel, +/area/talon/deckone/brig) "al" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -160,6 +179,17 @@ }, /turf/simulated/floor/tiled/eris/white/golden, /area/talon/deckone/bridge) +"at" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/machinery/alarm/talon{ + dir = 8; + pixel_x = 22; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/eris/dark/brown_perforated, +/area/talon/deckone/port_eng) "aC" = ( /turf/simulated/wall/rshull, /area/talon/maintenance/deckone_port) @@ -2333,29 +2363,6 @@ }, /turf/simulated/floor/tiled/eris/dark/orangecorner, /area/talon/deckone/brig) -"tn" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/alarm/talon{ - alarm_id = "anomaly_testing"; - breach_detection = 0; - dir = 8; - frequency = 1439; - pixel_x = 22; - pixel_y = 0; - report_danger_level = 0 - }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, -/obj/structure/table/standard, -/obj/item/weapon/paper_bin, -/obj/item/weapon/pen, -/turf/simulated/floor/tiled/eris/steel, -/area/talon/deckone/brig) "tr" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -5654,21 +5661,6 @@ /obj/machinery/portable_atmospherics/canister/oxygen, /turf/simulated/floor/plating/eris/under, /area/talon/maintenance/deckone_port) -"Xk" = ( -/obj/machinery/alarm/talon{ - alarm_id = "anomaly_testing"; - breach_detection = 0; - dir = 8; - frequency = 1439; - pixel_x = 22; - pixel_y = 0; - report_danger_level = 0 - }, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/simulated/floor/tiled/eris/dark/brown_perforated, -/area/talon/deckone/port_eng) "Xt" = ( /obj/machinery/light, /turf/simulated/floor/tiled/eris/dark/monofloor, @@ -14872,7 +14864,7 @@ Yc Yc Yc Yc -Xk +at iR Py ji @@ -15279,7 +15271,7 @@ dZ cL pw Mz -tn +ak pp KJ LK @@ -15676,7 +15668,7 @@ aa aa aa ag -ai +ae al an ao @@ -15818,7 +15810,7 @@ aa aa aa aa -ak +ai IM RS on @@ -15960,7 +15952,7 @@ aa aa aa aa -ak +ai IM wm LH diff --git a/maps/tether/submaps/offmap/talon2.dmm b/maps/tether/submaps/offmap/talon2.dmm index 33e976059ac..9f30e789f90 100644 --- a/maps/tether/submaps/offmap/talon2.dmm +++ b/maps/tether/submaps/offmap/talon2.dmm @@ -8,6 +8,17 @@ "ac" = ( /turf/simulated/wall, /area/talon/decktwo/bridge_upper) +"ad" = ( +/obj/effect/landmark/start{ + name = "Talon Engineer" + }, +/obj/machinery/alarm/talon{ + dir = 8; + pixel_x = 22; + pixel_y = 0 + }, +/turf/simulated/floor/carpet, +/area/talon/decktwo/eng_room) "ae" = ( /turf/simulated/open, /area/talon/decktwo/bridge_upper) @@ -22,6 +33,17 @@ /obj/structure/railing, /turf/simulated/open, /area/talon/decktwo/bridge_upper) +"ah" = ( +/obj/effect/landmark/start{ + name = "Talon Doctor" + }, +/obj/machinery/alarm/talon{ + dir = 8; + pixel_x = 22; + pixel_y = 0 + }, +/turf/simulated/floor/carpet, +/area/talon/decktwo/med_room) "ai" = ( /obj/structure/railing{ dir = 8 @@ -45,6 +67,31 @@ }, /turf/simulated/open, /area/talon/decktwo/bridge_upper) +"al" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/machinery/portable_atmospherics/powered/scrubber, +/obj/machinery/alarm/talon{ + dir = 8; + pixel_x = 22; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/techfloor/grid, +/area/talon/decktwo/lifeboat) +"am" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/alarm/talon{ + dir = 8; + pixel_x = 22; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/eris/steel, +/area/talon/decktwo/central_hallway) "an" = ( /obj/machinery/light{ dir = 4 @@ -756,17 +803,6 @@ "dM" = ( /turf/simulated/floor/carpet, /area/talon/decktwo/eng_room) -"dN" = ( -/obj/machinery/alarm/talon{ - dir = 8; - pixel_x = 22; - pixel_y = 0 - }, -/obj/effect/landmark/start{ - name = "Talon Engineer" - }, -/turf/simulated/floor/carpet, -/area/talon/decktwo/eng_room) "dQ" = ( /obj/structure/table/steel, /obj/machinery/button/remote/blast_door{ @@ -1095,17 +1131,6 @@ "fm" = ( /turf/simulated/floor/carpet, /area/talon/decktwo/med_room) -"fn" = ( -/obj/machinery/alarm/talon{ - dir = 8; - pixel_x = 22; - pixel_y = 0 - }, -/obj/effect/landmark/start{ - name = "Talon Doctor" - }, -/turf/simulated/floor/carpet, -/area/talon/decktwo/med_room) "fp" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ @@ -1934,23 +1959,6 @@ /obj/structure/window/reinforced, /turf/simulated/floor/plating/eris/under, /area/talon/maintenance/decktwo_aft) -"mN" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/alarm/talon{ - alarm_id = "anomaly_testing"; - breach_detection = 0; - dir = 8; - frequency = 1439; - pixel_x = 22; - pixel_y = 0; - report_danger_level = 0 - }, -/turf/simulated/floor/tiled/eris/steel, -/area/talon/decktwo/central_hallway) "mR" = ( /obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ dir = 4; @@ -3848,6 +3856,10 @@ }, /turf/simulated/floor/hull/airless, /area/talon/maintenance/decktwo_solars) +"Os" = ( +/obj/machinery/cryopod/robot/talon, +/turf/simulated/floor/tiled/eris/white/gray_platform, +/area/talon/decktwo/central_hallway) "Ou" = ( /obj/structure/cable/heavyduty{ dir = 2; @@ -4018,22 +4030,6 @@ }, /turf/simulated/floor/plating/eris/under/airless, /area/talon/maintenance/decktwo_solars) -"QM" = ( -/obj/machinery/alarm/talon{ - alarm_id = "anomaly_testing"; - breach_detection = 0; - dir = 8; - frequency = 1439; - pixel_x = 22; - pixel_y = 0; - report_danger_level = 0 - }, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 - }, -/obj/machinery/portable_atmospherics/powered/scrubber, -/turf/simulated/floor/tiled/techfloor/grid, -/area/talon/decktwo/lifeboat) "Rm" = ( /obj/structure/cable/green{ d1 = 1; @@ -13974,13 +13970,13 @@ NT qi dr dA -dN +ad ea ep eF dr eW -fn +ah fB fO gb @@ -14690,7 +14686,7 @@ lI ds eN Lh -QM +al Np CN eN @@ -15552,7 +15548,7 @@ at at at cc -jy +Os jy hu yd @@ -15832,7 +15828,7 @@ AB Nb Vg Tg -mN +am PS Zm cF diff --git a/maps/tether/submaps/om_ships/aro.dmm b/maps/tether/submaps/om_ships/aro.dmm index 5322661bb8c..4dce075b15c 100644 --- a/maps/tether/submaps/om_ships/aro.dmm +++ b/maps/tether/submaps/om_ships/aro.dmm @@ -616,12 +616,12 @@ /turf/simulated/floor/tiled/white, /area/ship/aro/recreation) "bp" = ( -/obj/machinery/cooker/oven, +/obj/machinery/appliance/cooker/oven, /obj/effect/floor_decal/borderfloorwhite/corner2, /turf/simulated/floor/tiled/white, /area/ship/aro/recreation) "bq" = ( -/obj/machinery/cooker/grill, +/obj/machinery/appliance/cooker/grill, /obj/effect/floor_decal/borderfloorwhite, /turf/simulated/floor/tiled/white, /area/ship/aro/recreation) diff --git a/maps/tether/submaps/om_ships/cruiser.dmm b/maps/tether/submaps/om_ships/cruiser.dmm index 719b3501b1b..842da3a6d34 100644 --- a/maps/tether/submaps/om_ships/cruiser.dmm +++ b/maps/tether/submaps/om_ships/cruiser.dmm @@ -1017,14 +1017,14 @@ /turf/simulated/floor/tiled/white, /area/mothership/kitchen) "cl" = ( -/obj/machinery/cooker/cereal, +/obj/machinery/appliance/mixer/cereal, /obj/effect/floor_decal/industrial/warning/dust{ dir = 9 }, /turf/simulated/floor/tiled/white, /area/mothership/kitchen) "cm" = ( -/obj/machinery/cooker/fryer, +/obj/machinery/appliance/cooker/fryer, /obj/structure/table/steel_reinforced, /obj/effect/floor_decal/industrial/warning/dust{ dir = 1 @@ -1032,7 +1032,7 @@ /turf/simulated/floor/tiled/white, /area/mothership/kitchen) "cn" = ( -/obj/machinery/cooker/oven, +/obj/machinery/appliance/cooker/oven, /obj/structure/table/steel_reinforced, /obj/effect/floor_decal/industrial/warning/dust{ dir = 1 @@ -1040,7 +1040,7 @@ /turf/simulated/floor/tiled/white, /area/mothership/kitchen) "co" = ( -/obj/machinery/cooker/grill, +/obj/machinery/appliance/cooker/grill, /obj/structure/table/steel_reinforced, /obj/effect/floor_decal/industrial/warning/dust{ dir = 1 @@ -1049,7 +1049,7 @@ /turf/simulated/floor/tiled/white, /area/mothership/kitchen) "cp" = ( -/obj/machinery/cooker/candy, +/obj/machinery/appliance/mixer/candy, /obj/effect/floor_decal/industrial/warning/dust{ dir = 1 }, diff --git a/maps/tether/submaps/om_ships/mercenarybase.dmm b/maps/tether/submaps/om_ships/mercenarybase.dmm index 95238c7b191..42b6a45289a 100644 --- a/maps/tether/submaps/om_ships/mercenarybase.dmm +++ b/maps/tether/submaps/om_ships/mercenarybase.dmm @@ -3272,15 +3272,15 @@ /turf/simulated/floor/tiled/dark, /area/mercbase/roid) "nm" = ( -/obj/machinery/cooker/oven, +/obj/machinery/appliance/cooker/oven, /turf/simulated/floor/tiled/dark, /area/mercbase/roid) "nn" = ( -/obj/machinery/cooker/grill, +/obj/machinery/appliance/cooker/grill, /turf/simulated/floor/tiled/dark, /area/mercbase/roid) "no" = ( -/obj/machinery/cooker/fryer, +/obj/machinery/appliance/cooker/fryer, /turf/simulated/floor/tiled/dark, /area/mercbase/roid) "np" = ( diff --git a/maps/tether/submaps/om_ships/shelter_6.dmm b/maps/tether/submaps/om_ships/shelter_6.dmm index e80de136a1c..93d7e9dedfd 100644 --- a/maps/tether/submaps/om_ships/shelter_6.dmm +++ b/maps/tether/submaps/om_ships/shelter_6.dmm @@ -144,14 +144,6 @@ /obj/item/weapon/storage/box/metalfoam, /obj/item/weapon/storage/box/metalfoam, /obj/item/weapon/storage/box/metalfoam, -/obj/item/clothing/suit/space/void/merc/prototype, -/obj/item/clothing/suit/space/void/merc/prototype, -/obj/item/clothing/suit/space/void/merc/prototype, -/obj/item/clothing/suit/space/void/merc/prototype, -/obj/item/clothing/head/helmet/space/void/merc/prototype, -/obj/item/clothing/head/helmet/space/void/merc/prototype, -/obj/item/clothing/head/helmet/space/void/merc/prototype, -/obj/item/clothing/head/helmet/space/void/merc/prototype, /obj/item/clothing/shoes/magboots/adv, /obj/item/clothing/shoes/magboots/adv, /obj/item/clothing/shoes/magboots/adv, @@ -189,6 +181,15 @@ /obj/item/weapon/storage/briefcase/inflatable, /obj/item/weapon/storage/briefcase/inflatable, /obj/item/weapon/storage/belt/utility/full, +/obj/item/clothing/suit/space/void/responseteam/command, +/obj/item/clothing/suit/space/void/responseteam/engineer, +/obj/item/clothing/suit/space/void/responseteam/engineer, +/obj/item/clothing/suit/space/void/responseteam/medical, +/obj/item/clothing/suit/space/void/responseteam/medical, +/obj/item/clothing/suit/space/void/responseteam/security, +/obj/item/clothing/suit/space/void/responseteam/security, +/obj/item/clothing/suit/space/void/responseteam/security, +/obj/item/clothing/suit/space/void/responseteam/security, /turf/simulated/floor/reinforced, /area/shuttle/tabiranth) "af" = ( @@ -877,6 +878,7 @@ /obj/item/weapon/tank/emergency/oxygen/double, /obj/item/weapon/tank/emergency/oxygen/double, /obj/item/weapon/tank/emergency/oxygen/double, +/obj/item/clothing/suit/space/void/refurb/officer, /turf/simulated/floor/tiled/white, /area/shuttle/tabiranth) "aP" = ( diff --git a/maps/tether/submaps/space/guttersite.dmm b/maps/tether/submaps/space/guttersite.dmm index e9e6bded61d..2b309d7cafa 100644 --- a/maps/tether/submaps/space/guttersite.dmm +++ b/maps/tether/submaps/space/guttersite.dmm @@ -594,16 +594,12 @@ /turf/simulated/floor/plating/eris/under, /area/tether_away/guttersite/atmos) "bO" = ( -/obj/structure/table/steel, -/obj/structure/cable/cyan, -/obj/machinery/power/apc{ - dir = 4; - name = "east bump"; - pixel_x = 24 +/obj/structure/closet/toolcloset, +/obj/machinery/alarm/alarms_hidden{ + pixel_y = 25 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/engines) +/area/tether_away/guttersite/storage) "bP" = ( /obj/structure/table/steel, /obj/structure/cable/cyan, @@ -650,20 +646,24 @@ /area/tether_away/guttersite/engines) "bU" = ( /obj/machinery/alarm{ - alarm_id = null; - breach_detection = 0; - dir = 1; + alarms_hidden = 1; + dir = 4; icon_state = "alarm0"; - pixel_y = -22 + pixel_x = -22; + pixel_y = 0 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/engines) +/area/tether_away/guttersite/maint) "bV" = ( -/obj/machinery/firealarm{ - dir = 1; - pixel_x = 0; - pixel_y = -25 +/obj/structure/table/steel, +/obj/structure/cable/cyan, +/obj/machinery/power/apc{ + alarms_hidden = 1; + dir = 4; + name = "east bump"; + pixel_x = 24 }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/engines) "bW" = ( @@ -711,23 +711,25 @@ /area/tether_away/guttersite/maint) "cb" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 + dir = 8 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6; + dir = 4; icon_state = "intact-supply" }, -/obj/structure/bed/chair/bay/comfy/black{ - dir = 1; - icon_state = "bay_comfychair_preview" - }, /obj/structure/cable/cyan{ - d1 = 2; - d2 = 4; - icon_state = "2-4" + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/turf/simulated/floor/tiled/eris/steel/bar_dance, -/area/tether_away/guttersite/commons) +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/maint) "cc" = ( /obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ dir = 5 @@ -942,14 +944,15 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/maint) "cD" = ( -/obj/machinery/alarm{ - dir = 4; - icon_state = "alarm0"; - pixel_x = -22; - pixel_y = 0 +/obj/structure/closet/crate/engineering, +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/maint) +/area/tether_away/guttersite/storage) "cE" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 1 @@ -1000,9 +1003,16 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/storage) "cL" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/structure/table/steel, +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/commons) +/area/tether_away/guttersite/atmos) "cM" = ( /obj/effect/landmark/corpse/clown, /turf/simulated/mineral/floor/vacuum, @@ -1126,11 +1136,14 @@ /turf/simulated/floor/tiled/eris/steel/bar_light, /area/tether_away/guttersite/commons) "da" = ( -/obj/structure/window/basic{ - dir = 1 +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/commons) +/area/tether_away/guttersite/engines) "db" = ( /obj/machinery/vending/food, /turf/simulated/floor/tiled/eris/dark/gray_perforated, @@ -1145,9 +1158,14 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/commons) "dd" = ( -/obj/machinery/light, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/commons) +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 + }, +/turf/simulated/floor/plating/eris/under, +/area/tether_away/guttersite/atmos) "de" = ( /turf/simulated/wall/r_wall, /area/tether_away/guttersite/medbay) @@ -1175,9 +1193,18 @@ /turf/simulated/floor/tiled/eris/steel/bar_dance, /area/tether_away/guttersite/commons) "di" = ( -/obj/structure/table/darkglass, -/obj/item/weapon/storage/box/glasses/meta, -/turf/simulated/floor/tiled/eris/steel/bar_dance, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/structure/cable/cyan{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/turf/simulated/floor/tiled/eris/steel/bar_light, /area/tether_away/guttersite/commons) "dj" = ( /obj/structure/table/darkglass, @@ -1342,22 +1369,21 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/office) "dy" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8; - icon_state = "map-scrubbers" +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/maintenance_hatch{ + req_one_access = list() }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4; + icon_state = "intact-supply" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 }, /obj/structure/cable/cyan{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/cable/cyan{ - d1 = 1; - d2 = 4; - icon_state = "1-4" + d1 = 4; + d2 = 8; + icon_state = "4-8" }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/commons) @@ -1450,14 +1476,23 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/office) "dJ" = ( -/obj/machinery/alarm{ +/obj/structure/window/basic{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4; - icon_state = "alarm0"; - pixel_x = -22; - pixel_y = 0 + icon_state = "intact-supply" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/medbay) +/area/tether_away/guttersite/commons) "dK" = ( /obj/structure/grille, /obj/machinery/door/firedoor/glass, @@ -1474,13 +1509,16 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/medbay) "dM" = ( -/obj/machinery/firealarm{ +/obj/machinery/alarm{ + alarm_id = null; + alarms_hidden = 1; + breach_detection = 0; dir = 1; - pixel_x = 0; - pixel_y = -25 + icon_state = "alarm0"; + pixel_y = -22 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/medbay) +/area/tether_away/guttersite/engines) "dN" = ( /turf/simulated/wall/r_wall, /area/tether_away/guttersite/office) @@ -1543,82 +1581,78 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/office) "dW" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4; icon_state = "intact-supply" }, -/obj/structure/bed/chair/bay/comfy/black{ - dir = 1; - icon_state = "bay_comfychair_preview" - }, /obj/structure/cable/cyan{ d1 = 4; d2 = 8; icon_state = "4-8" }, -/turf/simulated/floor/tiled/eris/steel/bar_dance, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 1 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/commons) "dX" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, /obj/structure/cable/cyan{ d1 = 4; d2 = 8; icon_state = "4-8" }, -/turf/simulated/floor/tiled/eris/steel/bar_dance, -/area/tether_away/guttersite/commons) -"dY" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/wall/r_wall, -/area/tether_away/guttersite/commons) -"dZ" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, -/obj/structure/closet/cabinet, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/commons) -"ea" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1; icon_state = "map-supply" }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/commons) +"dY" = ( +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/structure/cable/cyan{ + icon_state = "1-8" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/commons) +"dZ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, /obj/structure/cable/cyan{ d1 = 4; d2 = 8; icon_state = "4-8" }, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/turf/simulated/floor/tiled/eris/steel/bar_light, +/area/tether_away/guttersite/commons) +"ea" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/mob/living/simple_mob/vore/catgirl{ + name = "Blaire" + }, +/turf/simulated/floor/tiled/eris/steel/bar_light, /area/tether_away/guttersite/commons) "eb" = ( /turf/simulated/wall/r_wall, @@ -1655,20 +1689,17 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/office) "ej" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" + dir = 9; + pixel_y = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 }, -/obj/machinery/washing_machine, /obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" + icon_state = "1-8" }, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/turf/simulated/floor/tiled/eris/steel/bar_light, /area/tether_away/guttersite/commons) "ek" = ( /obj/structure/window/basic{ @@ -1679,30 +1710,28 @@ /turf/simulated/floor/tiled/eris/white/monofloor, /area/tether_away/guttersite/office) "el" = ( +/obj/machinery/holoplant, +/obj/machinery/holoplant{ + icon_state = "plant-10" + }, /obj/machinery/alarm{ + alarms_hidden = 1; dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/vault) +/area/tether_away/guttersite/commons) "em" = ( /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/vault) "en" = ( -/obj/machinery/alarm{ - dir = 4; - icon_state = "alarm0"; - pixel_x = -22; - pixel_y = 0 - }, -/obj/machinery/light{ - dir = 1; - icon_state = "tube1" +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 1 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/walkway) +/area/tether_away/guttersite/commons) "eo" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 8 @@ -1727,97 +1756,72 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/bridge) "er" = ( +/obj/structure/table/darkglass, +/obj/item/weapon/storage/box/glasses/meta, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 1 + }, +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 4; + dir = 1; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether_away/guttersite/commons) +"es" = ( +/turf/simulated/floor/tiled/eris/white/monofloor, +/area/tether_away/guttersite/office) +"et" = ( +/obj/structure/bed/chair/bay/comfy/black{ + dir = 1; + icon_state = "bay_comfychair_preview" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 1 + }, +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 4; + dir = 1; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether_away/guttersite/commons) +"eu" = ( +/obj/structure/bed/chair/bay/comfy/black{ + dir = 1; + icon_state = "bay_comfychair_preview" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether_away/guttersite/commons) +"ev" = ( +/obj/structure/curtain/open/shower, +/obj/machinery/shower, +/turf/simulated/floor/tiled/eris/dark/techfloor_grid, +/area/tether_away/guttersite/commons) +"ew" = ( +/obj/structure/bed/chair/bay/comfy/black{ + dir = 8; + icon_state = "bay_comfychair_preview" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/commons) +"ex" = ( /obj/machinery/alarm{ + alarms_hidden = 1; dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0 }, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/office) -"es" = ( -/turf/simulated/floor/tiled/eris/white/monofloor, -/area/tether_away/guttersite/office) -"et" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, -/obj/structure/curtain/open/shower, -/obj/machinery/shower, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled/eris/dark/techfloor_grid, -/area/tether_away/guttersite/commons) -"eu" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled/eris/dark/techfloor_grid, -/area/tether_away/guttersite/commons) -"ev" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, -/obj/structure/table/darkglass, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/commons) -"ew" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, -/obj/structure/bed/chair/bay/comfy/black{ - dir = 8; - icon_state = "bay_comfychair_preview" - }, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/commons) -"ex" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9; - icon_state = "intact-scrubbers" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9; - icon_state = "intact-supply" - }, -/obj/structure/cable/cyan{ - icon_state = "1-8" - }, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/turf/simulated/floor/tiled/eris/steel/bar_dance, /area/tether_away/guttersite/commons) "ey" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -1954,13 +1958,15 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/walkway) "eJ" = ( -/obj/machinery/firealarm{ - dir = 1; - pixel_x = 0; - pixel_y = -25 +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 }, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/walkway) +/turf/simulated/floor/tiled/eris/dark/techfloor_grid, +/area/tether_away/guttersite/commons) "eK" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 8 @@ -2275,13 +2281,12 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/bridge) "fm" = ( -/obj/machinery/firealarm{ - dir = 1; - pixel_x = 0; - pixel_y = -25 +/obj/machinery/door/airlock/maintenance_hatch{ + req_one_access = list() }, +/obj/machinery/door/firedoor, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/bridge) +/area/tether_away/guttersite/commons) "fn" = ( /obj/structure/bed/chair/bay/comfy/black{ dir = 4; @@ -2679,15 +2684,16 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "gb" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 +/obj/structure/table/darkglass, +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/security) +/area/tether_away/guttersite/commons) "gc" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 @@ -2932,16 +2938,15 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "gC" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4; - icon_state = "intact-scrubbers" +/obj/machinery/light, +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, -/turf/simulated/wall/r_wall, -/area/tether_away/guttersite/security) +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/commons) "gD" = ( /obj/structure/bed/chair/office/dark{ dir = 1; @@ -2953,16 +2958,16 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "gE" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10; - icon_state = "intact-scrubbers" +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10; - icon_state = "intact-supply" - }, -/turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/security) +/obj/structure/table/darkglass, +/obj/machinery/microwave, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether_away/guttersite/commons) "gF" = ( /obj/structure/table/rack/shelf/steel, /obj/random/mre, @@ -3025,22 +3030,36 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/vault) "gK" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 1 + }, +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /obj/machinery/alarm{ + alarms_hidden = 1; dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/security) +/area/tether_away/guttersite/walkway) "gL" = ( -/obj/machinery/firealarm{ - dir = 1; - pixel_x = 0; - pixel_y = -25 +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/security) +/area/tether_away/guttersite/medbay) "gM" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 1 @@ -3051,10 +3070,14 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "gN" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 + }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/security) +/area/tether_away/guttersite/medbay) "gO" = ( /obj/structure/fence/end{ dir = 4; @@ -3122,18 +3145,14 @@ /area/tether_away/guttersite/security) "gV" = ( /obj/machinery/alarm{ + alarms_hidden = 1; dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0 }, -/obj/structure/cable/cyan{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/bridge) +/area/tether_away/guttersite/vault) "gW" = ( /obj/structure/fence/door/opened{ dir = 8; @@ -3152,16 +3171,15 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "gZ" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 5; - icon_state = "intact-scrubbers" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9; - icon_state = "intact-supply" +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/security) +/area/tether_away/guttersite/office) "ha" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8; @@ -3236,23 +3254,14 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/docking) "hi" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4; - icon_state = "intact-scrubbers" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, -/obj/structure/bed/chair/office/dark{ - dir = 4; - icon_state = "officechair_dark" - }, -/mob/living/simple_mob/humanoid/merc/ranged/laser{ - faction = "wolfgirl" +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/security) +/area/tether_away/guttersite/walkway) "hj" = ( /mob/living/simple_mob/mobs_monsters/clowns/big/cluwne, /turf/simulated/mineral/floor/vacuum, @@ -3333,13 +3342,19 @@ /area/tether_away/guttersite/docking) "hq" = ( /obj/machinery/alarm{ + alarms_hidden = 1; dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0 }, +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/docking) +/area/tether_away/guttersite/bridge) "hr" = ( /obj/structure/table/rack/shelf/steel, /obj/random/cash, @@ -3473,15 +3488,24 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/docking) "hH" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 1 }, -/obj/machinery/light{ - dir = 1; - icon_state = "tube1" +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 1 + }, +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 4; + pixel_x = 26 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/docking) +/area/tether_away/guttersite/walkway) "hI" = ( /obj/machinery/atmospherics/pipe/manifold4w/hidden, /turf/simulated/floor/tiled/eris/dark/gray_perforated, @@ -3494,16 +3518,26 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/docking) "hK" = ( -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 8; - icon_state = "intact" +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4; + icon_state = "intact-supply" }, -/obj/machinery/light{ +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/firealarm{ + alarms_hidden = 1; dir = 1; - icon_state = "tube1" + pixel_x = 0; + pixel_y = -25 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/docking) +/area/tether_away/guttersite/bridge) "hL" = ( /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 8; @@ -3551,13 +3585,26 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/docking) "hQ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4; + icon_state = "intact-supply" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /obj/machinery/firealarm{ + alarms_hidden = 1; dir = 1; pixel_x = 0; pixel_y = -25 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/docking) +/area/tether_away/guttersite/office) "hR" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 @@ -3573,15 +3620,14 @@ /turf/space, /area/space) "hU" = ( -/obj/structure/bed/chair/office/dark{ - dir = 8; - icon_state = "officechair_dark" - }, -/mob/living/simple_mob/humanoid/merc/melee/poi{ - faction = "wolfgirl" +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/security) +/area/tether_away/guttersite/bridge) "hV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4; @@ -3598,25 +3644,17 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/office) "hW" = ( +/obj/machinery/light{ + dir = 8 + }, /obj/machinery/firealarm{ + alarms_hidden = 1; dir = 1; pixel_x = 0; pixel_y = -25 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/office) +/area/tether_away/guttersite/vault) "hX" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4; @@ -3907,15 +3945,13 @@ /area/tether_away/guttersite/office) "iI" = ( /obj/machinery/firealarm{ - dir = 1; - pixel_x = 0; - pixel_y = -25 - }, -/obj/machinery/light{ - dir = 8 + alarms_hidden = 1; + dir = 8; + pixel_x = -24; + pixel_y = 0 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/vault) +/area/tether_away/guttersite/docking) "iJ" = ( /mob/living/simple_mob/vore/aggressive/mimic, /turf/simulated/mineral/floor/vacuum, @@ -4194,11 +4230,19 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/commons) "jC" = ( -/obj/machinery/door/airlock/maintenance_hatch{ - req_one_access = list() +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/obj/machinery/light{ + dir = 1; + icon_state = "tube1" }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/commons) +/area/tether_away/guttersite/walkway) "jD" = ( /turf/simulated/floor/tiled/eris/steel/bar_dance, /area/tether_away/guttersite/commons) @@ -4277,21 +4321,14 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "jK" = ( -/obj/machinery/atmospherics/pipe/simple/hidden, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6; - icon_state = "intact-supply" - }, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 8; + pixel_x = 25; + pixel_y = 0 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/security) +/area/tether_away/guttersite/docking) "jL" = ( /obj/structure/bed/padded, /obj/item/weapon/bedsheet/ian, @@ -4372,20 +4409,11 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "jY" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 2 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/wall/r_wall, -/area/tether_away/guttersite/security) +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) "jZ" = ( /obj/machinery/meter, /obj/machinery/atmospherics/pipe/simple/visible/red{ @@ -4409,21 +4437,21 @@ /turf/simulated/floor/tiled/eris/steel/bar_dance, /area/tether_away/guttersite/commons) "kc" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" + dir = 1 }, -/obj/structure/table/steel, +/obj/machinery/atmospherics/pipe/simple/hidden, /obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 2 }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/security) +/area/tether_away/guttersite/docking) "kd" = ( /obj/machinery/light, /turf/simulated/floor/tiled/eris/steel/bar_dance, @@ -4459,15 +4487,14 @@ /turf/simulated/floor/tiled/eris/steel/bar_dance, /area/tether_away/guttersite/commons) "kj" = ( -/obj/machinery/firealarm{ - dir = 1; - pixel_x = 0; - pixel_y = -25 +/obj/machinery/atmospherics/pipe/simple/hidden, +/obj/structure/cable/cyan{ + d1 = 2; + d2 = 8; + icon_state = "2-8" }, -/obj/structure/table/darkglass, -/obj/machinery/microwave, -/turf/simulated/floor/tiled/eris/steel/bar_dance, -/area/tether_away/guttersite/commons) +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) "kk" = ( /obj/structure/table/darkglass, /obj/item/weapon/storage/box/cups, @@ -4485,34 +4512,13 @@ /turf/simulated/floor/tiled/eris/steel/bar_dance, /area/tether_away/guttersite/commons) "kn" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 1; - icon_state = "map-supply" - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /obj/structure/table/steel, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, +/obj/item/device/flashlight/lamp, /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "ko" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, /obj/structure/table/steel, -/obj/item/device/flashlight/lamp, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, +/obj/item/weapon/pen/fountain, /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "kp" = ( @@ -4541,12 +4547,10 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/commons) "kt" = ( -/obj/machinery/holoplant, -/obj/machinery/holoplant{ - icon_state = "plant-10" - }, +/obj/structure/table/steel, +/obj/item/weapon/paper_bin, /turf/simulated/floor/tiled/eris/dark/gray_perforated, -/area/tether_away/guttersite/commons) +/area/tether_away/guttersite/security) "ku" = ( /obj/machinery/holoplant, /obj/machinery/holoplant{ @@ -4602,36 +4606,26 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/commons) "kD" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4; - icon_state = "intact-supply" - }, /obj/structure/table/steel, -/obj/item/weapon/pen/fountain, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 1 + }, /obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" + d1 = 1; + d2 = 4; + dir = 1; + icon_state = "1-2" }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "kE" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ +/obj/machinery/light{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ +/obj/machinery/atmospherics/unary/vent_pump/on{ dir = 4; - icon_state = "intact-supply" - }, -/obj/structure/table/steel, -/obj/item/weapon/paper_bin, -/obj/structure/cable/cyan{ - d1 = 4; - d2 = 8; - icon_state = "4-8" + icon_state = "map_vent_out" }, /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) @@ -4644,18 +4638,16 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/commons) "kG" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9; - icon_state = "intact-scrubbers" +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 4; + dir = 1; + icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9; - icon_state = "intact-supply" - }, -/obj/structure/table/steel, -/obj/structure/cable/cyan{ - icon_state = "1-8" + dir = 10 }, +/obj/machinery/atmospherics/pipe/simple/hidden, /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "kH" = ( @@ -5048,9 +5040,18 @@ /turf/simulated/mineral/floor/vacuum, /area/space) "lP" = ( -/obj/item/weapon/card/emag, -/turf/simulated/mineral/floor/vacuum, -/area/space) +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 1 + }, +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 4; + dir = 1; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) "lQ" = ( /obj/item/weapon/card/emag_broken, /turf/simulated/mineral/floor/vacuum, @@ -5233,13 +5234,28 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/atmos) "mt" = ( -/obj/machinery/firealarm{ - dir = 1; - pixel_x = 0; - pixel_y = -25 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4; + icon_state = "intact-supply" }, -/turf/simulated/floor/plating/eris/under, -/area/tether_away/guttersite/atmos) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/light{ + dir = 1; + icon_state = "tube1" + }, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/alarm{ + alarms_hidden = 1; + pixel_y = 25 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/bridge) "mu" = ( /obj/structure/window/basic{ dir = 4; @@ -5478,12 +5494,20 @@ /turf/simulated/floor/carpet/gaycarpet, /area/tether_away/guttersite/unexplored) "mV" = ( -/obj/item/device/radio/headset/nanotrasen/alt{ - desc = "The headset of an Eltorro employee."; - name = "Weird Headset" +/obj/machinery/atmospherics/pipe/simple/hidden, +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 4; + icon_state = "1-4" }, -/turf/simulated/floor/carpet/gaycarpet, -/area/tether_away/guttersite/unexplored) +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 1 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) "mW" = ( /obj/item/weapon/reagent_containers/food/drinks/cans/cola, /turf/simulated/floor/carpet/gaycarpet, @@ -5509,9 +5533,21 @@ /turf/simulated/mineral/floor/vacuum, /area/tether_away/guttersite/unexplored) "nc" = ( -/obj/effect/landmark/corpse/syndicatecommando, -/turf/simulated/mineral/floor/vacuum, -/area/tether_away/guttersite/unexplored) +/obj/structure/table/steel, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4; + icon_state = "intact-supply" + }, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) "nd" = ( /obj/effect/landmark/corpse/syndicatesoldier, /turf/simulated/mineral/floor/vacuum, @@ -5619,11 +5655,27 @@ /turf/simulated/floor/tiled/eris/dark/gray_perforated, /area/tether_away/guttersite/security) "ny" = ( -/mob/living/simple_mob/vore/catgirl{ - name = "Blaire" +/obj/structure/bed/chair/office/dark{ + dir = 8; + icon_state = "officechair_dark" }, -/turf/simulated/floor/tiled/eris/steel/bar_light, -/area/tether_away/guttersite/commons) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4; + icon_state = "intact-supply" + }, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/mob/living/simple_mob/humanoid/merc/melee/poi{ + faction = "wolfgirl" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) "nz" = ( /mob/living/simple_mob/mobs_monsters/clowns/big/tunnelclown, /turf/simulated/mineral/floor/vacuum, @@ -5771,6 +5823,329 @@ /obj/effect/shuttle_landmark/premade/guttersite/mshuttle, /turf/space, /area/space) +"nO" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/maintenance_hatch{ + req_one_access = list(38) + }, +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4; + icon_state = "intact-supply" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"nP" = ( +/obj/structure/cable/cyan{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 1; + icon_state = "map-supply" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"nQ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 1 + }, +/obj/machinery/light{ + dir = 4 + }, +/obj/structure/cable/cyan{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/walkway) +"nR" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 8; + pixel_x = 25; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"nS" = ( +/obj/machinery/alarm/alarms_hidden{ + pixel_y = 25 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"nT" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9; + icon_state = "intact-supply" + }, +/obj/structure/cable/cyan{ + icon_state = "1-8" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"nU" = ( +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"nV" = ( +/obj/machinery/alarm/alarms_hidden{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -25 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"nW" = ( +/obj/machinery/alarm/alarms_hidden{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -25 + }, +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"nX" = ( +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 8; + pixel_x = -24; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"nY" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"nZ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1; + icon_state = "tube1" + }, +/obj/machinery/alarm{ + alarms_hidden = 1; + pixel_y = 25 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"oa" = ( +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 8; + icon_state = "intact" + }, +/obj/machinery/light{ + dir = 1; + icon_state = "tube1" + }, +/obj/machinery/alarm{ + alarms_hidden = 1; + pixel_y = 25 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"ob" = ( +/obj/structure/bed/chair/office/dark{ + dir = 4; + icon_state = "officechair_dark" + }, +/mob/living/simple_mob/humanoid/merc/ranged/laser{ + faction = "wolfgirl" + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"oc" = ( +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"od" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"oe" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"of" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"og" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/maintenance_hatch{ + req_one_access = list(38) + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"oh" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"oi" = ( +/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/eris/dark/gray_perforated, +/area/tether_away/guttersite/security) +"oj" = ( +/obj/machinery/atmospherics/pipe/simple/hidden, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 2 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"ok" = ( +/obj/machinery/alarm{ + alarms_hidden = 1; + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"ol" = ( +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"om" = ( +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass/hidden/steel, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"on" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"oo" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, +/obj/machinery/door/firedoor/glass/hidden/steel, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"op" = ( +/obj/machinery/firealarm{ + alarms_hidden = 1; + dir = 1; + pixel_x = 0; + pixel_y = -25 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"oq" = ( +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"or" = ( +/obj/machinery/door/firedoor/glass/hidden/steel, +/turf/simulated/floor/tiled/eris/dark/gray_perforated, +/area/tether_away/guttersite/docking) +"Bh" = ( +/obj/item/device/radio/headset/heads/captain, +/turf/simulated/floor/carpet/gaycarpet, +/area/tether_away/guttersite/unexplored) "Ob" = ( /obj/structure/cable/cyan{ d1 = 1; @@ -9961,7 +10336,7 @@ aa aa aa aB -aE +bU aH aJ aX @@ -9970,7 +10345,7 @@ cQ aX cQ aX -bU +dM aF ag ag @@ -10254,7 +10629,7 @@ bB bH bQ aX -bV +da aF ag ag @@ -10535,7 +10910,7 @@ aU aY bm bC -bO +bV aJ aJ bX @@ -10736,12 +11111,12 @@ ag fu fu jJ -gY +kE ga gk gq fw -gK +oc fu ag ag @@ -10822,7 +11197,7 @@ aE aE aE cz -cD +bU aB ag hd @@ -10877,13 +11252,13 @@ ag fu fu fC -jK -fU -gb +kj +kG +mV gl fU gy -gL +nU fu ag ag @@ -11019,9 +11394,9 @@ ag fu fz fD -jX fw -gc +fw +jX iT fw gz @@ -11161,15 +11536,15 @@ ag fu fz fE -jX fw -gd +fw +nc gd gd gz fw fu -fw +nW fu fu ag @@ -11303,9 +11678,9 @@ ag fu lG fF -jX fw -gd +fw +nc gd gd gz @@ -11445,9 +11820,9 @@ ag fu fA fG -jX fw -hU +fw +ny ge gs gz @@ -11531,7 +11906,7 @@ by bF bP cu -ms +cL ms aT ag @@ -11587,11 +11962,11 @@ ag fu fB fH +fw +fw jX fw fw -fw -fw gz fw fu @@ -11729,9 +12104,9 @@ fu fu fu fu -jY fu -gf +fu +nO fu fu gA @@ -11816,7 +12191,7 @@ bJ bq bq bq -mt +dd aT ag ag @@ -11871,10 +12246,10 @@ fu ly fw lH +fw +fw jX fw -fw -fw fu gz fw @@ -12013,9 +12388,9 @@ fu fx fw fw -kc -fw +gd fw +jX fw fu gB @@ -12154,11 +12529,11 @@ ad fu fw fw +fw +gd fI -kn +nP fV -fw -fw fu gz fw @@ -12294,13 +12669,13 @@ ad ad ad fu +nS fw fw +kn fw -ko -fw -fw -fw +jX +nU fu gz fw @@ -12395,7 +12770,7 @@ ag cF cF dh -jD +ex ez jD jD @@ -12439,18 +12814,18 @@ fu fw fw fw -kD +ko fZ -fw +jX fw fu -gz -hg -fw -fw -fw -fw -fw +nY +od +oe +oe +oe +oe +gy fw hg fw @@ -12560,7 +12935,7 @@ aa aa dn dn -en +jC fj iZ dn @@ -12581,18 +12956,18 @@ fu fw fw fw -kE +kt gD -fw +jX gX fu -gC fu fu fu fu fu -gf +fu +og fu fu fu @@ -12723,18 +13098,18 @@ fu fw fw fw -kc -fw +gd fw +jX gn fu -hi -fw +ob +nV gm -fw +nX nx fw -fw +oh gP fw fw @@ -12818,9 +13193,9 @@ ag ag cF cF -cZ di -cb +er +et ey eC ey @@ -12830,9 +13205,9 @@ ey eO eR eS +hH eS -eS -eS +gK eS eS eT @@ -12856,8 +13231,8 @@ eS eS eS eS -eT -eS +nQ +hH eS eS eS @@ -12865,18 +13240,18 @@ jy jH jH jI -kG -fw -fw +kD +lP +nT gn fu -gE -gN -gN -gN -gZ fw fw +fw +fw +of +oe +oi hl fw jx @@ -12960,9 +13335,9 @@ ag cF cF dc -cZ +dZ dh -dW +eu jD jD jD @@ -13102,9 +13477,9 @@ cF cF cZ jv -ny +ea dh -dW +eu jD ka jD @@ -13130,7 +13505,7 @@ dn dn ee fy -eJ +hi dn dn aa @@ -13244,9 +13619,9 @@ cF cU cZ cZ -cZ +dZ dh -dW +eu jD dh jD @@ -13385,17 +13760,17 @@ cF cF db cZ -cZ -cZ +di +ej dj -dW +eu jD kb jD kb jD jD -kj +gE cF ac ab @@ -13515,7 +13890,7 @@ lR ab ac aB -cA +cb aT br ji @@ -13527,10 +13902,10 @@ cF cF cF cF -dm +dy cF cF -dX +jD jD jD jD @@ -13669,10 +14044,10 @@ cF jL jP jT -da -kt +dJ +el +cF cF -dY cF cF jD @@ -13794,7 +14169,7 @@ ab ab lU ab -lP +ab ab ab ac @@ -13811,10 +14186,10 @@ cF cI cH cH -cH +eo cH jA -dZ +jA eG cF cF @@ -13953,11 +14328,11 @@ cF jM jQ jU -da +dJ +cH +cH +cH cH -cL -ea -cS cH cF jD @@ -13983,7 +14358,7 @@ eb eh fM fR -gV +hq ja eb eb @@ -14095,10 +14470,10 @@ cF cF cF cF -cH -cH +dW +en +jB jB -ej jB cH cF @@ -14237,11 +14612,11 @@ dk dk dk cF +dX +cS cH cH cH -eo -cH cH dm jD @@ -14269,7 +14644,7 @@ fN mN hb jc -fm +hU eb aa aa @@ -14379,10 +14754,10 @@ cF cF cF cF -cH +eo cH cF -dY +cF cF cF cF @@ -14521,11 +14896,11 @@ cF jN jR jV -da +dJ cH cF -et -kp +ev +eJ kq cF jD @@ -14663,10 +15038,10 @@ cF cI cH cH -cH +eo cH cF -eu +kp kp kp cF @@ -14805,10 +15180,10 @@ cF jO jS jW -da +dJ cH -jC -eu +fm +kp kp kr cF @@ -14931,7 +15306,7 @@ lS ac ac ax -le +bO aD aD aD @@ -14947,10 +15322,10 @@ cF cF cF cF -dm +dy +cF cF cF -dY cF cF cF @@ -15089,11 +15464,11 @@ cF ks kB kB -cH +eo cH kN -ev kA +gb lu hZ aa @@ -15231,7 +15606,7 @@ cF cO cH cH -cH +eo cH kO ew @@ -15251,7 +15626,7 @@ de la dp dp -dJ +gL de de aa @@ -15373,12 +15748,12 @@ cF cO cH cH -cH -cH -cH eo cH cH +cH +cH +cH hZ aa aa @@ -15515,12 +15890,12 @@ ds dt dt du -dy -du -du -ex +dY cH -dd +cH +cH +cH +gC cF aa aa @@ -15790,7 +16165,7 @@ cK aD aD lp -lp +cD ax ac ac @@ -16104,7 +16479,7 @@ dp dL eW dL -dM +gN de aa aa @@ -16539,7 +16914,7 @@ aa aa aa eb -hc +mt mx aa aa @@ -17391,7 +17766,7 @@ ab ab ac eb -fK +hK eb ac ac @@ -18524,7 +18899,7 @@ ml dN kv dR -er +gZ dR dR hV @@ -18669,7 +19044,7 @@ dR dR dR dR -hW +hQ dN dN dN @@ -19527,9 +19902,9 @@ dR fo fr lY +iI fr -fr -fr +jY ma fr fr @@ -19550,14 +19925,14 @@ fr fr fr fr +jY fr -fr -hq +ok fr fr lY fr -hQ +op fq eE eE @@ -19671,7 +20046,7 @@ jF jF jF jF -jF +kc kH jF jF @@ -19692,7 +20067,7 @@ kU kU kU kV -hh +oj hh hh hh @@ -19812,14 +20187,14 @@ fo fr fr ft -fr -fr +jK +jY gx fr fr fr fr -ft +nR fr fr fr @@ -19834,7 +20209,7 @@ ft fr fr lK -fr +jY fr fr fr @@ -19981,9 +20356,9 @@ mz mz mz gu -hG -hO -fr +ol +on +oq mG eE eE @@ -20691,7 +21066,7 @@ eE eE eE mF -hH +nZ hO fr mG @@ -21259,9 +21634,9 @@ eE mB mE gu -hG -hO -fr +om +oo +or mG eE eE @@ -21363,13 +21738,13 @@ ag ag ad ed -el +gV iU em gT iw iz -iI +hW ed ag ag @@ -22537,7 +22912,7 @@ eE eE eE fq -hK +oa hO fr mG @@ -23489,7 +23864,7 @@ ag ad ad ad -nc +ad ad ad ag @@ -24558,7 +24933,7 @@ ag ad mU na -mU +Bh mU mU ad @@ -24699,7 +25074,7 @@ aa ag ad mU -mV +mU mY mU mU diff --git a/maps/tether/tether-01-surface1.dmm b/maps/tether/tether-01-surface1.dmm index 0a07eadd299..15974d5c6c3 100644 --- a/maps/tether/tether-01-surface1.dmm +++ b/maps/tether/tether-01-surface1.dmm @@ -596,24 +596,9 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/cargo/mining) "aaY" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/obj/effect/floor_decal/corner/brown/border{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/cyan, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-4" +/obj/item/device/radio/intercom{ + dir = 8; + pixel_x = -24 }, /turf/simulated/floor/tiled, /area/tether/surfacebase/cargo/mining) @@ -814,6 +799,13 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_one_hall) +"abm" = ( +/turf/simulated/wall, +/area/rnd/hardstorage) +"abn" = ( +/obj/structure/table/rack/steel, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "abo" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -893,6 +885,13 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/trash_pit) +"abv" = ( +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) +"abw" = ( +/obj/structure/table/rack/shelf/steel, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "abx" = ( /obj/effect/floor_decal/industrial/loading{ dir = 8 @@ -960,18 +959,11 @@ /turf/simulated/floor/plating, /area/maintenance/lower/trash_pit) "abD" = ( -/obj/structure/table/glass, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/obj/machinery/atmospherics/unary/vent_pump/on{ +/obj/machinery/light/small{ dir = 1 }, -/obj/machinery/alarm{ - dir = 1; - pixel_y = -22 - }, /turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) +/area/rnd/hardstorage) "abE" = ( /obj/structure/catwalk, /obj/effect/decal/cleanable/dirt, @@ -1028,6 +1020,10 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, /area/maintenance/lower/trash_pit) +"abI" = ( +/obj/structure/closet/crate/plastic, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "abJ" = ( /obj/structure/catwalk, /obj/structure/cable{ @@ -1063,6 +1059,9 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/trash_pit) +"abN" = ( +/turf/simulated/wall/r_wall, +/area/rnd/testingroom) "abO" = ( /obj/machinery/door/airlock/maintenance/common{ name = "Trash Pit Access"; @@ -1137,6 +1136,13 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/cargo/mining) +"abW" = ( +/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary{ + name = "Research Testing Scrubber"; + use_power = 2 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "abX" = ( /obj/structure/catwalk, /obj/effect/decal/cleanable/dirt, @@ -1159,6 +1165,9 @@ }, /turf/simulated/floor/tiled/steel_dirty, /area/tether/surfacebase/cargo/warehouse) +"acb" = ( +/turf/simulated/mineral, +/area/rnd/testingroom) "acc" = ( /turf/simulated/wall, /area/tether/surfacebase/cargo/warehouse) @@ -1279,6 +1288,19 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, /area/maintenance/lower/research) +"acp" = ( +/obj/structure/grille, +/obj/structure/railing, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "suckysucky"; + name = "Scrubber Blast Door"; + opacity = 0 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "acq" = ( /obj/effect/floor_decal/techfloor{ dir = 4 @@ -1314,6 +1336,32 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled, /area/crew_quarters/visitor_dining) +"acu" = ( +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) "acv" = ( /obj/machinery/atmospherics/pipe/simple/visible/red{ dir = 6 @@ -1333,6 +1381,13 @@ /obj/machinery/vending/loadout/clothing, /turf/simulated/floor/tiled, /area/crew_quarters/visitor_laundry) +"acx" = ( +/obj/machinery/atmospherics/unary/vent_pump/on, +/obj/machinery/camera/network/research{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "acy" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ @@ -1403,6 +1458,10 @@ /obj/random/maintenance/clean, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining_eva) +"acD" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "acE" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 @@ -1854,17 +1913,8 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/cargo) "adn" = ( -/obj/effect/floor_decal/industrial/warning{ - dir = 8; - icon_state = "warning" - }, -/obj/machinery/computer/area_atmos/tag{ - dir = 4; - scrub_id = "rnd_can_store" - }, -/obj/machinery/camera/network/research, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora_storage) +/turf/simulated/wall/r_wall, +/area/rnd/tankstorage) "ado" = ( /obj/machinery/atmospherics/pipe/simple/visible/universal, /turf/simulated/floor/plating, @@ -1977,6 +2027,14 @@ /obj/machinery/portable_atmospherics/powered/pump/filled, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining_eva) +"adz" = ( +/obj/structure/cable/green{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "adA" = ( /obj/structure/disposaloutlet{ dir = 8 @@ -2005,8 +2063,8 @@ /obj/machinery/door/airlock/glass_mining{ id_tag = "cargodoor"; name = "Cargo Office"; - req_access = list(31); - req_one_access = list() + req_access = list(); + req_one_access = list(48,50) }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -2146,6 +2204,26 @@ /obj/machinery/light/small, /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) +"adM" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) +"adN" = ( +/obj/machinery/power/apc/high{ + dir = 4; + pixel_x = 28; + pixel_y = 0 + }, +/obj/structure/cable/green{ + d2 = 8; + icon_state = "0-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "adO" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -2901,6 +2979,9 @@ dir = 8 }, /area/tether/surfacebase/surface_one_hall) +"aeR" = ( +/turf/simulated/floor/reinforced, +/area/rnd/testingroom) "aeS" = ( /obj/effect/floor_decal/borderfloor{ dir = 10 @@ -3074,6 +3155,12 @@ "afd" = ( /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining_eva) +"afe" = ( +/obj/effect/floor_decal/industrial/warning{ + dir = 1 + }, +/turf/simulated/floor/reinforced, +/area/rnd/testingroom) "aff" = ( /obj/machinery/door/firedoor/glass, /obj/effect/floor_decal/steeldecal/steel_decals_central1{ @@ -3083,6 +3170,13 @@ dir = 4 }, /area/tether/surfacebase/cargo) +"afg" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5; + icon_state = "intact-supply" + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "afh" = ( /obj/effect/floor_decal/spline/plain{ dir = 4 @@ -3274,6 +3368,15 @@ /obj/machinery/lapvend, /turf/simulated/floor/tiled, /area/storage/primary) +"afu" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "afv" = ( /obj/structure/closet/firecloset, /turf/simulated/floor/tiled, @@ -3339,6 +3442,15 @@ /obj/machinery/camera/network/tether, /turf/simulated/floor/tiled, /area/hallway/lower/first_west) +"afA" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "afB" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -3523,6 +3635,24 @@ /obj/effect/floor_decal/industrial/loading, /turf/simulated/floor/tiled, /area/tether/surfacebase/cargo) +"afP" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "afQ" = ( /obj/structure/disposalpipe/segment{ dir = 1; @@ -3575,6 +3705,18 @@ "afT" = ( /turf/simulated/floor/tiled, /area/storage/primary) +"afU" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "afV" = ( /obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/tiled, @@ -3583,6 +3725,23 @@ /obj/structure/table/standard, /turf/simulated/floor/tiled, /area/storage/primary) +"afX" = ( +/obj/machinery/door/airlock/maintenance/rnd{ + name = "Research Maintenance Access"; + req_access = list(55) + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/hardstorage) "afY" = ( /obj/machinery/camera/network/civilian, /turf/simulated/floor/tiled, @@ -3684,6 +3843,27 @@ /obj/machinery/portable_atmospherics/canister/oxygen, /turf/simulated/floor/tiled, /area/rnd/xenoarch_storage) +"agl" = ( +/obj/machinery/atmospherics/unary/outlet_injector, +/turf/simulated/floor/reinforced, +/area/rnd/testingroom) +"agm" = ( +/obj/machinery/firealarm{ + dir = 1; + pixel_x = 0; + pixel_y = -24 + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) +"agn" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "ago" = ( /obj/effect/floor_decal/steeldecal/steel_decals6{ dir = 4 @@ -3713,6 +3893,14 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/cargo) +"agr" = ( +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) "ags" = ( /obj/machinery/light{ dir = 4 @@ -3753,6 +3941,24 @@ }, /turf/simulated/floor/tiled, /area/rnd/xenoarch_storage) +"agx" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"agy" = ( +/obj/structure/catwalk, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/obj/effect/floor_decal/rust, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) "agz" = ( /obj/structure/reagent_dispensers/watertank, /turf/simulated/floor/tiled, @@ -3787,6 +3993,45 @@ }, /turf/simulated/floor/tiled/steel_grid, /area/rnd/xenoarch_storage) +"agD" = ( +/obj/machinery/power/apc{ + cell_type = /obj/item/weapon/cell/apc; + dir = 8; + name = "west bump"; + pixel_x = -28 + }, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"agE" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/door/airlock/research{ + id_tag = "researchdoor"; + name = "Research Hard Storage"; + req_access = list(47) + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/rnd/hardstorage) +"agF" = ( +/obj/effect/floor_decal/industrial/warning/dust, +/turf/simulated/floor/reinforced, +/area/rnd/testingroom) +"agG" = ( +/obj/structure/disposaloutlet{ + dir = 1; + icon_state = "outlet" + }, +/obj/structure/disposalpipe/trunk, +/obj/effect/floor_decal/industrial/warning/dust, +/turf/simulated/floor/reinforced, +/area/rnd/testingroom) "agH" = ( /obj/structure/catwalk, /obj/effect/decal/cleanable/dirt, @@ -3831,6 +4076,11 @@ "agM" = ( /turf/simulated/wall, /area/tether/surfacebase/surface_one_hall) +"agN" = ( +/obj/effect/floor_decal/industrial/warning/dust, +/obj/machinery/atmospherics/pipe/simple/hidden, +/turf/simulated/floor/reinforced, +/area/rnd/testingroom) "agO" = ( /obj/structure/table/glass, /obj/machinery/status_display{ @@ -3847,6 +4097,23 @@ }, /turf/simulated/floor/tiled/white, /area/rnd/chemistry_lab) +"agP" = ( +/obj/machinery/door/firedoor, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "gogogo"; + name = "Blast Door"; + opacity = 0 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "agQ" = ( /obj/structure/railing{ dir = 8 @@ -3962,12 +4229,97 @@ }, /turf/simulated/floor/tiled/white, /area/rnd/chemistry_lab) +"aha" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/door/firedoor, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "gogogo"; + name = "Blast Door"; + opacity = 0 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"ahb" = ( +/obj/machinery/door/firedoor, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "gogogo"; + name = "Blast Door"; + opacity = 0 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "ahc" = ( /obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary{ scrub_id = "atrium" }, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/surface_one_hall) +"ahd" = ( +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "shuttle blast"; + name = "Shuttle Blast Doors"; + opacity = 0 + }, +/obj/machinery/door/window/northleft{ + req_access = list(47) + }, +/obj/machinery/door/window/southleft{ + req_access = list(47) + }, +/obj/machinery/atmospherics/pipe/simple/hidden, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "gogogo"; + name = "Blast Door"; + opacity = 0 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"ahe" = ( +/obj/machinery/door/firedoor, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "gogogo"; + name = "Blast Door"; + opacity = 0 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "ahf" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -4034,6 +4386,18 @@ "ahl" = ( /turf/simulated/wall, /area/hallway/lower/first_west) +"ahm" = ( +/obj/machinery/atmospherics/pipe/simple/visible/red{ + dir = 5; + icon_state = "intact" + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "ahn" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -4110,9 +4474,32 @@ /obj/structure/railing, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/surface_one_hall) +"ahv" = ( +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 1 + }, +/obj/machinery/atmospherics/portables_connector, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"ahw" = ( +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "ahx" = ( /turf/simulated/wall, /area/tether/surfacebase/emergency_storage/atrium) +"ahy" = ( +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "ahz" = ( /obj/structure/railing{ dir = 8 @@ -4161,6 +4548,13 @@ }, /turf/simulated/floor/plating, /area/storage/surface_eva) +"ahF" = ( +/obj/structure/table/steel_reinforced, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "ahG" = ( /obj/effect/floor_decal/borderfloor{ dir = 9 @@ -4405,6 +4799,13 @@ "ahX" = ( /turf/simulated/wall, /area/tether/surfacebase/north_stairs_one) +"ahY" = ( +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "ahZ" = ( /obj/structure/sign/directions/cargo{ dir = 4 @@ -4519,6 +4920,22 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_one_hall) +"aih" = ( +/obj/machinery/button/remote/blast_door{ + id = "gogogo"; + name = "Test Chamber Blast Seal Control"; + pixel_y = 32 + }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "aii" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -4545,6 +4962,42 @@ }, /turf/simulated/floor/tiled/white, /area/rnd/chemistry_lab) +"aik" = ( +/obj/structure/table/steel_reinforced, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 1 + }, +/obj/item/weapon/storage/toolbox/electrical, +/obj/item/weapon/storage/toolbox/mechanical, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"ail" = ( +/obj/structure/table/steel_reinforced, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 1 + }, +/obj/item/device/assembly/signaler, +/obj/item/device/assembly/prox_sensor, +/obj/item/device/assembly/signaler, +/obj/item/device/assembly/timer, +/obj/item/device/assembly/voice, +/obj/item/device/radio/electropack, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"aim" = ( +/obj/machinery/button/remote/blast_door{ + id = "suckysucky"; + name = "Scrubber Blast Door-Controller"; + pixel_x = 0; + pixel_y = 32 + }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "ain" = ( /obj/machinery/chem_master{ dir = 8 @@ -4561,6 +5014,13 @@ }, /turf/simulated/floor/tiled/white, /area/rnd/chemistry_lab) +"aio" = ( +/obj/machinery/camera/network/research{ + dir = 5; + icon_state = "camera" + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "aip" = ( /obj/structure/table/glass, /obj/item/weapon/storage/box/beakers, @@ -4577,6 +5037,17 @@ /obj/item/weapon/storage/fancy/vials, /turf/simulated/floor/tiled/white, /area/rnd/chemistry_lab) +"aiq" = ( +/obj/machinery/atmospherics/binary/pump{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "air" = ( /obj/structure/closet/firecloset, /turf/simulated/floor/plating, @@ -4593,6 +5064,49 @@ /obj/effect/floor_decal/industrial/outline/blue, /turf/simulated/floor/tiled/techfloor, /area/tether/surfacebase/emergency_storage/atrium) +"aiu" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"aiv" = ( +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"aiw" = ( +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 9; + icon_state = "intact" + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"aix" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/alarm{ + alarm_id = "pen_nine"; + breach_detection = 0; + dir = 1; + icon_state = "alarm0"; + pixel_y = -22 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "aiy" = ( /turf/simulated/wall, /area/storage/surface_eva/external) @@ -4611,6 +5125,17 @@ /obj/machinery/light/small, /turf/simulated/floor/plating, /area/storage/surface_eva) +"aiB" = ( +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"aiC" = ( +/obj/structure/catwalk, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) "aiD" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -4630,6 +5155,19 @@ /obj/machinery/hologram/holopad, /turf/simulated/floor/tiled, /area/hallway/lower/first_west) +"aiF" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"aiG" = ( +/obj/structure/table/steel_reinforced, +/obj/item/device/assembly/infra, +/obj/item/device/assembly/igniter, +/obj/item/device/assembly/igniter, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "aiH" = ( /obj/structure/bed/chair/office/light{ dir = 4 @@ -4736,18 +5274,20 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/tiled/monofloor, /area/tether/surfacebase/north_stairs_one) +"aiQ" = ( +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 1 + }, +/obj/machinery/computer/area_atmos/tag, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "aiR" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/obj/machinery/light_switch{ - pixel_y = 25 +/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary{ + name = "Research Testing Scrubber"; + use_power = 1 }, /turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) +/area/rnd/testingroom) "aiS" = ( /obj/machinery/alarm{ pixel_y = 22 @@ -4780,16 +5320,16 @@ /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) "aiU" = ( -/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/door/airlock/glass_research{ - name = "Xenoflora Research"; - req_access = list(55) - }, -/turf/simulated/floor/tiled/steel_grid, -/area/rnd/xenobiology/xenoflora) +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "aiV" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -4807,13 +5347,8 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/north_stairs_one) "aiW" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/glass_research{ - name = "Xenoflora Research"; - req_access = list(55) - }, -/turf/simulated/floor/tiled/steel_grid, -/area/rnd/xenobiology/xenoflora) +/turf/simulated/mineral, +/area/engineering/engine_room) "aiX" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on, /obj/structure/disposalpipe/segment{ @@ -4891,37 +5426,80 @@ dir = 1 }, /area/tether/surfacebase/surface_one_hall) +"ajb" = ( +/obj/machinery/door/airlock/maintenance/cargo{ + name = "Mining Maintenance Access"; + req_one_access = list(48) + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/cargo/mining) "ajc" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/cyan{ + dir = 4 + }, /obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/visible/supply{ + dir = 8 + }, +/obj/machinery/door/airlock/maintenance/common{ + req_one_access = newlist() + }, +/turf/simulated/floor/plating, +/area/maintenance/lower/mining_eva) +"ajd" = ( /obj/structure/cable/green{ d1 = 1; - d2 = 2; - icon_state = "1-2" + d2 = 8; + icon_state = "1-8" }, -/obj/machinery/door/airlock/glass_research{ - name = "Xenoflora Research"; - req_access = list(55) +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" }, -/turf/simulated/floor/tiled/steel_grid, -/area/rnd/xenobiology/xenoflora) -"ajd" = ( +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 9 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) +"aje" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 }, /obj/effect/floor_decal/corner/mauve/border{ dir = 1 }, -/obj/item/device/radio/intercom{ - dir = 1; - pixel_y = 24; - req_access = list() +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/structure/table/glass, -/obj/machinery/chemical_dispenser/xenoflora/full, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/structure/disposalpipe/junction{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, /turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) +/area/rnd/hallway) "ajf" = ( /obj/structure/cable/cyan{ d1 = 1; @@ -4955,6 +5533,13 @@ }, /turf/simulated/floor/tiled/steel_dirty/virgo3b, /area/engineering/atmos_intake) +"aji" = ( +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" + }, +/turf/simulated/floor/reinforced, +/area/rnd/testingroom) "ajj" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -4976,6 +5561,19 @@ }, /turf/simulated/floor/tiled, /area/engineering/atmos) +"ajl" = ( +/turf/simulated/wall/r_wall, +/area/crew_quarters/sleep/Dorm_7) +"ajm" = ( +/obj/machinery/vending/tool{ + dir = 1; + icon_state = "tool" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "ajn" = ( /obj/machinery/atmospherics/pipe/simple/visible/green{ dir = 4 @@ -5242,15 +5840,24 @@ /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) "ajJ" = ( -/obj/machinery/atmospherics/portables_connector{ +/obj/effect/floor_decal/borderfloor{ dir = 1 }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/obj/machinery/light, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, /obj/structure/disposalpipe/segment, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, /turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) +/area/rnd/hallway) "ajK" = ( /mob/living/simple_mob/animal/passive/gaslamp, /turf/simulated/floor/outdoors/grass/sif/virgo3b, @@ -5349,6 +5956,46 @@ }, /turf/simulated/floor/plating, /area/holodeck_control) +"ajW" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/machinery/camera/network/research, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) +"ajX" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/obj/machinery/light_switch{ + pixel_y = 25 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) "ajY" = ( /turf/simulated/floor/plating, /area/tether/surfacebase/public_garden_one) @@ -5359,10 +6006,118 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/public_garden_maintenence) +"aka" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/obj/machinery/newscaster{ + pixel_x = 0; + pixel_y = 30 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) "akb" = ( /obj/structure/grille, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/public_garden_one) +"akc" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) +"akd" = ( +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) +"ake" = ( +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 10 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) +"akf" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) +"akg" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) "akh" = ( /obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary{ scrub_id = "atrium" @@ -5375,6 +6130,28 @@ }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/public_garden_maintenence) +"akj" = ( +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" + }, +/obj/structure/closet/hydrant{ + pixel_x = -32 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/hallway) "akk" = ( /obj/structure/grille, /obj/structure/railing, @@ -5403,6 +6180,15 @@ /obj/random/drinkbottle, /turf/simulated/floor/plating, /area/maintenance/lower/public_garden_maintenence) +"akp" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "akq" = ( /obj/effect/floor_decal/techfloor{ dir = 9 @@ -5717,6 +6503,11 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_one) +"alb" = ( +/obj/structure/catwalk, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) "alc" = ( /obj/machinery/door/firedoor/glass, /obj/effect/floor_decal/steeldecal/steel_decals_central1{ @@ -6021,6 +6812,28 @@ }, /turf/simulated/floor/tiled/techfloor, /area/tether/surfacebase/public_garden) +"alt" = ( +/obj/structure/railing{ + dir = 8 + }, +/obj/structure/railing{ + dir = 1 + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) +"alu" = ( +/obj/structure/railing{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) +"alv" = ( +/obj/structure/railing{ + dir = 8 + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) "alw" = ( /obj/effect/floor_decal/borderfloor{ dir = 10 @@ -6116,6 +6929,135 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden) +"alC" = ( +/obj/structure/catwalk, +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) +"alD" = ( +/obj/structure/catwalk, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) +"alE" = ( +/obj/structure/catwalk, +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) +"alF" = ( +/obj/structure/catwalk, +/obj/structure/cable{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/obj/structure/cable{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/obj/machinery/atmospherics/pipe/simple/visible/supply{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ + dir = 6 + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) +"alG" = ( +/obj/structure/catwalk, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, +/obj/machinery/atmospherics/pipe/simple/visible/supply, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) +"alH" = ( +/obj/structure/catwalk, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/visible/supply, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) +"alI" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) +"alJ" = ( +/obj/structure/catwalk, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/visible/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) +"alK" = ( +/obj/structure/catwalk, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/junction, +/obj/random/junk, +/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/visible/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/techfloor, +/area/maintenance/lower/xenoflora) +"alL" = ( +/obj/structure/table/steel_reinforced, +/obj/item/device/radio, +/obj/item/device/radio, +/turf/simulated/floor/tiled, +/area/rnd/testingroom) "alM" = ( /obj/effect/floor_decal/borderfloor{ dir = 10 @@ -6198,6 +7140,54 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden) +"alS" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/turf/simulated/floor/plating, +/area/rnd/testingroom) +"alT" = ( +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/door/airlock/research{ + id_tag = "researchdoor"; + name = "Testing Room"; + req_access = list(47) + }, +/turf/simulated/floor/tiled/steel_grid, +/area/rnd/testingroom) +"alU" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plating, +/area/rnd/testingroom) +"alV" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/door/airlock/research{ + name = "Toxins Storage"; + req_access = list(8) + }, +/turf/simulated/floor/tiled/steel_grid, +/area/rnd/tankstorage) +"alW" = ( +/obj/structure/sign/warning/caution, +/turf/simulated/wall/r_wall, +/area/rnd/tankstorage) "alX" = ( /obj/structure/railing{ dir = 8 @@ -6219,9 +7209,64 @@ /obj/random/junk, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining_eva) +"alY" = ( +/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary{ + scrub_id = "rnd_can_store" + }, +/turf/simulated/floor/tiled/techmaint, +/area/rnd/tankstorage) +"alZ" = ( +/obj/structure/grille, +/obj/structure/railing{ + dir = 4 + }, +/turf/simulated/floor/tiled/techmaint, +/area/rnd/tankstorage) +"ama" = ( +/obj/effect/floor_decal/industrial/warning{ + dir = 8; + icon_state = "warning" + }, +/obj/machinery/computer/area_atmos/tag{ + dir = 4; + scrub_id = "rnd_can_store" + }, +/obj/machinery/camera/network/research, +/turf/simulated/floor/tiled, +/area/rnd/tankstorage) +"amb" = ( +/obj/machinery/light/small{ + dir = 4; + pixel_y = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/tankstorage) "amc" = ( /turf/simulated/wall, /area/tether/surfacebase/cargo/office) +"amd" = ( +/obj/structure/sign/warning/nosmoking_2, +/turf/simulated/wall/r_wall, +/area/rnd/tankstorage) "ame" = ( /obj/effect/floor_decal/techfloor{ dir = 10 @@ -6318,6 +7363,28 @@ }, /turf/simulated/floor/tiled, /area/storage/primary) +"amn" = ( +/obj/effect/floor_decal/rust, +/obj/machinery/portable_atmospherics/canister/phoron, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amo" = ( +/obj/effect/floor_decal/rust, +/obj/machinery/portable_atmospherics/canister/phoron, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amp" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/obj/machinery/light_switch{ + pixel_y = 25 + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) "amq" = ( /obj/structure/railing{ dir = 8 @@ -6330,10 +7397,92 @@ }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining_eva) +"amr" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 4 + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"ams" = ( +/obj/effect/floor_decal/industrial/warning/dust/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amt" = ( +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 1 + }, +/obj/effect/landmark{ + name = "morphspawn" + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amu" = ( +/obj/effect/floor_decal/rust, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 1 + }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amv" = ( +/obj/effect/floor_decal/industrial/warning/dust, +/obj/machinery/power/apc{ + cell_type = /obj/item/weapon/cell/super; + dir = 8; + name = "west bump"; + pixel_x = -30 + }, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) "amw" = ( /obj/structure/sign/department/cargo, /turf/simulated/wall, /area/tether/surfacebase/cargo/office) +"amx" = ( +/obj/effect/floor_decal/industrial/warning/dust, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amy" = ( +/obj/effect/floor_decal/industrial/warning/dust/corner{ + dir = 8 + }, +/obj/effect/floor_decal/industrial/warning/dust/corner, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amz" = ( +/obj/effect/floor_decal/industrial/warning/dust, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) "amA" = ( /obj/effect/floor_decal/techfloor{ dir = 10 @@ -6433,6 +7582,35 @@ }, /turf/simulated/floor/tiled, /area/storage/primary) +"amI" = ( +/obj/effect/floor_decal/industrial/warning/dust, +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amJ" = ( +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/obj/machinery/camera/network/research{ + dir = 4 + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amK" = ( +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amL" = ( +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 4 + }, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 8 + }, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) "amM" = ( /obj/structure/railing{ dir = 8 @@ -6444,6 +7622,14 @@ }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining_eva) +"amN" = ( +/obj/machinery/portable_atmospherics/canister/sleeping_agent, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) +"amO" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) "amP" = ( /obj/machinery/camera/network/cargo, /turf/simulated/floor/tiled, @@ -6456,6 +7642,10 @@ /obj/random/junk, /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) +"amR" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) "amS" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -6522,6 +7712,16 @@ }, /turf/simulated/floor/tiled, /area/storage/primary) +"amW" = ( +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 4 + }, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 8 + }, +/obj/machinery/light/small, +/turf/simulated/floor/tiled/steel_dirty, +/area/rnd/tankstorage) "amX" = ( /obj/machinery/power/apc{ cell_type = /obj/item/weapon/cell/super; @@ -6635,6 +7835,19 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) +"and" = ( +/obj/structure/grille, +/obj/structure/railing{ + dir = 1 + }, +/turf/simulated/floor/tiled/techmaint, +/area/rnd/tankstorage) +"ane" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/reinforced, +/area/rnd/testingroom) "anf" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/floor_decal/rust, @@ -6764,6 +7977,15 @@ }, /turf/simulated/floor/tiled, /area/storage/primary) +"anm" = ( +/turf/simulated/wall/r_wall, +/area/crew_quarters/sleep/Dorm_5) +"ann" = ( +/turf/simulated/wall/r_wall, +/area/crew_quarters/sleep/Dorm_3) +"ano" = ( +/turf/simulated/wall/r_wall, +/area/tether/surfacebase/outside/outside1) "anp" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -6955,13 +8177,55 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_one_hall) +"anE" = ( +/turf/simulated/wall/r_wall, +/area/crew_quarters/sleep/Dorm_1) "anF" = ( /obj/machinery/door/airlock/maintenance/cargo{ name = "Mining Maintenance Access"; - req_one_access = list(48) + req_one_access = list(48,50) }, /turf/simulated/floor/plating, /area/tether/surfacebase/cargo/office) +"anG" = ( +/obj/machinery/door/airlock/maintenance/rnd{ + req_one_access = list(47,24) + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/rnd/hallway) +"anH" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 10 + }, +/obj/effect/floor_decal/corner/red/border{ + dir = 10 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 8 + }, +/obj/effect/floor_decal/corner/red/bordercorner2{ + dir = 8 + }, +/obj/item/device/radio/intercom{ + dir = 8; + pixel_x = -24 + }, +/obj/structure/bed/chair/office/dark, +/obj/structure/barricade/cutout/ntsec, +/turf/simulated/floor/tiled, +/area/security/checkpoint) "anI" = ( /obj/structure/cable{ d2 = 2; @@ -6985,6 +8249,12 @@ }, /turf/simulated/floor/tiled/techfloor, /area/tether/surfacebase/emergency_storage/atrium) +"anK" = ( +/obj/structure/symbol/lo, +/turf/simulated/wall{ + can_open = 1 + }, +/area/maintenance/lower/atmos) "anL" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/floor_decal/industrial/outline/blue, @@ -7339,6 +8609,16 @@ /obj/random/maintenance/cargo, /turf/simulated/floor/tiled/techfloor, /area/tether/surfacebase/emergency_storage/atrium) +"aop" = ( +/obj/effect/decal/cleanable/dirt, +/obj/random/action_figure, +/obj/random/action_figure, +/obj/random/action_figure, +/obj/structure/closet/wardrobe/grey{ + starts_with = list(/obj/structure/barricade/cutout/viva, /obj/item/clothing/under/color/grey = 3, /obj/item/clothing/shoes/black = 3, /obj/item/clothing/head/soft/grey = 3, /obj/item/clothing/mask/gas/wwii = 3, /obj/item/weapon/storage/toolbox/mechanical = 3, /obj/item/clothing/gloves/fyellow = 3, /obj/item/weapon/card/id/gold/captain/spare/fakespare = 3, /obj/item/weapon/soap/syndie = 3, /obj/item/weapon/storage/box/mousetraps = 3) + }, +/turf/simulated/floor/plating, +/area/maintenance/lower/atmos) "aoq" = ( /turf/simulated/floor/tiled/steel_dirty/virgo3b, /area/tether/surfacebase/outside/outside1) @@ -10079,16 +11359,6 @@ /obj/item/weapon/pickaxe, /turf/simulated/floor/plating, /area/vacant/vacant_site) -"atd" = ( -/obj/structure/railing{ - dir = 8 - }, -/obj/structure/railing{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/visible/universal, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "ate" = ( /obj/structure/railing{ dir = 1 @@ -10376,16 +11646,6 @@ "atH" = ( /turf/simulated/wall, /area/maintenance/substation/civ_west) -"atJ" = ( -/obj/structure/railing{ - dir = 8 - }, -/obj/machinery/atmospherics/binary/passive_gate{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "atK" = ( /obj/machinery/light/small{ dir = 4; @@ -10664,22 +11924,6 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) -"auq" = ( -/obj/structure/railing{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/manifold/visible/yellow, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) -"aur" = ( -/obj/machinery/atmospherics/pipe/tank/phoron{ - dir = 8; - icon_state = "phoron_map"; - name = "Xenoflora Waste Buffer"; - start_pressure = 0 - }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "aus" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -11703,9 +12947,6 @@ /obj/structure/catwalk, /turf/simulated/floor/plating, /area/maintenance/lower/solars) -"avQ" = ( -/turf/simulated/wall, -/area/rnd/xenobiology/xenoflora/lab_atmos) "avT" = ( /turf/simulated/wall/r_wall, /area/maintenance/lower/xenoflora) @@ -11767,26 +13008,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_one_hall) -"avY" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/obj/effect/floor_decal/corner/red/border{ - dir = 10 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 8 - }, -/obj/effect/floor_decal/corner/red/bordercorner2{ - dir = 8 - }, -/obj/item/device/radio/intercom{ - dir = 8; - pixel_x = -24 - }, -/obj/structure/bed/chair/office/dark, -/turf/simulated/floor/tiled, -/area/security/checkpoint) "avZ" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/red/border, @@ -12019,97 +13240,6 @@ /obj/structure/catwalk, /turf/simulated/floor/plating, /area/maintenance/lower/solars) -"awu" = ( -/obj/machinery/atmospherics/unary/freezer{ - dir = 2; - icon_state = "freezer" - }, -/obj/effect/floor_decal/corner/green{ - dir = 10 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 9 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"awv" = ( -/obj/machinery/atmospherics/unary/heater{ - dir = 2; - icon_state = "heater" - }, -/obj/effect/floor_decal/corner/green{ - dir = 10 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"aww" = ( -/obj/machinery/atmospherics/portables_connector, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 1 - }, -/obj/machinery/camera/network/research, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"awx" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 1 - }, -/obj/machinery/alarm{ - pixel_y = 22 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"awy" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/machinery/atmospherics/portables_connector, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"awz" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/machinery/atmospherics/portables_connector, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 1 - }, -/obj/machinery/light{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"awA" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/machinery/atmospherics/portables_connector, -/obj/effect/floor_decal/borderfloor{ - dir = 5 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) "awD" = ( /obj/machinery/atmospherics/pipe/zpipe/up/scrubbers, /obj/machinery/atmospherics/pipe/zpipe/up/supply, @@ -12304,51 +13434,6 @@ /obj/structure/catwalk, /turf/simulated/floor/plating, /area/maintenance/lower/solars) -"awV" = ( -/turf/simulated/wall, -/area/rnd/xenobiology/xenoflora) -"awW" = ( -/obj/machinery/atmospherics/pipe/simple/visible{ - dir = 5 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"awX" = ( -/obj/machinery/atmospherics/pipe/manifold/visible, -/obj/machinery/meter, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"awY" = ( -/obj/machinery/atmospherics/pipe/simple/visible{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"awZ" = ( -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"axa" = ( -/obj/machinery/atmospherics/pipe/simple/visible, -/obj/machinery/meter, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"axb" = ( -/obj/machinery/atmospherics/pipe/simple/visible, -/obj/machinery/meter, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) "axe" = ( /obj/machinery/door/airlock/maintenance/engi{ name = "Elevator Maintenance" @@ -12694,132 +13779,6 @@ /obj/structure/catwalk, /turf/simulated/floor/plating, /area/maintenance/lower/solars) -"axF" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 9 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 9 - }, -/obj/machinery/camera/network/research{ - dir = 4 - }, -/obj/structure/closet/secure_closet/hydroponics/sci, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"axG" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/obj/machinery/power/apc{ - dir = 1; - name = "north bump"; - pixel_x = 0; - pixel_y = 28 - }, -/obj/structure/cable/green{ - d2 = 2; - icon_state = "0-2" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"axH" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/obj/machinery/firealarm{ - dir = 2; - layer = 3.3; - pixel_x = 0; - pixel_y = 26 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"axI" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 5 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 5 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 5 - }, -/obj/structure/closet/crate/hydroponics/prespawned, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"axJ" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/turf/simulated/floor/plating, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"axK" = ( -/obj/structure/window/reinforced, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"axL" = ( -/obj/structure/window/reinforced, -/obj/machinery/atmospherics/unary/vent_scrubber/on, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"axM" = ( -/obj/structure/window/reinforced, -/obj/machinery/atmospherics/unary/vent_pump/on, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"axN" = ( -/obj/machinery/door/window/brigdoor/southright{ - req_access = list(55); - req_one_access = list(47) - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"axO" = ( -/obj/structure/window/reinforced, -/obj/machinery/atmospherics/portables_connector{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"axP" = ( -/obj/structure/window/reinforced, -/obj/machinery/atmospherics/portables_connector{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/industrial/danger{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 - }, -/obj/machinery/status_display{ - pixel_x = 32; - pixel_y = 0 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) "axS" = ( /turf/simulated/floor/plating, /area/maintenance/lower/xenoflora) @@ -13062,220 +14021,6 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/rnd/hallway) -"ayt" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/structure/closet/secure_closet/hydroponics/sci, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"ayu" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"ayv" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"ayw" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/effect/floor_decal/steeldecal/steel_decals4, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"ayx" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/airlock/glass_research{ - name = "Xenoflora Research"; - req_access = list(55) - }, -/turf/simulated/floor/tiled/steel_grid, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"ayy" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"ayz" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/yellow, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"ayA" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"ayB" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/hologram/holopad, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"ayC" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"ayD" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"ayE" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 - }, -/obj/machinery/power/apc{ - dir = 4; - name = "east bump"; - pixel_x = 28 - }, -/obj/structure/cable/green{ - icon_state = "0-8" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) "ayG" = ( /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_one_hall) @@ -13636,215 +14381,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"azu" = ( -/obj/structure/table/glass, -/obj/effect/floor_decal/borderfloor{ - dir = 9 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 9 - }, -/obj/machinery/reagentgrinder, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"azv" = ( -/obj/structure/table/glass, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/obj/machinery/camera/network/research, -/obj/item/weapon/storage/box/beakers{ - pixel_x = 2; - pixel_y = 2 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"azw" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/obj/machinery/alarm{ - pixel_y = 22 - }, -/obj/machinery/chem_master, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"azx" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/item/weapon/reagent_containers/glass/bucket, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/obj/machinery/status_display{ - pixel_y = 30 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"azy" = ( -/obj/machinery/smartfridge/drying_rack, -/obj/machinery/light{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"azz" = ( -/obj/effect/floor_decal/borderfloor/corner{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"azA" = ( -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"azB" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow, -/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, -/area/rnd/xenobiology/xenoflora) -"azC" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 6 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"azD" = ( -/obj/machinery/atmospherics/pipe/simple/visible{ - dir = 6; - icon_state = "intact" - }, -/obj/machinery/meter, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"azE" = ( -/obj/machinery/atmospherics/binary/pump{ - dir = 4; - name = "Port to Isolation" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"azF" = ( -/obj/machinery/atmospherics/pipe/simple/visible{ - dir = 4 - }, -/obj/machinery/meter, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"azG" = ( -/obj/machinery/atmospherics/pipe/manifold/visible{ - dir = 1 - }, -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"azH" = ( -/obj/machinery/atmospherics/pipe/manifold/visible{ - dir = 1 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"azI" = ( -/obj/machinery/atmospherics/binary/pump{ - dir = 4; - name = "Isolation to Waste" - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"azJ" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"azK" = ( -/obj/machinery/door/airlock/maintenance/rnd{ - name = "Xenoflora Maintenance Access"; - req_access = list(55) - }, -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora/lab_atmos) "azL" = ( /obj/machinery/door/firedoor/glass/hidden/steel{ dir = 1 @@ -14051,138 +14587,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aAz" = ( -/obj/structure/table/glass, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/item/weapon/storage/box/gloves{ - pixel_x = 4; - pixel_y = 4 - }, -/obj/item/weapon/storage/box/syringes, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aAA" = ( -/obj/structure/bed/chair/office/light{ - dir = 1 - }, -/obj/effect/landmark/start{ - name = "Xenobiologist" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aAB" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aAC" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aAD" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 4 - }, -/obj/effect/landmark/start{ - name = "Xenobiologist" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aAE" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{ - dir = 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, -/area/rnd/xenobiology/xenoflora) -"aAF" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aAG" = ( -/obj/machinery/atmospherics/portables_connector{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 10 - }, -/obj/item/device/radio/intercom{ - dir = 2; - pixel_y = -24 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"aAH" = ( -/obj/machinery/portable_atmospherics/canister/nitrogen, -/obj/effect/floor_decal/industrial/warning{ - dir = 9 - }, -/turf/simulated/floor/tiled/white, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"aAI" = ( -/obj/machinery/portable_atmospherics/canister/carbon_dioxide, -/obj/effect/floor_decal/industrial/warning{ - dir = 5 - }, -/turf/simulated/floor/tiled/white, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"aAJ" = ( -/obj/machinery/atmospherics/portables_connector{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"aAK" = ( -/obj/machinery/atmospherics/portables_connector{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/obj/machinery/camera/network/research{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) -"aAL" = ( -/obj/structure/table/glass, -/obj/effect/floor_decal/borderfloor{ - dir = 6 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 6 - }, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 1 - }, -/obj/machinery/light_switch{ - pixel_x = 25 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora/lab_atmos) "aAM" = ( /obj/structure/closet/crate, /obj/random/maintenance/engineering, @@ -14269,124 +14673,6 @@ /obj/machinery/door/firedoor/glass/hidden/steel, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aBx" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 8 - }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/tiled, -/area/rnd/hallway) -"aBy" = ( -/obj/machinery/light{ - dir = 8; - icon_state = "tube1" - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 10 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 10 - }, -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aBz" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aBA" = ( -/obj/effect/floor_decal/corner/green/full{ - dir = 8 - }, -/turf/simulated/floor/tiled/dark, -/area/rnd/xenobiology/xenoflora) -"aBB" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/effect/floor_decal/corner/green{ - dir = 5 - }, -/turf/simulated/floor/tiled/dark, -/area/rnd/xenobiology/xenoflora) -"aBC" = ( -/obj/effect/floor_decal/corner/green/full{ - dir = 1 - }, -/turf/simulated/floor/tiled/dark, -/area/rnd/xenobiology/xenoflora) -"aBD" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aBE" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aBF" = ( -/obj/machinery/biogenerator, -/obj/machinery/light{ - dir = 4; - icon_state = "tube1" - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aBG" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating, -/area/rnd/xenobiology/xenoflora/lab_atmos) "aBH" = ( /obj/effect/decal/cleanable/dirt, /obj/random/junk, @@ -14607,64 +14893,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aCg" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/junction{ - dir = 2; - icon_state = "pipe-j2" - }, -/turf/simulated/floor/tiled, -/area/rnd/hallway) -"aCh" = ( -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 6 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aCi" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/effect/floor_decal/corner/green{ - dir = 9 - }, -/turf/simulated/floor/tiled/dark, -/area/rnd/xenobiology/xenoflora) -"aCj" = ( -/turf/simulated/floor/grass, -/area/rnd/xenobiology/xenoflora) -"aCk" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/effect/floor_decal/corner/green{ - dir = 6 - }, -/turf/simulated/floor/tiled/dark, -/area/rnd/xenobiology/xenoflora) -"aCl" = ( -/obj/machinery/seed_extractor, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) "aCm" = ( /obj/effect/floor_decal/borderfloor{ dir = 9 @@ -14707,54 +14935,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aCp" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/obj/machinery/camera/network/research, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/tiled, -/area/rnd/hallway) -"aCq" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/obj/machinery/light_switch{ - pixel_y = 25 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/turf/simulated/floor/tiled, -/area/rnd/hallway) -"aCr" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 1 - }, -/obj/machinery/newscaster{ - pixel_x = 0; - pixel_y = 30 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/turf/simulated/floor/tiled, -/area/rnd/hallway) "aCs" = ( /obj/effect/floor_decal/borderfloor{ dir = 5 @@ -15062,111 +15242,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aCW" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 6 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 6 - }, -/obj/structure/disposalpipe/segment, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/structure/cable/green{ - 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, -/area/rnd/hallway) -"aCX" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/turf/simulated/floor/plating, -/area/rnd/xenobiology/xenoflora) -"aCY" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 8 - }, -/obj/structure/sink{ - dir = 8; - icon_state = "sink"; - pixel_x = -12; - pixel_y = 2 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aCZ" = ( -/obj/machinery/hologram/holopad, -/turf/simulated/floor/grass, -/area/rnd/xenobiology/xenoflora) -"aDa" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 5 - }, -/obj/machinery/requests_console{ - department = "Science"; - departmentType = 2; - name = "Science Requests Console"; - pixel_x = 30; - pixel_y = 0 - }, -/obj/item/weapon/storage/box/botanydisk, -/obj/structure/table/glass, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aDb" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 10 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/rnd/hallway) "aDc" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 @@ -15368,71 +15443,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aDA" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aDB" = ( -/obj/machinery/atmospherics/unary/vent_pump/on, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aDC" = ( -/obj/effect/floor_decal/corner/green/full, -/turf/simulated/floor/tiled/dark, -/area/rnd/xenobiology/xenoflora) -"aDD" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/effect/floor_decal/corner/green{ - dir = 10 - }, -/turf/simulated/floor/tiled/dark, -/area/rnd/xenobiology/xenoflora) -"aDE" = ( -/obj/effect/floor_decal/corner/green/full{ - dir = 4 - }, -/turf/simulated/floor/tiled/dark, -/area/rnd/xenobiology/xenoflora) -"aDF" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aDG" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ - dir = 9 - }, -/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, -/area/rnd/xenobiology/xenoflora) -"aDH" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aDI" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/rnd/hallway) "aDJ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/tiled, @@ -15461,12 +15471,6 @@ /obj/structure/stairs/north, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aDM" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/rnd/hallway) "aDN" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -15625,104 +15629,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aEf" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEg" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEh" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEi" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEj" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEk" = ( -/obj/machinery/botany/editor, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 6 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEl" = ( -/obj/machinery/light{ - dir = 8; - icon_state = "tube1" - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 8 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 8 - }, -/obj/structure/closet/hydrant{ - pixel_x = -32 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/rnd/hallway) "aEm" = ( /obj/machinery/hologram/holopad, /turf/simulated/floor/tiled, @@ -15747,17 +15653,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals9, /turf/simulated/floor/tiled/monotile, /area/rnd/hallway) -"aEo" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/turf/simulated/floor/tiled, -/area/rnd/hallway) "aEp" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -16031,109 +15926,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aEU" = ( -/obj/machinery/seed_storage/xenobotany{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 10 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEV" = ( -/obj/machinery/vending/hydronutrients{ - categories = 3; - dir = 1 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEW" = ( -/obj/machinery/smartfridge, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEX" = ( -/obj/structure/table/glass, -/obj/item/weapon/tape_roll, -/obj/item/device/analyzer/plant_analyzer, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEY" = ( -/obj/structure/table/glass, -/obj/item/weapon/clipboard, -/obj/item/weapon/folder/white, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aEZ" = ( -/obj/structure/table/glass, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 9 - }, -/obj/effect/floor_decal/corner/mauve/bordercorner2{ - dir = 9 - }, -/obj/machinery/light, -/obj/item/weapon/paper_bin{ - pixel_x = 1; - pixel_y = 9 - }, -/obj/item/weapon/pen, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aFa" = ( -/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" - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aFb" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/obj/effect/floor_decal/borderfloor/corner2, -/obj/effect/floor_decal/corner/mauve/bordercorner2, -/obj/machinery/newscaster{ - pixel_x = 0; - pixel_y = -30 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aFc" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/mauve/border, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) -"aFd" = ( -/obj/machinery/botany/extractor, -/obj/effect/floor_decal/borderfloor{ - dir = 6 - }, -/obj/effect/floor_decal/corner/mauve/border{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora) "aFe" = ( /obj/effect/floor_decal/steeldecal/steel_decals5{ dir = 1 @@ -17092,28 +16884,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aHq" = ( -/turf/simulated/wall/r_wall, -/area/rnd/xenobiology/xenoflora_storage) -"aHr" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/door/airlock/research{ - name = "Toxins Storage"; - req_access = list(8) - }, -/turf/simulated/floor/tiled/steel_grid, -/area/rnd/xenobiology/xenoflora_storage) -"aHs" = ( -/obj/structure/sign/warning/caution, -/turf/simulated/wall/r_wall, -/area/rnd/xenobiology/xenoflora_storage) "aHt" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ @@ -17304,62 +17074,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) -"aHQ" = ( -/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary{ - scrub_id = "rnd_can_store" - }, -/turf/simulated/floor/tiled/techmaint, -/area/rnd/xenobiology/xenoflora_storage) -"aHR" = ( -/obj/structure/grille, -/obj/structure/railing{ - dir = 4 - }, -/turf/simulated/floor/tiled/techmaint, -/area/rnd/xenobiology/xenoflora_storage) -"aHS" = ( -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/rnd/xenobiology/xenoflora_storage) -"aHT" = ( -/obj/structure/sign/warning/nosmoking_2, -/turf/simulated/wall/r_wall, -/area/rnd/xenobiology/xenoflora_storage) -"aHU" = ( -/obj/effect/floor_decal/rust, -/obj/machinery/portable_atmospherics/canister/phoron, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aHV" = ( -/obj/effect/floor_decal/rust, -/obj/machinery/portable_atmospherics/canister/phoron, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) "aHW" = ( /obj/structure/cable/green{ d1 = 1; @@ -18126,22 +17840,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /turf/simulated/floor/tiled, /area/rnd/hallway) -"aJt" = ( -/obj/machinery/door/airlock/maintenance/rnd, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/plating, -/area/rnd/hallway) "aJu" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable/green{ @@ -18196,64 +17894,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/asmaint2) -"aJy" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/obj/machinery/light_switch{ - pixel_y = 25 - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aJz" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9 - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aJA" = ( -/obj/effect/floor_decal/industrial/warning/dust/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aJB" = ( -/obj/effect/floor_decal/industrial/warning/dust{ - dir = 1 - }, -/obj/effect/landmark{ - name = "morphspawn" - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aJC" = ( -/obj/effect/floor_decal/rust, -/obj/effect/floor_decal/industrial/warning/dust{ - dir = 1 - }, -/obj/machinery/firealarm{ - dir = 4; - pixel_x = 24 - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) "aJD" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -18464,48 +18104,6 @@ "aKa" = ( /turf/simulated/wall, /area/maintenance/asmaint2) -"aKb" = ( -/obj/effect/floor_decal/industrial/warning/dust, -/obj/machinery/power/apc{ - cell_type = /obj/item/weapon/cell/super; - dir = 8; - name = "west bump"; - pixel_x = -30 - }, -/obj/structure/cable/green{ - icon_state = "0-4" - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aKc" = ( -/obj/effect/floor_decal/industrial/warning/dust, -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aKd" = ( -/obj/effect/floor_decal/industrial/warning/dust/corner{ - dir = 8 - }, -/obj/effect/floor_decal/industrial/warning/dust/corner, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aKe" = ( -/obj/effect/floor_decal/industrial/warning/dust, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aKf" = ( -/obj/effect/floor_decal/industrial/warning/dust, -/obj/machinery/alarm{ - dir = 8; - icon_state = "alarm0"; - pixel_x = 24 - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) "aKg" = ( /obj/machinery/alarm{ dir = 4; @@ -18859,30 +18457,6 @@ /obj/effect/map_helper/airlock/door/int_door, /turf/simulated/floor/tiled/steel_grid, /area/rnd/external) -"aKO" = ( -/obj/machinery/portable_atmospherics/canister/carbon_dioxide, -/obj/machinery/camera/network/research{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aKP" = ( -/obj/machinery/portable_atmospherics/canister/carbon_dioxide, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aKQ" = ( -/obj/effect/floor_decal/industrial/warning/dust{ - dir = 4 - }, -/obj/effect/floor_decal/industrial/warning/dust{ - dir = 8 - }, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aKR" = ( -/obj/machinery/portable_atmospherics/canister/sleeping_agent, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) "aKS" = ( /obj/random/junk, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -19154,14 +18728,6 @@ }, /turf/simulated/floor/tiled/techmaint, /area/rnd/external) -"aLt" = ( -/obj/machinery/portable_atmospherics/canister/oxygen, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) -"aLu" = ( -/obj/machinery/portable_atmospherics/canister/nitrogen, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) "aLv" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -19519,16 +19085,6 @@ }, /turf/simulated/floor/tiled/techmaint, /area/rnd/external) -"aMe" = ( -/obj/effect/floor_decal/industrial/warning/dust{ - dir = 4 - }, -/obj/effect/floor_decal/industrial/warning/dust{ - dir = 8 - }, -/obj/machinery/light/small, -/turf/simulated/floor/tiled/steel_dirty, -/area/rnd/xenobiology/xenoflora_storage) "aMf" = ( /obj/effect/floor_decal/rust, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -19851,13 +19407,6 @@ /obj/effect/map_helper/airlock/door/ext_door, /turf/simulated/floor/tiled/steel_grid, /area/rnd/external) -"aML" = ( -/obj/structure/grille, -/obj/structure/railing{ - dir = 1 - }, -/turf/simulated/floor/tiled/techmaint, -/area/rnd/xenobiology/xenoflora_storage) "aMM" = ( /obj/effect/floor_decal/rust, /obj/structure/closet, @@ -25893,13 +25442,6 @@ /obj/effect/floor_decal/rust, /turf/simulated/floor/tiled/steel_dirty, /area/maintenance/lower/atmos) -"aXQ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/random/action_figure, -/obj/random/action_figure, -/obj/random/action_figure, -/turf/simulated/floor/plating, -/area/maintenance/lower/atmos) "aXR" = ( /obj/structure/window/reinforced, /obj/structure/closet/masks, @@ -27650,17 +27192,6 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/plating, /area/maintenance/lower/xenoflora) -"bbZ" = ( -/obj/structure/catwalk, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ - dir = 10 - }, -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "bcd" = ( /turf/simulated/mineral, /area/maintenance/lower/xenoflora) @@ -28658,30 +28189,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"cgN" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/turf/simulated/floor/tiled, -/area/rnd/hallway) "cpp" = ( /obj/machinery/door/firedoor/glass, /obj/structure/disposalpipe/segment{ @@ -28754,17 +28261,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_one_hall) -"crC" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/cyan{ - dir = 4 - }, -/obj/machinery/door/airlock/maintenance/common, -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/visible/supply{ - dir = 8 - }, -/turf/simulated/floor/plating, -/area/maintenance/lower/mining_eva) "csb" = ( /obj/structure/railing{ dir = 4 @@ -28923,24 +28419,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/cargo/mining) -"dZo" = ( -/obj/structure/catwalk, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/disposalpipe/junction, -/obj/random/junk, -/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/visible/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/visible/yellow{ - dir = 9 - }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "dZW" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 4 @@ -29143,13 +28621,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) -"fFf" = ( -/obj/structure/catwalk, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/visible/yellow, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "fGP" = ( /obj/structure/railing{ dir = 4 @@ -29160,34 +28631,10 @@ }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/xenoflora) -"fXu" = ( -/obj/structure/catwalk, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/visible/yellow{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "fYi" = ( /obj/random/cutout, /turf/simulated/floor/plating, /area/construction/vacant_mining_ops) -"fZA" = ( -/obj/structure/catwalk, -/obj/structure/cable{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, -/obj/machinery/atmospherics/pipe/simple/visible/yellow, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "gaK" = ( /obj/machinery/door/airlock/glass{ name = "Looking Glass" @@ -29556,18 +29003,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/locker/laundry_arrival) -"iHP" = ( -/obj/structure/catwalk, -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/visible/yellow, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "jkt" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/mauve/border, @@ -30282,19 +29717,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/locker/laundry_arrival) -"nrX" = ( -/obj/structure/catwalk, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/visible/yellow, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/visible/supply, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "nsp" = ( /obj/structure/cable/green{ d1 = 2; @@ -30359,17 +29781,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"ogk" = ( -/obj/structure/catwalk, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/visible/yellow, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, -/obj/machinery/atmospherics/pipe/simple/visible/supply, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "ohi" = ( /obj/structure/catwalk, /turf/simulated/floor/plating, @@ -30530,22 +29941,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_one_hall) -"pjp" = ( -/obj/structure/catwalk, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/visible/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/visible/yellow{ - dir = 4 - }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "poN" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/catwalk, @@ -30601,22 +29996,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_one_hall) -"qIr" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/cyan, -/obj/structure/catwalk, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/door/airlock/maintenance/common{ - name = "Mining Maintenance Access" - }, -/turf/simulated/floor/plating, -/area/tether/surfacebase/cargo/mining) "qKn" = ( /obj/effect/floor_decal/steeldecal/steel_decals_central1{ dir = 8 @@ -30682,21 +30061,6 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/locker/laundry_arrival) -"qYW" = ( -/obj/structure/catwalk, -/obj/machinery/alarm{ - pixel_y = 22 - }, -/obj/effect/floor_decal/rust, -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ - dir = 6 - }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "raS" = ( /obj/effect/floor_decal/industrial/warning, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, @@ -31018,31 +30382,6 @@ /obj/machinery/door/airlock/glass, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_one_hall) -"tbB" = ( -/obj/structure/catwalk, -/obj/structure/cable{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, -/obj/machinery/atmospherics/pipe/simple/visible/yellow, -/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/visible/supply{ - dir = 6 - }, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "tvk" = ( /obj/structure/cable{ d1 = 1; @@ -31269,23 +30608,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/hallway) -"uRe" = ( -/obj/structure/catwalk, -/obj/structure/cable{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/visible/yellow, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "uUP" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -31564,12 +30886,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/mining_eva) -"xYK" = ( -/obj/structure/catwalk, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, -/turf/simulated/floor/tiled/techfloor, -/area/maintenance/lower/xenoflora) "ygY" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -35796,7 +35112,7 @@ aah aah aah aah -aah +aiW aah aah aah @@ -36779,9 +36095,9 @@ axB ays ays ays -aBx -aCg -aCW +acu +ake +akf aDz aEe aET @@ -36918,16 +36234,16 @@ avG ahT auK axC -awV -awV -awV -awV -aiU -aCX -aCX -aCX -awV -awV +abN +abN +abN +abN +abN +abN +abN +abN +abN +abN ygY aGX aBv @@ -37060,16 +36376,16 @@ avH awn auK avh -awV -azu -aAz -aBy -aCh -aCY -aDA -aDA -aEU -awV +abN +aeR +aeR +aji +agF +agP +aiQ +agD +aio +abN xgQ ofS aBv @@ -37089,33 +36405,33 @@ aad aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad @@ -37202,16 +36518,16 @@ avI awo auK avh -awV -azv -aAA -azA -azA -azA -azA -azA -aEV -awV +abN +aeR +aeR +aeR +agF +agP +ahv +ahm +aiB +abN lMf aGX aBv @@ -37231,33 +36547,33 @@ aad aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad @@ -37344,16 +36660,16 @@ acJ awp auK avh -awV -ajd -aAB -aBz -azA -azA -aDB -aEf -aEW -awV +abN +aeR +aeR +aeR +agF +agP +ahw +aiq +aiB +abN lwN icB aFI @@ -37373,33 +36689,33 @@ aad aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad -adK -adK -adK +ano +ano +ano aad aad aad @@ -37486,16 +36802,16 @@ avJ awq auK avh -awV -azw -aAC -aBA -aCi -aCi -aDC -aEg -aEX -aCX +abN +aeR +aeR +aeR +agG +aha +ahy +aiu +aiB +alS vlJ uAA aHp @@ -37628,22 +36944,22 @@ auK auK auK axD -awV -azx -aAD -aBB -aCj -aCj -aDD -aEg -aEY -aCX +abN +aeR +aeR +aeR +agF +ahb +ahF +aih +aiv +alS cIh aGX awn awn awn -aJt +anG awn aKL aLr @@ -37770,16 +37086,16 @@ avK awr awU axE -awV -azy -aAC -aBB -aCj -aCZ -aDD -aEg -aEZ -awV +abN +aeR +aeR +agl +agN +ahd +ahY +aiw +aix +abN ovG jkt awn @@ -37910,19 +37226,19 @@ auI avd avL aws -awV -awV -awV -aiR -aAC -aBB -aCj -aCj -aDD -aEh -aFa -ajc -cgN +abN +abN +abN +aeR +aeR +aeR +agF +ahe +ahF +aim +aiU +alT +ajd aGX awn aHP @@ -38052,23 +37368,23 @@ auJ ave avM aws -awV -axF -ayt -azz -aAC -aBC -aCk -aCk -aDE -aEi -aFb -awV +abN +abW +acp +afe +aeR +aeR +agG +aha +ahy +aiB +ajm +abN kyE aGX -aHq -aHq -aHq +adn +adn +adn aJw aKa aKL @@ -38194,23 +37510,23 @@ atH auK avN aws -awV -axG -ayu -azA -aAC -aBD -azA -azA -aDF -aEi -aFc -aCX +abN +aiR +acp +afe +aeR +aeR +agF +agP +aik +aiF +akp +alS ygY aGX -aHq -aHQ -aHq +adn +alY +adn aJx aKa aah @@ -38336,29 +37652,29 @@ auK avf avO aws -awV -axH -ayv -azB -aAE -aBE -azB -azB -aDG -aEj -aFc -aCX -ygY +abN +abN +abN +aeR +aeR +aeR +agF +agP +ahF +agx +alI +alU +aje oli -aHq -aHR -aHq -aHq -aHq -aHq -aHq -aHq -aHq +adn +alZ +adn +adn +adn +adn +adn +adn +adn aah aah aah @@ -38478,31 +37794,31 @@ auK avg avP awt -awV -axI -ayw -azC -aAF -aBF -aCl -aDa -aDH -aEk -aFd -aCX +abN +acb +abN +aeR +aeR +ane +agF +agP +ail +aiG +alL +alS ygY hps -aHq adn -aHq -aJy -aKb -aKO -aLt -aLt -aHq -aHq -aHq +ama +adn +amp +amv +amJ +amO +amO +adn +adn +adn aah aah aad @@ -38618,33 +37934,33 @@ apj apj auK avh -avQ -avQ -avQ -axJ -ayx -axJ -axJ -avQ -awV -awV -aiW -awV -aCX -aCX +abm +abm +abN +abN +abN +abN +abN +abN +abN +abN +abN +abN +alS +alS gxM tvA -aHr -aHS -aHr -aJz -aKc -aKP -aLt -aLt -aML -aHQ -aHq +alV +amb +alV +amr +amx +amK +amO +amO +and +alY +adn aah aah aah @@ -38760,33 +38076,33 @@ apj apj auK avi -avQ -awu -awW -axK -ayy -azD -aAG -avQ +abm +abn +abn +abn +acx +afg +abv +abm aCm -aDb -aDI -aEl +akg +aDy +akj aCV aCV szT jSU -aHs -aHT -aHs -aJA -aKd -aKQ -aKQ -aMe -aHq -aHq -aHq +alW +amd +alW +ams +amy +amL +amL +amW +adn +adn +adn aah aah aah @@ -38902,14 +38218,14 @@ apj apj auK avh -avQ -awv -awX -axL -ayz -azE -aAH -avQ +abm +abv +abv +abv +acD +afu +agm +abm aCn aDc aDJ @@ -38918,17 +38234,17 @@ aDJ aDJ uOe nis -aHq -aHU -aHV -aJB -aKe -aKR -aLu -aLu -aML -aHQ -aHq +adn +amn +amo +amt +amz +amN +amR +amR +and +alY +adn aah aah aah @@ -39044,14 +38360,14 @@ apj apj auK avh -avQ -aww -awY -axM -ayA -azF -aAI -axJ +abm +abw +abw +abw +abv +afA +abv +abm aCo aDd aDg @@ -39060,17 +38376,17 @@ aDg aDg aGm aGW -aHq -aHV -aHV -aJC -aKf -aKR -aLu -aLu -aHq -aHq -aHq +adn +amo +amo +amu +amI +amN +amR +amR +adn +adn +adn aah aah aah @@ -39186,15 +38502,15 @@ apj apj auK avh -avQ -awx -awZ -axN -ayB -azG +abm +abD +abv +abv +adz +afP +agn +agE ajJ -aBG -aCp aDe aDK aEn @@ -39202,15 +38518,15 @@ aDe aDe aGn aGX -aHq -aHq -aHq -aHq -aHq -aHq -aHq -aHq -aHq +adn +adn +adn +adn +adn +adn +adn +adn +adn aah aah aah @@ -39328,15 +38644,15 @@ apj apj auK avh -avQ -awy -axa -axO -ayC -azH -aAJ -axJ -aCo +abm +abw +abw +abw +adM +afU +abv +abm +ajW aDf aDL aDg @@ -39470,15 +38786,15 @@ apj apj auK avh -avQ -awz -axa -axO -ayC -azH -aAK -avQ -aCq +abm +abv +abv +abv +adM +afU +abv +abm +ajX aDf aDL aDg @@ -39612,18 +38928,18 @@ apj apj auK avh -avQ -awy -axa -axO -ayD -azI -abD -avQ -aCr -aDg -aDM -aEo +abm +abI +abI +abI +adM +afU +abv +abm +aka +aFf +akc +akd aFf aFf aGp @@ -39754,14 +39070,14 @@ apj apj auK avh -avQ -awA -axb -axP -ayE -azJ -aAL -avQ +abm +abI +abI +abI +adN +afU +agr +abm aCs aDh aDN @@ -39896,14 +39212,14 @@ apu apu apu avj -avQ -avQ -avQ -avQ -avQ -azK -avQ -avQ +abm +abm +abm +abm +abm +afX +abm +abm awn awn awn @@ -40043,7 +39359,7 @@ kCz csb imW tMP -pjp +alJ apu aBH aCt @@ -40174,18 +39490,18 @@ bco bco bcl apu -qYW -xYK -xYK -fXu -fFf -fZA -iHP -uRe -tbB -ogk -nrX -dZo +agy +alb +alb +alb +alb +alC +alD +alE +alF +alG +alH +alK acW aBI aCu @@ -40316,10 +39632,10 @@ bck bck bck bbX -bbZ -atd -atJ -auq +aiC +alt +alu +alv apu bcq avT @@ -40461,7 +39777,7 @@ apu aqb ate atK -aur +atL apu bcr avT @@ -42281,7 +41597,7 @@ aar aar aar abT -crC +ajc abT agd acC @@ -42421,7 +41737,7 @@ aaG aaM aaP aaY -qIr +ajb ecq nDD jPk @@ -44604,21 +43920,21 @@ aJc agM agM aLg -aLg -aLg -aLg -aLg -aOj -aOj -aOj -aOj -aQb -aQb -aQb -aQb -aSi -aSi -aSi +ajl +ajl +ajl +ajl +anm +anm +anm +anm +ann +ann +ann +ann +anE +anE +anE aSi aUe aUH @@ -45576,7 +44892,7 @@ evF ast auR avq -avY +anH awM axs awN @@ -46475,7 +45791,7 @@ aWo aWM aWV aVn -aXQ +aop aYi aYE aZd @@ -46617,7 +45933,7 @@ aUP aUP bcT aVn -aVn +anK aYi aYi aYi @@ -46955,7 +46271,7 @@ aad aad aad aad -aad +aah aah aah aah @@ -47097,8 +46413,8 @@ aad aad aad aad -aad -aad +aah +aah aah aah aah @@ -47239,8 +46555,8 @@ aad aad aad aad -aad -aad +aah +aah aah aah aah @@ -47381,7 +46697,7 @@ aad aad aad aad -aad +aah aah aah aah @@ -47523,7 +46839,7 @@ aad aad aad aad -aad +aah aah aah aah @@ -47947,7 +47263,6 @@ aad aad aad aad -aad aah aah aah @@ -47962,12 +47277,13 @@ aah aah aah aah -aad -aad -aad -aad -aad -aad +aah +aah +aah +aah +aah +aah +aah aah aah aah @@ -48089,8 +47405,6 @@ aad aad aad aad -aad -aad aah aah aah @@ -48104,20 +47418,22 @@ aah aah aah aah -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah aah aah aah @@ -48231,8 +47547,14 @@ aad aad aad aad -aad -aad +aah +aah +aah +aah +aah +aah +aah +aah aah aah aah @@ -48247,19 +47569,8 @@ aah aah aah aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad +aah +aah aad aad aah @@ -48268,7 +47579,12 @@ aah aah aah aah -aad +aah +aah +aah +aah +aah +baU aty aub aub @@ -48373,8 +47689,20 @@ aad aad aad aad -aad -aad +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah aah aah aah @@ -48388,29 +47716,17 @@ aad aad aad aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad aah aah aah aah aah aah -aad +aah +aah +aah +aah +baU atz auc auc @@ -48515,6 +47831,22 @@ aad aad aad aad +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah aad aad aad @@ -48528,29 +47860,13 @@ aad aad aad aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad +aah +aah +aah +aah +aah +aah +aah aad aad atz @@ -48658,6 +47974,20 @@ ajK aad aad aad +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah aad aad aad @@ -48674,23 +48004,9 @@ aad aad aad aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad +aah +aah +aah aad aad aad @@ -48802,16 +48118,16 @@ aad aad aad aad -aad -aad -aad -aad -aad -aad -aad -aad -aad -aad +aah +aah +aah +aah +aah +aah +aah +aah +aah +aah aad aad aad @@ -48945,12 +48261,12 @@ aad aad aad aad -aad -aad -aad -aad -aad -aad +aah +aah +aah +aah +aah +aah aad aad aad diff --git a/maps/tether/tether-02-surface2.dmm b/maps/tether/tether-02-surface2.dmm index d12c504b263..46e00db73bc 100644 --- a/maps/tether/tether-02-surface2.dmm +++ b/maps/tether/tether-02-surface2.dmm @@ -190,17 +190,28 @@ /area/maintenance/substation/medsec) "aay" = ( /obj/effect/floor_decal/borderfloorwhite{ - dir = 5 + dir = 9 }, /obj/effect/floor_decal/corner/white/border{ - dir = 5 + dir = 9; + icon_state = "bordercolor" + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 10 + }, +/obj/effect/floor_decal/corner/white/bordercorner2{ + dir = 10 }, /obj/structure/table/standard, -/obj/item/device/defib_kit/loaded, -/obj/machinery/light{ - dir = 4; - icon_state = "tube1" +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/machinery/light_switch{ + dir = 2; + name = "light switch "; + on = 0; + pixel_x = 0; + pixel_y = 26 }, +/obj/item/stack/nanopaste, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/surgery) "aaz" = ( @@ -228,7 +239,6 @@ icon_state = "bordercolorcorner2" }, /obj/structure/table/standard, -/obj/item/stack/nanopaste, /obj/machinery/atmospherics/unary/vent_pump/on, /obj/structure/extinguisher_cabinet{ pixel_y = 30 @@ -251,26 +261,22 @@ /area/tether/surfacebase/medical/surgery) "aaD" = ( /obj/effect/floor_decal/borderfloorwhite{ - dir = 9 + dir = 5 }, /obj/effect/floor_decal/corner/white/border{ - dir = 9; - icon_state = "bordercolor" - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 10 - }, -/obj/effect/floor_decal/corner/white/bordercorner2{ - dir = 10 + dir = 5 }, /obj/structure/table/standard, -/obj/machinery/atmospherics/unary/vent_scrubber/on, -/obj/machinery/light_switch{ - dir = 2; - name = "light switch "; - on = 0; - pixel_x = 0; - pixel_y = 26 +/obj/item/device/defib_kit/loaded, +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" + }, +/obj/item/weapon/reagent_containers/spray/cleaner{ + desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; + name = "Surgery Cleaner"; + pixel_x = 2; + pixel_y = 2 }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/surgery) @@ -502,6 +508,12 @@ dir = 6 }, /obj/structure/curtain/open/shower/medical, +/obj/machinery/shower{ + dir = 4; + icon_state = "shower"; + pixel_x = 2; + pixel_y = 0 + }, /turf/simulated/floor/tiled/dark, /area/tether/surfacebase/medical/resleeving) "aaX" = ( @@ -1253,6 +1265,13 @@ "acF" = ( /turf/simulated/wall/r_wall, /area/rnd/rdoffice) +"acG" = ( +/obj/effect/floor_decal/industrial/outline/yellow, +/obj/structure/railing{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/maintenance/lower/south) "acH" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -1372,6 +1391,40 @@ }, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/north) +"acZ" = ( +/obj/effect/floor_decal/borderfloor/shifted{ + dir = 1; + icon_state = "borderfloor_shifted" + }, +/obj/effect/floor_decal/corner/lightorange/border/shifted{ + dir = 1; + icon_state = "bordercolor_shifted" + }, +/obj/effect/floor_decal/corner/lightorange{ + dir = 5; + icon_state = "corner_white" + }, +/obj/machinery/atmospherics/unary/vent_pump/on, +/obj/machinery/cryopod{ + dir = 4 + }, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/obj/machinery/computer/cryopod{ + pixel_x = -32 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/security/solitary) +"ada" = ( +/obj/machinery/cryopod{ + dir = 4 + }, +/obj/machinery/computer/cryopod{ + pixel_x = -32 + }, +/turf/simulated/floor/tiled/dark, +/area/tether/surfacebase/security/brig) "adb" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -1536,6 +1589,27 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/open, /area/maintenance/lower/north) +"adq" = ( +/obj/machinery/door/airlock/maintenance/engi{ + name = "Atmospherics"; + req_access = list(24) + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 1; + icon_state = "pdoor0"; + id = "atmoslockdown"; + layer = 1; + name = "Atmospherics Lockdown"; + opacity = 0; + open_layer = 1 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/engineering/atmos) "adr" = ( /obj/structure/railing{ dir = 1 @@ -1643,6 +1717,53 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/north) +"adE" = ( +/obj/item/device/radio/intercom{ + dir = 1; + name = "Station Intercom (General)"; + pixel_y = 21 + }, +/obj/machinery/alarm{ + pixel_x = 0; + pixel_y = 30 + }, +/obj/machinery/computer/security/xenobio, +/obj/machinery/camera/network/research/xenobio, +/turf/simulated/floor/tiled/white, +/area/rnd/outpost/xenobiology/outpost_slimepens) +"adF" = ( +/obj/machinery/button/remote/blast_door{ + id = "xenobiopen5"; + name = "Pen 5 Containment"; + pixel_x = -20; + pixel_y = -8; + req_access = list(55) + }, +/obj/machinery/button/remote/blast_door{ + id = "xenobiopen3"; + name = "Pen 3 Containment"; + pixel_x = -20; + pixel_y = 8; + req_access = list(55) + }, +/obj/machinery/button/remote/blast_door{ + id = "xenobiodiv3"; + name = "Divider 3 Blast Doors"; + pixel_x = -25; + pixel_y = 0; + req_access = list(55) + }, +/obj/machinery/alarm{ + dir = 4; + pixel_x = -35; + pixel_y = 0 + }, +/obj/machinery/camera/network/research/xenobio{ + icon_state = "camera"; + dir = 4 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/outpost/xenobiology/outpost_slimepens) "adG" = ( /obj/structure/railing{ dir = 4 @@ -1772,6 +1893,34 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/north) +"adX" = ( +/obj/machinery/button/remote/blast_door{ + id = "xenobiodiv6"; + name = "Divider 6 Blast Doors"; + pixel_x = 38; + pixel_y = 0; + req_access = list(55) + }, +/obj/machinery/button/remote/blast_door{ + id = "xenobiopen6"; + name = "Pen 6 Containment"; + pixel_x = 30; + pixel_y = 8; + req_access = list(55) + }, +/obj/machinery/button/remote/blast_door{ + id = "xenobiopen8"; + name = "Pen 8 Containment"; + pixel_x = 30; + pixel_y = -8; + req_access = list(55) + }, +/obj/machinery/camera/network/research/xenobio{ + icon_state = "camera"; + dir = 9 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/outpost/xenobiology/outpost_slimepens) "adY" = ( /turf/simulated/wall, /area/tether/surfacebase/surface_two_hall) @@ -1788,6 +1937,24 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/mining) +"aea" = ( +/turf/simulated/mineral/floor/virgo3b, +/area/tether/surfacebase/outside/outside2) +"aeb" = ( +/obj/effect/floor_decal/borderfloorwhite{ + dir = 8 + }, +/obj/effect/floor_decal/corner/white/border{ + dir = 8 + }, +/obj/structure/table/standard, +/obj/item/device/radio/intercom/department/medbay{ + dir = 8; + pixel_x = -24 + }, +/obj/item/weapon/storage/firstaid/surgery, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/surgery) "aec" = ( /obj/structure/catwalk, /obj/structure/cable{ @@ -1889,6 +2056,21 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/north) +"aem" = ( +/obj/effect/floor_decal/borderfloorwhite{ + dir = 8 + }, +/obj/effect/floor_decal/corner/white/border{ + dir = 8 + }, +/obj/structure/table/standard, +/obj/item/device/radio/intercom{ + dir = 8; + pixel_x = -24 + }, +/obj/item/device/healthanalyzer, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/surgery) "aen" = ( /obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary{ scrub_id = "atrium" @@ -1920,6 +2102,40 @@ /obj/effect/floor_decal/rust, /turf/simulated/floor/tiled/techfloor, /area/maintenance/lower/mining) +"aer" = ( +/obj/structure/table/rack, +/obj/machinery/light, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/item/clothing/suit/space/void/medical/emt, +/obj/item/clothing/suit/space/void/medical/emt, +/obj/item/clothing/head/helmet/space/void/medical/emt, +/obj/item/clothing/head/helmet/space/void/medical/emt, +/obj/item/clothing/shoes/magboots, +/obj/item/clothing/shoes/magboots, +/obj/item/clothing/mask/breath, +/obj/item/clothing/mask/breath, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/paramed) +"aes" = ( +/obj/effect/floor_decal/borderfloorwhite{ + dir = 4 + }, +/obj/effect/floor_decal/corner/paleblue/border{ + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/obj/structure/table/rack, +/obj/item/weapon/storage/belt/medical, +/obj/item/weapon/storage/belt/medical, +/obj/item/weapon/storage/belt/medical, +/obj/item/weapon/storage/belt/medical, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/storage) "aet" = ( /obj/structure/railing{ dir = 1 @@ -2045,11 +2261,84 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled/techfloor/grid, /area/maintenance/lower/north) +"aeI" = ( +/obj/machinery/door/window/eastleft{ + dir = 8; + icon_state = "left"; + name = "Janitorial Desk" + }, +/obj/machinery/door/window/eastleft{ + dir = 4; + icon_state = "left"; + name = "Janitorial Desk"; + req_access = list(26) + }, +/obj/structure/table/reinforced, +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "janitor_blast"; + layer = 3.3; + name = "Janitorial Shutters" + }, +/obj/machinery/door/firedoor/border_only, +/turf/simulated/floor/tiled, +/area/janitor) +"aeJ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = 25; + pixel_y = 0 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/purple/border{ + dir = 4 + }, +/obj/structure/table/steel, +/obj/item/weapon/grenade/chem_grenade/cleaner, +/obj/item/weapon/grenade/chem_grenade/cleaner, +/obj/item/weapon/grenade/chem_grenade/cleaner, +/obj/item/weapon/grenade/chem_grenade/cleaner, +/obj/item/weapon/storage/box/mousetraps, +/obj/item/weapon/storage/box/lights/mixed, +/obj/item/weapon/storage/box/lights/mixed, +/obj/item/weapon/reagent_containers/spray/cleaner, +/obj/item/weapon/reagent_containers/spray/cleaner, +/obj/item/weapon/reagent_containers/spray/cleaner, +/turf/simulated/floor/tiled, +/area/janitor) "aeK" = ( /obj/structure/grille, /obj/structure/railing, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/surface_two_hall) +"aeL" = ( +/obj/structure/catwalk, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1; + icon_state = "bulb1" + }, +/turf/simulated/floor/plating, +/area/maintenance/lower/bar) +"aeM" = ( +/obj/effect/floor_decal/borderfloorwhite, +/obj/effect/floor_decal/corner/paleblue/border, +/obj/item/weapon/storage/toolbox/mechanical, +/obj/item/device/multitool, +/obj/item/device/multitool, +/obj/structure/table/rack, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/storage) "aeN" = ( /obj/effect/floor_decal/rust, /obj/effect/decal/cleanable/dirt, @@ -2163,6 +2452,49 @@ }, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/surface_two_hall) +"afb" = ( +/obj/effect/floor_decal/borderfloorwhite, +/obj/effect/floor_decal/corner/paleblue/border, +/obj/machinery/power/apc{ + dir = 2; + name = "south bump"; + pixel_y = -28; + req_access = list(67) + }, +/obj/structure/cable/green, +/obj/structure/table/rack, +/obj/item/device/gps/medical{ + pixel_y = 3 + }, +/obj/item/device/gps/medical{ + pixel_x = -3 + }, +/obj/item/device/radio{ + pixel_x = 2; + pixel_y = 0 + }, +/obj/item/device/radio{ + pixel_x = -1; + pixel_y = -3 + }, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/storage) +"afc" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/airlock/medical{ + id_tag = null; + name = "Resleeving Backroom"; + req_access = list(0); + req_one_access = list(0) + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/tether/surfacebase/medical/resleeving) "afd" = ( /obj/machinery/atmospherics/pipe/simple/hidden/green{ dir = 4; @@ -2390,6 +2722,38 @@ }, /turf/simulated/floor/tiled/dark, /area/tether/surfacebase/security/evidence) +"afr" = ( +/obj/machinery/atmospherics/portables_connector, +/obj/machinery/portable_atmospherics/canister/air/airlock{ + start_pressure = 4559.63 + }, +/turf/simulated/floor/tiled/dark, +/area/tcommsat/computer) +"afs" = ( +/obj/machinery/door/airlock/maintenance/sec{ + name = "Riot Control"; + req_access = list(); + req_one_access = list(63,24) + }, +/obj/machinery/atmospherics/pipe/simple/hidden/green{ + dir = 4; + icon_state = "intact" + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor, +/area/tether/surfacebase/security/gasstorage) "aft" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -2500,6 +2864,56 @@ }, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/surface_two_hall) +"afC" = ( +/obj/machinery/door/airlock/security{ + name = "Observation"; + req_one_access = list(63,4) + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/dark, +/area/tether/surfacebase/security/interrogation) +"afD" = ( +/obj/machinery/door/airlock/maintenance/sec{ + name = "Riot Control"; + req_access = list(); + req_one_access = list(63,4) + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/visible/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ + dir = 8 + }, +/turf/simulated/floor, +/area/tether/surfacebase/security/interrogation) +"afE" = ( +/obj/machinery/door/airlock/security{ + name = "Evidence Storage"; + req_one_access = list(38,63) + }, +/obj/structure/cable/green{ + icon_state = "1-2" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/dark, +/area/tether/surfacebase/security/evidence) "afF" = ( /obj/machinery/atmospherics/unary/vent_pump/on{ dir = 8 @@ -7391,27 +7805,6 @@ }, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/surface_two_hall) -"apQ" = ( -/obj/machinery/door/airlock/maintenance/engi{ - name = "Atmospherics"; - req_access = list(24) - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 1; - icon_state = "pdoor0"; - id = "atmoslockdown"; - layer = 1; - name = "Atmospherics Lockdown"; - opacity = 0; - open_layer = 1 - }, -/turf/simulated/floor/plating, -/area/engineering/atmos) "apR" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 @@ -9853,12 +10246,6 @@ }, /turf/simulated/floor/wood, /area/rnd/breakroom) -"aup" = ( -/obj/structure/bed/chair/comfy{ - dir = 8 - }, -/turf/simulated/floor/wood, -/area/rnd/breakroom) "auq" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable/green{ @@ -10192,19 +10579,6 @@ /obj/structure/stairs/south, /turf/simulated/floor/tiled, /area/rnd/staircase/secondfloor) -"auW" = ( -/obj/structure/bed/chair/comfy{ - dir = 1 - }, -/obj/machinery/requests_console{ - department = "Science"; - departmentType = 2; - name = "Science Requests Console"; - pixel_x = -30; - pixel_y = 0 - }, -/turf/simulated/floor/wood, -/area/rnd/breakroom) "auX" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable/green{ @@ -12121,10 +12495,6 @@ /obj/effect/floor_decal/corner/yellow/bordercorner2, /turf/simulated/floor/tiled/monotile, /area/engineering/atmos) -"aya" = ( -/obj/structure/bed/chair/comfy, -/turf/simulated/floor/wood, -/area/rnd/breakroom) "ayb" = ( /obj/machinery/light_switch{ pixel_y = -28 @@ -13383,27 +13753,6 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/east_stairs_two) -"azK" = ( -/obj/machinery/door/window/eastleft{ - dir = 8; - icon_state = "left"; - name = "Janitorial Desk" - }, -/obj/machinery/door/window/eastleft{ - dir = 4; - icon_state = "left"; - name = "Janitorial Desk" - }, -/obj/structure/table/reinforced, -/obj/machinery/door/blast/shutters{ - dir = 2; - id = "janitor_blast"; - layer = 3.3; - name = "Janitorial Shutters" - }, -/obj/machinery/door/firedoor/border_only, -/turf/simulated/floor/tiled, -/area/janitor) "azL" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -14244,36 +14593,6 @@ }, /turf/simulated/floor/tiled, /area/janitor) -"aBn" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 - }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, -/obj/structure/extinguisher_cabinet{ - pixel_x = 25; - pixel_y = 0 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/purple/border{ - dir = 4 - }, -/obj/structure/table/steel, -/obj/item/weapon/grenade/chem_grenade/cleaner, -/obj/item/weapon/grenade/chem_grenade/cleaner, -/obj/item/weapon/grenade/chem_grenade/cleaner, -/obj/item/weapon/grenade/chem_grenade/cleaner, -/obj/item/weapon/storage/box/mousetraps, -/obj/item/weapon/storage/box/lights/mixed, -/obj/item/weapon/storage/box/lights/mixed, -/obj/item/weapon/reagent_containers/spray/cleaner, -/obj/item/weapon/reagent_containers/spray/cleaner, -/turf/simulated/floor/tiled, -/area/janitor) "aBo" = ( /obj/machinery/door/airlock/multi_tile/metal/mait, /obj/machinery/door/firedoor/glass, @@ -17487,11 +17806,6 @@ /area/tcomsat{ name = "\improper Telecomms Lobby" }) -"aIs" = ( -/obj/machinery/atmospherics/portables_connector, -/obj/machinery/portable_atmospherics/canister/air/airlock, -/turf/simulated/floor/tiled/dark, -/area/tcommsat/computer) "aIt" = ( /obj/structure/filingcabinet, /obj/machinery/status_display{ @@ -19148,20 +19462,6 @@ }, /turf/simulated/floor/reinforced, /area/rnd/outpost/xenobiology/outpost_slimepens) -"aLt" = ( -/obj/item/device/radio/intercom{ - dir = 1; - name = "Station Intercom (General)"; - pixel_y = 21 - }, -/obj/machinery/alarm{ - pixel_x = 0; - pixel_y = 30 - }, -/obj/machinery/computer/security/xenobio, -/obj/machinery/camera/network/research, -/turf/simulated/floor/tiled/white, -/area/rnd/outpost/xenobiology/outpost_slimepens) "aLu" = ( /obj/machinery/button/remote/blast_door{ id = "xenobiodiv4"; @@ -21065,38 +21365,6 @@ /obj/structure/table/standard, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/storage) -"aPb" = ( -/obj/machinery/button/remote/blast_door{ - id = "xenobiopen5"; - name = "Pen 5 Containment"; - pixel_x = -20; - pixel_y = -8; - req_access = list(55) - }, -/obj/machinery/button/remote/blast_door{ - id = "xenobiopen3"; - name = "Pen 3 Containment"; - pixel_x = -20; - pixel_y = 8; - req_access = list(55) - }, -/obj/machinery/button/remote/blast_door{ - id = "xenobiodiv3"; - name = "Divider 3 Blast Doors"; - pixel_x = -25; - pixel_y = 0; - req_access = list(55) - }, -/obj/machinery/alarm{ - dir = 4; - pixel_x = -35; - pixel_y = 0 - }, -/obj/machinery/camera/network/research{ - dir = 4 - }, -/turf/simulated/floor/tiled/dark, -/area/rnd/outpost/xenobiology/outpost_slimepens) "aPc" = ( /obj/structure/disposalpipe/trunk{ dir = 8 @@ -21111,34 +21379,6 @@ }, /turf/simulated/floor/reinforced, /area/rnd/outpost/xenobiology/outpost_slimepens) -"aPd" = ( -/obj/machinery/button/remote/blast_door{ - id = "xenobiodiv6"; - name = "Divider 6 Blast Doors"; - pixel_x = 38; - pixel_y = 0; - req_access = list(55) - }, -/obj/machinery/button/remote/blast_door{ - id = "xenobiopen6"; - name = "Pen 6 Containment"; - pixel_x = 30; - pixel_y = 8; - req_access = list(55) - }, -/obj/machinery/button/remote/blast_door{ - id = "xenobiopen8"; - name = "Pen 8 Containment"; - pixel_x = 30; - pixel_y = -8; - req_access = list(55) - }, -/obj/machinery/camera/network/research{ - dir = 8; - icon_state = "camera" - }, -/turf/simulated/floor/tiled/dark, -/area/rnd/outpost/xenobiology/outpost_slimepens) "aPe" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -21448,20 +21688,6 @@ /obj/machinery/light/small, /turf/simulated/floor/tiled/techfloor, /area/tether/surfacebase/medical/lowerhall) -"aPD" = ( -/obj/effect/floor_decal/borderfloorwhite{ - dir = 8 - }, -/obj/effect/floor_decal/corner/white/border{ - dir = 8 - }, -/obj/structure/table/standard, -/obj/item/device/radio/intercom/department/medbay{ - dir = 8; - pixel_x = -24 - }, -/turf/simulated/floor/tiled/white, -/area/tether/surfacebase/medical/surgery) "aPE" = ( /obj/effect/floor_decal/industrial/loading{ dir = 4 @@ -21757,20 +21983,6 @@ }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/lowerhall) -"aQe" = ( -/obj/effect/floor_decal/borderfloorwhite{ - dir = 8 - }, -/obj/effect/floor_decal/corner/white/border{ - dir = 8 - }, -/obj/structure/table/standard, -/obj/item/device/radio/intercom{ - dir = 8; - pixel_x = -24 - }, -/turf/simulated/floor/tiled/white, -/area/tether/surfacebase/medical/surgery) "aQf" = ( /obj/effect/floor_decal/steeldecal/steel_decals6{ dir = 4 @@ -21842,21 +22054,6 @@ }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/resleeving) -"aQm" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/medical{ - id_tag = null; - name = "Resleeving Backroom"; - req_access = list(5) - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/tether/surfacebase/medical/resleeving) "aQn" = ( /obj/effect/floor_decal/techfloor{ dir = 8 @@ -21945,18 +22142,6 @@ }, /turf/simulated/floor/tiled/dark, /area/chapel/main) -"aQv" = ( -/obj/structure/table/rack, -/obj/item/clothing/suit/space/void/medical/emt, -/obj/item/clothing/head/helmet/space/void/medical/emt, -/obj/item/clothing/shoes/magboots, -/obj/item/clothing/mask/breath, -/obj/machinery/light, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/tether/surfacebase/medical/paramed) "aQw" = ( /obj/structure/extinguisher_cabinet{ dir = 1; @@ -22291,22 +22476,6 @@ /obj/machinery/vitals_monitor, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/storage) -"aQR" = ( -/obj/effect/floor_decal/borderfloorwhite{ - dir = 4 - }, -/obj/effect/floor_decal/corner/paleblue/border{ - dir = 4 - }, -/obj/machinery/firealarm{ - dir = 4; - pixel_x = 24 - }, -/obj/structure/table/rack, -/obj/item/weapon/storage/belt/medical, -/obj/item/weapon/storage/belt/medical, -/turf/simulated/floor/tiled/white, -/area/tether/surfacebase/medical/storage) "aQS" = ( /obj/structure/table/glass, /obj/item/weapon/book/manual/resleeving, @@ -23432,23 +23601,6 @@ }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/storage) -"aSB" = ( -/obj/effect/floor_decal/borderfloorwhite, -/obj/effect/floor_decal/corner/paleblue/border, -/turf/simulated/floor/tiled/white, -/area/tether/surfacebase/medical/storage) -"aSC" = ( -/obj/effect/floor_decal/borderfloorwhite, -/obj/effect/floor_decal/corner/paleblue/border, -/obj/machinery/power/apc{ - dir = 2; - name = "south bump"; - pixel_y = -28; - req_access = list(67) - }, -/obj/structure/cable/green, -/turf/simulated/floor/tiled/white, -/area/tether/surfacebase/medical/storage) "aSD" = ( /obj/effect/floor_decal/borderfloorwhite, /obj/effect/floor_decal/corner/paleblue/border, @@ -24147,28 +24299,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/security/lowerhallway) -"aTI" = ( -/obj/effect/floor_decal/borderfloor/shifted{ - dir = 1; - icon_state = "borderfloor_shifted" - }, -/obj/effect/floor_decal/corner/lightorange/border/shifted{ - dir = 1; - icon_state = "bordercolor_shifted" - }, -/obj/effect/floor_decal/corner/lightorange{ - dir = 5; - icon_state = "corner_white" - }, -/obj/machinery/atmospherics/unary/vent_pump/on, -/obj/machinery/cryopod{ - dir = 4 - }, -/obj/machinery/alarm{ - pixel_y = 22 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/security/solitary) "aTJ" = ( /obj/effect/floor_decal/borderfloor/shifted{ dir = 1; @@ -24543,18 +24673,6 @@ "aUk" = ( /turf/simulated/wall/r_wall, /area/tether/surfacebase/security/evidence) -"aUl" = ( -/obj/machinery/door/airlock/security{ - name = "Evidence Storage"; - req_access = newlist(); - req_one_access = list(1,38) - }, -/obj/structure/cable/green{ - icon_state = "1-2" - }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled/dark, -/area/tether/surfacebase/security/evidence) "aUm" = ( /obj/machinery/atmospherics/portables_connector{ dir = 4 @@ -24731,30 +24849,6 @@ }, /turf/simulated/floor, /area/tether/surfacebase/security/gasstorage) -"aUD" = ( -/obj/machinery/door/airlock/maintenance/sec{ - name = "Riot Control"; - req_access = list(1) - }, -/obj/machinery/atmospherics/pipe/simple/hidden/green{ - dir = 4; - icon_state = "intact" - }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4; - icon_state = "intact-scrubbers" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor, -/area/tether/surfacebase/security/gasstorage) "aUE" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -25101,25 +25195,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/security/lowerhallway) -"aVb" = ( -/obj/machinery/door/airlock/security{ - name = "Observation"; - req_one_access = list(1,4) - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled/dark, -/area/tether/surfacebase/security/interrogation) "aVc" = ( /obj/structure/cable/green{ d1 = 4; @@ -25975,12 +26050,6 @@ }, /turf/simulated/floor/tiled/dark, /area/tether/surfacebase/security/interrogation) -"aWo" = ( -/obj/machinery/cryopod{ - dir = 4 - }, -/turf/simulated/floor/tiled/dark, -/area/tether/surfacebase/security/brig) "aWq" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 @@ -28393,6 +28462,10 @@ }, /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/surface_two_hall) +"dgA" = ( +/obj/structure/bed/chair/comfy/brown, +/turf/simulated/floor/wood, +/area/rnd/breakroom) "drH" = ( /obj/structure/cable{ d1 = 4; @@ -28412,6 +28485,12 @@ /obj/structure/railing, /turf/simulated/floor/plating, /area/maintenance/lower/rnd) +"dEl" = ( +/obj/structure/bed/chair/comfy/brown{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/rnd/breakroom) "dQd" = ( /obj/structure/catwalk, /obj/machinery/atmospherics/pipe/simple/visible/supply{ @@ -28507,25 +28586,6 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/north) -"fXU" = ( -/obj/machinery/door/airlock/maintenance/sec{ - name = "Riot Control"; - req_access = list(1) - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/visible/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ - dir = 8 - }, -/turf/simulated/floor, -/area/tether/surfacebase/security/interrogation) "fYA" = ( /obj/structure/catwalk, /obj/structure/cable{ @@ -29193,6 +29253,19 @@ /obj/structure/disposalpipe/up, /turf/simulated/floor/plating, /area/maintenance/lower/rnd) +"qXI" = ( +/obj/machinery/requests_console{ + department = "Science"; + departmentType = 2; + name = "Science Requests Console"; + pixel_x = -30; + pixel_y = 0 + }, +/obj/structure/bed/chair/comfy/brown{ + dir = 1 + }, +/turf/simulated/floor/wood, +/area/rnd/breakroom) "rim" = ( /obj/machinery/alarm{ dir = 1; @@ -34916,7 +34989,7 @@ aIZ aJB aHT aKZ -aPb +adF aJB aKl aKZ @@ -35044,9 +35117,9 @@ aab aab aab aab -acD -acD -acD +aaS +aaS +aaS aab aab aab @@ -35186,14 +35259,14 @@ aab aab aab aab -acD -acD -acD +aaS +aaS +aaS aab aab aab aHc -aLt +adE aHu aHx aHR @@ -35328,9 +35401,9 @@ aab aab aab aab -acD -acD -acD +aaS +aaS +aaS aab aab aab @@ -35488,7 +35561,7 @@ aLu aJF aKo aLa -aPd +adX aJF aKs aLa @@ -37681,7 +37754,7 @@ aVx akg aVQ aWe -aWo +ada aUN acW adw @@ -37719,9 +37792,9 @@ aqU arA ass aqk -aya +dgA auo -auW +qXI avu awj aAi @@ -37862,7 +37935,7 @@ arB ast aqk atD -aup +dEl atJ atJ awk @@ -38241,7 +38314,7 @@ aTv aTP aUf abE -aUD +afs aUN aUN aTB @@ -38722,7 +38795,7 @@ atJ axP auv azl -apQ +adq aAT aAT aBW @@ -39237,7 +39310,7 @@ aTr aUs aPh aUQ -aVb +afC aUQ aUQ aUQ @@ -39801,11 +39874,11 @@ aab aTs aTL aTV -aUl +afE aUv aUI aUQ -fXU +afD aUQ aUQ aUQ @@ -40225,7 +40298,7 @@ aab aab aab aTt -aTI +acZ aTZ aUk aUy @@ -41363,7 +41436,7 @@ aab aac aNz ayf -aQv +aer aan aaz aan @@ -42923,8 +42996,8 @@ aab aab aag aav -aPD -aQe +aeb +aem aQE aQV aRu @@ -43265,7 +43338,7 @@ arl axB axB axB -azK +aeI axB aBj axB @@ -43348,7 +43421,7 @@ aab aab aab aag -aaD +aay aPG aQh aQH @@ -43490,7 +43563,7 @@ aab aab aab aag -aay +aaD aPH aQi aQI @@ -43714,7 +43787,7 @@ aGO arZ aac aHP -aIs +afr aIS aJv aKd @@ -43835,7 +43908,7 @@ ayl ayU azN aAG -aBn +aeJ aBU axB aac @@ -43914,7 +43987,7 @@ aab aab aab aab -aac +aab aah aaH aQK @@ -44128,8 +44201,8 @@ aDF aDN aEe arZ -aac -aac +arZ +arZ aac arZ arZ @@ -44270,7 +44343,7 @@ arZ aDP arZ arZ -arZ +acG arZ arZ arZ @@ -44486,7 +44559,7 @@ aab aah aah aah -aQm +afc aah aah aah @@ -44642,7 +44715,7 @@ abT aad acz adu -adL +aeL aec aew aeP @@ -45344,7 +45417,7 @@ aRi aRz aRT aSm -aSB +aeM aad abl abx @@ -45486,7 +45559,7 @@ aRj aRA aQs aSn -aSC +afb aad abm aby @@ -45902,12 +45975,12 @@ aab aab aab aab -aab +aac aac aKv aPV aQt -aQR +aes aRl aRC ahi @@ -45917,8 +45990,8 @@ aKv aac aac aac -aab -aab +aac +aac aac aac aac @@ -46044,8 +46117,8 @@ aab aab aab aab -aab -aab +aac +aac aKv aKv aKv @@ -46059,20 +46132,20 @@ aKv aac aac aac -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac aac aac aac @@ -46186,6 +46259,30 @@ aab aab aab aab +aac +aac +aac +aac +aac +aac +aac +aac +aac +aea +aea +aac +aac +aac +aac +aac +aac +aac +aac +aac +aac +aab +aac +aac aab aab aac @@ -46194,30 +46291,6 @@ aac aac aac aac -apq -apq -apq -apq -apq -aac -aac -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aac adu adu adu @@ -46328,6 +46401,31 @@ aab aab aab aab +aac +aac +aac +aac +aac +aac +aac +aac +aea +aea +aea +aea +aac +aac +aac +aac +aac +aac +aac +aac +aac +aab +aab +aab +aab aab aab aac @@ -46335,31 +46433,6 @@ aac aac aac aac -apq -apq -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aac aac aac aac @@ -46470,6 +46543,22 @@ aab aab aab aab +aac +aac +aac +aac +aac +aac +aac +aac +apq +aea +aea +aea +aac +aac +aac +aac aab aab aab @@ -46483,29 +46572,13 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aac +aac +aac +aac +aac +aac +aac ajT ajT ajT @@ -46613,6 +46686,20 @@ aab aab aab aab +aac +aac +aac +aac +aac +aac +apq +apq +apq +apq +aac +aac +aac +aac aab aab aab @@ -46629,23 +46716,9 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aac +aac +aac aab aab aab @@ -46757,16 +46830,16 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aac +aac +aac +apq +apq +apq +apq +apq +apq +apq aab aab aab @@ -46900,12 +46973,12 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab +apq +apq +apq +apq +apq +apq aab aab aab diff --git a/maps/tether/tether-03-surface3.dmm b/maps/tether/tether-03-surface3.dmm index 4ccd5fb59b1..e48479aa87d 100644 --- a/maps/tether/tether-03-surface3.dmm +++ b/maps/tether/tether-03-surface3.dmm @@ -716,6 +716,12 @@ /obj/random/cigarettes, /turf/simulated/floor/plating, /area/maintenance/lower/medsec_maintenance) +"aby" = ( +/obj/machinery/alarm{ + pixel_y = 25 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "abz" = ( /obj/structure/lattice, /obj/machinery/door/firedoor/glass, @@ -1051,6 +1057,9 @@ }, /turf/simulated/floor/tiled/dark, /area/tether/surfacebase/medical/triage) +"acf" = ( +/turf/simulated/wall/r_wall, +/area/rnd/xenobiology/xenoflora) "acg" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -1087,6 +1096,29 @@ "acj" = ( /turf/simulated/wall, /area/rnd/outpost/xenobiology/outpost_hallway) +"ack" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8; + health = 1e+006 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"acl" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "acm" = ( /obj/structure/sink{ dir = 4; @@ -1102,6 +1134,16 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_three) +"acn" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aco" = ( /obj/structure/railing{ dir = 1; @@ -1291,7 +1333,7 @@ "acE" = ( /obj/machinery/door/airlock/glass_security{ name = "Break Room"; - req_access = list(1) + req_access = list(63) }, /obj/structure/disposalpipe/segment{ dir = 4 @@ -1530,8 +1572,11 @@ /obj/machinery/door/firedoor/glass, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/tiled, +/turf/simulated/floor/wood, /area/tether/surfacebase/reading_room) +"acV" = ( +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "acW" = ( /obj/machinery/atmospherics/pipe/cap/visible/scrubbers, /turf/simulated/floor/plating, @@ -1552,6 +1597,12 @@ /obj/structure/flora/pottedplant/stoutbush, /turf/simulated/floor/tiled/freezer, /area/crew_quarters/pool) +"acZ" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "ada" = ( /obj/structure/cable/green{ d1 = 4; @@ -1971,6 +2022,18 @@ /obj/effect/floor_decal/rust, /turf/simulated/floor/tiled/steel_dirty/virgo3b, /area/tether/surfacebase/outside/outside3) +"adK" = ( +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 5 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/industrial/danger{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "adL" = ( /obj/structure/cable/green{ d1 = 1; @@ -2022,7 +2085,7 @@ id_tag = "SurfaceBrigAccess"; layer = 2.8; name = "Security"; - req_access = list(1) + req_access = list(63) }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -2034,7 +2097,7 @@ id_tag = "SurfaceBrigAccess"; layer = 2.8; name = "Security"; - req_access = list(1) + req_access = list(63) }, /obj/structure/disposalpipe/segment, /obj/structure/cable/green{ @@ -2472,6 +2535,26 @@ /obj/random/tech_supply, /turf/simulated/floor/tiled/techfloor/grid, /area/maintenance/lower/medsec_maintenance) +"aeE" = ( +/obj/machinery/hologram/holopad, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"aeF" = ( +/obj/machinery/door/window/brigdoor/southright{ + dir = 4; + icon_state = "rightsecure"; + req_access = list(77); + req_one_access = newlist() + }, +/obj/machinery/door/window/brigdoor/southright{ + dir = 8; + icon_state = "rightsecure"; + req_access = list(77); + req_one_access = newlist() + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aeG" = ( /turf/simulated/wall, /area/tether/surfacebase/medical/lobby) @@ -2639,6 +2722,17 @@ }, /turf/simulated/floor/wood, /area/tether/surfacebase/reading_room) +"aeU" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5; + icon_state = "intact-supply" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aeV" = ( /obj/structure/table/glass, /obj/item/device/flashlight/lamp/green, @@ -2648,14 +2742,14 @@ /turf/simulated/floor/wood, /area/tether/surfacebase/reading_room) "aeW" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/window/reinforced{ +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/turf/simulated/floor/plating, -/area/tether/surfacebase/reading_room) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aeX" = ( /obj/structure/railing{ dir = 4 @@ -2674,6 +2768,16 @@ }, /turf/simulated/floor/tiled/steel_dirty/virgo3b, /area/tether/surfacebase/outside/outside3) +"aeZ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "afa" = ( /obj/machinery/door/airlock/maintenance/medical{ name = "Medical Maintenance Access"; @@ -2850,6 +2954,26 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/security/processing) +"afp" = ( +/obj/machinery/firealarm{ + dir = 2; + layer = 3.3; + pixel_x = 4; + pixel_y = 26 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"afq" = ( +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"afr" = ( +/obj/item/device/radio/intercom{ + dir = 1; + pixel_y = 24; + req_access = list() + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "afs" = ( /obj/structure/cable/green{ d1 = 4; @@ -3091,21 +3215,17 @@ /turf/simulated/floor/tiled/steel_grid, /area/tether/surfacebase/reading_room) "afI" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/window/reinforced, -/turf/simulated/floor/plating, -/area/tether/surfacebase/reading_room) -"afJ" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/window/reinforced{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" }, -/obj/structure/window/reinforced, -/turf/simulated/floor/plating, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"afJ" = ( +/turf/simulated/wall/r_wall, /area/tether/surfacebase/reading_room) "afK" = ( /turf/simulated/wall, @@ -3174,10 +3294,26 @@ }, /turf/simulated/floor/tiled/dark, /area/tether/surfacebase/security/common) +"afS" = ( +/turf/simulated/wall/r_wall, +/area/rnd/xenobiology/xenoflora_storage) +"afT" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/grass, +/area/hydroponics) "afU" = ( /obj/machinery/door/airlock/security{ name = "Security Processing"; - req_access = list(1) + req_access = list(63) }, /obj/structure/cable/green{ d1 = 4; @@ -3210,6 +3346,27 @@ }, /turf/simulated/floor/tiled/techfloor/grid, /area/maintenance/lower/medsec_maintenance) +"afX" = ( +/obj/machinery/door/airlock{ + id_tag = "ReadingRoom2"; + name = "Room 2" + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/wood, +/area/tether/surfacebase/reading_room) +"afY" = ( +/obj/machinery/atmospherics/pipe/manifold/visible, +/obj/machinery/meter, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"afZ" = ( +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aga" = ( /obj/structure/table/glass, /obj/item/weapon/backup_implanter{ @@ -3442,14 +3599,15 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "ags" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, /obj/machinery/door/firedoor, -/obj/structure/window/reinforced{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/door/airlock/glass_research{ + name = "Xenoflora Research"; + req_one_access = list(77) }, -/turf/simulated/floor/plating, -/area/tether/surfacebase/surface_three_hall) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "agt" = ( /obj/effect/floor_decal/steeldecal/steel_decals10{ dir = 4 @@ -3543,6 +3701,11 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"agB" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "agC" = ( /obj/structure/lattice, /obj/machinery/atmospherics/pipe/zpipe/down{ @@ -3595,6 +3758,22 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"agF" = ( +/obj/machinery/atmospherics/unary/freezer{ + dir = 2; + icon_state = "freezer" + }, +/obj/effect/floor_decal/corner/green{ + dir = 10 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 9 + }, +/obj/effect/floor_decal/industrial/danger{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "agG" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ @@ -3680,15 +3859,23 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/maintenance/lower/medsec_maintenance) "agN" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 6 +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 6 +/obj/structure/cable/green{ + d1 = 2; + d2 = 4; + icon_state = "2-4" }, -/obj/machinery/camera/network/tether{ - dir = 9 +/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, /area/tether/surfacebase/surface_three_hall) "agO" = ( @@ -3997,6 +4184,22 @@ }, /turf/simulated/floor/tiled/techfloor, /area/rnd/workshop) +"ahs" = ( +/obj/machinery/atmospherics/unary/heater{ + dir = 2; + icon_state = "heater" + }, +/obj/effect/floor_decal/corner/green{ + dir = 10 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/industrial/danger{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aht" = ( /obj/machinery/space_heater, /obj/effect/floor_decal/techfloor, @@ -4057,7 +4260,7 @@ "ahy" = ( /obj/machinery/door/airlock/glass_security{ name = "Front Desk"; - req_access = list(1) + req_access = list(63) }, /obj/structure/cable/green{ icon_state = "4-8" @@ -4072,6 +4275,16 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/security/frontdesk) +"ahz" = ( +/obj/machinery/door/airlock{ + id_tag = "ReadingRoom3"; + name = "Room 3" + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/wood, +/area/tether/surfacebase/reading_room) "ahA" = ( /obj/structure/cable/green{ d1 = 2; @@ -4327,23 +4540,13 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "ahR" = ( -/obj/structure/extinguisher_cabinet{ - dir = 8; - icon_state = "extinguisher_closed"; - pixel_x = 30 +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 8 }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "ahS" = ( @@ -4500,9 +4703,10 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/security/frontdesk) "aib" = ( -/obj/structure/closet/crate/freezer, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aic" = ( /obj/random/trash_pile, /obj/effect/floor_decal/techfloor{ @@ -4653,11 +4857,20 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 9 }, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 8 }, -/obj/structure/closet/hydrant{ - pixel_x = 32 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) @@ -4704,6 +4917,17 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"ais" = ( +/obj/item/device/radio/intercom{ + dir = 8; + pixel_x = -24 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"ait" = ( +/obj/machinery/camera/network/research, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aiu" = ( /obj/structure/table/steel, /obj/item/device/integrated_electronics/debugger{ @@ -5053,6 +5277,11 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/security/frontdesk) +"aiX" = ( +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/unary/vent_pump/on, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aiY" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 5 @@ -5068,6 +5297,13 @@ }, /turf/simulated/floor/tiled/techfloor/grid, /area/maintenance/lower/medsec_maintenance) +"aiZ" = ( +/obj/machinery/door/window/brigdoor/southright{ + req_access = list(77); + req_one_access = newlist() + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aja" = ( /obj/machinery/computer/crew{ dir = 4 @@ -5104,6 +5340,42 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"ajc" = ( +/obj/machinery/portable_atmospherics/hydroponics, +/obj/machinery/atmospherics/portables_connector, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/industrial/danger{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"ajd" = ( +/obj/machinery/portable_atmospherics/hydroponics, +/obj/machinery/atmospherics/portables_connector, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/industrial/danger{ + dir = 1 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"aje" = ( +/obj/machinery/portable_atmospherics/hydroponics, +/obj/machinery/atmospherics/portables_connector, +/obj/effect/floor_decal/borderfloor{ + dir = 5 + }, +/obj/effect/floor_decal/industrial/danger{ + dir = 5 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "ajf" = ( /obj/effect/floor_decal/steeldecal/steel_decals6{ dir = 1 @@ -5298,6 +5570,26 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_three) +"ajv" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/floor_decal/industrial/warning{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"ajw" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/floor_decal/industrial/warning{ + dir = 5; + icon_state = "warning" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"ajx" = ( +/obj/machinery/atmospherics/pipe/simple/visible, +/obj/machinery/meter, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "ajy" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -5343,15 +5635,39 @@ }, /turf/simulated/floor/tiled/dark, /area/bridge_hallway) -"ajD" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/closet/secure_closet/freezer/kitchen, -/obj/item/device/radio/intercom{ - dir = 4; - pixel_x = 24 +"ajC" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ + dir = 4 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"ajD" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/hologram/holopad, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "ajE" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -5369,6 +5685,21 @@ /obj/machinery/door/firedoor, /turf/simulated/floor/plating, /area/rnd/research_storage) +"ajF" = ( +/obj/machinery/atmospherics/pipe/simple/visible, +/obj/machinery/meter, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/industrial/danger{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"ajG" = ( +/obj/structure/catwalk, +/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/area/tether/surfacebase/outside/outside3) "ajH" = ( /obj/machinery/computer/secure_data, /obj/structure/fireaxecabinet{ @@ -5532,12 +5863,69 @@ "ajT" = ( /turf/simulated/wall/r_wall, /area/tether/surfacebase/security/lobby) +"ajU" = ( +/obj/structure/catwalk, +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ + dir = 6 + }, +/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/area/tether/surfacebase/outside/outside3) +"ajV" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"ajW" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/floor_decal/industrial/warning{ + dir = 4; + icon_state = "warning" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "ajX" = ( -/obj/structure/disposalpipe/segment{ +/obj/structure/cable/green{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"ajY" = ( +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 6; + icon_state = "intact" + }, +/obj/machinery/meter, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 8 + }, +/obj/effect/floor_decal/corner/mauve/bordercorner2{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"ajZ" = ( +/obj/machinery/atmospherics/portables_connector, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/industrial/danger{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aka" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -5583,10 +5971,6 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "akd" = ( -/obj/machinery/status_display{ - pixel_x = 32; - pixel_y = 0 - }, /obj/effect/floor_decal/borderfloor{ dir = 4 }, @@ -5599,6 +5983,7 @@ /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 9 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "ake" = ( @@ -5717,16 +6102,12 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "ako" = ( -/obj/structure/table/marble, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{ - pixel_x = -3; - pixel_y = 0 +/obj/machinery/atmospherics/binary/pump{ + dir = 4; + name = "Port to Isolation" }, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill{ - pixel_x = 3 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "akp" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/lightgrey/border, @@ -5978,68 +6359,74 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "akI" = ( -/obj/effect/floor_decal/borderfloor/corner, -/obj/effect/floor_decal/corner/lightgrey/bordercorner, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 9 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ +/obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8 }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" +/obj/structure/closet/hydrant{ + pixel_x = 32 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "akJ" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 4 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 + dir = 10 }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/glass, +/obj/machinery/light{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "akK" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/machinery/status_display{ + pixel_x = 32; + pixel_y = 0 }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 4 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 + dir = 10 }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "akL" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lightgrey/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/sortjunction{ + dir = 1; + icon_state = "pipe-j1s"; + name = "Xenobotany"; + sortType = "Xenobotany" }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) @@ -6140,20 +6527,19 @@ dir = 4 }, /area/crew_quarters/pool) +"akW" = ( +/obj/machinery/atmospherics/pipe/simple/visible{ + dir = 4 + }, +/obj/machinery/meter, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "akX" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/structure/extinguisher_cabinet{ - dir = 4; - icon_state = "extinguisher_closed"; - pixel_x = -30 +/obj/machinery/atmospherics/pipe/manifold/visible{ + dir = 1 }, /turf/simulated/floor/tiled, -/area/hydroponics) +/area/rnd/xenobiology/xenoflora_storage) "akY" = ( /turf/simulated/wall, /area/crew_quarters/recreation_area) @@ -6341,11 +6727,12 @@ /turf/simulated/floor/wood, /area/tether/surfacebase/surface_three_hall) "alr" = ( -/obj/structure/bed/chair/wood{ - dir = 8 +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/portables_connector{ + dir = 1 }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/surface_three_hall) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "als" = ( /obj/machinery/washing_machine, /obj/effect/floor_decal/techfloor{ @@ -6411,26 +6798,24 @@ /turf/simulated/floor/tiled/freezer, /area/crew_quarters/pool) "alz" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 10 +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/effect/floor_decal/corner/lime/bordercorner2{ - dir = 10 +/obj/machinery/door/airlock/glass_research{ + name = "Xenoflora Research"; + req_one_access = list(77) }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/steel_grid, +/area/rnd/xenobiology/xenoflora_storage) "alA" = ( /obj/effect/floor_decal/spline/plain{ dir = 1 @@ -6555,11 +6940,25 @@ /turf/simulated/floor/wood, /area/crew_quarters/recreation_area) "alM" = ( -/obj/structure/bed/chair/wood{ +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/portables_connector{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloor{ dir = 4 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/effect/floor_decal/industrial/danger{ + dir = 4 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 5 + }, +/obj/machinery/status_display{ + pixel_x = 32; + pixel_y = 0 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "alN" = ( /obj/machinery/fitness/heavy/lifter, /turf/simulated/floor/wood, @@ -6837,6 +7236,18 @@ }, /turf/simulated/floor/tiled/freezer, /area/crew_quarters/pool) +"amt" = ( +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ + dir = 10 + }, +/obj/structure/catwalk, +/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/area/tether/surfacebase/outside/outside3) +"amu" = ( +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers, +/obj/structure/catwalk, +/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/area/tether/surfacebase/outside/outside3) "amv" = ( /turf/simulated/floor/tiled, /area/crew_quarters/pool) @@ -7079,6 +7490,14 @@ }, /turf/simulated/floor/water/pool, /area/crew_quarters/pool) +"amS" = ( +/obj/machinery/portable_atmospherics/canister/sleeping_agent, +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "amT" = ( /obj/effect/floor_decal/borderfloor/corner{ dir = 4 @@ -7088,6 +7507,75 @@ }, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) +"amU" = ( +/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, +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 26 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"amV" = ( +/obj/machinery/portable_atmospherics/canister/sleeping_agent, +/obj/effect/floor_decal/industrial/warning{ + dir = 4; + icon_state = "warning" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"amW" = ( +/obj/structure/window/reinforced, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/industrial/danger{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 10 + }, +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"amX" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"amY" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/smartfridge{ + req_access = list(28) + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"amZ" = ( +/obj/machinery/atmospherics/portables_connector{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 10 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 10 + }, +/obj/item/device/radio/intercom{ + dir = 2; + pixel_y = -24 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "ana" = ( /obj/structure/table/woodentable, /obj/item/clothing/glasses/threedglasses, @@ -7116,27 +7604,17 @@ /turf/simulated/floor/tiled/steel_grid, /area/tether/surfacebase/north_stairs_three) "and" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/floor_decal/industrial/warning{ + dir = 9 + }, /obj/machinery/firealarm{ dir = 1; pixel_x = 0; - pixel_y = -25 + pixel_y = -24 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled/white, +/area/rnd/xenobiology/xenoflora_storage) "ane" = ( /turf/simulated/open, /area/tether/surfacebase/north_stairs_three) @@ -7174,6 +7652,15 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"ani" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/closet/secure_closet/freezer/kitchen, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"anj" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "ank" = ( /obj/machinery/door/airlock/maintenance/int{ name = "Fire/Phoron Shelter"; @@ -7193,6 +7680,27 @@ }, /turf/simulated/floor/tiled/techfloor/grid, /area/crew_quarters/panic_shelter) +"anl" = ( +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/obj/effect/floor_decal/industrial/warning{ + dir = 5 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/xenobiology/xenoflora_storage) +"anm" = ( +/obj/effect/floor_decal/corner/mauve/border, +/obj/machinery/light, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"ann" = ( +/obj/machinery/atmospherics/portables_connector{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/mauve/border, +/obj/machinery/light, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "ano" = ( /obj/machinery/light/small{ dir = 1 @@ -7331,6 +7839,48 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/pool) +"anC" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + icon_state = "map-scrubbers"; + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"anD" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"anE" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "anF" = ( /obj/structure/table/woodentable, /obj/item/weapon/coin/silver, @@ -7392,6 +7942,51 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"anM" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 + }, +/obj/machinery/power/apc{ + dir = 4; + name = "east bump"; + pixel_x = 28 + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"anN" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"anO" = ( +/obj/structure/catwalk, +/obj/machinery/atmospherics/pipe/simple/visible/universal, +/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/area/tether/surfacebase/outside/outside3) +"anP" = ( +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "anQ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -7589,6 +8184,14 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/recreation_area) +"aoe" = ( +/obj/machinery/portable_atmospherics/canister/carbon_dioxide, +/obj/effect/floor_decal/industrial/warning{ + dir = 4; + icon_state = "warning" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aof" = ( /obj/structure/bed/padded, /obj/effect/floor_decal/techfloor{ @@ -7633,6 +8236,18 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"aoj" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 9 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"aok" = ( +/turf/simulated/wall/r_wall, +/area/hydroponics) "aol" = ( /turf/simulated/wall/r_wall, /area/vacant/vacant_shop) @@ -7651,19 +8266,19 @@ /turf/simulated/floor/tiled/techfloor/grid, /area/vacant/vacant_shop) "aon" = ( -/turf/simulated/wall/r_wall, -/area/crew_quarters/freezer) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "aoo" = ( -/obj/machinery/door/airlock/maintenance/common{ - name = "Freezer Maintenance Access"; - req_access = list(28) +/obj/effect/floor_decal/corner/mauve/border{ + dir = 5 }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled/techfloor/grid, -/area/crew_quarters/freezer) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aop" = ( -/turf/simulated/wall/r_wall, -/area/hydroponics/cafegarden) +/turf/simulated/floor/grass, +/area/hydroponics) "aoq" = ( /obj/structure/bed/chair{ dir = 4 @@ -7804,6 +8419,16 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"aoD" = ( +/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/rnd/xenobiology/xenoflora_storage) "aoE" = ( /obj/structure/sign/directions/evac{ dir = 1 @@ -7866,8 +8491,13 @@ /turf/simulated/wall, /area/crew_quarters/freezer) "aoK" = ( -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/machinery/atmospherics/binary/pump{ + dir = 4; + name = "Isolation to Waste" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aoL" = ( /obj/structure/table/reinforced, /obj/effect/floor_decal/borderfloor{ @@ -7884,27 +8514,59 @@ /turf/simulated/floor/tiled, /area/rnd/research/testingrange) "aoM" = ( -/obj/structure/kitchenspike, -/obj/machinery/alarm{ - pixel_y = 22; - target_temperature = 293.15 +/obj/machinery/power/apc{ + dir = 1; + name = "north bump"; + pixel_x = 0; + pixel_y = 24 }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/structure/cable/green{ + d2 = 2; + icon_state = "0-2" + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aoN" = ( -/obj/structure/kitchenspike, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) -"aoO" = ( -/obj/structure/flora/ausbushes/grassybush, -/turf/simulated/floor/grass, -/area/hydroponics/cafegarden) -"aoP" = ( -/obj/machinery/light{ - dir = 1 +/obj/structure/bed/chair/wood{ + dir = 8 }, -/turf/simulated/floor/grass, -/area/hydroponics/cafegarden) +/obj/structure/extinguisher_cabinet{ + dir = 8; + icon_state = "extinguisher_closed"; + pixel_x = 30 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/surface_three_hall) +"aoO" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"aoP" = ( +/obj/machinery/atmospherics/pipe/simple/visible/yellow{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/steel/techfloor_grid, +/area/rnd/xenobiology/xenoflora_storage) "aoQ" = ( /obj/structure/table/reinforced, /obj/machinery/cell_charger, @@ -7917,14 +8579,12 @@ /turf/simulated/floor/tiled, /area/rnd/research/testingrange) "aoR" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/window/reinforced{ - dir = 4 +/obj/structure/catwalk, +/obj/machinery/atmospherics/binary/passive_gate{ + dir = 1 }, -/turf/simulated/floor/plating, -/area/hydroponics/cafegarden) +/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/area/tether/surfacebase/outside/outside3) "aoS" = ( /obj/effect/floor_decal/spline/plain{ dir = 10 @@ -8007,6 +8667,15 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"apa" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/obj/machinery/alarm{ + pixel_y = 22 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "apb" = ( /obj/structure/cable{ icon_state = "4-8" @@ -8032,6 +8701,16 @@ "apc" = ( /turf/simulated/wall, /area/vacant/vacant_shop) +"apd" = ( +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/visible/yellow{ + dir = 4 + }, +/obj/structure/catwalk, +/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/area/tether/surfacebase/outside/outside3) "ape" = ( /obj/structure/cable{ icon_state = "4-8" @@ -8095,34 +8774,59 @@ /turf/simulated/floor/tiled/techfloor, /area/vacant/vacant_shop) "aph" = ( -/obj/machinery/firealarm{ +/obj/structure/disposalpipe/segment{ dir = 8; - pixel_x = -24 + icon_state = "pipe-c" }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) "api" = ( -/obj/machinery/light_switch{ - pixel_x = 25 +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5; + icon_state = "intact-supply" + }, +/obj/machinery/appliance/cooker/grill, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 5; + icon_state = "warning_dust" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "apj" = ( -/obj/machinery/alarm{ - dir = 4; - icon_state = "alarm0"; - pixel_x = -22; - pixel_y = 0 - }, -/turf/simulated/floor/grass, -/area/hydroponics/cafegarden) +/obj/machinery/portable_atmospherics/canister/phoron, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "apk" = ( -/turf/simulated/floor/grass, -/area/hydroponics/cafegarden) +/obj/machinery/portable_atmospherics/canister/phoron, +/obj/effect/floor_decal/industrial/warning{ + dir = 4; + icon_state = "warning" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "apl" = ( -/obj/structure/flora/ausbushes/ppflowers, -/turf/simulated/floor/grass, -/area/hydroponics/cafegarden) +/obj/machinery/atmospherics/portables_connector{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "apm" = ( /obj/effect/floor_decal/spline/plain{ dir = 8 @@ -8399,24 +9103,35 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "apF" = ( -/obj/machinery/light{ - dir = 8; - icon_state = "tube1" +/obj/machinery/atmospherics/portables_connector{ + dir = 1 }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/mauve/border, +/obj/machinery/camera/network/research{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "apG" = ( -/obj/machinery/light{ - dir = 4; - icon_state = "tube1" +/obj/structure/table/glass, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/mauve/border, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/machinery/alarm{ + dir = 1; + pixel_y = -22 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "apH" = ( -/obj/structure/flora/ausbushes/lavendergrass, -/obj/structure/flora/ausbushes/ppflowers, -/turf/simulated/floor/grass, -/area/hydroponics/cafegarden) +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "apI" = ( /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled/freezer, @@ -8505,6 +9220,22 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"apP" = ( +/obj/structure/table/glass, +/obj/effect/floor_decal/borderfloor{ + dir = 6 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 6 + }, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/machinery/light_switch{ + pixel_x = 25 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "apQ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -8685,6 +9416,10 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"aqe" = ( +/obj/machinery/portable_atmospherics/hydroponics/soil, +/turf/simulated/floor/grass, +/area/hydroponics) "aqf" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -8773,65 +9508,44 @@ /turf/simulated/floor/tiled/techfloor, /area/vacant/vacant_shop) "aql" = ( -/obj/machinery/power/apc{ - cell_type = /obj/item/weapon/cell/super; - dir = 8; - name = "west bump"; - pixel_x = -30 +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 }, -/obj/structure/cable/green{ - icon_state = "0-4" +/obj/machinery/firealarm{ + dir = 2; + layer = 3.3; + pixel_x = 4; + pixel_y = 26 }, -/obj/machinery/button/remote/blast_door{ - id = "freezer"; - name = "Freezer shutters"; - pixel_x = -24; - pixel_y = -24 - }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aqm" = ( -/obj/machinery/atmospherics/unary/vent_pump/on, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/machinery/beehive, +/turf/simulated/floor/grass, +/area/hydroponics) "aqn" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on, -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" +/obj/machinery/light{ + dir = 1 }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "aqo" = ( -/obj/machinery/gibber, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "aqp" = ( -/obj/machinery/power/apc{ - cell_type = /obj/item/weapon/cell/super; - dir = 8; - name = "west bump"; - pixel_x = -30 - }, -/obj/structure/cable/green{ - icon_state = "0-4" - }, +/obj/machinery/portable_atmospherics/hydroponics, /turf/simulated/floor/grass, -/area/hydroponics/cafegarden) +/area/hydroponics) "aqq" = ( -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, +/obj/structure/flora/ausbushes/fullgrass, /turf/simulated/floor/grass, -/area/hydroponics/cafegarden) +/area/hydroponics) "aqr" = ( /obj/structure/bed/chair{ dir = 4 @@ -9212,12 +9926,6 @@ /turf/simulated/wall, /area/tether/surfacebase/surface_three_hall) "aqU" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 4 - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 9 }, @@ -9227,52 +9935,82 @@ /obj/machinery/newscaster{ pixel_x = 25 }, +/obj/effect/floor_decal/borderfloor/corner{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lightgrey/bordercorner{ + dir = 4 + }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "aqV" = ( -/obj/structure/closet/secure_closet/freezer/meat, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) -"aqW" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 5 - }, -/obj/machinery/icecream_vat, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) -"aqX" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) -"aqY" = ( -/obj/machinery/chem_master/condimaster, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) -"aqZ" = ( /obj/structure/flora/ausbushes/sparsegrass, -/obj/structure/flora/ausbushes/ywflowers, /turf/simulated/floor/grass, -/area/hydroponics/cafegarden) +/area/hydroponics) +"aqW" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 9 + }, +/obj/structure/closet/secure_closet/hydroponics/sci{ + req_access = list(77) + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"aqX" = ( +/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/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"aqY" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/effect/floor_decal/corner/grey/diagonal, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"aqZ" = ( +/obj/structure/closet/firecloset, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "ara" = ( +/obj/structure/closet/l3closet/scientist, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"arb" = ( +/obj/machinery/door/firedoor, /obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/turf/simulated/floor/grass, -/area/hydroponics/cafegarden) -"arb" = ( -/obj/structure/flora/ausbushes/pointybush, -/turf/simulated/floor/grass, -/area/hydroponics/cafegarden) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/door/airlock/glass_research{ + name = "Xenoflora Research"; + req_one_access = list(77) + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "arc" = ( /obj/structure/table/glass, /obj/effect/floor_decal/spline/plain{ @@ -9391,77 +10129,108 @@ /turf/simulated/floor/outdoors/grass/sif/virgo3b, /area/tether/surfacebase/outside/outside3) "aro" = ( -/obj/effect/floor_decal/spline/plain{ - dir = 4 - }, -/obj/effect/floor_decal/spline/plain{ +/obj/structure/disposalpipe/segment{ dir = 8 }, -/obj/machinery/media/jukebox, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "arp" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 }, -/obj/machinery/door/airlock/maintenance/int{ - name = "Fire/Phoron Shelter" +/obj/item/device/radio/intercom{ + dir = 1; + pixel_y = 24; + req_access = list() }, -/turf/simulated/floor/tiled/techfloor, -/area/vacant/vacant_shop) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "arq" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/machinery/door/blast/shutters{ - density = 0; - dir = 2; - icon_state = "shutter0"; - id = "freezer"; - name = "Freezer Shutters"; - opacity = 0 +/obj/structure/disposalpipe/segment{ + dir = 8 }, -/turf/simulated/floor/plating, -/area/crew_quarters/freezer) +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "arr" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/machinery/door/airlock/freezer{ - name = "Kitchen cold room"; - req_access = list(28) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "ars" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/turf/simulated/floor/plating, -/area/crew_quarters/kitchen) -"art" = ( -/obj/machinery/door/firedoor/glass, +/obj/machinery/portable_atmospherics/hydroponics, /obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/machinery/door/airlock/glass{ - name = "Garden"; - req_access = list(28) +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"art" = ( +/obj/machinery/portable_atmospherics/hydroponics, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "aru" = ( /turf/simulated/wall, /area/crew_quarters/kitchen) @@ -9479,12 +10248,27 @@ /turf/simulated/floor/tiled/freezer, /area/crew_quarters/pool) "arx" = ( -/obj/structure/table/marble, -/obj/machinery/chemical_dispenser/bar_soft/full{ - dir = 1 +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 8 }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/airlock/glass_research{ + name = "Xenoflora Research"; + req_one_access = list(77) + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "ary" = ( /obj/effect/floor_decal/spline/plain, /obj/machinery/light, @@ -9567,171 +10351,125 @@ /turf/simulated/floor/tiled/monotile, /area/tether/surfacebase/surface_three_hall) "arG" = ( -/obj/effect/floor_decal/borderfloor/corner{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/corner/lightgrey/bordercorner{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 1 }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "arH" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 1 - }, -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 2 +/obj/machinery/vending/hydronutrients, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 5 }, /turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) +/area/rnd/xenobiology/xenoflora) "arI" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 5 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 5 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/machinery/alarm{ - dir = 8; - icon_state = "alarm0"; - pixel_x = 24 +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 1 }, -/obj/machinery/firealarm{ - dir = 2; - layer = 3.3; - pixel_x = 0; - pixel_y = 26 +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 6 }, /turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) +/area/rnd/xenobiology/xenoflora_storage) "arJ" = ( /turf/simulated/wall, /area/crew_quarters/bar) "arK" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" + d1 = 2; + d2 = 4; + icon_state = "2-4" }, -/obj/machinery/light/small{ - dir = 8 - }, -/obj/structure/sign/fire{ - name = "\improper PHORON/FIRE SHELTER"; - pixel_x = -32; - pixel_y = 32 - }, -/obj/structure/closet/hydrant{ - pixel_x = -32 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/grass, +/area/hydroponics) "arL" = ( -/obj/structure/table/bench/wooden, -/obj/machinery/firealarm{ - dir = 2; - layer = 3.3; - pixel_x = 0; - pixel_y = 26 +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 1 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/plating, +/area/rnd/xenobiology/xenoflora) "arM" = ( -/obj/structure/table/bench/wooden, -/obj/machinery/alarm{ - pixel_y = 22 - }, -/obj/machinery/camera/network/civilian{ - dir = 9 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"arN" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/closet/chefcloset, -/obj/item/glass_jar, -/obj/item/device/retail_scanner/civilian, -/obj/item/weapon/soap/nanotrasen, +/obj/structure/table/woodentable, +/obj/effect/floor_decal/corner/lime/border, +/obj/machinery/light, +/obj/item/weapon/packageWrap, /obj/item/device/destTagger{ pixel_x = 4; pixel_y = 3 }, -/obj/item/weapon/packageWrap, -/obj/item/weapon/packageWrap, -/obj/item/weapon/packageWrap, -/obj/machinery/light_switch{ - pixel_x = -25 +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"arN" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 6 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/turf/simulated/floor/tiled/techfloor, +/area/hydroponics) "arO" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/portable_atmospherics/hydroponics, /obj/structure/cable/green{ d1 = 1; - d2 = 2; - icon_state = "1-2" + d2 = 8; + icon_state = "1-8" }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "arP" = ( -/obj/structure/table/standard, -/obj/machinery/microwave, -/obj/machinery/newscaster{ - pixel_x = 0; - pixel_y = 30 +/obj/machinery/portable_atmospherics/hydroponics, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "arQ" = ( -/obj/structure/table/standard, -/obj/machinery/microwave, -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/firealarm{ - dir = 2; - layer = 3.3; - pixel_x = 0; - pixel_y = 26 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "arR" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/turf/simulated/floor/grass, +/area/hydroponics) "arS" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" +/obj/machinery/portable_atmospherics/hydroponics, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 5 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "arT" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/closet/secure_closet/freezer/meat, -/obj/machinery/alarm{ - dir = 8; - icon_state = "alarm0"; - pixel_x = 24 +/obj/machinery/seed_extractor, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "arU" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -9752,6 +10490,30 @@ "arW" = ( /turf/simulated/wall, /area/tether/surfacebase/public_garden_three) +"arX" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 10 + }, +/obj/structure/closet/secure_closet/hydroponics/sci{ + req_access = list(77) + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"arY" = ( +/obj/structure/closet/firecloset, +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"arZ" = ( +/obj/structure/railing{ + dir = 1; + icon_state = "railing0" + }, +/obj/structure/railing{ + dir = 8 + }, +/turf/simulated/open/virgo3b, +/area/tether/surfacebase/outside/outside3) "asa" = ( /obj/machinery/computer/rdconsole/robotics{ dir = 8 @@ -9795,14 +10557,19 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "asd" = ( -/obj/machinery/light{ - dir = 1 +/obj/structure/sign/biohazard{ + pixel_y = 32 }, +/obj/structure/flora/pottedplant/crystal, /obj/effect/floor_decal/borderfloorblack{ dir = 1 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/camera/network/research/xenobio, /turf/simulated/floor/tiled, -/area/rnd/outpost/xenobiology/outpost_north_airlock) +/area/rnd/outpost/xenobiology/outpost_hallway) "ase" = ( /obj/structure/disposalpipe/segment{ dir = 8; @@ -9826,52 +10593,50 @@ /turf/simulated/floor/tiled, /area/rnd/outpost/xenobiology/outpost_north_airlock) "ash" = ( -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) -"asi" = ( /obj/effect/floor_decal/borderfloor{ - dir = 4 + dir = 1 }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/machinery/light{ - dir = 4; - icon_state = "tube1" +/obj/effect/floor_decal/industrial/danger{ + dir = 1 }, +/obj/machinery/camera/network/research, /turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) +/area/rnd/xenobiology/xenoflora_storage) +"asi" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/simulated/floor/plating, +/area/hydroponics) "asj" = ( -/obj/machinery/atm{ - pixel_x = -30 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/sign/botany, +/obj/structure/window/reinforced{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" +/obj/structure/window/reinforced{ + dir = 4 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/structure/window/reinforced, +/turf/simulated/floor/plating, +/area/hydroponics) "ask" = ( -/obj/structure/table/woodentable, -/obj/machinery/atmospherics/unary/vent_pump/on{ +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 8 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "asl" = ( /obj/machinery/recharge_station, /obj/effect/floor_decal/industrial/warning/corner{ @@ -9880,68 +10645,73 @@ /turf/simulated/floor/tiled/steel_grid, /area/assembly/chargebay) "asm" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/closet/secure_closet/freezer/fridge, -/obj/structure/extinguisher_cabinet{ - dir = 4; - icon_state = "extinguisher_closed"; - pixel_x = -30 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/structure/closet/l3closet/scientist, +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "asn" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/effect/floor_decal/corner/mauve/border, +/obj/machinery/firealarm{ + dir = 1; + pixel_x = 0; + pixel_y = -24 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"aso" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"asp" = ( /obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/obj/effect/landmark/start{ - name = "Chef" - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) -"aso" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) -"asp" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) -"asq" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) -"asr" = ( -/obj/structure/bed/chair/comfy{ +/obj/structure/disposalpipe/segment{ dir = 8 }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) +/turf/simulated/floor/grass, +/area/hydroponics) +"asq" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"asr" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "ass" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -9973,6 +10743,39 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"asu" = ( +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) +"asv" = ( +/obj/effect/floor_decal/corner/mauve/bordercorner{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"asw" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/alarm{ + pixel_y = 25 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"asx" = ( +/obj/machinery/power/apc{ + cell_type = /obj/item/weapon/cell/super; + dir = 1; + name = "north bump"; + pixel_x = 0; + pixel_y = 24 + }, +/obj/structure/cable/green{ + icon_state = "0-2" + }, +/obj/structure/flora/ausbushes/ppflowers, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) "asy" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -10017,136 +10820,170 @@ }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/triage) -"asF" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/disposalpipe/segment{ - dir = 4 +"asB" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 1 }, -/turf/simulated/floor/plating, +/turf/simulated/floor/lino, /area/crew_quarters/bar) -"asG" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" +"asC" = ( +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"asD" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor/glass, +/obj/effect/floor_decal/spline/plain{ + dir = 5 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"asH" = ( -/obj/structure/table/bench/wooden, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"asI" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/blast/shutters{ - dir = 8; - id = "kitchen"; - layer = 3.1; - name = "Kitchen Shutters" - }, -/turf/simulated/floor/plating, -/area/crew_quarters/kitchen) -"asJ" = ( -/obj/effect/floor_decal/corner/grey/diagonal{ - dir = 4 +/obj/item/weapon/reagent_containers/food/condiment/small/peppermill{ + pixel_x = 3 }, /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/structure/table/standard, -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/machinery/door/blast/shutters{ + dir = 1; + id = "kitchen2"; + layer = 3.3; + name = "Kitchen Shutters" }, /turf/simulated/floor/tiled/white, /area/crew_quarters/kitchen) -"asK" = ( -/obj/effect/floor_decal/corner/grey/diagonal, +"asE" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"asF" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 10 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"asG" = ( +/obj/machinery/door/airlock/glass{ + name = "Hydroponics Break Room"; + req_one_access = list(35,28) + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"asH" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"asI" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment{ +/obj/structure/flora/ausbushes/ppflowers, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) +"asJ" = ( +/obj/effect/floor_decal/corner/mauve/border{ dir = 4 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"asK" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "asL" = ( -/obj/structure/table/standard, /obj/effect/floor_decal/corner/grey/diagonal, -/obj/item/weapon/book/manual/chef_recipes, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 8 +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 1 }, -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/structure/closet/secure_closet/freezer/fridge, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, /turf/simulated/floor/tiled/white, /area/crew_quarters/kitchen) "asM" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/item/weapon/reagent_containers/food/condiment/enzyme{ - layer = 5 +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/item/weapon/reagent_containers/dropper, -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/firealarm{ + dir = 2; + layer = 3.3; + pixel_x = 0; + pixel_y = 26 }, /turf/simulated/floor/tiled/white, /area/crew_quarters/kitchen) "asN" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" +/obj/machinery/alarm{ + pixel_y = 25 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/structure/flora/ausbushes/ppflowers, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) "asO" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) -"asP" = ( -/obj/machinery/cooker/grill, -/obj/effect/floor_decal/industrial/warning/dust{ - dir = 9 +/obj/structure/flora/ausbushes/lavendergrass, +/obj/structure/flora/ausbushes/ppflowers, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) -"asQ" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/window/reinforced{ +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/turf/simulated/floor/plating, -/area/crew_quarters/kitchen) +/turf/simulated/floor/grass, +/area/hydroponics) +"asP" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"asQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "asR" = ( /obj/effect/floor_decal/borderfloor{ dir = 10 @@ -10178,162 +11015,179 @@ "asT" = ( /turf/simulated/wall/r_wall, /area/bridge) -"asV" = ( -/obj/machinery/door/airlock/glass, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled/steel_grid, -/area/crew_quarters/bar) -"asW" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" +"asU" = ( +/obj/machinery/door/airlock/maintenance/int{ + name = "Fire/Phoron Shelter"; + req_one_access = list() }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/techfloor/grid, +/area/hydroponics) +"asV" = ( +/obj/structure/flora/ausbushes/lavendergrass, +/obj/structure/flora/ausbushes/ywflowers, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"asW" = ( +/obj/structure/table/standard{ + name = "plastic table frame" + }, +/obj/item/weapon/reagent_containers/glass/bucket, +/obj/item/weapon/material/minihoe, +/obj/item/weapon/storage/box/botanydisk, +/obj/item/weapon/storage/box/botanydisk, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "asX" = ( /turf/simulated/floor/wood, /area/crew_quarters/bar) "asY" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/machinery/door/blast/shutters{ - dir = 8; - id = "kitchen"; - layer = 3.1; - name = "Kitchen Shutters" +/obj/machinery/light{ + dir = 4 }, -/turf/simulated/floor/plating, -/area/crew_quarters/kitchen) +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) "asZ" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/table/standard, -/obj/item/weapon/material/kitchen/rollingpin, -/obj/item/weapon/material/knife/butch, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/effect/floor_decal/spline/plain{ + dir = 8 + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "ata" = ( -/obj/structure/table/standard, -/obj/machinery/reagentgrinder, -/obj/machinery/light{ - dir = 4; - icon_state = "tube1"; - pixel_x = 0 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) -"atb" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/light{ - dir = 8; - icon_state = "tube1"; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) -"atc" = ( -/obj/machinery/cooker/candy, -/obj/effect/floor_decal/industrial/warning/dust{ - dir = 8 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) -"ate" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) -"atg" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/sign/department/bar, -/turf/simulated/floor/plating, -/area/crew_quarters/bar) -"ath" = ( -/obj/structure/disposalpipe/junction{ - dir = 8; - icon_state = "pipe-j2" - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"ati" = ( -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"atj" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/vending/dinnerware{ - dir = 4 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) -"atk" = ( -/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ +/turf/simulated/floor/grass, +/area/hydroponics) +"atb" = ( +/turf/simulated/wall, +/area/hydroponics/cafegarden) +"atc" = ( +/obj/effect/floor_decal/borderfloor/corner, +/obj/effect/floor_decal/corner/lightgrey/bordercorner, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 8 }, /obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" + d1 = 2; + d2 = 4; + icon_state = "2-4" }, -/obj/effect/landmark/start{ - name = "Chef" +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"atd" = ( +/obj/structure/catwalk, +/obj/machinery/atmospherics/pipe/manifold/visible/yellow, +/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/area/tether/surfacebase/outside/outside3) +"ate" = ( +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"atf" = ( +/obj/machinery/appliance/cooker/fryer, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 4; + icon_state = "warning_dust" }, /turf/simulated/floor/tiled/white, /area/crew_quarters/kitchen) -"atl" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/item/weapon/packageWrap, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ +"atg" = ( +/obj/structure/sink{ + dir = 8; + icon_state = "sink"; + pixel_x = -12; + pixel_y = 2 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"ath" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/vending/hydronutrients{ + dir = 8; + icon_state = "nutri_generic" + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"ati" = ( +/obj/structure/flora/ausbushes/pointybush, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) +"atj" = ( +/obj/machinery/botany/editor, +/obj/effect/floor_decal/corner/mauve/border{ dir = 8 }, -/turf/simulated/floor/tiled/white, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"atk" = ( +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/obj/machinery/biogenerator, +/turf/simulated/floor/grass, +/area/hydroponics) +"atl" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/turf/simulated/floor/plating, /area/crew_quarters/kitchen) "atm" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/sink/kitchen{ - pixel_y = 28 +/obj/machinery/portable_atmospherics/hydroponics, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 10 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "atn" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/item/weapon/reagent_containers/food/snacks/mint, -/obj/item/weapon/storage/box/donkpockets{ - pixel_x = 3; - pixel_y = 3 +/obj/structure/extinguisher_cabinet{ + dir = 8; + icon_state = "extinguisher_closed"; + pixel_x = 30 }, -/obj/item/weapon/reagent_containers/glass/beaker{ - pixel_x = 5 +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/smartfridge/drying_rack{ + dir = 8; + icon_state = "drying_rack" }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/turf/simulated/floor/grass, +/area/hydroponics) "ato" = ( -/obj/machinery/cooker/cereal, -/obj/effect/floor_decal/industrial/warning/dust{ - dir = 8 +/obj/effect/floor_decal/spline/plain{ + dir = 4 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/machinery/smartfridge/drinks, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) "atp" = ( /obj/structure/bed/chair/office/dark, /obj/effect/landmark/start{ @@ -10388,16 +11242,54 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/captain) -"atz" = ( -/obj/machinery/smartfridge{ - req_access = list(28) +"atv" = ( +/obj/machinery/portable_atmospherics/hydroponics, +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"atw" = ( +/obj/machinery/camera/network/outside{ + dir = 5; + icon_state = "camera" }, -/turf/simulated/wall, -/area/crew_quarters/kitchen) -"atA" = ( -/obj/machinery/cooker/fryer, +/obj/machinery/appliance/cooker/oven, /obj/effect/floor_decal/industrial/warning/dust{ - dir = 8 + dir = 4; + icon_state = "warning_dust" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"atx" = ( +/obj/machinery/portable_atmospherics/hydroponics, +/obj/effect/floor_decal/corner/mauve/border, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"aty" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) +"atz" = ( +/obj/machinery/portable_atmospherics/hydroponics, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 6 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"atA" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, /turf/simulated/floor/tiled/white, /area/crew_quarters/kitchen) @@ -10456,111 +11348,111 @@ }, /turf/simulated/floor/tiled/dark, /area/bridge_hallway) -"atN" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 +"atJ" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, /obj/structure/cable/green{ d1 = 1; d2 = 4; icon_state = "1-4" }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"atO" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ +/obj/structure/table/standard, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"atK" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/item/weapon/reagent_containers/glass/bucket, +/obj/effect/floor_decal/corner/mauve/border{ dir = 4 }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"atL" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; icon_state = "4-8" }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"atP" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/small/peppermill{ + pixel_x = 3 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/freezer{ - name = "Kitchen"; - req_access = list(28) +/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{ + pixel_x = -3; + pixel_y = 0 }, /turf/simulated/floor/tiled/white, /area/crew_quarters/kitchen) -"atQ" = ( +"atM" = ( +/obj/structure/table/standard, +/obj/machinery/microwave, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"atN" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 6 + }, +/obj/machinery/vending/boozeomat, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"atO" = ( /obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/effect/landmark/start{ + name = "Chef" }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"atP" = ( /obj/machinery/button/remote/blast_door{ id = "kitchen"; name = "Kitchen shutters"; pixel_x = -24; pixel_y = -24 }, +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/obj/machinery/appliance/mixer/cereal, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 4; + icon_state = "warning_dust" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"atQ" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/table/standard, +/obj/item/weapon/material/knife/butch, +/obj/item/weapon/material/kitchen/rollingpin, /turf/simulated/floor/tiled/white, /area/crew_quarters/kitchen) "atR" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9 - }, /obj/structure/cable/green{ d1 = 1; - d2 = 8; - icon_state = "1-8" + d2 = 2; + icon_state = "1-2" }, -/obj/machinery/power/apc{ - dir = 2; - name = "south bump"; - pixel_y = -28 - }, -/obj/structure/cable/green{ - icon_state = "0-8" - }, -/obj/machinery/camera/network/civilian{ - dir = 1 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/turf/simulated/floor/grass, +/area/hydroponics) "atS" = ( -/obj/machinery/cooker/oven, -/obj/effect/floor_decal/industrial/warning/dust{ - dir = 10 +/obj/machinery/botany/extractor, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "atT" = ( /turf/simulated/wall/r_wall, /area/rnd/research) @@ -10720,39 +11612,23 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "aui" = ( -/obj/effect/floor_decal/borderfloor{ +/obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 4 }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/machinery/light{ - dir = 4; - icon_state = "tube1" - }, /turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) +/area/rnd/xenobiology/xenoflora) "auj" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/computer/guestpass{ - dir = 4; - pixel_x = -28; - pixel_y = 0 +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/machinery/camera/network/tether, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "auk" = ( -/obj/structure/table/bench/wooden, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/grass, +/area/hydroponics) "aul" = ( /obj/effect/floor_decal/borderfloorblack{ dir = 4 @@ -10764,52 +11640,43 @@ /turf/simulated/floor/tiled, /area/rnd/outpost/xenobiology/outpost_hallway) "aum" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/door/blast/shutters{ - dir = 2; - id = "kitchen"; - layer = 3.3; - name = "Kitchen Shutters" +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5; + icon_state = "intact-scrubbers" }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) "aun" = ( -/obj/structure/table/reinforced, -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/chemical_dispenser/bar_soft/full, -/obj/machinery/door/blast/shutters{ - dir = 2; - id = "kitchen"; - layer = 3.3; - name = "Kitchen Shutters" +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5; + icon_state = "intact-supply" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "auo" = ( -/obj/machinery/door/blast/shutters{ - dir = 2; - id = "kitchen"; - layer = 3.3; - name = "Kitchen Shutters" +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 8 }, -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "aup" = ( -/obj/structure/table/reinforced, -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/machinery/door/blast/shutters{ - dir = 2; - id = "kitchen"; - layer = 3.3; - name = "Kitchen Shutters" +/obj/structure/reagent_dispensers/watertank, +/obj/item/weapon/reagent_containers/glass/bucket, +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "auq" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ @@ -10930,6 +11797,13 @@ "aux" = ( /turf/simulated/floor/holofloor/tiled/dark, /area/tether/elevator) +"auy" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/obj/machinery/camera/network/research, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "auz" = ( /obj/item/device/radio/intercom{ dir = 1; @@ -11088,72 +11962,80 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "auL" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/beige/border, -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 1 +/obj/structure/sink{ + dir = 4; + icon_state = "sink"; + pixel_x = 11; + pixel_y = 0 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 }, /turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) +/area/rnd/xenobiology/xenoflora) "auM" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 6 - }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 6 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/structure/closet/firecloset, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) -"auN" = ( +/obj/machinery/botany/extractor, /obj/machinery/light{ dir = 8; icon_state = "tube1" }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ +/obj/effect/floor_decal/corner/mauve/border{ dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, -/obj/item/device/radio/intercom{ - dir = 8; - pixel_x = -24 +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"auN" = ( +/obj/structure/table/glass, +/obj/item/weapon/storage/box/gloves{ + pixel_x = 4; + pixel_y = 4 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/item/weapon/storage/box/syringes, +/obj/item/weapon/storage/box/beakers{ + pixel_x = 2; + pixel_y = 2 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "auO" = ( -/obj/structure/table/woodentable, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 +/obj/structure/bed/chair/wood, +/obj/effect/floor_decal/borderfloor{ + dir = 4 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "auP" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill{ - pixel_x = 3 +/obj/structure/bed/chair/office/light, +/obj/effect/landmark/start{ + name = "Xenobotanist" }, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{ - pixel_x = -3; - pixel_y = 0 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "auQ" = ( -/obj/structure/table/marble, -/obj/effect/floor_decal/spline/plain{ - dir = 8 +/obj/structure/table/woodentable, +/obj/effect/floor_decal/borderfloor{ + dir = 4 }, -/obj/machinery/recharger, -/obj/machinery/camera/network/civilian, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "auR" = ( -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/rnd/xenobiology/xenoflora) "auS" = ( /obj/effect/floor_decal/corner/lightgrey{ dir = 9 @@ -11171,16 +12053,18 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "auT" = ( -/obj/machinery/hologram/holopad, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/obj/structure/table/glass, +/obj/machinery/chemical_dispenser/xenoflora/full, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "auU" = ( -/obj/machinery/light{ - dir = 4; - icon_state = "tube1" +/obj/structure/disposalpipe/segment{ + dir = 8 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/grass, +/area/hydroponics) "auV" = ( /obj/structure/railing{ dir = 4 @@ -11229,6 +12113,92 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"avb" = ( +/obj/structure/table/glass, +/obj/item/weapon/storage/box/beakers{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/weapon/storage/box/syringes, +/obj/item/weapon/storage/box/gloves{ + pixel_x = 4; + pixel_y = 4 + }, +/obj/effect/floor_decal/corner/mauve/bordercorner, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"avc" = ( +/obj/machinery/smartfridge/drying_rack, +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"avd" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/crew_quarters/kitchen) +"ave" = ( +/obj/machinery/biogenerator, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 6 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"avf" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ + dir = 4; + icon_state = "extinguisher_closed"; + pixel_x = -30 + }, +/obj/machinery/camera/network/research{ + dir = 5; + icon_state = "camera" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"avg" = ( +/obj/machinery/computer/security/telescreen/entertainment{ + desc = "Damn, looks like it's on the clown world channel. I wonder what else is on?"; + icon_state = "frame"; + pixel_x = 0; + pixel_y = 32 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"avh" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 10 + }, +/obj/machinery/alarm{ + alarm_id = "pen_nine"; + breach_detection = 0; + dir = 1; + icon_state = "alarm0"; + pixel_y = -22 + }, +/obj/structure/table/woodentable, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"avi" = ( +/obj/effect/floor_decal/corner/lime/border, +/obj/machinery/firealarm{ + dir = 1; + pixel_x = 0; + pixel_y = -24 + }, +/obj/item/weapon/stool/padded, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "avj" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -11245,6 +12215,15 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"avk" = ( +/obj/machinery/atmospherics/pipe/tank/phoron{ + dir = 8; + icon_state = "phoron_map"; + name = "Xenoflora Waste Buffer"; + start_pressure = 0 + }, +/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/area/tether/surfacebase/outside/outside3) "avl" = ( /obj/structure/bed/chair/comfy/brown{ dir = 8 @@ -11260,6 +12239,20 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/captain) +"avm" = ( +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "kitchen"; + layer = 3.3; + name = "Kitchen Shutters" + }, +/obj/machinery/door/firedoor/glass, +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/obj/structure/table/reinforced, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "avn" = ( /obj/structure/cable/green{ d1 = 1; @@ -11281,28 +12274,41 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "avo" = ( -/obj/structure/sign/directions/evac{ - dir = 8 +/obj/structure/table/reinforced, +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "kitchen"; + layer = 3.3; + name = "Kitchen Shutters" }, -/turf/simulated/wall, -/area/crew_quarters/bar) -"avp" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"avq" = ( -/obj/structure/table/marble, +/obj/machinery/door/firedoor/glass, /obj/effect/floor_decal/spline/plain{ - dir = 8 + dir = 1 }, /turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/area/crew_quarters/kitchen) +"avp" = ( +/obj/machinery/door/firedoor, +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/turf/simulated/floor/plating, +/area/crew_quarters/kitchen) +"avq" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/grass, +/area/hydroponics) "avr" = ( -/obj/structure/table/marble, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/turf/simulated/floor/grass, +/area/hydroponics) "avs" = ( /obj/effect/floor_decal/borderfloorblack{ dir = 1 @@ -11358,12 +12364,60 @@ }, /turf/simulated/floor/tiled/steel_grid, /area/rnd/research) +"avy" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/turf/simulated/wall, +/area/crew_quarters/kitchen) +"avz" = ( +/obj/item/weapon/stool/padded, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"avA" = ( +/obj/item/weapon/stool/padded, +/obj/effect/floor_decal/corner/beige{ + dir = 6; + icon_state = "corner_white" + }, +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/machinery/computer/guestpass{ + dir = 8; + pixel_x = 25 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"avB" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/floor_decal/corner/mauve/bordercorner, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "avC" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"avD" = ( +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/obj/machinery/appliance/mixer/candy, +/obj/effect/floor_decal/industrial/warning/dust{ + dir = 6; + icon_state = "warning_dust" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"avE" = ( +/obj/structure/table/glass, +/obj/machinery/reagentgrinder, +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "avF" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 @@ -11383,20 +12437,46 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "avH" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 }, -/obj/structure/disposalpipe/sortjunction{ - dir = 4; - icon_state = "pipe-j1s"; - name = "Hydroponics"; - sortType = "Hydroponics" +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/airlock/glass, +/obj/structure/disposalpipe/segment{ + dir = 4 }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"avI" = ( +/obj/machinery/chem_master, +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"avJ" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/obj/machinery/door/window/brigdoor/northleft{ + dir = 8; + icon_state = "leftsecure"; + name = "Bar"; + req_access = list(25) + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) "avK" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -11404,42 +12484,37 @@ /turf/simulated/floor/plating, /area/crew_quarters/bar) "avL" = ( -/obj/structure/table/bench/wooden, -/obj/structure/extinguisher_cabinet{ - pixel_y = 30 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/machinery/chem_master/condimaster, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "avM" = ( -/obj/structure/table/bench/wooden, -/obj/machinery/status_display{ - pixel_y = 30 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"avN" = ( /obj/effect/floor_decal/corner/beige{ - dir = 9 + dir = 10 }, -/obj/effect/floor_decal/spline/plain{ +/obj/effect/floor_decal/spline/plain, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"avN" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/honey_extractor, +/turf/simulated/floor/grass, +/area/hydroponics) +"avO" = ( +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"avP" = ( +/obj/structure/disposalpipe/segment{ dir = 8 }, -/obj/item/weapon/stool/padded, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) -"avO" = ( -/obj/item/weapon/stool/padded, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) -"avP" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/window/reinforced{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "avQ" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -11572,6 +12647,13 @@ /obj/machinery/hologram/holopad, /turf/simulated/floor/tiled, /area/rnd/outpost/xenobiology/outpost_north_airlock) +"awc" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "awd" = ( /obj/machinery/librarycomp{ pixel_y = 0 @@ -11675,6 +12757,9 @@ }, /turf/simulated/floor/tiled/white, /area/crew_quarters/captain) +"awm" = ( +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) "awn" = ( /turf/simulated/wall/r_wall, /area/bridge_hallway) @@ -11685,63 +12770,88 @@ /turf/simulated/floor/tiled/white, /area/crew_quarters/recreation_area_restroom) "awp" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lime/border, +/obj/effect/floor_decal/corner/lightgrey/border, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 1 }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 8 }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "awq" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lime/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ +/obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 8 }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) "awr" = ( -/obj/machinery/light, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lime/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"aws" = ( +/obj/machinery/light/small{ dir = 1 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ +/obj/structure/closet/secure_closet/bar{ + req_access = list(25) + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"awt" = ( +/obj/structure/closet/gmcloset{ + name = "formal wardrobe" + }, +/obj/item/glass_jar, +/obj/item/device/retail_scanner/civilian, +/obj/item/device/retail_scanner/civilian, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"awu" = ( +/obj/structure/table/glass, +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"awv" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/firealarm{ + dir = 1; + pixel_x = 0; + pixel_y = -25 + }, +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ dir = 8 }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) -"awu" = ( -/obj/structure/table/woodentable, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"awv" = ( -/obj/effect/floor_decal/corner/beige{ - dir = 10 - }, -/obj/effect/floor_decal/corner/beige{ - dir = 9 - }, -/obj/effect/floor_decal/spline/plain{ - dir = 10 - }, /turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/area/crew_quarters/kitchen) "aww" = ( -/obj/effect/floor_decal/corner/beige{ - dir = 10 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/obj/effect/floor_decal/spline/plain, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/obj/machinery/door/airlock/maintenance/int{ + name = "Fire/Phoron Shelter" + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/techfloor, +/area/vacant/vacant_shop) "awx" = ( /obj/structure/disposalpipe/segment, /obj/machinery/vending/fitness, @@ -11946,7 +13056,7 @@ id_tag = "SurfaceFoyer"; layer = 2.8; name = "Security"; - req_access = list(1) + req_access = list(63) }, /obj/machinery/door/blast/regular{ density = 0; @@ -11964,8 +13074,13 @@ /turf/simulated/floor/tiled/steel_grid, /area/tether/surfacebase/security/lobby) "awJ" = ( -/turf/simulated/wall, -/area/maintenance/lower/atrium) +/obj/machinery/reagentgrinder, +/obj/structure/table/glass, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 6 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "awK" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -12006,24 +13121,17 @@ /turf/simulated/floor/tiled/white, /area/crew_quarters/recreation_area_restroom) "awN" = ( -/obj/structure/sign/directions/medical{ - dir = 4; - pixel_y = 8 +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 1 }, -/obj/structure/sign/directions/science{ - dir = 8; - pixel_y = 3 +/obj/structure/window/reinforced{ + dir = 8 }, -/obj/structure/sign/directions/security{ - dir = 8; - pixel_y = -4 - }, -/obj/structure/sign/directions/engineering{ - dir = 8; - pixel_y = -10 - }, -/turf/simulated/wall, -/area/maintenance/lower/atrium) +/turf/simulated/floor/plating, +/area/rnd/xenobiology/xenoflora) "awO" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -12043,35 +13151,50 @@ /turf/simulated/wall, /area/hydroponics) "awQ" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/plating, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/turf/simulated/floor/grass, /area/hydroponics) "awR" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/turf/simulated/floor/plating, -/area/hydroponics) -"awS" = ( +/obj/structure/bed/chair/wood{ + dir = 1 + }, /obj/effect/floor_decal/borderfloor{ - dir = 8 + dir = 4 }, /obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"awS" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 8 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/glass, /turf/simulated/floor/tiled, -/area/hallway/lower/third_south) +/area/tether/surfacebase/surface_three_hall) +"awT" = ( +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) "awU" = ( /obj/structure/cable/green{ d1 = 1; @@ -12095,14 +13218,15 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "awV" = ( -/obj/structure/table/bench/wooden, -/obj/machinery/light{ +/obj/structure/table/woodentable, +/obj/item/weapon/reagent_containers/food/drinks/shaker, +/obj/machinery/alarm{ dir = 8; - icon_state = "tube1"; - pixel_y = 0 + icon_state = "alarm0"; + pixel_x = 24 }, /turf/simulated/floor/wood, -/area/crew_quarters/bar) +/area/tether/surfacebase/bar_backroom) "awW" = ( /obj/structure/disposalpipe/segment, /obj/machinery/alarm{ @@ -12298,128 +13422,97 @@ /turf/simulated/floor/tiled/steel_grid, /area/rnd/research) "axm" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced, +/turf/simulated/floor/plating, +/area/rnd/xenobiology/xenoflora) +"axn" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"axo" = ( +/obj/structure/bed/chair/comfy, +/obj/effect/landmark/start{ + name = "Bartender" + }, /obj/structure/disposalpipe/segment, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"axp" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/storage/box/beanbags, +/obj/item/weapon/gun/projectile/shotgun/doublebarrel, +/obj/item/weapon/paper{ + info = "This permit signifies that the Bartender is permitted to posess this firearm in the bar, and ONLY the bar. Failure to adhere to this permit will result in confiscation of the weapon and possibly arrest."; + name = "Shotgun permit" + }, +/obj/machinery/light_switch{ + pixel_x = 25 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"axq" = ( +/obj/machinery/camera/network/civilian{ + dir = 4 + }, +/turf/simulated/floor/grass, +/area/maintenance/lower/xenoflora) +"axr" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 10 + }, +/obj/machinery/smartfridge, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 10 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"axs" = ( +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"axt" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "kitchen"; + layer = 3.3; + name = "Kitchen Shutters" + }, +/obj/machinery/door/firedoor/glass, +/obj/effect/floor_decal/spline/plain{ + dir = 5 + }, +/obj/item/weapon/reagent_containers/food/condiment/small/peppermill{ + pixel_x = 3 + }, +/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{ + pixel_x = -3; pixel_y = 0 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) -"axn" = ( -/obj/machinery/floodlight, -/obj/machinery/alarm{ - dir = 8; - icon_state = "alarm0"; - pixel_x = 24 - }, -/obj/machinery/firealarm{ - dir = 2; - layer = 3.3; - pixel_x = 0; - pixel_y = 26 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) -"axo" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 9 - }, -/obj/structure/closet/secure_closet/hydroponics, -/obj/effect/floor_decal/corner/lime/border{ - dir = 9 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"axp" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 1 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/smartfridge, -/turf/simulated/floor/tiled, -/area/hydroponics) -"axq" = ( -/obj/machinery/honey_extractor, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"axr" = ( -/obj/machinery/smartfridge/drying_rack, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"axs" = ( -/obj/item/bee_pack, -/obj/item/honey_frame, -/obj/item/honey_frame, -/obj/item/honey_frame, -/obj/item/honey_frame, -/obj/item/honey_frame, -/obj/item/weapon/tool/crowbar, -/obj/item/bee_smoker, -/obj/item/beehive_assembly, -/obj/structure/closet/crate/hydroponics{ - desc = "All you need to start your own honey farm."; - name = "beekeeping crate" - }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"axt" = ( -/obj/machinery/vending/hydronutrients, -/obj/effect/floor_decal/borderfloor{ - dir = 5 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/obj/machinery/chemical_dispenser/bar_soft/full, +/obj/machinery/recharger, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "axu" = ( -/obj/structure/sign/directions/evac{ - dir = 1 - }, -/turf/simulated/wall, -/area/hydroponics) +/obj/structure/table/woodentable, +/obj/machinery/reagentgrinder, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) "axv" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) +/mob/living/simple_mob/animal/passive/cow, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) "axw" = ( /obj/structure/cable/green{ d1 = 1; @@ -12441,9 +13534,21 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "axx" = ( -/obj/structure/flora/pottedplant, +/obj/structure/table/woodentable, +/obj/item/weapon/flame/lighter/zippo, +/obj/item/clothing/head/that{ + pixel_x = 4; + pixel_y = 6 + }, +/obj/item/weapon/tool/screwdriver, +/obj/item/clothing/mask/smokable/cigarette/cigar/havana, +/obj/item/clothing/mask/smokable/cigarette/cigar/cohiba, /turf/simulated/floor/wood, -/area/crew_quarters/bar) +/area/tether/surfacebase/bar_backroom) +"axy" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) "axz" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 @@ -12704,16 +13809,25 @@ /turf/simulated/open, /area/rnd/staircase/thirdfloor) "axP" = ( -/obj/machinery/holoplant, -/obj/effect/floor_decal/borderfloorblack{ - dir = 8 +/obj/machinery/light{ + dir = 1 }, -/obj/machinery/camera/network/research{ - dir = 5; - icon_state = "camera" +/obj/effect/floor_decal/borderfloorblack{ + dir = 1 + }, +/obj/machinery/camera/network/research/xenobio, +/turf/simulated/floor/tiled, +/area/rnd/outpost/xenobiology/outpost_north_airlock) +"axQ" = ( +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 6 }, /turf/simulated/floor/tiled, -/area/rnd/outpost/xenobiology/outpost_hallway) +/area/rnd/xenobiology/xenoflora) "axR" = ( /obj/structure/disposalpipe/segment, /obj/effect/floor_decal/borderfloor{ @@ -12791,110 +13905,91 @@ /turf/simulated/floor/carpet, /area/tether/surfacebase/library/study) "axX" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ - icon_state = "1-8" +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 1 }, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2" +/obj/structure/window/reinforced{ + dir = 8; + icon_state = "rwindow" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, -/area/maintenance/lower/atrium) +/area/rnd/xenobiology/xenoflora) "axY" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"axZ" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 8; + icon_state = "spline_plain" }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 +/obj/item/weapon/stool/padded, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"aya" = ( /obj/machinery/alarm{ dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0 }, -/obj/structure/sink{ - dir = 8; - icon_state = "sink"; - pixel_x = -12; - pixel_y = 8 - }, -/obj/effect/landmark/start{ - name = "Gardener" - }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"axZ" = ( -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/tiled, -/area/hydroponics) -"aya" = ( -/turf/simulated/floor/tiled, -/area/hydroponics) +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) "ayb" = ( -/obj/effect/landmark/start{ - name = "Gardener" - }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) "ayc" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 +/obj/machinery/vending/wallmed1/public{ + pixel_y = 28 }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 4 +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"ayd" = ( +/obj/machinery/light/small{ + dir = 1 }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) "aye" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "ayf" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 +/obj/structure/table/marble, +/obj/machinery/door/blast/shutters{ + dir = 8; + id = "bar"; + layer = 3.3; + name = "Bar Shutters" }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/lino, /area/crew_quarters/bar) "ayg" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/wall/r_wall, +/area/tether/surfacebase/botanystorage) "ayh" = ( -/obj/structure/table/bench/wooden, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 +/obj/machinery/door/airlock{ + name = "Unit 3" }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) "ayi" = ( /obj/structure/disposalpipe/sortjunction{ name = "Research"; @@ -13107,47 +14202,43 @@ /turf/simulated/floor/tiled, /area/rnd/staircase/thirdfloor) "ayC" = ( -/obj/machinery/light{ - dir = 8; - icon_state = "tube1" +/obj/machinery/door/airlock{ + name = "Unit 2" }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) "ayD" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/structure/disposalpipe/segment, -/obj/effect/floor_decal/corner/green{ - dir = 10 +/obj/machinery/door/airlock{ + name = "Unit 1" }, -/obj/effect/floor_decal/corner/green{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) "ayE" = ( -/obj/effect/floor_decal/corner/green{ - dir = 5 +/obj/machinery/light/small{ + dir = 4; + pixel_y = 0 }, -/obj/effect/floor_decal/corner/green{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/obj/machinery/recharge_station, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) "ayF" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/effect/floor_decal/corner/green{ - dir = 10 +/obj/machinery/light/small{ + dir = 4; + pixel_y = 0 }, -/obj/effect/floor_decal/corner/green{ - dir = 5 +/obj/structure/toilet{ + dir = 1 }, -/turf/simulated/floor/tiled, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"ayG" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 8 + }, +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/turf/simulated/floor/grass, /area/hydroponics) "ayH" = ( /obj/structure/disposalpipe/segment, @@ -13175,49 +14266,32 @@ /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) "ayI" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 +/obj/effect/floor_decal/spline/plain{ + dir = 1 }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/grass, +/area/hydroponics) "ayJ" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/machinery/light/small{ + dir = 1 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) "ayK" = ( -/obj/structure/table/bench/wooden, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/machinery/door/airlock/glass_research{ + name = "Xenoflora Research"; + req_one_access = list(77) }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "ayL" = ( -/obj/structure/table/woodentable, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 - }, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill{ - pixel_x = 3 - }, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{ - pixel_x = -3; - pixel_y = 0 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/structure/bed/chair/wood, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "ayM" = ( -/obj/structure/table/woodentable, -/obj/machinery/computer/security/telescreen/entertainment{ - icon_state = "frame"; - pixel_x = 32; - pixel_y = 0 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/wall, +/area/tether/surfacebase/barbackmaintenance) "ayN" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 @@ -13632,19 +14706,15 @@ /turf/simulated/wall, /area/rnd/research/researchdivision) "azp" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/maintenance/common, /turf/simulated/floor/plating, -/area/maintenance/lower/atrium) +/area/rnd/xenobiology/xenoflora) "azq" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/mauve/border, @@ -13677,24 +14747,26 @@ /turf/simulated/floor/tiled, /area/rnd/outpost/xenobiology/outpost_breakroom) "azs" = ( -/obj/effect/floor_decal/borderfloor{ +/obj/structure/cable/green{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/floor_decal/corner/lime/border{ +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/lime/bordercorner2{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/turf/simulated/floor/lino, +/area/crew_quarters/bar) "azt" = ( -/obj/structure/sign/botany, -/turf/simulated/wall, -/area/hydroponics) +/obj/structure/sink{ + dir = 8; + icon_state = "sink"; + pixel_x = -12; + pixel_y = 0 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) "azu" = ( /obj/effect/floor_decal/borderfloorwhite, /obj/effect/floor_decal/corner/paleblue/border, @@ -13730,17 +14802,22 @@ /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) "azx" = ( -/obj/structure/table/bench/wooden, -/obj/machinery/light{ - dir = 4; - icon_state = "tube1" +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" }, -/obj/structure/extinguisher_cabinet{ - dir = 8; - icon_state = "extinguisher_closed"; - pixel_x = 30 +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/turf/simulated/floor/wood, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/lino, /area/crew_quarters/bar) "azy" = ( /obj/structure/disposalpipe/segment{ @@ -14006,83 +15083,66 @@ /turf/simulated/floor/wood, /area/library) "azX" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/servicebackroom) +"azY" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/botanystorage) +"azZ" = ( +/obj/structure/cable/green{ d1 = 1; d2 = 2; - icon_state = "1-2"; - pixel_y = 0 + icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/alarm{ - dir = 4; - icon_state = "alarm0"; - pixel_x = -22 - }, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) -"azY" = ( -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/machinery/power/apc{ - dir = 4; - name = "east bump"; - pixel_x = 28 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/floor_decal/rust, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) -"azZ" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/machinery/light_switch{ - pixel_x = -25 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/obj/structure/table/standard, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "aAa" = ( -/obj/machinery/atmospherics/unary/vent_pump/on, -/turf/simulated/floor/tiled, -/area/hydroponics) +/turf/simulated/wall/r_wall, +/area/tether/surfacebase/servicebackroom) "aAb" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 10 +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 1 }, -/obj/effect/floor_decal/steeldecal/steel_decals4, -/obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/turf/simulated/floor/plating, +/area/tether/surfacebase/servicebackroom) "aAc" = ( -/obj/machinery/door/firedoor/glass, +/obj/effect/floor_decal/spline/plain{ + dir = 10; + icon_state = "spline_plain" + }, /obj/structure/cable/green{ d1 = 4; d2 = 8; icon_state = "4-8" }, -/obj/machinery/door/airlock/glass{ - name = "Hydroponics"; - req_access = newlist(); - req_one_access = list(35,28) +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" }, -/turf/simulated/floor/tiled/steel_grid, -/area/hydroponics) +/turf/simulated/floor/lino, +/area/crew_quarters/bar) "aAd" = ( /obj/structure/cable/green{ d1 = 4; @@ -14097,6 +15157,17 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"aAe" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) "aAf" = ( /obj/structure/cable/green{ d1 = 2; @@ -14138,10 +15209,49 @@ /obj/machinery/door/firedoor/glass/hidden/steel, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) +"aAh" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/rnd/xenobiology/xenoflora) +"aAi" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/structure/cable/green{ + icon_state = "2-4" + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) "aAj" = ( -/obj/machinery/light/flamp, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) "aAk" = ( /obj/structure/flora/pottedplant/unusual, /obj/machinery/firealarm{ @@ -14154,6 +15264,15 @@ }, /turf/simulated/floor/wood, /area/rnd/outpost/xenobiology/outpost_office) +"aAl" = ( +/obj/random/maintenance/clean, +/obj/random/maintenance/clean, +/obj/structure/table/rack/steel, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) "aAm" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -14240,11 +15359,12 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "aAt" = ( -/obj/structure/table/wooden_reinforced, -/obj/item/weapon/paperplane, -/obj/machinery/camera/network/research, -/turf/simulated/floor/wood, -/area/rnd/outpost/xenobiology/outpost_office) +/obj/structure/flora/pottedplant/subterranean, +/obj/effect/floor_decal/borderfloorblack{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/outpost/xenobiology/outpost_hallway) "aAu" = ( /obj/machinery/alarm{ dir = 8; @@ -14301,6 +15421,12 @@ /obj/item/device/tape, /turf/simulated/floor/carpet, /area/tether/surfacebase/library/study) +"aAx" = ( +/obj/structure/railing{ + dir = 4 + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) "aAy" = ( /obj/structure/table/woodentable, /obj/item/weapon/paper_bin{ @@ -14328,214 +15454,108 @@ name = "\improper Surface Civilian Substation" }) "aAC" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/botanystorage) +"aAD" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/botanystorage) +"aAE" = ( +/obj/structure/closet/firecloset, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"aAF" = ( +/obj/structure/cable/green{ d1 = 1; d2 = 2; - icon_state = "1-2"; - pixel_y = 0 + icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 5 + dir = 6 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 5 + dir = 6 }, -/obj/machinery/light/small{ - dir = 8; - pixel_x = 0 - }, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) -"aAD" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) -"aAE" = ( -/obj/machinery/door/airlock/maintenance/common{ - name = "Hydroponics Maintenance"; - req_access = list(35) - }, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/hydroponics) -"aAF" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/turf/simulated/floor/wood, +/area/crew_quarters/bar) "aAG" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 + dir = 8 }, -/obj/structure/disposalpipe/segment, -/obj/effect/floor_decal/corner/green{ - dir = 10 - }, -/obj/effect/floor_decal/corner/green{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) +/turf/simulated/floor/wood, +/area/crew_quarters/bar) "aAH" = ( -/obj/effect/floor_decal/corner/green{ - dir = 5 - }, -/obj/effect/floor_decal/corner/green{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"aAI" = ( -/obj/machinery/portable_atmospherics/hydroponics, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/effect/floor_decal/corner/green{ - dir = 10 - }, -/obj/effect/floor_decal/corner/green{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"aAJ" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ +/obj/effect/floor_decal/corner/lime/border{ dir = 9 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aAI" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 1 + }, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 }, /turf/simulated/floor/tiled, -/area/hydroponics) -"aAK" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, +/area/tether/surfacebase/botanystorage) +"aAJ" = ( /obj/effect/floor_decal/corner/lime/border{ - dir = 4 + dir = 1 }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 }, -/obj/effect/floor_decal/borderfloor/corner2{ +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 6 }, -/obj/effect/floor_decal/corner/lime/bordercorner2{ - dir = 5 +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aAK" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 1 }, -/obj/effect/floor_decal/corner/lime/bordercorner2{ - dir = 6 +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aAL" = ( /obj/structure/cable/green{ d1 = 1; d2 = 8; icon_state = "1-8" }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"aAL" = ( -/obj/machinery/light{ - dir = 8; - icon_state = "tube1" +/obj/structure/table/standard, +/obj/item/device/destTagger{ + pixel_x = 4; + pixel_y = 3 }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 10 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/bordercorner2{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/bordercorner2{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) +/obj/item/weapon/packageWrap, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "aAM" = ( /obj/structure/disposalpipe/segment, /obj/effect/floor_decal/borderfloor/corner{ @@ -14554,29 +15574,39 @@ /turf/simulated/open, /area/hallway/lower/third_south) "aAO" = ( -/obj/machinery/recharge_station, -/obj/machinery/camera/network/research, -/turf/simulated/floor/tiled, -/area/rnd/outpost/xenobiology/outpost_breakroom) -"aAP" = ( -/obj/structure/bed/chair/wood, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"aAQ" = ( -/obj/machinery/newscaster{ - pixel_x = 0; - pixel_y = 30 - }, -/obj/structure/table/bench/wooden, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"aAR" = ( -/obj/machinery/computer/arcade, -/obj/machinery/camera/network/civilian{ +/obj/effect/floor_decal/borderfloorblack{ dir = 4 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/machinery/camera/network/research/xenobio{ + icon_state = "camera"; + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/rnd/outpost/xenobiology/outpost_hallway) +"aAP" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aAQ" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 5 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aAR" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/botanystorage) "aAS" = ( /obj/machinery/light{ dir = 1 @@ -14872,6 +15902,19 @@ }, /turf/simulated/floor/tiled, /area/rnd/research/testingrange) +"aBd" = ( +/obj/machinery/door/airlock/glass{ + name = "Hydroponics Storage"; + req_one_access = list(35,28) + }, +/obj/machinery/door/firedoor/glass, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aBe" = ( /obj/machinery/alarm{ dir = 4; @@ -14985,15 +16028,30 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "aBl" = ( -/obj/machinery/door/airlock/maintenance/common, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) +/obj/effect/floor_decal/corner/lime/border{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aBm" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aBn" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -15017,6 +16075,11 @@ }, /turf/simulated/floor/tiled/dark, /area/bridge) +"aBp" = ( +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lime/border, +/turf/simulated/floor/grass, +/area/hydroponics) "aBq" = ( /obj/item/device/radio/intercom{ pixel_x = 0; @@ -15027,6 +16090,17 @@ }, /turf/simulated/floor/wood, /area/library) +"aBr" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) "aBs" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -15041,12 +16115,16 @@ /turf/simulated/floor/wood, /area/library) "aBu" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 +/obj/machinery/holoplant, +/obj/effect/floor_decal/borderfloorblack{ + dir = 8 }, -/obj/machinery/camera/network/research, -/turf/simulated/floor/tiled/white, -/area/rnd/outpost/xenobiology/outpost_autopsy) +/obj/machinery/camera/network/research/xenobio{ + icon_state = "camera"; + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/outpost/xenobiology/outpost_hallway) "aBv" = ( /obj/structure/bed/chair/office/dark, /turf/simulated/floor/wood, @@ -15070,82 +16148,108 @@ /turf/simulated/floor/tiled, /area/rnd/staircase/thirdfloor) "aBx" = ( -/obj/effect/floor_decal/borderfloor{ +/obj/structure/table/standard, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 8 }, +/obj/machinery/microwave, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"aBy" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/plating, +/area/hydroponics/cafegarden) +"aBz" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aBA" = ( +/obj/item/weapon/stool/padded, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aBB" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 6 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 6 + }, +/obj/machinery/camera/network/tether{ + dir = 9 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"aBC" = ( +/obj/item/weapon/stool/padded, /obj/effect/floor_decal/corner/lime/border{ - dir = 8 + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aBD" = ( +/obj/structure/table/standard, +/obj/item/weapon/storage/box/donkpockets{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/weapon/reagent_containers/glass/beaker{ + pixel_x = 5 + }, +/obj/item/weapon/reagent_containers/food/snacks/mint, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"aBE" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 1 }, /obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/obj/machinery/computer/guestpass{ - dir = 4; - pixel_x = -28; - pixel_y = 0 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"aBy" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"aBz" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4, -/turf/simulated/floor/tiled, -/area/hydroponics) -"aBA" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/glass{ - name = "Hydroponics"; - req_access = newlist(); - req_one_access = list(35,28) - }, -/turf/simulated/floor/tiled/steel_grid, -/area/hydroponics) -"aBB" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) -"aBC" = ( -/obj/structure/table/gamblingtable, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"aBD" = ( -/obj/structure/table/gamblingtable, -/obj/item/weapon/storage/pill_bottle/dice, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"aBF" = ( -/obj/structure/table/woodentable, -/obj/machinery/atmospherics/unary/vent_pump/on{ +/obj/structure/disposalpipe/segment{ dir = 8 }, -/obj/item/weapon/reagent_containers/food/condiment/small/peppermill{ - pixel_x = 3 +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"aBF" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 }, -/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{ - pixel_x = -3; - pixel_y = 0 +/obj/effect/floor_decal/borderfloor{ + dir = 4 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aBG" = ( -/obj/item/weapon/stool/padded, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/structure/flora/ausbushes/fernybush, +/turf/simulated/floor/grass, +/area/hydroponics) "aBH" = ( /obj/machinery/atmospherics/unary/vent_pump/on, /obj/effect/floor_decal/borderfloor{ @@ -15185,19 +16289,14 @@ /turf/simulated/floor/tiled, /area/rnd/research/testingrange) "aBJ" = ( -/obj/machinery/shower{ - dir = 4; - icon_state = "shower"; - pixel_x = 5; - pixel_y = 0 - }, -/obj/structure/curtain/open/shower, -/obj/machinery/camera/network/research{ +/obj/structure/kitchenspike, +/obj/machinery/alarm/freezer{ dir = 1; - icon_state = "camera" + icon_state = "alarm0"; + pixel_y = -25 }, -/turf/simulated/floor/tiled/dark, -/area/rnd/outpost/xenobiology/outpost_south_airlock) +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) "aBK" = ( /obj/machinery/door/firedoor/glass, /obj/effect/floor_decal/borderfloorblack, @@ -15238,13 +16337,17 @@ /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) "aBM" = ( -/obj/machinery/hologram/holopad, -/obj/machinery/camera/network/research{ - dir = 8; - icon_state = "camera" +/obj/structure/cable/green{ + d1 = 2; + d2 = 4; + icon_state = "2-4" }, -/turf/simulated/floor/tiled/white, -/area/rnd/outpost/xenobiology/outpost_first_aid) +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "aBN" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -15411,6 +16514,15 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"aBZ" = ( +/obj/machinery/smartfridge/drying_rack, +/obj/effect/floor_decal/corner/lime/border, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aCa" = ( +/obj/machinery/hologram/holopad, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) "aCb" = ( /obj/structure/table/reinforced, /obj/item/weapon/paper{ @@ -15494,53 +16606,68 @@ }, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) +"aCf" = ( +/obj/structure/table/standard, +/obj/item/weapon/book/manual/chef_recipes, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"aCg" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/storage/box/sinpockets, +/obj/effect/floor_decal/corner/lime/border, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aCh" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ +/obj/machinery/door/airlock{ + name = "Service"; + req_one_access = list(35,28) + }, +/obj/structure/cable/green{ d1 = 1; d2 = 2; - icon_state = "1-2"; - pixel_y = 0 + icon_state = "1-2" }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/maintenance/engi{ - name = "Bar Substation" - }, -/turf/simulated/floor/plating, -/area/maintenance/substation/bar{ - name = "\improper Surface Civilian Substation" - }) -"aCi" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/machinery/power/apc{ - cell_type = /obj/item/weapon/cell/super; - dir = 8; - name = "west bump"; - pixel_x = -30 - }, -/obj/structure/cable/green, +/obj/machinery/door/firedoor, /turf/simulated/floor/tiled, -/area/hydroponics) +/area/tether/surfacebase/servicebackroom) +"aCi" = ( +/obj/effect/floor_decal/corner/beige{ + dir = 10 + }, +/obj/effect/floor_decal/corner/beige{ + dir = 4; + icon_state = "corner_white" + }, +/obj/effect/floor_decal/spline/plain{ + dir = 6 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "aCj" = ( -/obj/machinery/biogenerator, -/obj/effect/floor_decal/borderfloor{ - dir = 4 +/obj/effect/floor_decal/borderfloor/corner{ + dir = 8 }, +/obj/effect/floor_decal/corner/lime/bordercorner{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"aCk" = ( +/obj/structure/table/woodentable, +/obj/item/clothing/mask/smokable/pipe/cobpipe, +/obj/item/clothing/mask/smokable/cigarette/joint, +/obj/item/weapon/flame/lighter/random, /obj/effect/floor_decal/corner/lime/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 6 - }, -/obj/effect/floor_decal/corner/lime/bordercorner2{ dir = 6 }, /turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aCl" = ( +/obj/structure/table/rack/steel, +/turf/simulated/floor/tiled, /area/hydroponics) "aCm" = ( /obj/structure/disposalpipe/segment{ @@ -15548,11 +16675,45 @@ }, /turf/simulated/floor/tiled/dark, /area/rnd/outpost/xenobiology/outpost_hallway) +"aCn" = ( +/obj/machinery/portable_atmospherics/powered/pump/filled, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) "aCo" = ( -/obj/structure/table/gamblingtable, -/obj/item/weapon/deck/cards, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/botanystorage) +"aCp" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced, +/turf/simulated/floor/plating, +/area/tether/surfacebase/botanystorage) +"aCq" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/structure/closet/secure_closet/freezer/meat, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "aCr" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/mauve/border, @@ -15702,6 +16863,52 @@ /obj/structure/disposalpipe/junction, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) +"aCC" = ( +/obj/machinery/vending/hydronutrients, +/obj/effect/floor_decal/corner/lime/border{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aCD" = ( +/obj/machinery/seed_storage/garden, +/obj/effect/floor_decal/corner/lime/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aCE" = ( +/obj/item/bee_pack, +/obj/item/honey_frame, +/obj/item/honey_frame, +/obj/item/honey_frame, +/obj/item/honey_frame, +/obj/item/honey_frame, +/obj/item/weapon/tool/crowbar, +/obj/item/bee_smoker, +/obj/item/beehive_assembly, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/structure/closet/crate/hydroponics{ + desc = "All you need to start your own honey farm."; + name = "beekeeping crate" + }, +/obj/item/beehive_assembly, +/obj/item/beehive_assembly, +/obj/item/beehive_assembly, +/obj/item/beehive_assembly, +/obj/item/bee_pack, +/obj/item/bee_pack, +/obj/item/bee_pack, +/obj/item/honey_frame, +/obj/item/honey_frame, +/obj/item/honey_frame, +/obj/effect/floor_decal/corner/lime/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aCF" = ( /obj/machinery/light/small{ dir = 4; @@ -15725,6 +16932,45 @@ }, /turf/simulated/floor/wood, /area/library) +"aCI" = ( +/obj/structure/flora/ausbushes/fullgrass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/grass, +/area/hydroponics) +"aCJ" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"aCK" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/junction{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aCL" = ( /obj/machinery/power/breakerbox/activated{ RCon_tag = "Surface Civilian Substation Bypass" @@ -15807,15 +17053,27 @@ name = "\improper Surface Civilian Substation" }) "aCR" = ( -/obj/machinery/seed_extractor, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 4 - }, -/turf/simulated/floor/tiled, +/obj/structure/flora/ausbushes/sunnybush, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/grass, /area/hydroponics) +"aCS" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/crew_quarters/bar) +"aCT" = ( +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) "aCU" = ( /obj/structure/cable/green{ d1 = 1; @@ -15847,6 +17105,22 @@ }, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) +"aCW" = ( +/obj/machinery/seed_extractor, +/obj/effect/floor_decal/corner/lime/border{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aCX" = ( +/obj/effect/floor_decal/corner/beige{ + dir = 9 + }, +/obj/effect/floor_decal/spline/plain{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "aCY" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -15971,15 +17245,19 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_three) "aDo" = ( -/obj/structure/table/standard, -/obj/item/device/slime_scanner, -/obj/item/device/slime_scanner, -/obj/item/device/multitool, -/obj/machinery/camera/network/research{ - dir = 1 +/obj/machinery/shower{ + dir = 4; + icon_state = "shower"; + pixel_x = 5; + pixel_y = 0 }, -/turf/simulated/floor/tiled/techmaint, -/area/rnd/outpost/xenobiology/outpost_storage) +/obj/structure/curtain/open/shower, +/obj/machinery/camera/network/research/xenobio{ + icon_state = "camera"; + dir = 10 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/outpost/xenobiology/outpost_south_airlock) "aDp" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 @@ -16145,6 +17423,13 @@ /obj/random/maintenance/clean, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_three) +"aDC" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 1 + }, +/obj/machinery/smartfridge, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aDD" = ( /obj/structure/table/bench/wooden, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ @@ -16203,6 +17488,10 @@ }, /turf/simulated/open, /area/tether/surfacebase/public_garden_three) +"aDI" = ( +/obj/machinery/camera/network/civilian, +/turf/simulated/floor/grass, +/area/hydroponics) "aDJ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -16232,6 +17521,14 @@ /obj/machinery/light, /turf/simulated/floor/grass, /area/tether/surfacebase/public_garden_three) +"aDM" = ( +/obj/structure/closet/secure_closet/hydroponics, +/obj/effect/floor_decal/corner/lime/border{ + dir = 5 + }, +/obj/machinery/camera/network/civilian, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aDN" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/lime/border, @@ -16296,29 +17593,23 @@ /turf/simulated/floor/grass, /area/tether/surfacebase/public_garden_three) "aDU" = ( -/obj/structure/bed/chair/wood{ - dir = 1 - }, -/obj/machinery/camera/network/research{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/rnd/outpost/xenobiology/outpost_breakroom) +/obj/structure/table/wooden_reinforced, +/obj/item/weapon/paperplane, +/obj/machinery/camera/network/research/xenobio, +/turf/simulated/floor/wood, +/area/rnd/outpost/xenobiology/outpost_office) "aDV" = ( -/obj/effect/floor_decal/borderfloor{ +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, -/obj/effect/floor_decal/corner/lightgrey/border{ +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/machinery/light{ - dir = 4 +/obj/structure/disposalpipe/sortjunction{ + dir = 4; + icon_state = "pipe-j1s"; + name = "Service"; + sortType = "Service" }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) @@ -16336,6 +17627,22 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"aDX" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 10 + }, +/obj/machinery/portable_atmospherics/hydroponics, +/obj/machinery/firealarm{ + dir = 1; + pixel_x = 0; + pixel_y = -24 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aDY" = ( +/obj/structure/flora/tree/jungle, +/turf/simulated/floor/grass, +/area/hydroponics) "aDZ" = ( /obj/structure/cable/green{ d1 = 1; @@ -16375,12 +17682,19 @@ /turf/simulated/floor/tiled/dark, /area/bridge) "aEd" = ( -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/closet/crate/bin, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) "aEe" = ( /obj/structure/table/reinforced, /obj/machinery/newscaster{ @@ -16398,12 +17712,10 @@ /turf/simulated/floor/tiled/dark, /area/bridge) "aEf" = ( -/obj/machinery/camera/network/research{ - dir = 5; - icon_state = "camera" - }, -/turf/simulated/floor/tiled/dark, -/area/rnd/outpost/xenobiology/outpost_main) +/obj/machinery/recharge_station, +/obj/machinery/camera/network/research/xenobio, +/turf/simulated/floor/tiled, +/area/rnd/outpost/xenobiology/outpost_breakroom) "aEg" = ( /obj/structure/disposalpipe/segment{ dir = 1; @@ -16423,12 +17735,11 @@ /turf/simulated/floor/tiled/dark, /area/bridge) "aEh" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/effect/landmark/start{ - name = "Chef" - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) +/obj/structure/flora/ausbushes/lavendergrass, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/turf/simulated/floor/grass, +/area/hydroponics) "aEi" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -16461,37 +17772,35 @@ /turf/simulated/floor/plating, /area/maintenance/commandmaint) "aEk" = ( -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/effect/floor_decal/corner/lime/border{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aEl" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, /area/crew_quarters/bar) "aEm" = ( -/obj/structure/table/bench/wooden, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aEn" = ( -/obj/structure/table/woodentable, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 +/obj/structure/closet/secure_closet/hydroponics, +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aEo" = ( /obj/structure/cable{ icon_state = "1-2" @@ -16589,28 +17898,30 @@ /turf/simulated/floor/plating, /area/maintenance/commandmaint) "aEw" = ( -/obj/structure/flora/pottedplant/subterranean, -/obj/effect/floor_decal/borderfloorblack{ +/obj/machinery/camera/network/research/xenobio{ + icon_state = "camera"; dir = 4 }, -/obj/machinery/camera/network/research{ - dir = 8; - icon_state = "camera" - }, -/turf/simulated/floor/tiled, -/area/rnd/outpost/xenobiology/outpost_hallway) +/turf/simulated/floor/tiled/dark, +/area/rnd/outpost/xenobiology/outpost_main) "aEx" = ( -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lime/border, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ +/obj/structure/window/reinforced{ dir = 8 }, -/obj/machinery/light, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/botanystorage) "aEy" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -16649,22 +17960,11 @@ /turf/simulated/floor/tiled/techmaint, /area/tether/surfacebase/surface_three_hall) "aEB" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 +/obj/structure/sink{ + pixel_y = 24 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/maintenance/int{ - name = "Emergency Storage"; - req_one_access = list() - }, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) +/turf/simulated/floor/grass, +/area/hydroponics) "aEC" = ( /obj/structure/bed/chair/office/dark{ dir = 8 @@ -16687,18 +17987,9 @@ /turf/simulated/floor/wood, /area/library) "aEF" = ( -/obj/structure/table/rack{ - dir = 1 - }, -/obj/item/clothing/suit/fire/firefighter, -/obj/item/weapon/tank/oxygen, -/obj/item/clothing/mask/gas, -/obj/item/weapon/extinguisher, -/obj/item/clothing/head/hardhat/red, -/obj/item/clothing/glasses/meson, -/obj/item/weapon/storage/briefcase/inflatable, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) +/obj/machinery/hologram/holopad, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aEG" = ( /obj/structure/bed/chair/comfy/black{ dir = 4 @@ -16740,33 +18031,37 @@ /turf/simulated/floor/wood, /area/library) "aEL" = ( -/obj/machinery/power/apc{ - cell_type = /obj/item/weapon/cell/apc; - dir = 8; - name = "west bump"; - pixel_x = -28 +/obj/structure/table/standard{ + name = "plastic table frame" }, -/obj/structure/cable{ - icon_state = "0-4" +/obj/item/weapon/reagent_containers/glass/bucket, +/obj/item/weapon/reagent_containers/glass/bucket, +/obj/effect/floor_decal/borderfloor, +/obj/item/weapon/tool/wrench, +/obj/effect/floor_decal/corner/lime/border{ + dir = 9 }, -/obj/structure/table/standard, -/obj/item/weapon/storage/box/lights/mixed, -/obj/item/weapon/storage/box/lights/mixed, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) +/obj/item/weapon/tool/wrench, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aEM" = ( -/obj/machinery/space_heater, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) -"aEN" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 +/obj/structure/table/standard{ + name = "plastic table frame" }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/item/weapon/material/knife, +/obj/item/weapon/material/minihoe, +/obj/item/weapon/material/minihoe, +/obj/item/weapon/material/knife, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lime/border{ + dir = 5 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aEN" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aEO" = ( /obj/item/weapon/dice/d20, /obj/item/weapon/dice, @@ -16820,15 +18115,23 @@ /turf/simulated/floor/wood, /area/library) "aES" = ( -/obj/machinery/portable_atmospherics/powered/pump/filled, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) -"aET" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/obj/structure/table/standard, +/obj/item/weapon/reagent_containers/food/condiment/enzyme{ + layer = 5 }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, +/obj/item/weapon/reagent_containers/food/condiment/enzyme{ + layer = 5 + }, +/obj/item/weapon/reagent_containers/dropper, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"aET" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 8; + icon_state = "spline_plain" + }, +/obj/item/weapon/stool/padded, +/turf/simulated/floor/lino, /area/crew_quarters/bar) "aEU" = ( /obj/structure/bookcase{ @@ -16857,49 +18160,72 @@ /turf/simulated/floor/wood, /area/library) "aEW" = ( -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" +/obj/effect/floor_decal/spline/plain{ + dir = 4 }, -/turf/simulated/floor/wood, +/obj/structure/table/marble, +/obj/machinery/chemical_dispenser/bar_soft/full{ + dir = 8; + icon_state = "soda_dispenser" + }, +/turf/simulated/floor/lino, /area/crew_quarters/bar) "aEX" = ( -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" +/obj/machinery/portable_atmospherics/hydroponics, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/grass, +/area/hydroponics) "aEY" = ( -/obj/machinery/firealarm{ - pixel_x = -30 +/obj/effect/floor_decal/spline/plain{ + dir = 8 }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"aEZ" = ( /obj/machinery/light{ - dir = 8; + dir = 4; icon_state = "tube1" }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"aEZ" = ( -/obj/machinery/hologram/holopad, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/grass, +/area/hydroponics) "aFa" = ( -/obj/effect/landmark{ - name = "Observer-Start" +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/airlock/glass{ + name = "Hydroponics Storage"; + req_one_access = list(35,28) }, -/obj/machinery/light/flamp, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aFb" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/full, -/obj/machinery/door/firedoor, -/obj/structure/window/reinforced{ - dir = 1 +/obj/effect/floor_decal/corner/lime/border{ + dir = 8 }, -/turf/simulated/floor/plating, -/area/crew_quarters/bar) +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5; + icon_state = "intact-supply" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5; + icon_state = "intact-scrubbers" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aFc" = ( /obj/structure/bed/chair/office/dark{ dir = 4 @@ -16933,16 +18259,19 @@ /turf/simulated/floor/outdoors/grass/sif/virgo3b, /area/tether/surfacebase/outside/outside3) "aFg" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aFh" = ( /obj/effect/decal/cleanable/blood, /obj/effect/decal/remains/deer, @@ -16989,14 +18318,35 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "aFk" = ( -/obj/structure/table/standard, -/obj/random/maintenance/clean, -/obj/random/maintenance/medical, -/obj/item/device/t_scanner, -/obj/effect/decal/cleanable/dirt, -/obj/random/junk, -/turf/simulated/floor/plating, -/area/maintenance/lower/atrium) +/obj/structure/reagent_dispensers/watertank, +/obj/item/weapon/reagent_containers/glass/bucket, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lime/border{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aFl" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/item/weapon/reagent_containers/glass/bucket, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lime/border{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aFm" = ( /obj/structure/disposalpipe/segment, /obj/effect/floor_decal/borderfloor{ @@ -17079,6 +18429,16 @@ }, /turf/simulated/floor/tiled, /area/rnd/outpost/xenobiology/outpost_north_airlock) +"aFq" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) "aFr" = ( /obj/structure/cable/green{ d1 = 1; @@ -17109,6 +18469,16 @@ }, /turf/simulated/floor/wood, /area/library) +"aFv" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) "aFw" = ( /obj/structure/closet/crate, /obj/item/target, @@ -17138,142 +18508,119 @@ name = "\improper Surface Civilian Substation" }) "aFy" = ( -/obj/effect/floor_decal/borderfloor{ +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 8 }, -/obj/effect/floor_decal/corner/lime/border{ +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + icon_state = "2-4" + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"aFz" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/flora/ausbushes/pointybush, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) +"aFA" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 8 }, -/obj/item/device/radio/intercom{ - dir = 8; - pixel_x = -24 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, -/obj/structure/sink{ - dir = 8; - icon_state = "sink"; - pixel_x = -12; - pixel_y = 8 +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/effect/landmark/start{ - name = "Gardener" +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"aFB" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 }, /turf/simulated/floor/tiled, -/area/hydroponics) -"aFA" = ( +/area/tether/surfacebase/botanystorage) +"aFC" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 4; + icon_state = "map-scrubbers" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals5{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals5, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/shuttle_pad) +"aFD" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 10 + }, +/obj/machinery/alarm{ + alarm_id = "pen_nine"; + breach_detection = 0; + dir = 1; + icon_state = "alarm0"; + pixel_y = -22 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aFE" = ( +/obj/effect/floor_decal/corner/lime/border, +/obj/machinery/power/apc{ + dir = 2; + name = "south bump"; + pixel_y = -24 + }, +/obj/structure/cable/green, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aFF" = ( /obj/structure/bed/chair/wood{ dir = 1 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"aFC" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 +/obj/machinery/camera/network/research/xenobio{ + icon_state = "camera"; + dir = 10 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 +/turf/simulated/floor/tiled, +/area/rnd/outpost/xenobiology/outpost_breakroom) +"aFG" = ( +/obj/effect/floor_decal/corner/lime/bordercorner{ + dir = 8 }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"aFD" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"aFE" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/light/flamp, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"aFF" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/cable/green{ - icon_state = "1-2" - }, -/obj/structure/cable/green{ - icon_state = "1-4" - }, -/obj/structure/cable/green{ - icon_state = "1-8" - }, -/obj/structure/disposalpipe/junction{ - dir = 1; - icon_state = "pipe-j2" - }, -/obj/machinery/camera/network/research{ +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aFH" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ dir = 1 }, -/turf/simulated/floor/tiled/dark, -/area/rnd/outpost/xenobiology/outpost_main) -"aFG" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 2; - icon_state = "pipe-c" - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"aFH" = ( -/obj/machinery/light, -/obj/item/device/radio/intercom{ - dir = 2; - pixel_y = -24 - }, -/obj/structure/table/bench/wooden, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aFI" = ( -/obj/structure/table/woodentable, -/obj/machinery/alarm{ - dir = 1; - pixel_y = -25 +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aFJ" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4; @@ -17289,6 +18636,16 @@ }, /turf/simulated/floor/tiled, /area/rnd/outpost/xenobiology/outpost_north_airlock) +"aFK" = ( +/obj/structure/bed/chair/wood, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "aFL" = ( /obj/structure/window/reinforced/full, /obj/structure/grille, @@ -17306,6 +18663,9 @@ }, /turf/simulated/floor/tiled/dark, /area/rnd/outpost/xenobiology/outpost_north_airlock) +"aFM" = ( +/turf/simulated/wall, +/area/tether/surfacebase/servicebackroom) "aFN" = ( /obj/structure/table/reinforced, /obj/machinery/recharger/wallcharger{ @@ -17324,6 +18684,38 @@ /obj/item/weapon/storage/bag/trash, /turf/simulated/floor/tiled, /area/rnd/research/testingrange) +"aFO" = ( +/obj/machinery/door/airlock{ + name = "Service"; + req_one_access = list(35,28) + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aFP" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aFQ" = ( /obj/structure/cable/green{ d1 = 4; @@ -17355,6 +18747,22 @@ }, /turf/simulated/floor/tiled, /area/rnd/research/testingrange) +"aFR" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/obj/machinery/portable_atmospherics/hydroponics, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aFS" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/lime/border{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aFT" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/mauve/border, @@ -17419,65 +18827,96 @@ name = "\improper Surface Civilian Substation" }) "aFY" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 10 +/obj/machinery/button/windowtint{ + id = "draama"; + layer = 3.3; + name = "Mystery Window Tint Control"; + pixel_x = 3; + pixel_y = -29; + range = 10 }, -/obj/structure/closet/secure_closet/hydroponics, +/obj/machinery/button/remote/blast_door{ + id = "DRAMATIC"; + name = "Dramatic Blast Doors"; + pixel_x = 24; + pixel_y = -10 + }, +/obj/machinery/button/remote/blast_door{ + id = "Druma"; + name = "Entertainment Shutter Control"; + pixel_x = 24; + pixel_y = 10 + }, +/obj/item/weapon/stool/padded, +/obj/effect/landmark/start{ + name = "Entertainer" + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"aFZ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/yellow{ + dir = 5 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"aGa" = ( /obj/effect/floor_decal/corner/lime/border{ dir = 10 }, +/obj/machinery/portable_atmospherics/hydroponics, /turf/simulated/floor/tiled, -/area/hydroponics) -"aFZ" = ( -/obj/machinery/disposal, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lime/border, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/hydroponics) -"aGa" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/item/weapon/reagent_containers/glass/bucket, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lime/border, -/turf/simulated/floor/tiled, -/area/hydroponics) +/area/tether/surfacebase/botanystorage) "aGb" = ( -/obj/structure/table/standard{ - name = "plastic table frame" +/obj/machinery/camera/network/civilian{ + dir = 4 }, -/obj/item/weapon/reagent_containers/glass/bucket, -/obj/item/weapon/reagent_containers/glass/bucket, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lime/border, -/turf/simulated/floor/tiled, +/turf/simulated/floor/tiled/eris/cafe, /area/hydroponics) "aGc" = ( -/obj/structure/table/standard{ - name = "plastic table frame" +/obj/effect/floor_decal/corner/lime/bordercorner{ + dir = 8 }, -/obj/item/weapon/material/knife, -/obj/item/weapon/material/minihoe, -/obj/item/weapon/material/minihoe, -/obj/item/weapon/material/knife, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/lime/border, +/obj/machinery/portable_atmospherics/hydroponics, /turf/simulated/floor/tiled, -/area/hydroponics) +/area/tether/surfacebase/botanystorage) "aGd" = ( -/obj/machinery/seed_storage/garden{ +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 }, -/obj/effect/floor_decal/borderfloor{ - dir = 6 +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 1 }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 6 +/obj/machinery/requests_console{ + pixel_y = 30 }, /turf/simulated/floor/tiled, -/area/hydroponics) +/area/tether/surfacebase/servicebackroom) +"aGe" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aGf" = ( /obj/machinery/status_display{ pixel_x = 32; @@ -17502,21 +18941,87 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) -"aGk" = ( -/obj/machinery/door/airlock{ - name = "Unisex Restrooms" +"aGg" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/camera/network/civilian, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aGh" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/effect/floor_decal/corner/grey/diagonal, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"aGi" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/structure/table/standard, +/obj/machinery/reagentgrinder, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"aGj" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 }, -/obj/structure/disposalpipe/segment, -/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" }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aGk" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/structure/cable/green{ + icon_state = "2-4" + }, +/obj/machinery/door/blast/regular/open{ + dir = 4; + icon_state = "pdoor0"; + id = "DRAMATIC"; + name = "Dramatic Blast Door" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 1; + icon_state = "rwindow"; + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 1; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) "aGl" = ( /obj/structure/table/reinforced, /obj/item/clothing/ears/earmuffs, @@ -17601,6 +19106,31 @@ }, /turf/simulated/floor/tiled, /area/rnd/outpost/xenobiology/outpost_north_airlock) +"aGq" = ( +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aGr" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/table/standard, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "aGs" = ( /obj/machinery/door/firedoor/glass, /obj/machinery/door/airlock/research{ @@ -17624,6 +19154,40 @@ }, /turf/simulated/floor/tiled/dark, /area/rnd/outpost/xenobiology/outpost_south_airlock) +"aGt" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) +"aGu" = ( +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/machinery/light, +/obj/effect/floor_decal/corner/beige/border, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"aGv" = ( +/obj/machinery/hologram/holopad, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aGw" = ( /obj/structure/bookcase{ name = "bookcase (Non-Fiction)" @@ -17663,24 +19227,16 @@ name = "\improper Surface Civilian Substation" }) "aGA" = ( -/obj/structure/sign/directions/medical{ - dir = 4; - pixel_y = 8 +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 }, -/obj/structure/sign/directions/science{ - dir = 8; - pixel_y = 3 +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 }, -/obj/structure/sign/directions/security{ - dir = 8; - pixel_y = -4 - }, -/obj/structure/sign/directions/engineering{ - dir = 8; - pixel_y = -10 - }, -/turf/simulated/wall, -/area/hydroponics) +/obj/effect/floor_decal/corner/beige/border, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aGB" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -17712,52 +19268,90 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) -"aGF" = ( -/obj/effect/floor_decal/spline/plain{ - dir = 1 - }, -/obj/item/weapon/stool/padded, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) -"aGG" = ( -/obj/item/weapon/stool/padded, -/obj/effect/floor_decal/spline/plain{ - dir = 1 - }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) -"aGI" = ( -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, -/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" - }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ +"aGD" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 9 - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) -"aGJ" = ( -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk{ +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"aGE" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/machinery/door/blast/regular/open{ + dir = 4; + icon_state = "pdoor0"; + id = "DRAMATIC"; + name = "Dramatic Blast Door" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 1; + icon_state = "rwindow"; + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 1; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) +"aGF" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/airlock/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"aGG" = ( +/obj/machinery/vending/cigarette, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aGH" = ( +/obj/structure/table/woodentable, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"aGI" = ( +/obj/machinery/vending/cola/soft, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aGJ" = ( +/obj/machinery/portable_atmospherics/hydroponics, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aGK" = ( /turf/simulated/wall, /area/crew_quarters/barrestroom) @@ -17983,6 +19577,10 @@ }, /turf/simulated/floor/wood, /area/library) +"aHe" = ( +/obj/structure/table/woodentable, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) "aHf" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -18081,73 +19679,79 @@ /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) "aHk" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/disposalpipe/segment{ - dir = 8; + dir = 4; icon_state = "pipe-c" }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"aHl" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/flame/candle, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) "aHm" = ( -/obj/machinery/light{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/disposalpipe/junction{ + dir = 2; + icon_state = "pipe-j2" }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lightgrey/border{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "aHn" = ( -/obj/structure/extinguisher_cabinet{ - pixel_y = 30 +/obj/structure/disposalpipe/segment{ + dir = 8 }, /obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 4 }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "aHo" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 1 +/obj/structure/disposalpipe/segment{ + dir = 8 }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/effect/floor_decal/steeldecal/steel_decals7{ +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/door/firedoor/glass/hidden/steel, /turf/simulated/floor/tiled, -/area/hallway/lower/third_south) +/area/tether/surfacebase/servicebackroom) +"aHp" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aHq" = ( +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aHr" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/sign/department/bar, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/plating, +/area/crew_quarters/bar) +"aHs" = ( +/obj/structure/table/gamblingtable, +/obj/item/weapon/storage/pill_bottle/dice, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/carpet/turcarpet, +/area/crew_quarters/bar) "aHt" = ( /obj/structure/cable/green{ d1 = 1; @@ -18168,75 +19772,94 @@ dir = 1 }, /area/crew_quarters/bar) -"aHx" = ( -/obj/structure/table/marble, -/obj/machinery/door/blast/shutters{ - dir = 8; - id = "bar"; - layer = 3.3; - name = "Bar Shutters" +"aHv" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"aHw" = ( /obj/structure/cable/green{ d1 = 1; - d2 = 2; - icon_state = "1-2" + d2 = 4; + icon_state = "1-4" }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aHx" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aHy" = ( -/obj/structure/table/marble, -/obj/item/weapon/reagent_containers/food/drinks/glass2/pint, -/obj/machinery/door/blast/shutters{ - dir = 1; - id = "bar"; - layer = 3.3; - name = "Bar Shutters" +/obj/effect/floor_decal/corner/beige{ + dir = 10 }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) -"aHz" = ( -/obj/structure/table/marble, -/obj/machinery/door/blast/shutters{ - dir = 1; - id = "bar"; - layer = 3.3; - name = "Bar Shutters" +/obj/effect/floor_decal/corner/beige{ + dir = 9 }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) -"aHA" = ( -/obj/structure/table/marble, -/obj/item/weapon/reagent_containers/food/drinks/glass2/shot, -/obj/machinery/door/blast/shutters{ - dir = 1; - id = "bar"; - layer = 3.3; - name = "Bar Shutters" +/obj/effect/floor_decal/spline/plain{ + dir = 10 }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) -"aHB" = ( -/obj/structure/extinguisher_cabinet{ +/obj/machinery/light{ dir = 8; - icon_state = "extinguisher_closed"; - pixel_x = 30 + icon_state = "tube1"; + pixel_y = 0 }, -/obj/machinery/door/window/brigdoor/northleft{ - name = "Bar"; - req_access = list(25) +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"aHz" = ( +/obj/structure/device/piano, +/obj/effect/floor_decal/spline/plain{ + dir = 1 }, /turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"aHA" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aHB" = ( +/obj/structure/table/gamblingtable, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/carpet/turcarpet, /area/crew_quarters/bar) "aHC" = ( -/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" +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/spiderling_remains, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) "aHD" = ( /obj/structure/sink{ dir = 4; @@ -18610,72 +20233,109 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) -"aIk" = ( -/obj/structure/table/marble, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ +"aId" = ( +/obj/effect/floor_decal/industrial/warning, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/generic, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"aIe" = ( +/obj/structure/railing{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/door/blast/shutters{ - dir = 8; - id = "bar"; - layer = 3.3; - name = "Bar Shutters" +/obj/effect/floor_decal/industrial/warning/corner{ + dir = 8 }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/generic, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"aIf" = ( /obj/structure/cable/green{ d1 = 4; d2 = 8; icon_state = "4-8" }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) -"aIl" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 + dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 + dir = 8 }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"aIg" = ( +/obj/item/weapon/stool/padded, +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/carpet/turcarpet, +/area/crew_quarters/bar) +"aIh" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"aIi" = ( +/obj/structure/bed/chair/wood{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"aIj" = ( /obj/structure/cable/green{ d1 = 2; d2 = 8; icon_state = "2-8" }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) -"aIm" = ( -/turf/simulated/floor/lino, -/area/crew_quarters/bar) -"aIn" = ( -/obj/machinery/computer/guestpass{ - dir = 8; - pixel_x = 25 - }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) -"aIo" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/alarm{ - dir = 4; - icon_state = "alarm0"; - pixel_x = -22; - pixel_y = 0 - }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aIk" = ( /obj/structure/cable/green{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"aIl" = ( +/obj/item/weapon/stool/padded, +/turf/simulated/floor/carpet/turcarpet, +/area/crew_quarters/bar) +"aIm" = ( +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"aIn" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/turf/simulated/floor/carpet/turcarpet, +/area/crew_quarters/bar) +"aIo" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 8; + icon_state = "spline_plain" + }, +/obj/item/weapon/stool/padded, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) "aIp" = ( /obj/structure/flora/pottedplant/unusual, /obj/effect/floor_decal/borderfloorblack{ @@ -18925,6 +20585,10 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"aIH" = ( +/obj/structure/table/gamblingtable, +/turf/simulated/floor/carpet/turcarpet, +/area/crew_quarters/bar) "aII" = ( /obj/structure/sign/department/bar{ pixel_x = 32 @@ -18933,19 +20597,23 @@ /turf/simulated/floor/tiled, /area/hallway/lower/third_south) "aIJ" = ( -/obj/machinery/disposal, -/obj/structure/disposalpipe/trunk{ - dir = 1 +/obj/structure/table/marble, +/obj/machinery/door/blast/shutters{ + dir = 8; + id = "bar"; + layer = 3.3; + name = "Bar Shutters" }, -/obj/machinery/camera/network/civilian{ - dir = 4 +/obj/structure/disposalpipe/segment{ + dir = 8 }, -/turf/simulated/floor/wood, +/turf/simulated/floor/lino, /area/crew_quarters/bar) "aIK" = ( -/obj/machinery/light, -/obj/structure/flora/pottedplant, -/turf/simulated/floor/wood, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/lino, /area/crew_quarters/bar) "aIL" = ( /obj/machinery/camera/network/security, @@ -18962,31 +20630,32 @@ /turf/simulated/floor/lino, /area/crew_quarters/bar) "aIN" = ( -/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/lino, +/obj/structure/table/gamblingtable, +/obj/item/weapon/deck/cards, +/turf/simulated/floor/carpet/turcarpet, /area/crew_quarters/bar) "aIO" = ( -/obj/machinery/vending/boozeomat, -/obj/machinery/light, -/turf/simulated/floor/lino, +/obj/item/weapon/stool/padded, +/obj/effect/floor_decal/spline/plain, +/turf/simulated/floor/carpet/turcarpet, /area/crew_quarters/bar) "aIP" = ( -/obj/machinery/smartfridge/drinks, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, /turf/simulated/floor/lino, /area/crew_quarters/bar) "aIQ" = ( -/obj/structure/flora/pottedplant, -/obj/machinery/camera/network/civilian{ - dir = 9 +/obj/structure/bed/chair/comfy{ + dir = 1 }, +/obj/effect/landmark/start{ + name = "Bartender" + }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, -/area/crew_quarters/bar) +/area/tether/surfacebase/bar_backroom) "aIR" = ( /obj/structure/disposalpipe/trunk{ dir = 8 @@ -19005,61 +20674,36 @@ /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/chemistry) "aIS" = ( -/obj/structure/table/marble, -/obj/item/weapon/reagent_containers/glass/rag, -/obj/item/weapon/reagent_containers/food/drinks/flask/vacuumflask, -/obj/item/weapon/book/manual/barman_recipes, -/turf/simulated/floor/lino, +/obj/machinery/vending/cigarette{ + dir = 1 + }, +/turf/simulated/floor/wood, /area/crew_quarters/bar) "aIT" = ( -/obj/structure/table/marble, -/obj/item/weapon/flame/lighter/zippo, -/obj/item/weapon/tool/screwdriver, -/obj/item/clothing/head/that{ - pixel_x = 4; - pixel_y = 6 +/obj/machinery/alarm{ + pixel_y = 25 }, -/obj/machinery/light, -/obj/machinery/button/remote/blast_door{ - dir = 1; - id = "bar"; - name = "Bar shutters"; - pixel_x = 0; - pixel_y = -25 - }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aIU" = ( -/obj/machinery/light{ - dir = 8; - icon_state = "tube1" +/obj/machinery/vending/snack{ + dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 5 - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/turf/simulated/floor/wood, +/area/crew_quarters/bar) "aIV" = ( -/obj/structure/sink{ - dir = 4; - icon_state = "sink"; - pixel_x = 11; - pixel_y = 0 +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 4 }, -/obj/structure/mirror{ - pixel_x = 27 +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 10 +/obj/structure/disposalpipe/junction{ + dir = 2; + icon_state = "pipe-j2" }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) "aIW" = ( /obj/machinery/light{ dir = 8; @@ -19161,6 +20805,32 @@ }, /turf/simulated/floor/tiled, /area/rnd/outpost/xenobiology/outpost_breakroom) +"aJc" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 4 + }, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) "aJd" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/tiled, @@ -19274,6 +20944,10 @@ /obj/machinery/door/airlock/glass_external/public, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"aJq" = ( +/obj/structure/bed/chair/comfy, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aJr" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -19300,44 +20974,25 @@ /turf/simulated/wall, /area/tether/surfacebase/bar_backroom) "aJu" = ( -/obj/machinery/door/airlock{ - name = "Bar Backroom"; - req_access = list(25) +/obj/effect/floor_decal/corner/lime/border{ + dir = 8 }, -/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" - }, -/obj/machinery/door/firedoor/glass, -/turf/simulated/floor/lino, -/area/tether/surfacebase/bar_backroom) +/obj/machinery/portable_atmospherics/hydroponics, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) "aJv" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/power/apc{ - cell_type = /obj/item/weapon/cell/apc; - dir = 8; - name = "west bump"; - pixel_x = -28 +/obj/structure/table/gamblingtable, +/obj/item/weapon/storage/pill_bottle/dice_nerd, +/obj/structure/disposalpipe/segment{ + dir = 8 }, -/obj/structure/cable/green, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/turf/simulated/floor/carpet/turcarpet, +/area/crew_quarters/bar) "aJw" = ( -/obj/structure/sink{ - dir = 4; - icon_state = "sink"; - pixel_x = 11; - pixel_y = 0 - }, -/obj/structure/mirror{ - pixel_x = 27 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/obj/structure/flora/ausbushes/ppflowers, +/obj/structure/flora/ausbushes/lavendergrass, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) "aJx" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/disposalpipe/segment, @@ -19453,6 +21108,22 @@ /obj/effect/floor_decal/industrial/warning, /turf/simulated/floor/tiled, /area/rnd/research/testingrange) +"aJJ" = ( +/obj/effect/floor_decal/corner/lime/border, +/obj/machinery/portable_atmospherics/hydroponics, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aJK" = ( +/obj/item/weapon/stool/padded, +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/turf/simulated/floor/carpet/turcarpet, +/area/crew_quarters/bar) "aJL" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 4; @@ -19604,15 +21275,21 @@ /turf/simulated/floor/tiled/steel_grid, /area/assembly/chargebay) "aJV" = ( -/obj/structure/table/marble, -/obj/machinery/chemical_dispenser/bar_alc/full{ - dir = 1 +/obj/structure/table/glass, +/obj/structure/window/reinforced{ + dir = 8 }, -/obj/machinery/camera/network/civilian{ - dir = 1 +/obj/item/weapon/packageWrap, +/obj/item/device/destTagger{ + pixel_x = 4; + pixel_y = 3 }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled, +/area/hydroponics) "aJW" = ( /obj/effect/floor_decal/industrial/warning{ dir = 1; @@ -19664,11 +21341,24 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/shuttle_pad) "aKc" = ( -/obj/machinery/camera/network/civilian{ - dir = 4 +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor/glass, +/obj/effect/floor_decal/spline/plain{ + dir = 1 }, -/turf/simulated/floor/tiled/freezer, -/area/crew_quarters/freezer) +/obj/machinery/door/blast/shutters{ + dir = 1; + id = "kitchen2"; + layer = 3.3; + name = "Kitchen Shutters" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "aKd" = ( /obj/effect/floor_decal/borderfloorblack/corner{ dir = 8; @@ -19728,6 +21418,22 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, /area/tether/surfacebase/shuttle_pad) +"aKl" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 6 + }, +/obj/machinery/portable_atmospherics/hydroponics, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"aKm" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aKn" = ( /obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary{ scrub_id = "atrium" @@ -19735,65 +21441,64 @@ /turf/simulated/floor/tiled/techmaint, /area/crew_quarters/bar) "aKo" = ( -/obj/structure/closet/secure_closet/bar{ - req_access = list(25) - }, -/obj/machinery/camera/network/civilian{ +/obj/item/weapon/stool/padded, +/obj/effect/floor_decal/spline/plain{ dir = 4 }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/carpet/turcarpet, +/area/crew_quarters/bar) "aKp" = ( -/obj/structure/sink{ - pixel_y = 25 +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/item/weapon/paper{ + desc = ""; + info = "Yes hello, the goat in the freezer is named 'Spike'. Please do not fuck with Spike. He doesn't have the best temper."; + name = "Important notice from Rancher Jim" }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "aKq" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 5 +/obj/effect/floor_decal/spline/plain{ + dir = 6 }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/carpet/turcarpet, +/area/crew_quarters/bar) "aKr" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) +/area/crew_quarters/bar) "aKs" = ( -/obj/structure/table/woodentable, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/obj/structure/sign/securearea{ - desc = "Under the painting a plaque reads: 'While the meat grinder may not have spared you, fear not. Not one part of you has gone to waste... You were delicious.'"; - icon_state = "monkey_painting"; - name = "Mr. Deempisi portrait"; - pixel_x = 4; - pixel_y = 28 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 }, /turf/simulated/floor/wood, /area/tether/surfacebase/bar_backroom) "aKt" = ( -/obj/machinery/camera/network/civilian, -/turf/simulated/floor/grass, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/airlock/glass{ + name = "Garden"; + req_access = list(28) + }, +/turf/simulated/floor/tiled/freezer, /area/hydroponics/cafegarden) "aKu" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/effect/floor_decal/corner/grey/diagonal, /turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/area/crew_quarters/kitchen) "aKv" = ( /obj/machinery/disposal, /obj/structure/disposalpipe/trunk{ @@ -19806,31 +21511,52 @@ /turf/simulated/floor/wood, /area/crew_quarters/recreation_area) "aKw" = ( -/obj/machinery/light/small{ - dir = 1 +/obj/machinery/light, +/mob/living/simple_mob/animal/passive/chicken, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) +"aKx" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ +/obj/effect/floor_decal/borderfloor{ dir = 4 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) -"aKx" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9; - pixel_y = 0 +/obj/effect/floor_decal/corner/beige/border{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 10 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 9 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) -"aKy" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 1 + dir = 8 }, -/obj/machinery/firealarm{ - dir = 4; - pixel_x = 26 +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"aKy" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/machinery/power/apc{ + dir = 1; + name = "north bump"; + pixel_x = 0; + pixel_y = 24 }, /turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/area/crew_quarters/kitchen) "aKz" = ( /obj/structure/window/basic/full, /obj/structure/grille, @@ -20094,63 +21820,74 @@ /turf/simulated/floor/tiled/techfloor, /area/tether/surfacebase/shuttle_pad) "aLb" = ( -/obj/structure/table/woodentable, -/obj/machinery/alarm{ - dir = 4; - icon_state = "alarm0"; - pixel_x = -22; - pixel_y = 0 +/obj/structure/closet/crate, +/obj/machinery/firealarm{ + dir = 1; + pixel_x = 0; + pixel_y = -24 }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aLc" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) -"aLd" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 9; - pixel_y = 0 - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) -"aLe" = ( -/obj/effect/landmark/start{ - name = "Bartender" - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) -"aLf" = ( -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) -"aLg" = ( -/obj/item/weapon/storage/secure/safe{ - pixel_x = 30; - pixel_z = 0 +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/disposalpipe/segment{ + dir = 8 }, /obj/effect/landmark/start{ - name = "Bartender" + name = "Chef" }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) -"aLh" = ( /turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/area/crew_quarters/kitchen) +"aLd" = ( +/obj/structure/bed/chair/wood, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"aLe" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/machinery/door/blast/shutters{ + density = 0; + dir = 2; + icon_state = "shutter0"; + id = "freezer"; + name = "Freezer Shutters"; + opacity = 0 + }, +/turf/simulated/floor/plating, +/area/crew_quarters/freezer) +"aLf" = ( +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals4{ + dir = 6 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"aLg" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/camera/network/civilian{ + dir = 1 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"aLh" = ( +/obj/machinery/light, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 + }, +/obj/effect/floor_decal/corner/beige/border, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aLi" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable/green{ @@ -20371,81 +22108,99 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/shuttle_pad) "aLC" = ( -/obj/structure/table/woodentable, -/obj/item/weapon/storage/box/beanbags, -/obj/item/weapon/gun/projectile/shotgun/doublebarrel, -/obj/item/weapon/paper{ - info = "This permit signifies that the Bartender is permitted to posess this firearm in the bar, and ONLY the bar. Failure to adhere to this permit will result in confiscation of the weapon and possibly arrest."; - name = "Shotgun permit" +/obj/structure/window/reinforced/full, +/obj/structure/grille, +/obj/structure/window/reinforced/tinted{ + dir = 1 }, -/obj/machinery/light_switch{ - pixel_x = -25 - }, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aLD" = ( -/obj/structure/table/woodentable, -/obj/machinery/reagentgrinder, -/obj/item/weapon/reagent_containers/food/drinks/shaker, -/obj/item/weapon/packageWrap, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) +/obj/structure/window/reinforced/full, +/obj/structure/grille, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/obj/structure/window/reinforced/tinted{ + dir = 4; + icon_state = "twindow" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aLE" = ( +/obj/structure/cable/green{ + 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, +/area/tether/surfacebase/servicebackroom) +"aLF" = ( /obj/structure/table/woodentable, -/obj/machinery/firealarm{ - dir = 1; +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aLG" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/requests_console{ + pixel_x = 32; + pixel_y = -32 + }, +/obj/item/device/radio/intercom{ pixel_y = -24 }, -/obj/item/weapon/reagent_containers/food/drinks/metaglass, -/obj/item/weapon/reagent_containers/food/drinks/metaglass, -/obj/item/weapon/reagent_containers/food/drinks/metaglass, -/obj/item/weapon/reagent_containers/food/drinks/metaglass, -/obj/item/weapon/reagent_containers/food/drinks/metaglass, -/obj/item/weapon/reagent_containers/food/drinks/metaglass, -/obj/item/weapon/reagent_containers/food/drinks/metaglass, -/obj/item/weapon/reagent_containers/food/drinks/metaglass, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) -"aLF" = ( -/obj/machinery/power/apc{ - dir = 2; - name = "south bump"; - pixel_y = -28 - }, -/obj/structure/cable/green, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) -"aLG" = ( -/obj/structure/reagent_dispensers/beerkeg, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) +/turf/simulated/floor/grass, +/area/hydroponics) "aLH" = ( -/obj/structure/closet/gmcloset{ - name = "formal wardrobe" +/obj/structure/disposalpipe/trunk{ + dir = 1 }, -/obj/item/glass_jar, -/obj/item/device/retail_scanner/civilian, -/obj/item/device/retail_scanner/civilian, -/turf/simulated/floor/wood, -/area/tether/surfacebase/bar_backroom) +/obj/machinery/disposal/deliveryChute, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/obj/machinery/conveyor{ + dir = 1; + id = "serviceblock2" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aLI" = ( -/obj/machinery/door/airlock{ - name = "Unit 3" +/obj/structure/window/reinforced/full, +/obj/structure/grille, +/obj/structure/window/reinforced/tinted{ + dir = 4; + icon_state = "twindow" }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/obj/structure/window/reinforced/tinted{ + dir = 8; + icon_state = "twindow" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aLJ" = ( -/obj/machinery/door/airlock{ - name = "Unit 2" +/obj/structure/table/woodentable, +/obj/item/weapon/storage/box/sinpockets, +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aLK" = ( -/obj/machinery/door/airlock{ - name = "Unit 1" +/obj/structure/plasticflaps, +/obj/machinery/conveyor{ + dir = 1; + id = "serviceblock2" }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aLL" = ( /obj/machinery/camera/network/civilian{ dir = 1 @@ -20666,23 +22421,25 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/shuttle_pad) "aMg" = ( -/obj/machinery/light/small{ +/obj/structure/window/reinforced/full, +/obj/structure/grille, +/obj/structure/window/reinforced/tinted, +/obj/structure/window/reinforced/tinted{ dir = 4; - pixel_y = 0 + icon_state = "twindow" }, -/obj/machinery/recharge_station, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/obj/structure/window/reinforced/tinted{ + dir = 8; + icon_state = "twindow" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aMh" = ( -/obj/machinery/light/small{ - dir = 4; - pixel_y = 0 - }, -/obj/structure/toilet{ +/obj/structure/bed/chair/comfy{ dir = 1 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aMi" = ( /obj/structure/flora/pottedplant/unusual, /obj/machinery/firealarm{ @@ -21622,28 +23379,14 @@ /turf/simulated/wall/r_wall, /area/rnd/outpost/xenobiology/outpost_south_airlock) "aOg" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/machinery/camera/network/tether{ - dir = 9 +/obj/effect/floor_decal/corner/lime/border, +/obj/machinery/light, +/obj/machinery/portable_atmospherics/hydroponics, +/obj/machinery/camera/network/civilian{ + dir = 1 }, /turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) +/area/tether/surfacebase/botanystorage) "aOh" = ( /obj/structure/cable/green, /obj/machinery/power/apc{ @@ -22369,6 +24112,13 @@ }, /turf/simulated/wall, /area/rnd/outpost/xenobiology/outpost_breakroom) +"aPF" = ( +/obj/machinery/conveyor{ + dir = 1; + id = "serviceblock2" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aPG" = ( /obj/random/mob/mouse, /turf/simulated/floor/tiled, @@ -23089,12 +24839,14 @@ /turf/simulated/wall, /area/rnd/outpost/xenobiology/outpost_autopsy) "aRm" = ( -/obj/machinery/camera/network/outside{ - dir = 5; - icon_state = "camera" +/obj/machinery/conveyor_switch/oneway{ + id = "serviceblock2" }, -/turf/simulated/floor/outdoors/grass/sif/virgo3b, -/area/tether/surfacebase/outside/outside3) +/obj/effect/floor_decal/industrial/warning{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aRn" = ( /obj/machinery/newscaster, /turf/simulated/wall, @@ -23482,6 +25234,10 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/plating, /area/rnd/outpost/xenobiology/outpost_main) +"aRX" = ( +/obj/machinery/atmospherics/unary/vent_pump/on, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aRY" = ( /obj/structure/bed/roller, /obj/structure/extinguisher_cabinet{ @@ -23585,6 +25341,10 @@ }, /turf/simulated/floor/tiled/dark, /area/rnd/outpost/xenobiology/outpost_main) +"aSh" = ( +/obj/effect/floor_decal/industrial/outline/blue, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aSi" = ( /obj/structure/window/basic/full, /obj/structure/window/basic{ @@ -23624,6 +25384,13 @@ }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/triage) +"aSl" = ( +/obj/effect/floor_decal/industrial/warning{ + dir = 8; + icon_state = "warning" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aSm" = ( /obj/machinery/atmospherics/pipe/simple/hidden/cyan{ dir = 4 @@ -23776,6 +25543,19 @@ }, /turf/simulated/floor/tiled, /area/rnd/outpost/xenobiology/outpost_main) +"aSx" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"aSy" = ( +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aSz" = ( /obj/structure/window/basic/full, /obj/structure/window/basic, @@ -24189,6 +25969,18 @@ }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/chemistry) +"aTc" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aTd" = ( /obj/structure/table/reinforced, /obj/effect/floor_decal/borderfloorwhite{ @@ -24407,6 +26199,12 @@ }, /turf/simulated/floor/tiled/dark, /area/bridge) +"aTw" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aTx" = ( /obj/structure/window/basic/full, /obj/structure/grille, @@ -24493,6 +26291,59 @@ }, /turf/simulated/floor/tiled/dark, /area/rnd/outpost/xenobiology/outpost_south_airlock) +"aTE" = ( +/obj/structure/table/woodentable, +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"aTF" = ( +/obj/structure/closet/crate/plastic, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/hydroponics) +"aTG" = ( +/obj/structure/table/woodentable, +/obj/item/device/destTagger{ + pixel_x = 4; + pixel_y = 3 + }, +/obj/item/weapon/packageWrap, +/obj/item/weapon/packageWrap, +/obj/item/device/destTagger{ + pixel_x = 4; + pixel_y = 3 + }, +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aTH" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aTI" = ( +/obj/structure/closet/crate, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aTJ" = ( +/obj/machinery/conveyor{ + dir = 1; + id = "serviceblock1" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aTK" = ( /obj/structure/table/glass, /obj/machinery/light{ @@ -24542,25 +26393,21 @@ /turf/simulated/floor/wood, /area/tether/surfacebase/reading_room) "aTO" = ( -/obj/machinery/door/airlock{ - id_tag = "ReadingRoom2"; - name = "Room 2" +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/lightgrey/border, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 8 }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/machinery/light, /turf/simulated/floor/tiled, -/area/tether/surfacebase/reading_room) +/area/tether/surfacebase/surface_three_hall) "aTP" = ( -/obj/machinery/door/airlock{ - id_tag = "ReadingRoom3"; - name = "Room 3" - }, -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/reading_room) +/obj/item/weapon/card/id/gold/captain/spare/fakespare, +/turf/simulated/floor/plating, +/area/tether/surfacebase/surface_three_hall) "aTQ" = ( /obj/effect/floor_decal/industrial/warning{ dir = 8; @@ -24581,6 +26428,15 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"aTS" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "serviceblock1" + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 10 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aTT" = ( /obj/machinery/door/morgue{ dir = 2; @@ -24711,14 +26567,17 @@ /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) "aUg" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/obj/machinery/vending/wallmed1/public{ - pixel_y = 28 +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/barrestroom) +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aUh" = ( /obj/effect/floor_decal/steeldecal/steel_decals4, /obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers, @@ -24794,6 +26653,12 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"aUn" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aUo" = ( /obj/machinery/door/airlock/multi_tile/glass, /obj/effect/floor_decal/industrial/warning/corner{ @@ -24819,6 +26684,17 @@ dir = 4 }, /area/hallway/lower/third_south) +"aUq" = ( +/obj/structure/closet/secure_closet/freezer/meat, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"aUr" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aUs" = ( /obj/effect/floor_decal/techfloor/corner{ dir = 8 @@ -24931,6 +26807,14 @@ }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/triage) +"aUB" = ( +/obj/structure/plasticflaps, +/obj/machinery/conveyor{ + dir = 1; + id = "serviceblock1" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aUC" = ( /obj/effect/floor_decal/borderfloor/corner, /obj/effect/floor_decal/corner/lime/bordercorner, @@ -25095,6 +26979,22 @@ }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/chemistry) +"aUT" = ( +/obj/structure/window/reinforced/full, +/obj/structure/grille, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/obj/structure/window/reinforced/tinted{ + dir = 4; + icon_state = "twindow" + }, +/obj/structure/window/reinforced/tinted{ + dir = 8; + icon_state = "twindow" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aUU" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -25197,6 +27097,17 @@ }, /turf/simulated/floor/plating, /area/maintenance/lower/mining) +"aVd" = ( +/obj/machinery/conveyor{ + dir = 1; + id = "serviceblock1" + }, +/obj/structure/disposalpipe/trunk, +/obj/structure/disposaloutlet{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aVe" = ( /obj/structure/table/glass, /obj/item/weapon/storage/box/cups, @@ -25415,6 +27326,15 @@ }, /turf/simulated/floor/tiled/white, /area/tether/surfacebase/medical/triage) +"aVw" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aVx" = ( /obj/machinery/firealarm{ dir = 8; @@ -25422,6 +27342,12 @@ }, /turf/simulated/floor/grass, /area/tether/surfacebase/public_garden_three) +"aVy" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aVz" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -25440,11 +27366,27 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"aVB" = ( +/obj/structure/bed/chair/wood{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aVC" = ( -/obj/structure/shuttle/engine/propulsion, -/turf/simulated/floor/reinforced, -/turf/simulated/shuttle/plating/carry, -/area/shuttle/tether) +/obj/structure/bed/chair/wood{ + dir = 1 + }, +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aVD" = ( /obj/effect/floor_decal/borderfloor{ dir = 5 @@ -25608,6 +27550,24 @@ }, /turf/simulated/floor/plating, /area/tether/surfacebase/security/lobby) +"aVO" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"aVP" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/lime/border{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aVQ" = ( /obj/effect/floor_decal/borderfloor{ dir = 10 @@ -25620,6 +27580,17 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"aVR" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "aVS" = ( /obj/item/device/radio/intercom{ dir = 2; @@ -25864,6 +27835,28 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"aWk" = ( +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"aWl" = ( +/obj/structure/table/woodentable, +/obj/random/drinkbottle, +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "aWm" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -26112,6 +28105,39 @@ /obj/effect/floor_decal/steeldecal/steel_decals7, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"aWC" = ( +/turf/simulated/wall, +/area/tether/surfacebase/entertainment/backstage) +"aWD" = ( +/obj/structure/sign/directions/medical{ + dir = 4; + pixel_y = 8 + }, +/obj/structure/sign/directions/science{ + dir = 8; + pixel_y = 3 + }, +/obj/structure/sign/directions/security{ + dir = 8; + pixel_y = -4 + }, +/obj/structure/sign/directions/engineering{ + dir = 8; + pixel_y = -10 + }, +/turf/simulated/wall, +/area/tether/surfacebase/entertainment/backstage) +"aWE" = ( +/obj/structure/table/glass, +/obj/machinery/door/window/westright{ + req_one_access = list(35,28) + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled, +/area/hydroponics) "aWF" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -26183,6 +28209,10 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"aWM" = ( +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/grass, +/area/hydroponics) "aWN" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/lightgrey/border, @@ -26431,6 +28461,36 @@ }, /turf/simulated/floor/wood, /area/library) +"aXg" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"aXh" = ( +/obj/machinery/alarm{ + dir = 1; + pixel_y = -25 + }, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aXi" = ( +/obj/structure/extinguisher_cabinet{ + pixel_y = -30 + }, +/obj/machinery/door/firedoor/glass/hidden/steel, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aXj" = ( +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aXk" = ( /obj/structure/sign/directions/medical{ dir = 1; @@ -26600,6 +28660,19 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) +"aXv" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aXw" = ( /obj/structure/closet/hydrant{ pixel_x = 32 @@ -26809,6 +28882,15 @@ /obj/item/weapon/locator, /turf/simulated/floor/plating, /area/rnd/research_storage) +"aXK" = ( +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) "aXL" = ( /obj/structure/grille, /obj/structure/window/reinforced/full, @@ -26818,6 +28900,27 @@ }, /turf/simulated/floor/plating, /area/rnd/research_storage) +"aXM" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/structure/disposalpipe/junction/yjunction{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) "aXN" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/floor_decal/rust, @@ -26857,22 +28960,65 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/plating, /area/rnd/research_storage) +"aXS" = ( +/obj/structure/bed/chair/comfy, +/obj/machinery/camera/network/civilian, +/obj/machinery/firealarm{ + dir = 4; + layer = 3.3; + pixel_x = 26 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"aXT" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aXU" = ( -/obj/machinery/computer/security/telescreen/entertainment{ - desc = "Damn, looks like it's on the clown world channel. I wonder what else is on?"; - icon_state = "frame"; - pixel_x = 0; - pixel_y = 32 +/obj/structure/disposalpipe/segment{ + dir = 8 }, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/bar) +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aXV" = ( -/obj/machinery/atmospherics/unary/engine{ - dir = 1 +/obj/structure/disposalpipe/segment{ + dir = 8 }, -/turf/simulated/floor/reinforced, -/turf/simulated/shuttle/plating/carry, -/area/shuttle/tourbus/engines) +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aXW" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -27229,6 +29375,9 @@ }, /turf/simulated/floor/tiled/dark, /area/bridge) +"aYC" = ( +/turf/simulated/wall, +/area/tether/surfacebase/entertainment) "aYD" = ( /obj/machinery/computer/power_monitor{ dir = 8; @@ -27315,6 +29464,10 @@ }, /turf/simulated/floor/tiled/dark, /area/bridge) +"aYN" = ( +/obj/effect/floor_decal/corner/mauve/border, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aYO" = ( /turf/simulated/wall/r_wall, /area/maintenance/commandmaint) @@ -27443,6 +29596,29 @@ }, /turf/simulated/floor/tiled/dark, /area/bridge_hallway) +"aZd" = ( +/obj/effect/floor_decal/borderfloor/corner{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 1 + }, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/obj/effect/floor_decal/corner/beige/bordercorner{ + dir = 8; + icon_state = "bordercolorcorner" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) "aZe" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 4 @@ -27455,6 +29631,23 @@ }, /turf/simulated/floor/tiled/white, /area/rnd/outpost/xenobiology/outpost_first_aid) +"aZg" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 1 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aZh" = ( /obj/machinery/door/airlock/glass_command{ name = "Bridge"; @@ -27682,6 +29875,18 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/wood, /area/crew_quarters/captain) +"aZy" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/camera/network/civilian{ + dir = 1 + }, +/turf/simulated/floor/grass, +/area/hydroponics) "aZz" = ( /obj/structure/bed/chair{ dir = 1 @@ -27719,6 +29924,24 @@ "aZC" = ( /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) +"aZD" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 1 + }, +/obj/machinery/station_map{ + pixel_y = 32 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 2 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) "aZE" = ( /obj/effect/floor_decal/industrial/outline/yellow, /obj/machinery/light{ @@ -27778,6 +30001,28 @@ }, /turf/simulated/floor/tiled/dark, /area/bridge) +"aZJ" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "aZK" = ( /obj/machinery/sleep_console, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -27791,6 +30036,43 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/captain) +"aZM" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/machinery/door/blast/regular/open{ + dir = 8; + icon_state = "pdoor0" + }, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/machinery/door/blast/regular/open{ + dir = 4; + icon_state = "pdoor0"; + id = "DRAMATIC"; + name = "Dramatic Blast Door" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 1; + icon_state = "rwindow"; + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 1; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) "aZN" = ( /obj/structure/table/reinforced, /obj/machinery/photocopier/faxmachine{ @@ -27820,6 +30102,17 @@ /obj/item/weapon/pen/multi, /turf/simulated/floor/carpet, /area/crew_quarters/heads/hop) +"aZQ" = ( +/obj/machinery/hologram/holopad, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "aZR" = ( /obj/effect/floor_decal/industrial/outline/yellow, /obj/structure/window/basic{ @@ -27846,6 +30139,14 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"aZT" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "aZU" = ( /obj/structure/table/woodentable, /obj/machinery/computer/skills{ @@ -27879,6 +30180,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/wood, /area/crew_quarters/captain) +"aZX" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/foodcart, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "aZY" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -28016,6 +30322,40 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/captain) +"bah" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/machinery/door/blast/regular/open{ + dir = 8; + icon_state = "pdoor0" + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/machinery/door/blast/regular/open{ + dir = 4; + icon_state = "pdoor0"; + id = "DRAMATIC"; + name = "Dramatic Blast Door" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 1; + icon_state = "rwindow"; + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 1; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) "bai" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 @@ -28113,6 +30453,15 @@ /obj/structure/cable/green, /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) +"baq" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) "bar" = ( /obj/machinery/computer/communications, /obj/machinery/light/small{ @@ -28148,6 +30497,54 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) +"baw" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/disposalpipe/segment{ + dir = 1; + icon_state = "pipe-c" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bax" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/machinery/door/blast/regular/open{ + dir = 2; + icon_state = "pdoor0"; + id = "DRAMATIC" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 4; + icon_state = "rwindow"; + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 4; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/obj/structure/cable/green{ + icon_state = "0-2" + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) +"bay" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) "baz" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/lightgrey/border, @@ -28160,6 +30557,90 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"baA" = ( +/obj/item/weapon/stool/padded, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" + }, +/turf/simulated/floor/carpet/turcarpet, +/area/crew_quarters/bar) +"baB" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/camera/network/civilian{ + dir = 1 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"baC" = ( +/obj/machinery/vending/cola{ + dir = 1 + }, +/obj/machinery/light, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"baD" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/corner/lightgrey/border{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/machinery/atmospherics/unary/vent_pump/on, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"baE" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"baF" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/door/airlock/freezer{ + name = "Service"; + 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) "baG" = ( /obj/structure/bed/chair/comfy/brown{ dir = 8 @@ -28193,6 +30674,10 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"baI" = ( +/obj/machinery/icecream_vat, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) "baJ" = ( /obj/structure/cable{ icon_state = "1-2" @@ -28265,6 +30750,24 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) +"baO" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/vending/dinnerware{ + dir = 4; + icon_state = "dinnerware" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"baP" = ( +/obj/structure/table/woodentable, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) "baQ" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -28285,6 +30788,27 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"baR" = ( +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"baS" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/window/reinforced/full, +/obj/structure/grille, +/obj/structure/window/reinforced/tinted, +/obj/structure/window/reinforced/tinted{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"baT" = ( +/obj/machinery/alarm{ + dir = 1; + pixel_y = -22 + }, +/obj/machinery/media/jukebox, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) "baU" = ( /obj/structure/table/reinforced, /obj/machinery/computer/skills, @@ -28294,6 +30818,40 @@ /obj/machinery/computer/card, /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) +"baW" = ( +/obj/machinery/firealarm{ + dir = 1; + pixel_x = 0; + pixel_y = -25 + }, +/obj/machinery/computer/security/telescreen/entertainment{ + icon_state = "frame"; + pixel_x = 32; + pixel_y = 0 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"baX" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/light{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"baY" = ( +/obj/structure/window/reinforced/full, +/obj/structure/grille, +/obj/structure/window/reinforced/tinted, +/obj/structure/window/reinforced/tinted{ + dir = 4; + icon_state = "twindow" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"baZ" = ( +/obj/random/cutout, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) "bba" = ( /turf/simulated/floor/wood, /area/crew_quarters/captain) @@ -28315,6 +30873,63 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) +"bbd" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bbe" = ( +/obj/machinery/firealarm{ + dir = 2; + layer = 3.3; + pixel_x = 0; + pixel_y = 26 + }, +/obj/machinery/vending/loadout/accessory, +/obj/machinery/alarm{ + dir = 8; + icon_state = "alarm0"; + pixel_x = 24 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bbf" = ( +/obj/structure/bed/chair/wood{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bbg" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/flame/candle, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bbh" = ( +/obj/structure/bed/chair/wood{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) "bbi" = ( /obj/effect/floor_decal/industrial/outline/yellow, /obj/machinery/light, @@ -28329,6 +30944,39 @@ }, /turf/simulated/floor/tiled, /area/crew_quarters/heads/hop) +"bbk" = ( +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bbl" = ( +/obj/structure/bed/chair/wood, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bbm" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/camera/network/tether{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"bbn" = ( +/obj/structure/sign/directions/evac{ + dir = 1 + }, +/turf/simulated/wall, +/area/tether/surfacebase/entertainment) +"bbo" = ( +/obj/machinery/door/window/westright{ + req_one_access = list(35,28) + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) "bbp" = ( /obj/structure/filingcabinet/chestdrawer, /turf/simulated/floor/tiled, @@ -28343,6 +30991,15 @@ /obj/structure/bed/chair/wood, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"bbr" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "bbs" = ( /obj/effect/floor_decal/corner/lightgrey{ dir = 9 @@ -28379,6 +31036,25 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"bbv" = ( +/obj/machinery/power/apc{ + cell_type = /obj/item/weapon/cell/super; + dir = 1; + name = "north bump"; + pixel_x = 0; + pixel_y = 24 + }, +/obj/structure/cable/green{ + icon_state = "0-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "bbw" = ( /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, @@ -28420,6 +31096,24 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"bbz" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/airlock/glass, +/obj/effect/floor_decal/corner/beige/border{ + dir = 8; + icon_state = "bordercolor" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) "bbA" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -28440,6 +31134,16 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"bbB" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) "bbC" = ( /obj/item/device/radio/intercom{ dir = 8; @@ -28516,6 +31220,1213 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/captain) +"bbI" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/flame/candle, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"bbJ" = ( +/obj/machinery/firealarm{ + dir = 2; + layer = 3.3; + pixel_x = 0; + pixel_y = 26 + }, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bbK" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bbL" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bbM" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 8; + icon_state = "spline_plain" + }, +/obj/item/weapon/stool/padded, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bbN" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"bbO" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bbP" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/flame/candle, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bbQ" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/reagent_containers/food/drinks/metaglass, +/obj/item/weapon/reagent_containers/food/drinks/metaglass, +/obj/item/weapon/reagent_containers/food/drinks/metaglass, +/obj/item/weapon/reagent_containers/food/drinks/metaglass, +/obj/machinery/power/apc{ + dir = 4; + name = "east bump"; + pixel_x = 28 + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"bbR" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bbS" = ( +/obj/structure/table/marble, +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "bar"; + layer = 3.3; + name = "Bar Shutters" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bbT" = ( +/obj/structure/table/woodentable, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bbU" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bbV" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 8; + icon_state = "spline_plain" + }, +/obj/item/weapon/stool/padded, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bbW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"bbX" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"bbY" = ( +/obj/effect/floor_decal/spline/plain, +/obj/item/weapon/stool/padded, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bbZ" = ( +/obj/effect/floor_decal/spline/plain, +/obj/item/weapon/stool/padded, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bca" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/camera/network/civilian, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bcb" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bcc" = ( +/obj/structure/cable/green{ + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bcd" = ( +/obj/machinery/power/apc{ + cell_type = /obj/item/weapon/cell/apc; + dir = 8; + name = "west bump"; + pixel_x = -28 + }, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"bce" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bcf" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bcg" = ( +/obj/structure/table/marble, +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/window/westright{ + dir = 1; + icon_state = "right"; + name = "Botany"; + req_one_access = list(35,28) + }, +/obj/machinery/door/window/westright{ + dir = 2; + icon_state = "right"; + name = "Kitchen"; + req_access = list(28) + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bch" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 6 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/surface_three_hall) +"bci" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bcj" = ( +/obj/machinery/vending/loadout/costume, +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bck" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bcl" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bcm" = ( +/obj/structure/bed/chair/wood{ + dir = 1 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bcn" = ( +/obj/machinery/power/apc{ + cell_type = /obj/item/weapon/cell/super; + dir = 8; + name = "west bump"; + pixel_x = -30 + }, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bco" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/machinery/door/blast/regular/open{ + dir = 2; + icon_state = "pdoor0"; + id = "DRAMATIC" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 4; + icon_state = "rwindow"; + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 4; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/structure/cable/green, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) +"bcp" = ( +/obj/machinery/requests_console{ + pixel_x = 32; + pixel_y = -32 + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/button/remote/blast_door{ + id = "bar"; + name = "Bar Shutter Control"; + pixel_x = 24; + pixel_y = 24 + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bcq" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/machinery/door/blast/regular/open{ + dir = 2; + icon_state = "pdoor0"; + id = "DRAMATIC" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 4; + icon_state = "rwindow"; + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 4; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) +"bcr" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/entertainment/stage) +"bcs" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 8; + icon_state = "bordercolor" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bct" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 8; + icon_state = "bordercolor" + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 10 + }, +/obj/effect/floor_decal/corner/beige/bordercorner2{ + dir = 10; + icon_state = "bordercolorcorner2" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bcu" = ( +/obj/structure/table/marble, +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/window/brigdoor/northleft{ + dir = 2; + icon_state = "leftsecure"; + name = "Bar"; + req_access = list(25) + }, +/obj/machinery/door/window/westright{ + dir = 1; + icon_state = "right"; + name = "Kitchen"; + req_access = list(28) + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bcv" = ( +/obj/machinery/power/apc{ + cell_type = /obj/item/weapon/cell/super; + dir = 1; + name = "north bump"; + pixel_x = 0; + pixel_y = 24 + }, +/obj/structure/cable/green{ + icon_state = "0-2" + }, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bcw" = ( +/obj/machinery/light, +/obj/structure/bed/chair/comfy{ + dir = 4; + icon_state = "comfychair" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bcx" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 10 + }, +/obj/effect/floor_decal/corner/beige/bordercorner2{ + dir = 8; + icon_state = "bordercolorcorner2" + }, +/obj/effect/floor_decal/corner/beige/bordercorner2{ + dir = 10; + icon_state = "bordercolorcorner2" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bcy" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/machinery/computer/guestpass{ + dir = 4; + pixel_x = -28; + pixel_y = 0 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 8; + icon_state = "bordercolor" + }, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 8 + }, +/obj/effect/floor_decal/corner/beige/bordercorner2{ + dir = 8; + icon_state = "bordercolorcorner2" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bcz" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 8; + icon_state = "bordercolor" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bcA" = ( +/obj/structure/extinguisher_cabinet{ + dir = 4; + icon_state = "extinguisher_closed"; + pixel_x = -30 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 6 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 8; + icon_state = "bordercolor" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bcB" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bcC" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/light, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bcD" = ( +/obj/structure/closet/crate, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bcE" = ( +/obj/structure/closet/crate, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bcF" = ( +/obj/machinery/camera/network/civilian{ + dir = 9 + }, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) +"bcG" = ( +/obj/effect/floor_decal/industrial/outline/blue, +/obj/machinery/camera/network/civilian{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bcH" = ( +/obj/machinery/floodlight, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bcI" = ( +/turf/simulated/wall, +/area/tether/surfacebase/entertainment/stage) +"bcJ" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/entertainment/stage) +"bcK" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 5 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/entertainment/stage) +"bcL" = ( +/obj/structure/cable/green{ + icon_state = "2-4" + }, +/obj/structure/table/woodentable, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bcM" = ( +/obj/structure/bed/chair/wood{ + dir = 1 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bcN" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable/green{ + icon_state = "2-4" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bcO" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/machinery/door/firedoor/glass/hidden/steel, +/obj/effect/floor_decal/corner/beige/border{ + dir = 8; + icon_state = "bordercolor" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bcP" = ( +/obj/structure/table/rack/steel, +/obj/item/pizzavoucher, +/obj/item/weapon/moneybag, +/obj/item/weapon/inflatable_duck, +/obj/machinery/power/apc{ + dir = 4; + name = "east bump"; + pixel_x = 28 + }, +/obj/item/weapon/gun/projectile/revolver/capgun, +/obj/item/weapon/gun/projectile/revolver/capgun, +/obj/item/toy/cultsword, +/obj/item/toy/cultsword, +/obj/item/weapon/bikehorn/rubberducky, +/obj/item/weapon/reagent_containers/spray/cleaner, +/obj/structure/cable/green{ + icon_state = "0-2" + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bcQ" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bcR" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bcS" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bcT" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bcU" = ( +/obj/structure/table/rack/steel, +/obj/item/mecha_parts/part/durand_left_leg, +/obj/item/weapon/cane/crutch, +/obj/item/weapon/pack/cardemon, +/obj/item/weapon/soap/syndie, +/obj/item/weapon/soap/nanotrasen, +/obj/item/weapon/soap/deluxe, +/obj/item/weapon/staff/gentcane, +/obj/item/toy/crossbow, +/obj/item/toy/eight_ball/conch, +/obj/item/weapon/cell/potato, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/item/device/megaphone, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bcV" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/structure/table/rack/steel, +/obj/item/device/instrument/violin, +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bcW" = ( +/obj/effect/decal/cleanable/tomato_smudge, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/cable/green{ + icon_state = "2-4" + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bcX" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bcY" = ( +/obj/effect/landmark/start{ + name = "Entertainer" + }, +/obj/structure/bed/chair/wood{ + dir = 1 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bcZ" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/effect/decal/cleanable/tomato_smudge, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bda" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/obj/machinery/door/airlock/freezer{ + name = "Kitchen"; + req_access = list(28) + }, +/obj/effect/floor_decal/spline/plain{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bdb" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5 + }, +/obj/machinery/light_switch{ + name = "House Lights"; + pixel_x = -25 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment) +"bdc" = ( +/obj/effect/floor_decal/corner/mauve/border{ + dir = 1 + }, +/obj/machinery/alarm{ + pixel_y = 25 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"bdd" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/item/device/radio/intercom{ + dir = 4; + frequency = 1532; + name = "Stagehand Speaker"; + pixel_x = 24; + pixel_y = 24 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bde" = ( +/obj/machinery/light{ + dir = 4; + icon_state = "tube1"; + pixel_x = 0 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/bed/chair/wood{ + dir = 1 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bdf" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/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/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"bdg" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bdh" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/unary/vent_pump/on, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bdi" = ( +/obj/machinery/alarm{ + pixel_y = 25 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"bdj" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"bdk" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"bdl" = ( +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"bdm" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/item/device/radio/intercom{ + dir = 8; + frequency = 1532; + name = "Stagehand Mic"; + pixel_x = -24 + }, +/obj/item/weapon/stool/padded, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bdn" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/mob/living/carbon/human/monkey/punpun, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"bdo" = ( +/obj/effect/decal/cleanable/tomato_smudge, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bdp" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/machinery/light_switch{ + name = "Stage Lights"; + pixel_x = -25 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bdq" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bdr" = ( +/obj/structure/extinguisher_cabinet{ + pixel_y = 30 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 1; + icon_state = "bordercolor" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bds" = ( +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 1; + icon_state = "bordercolor" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bdt" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"bdu" = ( +/obj/machinery/atmospherics/unary/vent_pump/on, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"bdv" = ( +/obj/machinery/atmospherics/unary/vent_pump/on, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bdw" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bdx" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bdy" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/machinery/hologram/holopad, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bdz" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"bdA" = ( +/obj/structure/lattice, +/turf/simulated/open, +/area/tether/surfacebase/barbackmaintenance) +"bdB" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 8 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"bdC" = ( +/obj/structure/table/bench/standard, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/effect/landmark/start{ + name = "Botanist" + }, +/turf/simulated/floor/tiled, +/area/hydroponics) "bdD" = ( /obj/effect/floor_decal/corner/lightgrey{ dir = 9 @@ -28530,6 +32441,2090 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) +"bdE" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bdF" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bdG" = ( +/obj/machinery/hologram/holopad, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bdH" = ( +/obj/machinery/firealarm{ + dir = 1; + pixel_x = 0; + pixel_y = -24 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"bdI" = ( +/obj/structure/flora/ausbushes/sparsegrass, +/obj/structure/flora/ausbushes/ywflowers, +/obj/machinery/firealarm{ + dir = 4; + layer = 3.3; + pixel_x = 26 + }, +/turf/simulated/floor/grass, +/area/hydroponics/cafegarden) +"bdJ" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bdK" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/floor_decal/industrial/warning{ + dir = 8; + icon_state = "warning" + }, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"bdL" = ( +/obj/machinery/floodlight, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"bdM" = ( +/obj/structure/cable/green{ + 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/wood, +/area/crew_quarters/bar) +"bdN" = ( +/obj/machinery/portable_atmospherics/powered/scrubber, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"bdO" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/packageWrap, +/obj/item/device/destTagger{ + pixel_x = 4; + pixel_y = 3 + }, +/obj/machinery/light/small, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"bdP" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4; + icon_state = "pipe-c" + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bdQ" = ( +/obj/item/device/radio/intercom{ + dir = 2; + pixel_y = -24 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bdR" = ( +/obj/structure/kitchenspike, +/obj/machinery/camera/network/civilian{ + dir = 9 + }, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bdS" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/freezer{ + name = "Kitchen Cold Room"; + req_access = list(28) + }, +/obj/structure/fans/tiny, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/freezer) +"bdT" = ( +/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/white, +/area/crew_quarters/barrestroom) +"bdU" = ( +/obj/machinery/firealarm{ + dir = 2; + layer = 3.3; + pixel_x = 0; + pixel_y = 26 + }, +/obj/machinery/atmospherics/unary/vent_pump/on, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"bdV" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"bdW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5; + icon_state = "intact-supply" + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"bdX" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"bdY" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5; + icon_state = "intact-supply" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"bdZ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"bea" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"beb" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"bec" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/space_heater, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"bed" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/door/airlock/maintenance/int{ + name = "Entertainment Backroom"; + req_one_access = list(72,20,57) + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment/backstage) +"bee" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/computer/arcade/orion_trail, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bef" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"beg" = ( +/obj/structure/bed/chair/comfy/beige, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"beh" = ( +/obj/machinery/newscaster{ + pixel_y = -28 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bei" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bej" = ( +/obj/effect/floor_decal/corner/mauve/border, +/obj/machinery/seed_storage/xenobotany{ + dir = 1; + icon_state = "seeds" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"bek" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/requests_console{ + pixel_x = 32; + pixel_y = -32 + }, +/obj/machinery/light, +/obj/item/device/radio/intercom{ + pixel_y = -25 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bel" = ( +/obj/structure/bed/chair/comfy/beige{ + dir = 4; + icon_state = "comfychair" + }, +/turf/simulated/floor/tiled/eris/steel/bar_light, +/area/tether/surfacebase/barbackmaintenance) +"bem" = ( +/obj/structure/table/gamblingtable, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"ben" = ( +/obj/structure/table/gamblingtable, +/obj/item/weapon/storage/pill_bottle/dice, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"beo" = ( +/obj/structure/bed/chair/comfy/beige{ + dir = 8; + icon_state = "comfychair" + }, +/turf/simulated/floor/tiled/eris/steel/bar_light, +/area/tether/surfacebase/barbackmaintenance) +"bep" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/green{ + icon_state = "2-4" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"beq" = ( +/obj/machinery/door/airlock/freezer{ + name = "Kitchen Cold Room"; + req_access = list(28) + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/fans/tiny, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled, +/area/crew_quarters/freezer) +"ber" = ( +/obj/machinery/newscaster{ + pixel_x = 0; + pixel_y = 30 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/machinery/door/firedoor/glass/hidden/steel{ + dir = 2 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 1; + icon_state = "bordercolor" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bes" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/button/remote/blast_door{ + id = "kitchen2"; + name = "Kitchen shutters"; + pixel_x = -24; + pixel_y = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5; + icon_state = "intact-scrubbers" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bet" = ( +/obj/effect/floor_decal/industrial/warning{ + icon_state = "warning"; + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"beu" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bev" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bew" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/disposalpipe/segment{ + dir = 2; + icon_state = "pipe-c" + }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/machinery/light_switch{ + pixel_x = 24 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bex" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bey" = ( +/obj/machinery/firealarm{ + dir = 2; + layer = 3.3; + pixel_x = 0; + pixel_y = 26 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/machinery/atmospherics/unary/vent_pump/on, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/floor_decal/corner/beige/border{ + dir = 1; + icon_state = "bordercolor" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bez" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"beA" = ( +/obj/machinery/disposal, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"beB" = ( +/obj/effect/floor_decal/borderfloor/corner{ + dir = 1 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 4 + }, +/obj/effect/floor_decal/steeldecal/steel_decals7{ + dir = 5 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/floor_decal/corner/beige/bordercorner{ + dir = 1; + icon_state = "bordercolorcorner" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"beC" = ( +/obj/structure/table/bench/standard, +/obj/effect/landmark/start{ + name = "Botanist" + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/hydroponics) +"beD" = ( +/obj/machinery/camera/network/civilian, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"beE" = ( +/obj/structure/table/glass, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled, +/area/hydroponics) +"beF" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"beG" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"beH" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"beI" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"beJ" = ( +/obj/machinery/power/apc{ + cell_type = /obj/item/weapon/cell/super; + dir = 8; + name = "west bump"; + pixel_x = -30 + }, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/effect/floor_decal/spline/plain, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"beK" = ( +/obj/machinery/hologram/holopad, +/turf/simulated/floor/tiled, +/area/hydroponics) +"beL" = ( +/obj/machinery/light, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 4 + }, +/obj/effect/floor_decal/corner/lime/border{ + dir = 4 + }, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"beM" = ( +/obj/machinery/door/window/westright{ + req_one_access = list(35,28) + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled, +/area/hydroponics) +"beN" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/hydroponics) +"beO" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/effect/floor_decal/borderfloor{ + dir = 8 + }, +/obj/effect/floor_decal/corner/lime/border{ + dir = 8 + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"beP" = ( +/obj/machinery/gibber, +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"beQ" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/effect/floor_decal/spline/plain, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"beR" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/effect/floor_decal/spline/plain, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"beS" = ( +/obj/effect/landmark/start{ + name = "Entertainer" + }, +/obj/structure/bed/chair/wood, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"beT" = ( +/obj/machinery/light{ + dir = 4; + icon_state = "tube1"; + pixel_x = 0 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/bed/chair/wood, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"beU" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/machinery/door/blast/regular/open{ + dir = 2; + icon_state = "pdoor0"; + id = "DRAMATIC" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 4; + icon_state = "rwindow"; + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 4; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/obj/structure/cable/green{ + icon_state = "0-2" + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) +"beV" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/machinery/door/blast/regular/open{ + dir = 2; + icon_state = "pdoor0"; + id = "DRAMATIC" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 4; + icon_state = "rwindow"; + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 4; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/obj/structure/cable/green, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) +"beW" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"beX" = ( +/obj/structure/table/woodentable, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"beY" = ( +/obj/structure/bed/chair/wood, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/camera/network/civilian{ + dir = 9 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"beZ" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bfa" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bfb" = ( +/obj/machinery/door/airlock/freezer{ + name = "Service"; + req_access = list(28) + }, +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled, +/area/hydroponics/cafegarden) +"bfc" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/flame/candle, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bfd" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bfe" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/machinery/camera/network/civilian{ + dir = 1 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bff" = ( +/obj/structure/bed/chair/wood{ + dir = 1 + }, +/obj/machinery/light, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bfg" = ( +/obj/structure/sign/directions/medical{ + dir = 4; + pixel_y = 8 + }, +/obj/structure/sign/directions/science{ + dir = 8; + pixel_y = 3 + }, +/obj/structure/sign/directions/security{ + dir = 8; + pixel_y = -4 + }, +/obj/structure/sign/directions/engineering{ + dir = 8; + pixel_y = -10 + }, +/turf/simulated/wall, +/area/tether/surfacebase/entertainment) +"bfh" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/obj/machinery/door/blast/regular/open{ + dir = 4; + icon_state = "pdoor0"; + id = "DRAMATIC"; + name = "Dramatic Blast Door" + }, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) +"bfi" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/machinery/door/blast/regular/open{ + dir = 4; + icon_state = "pdoor0"; + id = "DRAMATIC"; + name = "Dramatic Blast Door" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) +"bfj" = ( +/obj/structure/grille, +/obj/machinery/door/firedoor, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/machinery/door/blast/regular/open{ + dir = 4; + icon_state = "pdoor0"; + id = "DRAMATIC"; + name = "Dramatic Blast Door" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "draama"; + name = "Mystery Window" + }, +/obj/structure/window/reinforced/polarized{ + id = "draama"; + name = "Mystery Window" + }, +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "Druma"; + layer = 3.3; + name = "Entertainment Shutters" + }, +/turf/simulated/floor/plating, +/area/tether/surfacebase/entertainment) +"bfk" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bfl" = ( +/obj/machinery/portable_atmospherics/hydroponics, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/floor_decal/corner/mauve/border{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora) +"bfm" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bfn" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bfo" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfp" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/disposalpipe/segment, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/camera/network/civilian{ + dir = 9 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bfq" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/door/firedoor/glass/hidden/steel, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bfr" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 6 + }, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bfs" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/mob/living/simple_mob/animal/goat{ + name = "Spike" + }, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bft" = ( +/obj/machinery/light, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"bfu" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/turf/simulated/floor/grass, +/area/hydroponics) +"bfv" = ( +/obj/structure/closet/crate, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/machinery/camera/network/civilian{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bfw" = ( +/obj/structure/closet/crate/freezer, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bfx" = ( +/obj/machinery/light, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bfy" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/disposalpipe/segment{ + dir = 8; + icon_state = "pipe-c" + }, +/turf/simulated/floor/tiled, +/area/hallway/lower/third_south) +"bfz" = ( +/obj/structure/bed/chair/comfy/beige{ + dir = 4; + icon_state = "comfychair" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfA" = ( +/obj/structure/table/gamblingtable, +/obj/item/weapon/storage/pill_bottle/dice_nerd, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfB" = ( +/obj/structure/bed/chair/wood, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfC" = ( +/obj/structure/table/gamblingtable, +/obj/item/weapon/deck/cards, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfD" = ( +/obj/structure/bed/chair/comfy/beige{ + dir = 8; + icon_state = "comfychair" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfE" = ( +/obj/machinery/light/small, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"bfF" = ( +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfG" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 1 + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfH" = ( +/obj/machinery/light/small, +/obj/structure/table/woodentable, +/obj/item/weapon/bone/skull{ + name = "Yo'rick" + }, +/obj/item/weapon/paper{ + desc = ""; + info = "The Silence Into Laughter program works to place hard working, studied, accomplished, hardworking, homebrewed, diplomaholding, or otherwise clowns and mimes into the workforce! The Head Clowncellor and the Director at Mime have finally worked together to bring this titan of a workers' union! If you have a background in silence or laughter, please apply at our exonet site at: https://forum.vore-station.net/viewforum.php?f=45"; + name = "Clowns and Mimes Wanted!" + }, +/obj/machinery/camera/network/civilian{ + dir = 4 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bfI" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 4 + }, +/obj/random/cutout, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24; + pixel_y = 0 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bfJ" = ( +/obj/structure/table/woodentable, +/obj/item/weapon/storage/box/sinpockets, +/obj/machinery/camera/network/outside{ + dir = 9; + icon_state = "camera" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bfK" = ( +/obj/machinery/light/small, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfL" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/full, +/obj/machinery/door/firedoor, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/window/reinforced, +/turf/simulated/floor/plating, +/area/tether/surfacebase/servicebackroom) +"bfM" = ( +/obj/structure/bed/chair/comfy/beige{ + dir = 1; + icon_state = "comfychair" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfN" = ( +/obj/machinery/power/apc{ + cell_type = /obj/item/weapon/cell/super; + dir = 8; + name = "west bump"; + pixel_x = -30 + }, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfO" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 9 + }, +/obj/machinery/door/airlock/freezer{ + name = "Kitchen"; + req_access = list(28) + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bfP" = ( +/obj/structure/bed/chair/comfy/beige{ + dir = 4; + icon_state = "comfychair" + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/eris/steel/bar_light, +/area/tether/surfacebase/barbackmaintenance) +"bfQ" = ( +/obj/structure/table/gamblingtable, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfR" = ( +/obj/machinery/computer/arcade/battle, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bfS" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bfT" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/machinery/light{ + dir = 8; + icon_state = "tube1" + }, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"bfU" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bfV" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bfW" = ( +/obj/machinery/light, +/turf/simulated/floor/tiled, +/area/rnd/xenobiology/xenoflora_storage) +"bfX" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 5 + }, +/obj/structure/table/marble, +/obj/machinery/chemical_dispenser/bar_alc/full{ + dir = 8; + icon_state = "booze_dispenser" + }, +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bfY" = ( +/obj/structure/table/marble, +/obj/machinery/door/blast/shutters{ + dir = 8; + id = "bar"; + layer = 3.3; + name = "Bar Shutters" + }, +/obj/item/weapon/material/ashtray/glass, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bfZ" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bga" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"bgb" = ( +/obj/machinery/button/remote/blast_door{ + id = "freezer"; + name = "Freezer Shutter Control"; + pixel_x = 0; + pixel_y = -24 + }, +/turf/simulated/floor/tiled/freezer, +/area/crew_quarters/freezer) +"bgc" = ( +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply, +/turf/simulated/floor/tiled/eris/cafe, +/area/hydroponics) +"bgd" = ( +/obj/effect/landmark{ + name = "Observer-Start" + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bge" = ( +/obj/machinery/requests_console{ + pixel_x = -30 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bgf" = ( +/obj/machinery/camera/network/civilian, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bgg" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/camera/network/civilian{ + dir = 4 + }, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/backstage) +"bgh" = ( +/obj/effect/floor_decal/corner/lime/border{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10; + icon_state = "intact-scrubbers" + }, +/obj/structure/sink{ + dir = 8; + icon_state = "sink"; + pixel_x = -12; + pixel_y = 0 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/botanystorage) +"bgi" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 9; + pixel_y = 0 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bgj" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 9 + }, +/obj/structure/sign/securearea{ + desc = "Under the painting a plaque reads: 'While the meat grinder may not have spared you, fear not. Not one part of you has gone to waste... You were delicious.'"; + icon_state = "monkey_painting"; + name = "Mr. Deempisi portrait"; + pixel_x = 4; + pixel_y = 28 + }, +/obj/machinery/camera/network/civilian, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bgk" = ( +/obj/effect/floor_decal/spline/plain, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/entertainment/stage) +"bgl" = ( +/obj/structure/bed/chair/comfy/beige{ + dir = 8; + icon_state = "comfychair" + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/eris/steel/bar_light, +/area/tether/surfacebase/barbackmaintenance) +"bgm" = ( +/obj/effect/floor_decal/spline/plain, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/entertainment/stage) +"bgn" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 5; + icon_state = "intact-scrubbers" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 5; + icon_state = "intact-supply" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bgo" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 6 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/entertainment/stage) +"bgp" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bgq" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bgr" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bgs" = ( +/obj/machinery/hologram/holopad, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bgt" = ( +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/closet/chefcloset, +/obj/item/glass_jar, +/obj/item/device/retail_scanner/civilian, +/obj/item/weapon/soap/nanotrasen, +/obj/item/device/destTagger{ + pixel_x = 4; + pixel_y = 3 + }, +/obj/item/weapon/packageWrap, +/obj/item/weapon/packageWrap, +/obj/item/weapon/packageWrap, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bgu" = ( +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/table/woodentable, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bgv" = ( +/obj/structure/bed/chair/wood{ + dir = 8 + }, +/obj/effect/landmark/start{ + name = "Entertainer" + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bgw" = ( +/obj/item/device/radio/intercom{ + pixel_y = -24 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bgx" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/effect/floor_decal/corner/grey/diagonal, +/obj/structure/sink/kitchen{ + pixel_y = 28 + }, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/kitchen) +"bgy" = ( +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/firedoor/glass/hidden/steel, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bgz" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/structure/table/marble, +/obj/item/weapon/reagent_containers/glass/rag, +/obj/item/weapon/reagent_containers/food/drinks/flask/vacuumflask, +/obj/item/weapon/book/manual/barman_recipes, +/obj/machinery/camera/network/civilian{ + dir = 9 + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bgA" = ( +/obj/structure/extinguisher_cabinet{ + dir = 4; + icon_state = "extinguisher_closed"; + pixel_x = -30 + }, +/obj/machinery/alarm{ + dir = 1; + pixel_y = -25; + target_temperature = 270 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bgB" = ( +/obj/structure/bed/chair/wood{ + dir = 4 + }, +/obj/machinery/light, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24; + pixel_y = 0 + }, +/obj/machinery/camera/network/civilian{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/entertainment) +"bgC" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 4 + }, +/obj/structure/table/marble, +/obj/machinery/door/blast/shutters{ + dir = 2; + id = "bar"; + layer = 3.3; + name = "Bar Shutters" + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bgD" = ( +/obj/machinery/camera/network/civilian{ + dir = 4 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bgE" = ( +/obj/effect/floor_decal/spline/plain{ + dir = 6 + }, +/obj/item/weapon/stool/padded, +/obj/machinery/power/apc{ + dir = 4; + name = "east bump"; + pixel_x = 28 + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/machinery/light{ + dir = 4; + icon_state = "tube1" + }, +/turf/simulated/floor/lino, +/area/crew_quarters/bar) +"bgF" = ( +/obj/structure/flora/pottedplant, +/obj/machinery/camera/network/civilian{ + dir = 1 + }, +/turf/simulated/floor/wood, +/area/crew_quarters/bar) +"bgG" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, +/obj/machinery/button/windowtint{ + id = "secreet"; + name = "Window Tint Control"; + pixel_x = -25; + range = 15 + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bgH" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/item/device/radio/intercom{ + dir = 8; + pixel_x = -24 + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bgI" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_x = 0; + pixel_y = -24 + }, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/servicebackroom) +"bgJ" = ( +/obj/machinery/door/airlock{ + name = "Service"; + req_access = list(25) + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled, +/area/tether/surfacebase/bar_backroom) +"bgK" = ( +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/silver{ + name = "Auditorium" + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/steel_grid, +/area/tether/surfacebase/entertainment) +"bgL" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/silver{ + name = "Entertainment Backroom"; + req_one_access = list(72,20,57) + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/lino, +/area/tether/surfacebase/entertainment/stage) +"bgM" = ( +/obj/structure/reagent_dispensers/beerkeg, +/obj/item/device/radio/intercom{ + dir = 4; + pixel_x = 24 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"bgN" = ( +/obj/machinery/door/airlock/silver{ + name = "Auditorium" + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/steel_grid, +/area/tether/surfacebase/entertainment) +"bgO" = ( +/obj/structure/table/woodentable, +/obj/structure/disposalpipe/segment, +/obj/machinery/camera/network/civilian{ + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24; + pixel_y = 0 + }, +/turf/simulated/floor/wood, +/area/tether/surfacebase/bar_backroom) +"bgP" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/machinery/door/airlock/maintenance/engi{ + name = "Bar Substation" + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/plating, +/area/maintenance/substation/bar{ + name = "\improper Surface Civilian Substation" + }) +"bgQ" = ( +/obj/machinery/door/airlock{ + name = "Bar Backroom"; + req_access = list(25) + }, +/obj/effect/floor_decal/spline/plain{ + dir = 5 + }, +/obj/effect/floor_decal/spline/plain, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/lino, +/area/tether/surfacebase/bar_backroom) +"bgR" = ( +/obj/machinery/door/airlock/maintenance/common, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/techmaint, +/area/crew_quarters/bar) +"bgS" = ( +/obj/machinery/door/airlock{ + name = "Unisex Restrooms" + }, +/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, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/white, +/area/crew_quarters/barrestroom) +"bgT" = ( +/obj/machinery/door/airlock/maintenance/common, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/door/firedoor, +/turf/simulated/floor/tiled/techmaint, +/area/tether/surfacebase/barbackmaintenance) +"bgU" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 2; + layer = 3.3; + pixel_x = 0; + pixel_y = 26 + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bgV" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 4; + icon_state = "rwindow"; + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/cable/green{ + icon_state = "0-2" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/tether/surfacebase/barbackmaintenance) +"bgW" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 4; + icon_state = "rwindow"; + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/structure/cable/green{ + icon_state = "0-2" + }, +/obj/structure/cable/green, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/tether/surfacebase/barbackmaintenance) +"bgX" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 + }, +/obj/machinery/camera/network/research/xenobio, +/turf/simulated/floor/tiled/white, +/area/rnd/outpost/xenobiology/outpost_autopsy) +"bgY" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 4; + icon_state = "rwindow"; + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/cable/green{ + icon_state = "0-2" + }, +/obj/structure/cable/green, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/tether/surfacebase/barbackmaintenance) +"bgZ" = ( +/obj/machinery/alarm{ + dir = 4; + icon_state = "alarm0"; + pixel_x = -22; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/eris/steel/bar_dance, +/area/tether/surfacebase/barbackmaintenance) +"bha" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/structure/cable/green{ + icon_state = "1-2" + }, +/obj/structure/cable/green{ + icon_state = "1-4" + }, +/obj/structure/cable/green{ + icon_state = "1-8" + }, +/obj/structure/disposalpipe/junction{ + dir = 1; + icon_state = "pipe-j2" + }, +/obj/machinery/camera/network/research/xenobio{ + icon_state = "camera"; + dir = 10 + }, +/turf/simulated/floor/tiled/dark, +/area/rnd/outpost/xenobiology/outpost_main) +"bhb" = ( +/obj/structure/grille, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/window/reinforced/polarized{ + id = "secreet"; + name = "Tintable Window" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/tether/surfacebase/barbackmaintenance) +"bhc" = ( +/obj/structure/grille, +/obj/structure/cable/green{ + icon_state = "0-4" + }, +/obj/structure/window/reinforced/polarized/full{ + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/window/reinforced/polarized{ + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/tether/surfacebase/barbackmaintenance) +"bhd" = ( +/obj/structure/grille, +/obj/structure/window/reinforced/polarized/full{ + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/window/reinforced/polarized{ + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/window/reinforced/polarized{ + dir = 4; + icon_state = "rwindow"; + id = "secreet"; + name = "Tintable Window" + }, +/obj/structure/cable/green{ + icon_state = "0-8" + }, +/obj/structure/cable/green, +/obj/machinery/door/firedoor/glass, +/turf/simulated/floor/plating, +/area/tether/surfacebase/barbackmaintenance) +"bhe" = ( +/obj/machinery/hologram/holopad, +/obj/machinery/camera/network/research/xenobio{ + icon_state = "camera"; + dir = 9 + }, +/turf/simulated/floor/tiled/white, +/area/rnd/outpost/xenobiology/outpost_first_aid) +"bhf" = ( +/obj/structure/table/standard, +/obj/item/device/slime_scanner, +/obj/item/device/slime_scanner, +/obj/item/device/multitool, +/obj/machinery/camera/network/research/xenobio{ + icon_state = "camera"; + dir = 10 + }, +/turf/simulated/floor/tiled/techmaint, +/area/rnd/outpost/xenobiology/outpost_storage) +"bhg" = ( +/obj/structure/shuttle/engine/propulsion, +/turf/simulated/floor/reinforced, +/turf/simulated/shuttle/plating/carry, +/area/shuttle/tether) +"bhh" = ( +/obj/machinery/atmospherics/unary/engine{ + dir = 1 + }, +/turf/simulated/floor/reinforced, +/turf/simulated/shuttle/plating/carry, +/area/shuttle/tourbus/engines) "bhu" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/lightgrey/border, @@ -28572,38 +34567,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"bqy" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) -"bqA" = ( -/obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "bxH" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -28613,16 +34576,6 @@ }, /turf/simulated/floor/tiled/techfloor/grid, /area/maintenance/lower/medsec_maintenance) -"byo" = ( -/obj/effect/floor_decal/steeldecal/steel_decals4, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "bzK" = ( /obj/structure/cable/green{ d1 = 2; @@ -28715,22 +34668,6 @@ /obj/effect/map_helper/airlock/door/simple, /turf/simulated/floor/tiled/eris/techmaint_panels, /area/shuttle/tourbus/general) -"ccf" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/effect/floor_decal/steeldecal/steel_decals4, -/obj/effect/floor_decal/steeldecal/steel_decals4{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "ceN" = ( /obj/structure/disposalpipe/segment{ dir = 8; @@ -28740,24 +34677,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"cko" = ( -/obj/structure/cable/green{ - d1 = 2; - d2 = 4; - icon_state = "2-4" - }, -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "cmQ" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/lightgrey/border, @@ -28808,33 +34727,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"cqA" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 6 - }, -/obj/effect/floor_decal/corner/beige/bordercorner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/beige/bordercorner2{ - dir = 6 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "cwI" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 @@ -28883,16 +34775,6 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) -"cGR" = ( -/obj/item/weapon/stool/padded, -/obj/effect/floor_decal/spline/plain{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) "cJL" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/mauve/border, @@ -28972,22 +34854,6 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/plating/eris/under, /area/shuttle/tourbus/cockpit) -"dfq" = ( -/obj/machinery/door/airlock/glass, -/obj/machinery/door/firedoor/glass, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/tiled/steel_grid, -/area/crew_quarters/bar) "dgA" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -29053,33 +34919,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"duW" = ( -/obj/structure/table/gamblingtable, -/obj/item/weapon/storage/pill_bottle/dice_nerd, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"dFb" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/structure/cable/green{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "dGZ" = ( /obj/structure/cable{ d1 = 2; @@ -29132,19 +34971,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) -"dQt" = ( -/obj/structure/cable/green{ - d2 = 2; - icon_state = "0-2" - }, -/obj/machinery/power/apc{ - cell_type = /obj/item/weapon/cell/super; - dir = 8; - name = "west bump"; - pixel_x = -30 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "dVE" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -29211,24 +35037,6 @@ "eiO" = ( /turf/simulated/floor/tiled/eris/dark/golden, /area/shuttle/tourbus/general) -"epM" = ( -/obj/item/weapon/stool/padded, -/obj/effect/floor_decal/spline/plain{ - dir = 8 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply, -/obj/structure/disposalpipe/segment{ - dir = 8; - icon_state = "pipe-c" - }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) "erS" = ( /obj/effect/floor_decal/borderfloor{ dir = 6 @@ -29392,32 +35200,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) -"fgi" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/beige/bordercorner2{ - dir = 5 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/structure/flora/pottedplant, -/obj/machinery/atmospherics/unary/vent_scrubber/on, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "fgW" = ( /obj/effect/floor_decal/borderfloor{ dir = 4 @@ -29615,16 +35397,6 @@ }, /turf/simulated/floor/wood, /area/crew_quarters/recreation_area) -"gqv" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/machinery/door/firedoor/glass/hidden/steel, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) "gtp" = ( /obj/effect/floor_decal/industrial/warning, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -29642,14 +35414,6 @@ /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) -"gBG" = ( -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) "gHh" = ( /obj/machinery/atmospherics/pipe/simple/hidden/yellow{ dir = 10 @@ -29754,27 +35518,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_three) -"hcY" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/bordercorner2{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) "hgf" = ( /obj/machinery/door/firedoor/glass/hidden{ dir = 2; @@ -29804,15 +35547,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) -"hvt" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) "hxc" = ( /obj/effect/floor_decal/borderfloor/corner, /obj/effect/floor_decal/corner/lime/bordercorner, @@ -29824,29 +35558,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/public_garden_three) -"hyh" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 4; - icon_state = "pipe-c" - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "hCB" = ( /obj/structure/cable/green{ d1 = 1; @@ -29888,16 +35599,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/tiled/techfloor/grid, /area/maintenance/lower/medsec_maintenance) -"hPF" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "hYK" = ( /obj/effect/floor_decal/techfloor{ dir = 4 @@ -29982,65 +35683,6 @@ }, /turf/simulated/floor/tiled/eris/white/orangecorner, /area/shuttle/tourbus/cockpit) -"iBA" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) -"iBG" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) -"iGj" = ( -/obj/effect/floor_decal/borderfloor/corner{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/bordercorner{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 1 - }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) -"iLR" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) -"iOg" = ( -/obj/machinery/light{ - dir = 8; - icon_state = "tube1" - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "iQr" = ( /obj/machinery/hologram/holopad, /obj/effect/landmark/start{ @@ -30076,22 +35718,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) -"jjp" = ( -/obj/machinery/newscaster{ - pixel_x = 0; - pixel_y = 30 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 1 - }, -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 2 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) "jpB" = ( /obj/machinery/atmospherics/pipe/simple/hidden/yellow{ dir = 6 @@ -30139,26 +35765,6 @@ "jvK" = ( /turf/simulated/wall/shull, /area/shuttle/tourbus/cockpit) -"jvN" = ( -/obj/machinery/firealarm{ - dir = 2; - layer = 3.3; - pixel_x = 0; - pixel_y = 26 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/obj/machinery/atmospherics/unary/vent_pump/on, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) "jAt" = ( /obj/structure/cable/green{ d1 = 1; @@ -30230,19 +35836,6 @@ /obj/structure/flora/pottedplant/stoutbush, /turf/simulated/floor/tiled, /area/tether/surfacebase/security/lobby) -"jFq" = ( -/obj/structure/disposalpipe/sortjunction{ - dir = 1; - icon_state = "pipe-j1s"; - name = "Bar"; - sortType = "Bar" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "jFz" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -30329,23 +35922,6 @@ }, /turf/simulated/floor/tiled/eris/dark/golden, /area/shuttle/tourbus/general) -"kcK" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/firedoor/glass/hidden/steel{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "kdx" = ( /obj/structure/table/standard, /obj/structure/closet/emergsuit_wall{ @@ -30458,13 +36034,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/tiled, /area/rnd/research/testingrange) -"kyb" = ( -/obj/structure/bed/chair/wood, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "kyC" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -30688,26 +36257,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"mtF" = ( -/obj/structure/extinguisher_cabinet{ - dir = 4; - icon_state = "extinguisher_closed"; - pixel_x = -30 - }, -/obj/effect/floor_decal/borderfloor{ - dir = 8 - }, -/obj/effect/floor_decal/corner/lime/border{ - dir = 8 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 6 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) "myZ" = ( /obj/structure/disposalpipe/segment, /obj/effect/floor_decal/borderfloor{ @@ -30880,24 +36429,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"nui" = ( -/obj/structure/disposalpipe/segment{ - dir = 1; - icon_state = "pipe-c" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) -"nHF" = ( -/obj/structure/table/gamblingtable, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "nLX" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 @@ -30979,18 +36510,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"ovI" = ( -/obj/structure/disposalpipe/junction{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "oAu" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -31041,15 +36560,6 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"oEU" = ( -/obj/structure/table/gamblingtable, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "oLR" = ( /obj/structure/bed/chair/bay/chair{ dir = 1; @@ -31132,29 +36642,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) -"paT" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 4 - }, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) "peS" = ( /obj/structure/cable/green{ d1 = 1; @@ -31326,12 +36813,6 @@ "qwm" = ( /turf/simulated/wall/shull, /area/shuttle/tourbus/engines) -"qCn" = ( -/obj/structure/bed/chair/wood{ - dir = 8 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "qIb" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -31345,15 +36826,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals7, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"qOw" = ( -/obj/structure/bed/chair/wood{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "qQZ" = ( /obj/effect/floor_decal/techfloor, /obj/machinery/firealarm{ @@ -31370,43 +36842,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/yellow, /turf/simulated/wall/shull, /area/shuttle/tourbus/engines) -"qWZ" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) -"qZs" = ( -/obj/structure/disposalpipe/junction{ - dir = 1; - icon_state = "pipe-j2" - }, -/obj/machinery/hologram/holopad, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "rbR" = ( /obj/structure/cable/green{ icon_state = "2-4" @@ -31562,14 +36997,6 @@ }, /turf/simulated/floor/tiled/eris/dark/bluecorner, /area/shuttle/tourbus/engines) -"sJC" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 2; - icon_state = "1-2" - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "sLa" = ( /obj/machinery/firealarm{ dir = 2; @@ -31632,15 +37059,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/lower/third_south) -"sSX" = ( -/obj/structure/bed/chair/wood{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "sWs" = ( /obj/effect/floor_decal/techfloor{ dir = 4 @@ -31663,34 +37081,6 @@ }, /turf/simulated/floor/grass, /area/tether/surfacebase/public_garden_three) -"sYk" = ( -/obj/effect/floor_decal/borderfloor{ - dir = 4 - }, -/obj/effect/floor_decal/corner/beige/border{ - dir = 4 - }, -/obj/effect/floor_decal/borderfloor/corner2{ - dir = 6 - }, -/obj/effect/floor_decal/corner/beige/bordercorner2{ - dir = 6 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 9 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 10 - }, -/obj/structure/flora/pottedplant, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "tcW" = ( /obj/effect/shuttle_landmark{ base_area = /area/tether/surfacebase/shuttle_pad; @@ -31836,19 +37226,6 @@ /obj/structure/table/steel, /turf/simulated/floor/tiled, /area/tether/surfacebase/security/processing) -"tZw" = ( -/obj/structure/sign/biohazard{ - pixel_y = 32 - }, -/obj/structure/flora/pottedplant/crystal, -/obj/effect/floor_decal/borderfloorblack{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/turf/simulated/floor/tiled, -/area/rnd/outpost/xenobiology/outpost_hallway) "uaN" = ( /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 9 @@ -31879,16 +37256,6 @@ }, /turf/simulated/floor/tiled/eris/dark/golden, /area/shuttle/tourbus/general) -"uxo" = ( -/obj/effect/floor_decal/spline/plain{ - dir = 1 - }, -/obj/machinery/holoposter{ - dir = 8; - pixel_x = 30 - }, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) "uxT" = ( /obj/effect/floor_decal/steeldecal/steel_decals_central5{ dir = 8; @@ -31916,11 +37283,6 @@ /obj/machinery/atmospherics/unary/vent_scrubber/on, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"uNM" = ( -/obj/effect/floor_decal/corner/grey/diagonal, -/obj/structure/foodcart, -/turf/simulated/floor/tiled/white, -/area/crew_quarters/kitchen) "uOc" = ( /obj/effect/floor_decal/techfloor{ dir = 4 @@ -31948,21 +37310,6 @@ }, /turf/simulated/floor/tiled/monofloor, /area/tether/surfacebase/shuttle_pad) -"vdE" = ( -/obj/effect/floor_decal/borderfloor/corner{ - dir = 1 - }, -/obj/effect/floor_decal/corner/lime/bordercorner{ - dir = 1 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 4 - }, -/obj/effect/floor_decal/steeldecal/steel_decals7{ - dir = 5 - }, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) "viF" = ( /obj/structure/disposalpipe/segment, /obj/effect/floor_decal/borderfloor{ @@ -32001,22 +37348,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/shuttle_pad) -"voS" = ( -/obj/effect/floor_decal/spline/plain{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/hologram/holopad, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/lino, -/area/crew_quarters/bar) -"vrs" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "vrU" = ( /obj/structure/cable{ d1 = 2; @@ -32072,12 +37403,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/surface_three_hall) -"vxO" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "vJA" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -32171,19 +37496,6 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor/plating/eris/under, /area/shuttle/tourbus/general) -"wGK" = ( -/obj/structure/bed/chair/wood{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 - }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/wood, -/area/crew_quarters/bar) "wPD" = ( /obj/effect/floor_decal/borderfloor/corner{ dir = 4 @@ -32228,27 +37540,6 @@ }, /turf/simulated/floor/tiled, /area/tether/surfacebase/security/processing) -"xbm" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/airlock/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) -"xbZ" = ( -/obj/structure/disposalpipe/sortjunction{ - dir = 1; - icon_state = "pipe-j1s"; - name = "Kitchen"; - sortType = "Kitchen" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/tiled, -/area/tether/surfacebase/surface_three_hall) "xdM" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on, /obj/effect/floor_decal/borderfloor{ @@ -32268,16 +37559,6 @@ }, /turf/simulated/floor/tiled, /area/rnd/research/researchdivision) -"xjd" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/simulated/floor/tiled, -/area/hallway/lower/third_south) "xkx" = ( /obj/effect/floor_decal/borderfloor{ dir = 1 @@ -37113,7 +42394,7 @@ aab aOm adG aOR -aAt +aDU aPw aPN aQb @@ -37264,7 +42545,7 @@ aQy aQI aQS aRa -aBu +bgX aRu aRI aRO @@ -37698,7 +42979,7 @@ aMK aMq aSB aPV -aBM +bhe aXA aSA aCO @@ -37822,7 +43103,7 @@ aNZ aOf aOo aHM -aBJ +aDo aOf aOR aPP @@ -37958,7 +43239,7 @@ aCc aMi aCc aCc -axP +aBu aNS aEt aGo @@ -37972,7 +43253,7 @@ aQe aQA aQB aQM -aEf +aEw aMo aQM aRz @@ -38083,7 +43364,7 @@ aac aac aac acj -tZw +asd dVE cWe hgf @@ -38121,7 +43402,7 @@ aRo aQC aRS aSe -aFF +bha aSr aBf aMl @@ -38230,10 +43511,10 @@ aCm awh aGM aNn -aEw +aAt aJB aNn -aNn +aAO asf aNn aNn @@ -38616,7 +43897,7 @@ aac agw aVG aWF -akn +aTO akS aly amn @@ -38675,14 +43956,14 @@ adG aRh adG aOW -aAO +aEf aPG aJb aQh aQu aQE aQO -aDU +aFF aRe aMJ aRD @@ -38977,7 +44258,7 @@ bKS aSJ aSY aTk -aDo +bhf aSI adG aOi @@ -39077,7 +44358,7 @@ aac aac aac aiE -asd +axP aBQ aGn aiE @@ -43499,7 +48780,7 @@ jML jHw jpB qWU -aXV +bhh aKU aOI aPb @@ -44351,7 +49632,7 @@ caw jHw gHh qWU -aXV +bhh aKU aOI aPb @@ -44605,11 +49886,11 @@ aXB bbF ajM apf -awJ -awJ -awJ -aBl -awJ +aWC +aWC +aWC +aWC +aWC aED aEQ aEE @@ -44747,14 +50028,14 @@ aXB bbF ajM apD -awN -aEF -aEL -aBm -awJ -awJ -awJ -awJ +aWD +baZ +bfI +bfH +aWC +aWC +aYC +bcI aAB aCL aut @@ -44889,20 +50170,20 @@ aXB bbF aEq apE -aEB -axm -axX -axm -azp -azX -aAC -aFg -aCh +bed +bbd +bci +bbd +bbd +bgg +bdb +bdp +bgP aCP aFx aFW aGz -aHk +aXM aHX aIz aJn @@ -45031,20 +50312,20 @@ aXD bbF avG aNE -awJ -axn -aEM -aES -awJ -azY -aAD -aFk +aWC +bbe +bcj +bcH +bcP +bcU +bdd +aFY aAB aCQ azn aFX aAB -aJr +aZD aHY aUm ats @@ -45173,20 +50454,20 @@ aXB bbF ajR akx -awP -awP -awP -awP -awP -awP -aAE -awP -awP -awP -awP -awP -aGA -aHm +aYC +aYC +aYC +bcI +bcI +bcI +bgL +bcI +bcI +aYC +aYC +aYC +bfg +baD aHZ aIC aJo @@ -45314,21 +50595,21 @@ aYK aXB bbF ajR -aEx -awP -axo -axY -ayC -akX -azZ -aAF -aBx -aCi -ayC -aFy -aFY -awP -aHn +aGu +aYC +bbf +bcn +bcr +aHz +bdm +bdg +bdo +beJ +bgk +bbk +bgB +aYC +bdr aIa aIz aJn @@ -45344,7 +50625,7 @@ ghf gLd aNx aMA -aMW +aFC aMA aOu aNx @@ -45455,22 +50736,22 @@ aYy aYL aXB bbF -avH -awq -awQ -axp -axZ -ayD -ayD -ayD -aAG -ayD -ayD -ayD -axZ -aFZ -awR -aHo +ajR +aGA +aGk +bbg +aWk +bcJ +bcQ +bcW +bcT +bcR +beQ +bgm +beW +bbg +bfh +bds aIb aID aJp @@ -45549,8 +50830,8 @@ aab aab aab aab -aab -aab +aOm +adG aag aag aaD @@ -45598,21 +50879,21 @@ aYM aXE bbF ajR -awp -awR -axq -aya -ayE -ayE -ayE -aAH -ayE -ayE -ayE -aya -aGa -awR -aHo +aGA +aGE +bbh +bbk +bcK +bcV +bcX +bcZ +bcS +beR +bgo +bbk +bgv +bfi +bds aIa aIz ats @@ -45691,8 +50972,8 @@ aab aab aab aab -aab -aab +aOm +adG aac aag aaL @@ -45740,21 +51021,21 @@ asT asT bbF ajR -awp -awR -axr -aya -ayF -ayF -ayF -aAI -ayF -ayF -ayF -aya -aGb -awR -aHo +aGA +aZM +bbk +bbk +bbk +bbk +bdh +bdy +bdF +bbk +bbk +bbk +bbk +bfi +bds aIa aIB ats @@ -45834,7 +51115,7 @@ aab aab aab aab -aab +aNM aQW aag aag @@ -45882,21 +51163,21 @@ alY auI bbA ajR -awp -awR -axs -ayb -aya -aya -aAa -aAJ -aBy -aya -aya -ayb -aGc -awR -aHo +aGA +bah +bbl +beX +beX +bcY +bdq +bbk +bbk +beS +beX +beX +bcM +bfj +bds aIa aIz ats @@ -46015,7 +51296,7 @@ aZR bbi ayx aqO -aqO +aTP asT aPp asT @@ -46024,21 +51305,21 @@ alY auI bbA ajR -awr -awP -axt -ayc -ayc -azs -aAb -aAK -aBz -aCj -aCR -ayc -aGd -awP -jjp +aLh +aYC +beY +bfc +bcL +bde +bcN +aEd +beW +beT +bgu +bfc +bff +aYC +ber fyZ aUm aJn @@ -46166,21 +51447,21 @@ alZ auJ bbA ajR -awp -awP -axu -awR -awR -azt -aAc -awR -aBA -azt -awR -awR -awP -awP -jvN +aGA +aYC +bbn +bax +bco +aYC +bgK +bcq +bgN +aYC +beU +beV +aYC +aYC +bey suT aIC aJn @@ -46307,22 +51588,22 @@ myZ myZ myZ dsF -avG -iGj -awS -axv -axv -axv -alz +aDV +aZd +bbz +bcs +bcs +bcs +bct aAd -aAL -aBB -hcY -bqy -axv -mtF -gqv -vdE +bcx +aLf +bcy +bcz +bcs +bcA +bcO +beB aHW knU aJn @@ -46336,7 +51617,7 @@ aNk uSA aNJ aNP -aVC +bhg aKU abg aOk @@ -46426,7 +51707,7 @@ agw agw aix gTN -akH +akL akH akH akH @@ -46439,32 +51720,32 @@ xUo bqs xUo xUo -xUo -xUo -xbZ +aCK +aCK +aCK xUo fOj -ovI -jFq +ahR +arG akH akH akH -qZs -hPF -xbm -iBA -nui -aEr -aEr -xjd -aEr -aEr -aEr -hvt -azF -azF -gBG -azF +aGv +aGD +aGF +aHk +aye +aye +aye +aBr +aHm +aye +aHm +aIV +aXg +aXg +aXK +bfy gAF pgi aUo @@ -46478,7 +51759,7 @@ aNl aNl aNK aNP -aVC +bhg aKU abg aOk @@ -46568,7 +51849,7 @@ aVs agw aix aka -akI +atc aMX ama amI @@ -46581,28 +51862,28 @@ apC aqf aOT aqU -arG +avP +avP +avP +apS apS ajX -apS -aEd -cko -iLR +bbm auh auK -aOg avn -qWZ +avn +aKx awU +aCJ axw -aye axw axw aAf +aCJ axw -axw -axw -paT +aCJ +aJc aCU aGf aIc @@ -46620,7 +51901,7 @@ aNm aNl aNK aNP -aVC +bhg aKU abg aOk @@ -46710,7 +51991,7 @@ agw agw ajj akb -akJ +avH alo amb aio @@ -46723,28 +52004,28 @@ agw aqg aqT apc -arH -ash -ate -ash -ate -kcK -ate -ash -auL -avo -avK -avK -arJ -avK -asF +aBF +aBF +aBF +aXT +aXT +bbN +aru +avp +avp +avp +atl +avd +aru +avd +aru arJ azv arJ +aCS avK -avK -avK -avK +aHr +aCS avK arJ arJ @@ -46828,7 +52109,7 @@ aab aab aab aab -aac +aab aac aac aac @@ -46852,7 +52133,7 @@ ahP ail ajk aka -akK +awp alp amc aio @@ -46865,34 +52146,34 @@ agw aqh agw apc -arI -asi -fgi -byo -cqA -ccf -sYk -aui -auM -arJ -avL -awu -awV -axx -ati -aAR -aBG -aEY +asZ +aVw +axn +ate +ayG +aZg +bda +bes +api +atf +atw +atP +avD +awc +bfO +aCX +aHy +bee +aCT +aIl +aHs +baA +aIN +aIO +bgD asX -asX -alM -asX -asX -iOg -dQt -sJC -hyh -aIJ +bdP +beA aJs aKn arJ @@ -46989,12 +52270,12 @@ aTL aeP afH agq -ahb +agN ahQ aim ahb akc -akL +awS alq alq amJ @@ -47007,39 +52288,39 @@ apc aqi apc apc -arJ -arJ -asF -asV -atg -dfq -asF -arJ -arJ -arJ +avg +aVy +axn +ate +ayI +baB +aru +asw +beF +anj +atO +anj +awc +bfe +avy +bgf avM -awu -auk asX asX -asX -asX -asX -aAP -aBD -aCo -aBC -aFA -asX -asX -asX -iBG -aIK -aJt -aJt -aJt -aJt -aJt +aIl +aHB +aJv +aIH +aIO +bcc +bdM +bdQ +arJ +aGK +aGK +aGK +aGK +aKj aKj aKj aKj @@ -47131,13 +52412,13 @@ aeh aeQ afG agr -ahc -ahR ain -aDV akd -agN -alr +akI +akJ +akK +aBB +aoN amd aio eHk @@ -47148,50 +52429,50 @@ aYd aYk aqj aoH -arp -arK -asj -asG -asW -asG -dFb -atN -auj -auN -avp -avp -avp -avp -avp -ayf -ayI -avp -vxO -kyb -nHF -oEU -duW -wGK -vrs -voS -cGR -epM -aro -aJt +aww +asp +avq +aBE +aVR +aEY +aZJ +aKc +beu +aqY +anj +anj +anj +aGh +aLc +avo +avz +avM +asX +asX +aIn +aIg +aJK aKo -aLb -aLC -aJt -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac +aKq +bck +aKr +beh +aGK +aya +bcd +ayh +ayE +aGK +aAl +aId +bdA +ayM +bgG +bgH +bfo +bfN +bgZ +bhb aac aac aac @@ -47267,14 +52548,14 @@ aac abf abt acS -aTO +afX aeg aTM aeR abe -ags -ags -agw +aoj +asr +asF aio aio aio @@ -47291,49 +52572,49 @@ aYl aqk apg apc -arL -ask -asH -asX -ath -aEk -aEl -aEm -aEn -aEm -aEk -aEk -aEk -aEk -aEN -aET -aEW +aGH +aVB +axn +aZQ +bga +bgc +asD +bev +beG +azZ +atJ +atQ +bfd +awc +avm +avz +avM asX asX -sSX -qOw -qCn -bqA -sJC -aGF -aHx -aIk -aIM -aJt -aKp -aLc -aLD -aJt -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac +asX +aIh +bdv +bbK +bbO +bcl +aAF +bcb +bgS +bdT +bdY +aGK +aGK +aGK +aAx +aIe +bdK +ayM +bef +bel +bfz +bfP +bfK +bhc aac aac aac @@ -47414,9 +52695,9 @@ adD aeh aeS abe -aac -aac -aac +apa +aXU +aYN aio ajl aof @@ -47426,56 +52707,56 @@ ame aio ano anR -aon -aoJ -aoJ -aoJ -aoJ -aoJ -aoJ -arM -auP -asH +aok +awP +awP +awP +awP +awP +awP +aTE +aVC +axn +bdB +ayL +baP +aru +asL +bdx +bez +beI +bgn +aKu +awc +avo +avz +avM asX -ati -asX -atO -auk -auP -auk -asX -asX -asX -asX -ayg -ayJ -aEX -aEk -aEk -aEN -aET -aEk -aFC -asX -aGG -aHy -aIl -aIN -aJu -aKq aLd -aLE -aJt -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac +aHe +aIi +bdG +aLd +bbP +bcm +aAG +bgF +aGK +ayd +bdZ +ayC +ayF +aGK +aAE +baR +bdL +ayM +beg +bem +bfA +bfQ +bfM +bhc aac aac aac @@ -47556,9 +52837,9 @@ adE aei aeT abe -aac -aac -aac +auj +aXU +anm aio ajm akf @@ -47568,56 +52849,56 @@ amf amK anp anS -aoo -aKc -aph -apF -aql -aqV -aoJ +asU +arN +aqo +avO +ate +awr +aGb +aVO +aVO +aVO +ate +aFK +bbI aru -aru -asI -asY -asY -atz -atP -aru -auQ -avq -avN -awv +aCq +beH +atM +atL +aBx +bfn +aLc +avo +avz +avM asX -asX -ayg -ayJ -asX -aEZ -asX -ayg -ayJ -asX -aFD -asX -aGG -aHz -aIm -aIO -aJt -aKr -aLe -aLF -aJt -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac +aLd +aHl +aIi +bgd +aLd +bbT +bcm +aAG +bfR +aGK +ayc +bdZ +aGK +aGK +aGK +aCn +baR +bdN +ayM +beg +ben +bfB +bfQ +bfM +bhc aac aac aac @@ -47693,14 +52974,14 @@ aac abf abt acT -aTP +ahz aeg aTN adC abe -aac -aac -aac +aql +aXU +aYN aio ajn akg @@ -47710,56 +52991,56 @@ amg aio anq anT -aon -aib -aoK -aoK -aqm -aqW -arq -arN -asm -asJ -asZ -atj -asO -atQ -aum -auR -avr -avO -aww +aok +asK +asP +auO +auQ +awR +asP +aHn +aHn +aHn +asP +beL +aru +aru +aKy +beH +anj +baq +bgp +baE +awc +axt +avA +aCi asX -auk -ayh -ayK -auk asX -auk -ayh -ayK -auk -aFD asX -aGG -aHz -aIm -aIP -aJt -aKs -aLf -aLG -aJt -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac +aIh +bdw +bbL +bbU +bdJ +aAG +aIS +aGK +bdU +bea +ayD +ayF +aGK +aFq +bbX +bdW +ayM +beg +bem +bfC +bfQ +bfM +bhc aac aac aac @@ -47839,10 +53120,10 @@ abe adF aek aeV -afI -aac -aac -aac +abe +aoo +aXV +bch aio ajo akf @@ -47852,56 +53133,56 @@ aht aio anr anU -aon -aoM -aoK -aoK -aqn -aqX -arr -arO -asn -asK -arO -atk -arO -atR -aru -aXU -avr -avO -aww -aAj -awu -ask -ayL -awu -aFa -awu -aBF -auO -awu -aFE -asX -aGG -aHz -aIm +aok +asi +asi +asi +asi +asi +asj aJV -aJt -asr -aLg -aLH -aJt -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac +aWE +aWE +beE +beM +aru +ani +bcf +bdE +anj +baq +bgp +baE +awv +aru +aru +aru +bgj +aET +aET +aIo +axZ +bbM +bbV +aAc +aEl +baC +aGK +bdV +beb +aGK +aGK +aGK +aFv +baR +aFv +ayM +bgU +beo +bfD +bgl +bfK +bhc aac aac aac @@ -47970,21 +53251,21 @@ aaq aaq aac aac -aac -aac -aac -aac -abe -abe -abe -abe -abe -abe -aeW +acf +acf +acf +acf afJ -aac -aac -aac +afJ +afJ +afJ +afJ +afJ +afJ +afJ +acf +arx +acf aio ajp akf @@ -47994,56 +53275,56 @@ ami aio aio anV -aon -aoN -api -apG -aqo -aqY -aoJ -arP -aso -asL -ata -atl -asO -asO -aun -auR -avr -avO -aww -asX -auk -auk -auk -auk -asX -auk -auk -auk -auk -aFD -asX -aGG -aHA -aIm -arx -aJt -aJt -aJt -aJt -aJt +aok +aSx +aop +aop +aop +aBp +aCl +aTF +bdC +beC +beK +beN +bcg +anN +atA +aAL +avL +aGi +bgq +bgr +anj +aZX +baO +aru +avJ +aIM +aIM +aIJ +ayf +aIM +bfY +bbY +aIf +aIU aGK -aQf -aac -aac -aac -aac -aac -aac -aac -aac +ayd +ayb +ayb +bfE +aGK +aFy +bdz +bdX +bgT +bei +bep +bfG +bfS +bfF +bhc aac aac aac @@ -48112,21 +53393,21 @@ aaq aaq aac aac -aac -aac -aac -aac -aac -aac -aac -aRm -aac -aac -aac -aac -aac -aac -aac +afS +afp +bfT +afq +afS +ais +ajv +ajV +amS +anP +apj +afS +aqW +aro +arX aio ajq akh @@ -48136,57 +53417,57 @@ amj amK ans anU -aon -aoJ -aoJ -aoJ -aoJ -aoJ -aoJ -arQ -aso -asM +aok +aDI +aqp +aop +aqp +aCj +aFS +aVP +aVP +aVP +aFS +beO +amY +baq +anj +aCf aru -atm -asO -asO -auo -auT -avr -avO -aww -asX -asX -asX -asX -asX -asX -asX -asX -asX -asX -aFD -asX -aGG -aHz +bgx +anj +baE +bgs +anj +anj +bcu +asB aIm -aIS -arJ -aKu -aLh -aLI -aMg +aIm +aIK +azs +bbR +bbS +bbZ +aIf +baT aGK -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac +aHD +aHD +aHD +aHD +aGK +aFA +ayM +bec +ayM +bgV +bgW +bgY +bgY +bgY +bhd +aQf aac aac aac @@ -48251,24 +53532,24 @@ aab aab aab aaq +aaq aac aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac +afS +afr +acn +aeU +afS +ait +ajw +ajW +amV +aoe +apk +afS +aqZ +arq +arY aio ajr aki @@ -48278,50 +53559,50 @@ amk amL ant anW +aok aop -aoO -apj -apk -aqp -aqZ -ars -arR -asp -asN -atb -atn -asO -uNM -aup -auR -avr -avO -aww -asX -asX -asX -asX -asX -asX -asX -asX -asX -asX -aFD -asX -uxo -aHB -aIn -aIT -arJ -aUg -aLh +aop +aop +aop +aUr +aWM +aXj +aVy +aVy +aop +aKm +aru +asM +anj +aBD +aES +aGr +anj +bew +bfp +baw +baX +amY +asB +aIm +aIm +aIP +azx +aIm +bgC +bgE +aIf +baW aGK aGK aGK -aac -aac -aac +aGK +aGK +aGK +aHC +ayM +ayM +ayM aac aac aac @@ -48393,24 +53674,24 @@ aab aab aab aaq +aaq aac aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac +afS +aby +acZ +aeW +afS +aby +afq +acl +amX +afq +afq +afS +ara +arq +asm aio ajs akj @@ -48420,48 +53701,48 @@ aml amK anu anX -aop -aoP -apk -apk -aqq -ara -art -arS +aok +aoM +aEX +atR +aEX +asp asq -aEh -asO -asO -asO -asO -aup -auR -avr -avO -aww -asX -asX -asX -asX -asX -asX -asX -asX -asX -asX -and +aWM +aXj +aVy +aop +aZy +aru +bca +anj +anj +anj +baq +bek +aru +aru +baF +aru +aru +bfX +aEW +bgz +ato +bcp +atN arJ arJ +bgR arJ -arJ -arJ -arJ -aKw -aLh -aLJ -aMh aGK -aac +aAi +aAe +aAe +aAe +aAe +aAj +ayM aac aac aac @@ -48533,77 +53814,77 @@ aab aab aab aab +aab +aaq aac aac aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aio -aio -aio -aio -aio -aio +afS +ait +aeE +afI +ags +agB +agB +anC +aBM +amU +aoD +arb +aIk +bdf +asn +acf +acf +acf +acf +acf +acf aio ajs anY +aok +bdi aop -aKt -apl -apH -apk -arb -ars -arT -ajD -asP -atc -ato -atA -atS -aup +bdj +arQ auU -ako -avO -aww -asX -axx -auk +aXv +ath +afT +atk +atn +awQ +aru +bgt +aKp +aZT +anj +baq +anj +aru +bge +bcB +bgA +aJt +aJt +aJt +aJt +aJt +bgQ +aJt +aJt +ayJ +bbW +aAe +aAe +aAj +ayM +ayM +ayM +ayM +ayM ayM -azx -aIQ -asX -asX -asX -asX -aFG -aGk -aGI -aHC -aIo -aIU -aJv -aKx -aLh -aGK -aGK -aGK -aac aac aac aac @@ -48680,71 +53961,71 @@ aac aac aac aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aio -aio -aio +afS +ack +aeF +ack +afS +afS +afS +afS +alz +afS +afS +afS +apH +arq +asv +atj +atS +atj +auM +avf +axr +acf +aok +aok +aok +aEB aop -aoR -aoR -aoR -aoR -aoR -aru -aru -aru -asQ -asQ -asQ -asQ -asQ -aru -arJ -arJ -avP -avP -avP -avP -avP -arJ -arJ -arJ -aAQ -auk -asX -auk -aFH -arJ -aGJ -aHD -aHD -aIV -aJw -aKy -aLh -aLK -aMh -aGK +aeZ +arR +aVy +bdl +aFM +aFO +aFM +atb +bbo +atb +aBy +aKt +aoJ +aLe +bdS +aLe +aoJ +bex +bfU +bgI +aJt +awT +axo +bgO +aIQ +aph +azt +aJt +ayM +ayM +ayM +ayM +ayM +ayM +aac +aac +aac +aac aac aac aac @@ -48822,17 +54103,61 @@ aac aac aac aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aab -aab +afS +bet +bet +bet +afS +agF +adK +amW +arI +ajY +amZ +afS +apH +arq +acV +acV +acV +acV +acV +acV +axs +ayK +axq +atg +aSy +aop +aop +bdk +ask +aVy +aLg +aFM +aGe +aLb +atb +asu +ati +aFz +asu +aoJ +aUq +beZ +bfw +aoJ +beD +bfV +aHq +bgJ +awm +bdt +axy +axy +aHv +bdO +aJt aac aac aac @@ -48848,50 +54173,6 @@ aac aac aac aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aFb -awu -awu -axx -awu -aFI -arJ -aGK -aGK -aGK -aGK -aGK -aGK -aGK -aGK -aGK -aGK -aac -aac -aac -aac -aac aab aab aab @@ -48958,70 +54239,70 @@ aab aab aab aab -aab -aab aac aac aac aac aac aac +afS +bay +afq +afq +afS +ahs +afY +aib +aFZ +ako +and +afS +apH +arr +asC +asC +asC +asC +asC +avB +axQ +arL +aop +aUr +aWM +aWM +aWM +aWM +asH +aXj +bdH +aFM +aFP +aTI +atb +asx +aty +aGt +aKw +aoJ +baI +bfa +bfx +aoJ +bfk +bgi +bcw +aJt +aws +bdu +axY +bdn +aKs +axu +aJt aac aac aac -aac -aac -aac -aac -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aaq -aaq -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -aac -arJ -avP -avP -avP -avP -avP -arJ -aac -aac -aab aab aab aab @@ -49100,67 +54381,67 @@ aab aab aab aab -aab -aab -aac -aac -aac -aac -aac -aac -aab -aab -aab -aab -aab -aac -aac -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aac -aac -aac -aac -aac -aac -aaq -aaq -aaq -aaq -aaq -aaq -aaq -aaq -aaq -aac -aac -aac -aab -aac -aac -aac -aac -aac aac aac aac aac aac aac +afS +afq +afq +afq +afS +ajZ +afZ +aiX +ajC +akW +anl +afS +bdc +bfl +asE +atm +acV +acV +auN +avE +axX +azp +aop +aVy +aop +aop +aqq +aBG +asO +aqe +bft +aFM +aGd +aHp +bfb +asI +aum +aJw +asu +aoJ +bbJ +bfr +bfZ +beq +bfm +bcB +aLF +aJt +awt +bgM +awV +axp +bbQ +axx +aJt aac aac aab @@ -49242,69 +54523,69 @@ aab aab aab aab -aab -aab -aac -aac -aac -aac -aac -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab aac aac aac aac aac aac -aaq -aaq -aaq -aaq -aaq -aaq -aaq -aaq -aaq -aaq -aab -aab -aab -aab -aab -aab -aac -aac -aac -aab -aab -aab -aab -aab -aab -aab +afS +afq +afq +afq +afS +ash +afq +aiZ +ajD +akX +ann +afS +aqn +ars +acV +atv +aui +acV +auP +avI +arL +avN +aop +aVy +bdj +aop +aqV +aDY +asV +aqe +aLG +aFM +aGg +aXh +atb +asN +awq +aJw +asu +aoJ +bcv +bfs +bgb +aoJ +bfq +bgy +aFM +aJt +aJt +aJt +aJt +aJt +aJt +aJt +aJt +adG +aNC aab aab aab @@ -49384,69 +54665,69 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aaq -aaq -aaq -aaq -aaq -aaq -aaq -aaq -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aac +aac +aac +aac +aac +aac +afS +aby +afq +afq +afS +ajc +ajx +alr +anD +akX +apl +afS +auy +art +aon +atx +aun +aCa +auT +awu +arL +aqm +aop +aVy +aeZ +ata +aCI +aCR +aEh +aqe +aso +aFM +aHo +aXi +atb +asY +axv +bcF +bdI +aoJ +beP +bdR +aBJ +aoJ +bbr +bcB +aAb +adG +adG +adG +adG +adG +adG +adG +adG +adG +aNC aab aab aab @@ -49527,67 +54808,67 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aac +aac +aac +aac +aac +afS +afp +afq +bfW +afS +ajd +ajx +alr +anD +akX +apF +acf +aqX +arO +acV +atv +auo +acV +auP +avI +arL +aqm +aop +aVy +bdk +aop +aop +aop +ask +arK +bfu +aCh +aGj +aHw +atb +atb +atb +atb +atb +aoJ +aoJ +aoJ +aoJ +aoJ +bbv +bcC +aAb +adG +arZ +aNM +aNM +aNM +aNM +aNM +aNM +aNM aab aab aab @@ -49671,58 +54952,58 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aac +aac +aac +afS +afS +afS +afS +afS +ajc +ajx +alr +anE +aoK +apG +afS +apH +arP +acV +atv +acV +acV +avb +awJ +arL +aop +aop +asQ +auk +aEZ +auk +auk +avr +aso +aop +aFM +aGq +aHx +aLC +aLH +aLK +aPF +aSh +bcG +aTJ +aUB +aVd +baS +bbB +bcD +aAb +adG +aNC aab aab aab @@ -49814,57 +55095,57 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aOm +adG +adG +adG +adG +ajG +afS +aje +ajF +alM +anM +aoO +apP +afS +arp +arS +asJ +atz +acV +acV +bej +awN +acf +aCo +aAD +asG +aAD +ayg +aAR +aFa +aEx +aBd +aAR +aFM +aGG +aHA +aLD +aLI +aMg +aRm +aSl +aSl +aTS +aUT +aLI +baY +bbr +bcE +aAb +adG +aNC aab aab aab @@ -49957,56 +55238,56 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aNM +aNM +aNM +aNW +ajG +afS +afS +afS +afS +afS +aoP +afS +afS +aqn +acV +acV +acV +acV +acV +avc +arL +adG +azY +aAH +aBl +avh +ayg +aCC +aEk +bgh +aFb +aFD +aFM +aGI +aIj +aLE +aLE +aLE +aLE +aTc +aLE +aUg +aLE +aLE +aLE +bce +bfv +aAb +adG +aNC aab aab aab @@ -50102,53 +55383,53 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aOm +ajG +ajG +ajG +ajU +amu +amu +apd +ajG +arL +arH +arT +asW +atK +aup +auL +ave +arL +adG +azY +aAI +aBm +avi +ayg +aCD +aEm +aEF +aFg +aFE +aFM +aFM +aIT +aHq +aHq +aHq +aRX +aTw +aTH +aUn +aHq +aHq +aHq +bgw +aAa +aAa +adG +aNC aab aab aab @@ -50245,52 +55526,52 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aNM +aNM +aNW +amt +anO +aoR +atd +ajG +auR +aAh +aAh +aAh +aAh +aAh +aAh +aAh +axm +adG +azY +aAJ +aBz +aBZ +aCp +aCE +aEm +aEL +aFk +aFG +aDX +aFM +aXS +aLF +aLJ +aMh +aJq +aTG +bfJ +aMh +aJq +aWl +aLF +aMh +bfL +adG +adG +aNC aab aab aab @@ -50389,49 +55670,49 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aOm +ajG +ajG +ajG +avk +ajG +adG +adG +adG +adG +adG +adG +adG +adG +adG +adG +azY +aAK +aBA +arM +aCp +aCW +aEm +aEM +aFl +aEm +aOg +aFM +aFM +aAa +azX +azX +azX +azX +azX +azX +azX +azX +azX +azX +aAa +adG +arZ aab aab aab @@ -50532,48 +55813,48 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aOt +adG +azY +aAP +aBA +aCg +aCp +aDC +aEm +aEN +aFB +aFH +aGc +aJu +aGa +azY +adG +adG +adG +adG +adG +adG +adG +adG +adG +adG +adG +adG +aNC aab aab aab @@ -50687,34 +55968,34 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aOm +adG +azY +aAQ +aBC +aCk +aCp +aAP +aEm +aEm +aEm +aEm +aGJ +aGJ +aJJ +azY +adG +arZ +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM aab aab aab @@ -50829,24 +56110,24 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aOm +adG +aAC +aAR +aAR +aAR +ayg +aDM +aEn +aFI +aFI +aFR +aFR +aFR +aKl +azY +adG +aNC aab aab aab @@ -50971,24 +56252,24 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aOm +adG +adG +adG +adG +adG +aAC +aAR +aAR +aAR +aAR +aAR +aAR +aAR +aAR +ayg +adG +aNC aab aab aab @@ -51114,23 +56395,23 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aNM +aNM +aNM +aNW +adG +adG +adG +adG +adG +adG +adG +adG +adG +adG +adG +adG +aNC aab aab aab @@ -51260,18 +56541,18 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM +aNM aab aab aab diff --git a/maps/tether/tether-04-transit.dmm b/maps/tether/tether-04-transit.dmm index c9d69a263b7..0966e00ca43 100644 --- a/maps/tether/tether-04-transit.dmm +++ b/maps/tether/tether-04-transit.dmm @@ -86,7 +86,6 @@ icon_state = "32-2" }, /obj/structure/disposalpipe/down, -/obj/effect/ceiling, /obj/machinery/door/firedoor/glass, /turf/simulated/open, /area/maintenance/tether_midpoint) @@ -260,6 +259,7 @@ }, /obj/structure/cable, /obj/effect/ceiling, +/obj/effect/ceiling, /turf/simulated/floor/plating, /area/maintenance/tether_midpoint) "y" = ( @@ -284,6 +284,7 @@ /obj/structure/disposalpipe/up{ dir = 8 }, +/obj/effect/ceiling, /turf/simulated/floor/plating, /area/maintenance/tether_midpoint) "B" = ( @@ -292,6 +293,7 @@ "C" = ( /obj/structure/disposalpipe/up, /obj/effect/ceiling, +/obj/effect/ceiling, /turf/simulated/floor/plating, /area/maintenance/tether_midpoint) "D" = ( diff --git a/maps/tether/tether-05-station1.dmm b/maps/tether/tether-05-station1.dmm index 0178eb04a34..f36d143c622 100644 --- a/maps/tether/tether-05-station1.dmm +++ b/maps/tether/tether-05-station1.dmm @@ -55,11 +55,6 @@ /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 10 }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -71,6 +66,11 @@ icon_state = "alarm0"; pixel_y = -22 }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_lobby) "aai" = ( @@ -4076,9 +4076,9 @@ dir = 9; icon_state = "steel_grid" }, -/obj/machinery/atmospherics/pipe/simple/hidden{ - dir = 10; - icon_state = "intact" +/obj/machinery/atmospherics/pipe/manifold/hidden{ + dir = 1; + icon_state = "map" }, /turf/simulated/floor/tiled, /area/engineering/engine_airlock) @@ -4105,6 +4105,9 @@ name = "Engine Access"; req_one_access = list(11) }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 8 + }, /turf/simulated/floor/tiled/steel_grid, /area/engineering/engine_airlock) "ahE" = ( @@ -4185,6 +4188,9 @@ dir = 10 }, /obj/effect/floor_decal/steeldecal/steel_decals4, +/obj/machinery/atmospherics/pipe/simple/hidden/universal{ + dir = 4 + }, /turf/simulated/floor/tiled, /area/engineering/engine_airlock) "ahL" = ( @@ -5670,11 +5676,6 @@ /turf/simulated/floor, /area/engineering/storage) "akX" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 8 }, @@ -5710,6 +5711,9 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "alb" = ( +/obj/machinery/atmospherics/binary/passive_gate{ + dir = 8 + }, /turf/simulated/floor/tiled, /area/engineering/engine_airlock) "alc" = ( @@ -5904,11 +5908,6 @@ /turf/simulated/floor, /area/engineering/engineering_monitoring) "alu" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -5925,6 +5924,11 @@ /obj/machinery/door/firedoor/glass/hidden/steel{ dir = 1 }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "alv" = ( @@ -6216,11 +6220,6 @@ /turf/simulated/floor/wood, /area/hallway/station/atrium) "amc" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 8 }, @@ -6309,11 +6308,6 @@ /turf/simulated/floor/wood, /area/hallway/station/atrium) "amj" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 8 }, @@ -6329,11 +6323,6 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "amk" = ( -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/effect/floor_decal/steeldecal/steel_decals7{ dir = 8 }, @@ -6360,11 +6349,6 @@ /turf/simulated/floor/wood, /area/hallway/station/atrium) "amn" = ( -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/effect/floor_decal/steeldecal/steel_decals7{ @@ -6379,6 +6363,11 @@ /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 4 }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "amo" = ( @@ -6906,11 +6895,6 @@ /turf/simulated/floor/plating, /area/maintenance/abandonedlibrary) "ant" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -6924,6 +6908,11 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "anu" = ( @@ -6959,11 +6948,6 @@ /turf/simulated/floor/wood/broken, /area/maintenance/abandonedlibrary) "any" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -6975,14 +6959,14 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/turf/simulated/floor/tiled, -/area/engineering/hallway) -"anz" = ( -/obj/structure/cable{ +/obj/structure/cable/green{ d1 = 4; d2 = 8; icon_state = "4-8" }, +/turf/simulated/floor/tiled, +/area/engineering/hallway) +"anz" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /obj/effect/floor_decal/steeldecal/steel_decals7, @@ -6993,6 +6977,16 @@ dir = 4 }, /obj/machinery/light, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "anA" = ( @@ -7005,11 +6999,6 @@ /turf/simulated/floor/plating, /area/maintenance/abandonedlibrary) "anB" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -7021,6 +7010,11 @@ /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 10 }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "anC" = ( @@ -7046,16 +7040,6 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "anD" = ( -/obj/structure/cable{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, -/obj/structure/cable{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, /obj/structure/disposalpipe/segment{ dir = 2; icon_state = "pipe-c" @@ -7066,17 +7050,22 @@ /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 6 }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 1 }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_lobby) "anE" = ( @@ -7086,11 +7075,6 @@ /turf/simulated/floor, /area/maintenance/station/eng_lower) "anF" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, @@ -7113,6 +7097,11 @@ name = "Gravity Generator"; req_access = list(11) }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled/steel_grid, /area/engineering/hallway) "anG" = ( @@ -7829,7 +7818,7 @@ }, /obj/machinery/door/firedoor/glass, /obj/machinery/door/airlock/glass_atmos{ - name = "Atmospherics Substation"; + name = "Backup Atmospherics"; req_access = list(24) }, /turf/simulated/floor/tiled/steel_grid, @@ -8187,6 +8176,11 @@ d2 = 8; icon_state = "4-8" }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "apN" = ( @@ -8815,6 +8809,11 @@ name = "Engineering"; sortType = "Engineering" }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "aqT" = ( @@ -8826,6 +8825,11 @@ dir = 8 }, /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "aqU" = ( @@ -9183,6 +9187,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /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/engineering/hallway) "arI" = ( @@ -10656,6 +10665,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/cable{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "auw" = ( @@ -10699,6 +10713,11 @@ dir = 4 }, /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "auz" = ( @@ -11368,6 +11387,11 @@ name = "Engineering Break Room"; sortType = "Engineering Break Room" }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "avA" = ( @@ -11878,6 +11902,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/cyan{ dir = 6 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "awo" = ( @@ -15516,6 +15545,11 @@ dir = 4; icon_state = "map" }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "aCS" = ( @@ -16216,6 +16250,11 @@ icon_state = "map" }, /obj/machinery/meter, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "aEy" = ( @@ -16794,6 +16833,11 @@ dir = 9; icon_state = "intact" }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "aIl" = ( @@ -20002,6 +20046,11 @@ name = "Engineering Lobby"; req_one_access = newlist() }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled/steel_grid, /area/engineering/foyer) "bzR" = ( @@ -20809,6 +20858,11 @@ name = "Engineering Hallway"; req_one_access = list(10) }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled/steel_grid, /area/engineering/foyer) "chD" = ( @@ -20860,12 +20914,6 @@ /area/tether/station/dock_two) "cto" = ( /obj/machinery/door/firedoor/glass, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, @@ -20877,6 +20925,11 @@ id_tag = "gravity_outer"; req_access = list(11) }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_lobby) "cuX" = ( @@ -20922,18 +20975,17 @@ dir = 4; icon_state = "map" }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled/techmaint, /area/engineering/gravity_lobby) "cTc" = ( @@ -21067,6 +21119,14 @@ }, /turf/simulated/floor/tiled/techmaint, /area/engineering/gravity_gen) +"dub" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/engineering/foyer) "dzP" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -21159,6 +21219,14 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /turf/simulated/floor/carpet/purcarpet, /area/bridge/meeting_room) +"eed" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/engineering/hallway) "ejF" = ( /obj/effect/floor_decal/borderfloor/corner{ dir = 1 @@ -21428,6 +21496,17 @@ /obj/machinery/atmospherics/pipe/simple/hidden, /turf/simulated/floor/tiled, /area/tether/station/dock_one) +"fPT" = ( +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/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/engineering/hallway) "fTF" = ( /obj/structure/cable/green{ d1 = 1; @@ -21455,15 +21534,14 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 1 }, -/obj/structure/cable{ - d2 = 2; - icon_state = "0-2"; - pixel_y = 0 - }, /obj/machinery/power/apc/super{ dir = 1; pixel_y = 28 }, +/obj/structure/cable/green{ + d2 = 2; + icon_state = "0-2" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_gen) "fXG" = ( @@ -21481,11 +21559,6 @@ d2 = 2; icon_state = "1-2" }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, /obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/engineering/hallway) @@ -21786,6 +21859,11 @@ /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 5 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/foyer) "hLV" = ( @@ -21985,11 +22063,6 @@ /turf/simulated/floor/tiled, /area/tether/station/dock_one) "juf" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/structure/cable/green{ d1 = 1; d2 = 2; @@ -22004,6 +22077,11 @@ /obj/structure/disposalpipe/junction{ dir = 8 }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "juI" = ( @@ -22017,6 +22095,11 @@ /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 9 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) "jFv" = ( @@ -22033,13 +22116,10 @@ dir = 8; icon_state = "bordercolorcorner" }, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 - }, /obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/structure/cable/green{ + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_gen) "jNX" = ( @@ -22064,15 +22144,15 @@ dir = 9; icon_state = "steel_grid" }, -/obj/structure/cable{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_gen) "jOH" = ( @@ -22228,6 +22308,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/foyer) "kJJ" = ( @@ -22592,6 +22677,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "nll" = ( @@ -22743,17 +22833,14 @@ /obj/effect/floor_decal/corner/yellow/border{ dir = 8 }, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 - }, /obj/machinery/firealarm{ dir = 8; pixel_x = -24 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/green{ + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_gen) "oso" = ( @@ -22800,11 +22887,6 @@ /turf/simulated/floor/tiled/steel_grid, /area/tether/station/dock_two) "oAK" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, @@ -22812,6 +22894,11 @@ dir = 8 }, /obj/structure/disposalpipe/junction/yjunction, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "oFB" = ( @@ -22998,18 +23085,17 @@ dir = 6; icon_state = "steel_grid" }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_lobby) "qdM" = ( @@ -23103,6 +23189,22 @@ }, /turf/simulated/floor/tiled, /area/engineering/gravity_gen) +"qvC" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/simulated/floor/tiled, +/area/hallway/station/atrium) "qxn" = ( /obj/effect/floor_decal/techfloor/orange{ dir = 10 @@ -23123,18 +23225,17 @@ /obj/machinery/atmospherics/pipe/simple/hidden{ dir = 4 }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled/techmaint, /area/engineering/gravity_lobby) "riO" = ( @@ -23197,7 +23298,7 @@ name = "west bump"; pixel_x = -28 }, -/obj/structure/cable{ +/obj/structure/cable/green{ d2 = 4; icon_state = "0-4" }, @@ -23394,11 +23495,6 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "sjw" = ( -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/door/firedoor/glass, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -23410,6 +23506,11 @@ name = "Gravity Generator"; req_access = list(11) }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled/steel_grid, /area/engineering/gravity_lobby) "sqw" = ( @@ -23508,6 +23609,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/cable{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, /turf/simulated/floor/tiled, /area/hallway/station/atrium) "sTb" = ( @@ -23644,6 +23750,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/foyer) "tqW" = ( @@ -23818,14 +23929,13 @@ /turf/simulated/floor/tiled, /area/engineering/hallway) "uOm" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 - }, /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, /area/engineering/gravity_lobby) "uTq" = ( @@ -23976,7 +24086,9 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ + dir = 4 + }, /turf/simulated/floor/tiled, /area/engineering/hallway) "vms" = ( @@ -24001,17 +24113,17 @@ /turf/space, /area/space) "vxw" = ( -/obj/structure/cable{ - d1 = 2; - d2 = 8; - icon_state = "2-8" - }, /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, +/obj/structure/cable/green{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_lobby) "vyI" = ( @@ -24048,6 +24160,11 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/foyer) "vAQ" = ( @@ -24057,17 +24174,17 @@ /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 6 }, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_lobby) "vCw" = ( @@ -24134,13 +24251,10 @@ /obj/effect/floor_decal/corner/yellow/bordercorner2{ dir = 10 }, -/obj/structure/cable{ - d1 = 1; - d2 = 2; - icon_state = "1-2"; - pixel_y = 0 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, +/obj/structure/cable/green{ + icon_state = "1-2" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_gen) "wbY" = ( @@ -24353,18 +24467,17 @@ dir = 4 }, /obj/machinery/door/firedoor/glass, -/obj/structure/cable{ - d1 = 4; - d2 = 8; - icon_state = "4-8"; - pixel_x = 0 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_lobby) "xMk" = ( @@ -24459,22 +24572,22 @@ /turf/simulated/floor/tiled, /area/hallway/station/atrium) "ykG" = ( -/obj/structure/cable{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/structure/cable{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 8 }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 5 }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, /turf/simulated/floor/tiled, /area/engineering/gravity_lobby) @@ -31641,17 +31754,17 @@ aCR aEx aCR aIi -atW +eed mYV ceq vAn tpy -aoI +dub kHi hKn bzw jBX -agj +qvC sRG aws fjd @@ -31769,7 +31882,7 @@ bcc hAh qsp oAK -aKt +fPT apM aqS aqT diff --git a/maps/tether/tether-06-station2.dmm b/maps/tether/tether-06-station2.dmm index 24611e22dab..c9ff3f61904 100644 --- a/maps/tether/tether-06-station2.dmm +++ b/maps/tether/tether-06-station2.dmm @@ -91,19 +91,30 @@ /turf/simulated/floor/tiled/dark, /area/security/brig) "an" = ( +/obj/effect/floor_decal/corner/red{ + dir = 9; + icon_state = "corner_white" + }, +/obj/effect/floor_decal/corner/red{ + dir = 6; + icon_state = "corner_white" + }, /obj/machinery/door/firedoor/glass, -/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" +/obj/machinery/door/blast/regular{ + density = 0; + dir = 1; + icon_state = "pdoor0"; + id = "brig_lockdown"; + name = "Security Blast Doors"; + opacity = 0 }, -/obj/machinery/door/airlock{ - name = "Visitation"; - req_one_access = list(1,38) +/obj/structure/table/reinforced, +/obj/machinery/door/window/brigdoor/westleft{ + req_access = list(2) + }, +/obj/machinery/door/window/brigdoor/eastright{ + req_access = list(2) }, -/obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, /area/security/brig/visitation) "ao" = ( @@ -305,6 +316,16 @@ }, /turf/simulated/floor/tiled/dark, /area/security/brig) +"aH" = ( +/obj/effect/floor_decal/industrial/warning/corner, +/obj/machinery/cryopod{ + dir = 4 + }, +/obj/machinery/computer/cryopod{ + pixel_x = -32 + }, +/turf/simulated/floor/tiled, +/area/security/brig) "aI" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 @@ -427,6 +448,20 @@ /obj/machinery/light, /turf/simulated/floor/tiled, /area/security/brig/visitation) +"aW" = ( +/obj/structure/table/rack{ + dir = 8; + layer = 2.9 + }, +/obj/item/weapon/stock_parts/matter_bin, +/obj/item/weapon/stock_parts/matter_bin, +/obj/item/weapon/stock_parts/manipulator, +/obj/item/weapon/stock_parts/manipulator, +/obj/item/weapon/stock_parts/console_screen, +/obj/item/weapon/circuitboard/autolathe, +/obj/item/weapon/circuitboard/partslathe, +/turf/simulated/floor, +/area/storage/tech) "aX" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -761,6 +796,22 @@ /obj/effect/floor_decal/borderfloor/shifted, /turf/simulated/floor/tiled, /area/security/brig) +"bs" = ( +/obj/machinery/door/firedoor/glass, +/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" + }, +/obj/machinery/door/airlock{ + name = "Visitation"; + req_one_access = list(38,63) + }, +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/tiled, +/area/security/brig/visitation) "bt" = ( /obj/structure/bed/chair{ dir = 1 @@ -860,6 +911,28 @@ }, /turf/simulated/floor/tiled/steel_dirty, /area/security/brig) +"bC" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/airlock/security{ + name = "Brig Recreation Storage"; + req_one_access = list(63) + }, +/turf/simulated/floor/tiled, +/area/security/recstorage) "bD" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 4 @@ -1606,23 +1679,30 @@ /area/security/security_cell_hallway) "cx" = ( /obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply, +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" + d1 = 1; + d2 = 2; + icon_state = "1-2" }, -/obj/machinery/door/airlock/security{ - name = "Observation"; - req_one_access = list(1,4) +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "security_lockdown"; + name = "Security Blast Doors"; + opacity = 0 }, -/turf/simulated/floor/tiled/dark, -/area/security/interrogation) +/obj/machinery/door/airlock/maintenance/sec{ + name = "Riot Control"; + req_access = list(); + req_one_access = list(2,63) + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/hidden/green, +/turf/simulated/floor, +/area/security/riot_control) "cy" = ( /obj/structure/device/piano, /turf/simulated/mineral/floor/vacuum, @@ -2188,30 +2268,24 @@ /turf/simulated/floor/tiled, /area/security/brig/visitation) "dl" = ( -/obj/effect/floor_decal/corner/red{ - dir = 9; - icon_state = "corner_white" - }, -/obj/effect/floor_decal/corner/red{ - dir = 6; - icon_state = "corner_white" - }, /obj/machinery/door/firedoor/glass, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 1; - icon_state = "pdoor0"; - id = "brig_lockdown"; - name = "Security Blast Doors"; - opacity = 0 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, -/obj/structure/table/reinforced, -/obj/machinery/door/window/brigdoor/westleft{ - req_access = list(1,2) +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 }, -/obj/machinery/door/window/brigdoor/eastright, -/turf/simulated/floor/tiled, -/area/security/brig/visitation) +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/door/airlock/security{ + name = "Observation"; + req_one_access = list(4,63) + }, +/turf/simulated/floor/tiled/dark, +/area/security/interrogation) "dm" = ( /obj/structure/table/woodentable, /obj/item/weapon/folder/yellow, @@ -2476,6 +2550,22 @@ /obj/machinery/atmospherics/unary/vent_pump/on, /turf/simulated/floor/tiled, /area/tether/exploration/crew) +"dI" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 1; + icon_state = "pdoor0"; + id = "englockdown"; + name = "Engineering Lockdown"; + opacity = 0 + }, +/obj/machinery/door/airlock/maintenance/sec{ + name = "Riot Control"; + req_one_access = list(2,10,24) + }, +/turf/simulated/floor/plating, +/area/security/riot_control) "dJ" = ( /obj/structure/bed/chair/office/dark{ dir = 8 @@ -2580,29 +2670,27 @@ /turf/simulated/floor/tiled, /area/security/brig) "dR" = ( +/obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor/glass, -/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" +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 4 }, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 4; - icon_state = "pdoor0"; - id = "security_lockdown"; - name = "Security Blast Doors"; - opacity = 0 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 4 + }, +/obj/structure/cable/green{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, /obj/machinery/door/airlock/maintenance/sec{ name = "Riot Control"; - req_access = list(1) + req_one_access = list(2,10,24) }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/simple/hidden/green, -/turf/simulated/floor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/simulated/floor/plating, /area/security/riot_control) "dS" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -2662,26 +2750,13 @@ /turf/simulated/floor/tiled, /area/security/security_cell_hallway) "dU" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_l" }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/airlock/security{ - name = "Brig Recreation Storage" - }, -/turf/simulated/floor/tiled, -/area/security/recstorage) +/turf/space, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/large_escape_pod1) "dV" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 9 @@ -2958,6 +3033,18 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/port) +"ev" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/borderfloorwhite{ + dir = 6 + }, +/obj/effect/floor_decal/corner/white/border{ + dir = 6 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2, +/obj/effect/floor_decal/corner/white/bordercorner2, +/turf/simulated/floor/tiled/white, +/area/medical/surgery2) "ew" = ( /obj/machinery/door/firedoor/glass, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ @@ -3093,6 +3180,40 @@ }, /turf/simulated/floor/tiled, /area/tether/exploration/crew) +"eE" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/borderfloorwhite{ + dir = 9 + }, +/obj/effect/floor_decal/corner/white/border{ + dir = 9 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 1 + }, +/obj/effect/floor_decal/corner/white/bordercorner2{ + dir = 1; + icon_state = "bordercolorcorner2" + }, +/obj/machinery/status_display{ + density = 0; + layer = 4; + pixel_x = -32; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/white, +/area/medical/surgery) +"eF" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/borderfloorwhite{ + dir = 10 + }, +/obj/effect/floor_decal/corner/white/border{ + dir = 10; + icon_state = "bordercolor" + }, +/turf/simulated/floor/tiled/white, +/area/medical/surgery) "eG" = ( /turf/simulated/floor/tiled, /area/tether/exploration/crew) @@ -3296,6 +3417,15 @@ "eT" = ( /turf/simulated/floor, /area/maintenance/station/micro) +"eU" = ( +/obj/structure/table/standard, +/obj/item/device/radio/intercom/department/medbay{ + pixel_y = -24 + }, +/obj/effect/floor_decal/borderfloorwhite, +/obj/effect/floor_decal/corner/white/border, +/turf/simulated/floor/tiled/white, +/area/medical/surgery) "eV" = ( /obj/structure/table/wooden_reinforced, /obj/item/weapon/paper_bin{ @@ -3327,6 +3457,12 @@ }, /turf/simulated/floor/tiled, /area/tether/exploration/staircase) +"eX" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/borderfloorwhite, +/obj/effect/floor_decal/corner/white/border, +/turf/simulated/floor/tiled/white, +/area/medical/surgery) "eY" = ( /obj/structure/cable/green{ d1 = 4; @@ -3685,12 +3821,21 @@ /turf/simulated/floor/tiled, /area/tether/exploration/staircase) "fD" = ( -/obj/effect/floor_decal/industrial/warning/corner, -/obj/machinery/cryopod{ - dir = 4 +/obj/structure/table/standard, +/obj/effect/floor_decal/borderfloorwhite{ + dir = 6 }, -/turf/simulated/floor/tiled, -/area/security/brig) +/obj/effect/floor_decal/corner/white/border{ + dir = 6 + }, +/obj/item/weapon/reagent_containers/spray/cleaner{ + desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; + name = "Surgery Cleaner"; + pixel_x = 2; + pixel_y = 2 + }, +/turf/simulated/floor/tiled/white, +/area/medical/surgery2) "fE" = ( /obj/effect/floor_decal/techfloor{ dir = 8 @@ -4491,6 +4636,44 @@ /obj/random/maintenance/research, /turf/simulated/floor, /area/maintenance/station/exploration) +"gS" = ( +/obj/structure/table/standard, +/obj/effect/floor_decal/borderfloorwhite{ + dir = 5 + }, +/obj/effect/floor_decal/corner/white/border{ + dir = 5 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 4 + }, +/obj/effect/floor_decal/corner/white/bordercorner2{ + dir = 4; + icon_state = "bordercolorcorner2" + }, +/obj/machinery/status_display{ + density = 0; + layer = 4; + pixel_x = 32; + pixel_y = 0 + }, +/turf/simulated/floor/tiled/white, +/area/medical/surgery2) +"gT" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8 + }, +/turf/space, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/large_escape_pod1) +"gU" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_r" + }, +/turf/space, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/large_escape_pod1) "gV" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/red/border, @@ -5974,22 +6157,6 @@ }, /turf/simulated/floor/tiled, /area/engineering/foyer_mezzenine) -"jh" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 1; - icon_state = "pdoor0"; - id = "englockdown"; - name = "Engineering Lockdown"; - opacity = 0 - }, -/obj/machinery/door/airlock/maintenance/sec{ - name = "Riot Control"; - req_one_access = list(1,10,24) - }, -/turf/simulated/floor/plating, -/area/security/riot_control) "ji" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, @@ -7025,19 +7192,6 @@ /obj/item/device/analyzer, /turf/simulated/floor/plating, /area/storage/tech) -"kN" = ( -/obj/structure/table/rack{ - dir = 8; - layer = 2.9 - }, -/obj/item/weapon/stock_parts/matter_bin, -/obj/item/weapon/stock_parts/matter_bin, -/obj/item/weapon/stock_parts/manipulator, -/obj/item/weapon/stock_parts/console_screen, -/obj/item/weapon/circuitboard/autolathe, -/obj/item/weapon/circuitboard/partslathe, -/turf/simulated/floor, -/area/storage/tech) "kO" = ( /obj/structure/table/rack{ dir = 8; @@ -9407,21 +9561,6 @@ /obj/structure/disposalpipe/segment, /turf/simulated/floor, /area/maintenance/station/exploration) -"ot" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8; - icon_state = "propulsion_l" - }, -/turf/space, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/large_escape_pod1) -"ou" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8 - }, -/turf/space, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/large_escape_pod1) "ov" = ( /obj/machinery/door/firedoor/glass, /obj/structure/lattice, @@ -10145,14 +10284,6 @@ }, /turf/simulated/floor/tiled/steel_grid, /area/engineering/foyer_mezzenine) -"pM" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8; - icon_state = "propulsion_r" - }, -/turf/space, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/large_escape_pod1) "pN" = ( /obj/machinery/requests_console{ department = "Tech storage"; @@ -15374,18 +15505,6 @@ /obj/effect/floor_decal/industrial/loading, /turf/simulated/floor/tiled/white, /area/medical/surgery2) -"yx" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 6 - }, -/obj/effect/floor_decal/corner/white/border{ - dir = 6 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2, -/obj/effect/floor_decal/corner/white/bordercorner2, -/turf/simulated/floor/tiled/white, -/area/medical/surgery2) "yy" = ( /obj/structure/cable/green{ d1 = 1; @@ -15907,32 +16026,6 @@ }, /turf/simulated/floor/plating, /area/medical/patient_a) -"zH" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 10 - }, -/obj/effect/floor_decal/corner/white/border{ - dir = 10; - icon_state = "bordercolor" - }, -/turf/simulated/floor/tiled/white, -/area/medical/surgery) -"zI" = ( -/obj/structure/table/standard, -/obj/item/device/radio/intercom/department/medbay{ - pixel_y = -24 - }, -/obj/effect/floor_decal/borderfloorwhite, -/obj/effect/floor_decal/corner/white/border, -/turf/simulated/floor/tiled/white, -/area/medical/surgery) -"zJ" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/borderfloorwhite, -/obj/effect/floor_decal/corner/white/border, -/turf/simulated/floor/tiled/white, -/area/medical/surgery) "zK" = ( /obj/structure/closet/crate/freezer, /obj/item/weapon/reagent_containers/blood/OMinus, @@ -16023,16 +16116,6 @@ /obj/effect/floor_decal/corner/white/border, /turf/simulated/floor/tiled/white, /area/medical/surgery2) -"zQ" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 6 - }, -/obj/effect/floor_decal/corner/white/border{ - dir = 6 - }, -/turf/simulated/floor/tiled/white, -/area/medical/surgery2) "zR" = ( /obj/structure/cable/green{ d1 = 1; @@ -16301,29 +16384,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/surgery_hallway) -"An" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 9 - }, -/obj/effect/floor_decal/corner/white/border{ - dir = 9 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 1 - }, -/obj/effect/floor_decal/corner/white/bordercorner2{ - dir = 1; - icon_state = "bordercolorcorner2" - }, -/obj/machinery/status_display{ - density = 0; - layer = 4; - pixel_x = -32; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/white, -/area/medical/surgery) "Ao" = ( /obj/structure/filingcabinet/chestdrawer{ name = "Scan Records" @@ -19232,29 +19292,6 @@ }, /turf/simulated/floor/airless, /area/maintenance/station/sec_lower) -"Fg" = ( -/obj/structure/table/standard, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 5 - }, -/obj/effect/floor_decal/corner/white/border{ - dir = 5 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 4 - }, -/obj/effect/floor_decal/corner/white/bordercorner2{ - dir = 4; - icon_state = "bordercolorcorner2" - }, -/obj/machinery/status_display{ - density = 0; - layer = 4; - pixel_x = 32; - pixel_y = 0 - }, -/turf/simulated/floor/tiled/white, -/area/medical/surgery2) "Fh" = ( /obj/structure/bed/roller, /obj/machinery/atmospherics/unary/vent_scrubber/on, @@ -22598,29 +22635,6 @@ }, /turf/simulated/floor/tiled, /area/hallway/station/port) -"Yq" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/firedoor/glass, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/obj/structure/cable/green{ - d1 = 4; - d2 = 8; - icon_state = "4-8" - }, -/obj/machinery/door/airlock/maintenance/sec{ - name = "Riot Control"; - req_one_access = list(1,10,24) - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/simulated/floor/plating, -/area/security/riot_control) "Yw" = ( /turf/simulated/floor/airless, /area/mine/explored/upper_level) @@ -28396,13 +28410,13 @@ fX fX fX fX -kJ +lw lw lw mF lw lw -kJ +lw kJ pG pG @@ -28964,7 +28978,7 @@ is jb jC fX -kN +aW kK mj mJ @@ -29092,7 +29106,7 @@ af RE EP PM -an +bs EZ Ix BV @@ -29374,7 +29388,7 @@ ch ch af cX -dl +an cX af bi @@ -29948,7 +29962,7 @@ bI Hx VU eS -fD +aH Pm aS sg @@ -30523,7 +30537,7 @@ ct cv TY TY -jh +dI TY TY ac @@ -30805,7 +30819,7 @@ Ui aS gW Eu -dR +cx aJ aZ bo @@ -31092,7 +31106,7 @@ Oc TY TY TY -Yq +dR TY TY kj @@ -31791,7 +31805,7 @@ ba cA cU cU -dU +bC cU fd fd @@ -31799,7 +31813,7 @@ cl fd fd fd -cx +dl fd aj dW @@ -31973,8 +31987,8 @@ xb ya xZ yY -An -zH +eE +eF xb Ah Aw @@ -32116,7 +32130,7 @@ xp yb yZ zq -zI +eU xb Ai Ax @@ -32258,7 +32272,7 @@ xq yc za zr -zJ +eX xb Aj Ax @@ -33959,10 +33973,10 @@ wi wI xf ys -yx +ev zm -Fg -zQ +gS +fD xf pp pp @@ -37490,11 +37504,11 @@ hl DI RX DL -ot -ou -ou -ou -pM +dU +gT +gT +gT +gU oY sW ef diff --git a/maps/tether/tether-07-station3.dmm b/maps/tether/tether-07-station3.dmm index c24589d762b..b48c56c97fa 100644 --- a/maps/tether/tether-07-station3.dmm +++ b/maps/tether/tether-07-station3.dmm @@ -29,6 +29,13 @@ }, /turf/simulated/floor/tiled, /area/security/eva) +"aah" = ( +/obj/machinery/atmospherics/unary/engine{ + dir = 1 + }, +/turf/simulated/floor/reinforced, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/excursion/cargo) "aai" = ( /turf/simulated/wall/r_wall, /area/security/armory/red) @@ -161,7 +168,7 @@ "aas" = ( /obj/machinery/door/firedoor/glass, /obj/machinery/door/airlock/glass_security{ - req_one_access = list(1,38) + req_one_access = list(38,63) }, /turf/simulated/floor/tiled, /area/security/hallway) @@ -259,7 +266,7 @@ /obj/machinery/door/firedoor/glass, /obj/structure/disposalpipe/segment, /obj/machinery/door/airlock/glass_security{ - req_one_access = list(1,38) + req_one_access = list(38,63) }, /turf/simulated/floor/tiled, /area/security/hallway) @@ -345,7 +352,7 @@ }, /obj/machinery/door/firedoor/glass, /obj/machinery/door/airlock/glass_security{ - req_one_access = list(1,38) + req_one_access = list(38,63) }, /turf/simulated/floor/tiled, /area/security/hallway) @@ -376,7 +383,7 @@ }, /obj/machinery/door/firedoor/glass, /obj/machinery/door/airlock/glass_security{ - req_one_access = list(1,38) + req_one_access = list(38,63) }, /turf/simulated/floor/tiled, /area/security/hallway) @@ -402,29 +409,36 @@ icon_state = "1-2" }, /obj/machinery/door/airlock/glass_security{ - req_one_access = list(1,38) + req_one_access = list(38,63) }, /turf/simulated/floor/tiled, /area/security/hallway) "aaM" = ( -/obj/machinery/door/firedoor/glass, -/obj/machinery/door/blast/regular{ - density = 0; - dir = 4; - icon_state = "pdoor0"; - id = "security_lockdown"; - name = "Security Blast Doors"; - opacity = 0 +/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" }, /obj/machinery/door/airlock/glass_security{ - id_tag = "BrigFoyer"; - layer = 2.8; - name = "Security"; - req_access = newlist(); - req_one_access = list(1,38) + name = "Front Desk"; + req_access = list(63); + req_one_access = list(63) }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/cable/green{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/tiled, -/area/security/hallway) +/area/security/lobby) "aaN" = ( /obj/machinery/door/firedoor/glass, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -637,6 +651,17 @@ "abc" = ( /turf/simulated/wall, /area/security/eva) +"abd" = ( +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/red/border, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 9 + }, +/turf/simulated/floor/tiled, +/area/security/hallway) "abe" = ( /turf/simulated/wall/r_wall, /area/tether/exploration) @@ -714,6 +739,12 @@ }, /turf/simulated/floor/tiled, /area/security/eva) +"abl" = ( +/obj/machinery/atmospherics/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/simulated/floor/tiled, +/area/security/hallway) "abm" = ( /turf/simulated/wall, /area/maintenance/substation/security) @@ -1236,6 +1267,14 @@ }, /turf/simulated/floor/tiled/monotile, /area/tether/exploration) +"abZ" = ( +/obj/effect/floor_decal/borderfloor, +/obj/effect/floor_decal/corner/red/border, +/obj/effect/floor_decal/borderfloor/corner2{ + dir = 2 + }, +/turf/simulated/floor/tiled, +/area/security/hallway) "aca" = ( /obj/machinery/door/firedoor/glass, /obj/machinery/atmospherics/pipe/simple/hidden/supply, @@ -1349,6 +1388,12 @@ /obj/structure/window/reinforced/full, /turf/simulated/floor, /area/security/hallwayaux) +"ach" = ( +/obj/machinery/door/airlock/glass_security{ + name = "Forensics Lab" + }, +/turf/simulated/floor/tiled, +/area/security/forensics) "aci" = ( /obj/effect/floor_decal/borderfloor{ dir = 1; @@ -1423,6 +1468,34 @@ /obj/structure/cable/green, /turf/simulated/floor, /area/maintenance/substation/security) +"acm" = ( +/obj/effect/floor_decal/borderfloorwhite{ + dir = 9 + }, +/obj/effect/floor_decal/corner/red/border{ + dir = 9 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 10 + }, +/obj/effect/floor_decal/corner/red/bordercorner2{ + dir = 10 + }, +/obj/structure/cable/green{ + d2 = 2; + icon_state = "0-2" + }, +/obj/structure/closet{ + name = "Evidence Closet" + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 1 + }, +/obj/effect/floor_decal/corner/red/bordercorner2{ + dir = 1 + }, +/turf/simulated/floor/tiled/white, +/area/security/forensics) "acn" = ( /obj/machinery/door/airlock/engineering{ name = "Security Substation"; @@ -1809,13 +1882,8 @@ /turf/simulated/floor/tiled, /area/security/hallwayaux) "acZ" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/red/border, -/turf/simulated/floor/tiled, -/area/security/hallway) +/turf/simulated/floor/tiled/white, +/area/security/forensics) "ada" = ( /obj/structure/bed/chair/office/dark{ dir = 1 @@ -1901,6 +1969,29 @@ }, /turf/simulated/floor/tiled/monotile, /area/tether/exploration) +"adi" = ( +/obj/machinery/disposal, +/obj/effect/floor_decal/borderfloorwhite{ + dir = 5 + }, +/obj/effect/floor_decal/corner/red/border{ + dir = 5 + }, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 5 + }, +/obj/effect/floor_decal/corner/red/bordercorner2{ + dir = 5 + }, +/obj/structure/disposalpipe/trunk, +/obj/effect/floor_decal/borderfloorwhite/corner2{ + dir = 4 + }, +/obj/effect/floor_decal/corner/red/bordercorner2{ + dir = 4 + }, +/turf/simulated/floor/tiled/white, +/area/security/forensics) "adj" = ( /turf/simulated/wall/rshull, /area/shuttle/excursion/general) @@ -2048,6 +2139,24 @@ /obj/machinery/door/firedoor/glass, /turf/simulated/floor, /area/maintenance/station/ai) +"ady" = ( +/obj/machinery/door/firedoor/glass, +/obj/machinery/door/blast/regular{ + density = 0; + dir = 4; + icon_state = "pdoor0"; + id = "security_lockdown"; + name = "Security Blast Doors"; + opacity = 0 + }, +/obj/machinery/door/airlock/glass_security{ + id_tag = "BrigFoyer"; + layer = 2.8; + name = "Security"; + req_one_access = list(38,63) + }, +/turf/simulated/floor/tiled, +/area/security/hallway) "adz" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -2063,6 +2172,30 @@ /obj/structure/catwalk, /turf/simulated/floor, /area/maintenance/station/sec_upper) +"adB" = ( +/turf/simulated/wall/r_wall, +/area/quartermaster/belterdock) +"adC" = ( +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; + icon_state = "space"; + layer = 4; + name = "EXTERNAL AIRLOCK"; + pixel_x = 0 + }, +/turf/simulated/wall/r_wall, +/area/quartermaster/belterdock) +"adD" = ( +/turf/simulated/wall/r_wall, +/area/quartermaster/belterdock/surface_mining_outpost_shuttle_hangar) +"adE" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_l" + }, +/turf/simulated/floor/tiled/asteroid_steel/airless, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/mining_outpost/shuttle) "adF" = ( /obj/effect/floor_decal/borderfloor{ dir = 8 @@ -2072,6 +2205,13 @@ }, /turf/simulated/floor/tiled/monotile, /area/tether/exploration) +"adG" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8 + }, +/turf/simulated/floor/tiled/asteroid_steel/airless, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/mining_outpost/shuttle) "adH" = ( /obj/machinery/light{ dir = 4 @@ -2083,6 +2223,14 @@ "adI" = ( /turf/simulated/wall/r_wall, /area/security/warden) +"adJ" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_r" + }, +/turf/simulated/floor/tiled/asteroid_steel/airless, +/turf/simulated/shuttle/plating/airless/carry, +/area/shuttle/mining_outpost/shuttle) "adM" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 1 @@ -2966,13 +3114,6 @@ /obj/structure/cable/green, /turf/simulated/floor/wood, /area/crew_quarters/heads/hos) -"afs" = ( -/obj/machinery/atmospherics/unary/engine{ - dir = 1 - }, -/turf/simulated/floor/reinforced, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/excursion/cargo) "aft" = ( /obj/effect/floor_decal/borderfloor, /obj/effect/floor_decal/corner/red/border, @@ -9405,62 +9546,6 @@ /obj/machinery/dnaforensics, /turf/simulated/floor/tiled/white, /area/security/forensics) -"aqz" = ( -/obj/effect/floor_decal/borderfloorwhite{ - dir = 9 - }, -/obj/effect/floor_decal/corner/red/border{ - dir = 9 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 10 - }, -/obj/effect/floor_decal/corner/red/bordercorner2{ - dir = 10 - }, -/obj/structure/cable/green{ - d2 = 2; - icon_state = "0-2" - }, -/obj/structure/closet{ - name = "Evidence Closet" - }, -/turf/simulated/floor/tiled/white, -/area/security/forensics) -"aqA" = ( -/obj/effect/floor_decal/borderfloorwhite{ - dir = 1 - }, -/obj/effect/floor_decal/corner/red/border{ - dir = 1 - }, -/obj/structure/closet{ - name = "Evidence Closet" - }, -/obj/item/device/radio/intercom{ - dir = 1; - pixel_y = 24; - req_access = list() - }, -/turf/simulated/floor/tiled/white, -/area/security/forensics) -"aqB" = ( -/obj/machinery/disposal, -/obj/effect/floor_decal/borderfloorwhite{ - dir = 5 - }, -/obj/effect/floor_decal/corner/red/border{ - dir = 5 - }, -/obj/effect/floor_decal/borderfloorwhite/corner2{ - dir = 5 - }, -/obj/effect/floor_decal/corner/red/bordercorner2{ - dir = 5 - }, -/obj/structure/disposalpipe/trunk, -/turf/simulated/floor/tiled/white, -/area/security/forensics) "aqC" = ( /obj/machinery/door/firedoor/glass, /obj/structure/grille, @@ -10877,9 +10962,6 @@ }, /turf/simulated/floor/tiled/white, /area/security/forensics) -"asN" = ( -/turf/simulated/floor/tiled/white, -/area/security/forensics) "asO" = ( /obj/machinery/door/window/eastright, /turf/simulated/floor/tiled/white, @@ -12103,31 +12185,6 @@ /obj/structure/window/reinforced/full, /turf/simulated/floor, /area/security/lobby) -"auR" = ( -/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" - }, -/obj/machinery/door/airlock/glass_security{ - name = "Front Desk"; - req_access = list(1) - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 4; - icon_state = "1-4" - }, -/obj/structure/cable/green{ - d1 = 1; - d2 = 8; - icon_state = "1-8" - }, -/obj/structure/disposalpipe/segment, -/turf/simulated/floor/tiled, -/area/security/lobby) "auS" = ( /obj/machinery/door/firedoor/glass, /obj/structure/cable/green{ @@ -23172,14 +23229,6 @@ }, /turf/simulated/floor/tiled/white, /area/medical/virology) -"aNf" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8; - icon_state = "propulsion_l" - }, -/turf/simulated/floor/tiled/asteroid_steel/airless, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/mining_outpost/shuttle) "aNg" = ( /obj/structure/bed/chair{ dir = 1 @@ -25903,14 +25952,6 @@ }, /turf/simulated/floor/tiled, /area/quartermaster/storage) -"aSz" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 1 - }, -/obj/effect/floor_decal/borderfloor, -/obj/effect/floor_decal/corner/red/border, -/turf/simulated/floor/tiled, -/area/security/hallway) "aSA" = ( /obj/machinery/door/airlock/maintenance/cargo{ name = "Belter Shuttle Access"; @@ -26204,16 +26245,6 @@ }, /turf/simulated/floor/tiled, /area/quartermaster/belterdock/gear) -"aTk" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; - icon_state = "space"; - layer = 4; - name = "EXTERNAL AIRLOCK"; - pixel_x = 0 - }, -/turf/simulated/wall, -/area/quartermaster/belterdock) "aTm" = ( /obj/machinery/airlock_sensor{ pixel_y = 28 @@ -26915,9 +26946,6 @@ /obj/effect/floor_decal/industrial/warning, /turf/simulated/floor/airless, /area/quartermaster/belterdock) -"aVc" = ( -/turf/simulated/wall, -/area/quartermaster/belterdock/surface_mining_outpost_shuttle_hangar) "aVe" = ( /obj/structure/cable/green{ d1 = 1; @@ -27856,13 +27884,6 @@ /obj/effect/floor_decal/corner/brown/border, /turf/simulated/floor/tiled, /area/quartermaster/belterdock/gear) -"aYo" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8 - }, -/turf/simulated/floor/tiled/asteroid_steel/airless, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/mining_outpost/shuttle) "aYp" = ( /turf/simulated/wall{ can_open = 0 @@ -27897,14 +27918,6 @@ }, /turf/simulated/floor/carpet, /area/crew_quarters/heads/hos) -"aYy" = ( -/obj/structure/shuttle/engine/propulsion{ - dir = 8; - icon_state = "propulsion_r" - }, -/turf/simulated/floor/tiled/asteroid_steel/airless, -/turf/simulated/shuttle/plating/airless/carry, -/area/shuttle/mining_outpost/shuttle) "aYz" = ( /obj/structure/window/reinforced, /obj/structure/grille, @@ -28413,14 +28426,6 @@ /obj/structure/window/reinforced, /turf/simulated/shuttle/floor/yellow/airless, /area/shuttle/belter) -"baw" = ( -/obj/structure/bed/chair/shuttle, -/obj/structure/shuttle/engine/heater{ - dir = 1 - }, -/obj/structure/window/reinforced, -/turf/simulated/shuttle/floor/yellow/airless, -/area/shuttle/belter) "bax" = ( /obj/structure/bed/chair/shuttle, /turf/simulated/shuttle/floor/yellow, @@ -37440,7 +37445,7 @@ amb aqy arg asc -asN +acZ agc aqc avs @@ -37719,9 +37724,9 @@ rlz rgV jxg aUn -acZ +abd amb -aqz +acm ari asd asP @@ -37861,9 +37866,9 @@ jnQ iUO xaA apa -aSz -amb -aqA +abl +ach +acZ arj ase asM @@ -38003,9 +38008,9 @@ amy aoa xmG aff -atT +abZ amb -aqB +adi ark asf asQ @@ -40282,7 +40287,7 @@ arv alw aqP atX -auR +aaM avF awk awP @@ -41134,7 +41139,7 @@ alE aaK ath auc -aaM +ady avK awp awn @@ -44098,7 +44103,7 @@ aUJ aXb aWp iJT -afs +aah ams aXq abe @@ -44240,7 +44245,7 @@ wRt eug aWp cQa -afs +aah ams aXq abe @@ -45376,7 +45381,7 @@ pPy efQ aWp cQa -afs +aah ams amq abe @@ -45518,7 +45523,7 @@ iEV tEV aWp rUl -afs +aah ams aQL abe @@ -45847,12 +45852,12 @@ aTa aTr aTE aQG -aQG -aQG -aQG -aQG -aQG -aQG +adB +adB +adB +adB +adB +adB aVa bap bap @@ -45994,7 +45999,7 @@ aUh aUr aTZ aUg -aQG +adB aVb baq aVo @@ -46420,10 +46425,10 @@ aTV aUF aOL apC -aQG +adB aVb baq -baw +bav baz baE aVG @@ -46556,13 +46561,13 @@ aSV aSV aWP aMN -aQG -aTk +adB +adC aTw -aQG -aQG -aQG -aQG +adB +adB +adB +adB bak baq aVo @@ -46698,11 +46703,11 @@ aSW aXY aWQ aYn -aQG +adB aTm aTx aTK -aQG +adB aVh bag bal @@ -46840,7 +46845,7 @@ aTg aUX aWQ amK -aQG +adB aTn aOO aTA @@ -46982,11 +46987,11 @@ aTg aVk aWU aYt -aQG -aQG -aQG -aQG -aQG +adB +adB +adB +adB +adB aUI aUI aWi @@ -47269,15 +47274,15 @@ aTM aMN avt avt -aVc -aVc +adD +adD aWc aWc aWc aWc aWc -aVc -aVc +adD +adD avt avt avt @@ -47411,7 +47416,7 @@ aZA aMN avt avt -aVc +adD aZJ baf baf @@ -47419,7 +47424,7 @@ baf baf baf baP -aVc +adD avt avt aaa @@ -47553,15 +47558,15 @@ aZB aMN avt avt -aVc +adD aZS -aNf -aYo -aYo -aYo -aYy +adE +adG +adG +adG +adJ baB -aVc +adD avt avt aaa @@ -47695,7 +47700,7 @@ aVx aMN avt avt -aVc +adD aZS bai bao @@ -47703,7 +47708,7 @@ bao bao bai baB -aVc +adD aaa aaa aaa @@ -47836,8 +47841,8 @@ aXm aVt aMD aMD -aVc -aVc +adD +adD baL bai bat @@ -47845,7 +47850,7 @@ bau baM bai baW -aVc +adD aaa aaa aaa @@ -47978,7 +47983,7 @@ aXn aWI aWf aYJ -aVc +adD aYZ aZS bai @@ -47987,7 +47992,7 @@ bau bau bai baB -aVc +adD aaa aaa aaa @@ -48129,7 +48134,7 @@ bau baN bai baB -aVc +adD aaa aaa aaa @@ -48262,7 +48267,7 @@ aXu aWI aYP aZf -aVc +adD aZZ ban bai @@ -48271,7 +48276,7 @@ bau baN bai baC -aVc +adD aaa aaa aaa @@ -48404,7 +48409,7 @@ aXz aYE aUe aZq -aVc +adD aYL baR bai @@ -48413,7 +48418,7 @@ bau baN bai baB -aVc +adD aaa aaa aaa @@ -48546,7 +48551,7 @@ aXA aYF aUe aZH -aVc +adD aZb bab bai @@ -48555,7 +48560,7 @@ baJ baA bai baB -aVc +adD aaa aaa aaa @@ -48688,7 +48693,7 @@ aXI aYI aYR aZI -aVc +adD aVz bab bai @@ -48697,7 +48702,7 @@ baK baD bai baW -aVc +adD aaa aaa aaa @@ -48830,7 +48835,7 @@ aXJ aUe aUe aZj -aVc +adD baa bad aVs @@ -48839,7 +48844,7 @@ baT bai aVs baB -aVc +adD aaa aaa aaa @@ -48972,7 +48977,7 @@ aXV aZh aWO aZC -aVc +adD aVJ bae bam @@ -48981,7 +48986,7 @@ bam bam bam baQ -aVc +adD aaa aaa aaa @@ -49107,23 +49112,23 @@ aaa aaa aaa baS -aMD -aMD -aMD -aMD -aMD -aMD -aMD -aVc -aVc -aVc +baS +baS +baS +baS +baS +baS +baS +adD +adD +adD aWc aWc aWc aWc aWc -aVc -aVc +adD +adD aaa aaa aaa diff --git a/maps/tether/tether-09-solars.dmm b/maps/tether/tether-09-solars.dmm index 167568a6d10..d5d2c5afde4 100644 --- a/maps/tether/tether-09-solars.dmm +++ b/maps/tether/tether-09-solars.dmm @@ -279,15 +279,18 @@ /area/tether/outpost/solars_shed) "aC" = ( /obj/effect/decal/cleanable/dirt, -/obj/item/stack/cable_coil/lime, -/obj/structure/table/standard, -/obj/structure/cable/yellow{ - d1 = 4; - d2 = 8; - icon_state = "4-8" +/obj/structure/cable/heavyduty{ + icon_state = "0-8" }, -/turf/simulated/floor/virgo3b_indoors, -/area/tether/outpost/solars_shed) +/obj/structure/cable/heavyduty{ + icon_state = "0-2" + }, +/obj/machinery/power/sensor{ + name = "Powernet Sensor - Solar Farm Output"; + name_tag = "Solar Farm Output" + }, +/turf/simulated/floor/virgo3b, +/area/tether/outpost/solars_outside) "aD" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable/yellow{ @@ -313,19 +316,20 @@ /area/tether/outpost/solars_shed) "aG" = ( /obj/effect/decal/cleanable/dirt, -/obj/structure/cable/heavyduty{ - icon_state = "2-8" - }, -/obj/structure/cable/heavyduty{ - icon_state = "2-4" +/obj/structure/table/standard, +/obj/structure/cable/yellow{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, +/obj/item/stack/cable_coil/yellow, /turf/simulated/floor/virgo3b_indoors, /area/tether/outpost/solars_shed) "aH" = ( -/obj/structure/grille, /obj/structure/cable/heavyduty{ icon_state = "4-8" }, +/obj/structure/grille, /turf/simulated/floor/virgo3b_indoors, /area/tether/outpost/solars_shed) "aI" = ( @@ -357,17 +361,10 @@ /turf/simulated/floor/virgo3b, /area/tether/outpost/solars_outside) "aK" = ( +/obj/structure/cable/heavyduty{ + icon_state = "1-2" + }, /obj/effect/decal/cleanable/dirt, -/obj/structure/cable/heavyduty{ - icon_state = "0-8" - }, -/obj/structure/cable/heavyduty{ - icon_state = "0-2" - }, -/obj/machinery/power/sensor{ - name = "Powernet Sensor - Solar Farm Output"; - name_tag = "Solar Farm Output" - }, /turf/simulated/floor/virgo3b, /area/tether/outpost/solars_outside) "aL" = ( @@ -381,32 +378,31 @@ /turf/simulated/floor/virgo3b_indoors, /area/tether/outpost/solars_shed) "aM" = ( -/obj/machinery/power/smes/buildable{ - charge = 0; - output_attempt = 0; - outputting = 0; - RCon_tag = "Solar Farm - SMES 1" +/obj/structure/cable/heavyduty{ + icon_state = "4-8" }, -/obj/structure/cable/heavyduty, -/turf/simulated/floor/virgo3b_indoors, -/area/tether/outpost/solars_shed) -"aN" = ( -/obj/machinery/power/smes/buildable{ - charge = 0; - output_attempt = 0; - outputting = 0; - RCon_tag = "Solar Farm - SMES 2" - }, -/obj/structure/cable/heavyduty, -/turf/simulated/floor/virgo3b_indoors, -/area/tether/outpost/solars_shed) -"aO" = ( +/obj/structure/railing, /obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/virgo3b, +/area/tether/outpost/solars_outside) +"aN" = ( +/obj/structure/cable/heavyduty{ + icon_state = "1-2" + }, +/obj/machinery/light/small{ + dir = 8; + pixel_x = 0 + }, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/floor/virgo3b, +/area/tether/outpost/solars_outside) +"aO" = ( /obj/machinery/power/smes/buildable{ charge = 0; + cur_coils = 3; output_attempt = 0; outputting = 0; - RCon_tag = "Solar Farm - SMES 3" + RCon_tag = "Power - Solar Array" }, /obj/structure/cable/heavyduty, /turf/simulated/floor/virgo3b_indoors, @@ -461,22 +457,6 @@ }, /turf/simulated/floor/virgo3b_indoors, /area/tether/outpost/solars_shed) -"aU" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/power/terminal{ - icon_state = "term"; - dir = 1 - }, -/obj/structure/cable/yellow{ - d2 = 8; - icon_state = "0-8" - }, -/obj/structure/cable/yellow{ - d2 = 4; - icon_state = "0-4" - }, -/turf/simulated/floor/virgo3b_indoors, -/area/tether/outpost/solars_shed) "aV" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/power/terminal{ @@ -503,12 +483,10 @@ /turf/simulated/floor/virgo3b, /area/tether/outpost/solars_outside) "aY" = ( -/obj/structure/cable/heavyduty{ - icon_state = "1-2" - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/virgo3b, -/area/tether/outpost/solars_outside) +/obj/effect/floor_decal/industrial/warning/dust, +/obj/effect/floor_decal/rust, +/turf/simulated/floor/tiled/steel_dirty/virgo3b, +/area/mine/explored) "aZ" = ( /obj/structure/railing, /obj/effect/decal/cleanable/dirt, @@ -549,17 +527,6 @@ /obj/machinery/door/airlock/multi_tile/metal/mait, /turf/simulated/floor/virgo3b_indoors, /area/tether/outpost/solars_shed) -"bd" = ( -/obj/structure/cable/heavyduty{ - icon_state = "1-2" - }, -/obj/machinery/light/small{ - dir = 8; - pixel_x = 0 - }, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/virgo3b, -/area/tether/outpost/solars_outside) "be" = ( /obj/effect/floor_decal/industrial/warning/dust{ dir = 8 @@ -665,14 +632,6 @@ /obj/effect/decal/cleanable/dirt, /turf/simulated/floor/virgo3b, /area/mine/explored) -"bq" = ( -/obj/structure/cable/heavyduty{ - icon_state = "4-8" - }, -/obj/structure/railing, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/floor/virgo3b, -/area/tether/outpost/solars_outside) "br" = ( /mob/living/simple_mob/animal/passive/gaslamp, /turf/simulated/floor/tiled/steel_dirty/virgo3b, @@ -19601,7 +19560,7 @@ ad ad ad au -aC +aG aE aT au @@ -20028,8 +19987,8 @@ ad ad au aF -aM -aU +aO +aV bP bm bl @@ -20169,9 +20128,9 @@ ad ad ad au -aG -aN -aU +aH +au +au bb bl bv @@ -20310,12 +20269,12 @@ ad ad ad ad -au -aG -aO -aV -au -bl +ad +aC +aK +aK +aN +bn bl ad ad @@ -20452,12 +20411,12 @@ ad ad ad ad -au -aH -au -au -au -al +ad +aW +aW +aW +aW +aM bl ad ad @@ -20595,12 +20554,12 @@ ad ad ad ad -aK -aY -aY -bd -bn -bl +ad +ad +ad +ad +bo +bj ad ad ad @@ -20737,12 +20696,12 @@ ad ad ad ad -aW -aW -aW -aW -bq -bv +ad +ad +ad +ad +bo +aY ad ad ad @@ -22212,7 +22171,7 @@ bF bF bF bF -bG +bF bF bF bF diff --git a/maps/tether/tether_areas.dm b/maps/tether/tether_areas.dm index 9c595e82e11..f25efef20c5 100644 --- a/maps/tether/tether_areas.dm +++ b/maps/tether/tether_areas.dm @@ -221,6 +221,12 @@ name = "\improper Bar Backroom" icon_state = "red" sound_env = SMALL_SOFTFLOOR +/area/tether/surfacebase/servicebackroom + name = "\improper Service Block Backroom" + icon_state = "red" +/area/tether/surfacebase/barbackmaintenance + name = "\improper Bar Back Maintenance" + icon_state = "red" /area/tether/surfacebase/public_garden_lg name = "\improper Public Garden Looking Glass" @@ -378,6 +384,23 @@ lightswitch = 0 icon_state = "library" +/area/tether/surfacebase/entertainment + name = "\improper Entertainment Auditorium" + icon_state = "library" + +/area/tether/surfacebase/entertainment/stage + name = "\improper Entertainment Stage" + icon_state = "library" + +/area/tether/surfacebase/entertainment/backstage + name = "\improper Entertainment Backstage" + icon_state = "library" + +/area/tether/surfacebase/botanystorage + name = "\improper Botany Storage" + icon_state = "library" + + /area/tether/surfacebase/security icon_state = "security" /area/tether/surfacebase/security/breakroom @@ -537,6 +560,15 @@ /area/rnd/breakroom/bathroom name = "\improper Research Bathroom" icon_state = "research" +/area/rnd/testingroom + name = "\improper Research Testing Room" + icon_state = "research" +/area/rnd/hardstorage + name = "\improper Research Hard Storage" + icon_state = "research" +/area/rnd/tankstorage + name = "\improper Research Tank Storage" + icon_state = "research" //TFF 28/8/19 - cleanup of areas placement /area/rnd/research/testingrange @@ -615,43 +647,43 @@ // Xenobiology Outpost Areas /area/rnd/outpost/xenobiology/outpost_north_airlock - name = "\improper Xenbiology Northern Airlock" + name = "\improper Xenobiology Northern Airlock" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_south_airlock - name = "\improper Xenbiology Southern Airlock" + name = "\improper Xenobiology Southern Airlock" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_hallway - name = "\improper Xenbiology Access Corridor" + name = "\improper Xenobiology Access Corridor" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_breakroom - name = "\improper Xenbiology Breakroom" + name = "\improper Xenobiology Breakroom" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_office - name = "\improper Xenbiology Main Office" + name = "\improper Xenobiology Main Office" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_autopsy - name = "\improper Xenbiology Alien Autopsy Room" + name = "\improper Xenobiology Alien Autopsy Room" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_decon - name = "\improper Xenbiology Decontamination and Showers" + name = "\improper Xenobiology Decontamination and Showers" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_first_aid - name = "\improper Xenbiology First Aid" + name = "\improper Xenobiology First Aid" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_slimepens - name = "\improper Xenbiology Slime and Xenos Containment" + name = "\improper Xenobiology Slime and Xenos Containment" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_main - name = "\improper Xenbiology Main Outpost" + name = "\improper Xenobiology Main Outpost" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_storage - name = "\improper Xenbiology Equipment Storage" + name = "\improper Xenobiology Equipment Storage" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_stairs - name = "\improper Xenbiology Stairwell" + name = "\improper Xenobiology Stairwell" icon_state = "research" /area/rnd/outpost/xenobiology/outpost_substation - name = "\improper Xenbiology SMES Substation" + name = "\improper Xenobiology SMES Substation" icon_state = "research" // Misc diff --git a/maps/tether/tether_phoronlock.dm b/maps/tether/tether_phoronlock.dm index 91182842855..3afc89ebce9 100644 --- a/maps/tether/tether_phoronlock.dm +++ b/maps/tether/tether_phoronlock.dm @@ -126,49 +126,18 @@ obj/machinery/airlock_sensor/phoron/airlock_exterior //Advanced airlock controller for when you want a more versatile airlock controller - useful for turning simple access control rooms into airlocks /obj/machinery/embedded_controller/radio/airlock/phoron name = "Phoron Lock Controller" + valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "secure") -/obj/machinery/embedded_controller/radio/airlock/phoron/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/data[0] - - data = list( +/obj/machinery/embedded_controller/radio/airlock/phoron/tgui_data(mob/user) + . = list( "chamber_pressure" = program.memory["chamber_sensor_pressure"], "chamber_phoron" = program.memory["chamber_sensor_phoron"], "exterior_status" = program.memory["exterior_status"], "interior_status" = program.memory["interior_status"], - "processing" = program.memory["processing"] + "processing" = program.memory["processing"], + "internalTemplateName" = "AirlockConsolePhoron", ) - ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "phoron_airlock_console.tmpl", name, 470, 290) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/embedded_controller/radio/airlock/phoron/Topic(href, href_list) - if((. = ..())) - return - - var/clean = 0 - switch(href_list["command"]) //anti-HTML-hacking checks - if("cycle_ext") - clean = 1 - if("cycle_int") - clean = 1 - if("force_ext") - clean = 1 - if("force_int") - clean = 1 - if("abort") - clean = 1 - if("secure") - clean = 1 - - if(clean) - program.receive_user_command(href_list["command"]) - - return 1 - // // PHORON LOCK CONTROLLER PROGRAM // diff --git a/maps/virgo/virgo-1.dmm b/maps/virgo/virgo-1.dmm index 4450499fde8..070412998bd 100644 --- a/maps/virgo/virgo-1.dmm +++ b/maps/virgo/virgo-1.dmm @@ -4249,7 +4249,7 @@ "bDK" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{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,/area/maintenance/central) "bDL" = (/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) "bDM" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"bDN" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/oven,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"bDN" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/appliance/cooker/oven,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bDO" = (/obj/effect/floor_decal/corner/lime{dir = 5},/obj/structure/closet/secure_closet/hydroponics,/turf/simulated/floor/tiled,/area/hydroponics) "bDP" = (/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) "bDQ" = (/obj/structure/closet/secure_closet/hydroponics,/obj/effect/floor_decal/corner/lime/full{dir = 8},/turf/simulated/floor/tiled,/area/hydroponics) @@ -4668,8 +4668,8 @@ "bLN" = (/obj/effect/floor_decal/corner/blue,/obj/structure/reagent_dispensers/water_cooler/full,/turf/simulated/floor/tiled,/area/bridge_hallway) "bLO" = (/turf/simulated/wall/r_wall,/area/crew_quarters/captain) "bLP" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = 28},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"bLQ" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/grill,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"bLR" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/fryer,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"bLQ" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/appliance/cooker/grill,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"bLR" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/appliance/cooker/fryer,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bLS" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{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/crew_quarters/kitchen) "bLT" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/closet/secure_closet/freezer/fridge,/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bLU" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/sink/kitchen{pixel_y = 28},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) @@ -4886,9 +4886,9 @@ "bPX" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bPY" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/table/marble,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bPZ" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/item/weapon/reagent_containers/food/snacks/mint,/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) -"bQa" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/cooker/candy,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"bQa" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/appliance/mixer/candy,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bQb" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) -"bQc" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/cereal,/obj/machinery/camera/network/civilian{c_tag = "CIV - Kitchen Starboard"; dir = 8},/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) +"bQc" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/appliance/mixer/cereal,/obj/machinery/camera/network/civilian{c_tag = "CIV - Kitchen Starboard"; dir = 8},/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen) "bQd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/crew_quarters/kitchen) "bQe" = (/obj/structure/flora/ausbushes/brflowers,/obj/structure/flora/ausbushes/ppflowers,/turf/simulated/floor/grass,/area/crew_quarters/kitchen) "bQf" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/hallway/primary/central_two) diff --git a/nano/README.md b/nano/README.md index 9858dcdff76..5a3f55425b8 100644 --- a/nano/README.md +++ b/nano/README.md @@ -137,17 +137,17 @@ stringbuilder-based UIs, and this needs little explanation. if(location.internal == src) location.internal = null location.internals.icon_state = "internal0" - usr << "You close the tank release valve." + to_chat(usr, "You close the tank release valve.") if(location.internals) location.internals.icon_state = "internal0" else if(location.wear_mask && (location.wear_mask.flags & MASKINTERNALS)) location.internal = src - usr << "You open \the [src] valve." + to_chat(usr, "You open \the [src] valve.") if(location.internals) location.internals.icon_state = "internal1" else - usr << "You need something to connect to \the [src]!" + to_chat(usr, "You need something to connect to \the [src]!") ``` ### Template (doT) diff --git a/nano/images/southern_cross_nanomap_z1.png b/nano/images/southern_cross_nanomap_z1.png new file mode 100644 index 00000000000..b3674302003 Binary files /dev/null and b/nano/images/southern_cross_nanomap_z1.png differ diff --git a/nano/images/southern_cross_nanomap_z10.png b/nano/images/southern_cross_nanomap_z10.png new file mode 100644 index 00000000000..b9645bb74b0 Binary files /dev/null and b/nano/images/southern_cross_nanomap_z10.png differ diff --git a/nano/images/southern_cross_nanomap_z2.png b/nano/images/southern_cross_nanomap_z2.png new file mode 100644 index 00000000000..1f4830a884e Binary files /dev/null and b/nano/images/southern_cross_nanomap_z2.png differ diff --git a/nano/images/southern_cross_nanomap_z3.png b/nano/images/southern_cross_nanomap_z3.png new file mode 100644 index 00000000000..6c9d9b5a615 Binary files /dev/null and b/nano/images/southern_cross_nanomap_z3.png differ diff --git a/nano/images/southern_cross_nanomap_z5.png b/nano/images/southern_cross_nanomap_z5.png new file mode 100644 index 00000000000..b89543e9de0 Binary files /dev/null and b/nano/images/southern_cross_nanomap_z5.png differ diff --git a/nano/images/southern_cross_nanomap_z6.png b/nano/images/southern_cross_nanomap_z6.png new file mode 100644 index 00000000000..b8fb0ebfc10 Binary files /dev/null and b/nano/images/southern_cross_nanomap_z6.png differ diff --git a/nano/images/tether_nanomap_z1.png b/nano/images/tether_nanomap_z1.png new file mode 100644 index 00000000000..c463bd04b76 Binary files /dev/null and b/nano/images/tether_nanomap_z1.png differ diff --git a/nano/images/tether_nanomap_z10.png b/nano/images/tether_nanomap_z10.png new file mode 100644 index 00000000000..c12164d92e1 Binary files /dev/null and b/nano/images/tether_nanomap_z10.png differ diff --git a/nano/images/tether_nanomap_z13.png b/nano/images/tether_nanomap_z13.png new file mode 100644 index 00000000000..6f87d9911fd Binary files /dev/null and b/nano/images/tether_nanomap_z13.png differ diff --git a/nano/images/tether_nanomap_z14.png b/nano/images/tether_nanomap_z14.png new file mode 100644 index 00000000000..84d106a5ac5 Binary files /dev/null and b/nano/images/tether_nanomap_z14.png differ diff --git a/nano/images/tether_nanomap_z2.png b/nano/images/tether_nanomap_z2.png new file mode 100644 index 00000000000..5ccd4618085 Binary files /dev/null and b/nano/images/tether_nanomap_z2.png differ diff --git a/nano/images/tether_nanomap_z3.png b/nano/images/tether_nanomap_z3.png new file mode 100644 index 00000000000..0761eed916c Binary files /dev/null and b/nano/images/tether_nanomap_z3.png differ diff --git a/nano/images/tether_nanomap_z4.png b/nano/images/tether_nanomap_z4.png new file mode 100644 index 00000000000..f6465c7c130 Binary files /dev/null and b/nano/images/tether_nanomap_z4.png differ diff --git a/nano/images/tether_nanomap_z5.png b/nano/images/tether_nanomap_z5.png new file mode 100644 index 00000000000..d8aece303d7 Binary files /dev/null and b/nano/images/tether_nanomap_z5.png differ diff --git a/nano/images/tether_nanomap_z6.png b/nano/images/tether_nanomap_z6.png new file mode 100644 index 00000000000..7fb5111527d Binary files /dev/null and b/nano/images/tether_nanomap_z6.png differ diff --git a/nano/images/tether_nanomap_z7.png b/nano/images/tether_nanomap_z7.png new file mode 100644 index 00000000000..7645d78d098 Binary files /dev/null and b/nano/images/tether_nanomap_z7.png differ diff --git a/nano/images/tether_nanomap_z8.png b/nano/images/tether_nanomap_z8.png new file mode 100644 index 00000000000..c973b2b7842 Binary files /dev/null and b/nano/images/tether_nanomap_z8.png differ diff --git a/nano/images/tether_nanomap_z9.png b/nano/images/tether_nanomap_z9.png new file mode 100644 index 00000000000..bff91820dd8 Binary files /dev/null and b/nano/images/tether_nanomap_z9.png differ diff --git a/nano/templates/adv_med.tmpl b/nano/templates/adv_med.tmpl deleted file mode 100644 index 2cd4d576c0c..00000000000 --- a/nano/templates/adv_med.tmpl +++ /dev/null @@ -1,290 +0,0 @@ - -{{if !data.occupied}} -

    No occupant detected.

    -{{else}} -

    Occupant Data:

    -
    -
    - Name: -
    -
    - {{:data.occupant.name}} -
    -
    -
    -
    - Health: -
    - {{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, (data.occupant.health >= 50) ? 'good' : (data.occupant.health >= 25) ? 'average' : 'bad')}} -
    - {{:helper.round(data.occupant.health / data.occupant.maxHealth)*100}}% -
    -
    -
    - 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:

    -
[thing]") + if(istype(thing, /obj/item/weapon/paper)) + LAZYADD(dat, "ReadWrite") + else if(istype(thing, /obj/item/weapon/photo)) + LAZYADD(dat, "Look") + LAZYADD(dat, "Remove
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{if data.occupant.humanPrey}} - - - - - {{/if}} - {{if data.occupant.livingPrey}} - - - - - {{/if}} - {{if data.occupant.objectPrey}} - - - - - {{/if}} - - -
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
Body Weight:{{:helper.round(data.occupant.weight)}} lbs, {{:helper.round( - data.occupant.weight/2.20463)}} kgs
Foreign Humanoids:{{:data.occupant.humanPrey}}
Foreign Creatures:{{:data.occupant.livingPrey}}
Foreign Objects:{{:data.occupant.objectPrey}}
- - {{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}}%
-

Blood Reagents

- {{if data.occupant.reagents}} - - {{for data.occupant.reagents}} - - - - - {{/for}} -
{{:value.name}}:{{:value.amount}}
- {{else}} -
No blood reagents detected.
- {{/if}} -

Stomach Reagents

- {{if data.occupant.ingested}} - - {{for data.occupant.ingested}} - - - - - {{/for}} -
{{:value.name}}:{{:value.amount}}
- {{else}} -
No stomach reagents detected.
- {{/if}} -

External Organs

-
- {{for data.occupant.extOrgan}} -
- {{if value.status.destroyed}} -
- {{:value.name}} - DESTROYED -
- {{else}} -
-
- {{:value.name}} -
-
-
- {{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 < 950}} - Acute Infection++ - {{else value.germ_level >= 950}} - Gangrene Detected - {{/if}} -
- {{/if}} - {{if value.status.dead}} -
-  Necrosis -
-
- Necrotic Tissue Present -
- {{/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 < 950}} - Acute Infection++ - {{else value.germ_level >= 950}} - Necrosis Detected - {{/if}} -
- {{/if}} -
-  Damage -
-
- {{:value.damage}} -
-
- {{/for}} -
-{{/if}} \ No newline at end of file diff --git a/nano/templates/advanced_airlock_console.tmpl b/nano/templates/advanced_airlock_console.tmpl deleted file mode 100644 index e60cf7c9327..00000000000 --- a/nano/templates/advanced_airlock_console.tmpl +++ /dev/null @@ -1,60 +0,0 @@ -
-
-
- External Pressure: -
-
- {{:helper.displayBar(data.external_pressure, 0, 200, (data.external_pressure < 80 || data.external_pressure > 120) ? 'bad' : (data.external_pressure < 95 || data.external_pressure > 110) ? 'average' : 'good')}} -
- {{:data.external_pressure}} kPa -
-
-
-
-
- Chamber Pressure: -
-
- {{:helper.displayBar(data.chamber_pressure, 0, 200, (data.chamber_pressure < 80 || data.chamber_pressure > 120) ? 'bad' : (data.chamber_pressure < 95 || data.chamber_pressure > 110) ? 'average' : 'good')}} -
- {{:data.chamber_pressure}} kPa -
-
-
-
-
- Internal Pressure: -
-
- {{:helper.displayBar(data.internal_pressure, 0, 200, (data.internal_pressure < 80 || data.internal_pressure > 120) ? 'bad' : (data.internal_pressure < 95 || data.internal_pressure > 110) ? 'average' : 'good')}} -
- {{:data.internal_pressure}} kPa -
-
-
-
-
-
-
- {{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, data.processing ? 'disabled' : null)}} - {{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, data.processing ? 'disabled' : null)}} -
-
- {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, data.processing ? 'yellowButton' : null)}} - {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, data.processing ? 'yellowButton' : null)}} -
-
-
-
-
- {{:helper.link('Purge', 'refresh', {'command' : 'purge'}, data.processing ? 'disabled' : null, data.purge ? 'linkOn' : null)}} -
-
- {{:helper.link('Secure', data.secure ? 'locked' : 'unlocked', {'command' : 'secure'}, data.processing ? 'disabled' : null, data.secure ? 'linkOn' : null)}} -
-
-
-
- {{:helper.link('Abort', 'cancel', {'command' : 'abort'}, data.processing ? null : 'disabled', data.processing ? 'redButton' : null)}} -
-
\ No newline at end of file diff --git a/nano/templates/aicard.tmpl b/nano/templates/aicard.tmpl deleted file mode 100644 index 40a192a1657..00000000000 --- a/nano/templates/aicard.tmpl +++ /dev/null @@ -1,103 +0,0 @@ - - - - -{{if data.has_ai}} -
-
- Hardware Integrity: -
-
- {{:data.hardware_integrity}}% -
-
- Backup Capacitor: -
-
- {{:data.backup_capacitor}}% -
-
- - {{if data.has_laws}} - - - -
- Laws: -
- {{for data.laws}} - - {{/for}} -
IndexLaw
{{:value.index}}.{{:value.law}}
- {{else}} - No laws found. - {{/if}} - - {{if data.operational}} - - - - - - - - - - - {{if data.flushing}} - - {{else}} - - - - - {{/if}} -
Radio Subspace Transceiver{{:helper.link("Enabled", null, {'radio' : 0}, data.radio ? 'selected' : null)}}{{:helper.link("Disabled", null, {'radio' : 1}, data.radio ? null : 'redButton' )}}
Wireless Interface{{:helper.link("Enabled", null, {'wireless' : 0}, data.wireless ? 'selected' : null)}}{{:helper.link("Disabled", null, {'wireless' : 1}, data.wireless ? null : 'redButton' )}}
AI shutdown in progress...
AI Power{{:helper.link("Shutdown", 'radiation', {'wipe' : 1}, null, 'redButton')}}
- {{/if}} -{{else}} - Stored AI: No AI detected. -{{/if}} diff --git a/nano/templates/air_alarm.tmpl b/nano/templates/air_alarm.tmpl deleted file mode 100644 index 5914d326464..00000000000 --- a/nano/templates/air_alarm.tmpl +++ /dev/null @@ -1,217 +0,0 @@ - -

Air Status

-{{if data.has_environment}} - {{for data.environment}} - {{:value.name}}: - {{if value.danger_level == 2}} - - {{else value.danger_level == 1}} - - {{else}} - - {{/if}} - {{:helper.fixed(value.value, 1)}} - {{:value.unit}}
- {{/for}} - Local Status: {{if data.total_danger == 2}} - DANGER: Internals Required - {{else data.total_danger == 1}} - Caution - {{else}} - Optimal - {{/if}} -
- Area Status: {{if data.atmos_alarm}}Atmosphere alert in area{{else data.fire_alarm}}Fire alarm in area{{else}}No alerts{{/if}} -{{else}} - Warning: Cannot obtain air sample for analysis. -{{/if}} -
- - - - - - - - - - - - - -
-
-

Remote Control

-
-

Thermostat

-
-
-
-
- {{:helper.link('Off', null, { 'rcon' : 1}, data.remote_connection && !data.remote_access ? (data.rcon == 1 ? 'yellowButton' : 'disabled') : null, data.rcon == 1 ? 'selected' : null)}} - {{:helper.link('Auto', null, { 'rcon' : 2}, data.remote_connection && !data.remote_access ? (data.rcon == 2 ? 'yellowButton' : 'disabled') : null, data.rcon == 2 ? 'selected' : null)}} - {{:helper.link('On', null, { 'rcon' : 3}, data.remote_connection && !data.remote_access ? (data.rcon == 3 ? 'yellowButton' : 'disabled') : null, data.rcon == 3 ? 'selected' : null)}} -
-
-
- {{:helper.link(data.target_temperature, null, { 'temperature' : 1})}} -
-
-{{if (data.locked && !data.remote_connection) || (data.remote_connection && ! data.remote_access)}} - {{if data.remote_connection}} - (Current remote control settings and alarm status restricts access.) - {{else}} - (Swipe ID card to unlock interface.) - {{/if}} -{{else}} - {{if data.screen != 1}} -
{{:helper.link('Main Menu', null, { 'screen' : 1})}}
- {{/if}} - {{if data.screen == 1}} -
- {{if data.atmos_alarm}} - {{:helper.link('Reset - Area Atmospheric Alarm', null, { 'atmos_reset' : 1})}} - {{else}} - {{:helper.link('Activate - Area Atmospheric Alarm', null, { 'atmos_alarm' : 1})}} - {{/if}} -
-
-
- {{:helper.link('Scrubbers Control', null, { 'screen' : 3})}} -
-
- {{:helper.link('Vents Control', null, { 'screen' : 2})}} -
-
- {{:helper.link('Set Environmental Mode', null, { 'screen' : 4})}} -
-
- {{:helper.link('Sensor Settings', null, { 'screen' : 5})}} -
-
- {{if data.mode==3}} - {{:helper.link('PANIC SIPHON ACTIVE - Turn siphoning off', null, { 'mode' : 1}, null, 'redButton')}} - {{else}} - {{:helper.link('ACTIVATE PANIC SIPHON IN AREA', null, { 'mode' : 3}, null, 'yellowButton')}} - {{/if}} - {{else data.screen == 2}} - {{for data.vents}} -
- {{:value.long_name}}
-
-
- Operating: -
-
- {{:helper.link(value.power ? 'On' : 'Off', null, { 'id_tag' : value.id_tag, 'command' : 'power', 'val' : value.power ? 0 : 1}, null, value.power ? null : 'redButton')}} -
-
-
-
- Operation Mode: -
-
- {{:helper.link(value.direction == "siphon" ? 'Siphoning' : 'Pressurizing', null, { 'id_tag' : value.id_tag, 'command' : 'direction', 'val' : value.direction == "siphon" ? 1 : 0}, null, value.direction == "siphon" ? 'redButton' : null)}} -
-
-
-
- Pressure Checks: -
-
- {{:helper.link('External', null, { 'id_tag' : value.id_tag, 'command' : 'checks', 'val' : value.checks^1}, null, value.checks&1 ? 'selected' : null)}} - {{:helper.link('Internal', null, { 'id_tag' : value.id_tag, 'command' : 'checks', 'val' : value.checks^2}, null, value.checks&2 ? 'selected' : null)}} -
-
-
-
- External Pressure Bound: -
-
- {{:helper.link(helper.fixed(value.external,2), null, { 'id_tag' : value.id_tag, 'command' : 'set_external_pressure'})}} - {{:helper.link('Reset', null, { 'id_tag' : value.id_tag, 'command' : 'reset_external_pressure'})}} -
-
-
- {{empty}} - No vents connected. - {{/for}} - {{else data.screen == 3}} - {{for data.scrubbers}} -
- {{:value.long_name}}
-
-
- Operating: -
-
- {{:helper.link(value.power ? 'On' : 'Off', null, { 'id_tag' : value.id_tag, 'command' : 'power', 'val' : value.power ? 0 : 1}, null, value.power ? null : 'redButton')}} -
-
-
-
- Operation Mode: -
-
- {{:helper.link(value.scrubbing ? 'Scrubbing' : 'Siphoning', null, { 'id_tag' : value.id_tag, 'command' : 'scrubbing', 'val' : value.scrubbing ? 0 : 1}, null, value.scrubbing ? null : 'redButton')}} -
-
-
-
- Filters: -
-
- {{for value.filters :filterValue:filterIndex}} - {{:helper.link(filterValue.name, null, { 'id_tag' : value.id_tag, 'command' : filterValue.command, 'val' : filterValue.val ? 0 : 1}, null, filterValue.val ? 'selected' : null)}} - {{/for}} -
-
-
- {{empty}} - No scrubbers connected. - {{/for}} - {{else data.screen == 4}} -

Environmental Modes

- {{for data.modes}} -
- {{:helper.link(value.name, null, { 'mode' : value.mode }, null, value.selected ? (value.danger ? 'redButton' : 'selected') : null)}} -
- {{/for}} - {{else data.screen == 5}} -

Alarm Threshold

- Partial pressure for gases. - - - - - {{for data.thresholds}} - - - {{for value.settings :settingsValue:settingsIndex}} - - {{/for}} - - {{/for}} -
min2min1max1max2
{{:value.name}} - {{:helper.link(settingsValue.selected >= 0 ? helper.fixed(settingsValue.selected, 2) : "Off", null, { 'command' : 'set_threshold', 'env' : settingsValue.env, 'var' : settingsValue.val })}} -
- {{/if}} -{{/if}} - \ No newline at end of file diff --git a/nano/templates/alarm_monitor.tmpl b/nano/templates/alarm_monitor.tmpl deleted file mode 100644 index 2591763fc04..00000000000 --- a/nano/templates/alarm_monitor.tmpl +++ /dev/null @@ -1,38 +0,0 @@ - - -{{for data.categories}} -

{{:value.category}}

- {{for value.alarms :alarmValue:alarmIndex}} - {{if alarmValue.origin_lost}} - {{:alarmValue.name}} Alarm Origin Lost
- {{else}} - {{:alarmValue.name}}
- {{/if}} - {{if alarmValue.has_cameras || alarmValue.lost_sources != ""}} -
- {{if alarmValue.has_cameras}} -
- {{for alarmValue.cameras :cameraValue:cameraIndex}} - {{if cameraValue.deact}} - {{:helper.link(cameraValue.name + " (deactivated)", '', {}, 'inactive')}} - {{else}} - {{:helper.link(cameraValue.name, '', {'switchTo' : cameraValue.camera})}} - {{/if}} - {{/for}} -
- {{/if}} - {{if alarmValue.lost_sources != ""}} -
-

Lost Alarm Sources: {{:alarmValue.lost_sources}}

-
- {{/if}} -
- {{/if}} - {{empty}} - --All Systems Nominal - {{/for}} -{{/for}} diff --git a/nano/templates/algae_farm_vr.tmpl b/nano/templates/algae_farm_vr.tmpl deleted file mode 100644 index be730d9d650..00000000000 --- a/nano/templates/algae_farm_vr.tmpl +++ /dev/null @@ -1,70 +0,0 @@ - -{{if data.errorText }} -
{{:data.errorText}}

-{{/if}} - -
-
- {{if data.usePower==2}} - {{:helper.link('Deactivate Processing', 'power', {'deactivate' : 1})}} - {{else}} - {{:helper.link('Activate Processing', 'power', {'activate' : 1})}} - {{/if}} -
-
-
Flow Rate
-
{{:helper.fixed(data.last_flow_rate)}} L/s
-
-
-
Power Draw
-
{{:helper.formatNumber(data.last_power_draw)}} Watts
-
-
- -

Materials

-
- {{for data.materials }} -
-
{{:value.display.toTitleCase()}}
-
{{:helper.displayBar(value.percent, 0, 100, - (value.percent < 25) ? 'bad' : (value.percent < 50) ? 'average' : 'good', - value.qty + "/" + value.max )}}
-
{{:helper.link("Eject", 'eject', {'ejectMaterial' : value.name })}}
-
- {{/for}} -
- -

Gas Input ({{:data.inputDir}})

-
- {{if data.input}} -
-
Total Pressure
-
{{:data.input.pressure}} kPa
-
-
-
{{:data.input.name}}
-
{{:helper.fixed(data.input.percent)}}% ({{:helper.fixed(data.input.moles)}} moles)
-
- {{else}} -
Not Connected
- {{/if}} -
- -

Gas Output ({{:data.outputDir}})

-
- {{if data.output}} -
-
Total Pressure
-
{{:data.output.pressure}} kPa
-
-
-
{{:data.output.name}}
-
{{:helper.fixed(data.output.percent)}}% ({{:helper.fixed(data.output.moles)}} moles)
-
- {{else}} -
Not Connected
- {{/if}} -
diff --git a/nano/templates/apc.tmpl b/nano/templates/apc.tmpl deleted file mode 100644 index a26abef4a06..00000000000 --- a/nano/templates/apc.tmpl +++ /dev/null @@ -1,229 +0,0 @@ -{{if data.gridCheck}} -
-

SYSTEM FAILURE

- Power surge detected, grid check in effect...
-
-{{else data.failTime}} -
-

SYSTEM FAILURE

- I/O regulators malfunction detected! Waiting for system reboot...
- Automatic reboot in {{:data.failTime}} seconds...
- {{if !data.siliconUser}} - {{if data.locked}} - Swipe an ID card for manual reboot.


- {{else}} - {{:helper.link('Reboot Now', 'refresh', {'reboot' : 1})}}


- {{/if}} - {{else}} - {{:helper.link('Reboot Now', 'refresh', {'reboot' : 1})}}


- {{/if}} -
-{{else}} -
- {{if data.siliconUser}} -
- Interface Lock: -
-
- {{:helper.link('Engaged', 'locked', {'toggleaccess' : 1}, data.locked ? 'selected' : null)}}{{:helper.link('Disengaged', 'unlocked', {'toggleaccess' : 1}, data.malfStatus >= 2 ? 'linkOff' : (data.locked ? null : 'selected'))}} -
-
- {{else}} - {{if data.emagged}} -

Fault in ID authenticator

- Please contact maintenance for service. - {{else data.locked}} - Swipe an ID card to unlock this interface - {{else}} - Swipe an ID card to lock this interface - {{/if}} - {{/if}} -
- -
- -

Power Status

- -
-
- Main Breaker: -
-
- {{if data.locked && !data.siliconUser}} - {{if data.isOperating}} - On - {{else}} - Off - {{/if}} - {{else}} - {{:helper.link('On', 'power', {'breaker' : 1}, data.isOperating ? 'selected' : null)}}{{:helper.link('Off', 'close', {'breaker' : 1}, data.isOperating ? null : 'selected')}} - {{/if}} -
-
- -
-
- External Power: -
-
- {{if data.externalPower == 2}} - Good - {{else data.externalPower == 1}} - Low - {{else}} - None - {{/if}} -
-
- -
-
- Power Cell: -
- {{if data.powerCellStatus == null}} -
- Power cell removed. -
- {{else}} - - {{:helper.displayBar(data.powerCellStatus, 0, 100, (data.powerCellStatus >= 50) ? 'good' : (data.powerCellStatus >= 25) ? 'average' : 'bad')}} -
- {{:helper.round(data.powerCellStatus*10)/10}}% -
- {{/if}} -
- - {{if data.powerCellStatus != null}} -
-
- Charge Mode: -
-
- {{if data.locked && !data.siliconUser}} - {{if data.chargeMode}} - Auto - {{else}} - Off - {{/if}} - {{else}} - {{:helper.link('Auto', 'refresh', {'cmode' : 1}, data.chargeMode ? 'selected' : null)}}{{:helper.link('Off', 'close', {'cmode' : 1}, data.chargeMode ? null : 'selected')}} - {{/if}} -   - {{if data.chargingStatus > 1}} - [Fully Charged] - {{else data.chargingStatus == 1}} - [Charging] - {{else}} - [Not Charging] - {{/if}} -
-
- {{/if}} - - -

Power Channels

- - {{for data.powerChannels}} -
-
- {{:value.title}}: -
-
- {{:value.powerLoad}} W -
-
-    - {{if value.status <= 1}} - Off - {{else value.status >= 2}} - On - {{/if}} - {{if data.locked}} - {{if value.status == 1 || value.status == 3}} -   Auto - {{else}} -   Manual - {{/if}} - {{/if}} -
- {{if !data.locked || data.siliconUser}} -
- {{:helper.link('Auto', 'refresh', value.topicParams.auto, (value.status == 1 || value.status == 3) ? 'selected' : null)}} - {{:helper.link('On', 'power', value.topicParams.on, (value.status == 2) ? 'selected' : null)}} - {{:helper.link('Off', 'close', value.topicParams.off, (value.status == 0) ? 'selected' : null)}} -
- {{/if}} -
- {{/for}} - -
-
- Total Load: -
-
- {{if data.totalCharging}} - {{:data.totalLoad}}W (+ {{:data.totalCharging}}W Charging) - {{else}} - {{:data.totalLoad}}W - {{/if}} -
-
- -
 
- -
-
- Cover Lock: -
-
- {{if data.locked && !data.siliconUser}} - {{if data.coverLocked}} - Engaged - {{else}} - Disengaged - {{/if}} - {{else}} - {{:helper.link('Engaged', 'locked', {'lock' : 1}, data.coverLocked ? 'selected' : null)}}{{:helper.link('Disengaged', 'unlocked', {'lock' : 1}, data.coverLocked ? null : 'selected')}} - {{/if}} -
-
- -
-
- Emergency Lighting: -
-
- {{if data.locked && !data.siliconUser}} - {{:data.emergencyLights ? "Enabled" : "Disabled"}} - {{else}} - {{:helper.link(data.emergencyLights ? 'Enabled' : 'Disabled', data.emergencyLights ? 'power' : 'close', {'emergency_lighting' : 1}, null)}} - {{/if}} -
-
- -
-
- Night Lighting: -
-
- {{:helper.link('Disabled', null, {'nightshift' : 2}, data.nightshiftSetting == 2 ? 'selected' : null)}} - {{:helper.link('Automatic', null, {'nightshift' : 1}, data.nightshiftSetting == 1 ? 'selected' : null)}} - {{:helper.link('Enabled', null, {'nightshift' : 3}, data.nightshiftSetting == 3 ? 'selected' : null)}} -
-
- - {{if data.siliconUser}} -

System Overrides

- -
- {{:helper.link('Overload Lighting Circuit', 'lightbulb', {'overload' : 1})}} - {{if data.malfStatus == 1}} - {{:helper.link('Override Programming', 'script', {'malfhack' : 1})}} - {{else data.malfStatus > 1}} -
APC Hacked
- {{/if}} -
- {{/if}} - -
-{{/if}} \ No newline at end of file diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl deleted file mode 100644 index 1111add5c53..00000000000 --- a/nano/templates/appearance_changer.tmpl +++ /dev/null @@ -1,86 +0,0 @@ -{{if data.change_race}} -
-
- Species: -
-
- {{for data.species}} - {{:helper.link(value.specimen, null, { 'race' : value.specimen}, null, data.specimen == value.specimen ? 'selected' : null)}} - {{/for}} -
-
-{{/if}} - -{{if data.change_gender}} -
-
- Biological Gender: -
-
- {{for data.genders}} - {{:helper.link(value.gender_name, null, { 'gender' : value.gender_key}, null, data.gender == value.gender_key ? 'selected' : null)}} - {{/for}} -
- -
-
- Gender Identity: -
-
- {{for data.id_genders}} - {{:helper.link(value.gender_name, null, { 'gender_id' : value.gender_key}, null, data.gender_id == value.gender_key ? 'selected' : null)}} - {{/for}} -
-
-{{/if}} - -{{if data.change_eye_color || data.change_skin_tone || data.change_skin_color || data.change_hair_color || data.change_facial_hair_color}} -
-
- Colors: -
-
- {{if data.change_eye_color}} - {{:helper.link('Change eye color', null, { 'eye_color' : 1})}} - {{/if}} - {{if data.change_skin_tone}} - {{:helper.link('Change skin tone', null, { 'skin_tone' : 1})}} - {{/if}} - {{if data.change_skin_color}} - {{:helper.link('Change skin color', null, { 'skin_color' : 1})}} - {{/if}} - {{if data.change_hair_color}} - {{:helper.link('Change hair color', null, { 'hair_color' : 1})}} - {{/if}} - {{if data.change_facial_hair_color}} - {{:helper.link('Change facial hair color', null, { 'facial_hair_color' : 1})}} - {{/if}} -
-
-{{/if}} - -{{if data.change_hair}} -
-
- Hair styles: -
-
- {{for data.hair_styles}} - {{:helper.link(value.hairstyle, null, { 'hair' : value.hairstyle}, null, data.hair_style == value.hairstyle ? 'selected' : null)}} - {{/for}} -
-
-{{/if}} - -{{if data.change_facial_hair}} -
-
- Facial hair styles: -
-
- {{for data.facial_hair_styles}} - {{:helper.link(value.facialhairstyle, null, { 'facial_hair' : value.facialhairstyle}, null, data.facial_hair_style == value.facialhairstyle ? 'selected' : null)}} - {{/for}} -
-
-{{/if}} diff --git a/nano/templates/atmo_control.tmpl b/nano/templates/atmo_control.tmpl deleted file mode 100644 index d3c61758e72..00000000000 --- a/nano/templates/atmo_control.tmpl +++ /dev/null @@ -1,224 +0,0 @@ - -{{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}} K
-
- {{/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}} diff --git a/nano/templates/atmos_alert.tmpl b/nano/templates/atmos_alert.tmpl deleted file mode 100644 index 92946e8d312..00000000000 --- a/nano/templates/atmos_alert.tmpl +++ /dev/null @@ -1,18 +0,0 @@ -

Priority Alerts

-{{for data.priority_alarms}} -
- {{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}} -
-{{empty}} - No priority alerts detected. -{{/for}} - -

Minor Alerts

-{{for data.minor_alarms}} -
- {{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}} -
-{{empty}} - No minor alerts detected. -{{/for}} - diff --git a/nano/templates/atmos_control.tmpl b/nano/templates/atmos_control.tmpl deleted file mode 100644 index ac50e3fbdfd..00000000000 --- a/nano/templates/atmos_control.tmpl +++ /dev/null @@ -1,10 +0,0 @@ -{{if data.map_levels.length}} -
- {{:helper.link('Show Air Alarms On Map', 'pin-s', {'showMap' : 1})}} -
-{{/if}} -
- {{for data.alarms}} - {{:helper.link(value.name, null, {'alarm' : value.ref}, null, value.danger == 2 ? 'redButton' : (value.danger == 1 ? 'yellowButton' : null))}} - {{/for}} -
diff --git a/nano/templates/atmos_control_map_content.tmpl b/nano/templates/atmos_control_map_content.tmpl deleted file mode 100644 index 931ddb974ce..00000000000 --- a/nano/templates/atmos_control_map_content.tmpl +++ /dev/null @@ -1,13 +0,0 @@ - -{{for data.alarms}} - {{if value.z == config.mapZLevel}} -
- -
- {{/if}} -{{/for}} diff --git a/nano/templates/atmos_control_map_header.tmpl b/nano/templates/atmos_control_map_header.tmpl deleted file mode 100644 index 7fea71a965f..00000000000 --- a/nano/templates/atmos_control_map_header.tmpl +++ /dev/null @@ -1,20 +0,0 @@ - -{{:helper.link('Show List', 'script', {'showMap' : 0})}} -{{if data.map_levels.length > 1}} -
- Z Level:  - {{for data.map_levels }} - {{:helper.link(value, null, {'mapZLevel' : value}, null, config.mapZLevel == value ? 'selected' : null)}} - {{/for}} -
-{{/if}} -
- Zoom Level:  - - - - -
diff --git a/nano/templates/body_designer.tmpl b/nano/templates/body_designer.tmpl deleted file mode 100644 index 43b23af8f46..00000000000 --- a/nano/templates/body_designer.tmpl +++ /dev/null @@ -1,129 +0,0 @@ - -{{:data.temp}} - -{{if data.disk}} - {{:helper.link('Save To Disk', 'disk', {'savetodisk' : 1}, data.activeBodyRecord ? null : 'linkOff')}} - {{:helper.link('Load From Disk', 'folder-open', {'loadfromdisk' : 1}, data.diskStored ? null : 'linkOff')}} - {{:helper.link('Eject Disk', 'eject', {'ejectdisk' : 1})}} -{{/if}} - - - - -{{if data.menu == 1}} - -

Database Functions

-
- {{:helper.link('View Individual Body Records', 'list', {'menu' : 2})}} -
-
- {{:helper.link('View Stock Body Records', 'list', {'menu' : 3})}} -
- - -{{else data.menu == 2}} -

Current body records

- {{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 1})}} -
- {{for data.bodyrecords}} - {{:helper.link(value.name, 'document', {'view_brec' : value.recref})}} - {{/for}} -
- - -{{else data.menu == 3}} -

Stock body records

- {{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 1})}} -
- {{for data.stock_bodyrecords}} - {{:helper.link(value, 'document', {'view_stock_brec' : value})}} - {{/for}} -
- - -{{else data.menu == 4}} -

Selected Body Record

-
{{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 1})}}
- - {{if data.activeBodyRecord}} -
-
Name:
-
{{:data.activeBodyRecord.real_name}}
-
-
-
Species:
-
{{:data.activeBodyRecord.speciesname}}
-
-
-
Bio. Sex:
-
{{:helper.link(data.activeBodyRecord.gender, null, {'bio_gender' : 1})}}
-
-
-
Synthetic:
-
{{:data.activeBodyRecord.synthetic}}
-
-
-
Mind compat.:
-
{{:data.activeBodyRecord.locked}}
-
{{:helper.link('View OOC Notes', null, {'boocnotes' : 1}, data.activeBodyRecord.booc ? null : 'linkOff')}}
-
- -
-
- -
-
-
-
Scale:
-
{{:helper.link(data.activeBodyRecord.scale, null, {'size_multiplier' : 1})}}
-
- - {{props data.activeBodyRecord.styles}} -
-
{{:key}}:
-
- {{if value.styleHref}} - - {{:helper.link(value.style, null, (a={},a[value.styleHref]=1,a))}} - {{/if}} - {{if value.colorHref}} - {{:helper.link(value.color, null, (a={},a[value.colorHref]=1,a))}} -
 
- {{/if}} -
-
- {{/props}} - -
-
-
Body Markings
-
- {{:helper.link('Add Marking', 'plus', {'marking_style' : 1})}} -
-
- {{props data.activeBodyRecord.markings}} -
- {{:key}}  - - {{:helper.link('', 'minus', {'marking_remove' : key})}} -
- {{props}} -
- {{else}} -
ERROR: Record not found.
- {{/if}} - - -{{else data.menu == 6}} -

Body OOC Notes (This is OOC!)

-
{{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 4})}}
- {{if data.activeBodyRecord}} -
Notes:
-
{{:data.activeBodyRecord.booc}}
- {{else}} -
ERROR: Record not found.
- {{/if}} - -{{/if}} -
{{:JSON.stringify(data, null, 2)}}
diff --git a/nano/templates/canister.tmpl b/nano/templates/canister.tmpl deleted file mode 100644 index e4033eb0164..00000000000 --- a/nano/templates/canister.tmpl +++ /dev/null @@ -1,83 +0,0 @@ -

Tank Status

-
-
- Tank Label: -
-
-
{{:data.name}}
{{:helper.link('Relabel', 'pencil', {'relabel' : 1}, data.canLabel ? null : 'disabled')}} -
-
- -
-
- Tank Pressure: -
-
- {{:data.tankPressure}} kPa -
-
- -
-
- Port Status: -
-
- {{:data.portConnected ? 'Connected' : 'Disconnected'}} -
-
- -

Holding Tank Status

-{{if data.hasHoldingTank}} -
-
- Tank Label: -
-
-
{{:data.holdingTank.name}}
{{:helper.link('Eject', 'eject', {'remove_tank' : 1})}} -
-
- -
-
- Tank Pressure: -
-
- {{:data.holdingTank.tankPressure}} kPa -
-
-{{else}} -
No holding tank inserted.
-
 
-{{/if}} - - -

Release Valve Status

-
-
- Release Pressure: -
-
- {{:helper.displayBar(data.releasePressure, data.minReleasePressure, data.maxReleasePressure)}} -
- {{:helper.link('-', null, {'pressure_adj' : -1000}, (data.releasePressure > data.minReleasePressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -100}, (data.releasePressure > data.minReleasePressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -10}, (data.releasePressure > data.minReleasePressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -1}, (data.releasePressure > data.minReleasePressure) ? null : 'disabled')}} -
 {{:data.releasePressure}} kPa 
- {{:helper.link('+', null, {'pressure_adj' : 1}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 10}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 100}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 1000}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}} -
-
-
- -
-
- Release Valve: -
-
- {{:helper.link('Open', 'unlocked', {'toggle' : 1}, data.valveOpen ? 'selected' : null)}}{{:helper.link('Close', 'locked', {'toggle' : 1}, data.valveOpen ? null : 'selected')}} -
-
- diff --git a/nano/templates/chem_disp.tmpl b/nano/templates/chem_disp.tmpl deleted file mode 100644 index eaacb6a1dd5..00000000000 --- a/nano/templates/chem_disp.tmpl +++ /dev/null @@ -1,76 +0,0 @@ - -
-
- Dispense: -
-
- {{:helper.link('5', 'gear', {'amount' : 5}, (data.amount == 5) ? 'selected' : null)}} - {{:helper.link('10', 'gear', {'amount' : 10}, (data.amount == 10) ? 'selected' : null)}} - {{:helper.link('20', 'gear', {'amount' : 20}, (data.amount == 20) ? 'selected' : null)}} - {{:helper.link('30', 'gear', {'amount' : 30}, (data.amount == 30) ? 'selected' : null)}} - {{:helper.link('40', 'gear', {'amount' : 40}, (data.amount == 40) ? 'selected' : null)}} -

- {{:helper.link('--', '', {'amount' : data.amount-10})}} - {{:helper.link('-', '', {'amount' : data.amount-1})}} -
{{:data.amount}}
- {{:helper.link('+', '', {'amount' : data.amount+1})}} - {{:helper.link('++', '', {'amount' : data.amount+10})}} -
-
-
 
-
-
- {{if data.chemicals.length}} - {{for data.chemicals}} - {{:helper.link(value.label + " ("+value.amount+")", 'circle-arrow-s', {"dispense":value.label}, null, 'fixedLeftWide')}} - {{/for}} - {{else}} - No cartridges installed! - {{/if}} -
-
-
 
-
-
- {{if data.glass}} - Glass - {{else}} - Beaker - {{/if}} Contents -
-
- {{:helper.link(data.glass ? 'Eject Glass' : 'Eject Beaker', 'eject', {'ejectBeaker' : 1}, data.isBeakerLoaded ? null : 'disabled', 'floatRight')}} -
-
-
-
-
- {{if data.isBeakerLoaded}} - Volume: {{:data.beakerCurrentVolume}} / {{:data.beakerMaxVolume}}
- {{for data.beakerContents}} - {{:value.volume}} units of {{:value.name}}
- {{empty}} - - {{if data.glass}} - Glass - {{else}} - Beaker - {{/if}} is empty - - {{/for}} - {{else}} - - No - {{if data.glass}} - Glass - {{else}} - Beaker - {{/if}} loaded - - {{/if}} -
-
-
diff --git a/nano/templates/chem_master.tmpl b/nano/templates/chem_master.tmpl deleted file mode 100644 index f1b981ba6ec..00000000000 --- a/nano/templates/chem_master.tmpl +++ /dev/null @@ -1,123 +0,0 @@ - -{{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('Create patch (60 units max)', null, {'createpatch' : 1})}} -
-
- {{:helper.link('', 'pill pill' + data.pillSprite, {'tab_select' : 'pill'}, null, 'link32')}} - {{:helper.link('', 'pill bottle' + data.bottleSprite, {'tab_select' : 'bottle'}, null, 'link32')}} -
- {{else}} -
-
- {{:helper.link('Create bottle (50 units max)', null, {'createbottle' : 1})}} - {{:helper.link('Create bouillon cube (60 units max)', null, {'createpill' : 1})}} -
- {{/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 deleted file mode 100644 index a927fcc4d9c..00000000000 --- a/nano/templates/cloning.tmpl +++ /dev/null @@ -1,104 +0,0 @@ - - -{{: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/crew_monitor.tmpl b/nano/templates/crew_monitor.tmpl deleted file mode 100644 index 2dbc65d36d7..00000000000 --- a/nano/templates/crew_monitor.tmpl +++ /dev/null @@ -1,32 +0,0 @@ - - - -{{if data.map_levels.length}} - {{:helper.link('Show Tracker Map', 'pin-s', {'showMap' : 1})}} -{{/if}} -
- {{for data.crewmembers}} - {{if value.sensor_type == 1}} - {{if data.isAI}}{{/if}} - {{else value.sensor_type == 2}} - {{if data.isAI}}{{/if}} - {{else value.sensor_type == 3}} - {{if data.isAI}}{{/if}} - {{/if}} - {{/for}} -
{{:value.name}} ({{:value.assignment}}){{:value.dead ? "Deceased" : "Living"}}Not Available{{:helper.link('Track', null, {}, 'disabled')}}
{{:value.name}} ({{:value.assignment}}){{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}})Not Available{{:helper.link('Track', null, {}, 'disabled')}}
{{:value.name}} ({{:value.assignment}}){{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}}){{:value.area}}({{:value.x}}, {{:value.y}}, {{:value.z}}){{:helper.link('Track', null, {'track' : value.ref})}}
diff --git a/nano/templates/crew_monitor_map_content.tmpl b/nano/templates/crew_monitor_map_content.tmpl deleted file mode 100644 index 432649926c2..00000000000 --- a/nano/templates/crew_monitor_map_content.tmpl +++ /dev/null @@ -1,13 +0,0 @@ - -{{for data.crewmembers}} - {{if value.sensor_type == 3 && value.z == config.mapZLevel}} -
- -
- {{/if}} -{{/for}} diff --git a/nano/templates/crew_monitor_map_header.tmpl b/nano/templates/crew_monitor_map_header.tmpl deleted file mode 100644 index 2ec94854918..00000000000 --- a/nano/templates/crew_monitor_map_header.tmpl +++ /dev/null @@ -1,20 +0,0 @@ - -{{:helper.link('Show Detail List', 'script', {'showMap' : 0})}} -{{if data.map_levels.length > 1}} -
- Z Level:  - {{for data.map_levels }} - {{:helper.link(value, null, {'mapZLevel' : value}, null, config.mapZLevel == value ? 'selected' : null)}} - {{/for}} -
-{{/if}} -
- Zoom Level:  - - - - -
\ No newline at end of file diff --git a/nano/templates/cryo.tmpl b/nano/templates/cryo.tmpl deleted file mode 100644 index e8302b07df9..00000000000 --- a/nano/templates/cryo.tmpl +++ /dev/null @@ -1,98 +0,0 @@ - -

Cryo Cell Status

- -
- {{if !data.hasOccupant}} -
Cell Unoccupied
- {{else}} -
- {{:data.occupant.name}} =>  - {{if data.occupant.stat == 0}} - Conscious - {{else data.occupant.stat == 1}} - Unconscious - {{else}} - DEAD - {{/if}} -
- - {{if data.occupant.stat < 2}} -
-
Health:
- {{if data.occupant.health >= 0}} - {{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, 'good')}} - {{else}} - {{:helper.displayBar(data.occupant.health, 0, data.occupant.minHealth, 'average alignRight')}} - {{/if}} -
{{:helper.round(data.occupant.health)}}
-
- -
-
=> Brute Damage:
- {{:helper.displayBar(data.occupant.bruteLoss, 0, data.occupant.maxHealth, 'bad')}} -
{{:helper.round(data.occupant.bruteLoss)}}
-
- -
-
=> Resp. Damage:
- {{:helper.displayBar(data.occupant.oxyLoss, 0, data.occupant.maxHealth, 'bad')}} -
{{:helper.round(data.occupant.oxyLoss)}}
-
- -
-
=> Toxin Damage:
- {{:helper.displayBar(data.occupant.toxLoss, 0, data.occupant.maxHealth, 'bad')}} -
{{:helper.round(data.occupant.toxLoss)}}
-
- -
-
=> Burn Severity:
- {{:helper.displayBar(data.occupant.fireLoss, 0, data.occupant.maxHealth, 'bad')}} -
{{:helper.round(data.occupant.fireLoss)}}
-
- {{/if}} - {{/if}} -
-
-
Cell Temperature:
- {{:data.cellTemperature}} K -
-
-
- -

Cryo Cell Operation

-
-
- Cryo Cell Status: -
-
- {{:helper.link('On', 'power', {'switchOn' : 1}, data.isOperating ? 'selected' : null)}}{{:helper.link('Off', 'close', {'switchOff' : 1}, data.isOperating ? null : 'selected')}} -
-
- {{:helper.link('Eject Occupant', 'arrowreturnthick-1-s', {'ejectOccupant' : 1}, data.hasOccupant ? null : 'disabled')}} -
-
-
 
-
-
- Beaker: -
-
- {{if data.isBeakerLoaded}} - {{:data.beakerLabel ? data.beakerLabel : 'No label'}}
- {{if data.beakerVolume}} - {{:data.beakerVolume}} units remaining
- {{else}} - Beaker is empty - {{/if}} - {{else}} - No beaker loaded - {{/if}} -
-
- {{:helper.link('Eject Beaker', 'eject', {'ejectBeaker' : 1}, data.isBeakerLoaded ? null : 'disabled')}} -
-
\ No newline at end of file diff --git a/nano/templates/disease_splicer.tmpl b/nano/templates/disease_splicer.tmpl deleted file mode 100644 index d2e874afe67..00000000000 --- a/nano/templates/disease_splicer.tmpl +++ /dev/null @@ -1,125 +0,0 @@ -
-
- {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}} -
-
- -{{if data.busy}} -
The Splicer is currently busy.
-
-
{{:data.busy}}
-
-

- Thank you for your patience! -

-{{else}} -
-

Virus Dish

-
-
- {{:helper.link('Eject Dish', 'eject', { 'eject' : 1 }, data.dish_inserted ? null : 'disabled')}} -
- -
-
- Growth Density: -
-
- {{:helper.displayBar(data.growth, 0, 100, (data.growth >= 50) ? 'good' : data.growth >= 25 ? 'average' : 'bad', data.growth + '%' )}} -
-
- -
-
- {{if !data.info}} -
- Symptoms: -
- {{/if}} -
- {{if data.info}} - {{:data.info}} - {{else}} - {{for data.effects}} -
-
- ({{:value.stage}}) {{:value.name}} - {{if value.badness > 1}} - Dangerous - {{/if}} -
-
- {{/for}} - {{/if}} -
-
- {{if data.affected_species && !data.info}} -
-
- Affected Species: -
-
- {{:data.affected_species}} -
-
- {{/if}} -
- {{if data.effects}} -
- CAUTION: Reverse engineering will destroy the viral sample. -
-
-
- Reverse Engineering: -
-
- {{for data.effects}} - {{:helper.link(value.stage, 'transferthick-e-w', { 'grab' : value.reference })}} - {{/for}} -
-
- {{:helper.link('Species', 'transferthick-e-w', { 'affected_species' : 1 })}} -
-
- {{/if}} - -
-

Storage

-
- -
-
- Memory Buffer: -
-
- {{if data.buffer}} - {{:data.buffer.name}} ({{:data.buffer.stage}}) - {{else}} - {{if data.species_buffer}} - {{:data.species_buffer}} - {{else}} - Empty - {{/if}} - {{/if}} -
-
- {{:helper.link('Save To Disk', 'disk', { 'disk' : 1 }, (data.buffer || data.species_buffer) ? null : 'disabled')}} - {{if data.species_buffer}} - {{:helper.link('Splice Species', 'pencil', { 'splice' : 5 }, (data.species_buffer && !data.info) ? null : 'disabled')}} - {{else data.buffer}} - {{:helper.link('Splice #1', 'pencil', { 'splice' : 1 }, data.buffer.stage > 1 ? 'disabled' : null)}} - {{:helper.link('Splice #2', 'pencil', { 'splice' : 2 }, data.buffer.stage > 2 ? 'disabled' : null)}} - {{:helper.link('Splice #3', 'pencil', { 'splice' : 3 }, data.buffer.stage > 3 ? 'disabled' : null)}} - {{:helper.link('Splice #4', 'pencil', { 'splice' : 4 }, data.buffer.stage > 4 ? 'disabled' : null)}} - {{/if}} -{{/if}} - - - - - - - - - - diff --git a/nano/templates/dish_incubator.tmpl b/nano/templates/dish_incubator.tmpl deleted file mode 100644 index ae887e6986e..00000000000 --- a/nano/templates/dish_incubator.tmpl +++ /dev/null @@ -1,123 +0,0 @@ -
-
- {{:helper.link('Close', 'gear', {'close' : '1'}, null, 'fixedLeft')}} -
-
- -
-

Environmental Conditions

-
-
-
- Power: -
-
- {{:helper.link('On', 'power', { 'power' : 1 }, !data.dish_inserted ? 'disabled' : data.on ? 'selected' : null)}}{{:helper.link('Off', 'close', { 'power' : 1 }, data.on ? null : 'selected')}} -
-
-
- {{:helper.link('Add Radiation', 'radiation', {'rad' : 1})}} - {{:helper.link('Flush System', 'trash', {'flush' : 1}, data.system_in_use ? null : 'disabled')}} -
- -
-
-
- Virus Food: -
-
- {{:helper.displayBar(data.food_supply, 0, 100, 'good', data.food_supply)}} -
-
-
-
- Radiation Level: -
-
- {{:helper.displayBar(data.radiation, 0, 100, (data.radiation >= 50) ? 'bad' : (data.growth >= 25) ? 'average' : 'good')}} -
- {{:helper.formatNumber(data.radiation * 10000)}} µSv -
-
-
-
- Toxicity: -
-
- {{:helper.displayBar(data.toxins, 0, 100, (data.toxins >= 50) ? 'bad' : (data.toxins >= 25) ? 'average' : 'good', data.toxins + '%')}} -
-
-
- -
-

Chemicals

-
-
- {{:helper.link('Eject Chemicals', 'eject', { 'ejectchem' : 1 }, data.chemicals_inserted ? null : 'disabled')}} - {{:helper.link('Breed Virus', 'circle-arrow-s', { 'virus' : 1 }, data.can_breed_virus ? null : 'disabled')}} -
- -{{if data.chemicals_inserted}} -
-
- Volume: -
-
- {{:helper.displayBar(data.chemical_volume, 0, data.max_chemical_volume, 'good', data.chemical_volume + ' / ' + data.max_chemical_volume)}} -
-
-
-
- Breeding Environment: -
-
- - {{:!data.dish_inserted ? 'N/A' : data.can_breed_virus ? 'Suitable' : 'No hemolytic samples detected'}} - - {{if data.blood_already_infected}} -
- CAUTION: Viral infection detected in blood sample. - {{/if}} -
-
-{{else}} -
- No chemicals inserted. -
-{{/if}} - -
-

Virus Dish

-
-
- {{:helper.link('Eject Dish', 'eject', {'ejectdish' : 1}, data.dish_inserted ? null : 'disabled')}} -
- -{{if data.dish_inserted}} - {{if data.virus}} -
-
- Growth Density: -
-
- {{:helper.displayBar(data.growth, 0, 100, (data.growth >= 50) ? 'good' : (data.growth >= 25) ? 'average' : 'bad', data.growth + '%' )}} -
-
-
-
- Infection Rate: -
-
- {{:data.analysed ? data.infection_rate : "Unknown"}} -
-
- {{else}} -
- No virus detected. -
- {{/if}} -{{else}} -
- No dish loaded. -
-{{/if}} diff --git a/nano/templates/dna_modifier.tmpl b/nano/templates/dna_modifier.tmpl deleted file mode 100644 index 9a2804ba987..00000000000 --- a/nano/templates/dna_modifier.tmpl +++ /dev/null @@ -1,318 +0,0 @@ - -

Status

- -
- {{if !data.hasOccupant}} -
Cell Unoccupied
- {{else}} -
- {{:data.occupant.name}} =>  - {{if data.occupant.stat == 0}} - Conscious - {{else data.occupant.stat == 1}} - Unconscious - {{else}} - DEAD - {{/if}} -
- - {{if !data.occupant.isViableSubject || !data.occupant.uniqueIdentity || !data.occupant.structuralEnzymes}} -
- The occupant's DNA structure is ruined beyond recognition, please insert a subject with an intact DNA structure. -
- {{else data.occupant.stat < 2}} -
-
Health:
- {{if data.occupant.health >= 0}} - {{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, 'good')}} - {{else}} - {{:helper.displayBar(data.occupant.health, 0, data.occupant.minHealth, 'average alignRight')}} - {{/if}} -
{{:helper.round(data.occupant.health)}}
-
- -
-
Radiation:
- {{:helper.displayBar(data.occupant.radiationLevel, 0, 100, 'average')}} -
{{:helper.round(data.occupant.radiationLevel)}}
-
- -
-
Unique Enzymes:
-
{{:data.occupant.uniqueEnzymes ? data.occupant.uniqueEnzymes : 'Unknown'}}
-
- - - {{/if}} - {{/if}} -
-
- -

Operations

-
- {{:helper.link('Modify U.I.', 'link', {'selectMenuKey' : 'ui'}, data.selectedMenuKey == 'ui' ? 'selected' : null)}} - {{:helper.link('Modify S.E.', 'link', {'selectMenuKey' : 'se'}, data.selectedMenuKey == 'se' ? 'selected' : null)}} - {{:helper.link('Transfer Buffers', 'disk', {'selectMenuKey' : 'buffer'}, data.selectedMenuKey == 'buffer' ? 'selected' : null)}} - {{:helper.link('Rejuvenators', 'plusthick', {'selectMenuKey' : 'rejuvenators'}, data.selectedMenuKey == 'rejuvenators' ? 'selected' : null)}} -
- -
 
- -{{if !data.selectedMenuKey || data.selectedMenuKey == 'ui'}} -

Modify Unique Identifier

- {{:helper.displayDNABlocks(data.occupant.uniqueIdentity, data.selectedUIBlock, data.selectedUISubBlock, data.dnaBlockSize, 'UI')}} -
-
-
- Target: -
-
- {{:helper.link('-', null, {'changeUITarget' : 0}, (data.selectedUITarget > 0) ? null : 'disabled')}} -
 {{:data.selectedUITargetHex}} 
- {{:helper.link('+', null, {'changeUITarget' : 1}, (data.selectedUITarget < 15) ? null : 'disabled')}} -
-
-
-
- {{:helper.link('Irradiate Block', 'radiation', {'pulseUIRadiation' : 1}, !data.occupant.isViableSubject ? 'disabled' : null)}} -
-
-{{else data.selectedMenuKey == 'se'}} -

Modify Structural Enzymes

- {{:helper.displayDNABlocks(data.occupant.structuralEnzymes, data.selectedSEBlock, data.selectedSESubBlock, data.dnaBlockSize, 'SE')}} -
-
-
- {{:helper.link('Irradiate Block', 'radiation', {'pulseSERadiation' : 1}, !data.occupant.isViableSubject ? 'disabled' : null)}} -
-
-{{else data.selectedMenuKey == 'buffer'}} -

Transfer Buffers

- {{for data.buffers}} -

Buffer {{:(index + 1)}}

-
-
-
- Load Data: -
-
- {{:helper.link('Subject U.I.', 'link', {'bufferOption' : 'saveUI', 'bufferId' : (index + 1)}, !data.hasOccupant ? 'disabled' : null)}} - {{:helper.link('Subject U.I. + U.E.', 'link', {'bufferOption' : 'saveUIAndUE', 'bufferId' : (index + 1)}, !data.hasOccupant ? 'disabled' : null)}} - {{:helper.link('Subject S.E.', 'link', {'bufferOption' : 'saveSE', 'bufferId' : (index + 1)}, !data.hasOccupant ? 'disabled' : null)}} - {{:helper.link('From Disk', 'disk', {'bufferOption' : 'loadDisk', 'bufferId' : (index + 1)}, (!data.hasDisk || !data.disk.data) ? 'disabled' : null)}} -
-
- {{if value.data}} -
-
- Label: -
-
- {{:helper.link(value.label, 'document-b', {'bufferOption' : 'changeLabel', 'bufferId' : (index + 1)})}} -
-
-
-
- Subject: -
-
- {{:value.owner ? value.owner : 'Unknown'}} -
-
-
-
- Stored Data: -
-
- {{:value.data == 'ui' ? 'Unique Identifiers' : 'Structural Enzymes'}} - {{:value.ue ? ' + Unique Enzymes' : ''}} -
-
- {{else}} -
-
- This buffer is empty. -
-
- {{/if}} -
-
- Options: -
-
- {{:helper.link('Clear', 'trash', {'bufferOption' : 'clear', 'bufferId' : (index + 1)}, !value.data ? 'disabled' : null)}} - {{:helper.link('Injector', data.isInjectorReady ? 'pencil' : 'clock', {'bufferOption' : 'createInjector', 'bufferId' : (index + 1)}, (!data.isInjectorReady || !value.data) ? 'disabled' : null)}} - {{:helper.link('Block Injector', data.isInjectorReady ? 'pencil' : 'clock', {'bufferOption' : 'createInjector', 'bufferId' : (index + 1), 'createBlockInjector' : 1}, (!data.isInjectorReady || !value.data) ? 'disabled' : null)}} - {{:helper.link('Transfer', 'radiation', {'bufferOption' : 'transfer', 'bufferId' : (index + 1)}, (!data.hasOccupant || !value.data) ? 'disabled' : null)}} - {{:helper.link('Save To Disk', 'disk', {'bufferOption' : 'saveDisk', 'bufferId' : (index + 1)}, (!value.data || !data.hasDisk) ? 'disabled' : null)}} -
-
-
- {{/for}} - -

Data Disk

-
- {{if data.hasDisk}} - {{if data.disk.data}} -
-
- Label: -
-
- {{:data.disk.label ? data.disk.label : 'No Label'}} -
-
-
-
- Subject: -
-
- {{:data.disk.owner ? data.disk.owner : 'Unknown'}} -
-
-
-
- Stored Data: -
-
- {{:data.disk.data == 'ui' ? 'Unique Identifiers' : 'Structural Enzymes'}} - {{:data.disk.ue ? ' + Unique Enzymes' : ''}} -
-
- {{else}} -
-
- Disk is blank. -
-
- {{/if}} - {{else}} -
-
- No disk inserted. -
-
- {{/if}} -
-
- Options: -
-
- {{:helper.link('Wipe Disk', 'trash', {'bufferOption' : 'wipeDisk'}, (!data.hasDisk || !data.disk.data) ? 'disabled' : null)}} - {{:helper.link('Eject Disk', 'eject', {'bufferOption' : 'ejectDisk'}, !data.hasDisk ? 'disabled' : null)}} -
-
-
-{{else data.selectedMenuKey == 'rejuvenators'}} -

Rejuvenators

-
-
- Inject: -
-
- {{:helper.link('5', 'pencil', {'injectRejuvenators' : 5}, (!data.hasOccupant || !data.beakerVolume) ? 'disabled' : null)}} - {{:helper.link('10', 'pencil', {'injectRejuvenators' : 10}, (!data.hasOccupant || !data.beakerVolume) ? 'disabled' : null)}} - {{:helper.link('20', 'pencil', {'injectRejuvenators' : 20}, (!data.hasOccupant || !data.beakerVolume) ? 'disabled' : null)}} - {{:helper.link('30', 'pencil', {'injectRejuvenators' : 30}, (!data.hasOccupant || !data.beakerVolume) ? 'disabled' : null)}} - {{:helper.link('50', 'pencil', {'injectRejuvenators' : 50}, (!data.hasOccupant || !data.beakerVolume) ? 'disabled' : null)}} -
-
-
 
-
-
- Beaker: -
-
- {{if data.isBeakerLoaded}} - {{:data.beakerLabel ? data.beakerLabel : 'No label'}}
- {{if data.beakerVolume}} - {{:data.beakerVolume}} units remaining
- {{else}} - Beaker is empty - {{/if}} - {{else}} - No beaker loaded - {{/if}} -
-
- {{:helper.link('Eject Beaker', 'eject', {'ejectBeaker' : 1}, data.isBeakerLoaded ? null : 'disabled')}} -
-
-{{/if}} - -
 
- -{{if !data.selectedMenuKey || data.selectedMenuKey == 'ui' || data.selectedMenuKey == 'se'}} -

Radiation Emitter Settings

-
-
- Intensity: -
-
- {{:helper.link('-', null, {'radiationIntensity' : 0}, (data.radiationIntensity > 1) ? null : 'disabled')}} -
 {{:data.radiationIntensity}} 
- {{:helper.link('+', null, {'radiationIntensity' : 1}, (data.radiationIntensity < 10) ? null : 'disabled')}} -
-
-
-
- Duration: -
-
- {{:helper.link('-', null, {'radiationDuration' : 0}, (data.radiationDuration > 2) ? null : 'disabled')}} -
 {{:data.radiationDuration}} 
- {{:helper.link('+', null, {'radiationDuration' : 1}, (data.radiationDuration < 20) ? null : 'disabled')}} -
-
-
-
-   -
-
- {{:helper.link('Pulse Radiation', 'radiation', {'pulseRadiation' : 1}, !data.hasOccupant ? 'disabled' : null)}} -
-
-{{/if}} - -
 
- -
- -
-
- Occupant: -
-
- {{:helper.link('Eject Occupant', 'eject', {'ejectOccupant' : 1}, data.locked || !data.hasOccupant || data.irradiating ? 'disabled' : null)}} -
-
-
-
- Door Lock: -
-
- {{:helper.link('Engaged', 'locked', {'toggleLock' : 1}, data.locked ? 'selected' : !data.hasOccupant ? 'disabled' : null)}} - {{:helper.link('Disengaged', 'unlocked', {'toggleLock' : 1}, !data.locked ? 'selected' : data.irradiating ? 'disabled' : null)}} -
-
- -{{if data.irradiating}} -
-
-

Irradiating Subject

-

For {{:data.irradiating}} seconds.

-
-
-{{/if}} - diff --git a/nano/templates/docking_airlock_console.tmpl b/nano/templates/docking_airlock_console.tmpl deleted file mode 100644 index 08d4dbf0e42..00000000000 --- a/nano/templates/docking_airlock_console.tmpl +++ /dev/null @@ -1,96 +0,0 @@ -
-
-
- Docking Port Status: -
- {{if data.docking_status == "docked"}} -
- {{if !data.override_enabled}} - DOCKED - {{else}} - DOCKED-OVERRIDE ENABLED - {{/if}} - - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : null)}} - -
- {{else data.docking_status == "docking"}} -
- {{if !data.override_enabled}} - DOCKING - {{else}} - DOCKING-OVERRIDE ENABLED - {{/if}} - - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : null)}} - -
- {{else data.docking_status == "undocking"}} -
- {{if !data.override_enabled}} - UNDOCKING - {{else}} - UNDOCKING-OVERRIDE ENABLED - {{/if}} - - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : null)}} - -
- {{else data.docking_status == "undocked"}} -
- {{if !data.override_enabled}} - NOT IN USE - {{else}} - OVERRIDE ENABLED - {{/if}} - - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : null)}} - -
- {{else}} - ERROR - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : null)}} - {{/if}} -
-
-
-
-
- Chamber Pressure: -
-
- {{:helper.displayBar(data.chamber_pressure, 0, 200, (data.chamber_pressure < 80 || data.chamber_pressure > 120) ? 'bad' : (data.chamber_pressure < 95 || data.chamber_pressure > 110) ? 'average' : 'good')}} -
- {{:data.chamber_pressure}} kPa -
-
-
-
-
-
-
- {{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, (data.processing || data.airlock_disabled) ? 'disabled' : null)}} - {{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, (data.processing || data.airlock_disabled) ? 'disabled' : null)}} -
-
- {{if data.airlock_disabled}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, 'disabled', null)}} - {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, 'disabled', null)}} - {{else}} - {{if data.interior_status.state == "open"}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, 'redButton')}} - {{else}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, data.processing ? 'yellowButton' : null)}} - {{/if}} - {{if data.exterior_status.state == "open"}} - {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, 'redButton')}} - {{else}} - {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, data.processing ? 'yellowButton' : null)}} - {{/if}} - {{/if}} -
-
-
- {{:helper.link('Abort', 'cancel', {'command' : 'abort'}, (data.processing && !data.airlock_disabled) ? null : 'disabled', (data.processing && !data.airlock_disabled) ? 'redButton' : null)}} -
-
\ No newline at end of file diff --git a/nano/templates/door_access_console.tmpl b/nano/templates/door_access_console.tmpl deleted file mode 100644 index 2e5c81cb7e5..00000000000 --- a/nano/templates/door_access_console.tmpl +++ /dev/null @@ -1,42 +0,0 @@ -
-
-
- Exterior Door Status: -
-
- {{if data.exterior_status.state == "closed"}} - Locked - {{else}} - Open - {{/if}} -
-
-
-
- Interior Door Status: -
-
- {{if data.interior_status.state == "closed"}} - Locked - {{else}} - Open - {{/if}} -
-
-
-
-
-
- {{if data.exterior_status.state == "open"}} - {{:helper.link('Lock Exterior Door', 'alert', {'command' : 'force_ext'}, data.processing ? 'disabled' : null)}} - {{else}} - {{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext_door'}, data.processing ? 'disabled' : null)}} - {{/if}} - {{if data.interior_status.state == "open"}} - {{:helper.link('Lock Interior Door', 'alert', {'command' : 'force_int'}, data.processing ? 'disabled' : null)}} - {{else}} - {{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int_door'}, data.processing ? 'disabled' : null)}} - {{/if}} -
-
-
\ No newline at end of file diff --git a/nano/templates/escape_pod_berth_console.tmpl b/nano/templates/escape_pod_berth_console.tmpl deleted file mode 100644 index 434fa386cf1..00000000000 --- a/nano/templates/escape_pod_berth_console.tmpl +++ /dev/null @@ -1,42 +0,0 @@ -
-
-
- Escape Pod Status: -
-
- {{if data.docking_status == "docked"}} - {{if data.armed}} - ARMED - {{else}} - SYSTEMS OK - {{/if}} - {{else data.docking_status == "undocking"}} - EJECTING-STAND CLEAR! - {{else data.docking_status == "undocked"}} - POD EJECTED - {{else data.docking_status == "docking"}} - INITIALIZING... - {{else}} - ERROR - {{/if}} -
-
-
-
-
-
- {{if data.armed}} - {{if data.docking_status == "docked"}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', null)}} - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : null)}} - {{else}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redButton' : null)}} - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : 'yellowButton')}} - {{/if}} - {{else}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, 'disabled', null)}} - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, 'disabled', null)}} - {{/if}} -
-
-
\ No newline at end of file diff --git a/nano/templates/escape_pod_console.tmpl b/nano/templates/escape_pod_console.tmpl deleted file mode 100644 index aa24d3a9cef..00000000000 --- a/nano/templates/escape_pod_console.tmpl +++ /dev/null @@ -1,95 +0,0 @@ -
-
-
- Escape Pod Status: -
-
- {{if data.docking_status == "docked"}} - {{if data.is_armed}} - ARMED - {{else}} - SYSTEMS OK - {{/if}} - {{else data.docking_status == "undocking"}} - EJECTING - {{else data.docking_status == "undocked"}} - POD EJECTED - {{else data.docking_status == "docking"}} - DOCKING - {{else}} - ERROR - {{/if}} -
-
-
-
-
-
- Docking Hatch: -
-
- {{if data.docking_status == "docked"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed"}} - CLOSED - {{else}} - ERROR - {{/if}} - {{else data.docking_status == "docking"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed" && data.door_lock == "locked"}} - SECURED - {{else data.door_state == "closed" && data.door_lock == "unlocked"}} - UNSECURED - {{else}} - ERROR - {{/if}} - {{else data.docking_status == "undocking"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed" && data.door_lock == "locked"}} - SECURED - {{else data.door_state == "closed" && data.door_lock == "unlocked"}} - UNSECURED - {{else}} - ERROR - {{/if}} - {{else data.docking_status == "undocked"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed" && data.door_lock == "locked"}} - SECURED - {{else data.door_state == "closed" && data.door_lock == "unlocked"}} - UNSECURED - {{else}} - ERROR - {{/if}} - {{else}} - ERROR - {{/if}} -
-
-
-
-
-
- {{if data.docking_status == "docked"}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', null)}} - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : null)}} - {{else}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redButton' : null)}} - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : 'yellowButton')}} - {{/if}} -
-
-
-
-
-
- {{:helper.link('ARM', 'alert', {'command' : 'manual_arm'}, data.is_armed ? 'disabled' : null, data.is_armed ? 'redButton' : 'yellowButton')}} - {{:helper.link('MANUAL EJECT', 'alert', {'command' : 'force_launch'}, data.can_force ? null : 'disabled', data.can_force ? 'yellowButton' : null)}} -
-
-
diff --git a/nano/templates/exonet_node.tmpl b/nano/templates/exonet_node.tmpl deleted file mode 100644 index df075c8b89f..00000000000 --- a/nano/templates/exonet_node.tmpl +++ /dev/null @@ -1,49 +0,0 @@ - - -

Status

-
-
- Power: -
-
- {{:helper.link('On', 'power', {'toggle_power' : 1}, data.on ? 'selected' : null)}}{{:helper.link('Off', 'close', {'toggle_power' : 1}, data.on ? null : 'selected', data.on ? 'redButton' : null)}} -
-
- -

Ports

-
-
- Incoming PDA Messages: -
-
- {{:helper.link('Open', 'check', {'toggle_PDA_port' : 1}, data.allowPDAs ? 'selected' : null)}}{{:helper.link('Close', 'close', {'toggle_PDA_port' : 1}, data.allowPDAs ? null : 'selected')}} -
-
-
-
- Incoming Communicators: -
-
- {{:helper.link('Open', 'check', {'toggle_communicator_port' : 1}, data.allowCommunicators ? 'selected' : null)}}{{:helper.link('Close', 'close', {'toggle_communicator_port' : 1}, data.allowCommunicators ? null : 'selected')}} -
-
-
-
- Incoming Newscaster Content: -
-
- {{:helper.link('Open', 'check', {'toggle_newscaster_port' : 1}, data.allowNewscasters ? 'selected' : null)}}{{:helper.link('Close', 'close', {'toggle_newscaster_port' : 1}, data.allowNewscasters ? null : 'selected')}} -
-
- -

Logging

-
- {{for data.logs}} -
- {{:value}} -
- {{/for}} -
diff --git a/nano/templates/freezer.tmpl b/nano/templates/freezer.tmpl deleted file mode 100644 index fad41bad9fc..00000000000 --- a/nano/templates/freezer.tmpl +++ /dev/null @@ -1,62 +0,0 @@ -
-
- Status: -
-
- {{:helper.link('On', 'power', {'toggleStatus' : 1}, data.on ? 'selected' : null)}}{{:helper.link('Off', 'close', {'toggleStatus' : 1}, data.on ? null : 'selected')}} -
-
- -
-
- Power Level: -
-
- {{:helper.link('1', null, {'setPower' : 20}, (data.powerSetting == 20)? 'selected' : null)}} - {{:helper.link('2', null, {'setPower' : 40}, (data.powerSetting == 40)? 'selected' : null)}} - {{:helper.link('3', null, {'setPower' : 60}, (data.powerSetting == 60)? 'selected' : null)}} - {{:helper.link('4', null, {'setPower' : 80}, (data.powerSetting == 80)? 'selected' : null)}} - {{:helper.link('5', null, {'setPower' : 100}, (data.powerSetting == 100)? 'selected' : null)}} -
-
- -
-
- Gas Pressure: -
-
- {{:data.gasPressure}} kPa -
-
- -

Gas Temperature

-
-
- Current: -
-
- {{:helper.displayBar(data.gasTemperature, data.minGasTemperature, data.maxGasTemperature, data.gasTemperatureClass)}} -
- {{:data.gasTemperature}} K -
-
-
- -
-
- Target: -
-
- {{:helper.displayBar(data.targetGasTemperature, data.minGasTemperature, data.maxGasTemperature)}} -
- {{:helper.link('-', null, {'temp' : -100}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} - {{:helper.link('-', null, {'temp' : -10}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} - {{:helper.link('-', null, {'temp' : -1}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} -
 {{:data.targetGasTemperature}} K 
- {{:helper.link('+', null, {'temp' : 1}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}} - {{:helper.link('+', null, {'temp' : 10}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}} - {{:helper.link('+', null, {'temp' : 100}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}} -
-
-
- diff --git a/nano/templates/gas_pump.tmpl b/nano/templates/gas_pump.tmpl deleted file mode 100644 index a26d88a2cfe..00000000000 --- a/nano/templates/gas_pump.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -
-
- Power: -
-
- {{:helper.link(data.on? 'On' : 'Off', null, {'power' : 1})}} -
-
- -
-
- Desirable output pressure: -
-
-
- {{:helper.link('MAX', null, {'set_press' : 'max'}, null)}} - {{:helper.link('SET', null, {'set_press' : 'set'}, null)}} -
 {{:(data.pressure_set/100)}} kPa 
-
-
-
- -
-
- Load: -
-
- {{:helper.displayBar(data.last_power_draw, 0, data.max_power_draw, (data.last_power_draw < data.max_power_draw - 5) ? 'good' : 'average')}} -
- {{:data.last_power_draw}} W -
-
-
- -
-
- Flow Rate: -
-
-
- {{:(data.last_flow_rate/10)}} L/s -
-
-
\ No newline at end of file diff --git a/nano/templates/generator.tmpl b/nano/templates/generator.tmpl deleted file mode 100644 index 150884187f4..00000000000 --- a/nano/templates/generator.tmpl +++ /dev/null @@ -1,142 +0,0 @@ -
-
- Total Output: -
-
- {{:helper.displayBar(data.totalOutput, 0, data.maxTotalOutput)}} -
-
- {{:helper.fixed(data.totalOutput, 1)}} kW -
-
-
-
- Thermal Output: -
-
- {{:helper.fixed(data.thermalOutput, 1)}} kW -
-
-
- -{{if data.circConnected}} - - - - - - -
-
-

Primary Circulator ({{:data.primaryDir}})

-
-
- Turbine Output: -
-
- {{:helper.fixed(data.primaryOutput, 1)}} kW -
-
-
-
- Flow Capacity: -
-
- {{:helper.fixed(data.primaryFlowCapacity, 1)}} % -
-
-
-
-
- Inlet Pressure: -
-
- {{:helper.fixed(data.primaryInletPressure, 1)}} kPa -
-
-
-
- Inlet Temperature: -
-
- {{:helper.fixed(data.primaryInletTemperature, 1)}} K -
-
-
-
-
- Outlet Pressure: -
-
- {{:helper.fixed(data.primaryOutletPressure, 1)}} kPa -
-
-
-
- Outlet Temperature: -
-
- {{:helper.fixed(data.primaryOutletTemperature, 1)}} K -
-
-
-
-
-

Secondary Circulator ({{:data.secondaryDir}})

-
-
- Turbine Output: -
-
- {{:helper.fixed(data.secondaryOutput, 1)}} kW -
-
-
-
- Flow Capacity: -
-
- {{:helper.fixed(data.secondaryFlowCapacity, 1)}} % -
-
-
-
-
- Inlet Pressure: -
-
- {{:helper.fixed(data.secondaryInletPressure, 1)}} kPa -
-
-
-
- Inlet Temperature: -
-
- {{:helper.fixed(data.secondaryInletTemperature, 1)}} K -
-
-
-
-
- Outlet Pressure: -
-
- {{:helper.fixed(data.secondaryOutletPressure, 1)}} kPa -
-
-
-
- Outlet Temperature: -
-
- {{:helper.fixed(data.secondaryOutletTemperature, 1)}} K -
-
-
-
-{{else}} -
- ERROR: Both circulators must be connected! -
-{{/if}} diff --git a/nano/templates/gravity_generator.tmpl b/nano/templates/gravity_generator.tmpl deleted file mode 100644 index ad8e686c492..00000000000 --- a/nano/templates/gravity_generator.tmpl +++ /dev/null @@ -1,45 +0,0 @@ -
-
-
- Breaker Setting: -
-
- {{if data.breaker}} - Generator Enabled - {{else}} - Generator Disabled - {{/if}} -
-
-
-
- Charge Mode: -
-
- {{if (data.breaker && data.charge_count < 100)}} - Generator CHARGING - {{else (data.breaker && data.charge_count >= 100)}} - Generator Running - {{else (!data.breaker && data.charge_count > 0)}} - Generator DISCHARGING - {{else}} - Generator Offline - {{/if}} -
-
-
-
- Charge Status: -
-
- {{:data.charge_count}}% -
-
-
-
-
-
- {{:helper.link('Toggle Breaker', 'alert', {'gentoggle' : 1}, null)}} -
-
-
\ No newline at end of file diff --git a/nano/templates/hardsuit.tmpl b/nano/templates/hardsuit.tmpl deleted file mode 100644 index deb906249bf..00000000000 --- a/nano/templates/hardsuit.tmpl +++ /dev/null @@ -1,257 +0,0 @@ - - - - -{{if data.interfacelock || data.malf > 0}} -
-- HARDSUIT INTERFACE OFFLINE --
-{{else}} - {{if data.aicontrol && data.ai != 1}} -
-- HARDSUIT CONTROL OVERRIDDEN BY AI --
- {{else}} -
-
-
- Power supply -
-
- {{:helper.displayBar(data.chargestatus, 0, 50, (data.chargestatus >= 35) ? 'good' : (data.chargestatus >= 15) ? 'average' : 'bad')}} {{:data.charge}}/{{:data.maxcharge}} -
-
-
-
-
- AI control: -
-
- {{if data.aioverride}} -
ENABLED
- {{else}} -
DISABLED
- {{/if}} -
-
- {{:helper.link('Toggle', 'circle-arrow-s', {'toggle_ai_control' : 1}, null)}} -
-
-
-
- Suit status: -
-
- {{if data.sealing == 1}} -
PROCESSING
- {{else}} - {{if data.seals == 1}} -
INACTIVE
- {{else}} -
ACTIVE
- {{/if}} - {{/if}} -
-
- {{:helper.link('Toggle', 'circle-arrow-s', {'toggle_seals' : 1}, null)}} -
-
-
-
- Cover status: -
-
- {{if data.emagged || !data.securitycheck}} -
ERROR - MAINTENANCE LOCK CONTROL OFFLINE
- {{else}} - {{if data.coverlock}} -
LOCKED
- {{else}} -
UNLOCKED
- {{/if}} - {{/if}} -
-
- {{:helper.link('Toggle', 'circle-arrow-s', {'toggle_suit_lock' : 1}, null)}} -
-
-
-
- -

Hardware

-

Suit pieces

- -
-
-
- Helmet: -
-
- {{:helper.capitalizeFirstLetter(data.helmet)}} -
- {{if data.sealing != 1}} -
- {{:helper.link('Toggle', 'circle-arrow-s', {'toggle_piece' : 'helmet'}, null)}} -
- {{/if}} -
-
-
- Gauntlets: -
-
- {{:helper.capitalizeFirstLetter(data.gauntlets)}} -
- {{if data.sealing != 1}} -
- {{:helper.link('Toggle', 'circle-arrow-s', {'toggle_piece' : 'gauntlets'}, null)}} -
- {{/if}} -
-
-
- Boots: -
-
- {{:helper.capitalizeFirstLetter(data.boots)}} -
- {{if data.sealing != 1}} -
- {{:helper.link('Toggle', 'circle-arrow-s', {'toggle_piece' : 'boots'}, null)}} -
- {{/if}} -
-
-
- Chestpiece: -
-
- {{:helper.capitalizeFirstLetter(data.chest)}} -
- {{if data.sealing != 1}} -
- {{:helper.link('Toggle', 'circle-arrow-s', {'toggle_piece' : 'chest'}, null)}} -
- {{/if}} -
-
- -

System modules

- {{if data.seals == 1 || data.sealing == 1}} -

HARDSUIT SYSTEMS OFFLINE

- {{else}} -

Selected primary system: - {{if data.primarysystem}} - {{:helper.capitalizeFirstLetter(data.primarysystem)}} - {{else}} - None - {{/if}} -

- {{if data.modules}} -
- {{for data.modules}} -
-
-
-
{{:helper.capitalizeFirstLetter(value.name)}}
- {{if value.damage > 0}} -
- {{if value.damage == 1}} - (
damaged
) - {{else}} - (
destroyed
) - {{/if}} -
- {{/if}} -
-
- Engage: {{:value.engagecost}} - Activate: {{:value.activecost}} - Passive: {{:value.passivecost}} -
-
- {{:value.desc}} -
-
- {{if value.can_use == 1}} -
- {{:helper.link(value.engagestring, 'circle-arrow-s', {'interact_module' : value.index, 'module_mode' : 'engage'}, null)}} -
- {{/if}} - {{if value.can_select == 1}} -
- {{if value.name == data.primarysystem}} -
SELECTED
- {{else}} - {{:helper.link('Select', 'circle-arrow-s', {'interact_module' : value.index, 'module_mode' : 'select'}, null)}} - {{/if}} -
- {{/if}} - {{if value.can_toggle == 1}} -
- {{if value.is_active == 1}} - {{:helper.link(value.deactivatestring, 'circle-arrow-s', {'interact_module' : value.index, 'module_mode' : 'deactivate'}, null)}} - {{else}} - {{:helper.link(value.activatestring, 'circle-arrow-s', {'interact_module' : value.index, 'module_mode' : 'activate'}, null)}} - {{/if}} -
- {{/if}} -
-
-
-
- {{if value.charges}} -
Stored charges
-
Selected: {{:helper.capitalizeFirstLetter(value.chargetype)}}
- {{for value.charges :itemValue:itemIndex}} -
- {{:helper.link(helper.capitalizeFirstLetter(itemValue.caption), null, {'interact_module' : value.index, 'module_mode' : 'select_charge_type', 'charge_type' : itemValue.index}, null)}} -
- {{/for}} - {{/if}} -
-
-
- {{/for}} -
- {{else}} - None. - {{/if}} - {{/if}} - {{/if}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/isolation_centrifuge.tmpl b/nano/templates/isolation_centrifuge.tmpl deleted file mode 100644 index 4ff0272df02..00000000000 --- a/nano/templates/isolation_centrifuge.tmpl +++ /dev/null @@ -1,81 +0,0 @@ -
- {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}} - {{:helper.link('Print', 'print', { 'print' : 1 }, data.antibodies || data.pathogens ? null : 'disabled', 'fixedLeft')}} -
- -{{if data.busy}} -
The Centrifuge is currently busy.
-
-
{{:data.busy}}
-
-

- Thank you for your patience! -

-{{else}} -
-

{{:data.is_antibody_sample ? 'Antibody Sample' : 'Blood Sample'}}

-
-
- {{:helper.link('Eject Vial', 'eject', { 'action' : 'sample' }, data.sample_inserted ? null : 'disabled')}} -
- {{if data.sample_inserted}} - {{if data.antibodies || data.pathogens}} -
- {{if data.antibodies}} -
-
- Antibodies: -
-
- {{:data.antibodies}} -
-
- {{/if}} - {{if data.pathogens}} -
-
- Pathogens: -
-
- {{for data.pathogens}} -
- {{:value.name}} ({{:value.spread_type}}) -
- {{/for}} -
-
- {{/if}} -
- {{else}} -
- No antibodies or viral strains detected. -
- {{/if}} - {{else}} -
- No vial detected. -
- {{/if}} - {{if data.antibodies && !data.is_antibody_sample}} -
-
- Isolate Antibodies: -
-
- {{:helper.link(data.antibodies, 'pencil', { 'action' : 'antibody' })}} -
-
- {{/if}} - {{if data.pathogens}} -
-
- Isolate Strain: -
-
- {{for data.pathogens}} - {{:helper.link(value.name, 'pencil', { 'isolate' : value.reference })}} - {{/for}} -
-
- {{/if}} -{{/if}} diff --git a/nano/templates/mod_sec_camera.tmpl b/nano/templates/mod_sec_camera.tmpl deleted file mode 100644 index 0afb80f4b8f..00000000000 --- a/nano/templates/mod_sec_camera.tmpl +++ /dev/null @@ -1,36 +0,0 @@ -
- {{:helper.link('Show Map', 'pin-s', {'showMap' : 1})}} - {{:helper.link('Reset', 'refresh', {'reset' : 1})}} -
- -
-
Current Camera:
- {{if data.current_camera}} -
{{:data.current_camera.name}}
- {{else}} -
None
- {{/if}} -
- -
-
Networks:
-
-{{for data.networks}} - {{if value.has_access}} - {{:helper.link(value.tag, '', {'switch_network' : value.tag}, null, data.current_network == value.tag ? 'selected' : null)}} - {{else}} - {{:helper.link(value.tag, '', {}, null, data.current_network == value.tag ? 'selected' : 'redButton')}} - {{/if}} -{{/for}} -
-
Cameras:
-
-{{for data.cameras}} - {{if data.current_camera && value.name == data.current_camera.name}} - {{:helper.link(value.name, '', {'switch_camera' : value.camera}, 'selected')}} - {{else value.deact}} - {{:helper.link(value.name + " (deactivated)", '', {}, 'inactive')}} - {{else}} - {{:helper.link(value.name, '', {'switch_camera' : value.camera})}} - {{/if}} -{{/for}} diff --git a/nano/templates/mod_sec_camera_map_header.tmpl b/nano/templates/mod_sec_camera_map_header.tmpl deleted file mode 100644 index 459027797f5..00000000000 --- a/nano/templates/mod_sec_camera_map_header.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -
- {{:helper.link('Show Camera List', 'script', {'showMap' : 0})}} - {{:helper.link('Reset', 'refresh', {'reset' : 1})}} -
-
-
Current Camera:
- {{if data.current_camera}} -
{{:data.current_camera.name}}
- {{else}} -
None
- {{/if}} -
- -
-
- Z-Level: -
-
- {{for config.mapZLevels :zValue:zIndex}} - {{:helper.link(zValue, 'close', {'mapZLevel' : zValue}, null, config.mapZLevel == zValue ? 'selected' : null)}} - {{/for}} -
-
-
-
- Zoom Level: -
-
- - - - -
-
-
-
Networks:
-
-{{for data.networks}} - {{if value.has_access}} - {{:helper.link(value.tag, '', {'switch_network' : value.tag}, null, data.current_network == value.tag ? 'selected' : null)}} - {{else}} - {{:helper.link(value.tag, '', {}, null, data.current_network == value.tag ? 'selected' : 'redButton')}} - {{/if}} -{{/for}} \ No newline at end of file diff --git a/nano/templates/multi_docking_console.tmpl b/nano/templates/multi_docking_console.tmpl deleted file mode 100644 index 9515799644e..00000000000 --- a/nano/templates/multi_docking_console.tmpl +++ /dev/null @@ -1,37 +0,0 @@ -
-
-
- Docking Port Status: -
-
- {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - DOCKING - {{else data.docking_status == "undocking"}} - UNDOCKING - {{else data.docking_status == "undocked"}} - NOT IN USE - {{else}} - ERROR - {{/if}} -
-
-
- -{{for data.airlocks}} -
-
-
- {{:value.name}} -
-
- {{if value.override_enabled}} - OVERRIDE ENABLED - {{else}} - STATUS OK - {{/if}} -
-
-
-{{/for}} \ No newline at end of file diff --git a/nano/templates/ntnet_relay.tmpl b/nano/templates/ntnet_relay.tmpl deleted file mode 100644 index 24bd8317827..00000000000 --- a/nano/templates/ntnet_relay.tmpl +++ /dev/null @@ -1,32 +0,0 @@ -{{if data.dos_crashed}} -

NETWORK BUFFERS OVERLOADED

-

Overload Recovery Mode

- This system is suffering temporary outage due to overflow of traffic buffers. Until buffered traffic is processed, all further requests will be dropped. Frequent occurences of this error may indicate insufficient hardware capacity of your network. Please contact your network planning department for instructions on how to resolve this issue. -

ADMINISTRATIVE OVERRIDE

- CAUTION - Data loss may occur - {{:helper.link('Purge buffered traffic', null, { 'restart' : 1 })}} -{{else}} -
- Relay status: -
-
- {{if data.enabled}} - {{:helper.link('ENABLED', null, { 'toggle' : 1 })}} - {{else}} - {{:helper.link('DISABLED', null, { 'toggle' : 1 })}} - {{/if}} - -
-
- Network buffer status: -
-
- {{:data.dos_overload}} / {{:data.dos_capacity}} GQ -
-
- Options: -
-
- {{:helper.link('Purge network blacklist', null, { 'purge' : 1 })}} -
-{{/if}} \ No newline at end of file diff --git a/nano/templates/omni_filter.tmpl b/nano/templates/omni_filter.tmpl deleted file mode 100644 index 672ffcfe053..00000000000 --- a/nano/templates/omni_filter.tmpl +++ /dev/null @@ -1,87 +0,0 @@ -
-
- {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}} -
-
- {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} -
-
-
- {{if data.config}} - -
-
-
Port
- {{for data.ports}} -
{{:value.dir}} Port
- {{/for}} -
-
-
Input
- {{for data.ports}} -
- {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, null, value.input ? 'selected' : null)}} -
- {{/for}} -
-
-
Output
- {{for data.ports}} -
- {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} -
- {{/for}} -
-
-
Filter
- {{for data.ports}} -
- {{:helper.link(value.f_type ? value.f_type : 'None', null, {'command' : 'switch_filter', 'mode' : value.f_type, 'dir' : value.dir}, value.atmo_filter ? null : 'disabled', value.f_type ? 'selected' : null)}} -
- {{/for}} -
-
- -
- Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
-
- {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} -
- - {{else}} - -
-
-
Port
- {{for data.ports}} -
{{:value.dir}} Port
- {{/for}} -
-
-
Mode
- {{for data.ports}} -
- {{if value.input}} - Input - {{else value.output}} - Output - {{else value.f_type}} - {{:value.f_type}} - {{else}} - Disabled - {{/if}} -
- {{/for}} -
-
- -
- Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
- -
- Flow Rate: {{:(data.last_flow_rate/10)}} L/s -
- {{/if}} -
diff --git a/nano/templates/omni_mixer.tmpl b/nano/templates/omni_mixer.tmpl deleted file mode 100644 index 77c4573880b..00000000000 --- a/nano/templates/omni_mixer.tmpl +++ /dev/null @@ -1,102 +0,0 @@ -
-
- {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}} -
-
- {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} -
-
-
- {{if data.config}} - -
-
-
Port
- {{for data.ports}} -
{{:value.dir}} Port
- {{/for}} -
-
-
Input
- {{for data.ports}} -
- {{:helper.link(' ', null, value.input ? {'command' : 'switch_mode', 'mode' : 'none', 'dir' : value.dir} : {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, value.output ? 'disabled' : null, value.input ? 'selected' : null)}} -
- {{/for}} -
-
-
Output
- {{for data.ports}} -
- {{:helper.link(' ', null, value.output ? null : {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} -
- {{/for}} -
-
-
Concentration
- {{for data.ports}} -
- {{:helper.link( value.input ? helper.round(value.concentration*100)+' %' : '-', null, {'command' : 'switch_con', 'dir' : value.dir}, value.input ? null : 'disabled')}} -
- {{/for}} -
-
-
Lock
- {{for data.ports}} -
- {{:helper.link(' ', value.con_lock ? 'locked' : 'unlocked', {'command' : 'switch_conlock', 'dir' : value.dir}, value.input ? null : 'disabled', value.con_lock ? 'selected' : null)}} -
- {{/for}} -
-
- -
- Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
-
- {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} -
- - {{else}} - -
-
-
Port
- {{for data.ports}} -
{{:value.dir}} Port
- {{/for}} -
-
-
Mode
- {{for data.ports}} -
- {{if value.input}} - Input - {{else value.output}} - Output - {{else}} - Disabled - {{/if}} -
- {{/for}} -
-
-
Concentration
- {{for data.ports}} -
- {{if value.input}} - {{:helper.round(value.concentration*100)}} % - {{else}} - - - {{/if}} -
- {{/for}} -
-
- -
- Flow Rate: {{:(data.last_flow_rate/10)}} L/s -
- - {{/if}} -
\ No newline at end of file diff --git a/nano/templates/operating.tmpl b/nano/templates/operating.tmpl deleted file mode 100644 index c53bd94c651..00000000000 --- a/nano/templates/operating.tmpl +++ /dev/null @@ -1,47 +0,0 @@ - - -{{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/pacman.tmpl b/nano/templates/pacman.tmpl deleted file mode 100644 index 386358c9cc6..00000000000 --- a/nano/templates/pacman.tmpl +++ /dev/null @@ -1,113 +0,0 @@ -

Status

-
-
- Generator Status: -
-
- {{if data.active}} - Online - {{else}} - Offline - {{/if}} -
-
- Generator Control: -
-
- {{if data.active}} - {{:helper.link('STOP', 'power', {'action' : "disable"})}} - {{else}} - {{:helper.link('START', 'power', {'action' : "enable"})}} - {{/if}} -
-
-

Fuel

-
-
- Fuel Type: -
-
- {{:data.fuel_type}} -
-
- Fuel Level: -
-
- {{if data.fuel_stored >= 5000}} - {{:helper.displayBar(data.fuel_stored, 0, data.fuel_capacity, 'good')}} -
{{:data.fuel_stored}}/{{:data.fuel_capacity}} cm3 - {{else data.fuel_stored >= 1000}} - {{:helper.displayBar(data.fuel_stored, 0, data.fuel_capacity, 'average')}} -
{{:data.fuel_stored}}/{{:data.fuel_capacity}} cm3 - {{else}} - {{:helper.displayBar(data.fuel_stored, 0, data.fuel_capacity, 'bad')}} -
{{:data.fuel_stored}}/{{:data.fuel_capacity}} cm3 - {{/if}} -
-
- Fuel Usage: -
-
- {{:data.fuel_usage}} cm3/s -
- {{if !data.is_ai}} -
- Control: -
-
- {{:helper.link('EJECT FUEL', 'arrowupthick-1-s', {'action' : "eject"}, data.active ? 'disabled' : null)}} -
- {{/if}} -
-

Output

-
-
- Power setting: -
-
- {{if data.output_set > data.output_safe}} - {{:data.output_set}} / {{:data.output_max}} ({{:data.output_watts}} W) - {{else}} - {{:data.output_set}} / {{:data.output_max}} ({{:data.output_watts}} W) - {{/if}} -
-
- Control: -
-
- {{:helper.link('+', null, {'action' : "higher_power"})}} - {{:helper.link('-', null, {'action' : "lower_power"})}} -
-
-

Temperature

-
-
- Temperature: -
-
- {{if data.temperature_current < (data.temperature_max * 0.8)}} - {{:helper.displayBar(data.temperature_current, 0, (data.temperature_max * 1.5), 'good')}} -
{{:data.temperature_current}} C - {{else data.temperature_current < data.temperature_max}} - {{:helper.displayBar(data.temperature_current, 0, (data.temperature_max * 1.5), 'average')}} -
{{:data.temperature_current}} C - {{else}} - {{:helper.displayBar(data.temperature_current, 0, (data.temperature_max * 1.5), 'bad')}} -
{{:data.temperature_current}} C - {{/if}} -
-
- Generator Status: -
-
- {{if data.temperature_overheat > 50}} - DANGER: CRITICAL OVERHEAT! Deactivate generator immediately! - {{else data.temperature_overheat > 20}} - WARNING: Overheating! - {{else data.temperature_overheat > 1}} - Temperature High - {{else}} - Optimal - {{/if}} -
-
\ No newline at end of file diff --git a/nano/templates/pathogenic_isolator.tmpl b/nano/templates/pathogenic_isolator.tmpl deleted file mode 100644 index 69411d858fc..00000000000 --- a/nano/templates/pathogenic_isolator.tmpl +++ /dev/null @@ -1,107 +0,0 @@ -
-

Menu

-
-
- {{if !data.isolating}} - {{:helper.link('Home', 'home', {'home' : 1}, data.state == 'home' ? 'disabled' : null, 'fixedLeft')}} - {{:helper.link('List', 'note', {'list' : 1}, data.state == 'list' ? 'disabled' : null, 'fixedLeft')}} - {{:helper.link('Pathogen', 'folder-open', {'entry' : 1}, data.state == 'entry' ? 'disabled' : null, 'fixedLeft')}} - {{/if}} -
- {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}} - {{:helper.link('Print', 'print', { 'print' : 1 }, data.can_print ? null : 'disabled', 'fixedLeft')}} -
- -{{if data.isolating}} -
The Isolator is currently busy.
-
-
Isolating pathogens...
-
-

- Thank you for your patience! -

-{{else}} - {{if data.state =="home"}} -
-

Blood Sample

-
-
- {{:helper.link('Eject Syringe', 'eject', { 'eject' : 1 }, data.syringe_inserted ? null : 'disabled')}} -
- - {{if data.syringe_inserted}} -
- Pathogens: - {{if data.pathogen_pool}} - {{for data.pathogen_pool}} -
- {{:index + 1}}. #{{:value.unique_id}} {{:value.is_in_database ? "(Analysed)" : ""}}
- {{:value.name}}: {{:value.dna}} -
- {{/for}} - {{else}} - No pathogens detected. - {{/if}} -
- {{else}} -
- No syringe loaded. -
- {{/if}} - {{if data.pathogen_pool}} -
-
- Isolate Pathogens: -
-
- {{for data.pathogen_pool}} - {{:helper.link('#' + value.unique_id, 'pencil', { 'isolate' : value.reference }, null, 'fixedLeft')}} - {{/for}} -
-
-
-
- Database Lookup: -
-
- {{for data.pathogen_pool}} - {{if value.is_in_database}} - {{:helper.link('#' + value.unique_id, 'info', { 'entry' : 1, 'view' : value.record }, null, 'fixedLeft')}} - {{/if}} - {{/for}} -
-
- {{/if}} - {{else}} - {{if data.state == "list"}} -
-

View Database

-
-
- {{if data.database}} - {{for data.database}} -
-
{{:value.name}}
- {{:helper.link('Details', 'circle-arrow-s', { 'entry' : 1, 'view' : value.record }, null, 'fixedLeft')}} -
- {{/for}} - {{else}} - The viral database is empty. - {{/if}} -
- {{else}} - {{if data.state == "entry"}} - {{if data.entry}} -
-

{{:data.entry.name}}

-
-
- {{:data.entry.description}} -
- {{else}} - No virus selected. - {{/if}} - {{/if}} - {{/if}} - {{/if}} -{{/if}} diff --git a/nano/templates/phoron_airlock_console.tmpl b/nano/templates/phoron_airlock_console.tmpl deleted file mode 100644 index 8c0bb69cd70..00000000000 --- a/nano/templates/phoron_airlock_console.tmpl +++ /dev/null @@ -1,47 +0,0 @@ -
-
-
- Chamber Pressure: -
-
- {{:helper.displayBar(data.chamber_pressure, 0, 200, (data.chamber_pressure < 80 || data.chamber_pressure) > 120 ? 'bad' : (data.chamber_pressure < 95 || data.chamber_pressure > 110) ? 'average' : 'good')}} -
- {{:helper.round(data.chamber_pressure)}} kPa -
-
-
-
-
- Chamber Phoron: -
-
- {{:helper.displayBar(data.chamber_phoron, 0, 100, data.chamber_phoron >= 5 ? 'bad' : data.chamber_phoron > 0.5 ? 'average' : 'good')}} -
- {{:data.chamber_phoron < 10 ? helper.fixed(data.chamber_phoron) : helper.round(data.chamber_phoron)}} mol -
-
-
-
-
-
-
- {{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, data.processing ? 'disabled' : null)}} - {{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, data.processing ? 'disabled' : null)}} -
-
- {{if data.interior_status.state == "open"}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, 'redButton')}} - {{else}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, data.processing ? 'yellowButton' : null)}} - {{/if}} - {{if data.exterior_status.state == "open"}} - {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, 'redButton')}} - {{else}} - {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, data.processing ? 'yellowButton' : null)}} - {{/if}} -
-
-
- {{:helper.link('Abort', 'cancel', {'command' : 'abort'}, data.processing ? null : 'disabled', data.processing ? 'redButton' : null)}} -
-
\ No newline at end of file diff --git a/nano/templates/portpump.tmpl b/nano/templates/portpump.tmpl deleted file mode 100644 index 3e14aac8f92..00000000000 --- a/nano/templates/portpump.tmpl +++ /dev/null @@ -1,100 +0,0 @@ -

Pump Status

-
-
- Tank Pressure: -
-
- {{:data.tankPressure}} kPa -
-
- -
-
- Port Status: -
-
- {{:data.portConnected ? 'Connected' : 'Disconnected'}} -
-
- -
-
- Load: -
-
- {{:data.powerDraw}} W -
-
- -
-
- Cell Charge: -
-
- {{:helper.displayBar(data.cellCharge, 0, data.cellMaxCharge)}} -
-
- -

Holding Tank Status

-{{if data.hasHoldingTank}} -
-
- Tank Label: -
-
-
{{:data.holdingTank.name}}
{{:helper.link('Eject', 'eject', {'remove_tank' : 1})}} -
-
- -
-
- Tank Pressure: -
-
- {{:data.holdingTank.tankPressure}} kPa -
-
-{{else}} -
No holding tank inserted.
-
 
-{{/if}} - - -

Power Regulator Status

-
-
- Target Pressure: -
-
- {{:helper.displayBar(data.targetpressure, data.minpressure, data.maxpressure)}} -
- {{:helper.link('-', null, {'pressure_adj' : -1000}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -100}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -10}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -1}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} -
 {{:data.targetpressure}} kPa 
- {{:helper.link('+', null, {'pressure_adj' : 1}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 10}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 100}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 1000}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} -
-
-
- -
-
- Power Switch: -
-
- {{:helper.link('On', 'unlocked', {'power' : 1}, data.on ? 'selected' : null)}} {{:helper.link('Off', 'locked', {'power' : 1}, data.on ? null : 'selected')}} -
-
- -
-
- Pump Direction: -
-
- {{:helper.link('Out', 'arrowreturn-1-e', {'direction' : 1}, data.pump_dir ? 'selected' : null)}} {{:helper.link('In', 'arrowreturn-1-w', {'direction' : 1}, data.pump_dir ? null : 'selected')}} -
-
diff --git a/nano/templates/portscrubber.tmpl b/nano/templates/portscrubber.tmpl deleted file mode 100644 index c99f53344c4..00000000000 --- a/nano/templates/portscrubber.tmpl +++ /dev/null @@ -1,91 +0,0 @@ -

Scrubber Status

-
-
- Tank Pressure: -
-
- {{:data.tankPressure}} kPa -
-
- -
-
- Port Status: -
-
- {{:data.portConnected ? 'Connected' : 'Disconnected'}} -
-
- -
-
- Load: -
-
- {{:data.powerDraw}} W -
-
- -
-
- Cell Charge: -
-
- {{:helper.displayBar(data.cellCharge, 0, data.cellMaxCharge)}} -
-
- -

Holding Tank Status

-{{if data.hasHoldingTank}} -
-
- Tank Label: -
-
-
{{:data.holdingTank.name}}
{{:helper.link('Eject', 'eject', {'remove_tank' : 1})}} -
-
q - -
-
- Tank Pressure: -
-
- {{:data.holdingTank.tankPressure}} kPa -
-
-{{else}} -
No holding tank inserted.
-
 
-{{/if}} - - -

Power Regulator Status

-
-
- Volume Rate: -
-
- {{:helper.displayBar(data.rate, data.minrate, data.maxrate)}} -
- {{:helper.link('-', null, {'volume_adj' : -1000}, (data.rate > data.minrate) ? null : 'disabled')}} - {{:helper.link('-', null, {'volume_adj' : -100}, (data.rate > data.minrate) ? null : 'disabled')}} - {{:helper.link('-', null, {'volume_adj' : -10}, (data.rate > data.minrate) ? null : 'disabled')}} - {{:helper.link('-', null, {'volume_adj' : -1}, (data.rate > data.minrate) ? null : 'disabled')}} -
 {{:data.rate}} L/s 
- {{:helper.link('+', null, {'volume_adj' : 1}, (data.rate < data.maxrate) ? null : 'disabled')}} - {{:helper.link('+', null, {'volume_adj' : 10}, (data.rate < data.maxrate) ? null : 'disabled')}} - {{:helper.link('+', null, {'volume_adj' : 100}, (data.rate < data.maxrate) ? null : 'disabled')}} - {{:helper.link('+', null, {'volume_adj' : 1000}, (data.rate < data.maxrate) ? null : 'disabled')}} -
-
-
- -
-
- Power Switch: -
-
- {{:helper.link('On', 'unlocked', {'power' : 1}, data.on ? 'selected' : null)}} {{:helper.link('Off', 'locked', {'power' : 1}, data.on ? null : 'selected')}} -
-
diff --git a/nano/templates/power_monitor.tmpl b/nano/templates/power_monitor.tmpl deleted file mode 100644 index 6c9e5eee341..00000000000 --- a/nano/templates/power_monitor.tmpl +++ /dev/null @@ -1,96 +0,0 @@ -{{if data.focus}} -
- {{:helper.link('Show List', 'cancel', { 'clear' : 1})}} Sensor selected: {{:data.focus.name}} -
- {{if data.map_levels.length}} - {{:helper.link('Show APCs On Map', 'pin-s', {'showMap' : 1})}} - {{/if}} - {{if data.focus.error}} - {{:data.focus.error}} - {{else}} -

Network Information

-
- Network Load Status: -
- {{if data.focus.load_percentage >= 95}} -
DANGER: Overload
- {{else data.focus.load_percentage >= 85}} -
WARNING: High Load
- {{else}} -
Optimal
- {{/if}} -
- Network Security Status: -
- {{if data.focus.alarm}} -
WARNING: Abnormal activity detected!
- {{else}} -
Secure
- {{/if}} - -
- Load Percentage: -
-
- {{:helper.displayBar(data.focus.load_percentage, 0, 100, (data.focus.load_percentage <= 75) ? 'good' : (data.focus.load_percentage <= 90) ? 'average' : 'bad')}}{{:data.focus.load_percentage}}% -
-
- Available Power: -
-
- {{:data.focus.total_avail}} -
-
- APC Power Usage: -
-
- {{:data.focus.total_used_apc}} -
-
- Other Power Usage: -
-
- {{:data.focus.total_used_other}} -
-
- Total Usage: -
-
- {{:data.focus.total_used_all}} -
-

Sensor Readings

- -
APC NameEquipmentLightingEnvironmentCell StatusAPC Load - {{for data.focus.apc_data}} -
{{:value.name}} - {{:value.s_equipment}} - {{:value.s_lighting}} - {{:value.s_environment}} - {{if value.cell_status == "N"}} - {{:helper.link(value.cell_charge + '%', 'batt_disc', null,'disabled', 'width75btn')}} - {{else value.cell_status == "C"}} - {{:helper.link(value.cell_charge + '%', 'batt_chrg', null,'disabled', 'width75btn')}} - {{else}} - {{:helper.link(value.cell_charge + '%', 'batt_full', null,'disabled', 'width75btn')}} - {{/if}} - {{:value.total_load}} - {{empty}} -
No APCs detected in connected powernet. - {{/for}} -
- {{/if}} -{{else}} -
- {{:helper.link('Scan For Sensors', 'refresh', { 'refresh' : 1})}} No active sensor. Printing sensor list. -

- {{for data.all_sensors}} - {{if value.alarm}} -
{{:helper.link(value.name, 'alert', { 'setsensor' : value.name})}} - {{else}} -
{{:helper.link(value.name, '' , { 'setsensor' : value.name})}} - {{/if}} - {{empty}} - WARN: No Sensors Detected! - {{/for}} -
-{{/if}} \ No newline at end of file diff --git a/nano/templates/power_monitor_map_content.tmpl b/nano/templates/power_monitor_map_content.tmpl deleted file mode 100644 index 291903144d7..00000000000 --- a/nano/templates/power_monitor_map_content.tmpl +++ /dev/null @@ -1,33 +0,0 @@ - -{{if data.focus}} - {{for data.focus.apc_data}} - {{if value.z == config.mapZLevel}} -
- -
- {{/if}} - {{/for}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/power_monitor_map_header.tmpl b/nano/templates/power_monitor_map_header.tmpl deleted file mode 100644 index 171fd034291..00000000000 --- a/nano/templates/power_monitor_map_header.tmpl +++ /dev/null @@ -1,33 +0,0 @@ - -{{:helper.link('Show Network Information', 'script', {'showMap' : 0})}} -{{if data.focus}}Sensor selected: {{:data.focus.name}}{{/if}} -{{if data.map_levels.length > 1}} -
- Z Level:  - {{for data.map_levels }} - {{:helper.link(value, null, {'mapZLevel' : value}, null, config.mapZLevel == value ? 'selected' : null)}} - {{/for}} -
-{{/if}} -
- Zoom Level:  - - - - -
-
-
Sensors:
-
-{{for data.all_sensors}} - {{if value.alarm}} - {{:helper.link(value.name, 'alert', { 'setsensor' : value.name})}} - {{else}} - {{:helper.link(value.name, '' , { 'setsensor' : value.name})}} - {{/if}} -{{empty}} - WARN: No Sensors Detected! -{{/for}} diff --git a/nano/templates/pressure_regulator.tmpl b/nano/templates/pressure_regulator.tmpl deleted file mode 100644 index bbbfcc22df1..00000000000 --- a/nano/templates/pressure_regulator.tmpl +++ /dev/null @@ -1,76 +0,0 @@ -
-
- Input Pressure: -
-
- {{:(data.input_pressure/100)}} kPa -
-
- -
-
- Output Pressure: -
-
- {{:(data.output_pressure/100)}} kPa -
-
- -
-
- Flow Rate: -
-
-
- {{:(data.last_flow_rate/10)}} L/s -
-
-
- -
- -
-
- Valve: -
-
- {{:helper.link(data.on? 'Unlocked' : 'Closed', null, {'toggle_valve' : 1})}} -
-
- -
-
- Pressure Regulation: -
-
- {{:helper.link('Off', null, {'regulate_mode' : 'off'}, data.regulate_mode == 0? 'selected' : null)}} - {{:helper.link('Input', null, {'regulate_mode' : 'input'}, data.regulate_mode == 1? 'selected' : null)}} - {{:helper.link('Output', null, {'regulate_mode' : 'output'}, data.regulate_mode == 2? 'selected' : null)}} -
-
- -
-
- Target Pressure: -
-
-
- {{:helper.link('MAX', null, {'set_press' : 'max'}, null)}} - {{:helper.link('SET', null, {'set_press' : 'set'}, null)}} -
 {{:(data.pressure_set/100)}} kPa 
-
-
-
- -
-
- Flow Rate Limit: -
-
-
- {{:helper.link('MAX', null, {'set_flow_rate' : 'max'}, null)}} - {{:helper.link('SET', null, {'set_flow_rate' : 'set'}, null)}} -
 {{:(data.set_flow_rate/10)}} L/s 
-
-
-
\ No newline at end of file diff --git a/nano/templates/radio_basic.tmpl b/nano/templates/radio_basic.tmpl deleted file mode 100644 index 6cfbb6dc7a5..00000000000 --- a/nano/templates/radio_basic.tmpl +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - -{{if data.useSyndMode}} - {{:helper.syndicateMode()}} -{{/if}} - -
-
- Microphone -
-
- {{if data.mic_cut}} - {{:helper.link('On', null, null, 'disabled')}} - {{:helper.link('Off', null, null, 'disabled')}} - {{else}} - {{:helper.link('On', null, {'talk' : 0}, data.mic_status ? 'selected' : null)}} - {{:helper.link('Off', null, {'talk' : 1}, data.mic_status ? null : 'selected')}} - {{/if}} -
-
- -
-
- Speaker -
-
- {{if data.spk_cut}} - {{:helper.link('On', null, null, 'disabled')}} - {{:helper.link('Off', null, null, 'disabled')}} - {{else}} - {{:helper.link('On', null, {'listen' : 0}, data.speaker ? 'selected' : null)}} - {{:helper.link('Off', null, {'listen' : 1}, data.speaker ? null : 'selected')}} - {{/if}} -
-
- -{{if data.has_subspace}} -
-
- Subspace Transmission: -
-
- {{:helper.link('On', null, {'mode' : 1}, data.subspace ? 'selected' : null)}} - {{:helper.link('Off', null, {'mode' : 0}, data.subspace ? null : 'selected')}} -
-
-{{/if}} - -{{if data.has_loudspeaker}} -
-
- Loudspeaker: -
-
- {{:helper.link('On', null, {'shutup' : 0}, data.loudspeaker ? 'selected' : null)}} - {{:helper.link('Off', null, {'shutup' : 1}, data.loudspeaker ? null : 'selected')}} -
-
-{{/if}} - -
-
- Frequency: {{:data.freq}} -
-
- {{:helper.link('--', null, {'freq' : -10})}} - {{:helper.link('-', null, {'freq' : -2})}} - {{:helper.link('+', null, {'freq' : 2})}} - {{:helper.link('++', null, {'freq' : 10})}} -
-
- -{{if data.chan_list_len >= 1}} -

Channels

-
- {{for data.chan_list}} -
- {{:value.display_name}} -
-
- {{if value.secure_channel}} - {{:helper.link('On', null, {'ch_name' : value.chan, 'listen' : value.sec_channel_listen}, value.sec_channel_listen ? null : 'selected')}} - {{:helper.link('Off', null, {'ch_name' : value.chan, 'listen' : value.sec_channel_listen}, value.sec_channel_listen ? 'selected' : null)}} - {{else}} - {{:helper.link('Switch', null, {'spec_freq' : value.chan}, data.rawfreq == value.chan ? 'selected' : null)}} - {{/if}} -
- {{/for}} -{{/if}} diff --git a/nano/templates/rcon.tmpl b/nano/templates/rcon.tmpl deleted file mode 100644 index e16062aec4d..00000000000 --- a/nano/templates/rcon.tmpl +++ /dev/null @@ -1,73 +0,0 @@ - -
{{:helper.link('Show/Hide SMES readings', 'folder', { 'hide_smes' : 1})}} -
{{:helper.link('Show/Hide SMES controls', 'folder', { 'hide_smes_details' : 1})}} -
{{:helper.link('Show/Hide Breaker readings', 'folder', { 'hide_breakers' : 1})}} -
-{{if data.hide_smes}} - SMES readings hidden.
-{{else}} - Detected SMES units with RCON support:
- {{for data.smes_info}} -
-
- {{:value.RCON_tag}} -
-
- -
- {{if value.charge > 50}} - {{:helper.displayBar(value.charge, 0, 100, 'good')}} - {{else value.charge > 25}} - {{:helper.displayBar(value.charge, 0, 100, 'average')}} - {{else}} - {{:helper.displayBar(value.charge, 0, 100, 'bad')}} - {{/if}} -
- {{:value.charge}}%
-
- {{if !data.hide_smes_details}} -
- Input: {{:value.input_val}} kW - {{:value.input_set ? "AUTO" : "OFF"}} - - {{:helper.link('', 'power', { 'smes_in_toggle' : value.RCON_tag})}} - {{:helper.link('', 'pencil', { 'smes_in_set' : value.RCON_tag})}} -
- Output: {{:value.output_val}} kW - {{:value.output_set ? "ONLINE" : "OFFLINE"}} - - {{:helper.link('', 'power', { 'smes_out_toggle' : value.RCON_tag})}} - {{:helper.link('', 'pencil', { 'smes_out_set' : value.RCON_tag})}} - -
- Output Load: - - {{:value.output_load}} kW - {{/if}} -
-
-
- {{empty}} - No connected SMES units detected!
- {{/for}} -{{/if}} -{{if data.hide_breakers}} - Breaker readings hidden.
-{{else}} - Detected Breaker Boxes with RCON support:
- {{for data.breaker_info}} -
-
- {{:value.RCON_tag}} -
-
- -
- {{:value.enabled ? "[ENABLED]" : "[DISABLED]"}} - - {{:helper.link('', 'power', {'toggle_breaker' : value.RCON_tag})}} -
-
-
- {{empty}} - No connected Breaker Boxes detected! - {{/for}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/sec_camera.tmpl b/nano/templates/sec_camera.tmpl deleted file mode 100644 index 21ecea71e78..00000000000 --- a/nano/templates/sec_camera.tmpl +++ /dev/null @@ -1,37 +0,0 @@ - -{{if data.map_levels.length}} - {{:helper.link('Show Map', 'pin-s', {'showMap' : 1})}} -{{/if}} -{{:helper.link('Reset', 'refresh', {'reset' : 1})}} -
-
-
Current Camera: 
-
- {{if data.current_camera}} -
{{:data.current_camera.name}}
- {{else}} -
None
- {{/if}} -
-
-
-
Networks:
-
-{{for data.networks}} - {{:helper.link(value, '', {'switch_network' : value}, null, data.current_network == value ? 'selected' : null)}} -{{/for}} -
-
Cameras:
-
-{{for data.cameras}} - {{if data.current_camera && value.name == data.current_camera.name}} - {{:helper.link(value.name, '', {'switch_camera' : value.camera}, 'selected')}} - {{else value.deact}} - {{:helper.link(value.name + " (deactivated)", '', {}, 'inactive')}} - {{else}} - {{:helper.link(value.name, '', {'switch_camera' : value.camera})}} - {{/if}} -{{/for}} diff --git a/nano/templates/sec_camera_map_content.tmpl b/nano/templates/sec_camera_map_content.tmpl deleted file mode 100644 index e9369c4b01a..00000000000 --- a/nano/templates/sec_camera_map_content.tmpl +++ /dev/null @@ -1,20 +0,0 @@ - -{{for data.cameras}} - {{if value.z == config.mapZLevel}} -
- {{if data.current && value.name == data.current.name}} - {{:helper.link("#", '', {'switch_camera' : value.camera}, 'selected')}} - {{else value.deact}} - {{:helper.link('#', '', {}, 'inactive')}} - {{else}} - {{:helper.link("#", '', {'switch_camera' : value.camera})}} - {{/if}} - -
- {{/if}} -{{/for}} diff --git a/nano/templates/sec_camera_map_header.tmpl b/nano/templates/sec_camera_map_header.tmpl deleted file mode 100644 index 0281c70cf5d..00000000000 --- a/nano/templates/sec_camera_map_header.tmpl +++ /dev/null @@ -1,38 +0,0 @@ - -{{:helper.link('Show Camera List', 'script', {'showMap' : 0})}} -{{:helper.link('Reset', 'refresh', {'reset' : 1})}} -
-
-
Current Camera: 
- {{if data.current_camera}} -
{{:data.current_camera.name}}
- {{else}} -
None
- {{/if}} -
-
-{{if data.map_levels.length > 1}} -
- Z Level:  - {{for data.map_levels }} - {{:helper.link(value, null, {'mapZLevel' : value}, null, config.mapZLevel == value ? 'selected' : null)}} - {{/for}} -
-{{/if}} -
- Zoom Level:  - - - - -
-
-
-
Networks:
-
-{{for data.networks}} - {{:helper.link(value, '', {'switch_network' : value}, null, data.current_network == value ? 'selected' : null)}} -{{/for}} \ No newline at end of file diff --git a/nano/templates/shutoff_monitor.tmpl b/nano/templates/shutoff_monitor.tmpl deleted file mode 100644 index 2597a1b6f5d..00000000000 --- a/nano/templates/shutoff_monitor.tmpl +++ /dev/null @@ -1,13 +0,0 @@ -

Automated Shutoff Valve Monitoring Console

-
- -
NamePositionOpenModeActions -{{for data.valves}} -
{{:value.name}} - {{:value.x}}, {{:value.y}}, {{:value.z}} - {{:value.open ? 'Yes' : 'No'}} - {{:value.enabled ? 'Auto' : 'Manual'}} - {{:helper.link(value.open ? 'Close' : 'Open', null, {'toggle_open' : value.ref}, value.enabled ? 'disabled' : null)}} - {{:helper.link(value.enabled ? 'Manual' : 'Auto', null, {'toggle_enable' : value.ref})}} -{{/for}} -
\ No newline at end of file diff --git a/nano/templates/simple_airlock_console.tmpl b/nano/templates/simple_airlock_console.tmpl deleted file mode 100644 index ca49b20f6ae..00000000000 --- a/nano/templates/simple_airlock_console.tmpl +++ /dev/null @@ -1,36 +0,0 @@ -
-
-
- Chamber Pressure: -
-
- {{:helper.displayBar(data.chamber_pressure, 0, 200, (data.chamber_pressure < 80) || (data.chamber_pressure > 120) ? 'bad' : (data.chamber_pressure < 95) || (data.chamber_pressure > 110) ? 'average' : 'good')}} -
- {{:data.chamber_pressure}} kPa -
-
-
-
-
-
-
- {{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, data.processing ? 'disabled' : null)}} - {{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, data.processing ? 'disabled' : null)}} -
-
- {{if data.interior_status.state == "open"}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, 'redButton')}} - {{else}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, data.processing ? 'yellowButton' : null)}} - {{/if}} - {{if data.exterior_status.state == "open"}} - {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, 'redButton')}} - {{else}} - {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, data.processing ? 'yellowButton' : null)}} - {{/if}} -
-
-
- {{:helper.link('Abort', 'cancel', {'command' : 'abort'}, data.processing ? null : 'disabled', data.processing ? 'redButton' : null)}} -
-
\ No newline at end of file diff --git a/nano/templates/simple_docking_console.tmpl b/nano/templates/simple_docking_console.tmpl deleted file mode 100644 index 73c8ff8e3e1..00000000000 --- a/nano/templates/simple_docking_console.tmpl +++ /dev/null @@ -1,99 +0,0 @@ -
-
-
- Docking Port Status: -
-
- {{if data.docking_status == "docked"}} - {{if !data.override_enabled}} - DOCKED - {{else}} - DOCKED-OVERRIDE ENABLED - {{/if}} - {{else data.docking_status == "docking"}} - {{if !data.override_enabled}} - DOCKING - {{else}} - DOCKING-OVERRIDE ENABLED - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.override_enabled}} - UNDOCKING - {{else}} - UNDOCKING-OVERRIDE ENABLED - {{/if}} - {{else data.docking_status == "undocked"}} - {{if !data.override_enabled}} - NOT IN USE - {{else}} - OVERRIDE ENABLED - {{/if}} - {{else}} - ERROR - {{/if}} -
-
-
-
-
-
- Docking Hatch: -
-
- {{if data.docking_status == "docked"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed"}} - CLOSED - {{else}} - ERROR - {{/if}} - {{else data.docking_status == "docking"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed" && data.door_lock == "locked"}} - SECURED - {{else data.door_state == "closed" && data.door_lock == "unlocked"}} - UNSECURED - {{else}} - ERROR - {{/if}} - {{else data.docking_status == "undocking"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed" && data.door_lock == "locked"}} - SECURED - {{else data.door_state == "closed" && data.door_lock == "unlocked"}} - UNSECURED - {{else}} - ERROR - {{/if}} - {{else data.docking_status == "undocked"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed" && data.door_lock == "locked"}} - SECURED - {{else data.door_state == "closed" && data.door_lock == "unlocked"}} - UNSECURED - {{else}} - ERROR - {{/if}} - {{else}} - ERROR - {{/if}} -
-
-
-
-
-
- {{if data.docking_status == "docked"}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', null)}} - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : null)}} - {{else}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redButton' : null)}} - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : 'yellowButton')}} - {{/if}} -
-
-
\ No newline at end of file diff --git a/nano/templates/simple_docking_console_pod.tmpl b/nano/templates/simple_docking_console_pod.tmpl deleted file mode 100644 index 07f055ea2cc..00000000000 --- a/nano/templates/simple_docking_console_pod.tmpl +++ /dev/null @@ -1,101 +0,0 @@ -
-
-
- Docking Port Status: -
-
- {{if data.docking_status == "docked"}} - {{if !data.override_enabled}} - DOCKED - {{else}} - DOCKED-OVERRIDE ENABLED - {{/if}} - {{else data.docking_status == "docking"}} - {{if !data.override_enabled}} - DOCKING - {{else}} - DOCKING-OVERRIDE ENABLED - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.override_enabled}} - UNDOCKING - {{else}} - UNDOCKING-OVERRIDE ENABLED - {{/if}} - {{else data.docking_status == "undocked"}} - {{if !data.override_enabled}} - NOT IN USE - {{else}} - OVERRIDE ENABLED - {{/if}} - {{else}} - ERROR - {{/if}} -
-
-
-
-
-
- Docking Hatch: -
-
- {{if data.docking_status == "docked"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed"}} - CLOSED - {{else}} - ERROR - {{/if}} - {{else data.docking_status == "docking"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed" && data.door_lock == "locked"}} - SECURED - {{else data.door_state == "closed" && data.door_lock == "unlocked"}} - UNSECURED - {{else}} - ERROR - {{/if}} - {{else data.docking_status == "undocking"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed" && data.door_lock == "locked"}} - SECURED - {{else data.door_state == "closed" && data.door_lock == "unlocked"}} - UNSECURED - {{else}} - ERROR - {{/if}} - {{else data.docking_status == "undocked"}} - {{if data.door_state == "open"}} - OPEN - {{else data.door_state == "closed" && data.door_lock == "locked"}} - SECURED - {{else data.door_state == "closed" && data.door_lock == "unlocked"}} - UNSECURED - {{else}} - ERROR - {{/if}} - {{else}} - ERROR - {{/if}} -
-
-
-
-
-
- {{if data.docking_status == "docked"}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', null)}} - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : null)}} - {{:helper.link('MANUAL EJECT', 'alert', {'command' : 'toggle_override'}, 'disabled', null)}} - {{else}} - {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redButton' : null)}} - {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redButton' : 'yellowButton')}} - {{:helper.link('MANUAL EJECT', 'alert', {'command' : 'toggle_override'}, data.can_force ? null : 'disabled', data.can_force ? 'redButton' : null)}} - {{/if}} -
-
-
\ No newline at end of file diff --git a/nano/templates/sleeper.tmpl b/nano/templates/sleeper.tmpl deleted file mode 100644 index 885a1c025c1..00000000000 --- a/nano/templates/sleeper.tmpl +++ /dev/null @@ -1,102 +0,0 @@ -

Sleeper

-{{if !data.power}} -
-
- NO POWER -
- {{if data.occupant}} -
- {{:helper.link("Eject occupant", null, {'eject' : 0})}} -
- {{/if}} -{{else}} - {{if data.occupant}} -
-
- Occupant status: -
-
- Health: {{:helper.round(data.health / data.maxHealth)*100}}% ({{:data.stat}}). -
-
- Pulse: -
-
- {{:data.pulse}} -
-
- Brute damage: -
-
- {{:helper.displayBar(data.brute, 0, 100, (data.brute <= 25) ? 'good' : (data.brute <= 50) ? 'average' : 'bad')}}{{:helper.round(data.brute)}} -
-
- Burn severity: -
-
- {{:helper.displayBar(data.burn, 0, 100, (data.burn <= 25) ? 'good' : (data.burn <= 50) ? 'average' : 'bad')}}{{:helper.round(data.burn)}} -
-
- Respiratory damage: -
-
- {{:helper.displayBar(data.oxy, 0, 100, (data.oxy <= 25) ? 'good' : (data.oxy <= 50) ? 'average' : 'bad')}}{{:helper.round(data.oxy)}} -
-
- Toxin content: -
-
- {{:helper.displayBar(data.tox, 0, 100, (data.tox <= 25) ? 'good' : (data.tox <= 50) ? 'average' : 'bad')}}{{:helper.round(data.tox)}} -
-
- {{:helper.link(data.filtering ? "Dialysis active" : "Dialysis inactive", null, {'sleeper_filter' : !data.filtering})}} -
-
- {{:helper.link(data.pump ? "Stomach pump active" : "Stomach pump inactive", null, {'pump' : !data.pump})}} -
-
- {{:helper.link("Eject occupant", null, {'eject' : 0})}} -
-
- {{else}} -
- No occupant. -
- {{/if}} -
- {{for data.reagents}} -
- {{:value.name}} -
-
- {{if data.occupant}}Occupant: {{:value.amount}} units{{/if}} - {{:helper.link('Inject 5', null, {'chemical' : value.id, 'amount' : 5}, data.occupant ? null : 'disabled')}}{{:helper.link('Inject 10', null, {'chemical' : value.id, 'amount' : 10}, data.occupant ? null : 'disabled')}} -
- {{/for}} -
- {{if data.beaker != -1}} -
-
- Beaker: -
-
- {{:data.beaker}} units of free space remaining. - {{:helper.link("Eject", null, {'beaker' : 0})}} -
-
- {{else}} -
-
- No beaker inserted. -
-
- {{/if}} -
-
- Stasis Level: -
-
- {{:helper.link(data.stasis, null, {'change_stasis' : 1})}} -
-
-{{/if}} diff --git a/nano/templates/sleever.tmpl b/nano/templates/sleever.tmpl deleted file mode 100644 index 89b41551a1b..00000000000 --- a/nano/templates/sleever.tmpl +++ /dev/null @@ -1,170 +0,0 @@ -{{if data.coredumped}} -
- TransCore dump complete. Disk ejected. -
-{{else data.emergency}} -
- !!WARNING!!
Dump Disk Inserted! This will transfer all minds to the dump disk, and the TransCore will be made unusable until post-shift maintenance! This should only be used in emergencies!

-
- {{:helper.link('DUMP CORE', 'radiation', {'coredump' : data.emergency}, null, 'redButton')}} - {{:helper.link('Eject Disk', 'eject', {'ejectdisk' : data.emergency})}} -{{else}} - {{:data.temp}} - - - {{if data.menu == 1}} -

Resleeving Control

-
-
- -
- {{if data.podsLen > 0}} - {{:data.podsLen}} growing vats found. - {{/if}} -
- -
- {{if data.spodsLen > 0}} - {{:data.spodsLen}} SyntFabs found. - {{/if}} -
- -
- {{if data.sleeversLen > 0}} - {{:data.sleeversLen}} resleeving pods found. - {{/if}} -
- - {{if data.podsLen}} - {{for data.pods}} -
{{:value.pod}}, biomass: {{:value.biomass}}
- {{/for}} - {{/if}} - - {{if data.spodsLen}} - {{for data.spods}} -
{{:value.spod}}, S/G: {{:value.steel}}/{{:value.glass}}
- {{/for}} - {{/if}} - - {{if data.sleeversLen}} - {{for data.sleevers}} -
{{:value.sleever}}, occupant: {{:value.occupant}}
- {{/for}} - {{/if}} - - -

Database Functions

-
- {{:helper.link('View Body Records', 'list', {'menu' : 2})}} -
-
- {{:helper.link('View Mind Records', 'list', {'menu' : 3})}} -
- - - {{else data.menu == 2}} -

Current body records

- {{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 1})}} -
- {{for data.bodyrecords}} - {{:helper.link(value.name, 'document', {'view_brec' : value.recref})}} - {{/for}} -
- - - {{else data.menu == 3}} -

Current mind records

- {{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 1})}} -
- {{for data.mindrecords}} - {{:helper.link(value.name, 'document', {'view_mrec' : value.recref})}} - {{/for}} -
- - - {{else data.menu == 4}} -

Selected Body Record

-
{{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 2})}}
- - {{if data.activeBodyRecord}} -
-
Name:
-
{{:data.activeBodyRecord.real_name}}
-
-
-
Species:
-
{{:data.activeBodyRecord.speciesname}}
-
-
-
Bio. Sex:
-
{{:data.activeBodyRecord.gender}}
-
-
-
Mind compat.:
-
{{:data.activeBodyRecord.locked}}
-
-
-
Synthetic:
-
{{:data.activeBodyRecord.synthetic}}
-
-
-
OOC Notes:
-
{{:helper.link('View', null, {'boocnotes' : data.activeBodyRecord.booc}, data.activeBodyRecord.booc ? null : 'linkOff')}}
-
- - {{:helper.link('Create', 'play', {'create' : data.activeBodyRecord.real_name}, data.activeBodyRecord.cando ? null : 'linkOff')}} - - {{else}} -
ERROR: Record not found.
- {{/if}} - - - {{else data.menu == 5}} -

Selected Mind Record

-
{{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 3})}}
- - {{if data.activeMindRecord}} -
-
Name:
-
{{:data.activeMindRecord.charname}}
-
-
-
Backup Status:
-
{{:data.activeMindRecord.obviously_dead}}
-
-
-
OOC Notes:
-
{{:helper.link('View', null, {'moocnotes' : data.activeMindRecord.mooc}, data.activeMindRecord.mooc ? null : 'linkOff')}}
-
- {{:helper.link('Sleeve', 'play', {'sleeve' : 1}, data.activeMindRecord.cando ? null : 'linkOff')}} - {{:helper.link('Card', 'play', {'sleeve' : 2}, data.activeMindRecord.cando ? null : 'linkOff')}} - - {{else}} -
ERROR: Record not found.
- {{/if}} - - - {{else data.menu == 6}} -

Body OOC Notes (This is OOC!)

-
{{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 4})}}
- {{if data.activeBodyRecord}} -
Notes:
-
{{:data.activeBodyRecord.booc}}
- {{else}} -
ERROR: Record not found.
- {{/if}} - - - {{else data.menu == 7}} -

Mind OOC Notes (This is OOC!)

-
{{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 5})}}
- {{if data.activeMindRecord}} -
Notes:
-
{{:data.activeMindRecord.mooc}}
- {{else}} -
ERROR: Record not found.
- {{/if}} - - {{/if}} -{{/if}} \ No newline at end of file diff --git a/nano/templates/smartfridge.tmpl b/nano/templates/smartfridge.tmpl deleted file mode 100644 index cc25d760ce0..00000000000 --- a/nano/templates/smartfridge.tmpl +++ /dev/null @@ -1,36 +0,0 @@ -
- {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}} -
- -
-

Storage

- {{if data.secure}} - - {{:data.locked == -1 ? "Sec.re ACC_** //):securi_nt.diag=>##'or 1=1'%($..." : "Secure Access: Please have your identification ready."}} - - {{/if}} -
-
- {{if data.contents}} - {{for data.contents}} -
- {{:value.display_name}} ({{:value.quantity}} available) -
Vend: 
{{:helper.link('x1', 'circle-arrow-s', { "vend" : value.vend, "amount" : 1 }, null, 'statusValue')}} - {{if value.quantity >= 5}} - {{:helper.link('x5', 'circle-arrow-s', { "vend" : value.vend, "amount" : 5 }, null, 'statusValue')}} - {{/if}} - {{if value.quantity >= 10}} - {{:helper.link('x10', 'circle-arrow-s', { "vend" : value.vend, "amount" : 10 }, null, 'statusValue')}} - {{/if}} - {{if value.quantity >= 25}} - {{:helper.link('x25', 'circle-arrow-s', { "vend" : value.vend, "amount" : 25 }, null, 'statusValue')}} - {{/if}} - {{if value.quantity > 1}} - {{:helper.link('All', 'circle-arrow-s', { "vend" : value.vend, "amount" : value.quantity }, null, 'statusValue')}} - {{/if}} -
- {{/for}} - {{else}} - No products loaded. - {{/if}} -
diff --git a/nano/templates/smes.tmpl b/nano/templates/smes.tmpl deleted file mode 100644 index bdbff2da0e0..00000000000 --- a/nano/templates/smes.tmpl +++ /dev/null @@ -1,104 +0,0 @@ -
-
- Stored Charge: -
-
- {{:helper.displayBar(data.storedCapacity, 0, 100, data.charging ? 'good' : 'average')}} -
- {{:helper.round(data.storedCapacity)}}% -

-
- {{:data.storedCapacityAbs}} kWh / {{:data.storedCapacityMax}} kWh -
-
-
- -

Input Management

-
-
- Charge Mode: -
-
- {{:helper.link('Auto', 'refresh', {'cmode' : 1}, data.chargeMode ? 'selected' : null)}}{{:helper.link('Off', 'close', {'cmode' : 1}, data.chargeMode ? null : 'selected')}} -   - {{if data.charging == 2}} - [Charging] - {{else data.charging == 1}} - [Partially Charging] - {{else}} - [Not Charging] - {{/if}} -
-
- -
-
- Input Level: -
-
- {{:helper.displayBar(data.chargeLevel, 0, data.chargeMax)}} -
- {{:helper.link('MIN', null, {'input' : 'min'}, (data.chargeLevel > 0) ? null : 'disabled')}} - {{:helper.link('SET', null, {'input' : 'set'}, null)}} - {{:helper.link('MAX', null, {'input' : 'max'}, (data.chargeLevel < data.chargeMax) ? null : 'disabled')}} -
 {{:data.chargeLevel}} kW 
-
-
-
- -
-
- Input Load: -
-
- {{:helper.displayBar(data.chargeLoad, 0, data.chargeMax, (data.chargeLoad < data.chargeLevel) ? 'good' : 'average')}} -
- {{:data.chargeLoad}} kW -
-
-
- -

Output Management

-
-
- Output Status: -
-
- {{:helper.link('Online', 'power', {'online' : 1}, data.outputOnline ? 'selected' : null)}}{{:helper.link('Offline', 'close', {'online' : 1}, data.outputOnline ? null : 'selected')}} -   - {{if data.outputting == 2}} - [Outputting] - {{else data.outputting == 1}} - [Stored energy too low] - {{else}} - [Not Outputting] - {{/if}} -
-
- -
-
- Output Level: -
-
- {{:helper.displayBar(data.outputLevel, 0, data.outputMax)}} -
- {{:helper.link('MIN', null, {'output' : 'min'}, (data.outputLevel > 0) ? null : 'disabled')}} - {{:helper.link('SET', null, {'output' : 'set'}, null)}} - {{:helper.link('MAX', null, {'output' : 'max'}, (data.outputLevel < data.outputMax) ? null : 'disabled')}} -
 {{:data.outputLevel}} kW 
-
-
-
- -
-
- Output Load: -
-
- {{:helper.displayBar(data.outputLoad, 0, data.outputMax, (data.outputLoad < data.outputLevel) ? 'good' : 'average')}} -
- {{:data.outputLoad}} kW -
-
-
\ No newline at end of file diff --git a/nano/templates/supermatter_crystal.tmpl b/nano/templates/supermatter_crystal.tmpl deleted file mode 100644 index b06aaae7466..00000000000 --- a/nano/templates/supermatter_crystal.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -{{if data.detonating}} -
-

CRYSTAL DELAMINATING

-

Evacuate area immediately

-
-
-{{else}} -

Crystal Integrity

- {{:helper.displayBar(data.integrity_percentage, 0, 100, (data.integrity_percentage >= 90) ? 'good' : (data.integrity_percentage >= 25) ? 'average' : 'bad')}} - {{:data.integrity_percentage}} % -

Environment

- - Temperature: - - - {{:helper.displayBar(data.ambient_temp, 0, 10000, (data.ambient_temp >= 5000) ? 'bad' : (data.ambient_temp >= 4000) ? 'average' : 'good')}} - {{:data.ambient_temp}} K - - - Pressure: - - - {{:data.ambient_pressure}} kPa - -{{/if}} \ No newline at end of file diff --git a/nano/templates/supermatter_monitor.tmpl b/nano/templates/supermatter_monitor.tmpl deleted file mode 100644 index 1d7bdb7cffd..00000000000 --- a/nano/templates/supermatter_monitor.tmpl +++ /dev/null @@ -1,125 +0,0 @@ -{{if data.active}} - {{:helper.link('Back to Menu', null, {'clear' : 1})}}
-
-
- Core Integrity: -
-
- {{:helper.displayBar(data.SM_integrity, 0, 100, (data.SM_integrity == 100) ? 'good' : (data.SM_integrity >= 50) ? 'average' : 'bad')}} {{:data.SM_integrity}}% -
-
- Relative EER: -
-
- {{if data.SM_power > 300}} - {{:data.SM_power}} MeV/cm3 - {{else data.SM_power > 150}} - {{:data.SM_power}} MeV/cm3 - {{else}} - {{:data.SM_power}} MeV/cm3 - {{/if}} -
-
- Temperature: -
-
- {{if data.SM_ambienttemp > 5000}} - {{:data.SM_ambienttemp}} K - {{else data.SM_ambienttemp > 4000}} - {{:data.SM_ambienttemp}} K - {{else}} - {{:data.SM_ambienttemp}} K - {{/if}} -
-
- Pressure: -
-
- {{if data.SM_ambientpressure > 10000}} - {{:data.SM_ambientpressure}} kPa - {{else data.SM_ambientpressure > 5000}} - {{:data.SM_ambientpressure}} kPa - {{else}} - {{:data.SM_ambientpressure}} kPa - {{/if}} -
-
- Chamber EPR: -
-
- {{if data.SM_EPR > 4}} - {{:data.SM_EPR}} - {{else data.SM_EPR > 2.5}} - {{:data.SM_EPR}} - {{else data.SM_EPR < 1}} - {{:data.SM_EPR}} - {{else}} - {{:data.SM_EPR}} - {{/if}} -
-
-

-
- Gas Composition: -
-
-
-
- O2: -
-
- {{:data.SM_gas_O2}} % -
-
- CO2: -
-
- {{:data.SM_gas_CO2}} % -
-
- N2: -
-
- {{:data.SM_gas_N2}} % -
-
- PH: -
-
- {{:data.SM_gas_PH}} % -
-
- N2O: -
-
- {{:data.SM_gas_N2O}} % -
-
-
-
-{{else}} - {{:helper.link('Refresh', null, {'refresh' : 1})}}
- {{for data.supermatters}} -
-
- Area: -
-
- {{:value.area_name}} - (#{{:value.uid}}) -
-
- Integrity: -
-
- {{:value.integrity}} % -
-
- Options: -
-
- {{:helper.link('View Details', null, {'set' : value.uid})}} -
-
- {{/for}} -{{/if}} diff --git a/nano/templates/tanks.tmpl b/nano/templates/tanks.tmpl deleted file mode 100644 index c9d4e6c335a..00000000000 --- a/nano/templates/tanks.tmpl +++ /dev/null @@ -1,47 +0,0 @@ -{{if data.maskConnected}} -
This tank is connected to a mask.
-{{else}} -
This tank is NOT connected to a mask.
-{{/if}} - -
-
- Tank Pressure: -
-
- {{:helper.displayBar(data.tankPressure, 0, 1013, (data.tankPressure > 200) ? 'good' : ((data.tankPressure > 100) ? 'average' : 'bad'))}} -
- {{:data.tankPressure}} kPa -
-
-
- -
 
- -
-
- Mask Release Pressure: -
-
- {{:helper.displayBar(data.releasePressure, 0, data.maxReleasePressure, (data.releasePressure >= 23) ? null : ((data.releasePressure >= 17) ? 'average' : 'bad'))}} -
- {{:helper.link('-', null, {'dist_p' : -10}, (data.releasePressure > 0) ? null : 'disabled')}} - {{:helper.link('-', null, {'dist_p' : -1}, (data.releasePressure > 0) ? null : 'disabled')}} -
 {{:data.releasePressure}} kPa 
- {{:helper.link('+', null, {'dist_p' : 1}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'dist_p' : 10}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}} - {{:helper.link('Max', null, {'dist_p' : 'max'}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}} - {{:helper.link('Reset', null, {'dist_p' : 'reset'}, (data.releasePressure != data.defaultReleasePressure) ? null : 'disabled')}} -
-
-
- -
-
- Mask Release Valve: -
-
- {{:helper.link('Open', 'unlocked', {'stat' : 1}, (!data.maskConnected) ? 'disabled' : (data.valveOpen ? 'selected' : null))}}{{:helper.link('Close', 'locked', {'stat' : 1}, data.valveOpen ? null : 'selected')}} -
-
- diff --git a/nano/templates/vending_machine.tmpl b/nano/templates/vending_machine.tmpl deleted file mode 100644 index 93d5c1007c9..00000000000 --- a/nano/templates/vending_machine.tmpl +++ /dev/null @@ -1,56 +0,0 @@ - - -{{if data.mode == 0}} -

Items available

-
- {{for data.products}} -
-
- {{if value.price > 0}} - {{:helper.link('Buy (' + value.price + ')', 'cart', { "vend" : value.key }, value.amount > 0 ? null : 'disabled')}} - {{else}} - {{:helper.link('Vend', 'circle-arrow-s', { "vend" : value.key }, value.amount > 0 ? null : 'disabled')}} - {{/if}} -
-
- {{if value.color}}{{:value.name}} - {{else}}{{:value.name}} - {{/if}} - ({{:value.amount ? value.amount : "NONE LEFT"}}) -
-
- {{empty}} - No items available! - {{/for}} -
-{{if data.coin}} -

Coin

-
-
Coin deposited:
-
{{:helper.link(data.coin, 'eject', {'remove_coin' : 1})}}
-
-{{/if}} -{{else data.mode == 1}} -

Item selected

-
-
-
Item selected:
{{:data.product}}
-
Charge:
{{:data.price}}
-
-
- {{if data.message_err}} {{/if}} {{:data.message}} -
-
- {{:helper.link('Cancel', 'arrowreturn-1-w', {'cancelpurchase' : 1})}} -
-
-{{/if}} -{{if data.panel}} -

Maintenance panel

-
-
Speaker
{{:helper.link(data.speaker ? 'Enabled' : 'Disabled', 'gear', {'togglevoice' : 1})}}
-
-{{/if}} \ No newline at end of file diff --git a/sound/ambience/foreboding/foreboding1.ogg b/sound/ambience/foreboding/foreboding1.ogg index b6e65c0bf62..be3cf1b7032 100644 Binary files a/sound/ambience/foreboding/foreboding1.ogg and b/sound/ambience/foreboding/foreboding1.ogg differ diff --git a/sound/ambience/foreboding/foreboding2.ogg b/sound/ambience/foreboding/foreboding2.ogg index dde64a9858f..9562178a2be 100644 Binary files a/sound/ambience/foreboding/foreboding2.ogg and b/sound/ambience/foreboding/foreboding2.ogg differ diff --git a/sound/ambience/foreboding/foreboding3.ogg b/sound/ambience/foreboding/foreboding3.ogg new file mode 100644 index 00000000000..4214afd9b8b Binary files /dev/null and b/sound/ambience/foreboding/foreboding3.ogg differ diff --git a/sound/ambience/foreboding/foreboding4.ogg b/sound/ambience/foreboding/foreboding4.ogg new file mode 100644 index 00000000000..2a8177f274d Binary files /dev/null and b/sound/ambience/foreboding/foreboding4.ogg differ diff --git a/sound/ambience/foreboding/foreboding5.ogg b/sound/ambience/foreboding/foreboding5.ogg new file mode 100644 index 00000000000..604a013a5e2 Binary files /dev/null and b/sound/ambience/foreboding/foreboding5.ogg differ diff --git a/sound/ambience/maintenance/maintenance6.ogg b/sound/ambience/foreboding/foreboding6.ogg similarity index 100% rename from sound/ambience/maintenance/maintenance6.ogg rename to sound/ambience/foreboding/foreboding6.ogg diff --git a/sound/ambience/maintenance/maintenance1.ogg b/sound/ambience/maintenance/maintenance1.ogg index be3cf1b7032..0c18c46af68 100644 Binary files a/sound/ambience/maintenance/maintenance1.ogg and b/sound/ambience/maintenance/maintenance1.ogg differ diff --git a/sound/ambience/maintenance/maintenance2.ogg b/sound/ambience/maintenance/maintenance2.ogg index 9562178a2be..655d940cda9 100644 Binary files a/sound/ambience/maintenance/maintenance2.ogg and b/sound/ambience/maintenance/maintenance2.ogg differ diff --git a/sound/ambience/maintenance/maintenance3.ogg b/sound/ambience/maintenance/maintenance3.ogg index 4214afd9b8b..9891916010e 100644 Binary files a/sound/ambience/maintenance/maintenance3.ogg and b/sound/ambience/maintenance/maintenance3.ogg differ diff --git a/sound/ambience/maintenance/maintenance4.ogg b/sound/ambience/maintenance/maintenance4.ogg index 2a8177f274d..1d01e2016ca 100644 Binary files a/sound/ambience/maintenance/maintenance4.ogg and b/sound/ambience/maintenance/maintenance4.ogg differ diff --git a/sound/ambience/maintenance/maintenance5.ogg b/sound/ambience/maintenance/maintenance5.ogg index 604a013a5e2..7a065ecbcb3 100644 Binary files a/sound/ambience/maintenance/maintenance5.ogg and b/sound/ambience/maintenance/maintenance5.ogg differ diff --git a/sound/ambience/old_foreboding/foreboding1.ogg b/sound/ambience/old_foreboding/foreboding1.ogg new file mode 100644 index 00000000000..b6e65c0bf62 Binary files /dev/null and b/sound/ambience/old_foreboding/foreboding1.ogg differ diff --git a/sound/ambience/old_foreboding/foreboding2.ogg b/sound/ambience/old_foreboding/foreboding2.ogg new file mode 100644 index 00000000000..dde64a9858f Binary files /dev/null and b/sound/ambience/old_foreboding/foreboding2.ogg differ diff --git a/sound/arcade/Ori_begin.ogg b/sound/arcade/Ori_begin.ogg new file mode 100644 index 00000000000..2e8f2d262bc Binary files /dev/null and b/sound/arcade/Ori_begin.ogg differ diff --git a/sound/arcade/Ori_fail.ogg b/sound/arcade/Ori_fail.ogg new file mode 100644 index 00000000000..7347c6f02c4 Binary files /dev/null and b/sound/arcade/Ori_fail.ogg differ diff --git a/sound/arcade/Ori_win.ogg b/sound/arcade/Ori_win.ogg new file mode 100644 index 00000000000..14dd7888c40 Binary files /dev/null and b/sound/arcade/Ori_win.ogg differ diff --git a/sound/arcade/boom.ogg b/sound/arcade/boom.ogg new file mode 100644 index 00000000000..8adfb2bc430 Binary files /dev/null and b/sound/arcade/boom.ogg differ diff --git a/sound/arcade/explo.ogg b/sound/arcade/explo.ogg new file mode 100644 index 00000000000..d99132a26a2 Binary files /dev/null and b/sound/arcade/explo.ogg differ diff --git a/sound/arcade/get_fuel.ogg b/sound/arcade/get_fuel.ogg new file mode 100644 index 00000000000..57ed7dd137f Binary files /dev/null and b/sound/arcade/get_fuel.ogg differ diff --git a/sound/arcade/heal.ogg b/sound/arcade/heal.ogg new file mode 100644 index 00000000000..26f47195c65 Binary files /dev/null and b/sound/arcade/heal.ogg differ diff --git a/sound/arcade/hit.ogg b/sound/arcade/hit.ogg new file mode 100644 index 00000000000..0bf18679a65 Binary files /dev/null and b/sound/arcade/hit.ogg differ diff --git a/sound/arcade/kill_crew.ogg b/sound/arcade/kill_crew.ogg new file mode 100644 index 00000000000..e72533200dc Binary files /dev/null and b/sound/arcade/kill_crew.ogg differ diff --git a/sound/arcade/lose.ogg b/sound/arcade/lose.ogg new file mode 100644 index 00000000000..dd2145737cd Binary files /dev/null and b/sound/arcade/lose.ogg differ diff --git a/sound/arcade/lose_fuel.ogg b/sound/arcade/lose_fuel.ogg new file mode 100644 index 00000000000..9ac5e98db39 Binary files /dev/null and b/sound/arcade/lose_fuel.ogg differ diff --git a/sound/arcade/mana.ogg b/sound/arcade/mana.ogg new file mode 100644 index 00000000000..7f26ae53fe7 Binary files /dev/null and b/sound/arcade/mana.ogg differ diff --git a/sound/arcade/raid.ogg b/sound/arcade/raid.ogg new file mode 100644 index 00000000000..135a013fb0b Binary files /dev/null and b/sound/arcade/raid.ogg differ diff --git a/sound/arcade/steal.ogg b/sound/arcade/steal.ogg new file mode 100644 index 00000000000..9c7b3be2a5a Binary files /dev/null and b/sound/arcade/steal.ogg differ diff --git a/sound/arcade/win.ogg b/sound/arcade/win.ogg new file mode 100644 index 00000000000..27fb9725f20 Binary files /dev/null and b/sound/arcade/win.ogg differ diff --git a/sound/effects/mob_effects/tesharisneeze.ogg b/sound/effects/mob_effects/tesharisneeze.ogg index f7428654647..b344bbcff96 100644 Binary files a/sound/effects/mob_effects/tesharisneeze.ogg and b/sound/effects/mob_effects/tesharisneeze.ogg differ diff --git a/sound/machines/blastdoorclose.ogg b/sound/machines/blastdoorclose.ogg new file mode 100644 index 00000000000..c48a0bd7d6f Binary files /dev/null and b/sound/machines/blastdoorclose.ogg differ diff --git a/sound/machines/blastdooropen.ogg b/sound/machines/blastdooropen.ogg new file mode 100644 index 00000000000..4f61ea2302a Binary files /dev/null and b/sound/machines/blastdooropen.ogg differ diff --git a/sound/machines/fryer/deep_fryer_1.ogg b/sound/machines/fryer/deep_fryer_1.ogg index 7b726c9de6f..ee7a748667f 100644 Binary files a/sound/machines/fryer/deep_fryer_1.ogg and b/sound/machines/fryer/deep_fryer_1.ogg differ diff --git a/sound/machines/fryer/deep_fryer_2.ogg b/sound/machines/fryer/deep_fryer_2.ogg index 4bd4be7d772..b423f44229c 100644 Binary files a/sound/machines/fryer/deep_fryer_2.ogg and b/sound/machines/fryer/deep_fryer_2.ogg differ diff --git a/sound/machines/fryer/deep_fryer_emerge.ogg b/sound/machines/fryer/deep_fryer_emerge.ogg index a803dd4c677..4fb29de1c10 100644 Binary files a/sound/machines/fryer/deep_fryer_emerge.ogg and b/sound/machines/fryer/deep_fryer_emerge.ogg differ diff --git a/sound/machines/fryer/deep_fryer_immerse.ogg b/sound/machines/fryer/deep_fryer_immerse.ogg index 3c06b865caa..76960ec664c 100644 Binary files a/sound/machines/fryer/deep_fryer_immerse.ogg and b/sound/machines/fryer/deep_fryer_immerse.ogg differ diff --git a/sound/machines/hatch_open.ogg b/sound/machines/hatch_open.ogg new file mode 100644 index 00000000000..142248416c1 Binary files /dev/null and b/sound/machines/hatch_open.ogg differ diff --git a/sound/machines/rig/rigdown.ogg b/sound/machines/rig/rigdown.ogg new file mode 100644 index 00000000000..21207573322 Binary files /dev/null and b/sound/machines/rig/rigdown.ogg differ diff --git a/sound/machines/rig/rigerror.ogg b/sound/machines/rig/rigerror.ogg new file mode 100644 index 00000000000..909d6a19e2f Binary files /dev/null and b/sound/machines/rig/rigerror.ogg differ diff --git a/sound/machines/rig/rigonline.ogg b/sound/machines/rig/rigonline.ogg new file mode 100644 index 00000000000..dae104f9656 Binary files /dev/null and b/sound/machines/rig/rigonline.ogg differ diff --git a/sound/machines/rig/rigservo.ogg b/sound/machines/rig/rigservo.ogg new file mode 100644 index 00000000000..3193acaff44 Binary files /dev/null and b/sound/machines/rig/rigservo.ogg differ diff --git a/sound/machines/rig/rigstarted.ogg b/sound/machines/rig/rigstarted.ogg new file mode 100644 index 00000000000..d7bb9716f42 Binary files /dev/null and b/sound/machines/rig/rigstarted.ogg differ diff --git a/sound/machines/rig/rigstep.ogg b/sound/machines/rig/rigstep.ogg new file mode 100644 index 00000000000..02d3eff5125 Binary files /dev/null and b/sound/machines/rig/rigstep.ogg differ diff --git a/sound/machines/shower/shower_end.ogg b/sound/machines/shower/shower_end.ogg index 80b93af39eb..4ab4479a06e 100644 Binary files a/sound/machines/shower/shower_end.ogg and b/sound/machines/shower/shower_end.ogg differ diff --git a/sound/machines/shower/shower_mid1.ogg b/sound/machines/shower/shower_mid1.ogg index e1ae5a0c456..3e35ac57af7 100644 Binary files a/sound/machines/shower/shower_mid1.ogg and b/sound/machines/shower/shower_mid1.ogg differ diff --git a/sound/machines/shower/shower_mid2.ogg b/sound/machines/shower/shower_mid2.ogg index 4a54acd3524..66da790cb15 100644 Binary files a/sound/machines/shower/shower_mid2.ogg and b/sound/machines/shower/shower_mid2.ogg differ diff --git a/sound/machines/shower/shower_mid3.ogg b/sound/machines/shower/shower_mid3.ogg index 8b4776a9b97..0c03ce6e435 100644 Binary files a/sound/machines/shower/shower_mid3.ogg and b/sound/machines/shower/shower_mid3.ogg differ diff --git a/sound/machines/shower/shower_start.ogg b/sound/machines/shower/shower_start.ogg index e5529f401bb..9fb6aa22aae 100644 Binary files a/sound/machines/shower/shower_start.ogg and b/sound/machines/shower/shower_start.ogg differ diff --git a/sound/machines/terminal_alert.ogg b/sound/machines/terminal_alert.ogg new file mode 100644 index 00000000000..a790c03ebdf Binary files /dev/null and b/sound/machines/terminal_alert.ogg differ diff --git a/sound/machines/terminal_button01.ogg b/sound/machines/terminal_button01.ogg new file mode 100644 index 00000000000..88b10c88912 Binary files /dev/null and b/sound/machines/terminal_button01.ogg differ diff --git a/sound/machines/terminal_button02.ogg b/sound/machines/terminal_button02.ogg new file mode 100644 index 00000000000..8b30fd892ee Binary files /dev/null and b/sound/machines/terminal_button02.ogg differ diff --git a/sound/machines/terminal_button03.ogg b/sound/machines/terminal_button03.ogg new file mode 100644 index 00000000000..7a00168cfc3 Binary files /dev/null and b/sound/machines/terminal_button03.ogg differ diff --git a/sound/machines/terminal_button04.ogg b/sound/machines/terminal_button04.ogg new file mode 100644 index 00000000000..c56b23919cc Binary files /dev/null and b/sound/machines/terminal_button04.ogg differ diff --git a/sound/machines/terminal_button05.ogg b/sound/machines/terminal_button05.ogg new file mode 100644 index 00000000000..e660ecf154c Binary files /dev/null and b/sound/machines/terminal_button05.ogg differ diff --git a/sound/machines/terminal_button06.ogg b/sound/machines/terminal_button06.ogg new file mode 100644 index 00000000000..bef143ac521 Binary files /dev/null and b/sound/machines/terminal_button06.ogg differ diff --git a/sound/machines/terminal_button07.ogg b/sound/machines/terminal_button07.ogg new file mode 100644 index 00000000000..91a31a1156a Binary files /dev/null and b/sound/machines/terminal_button07.ogg differ diff --git a/sound/machines/terminal_button08.ogg b/sound/machines/terminal_button08.ogg new file mode 100644 index 00000000000..fc0131f5f4e Binary files /dev/null and b/sound/machines/terminal_button08.ogg differ diff --git a/sound/machines/terminal_insert_disc.ogg b/sound/machines/terminal_insert_disc.ogg new file mode 100644 index 00000000000..dd226c1ebde Binary files /dev/null and b/sound/machines/terminal_insert_disc.ogg differ diff --git a/sound/machines/terminal_off.ogg b/sound/machines/terminal_off.ogg new file mode 100644 index 00000000000..90da8d75daf Binary files /dev/null and b/sound/machines/terminal_off.ogg differ diff --git a/sound/machines/terminal_on.ogg b/sound/machines/terminal_on.ogg new file mode 100644 index 00000000000..3c69d85de54 Binary files /dev/null and b/sound/machines/terminal_on.ogg differ diff --git a/sound/machines/terminal_prompt.ogg b/sound/machines/terminal_prompt.ogg new file mode 100644 index 00000000000..74de1c9a298 Binary files /dev/null and b/sound/machines/terminal_prompt.ogg differ diff --git a/sound/machines/terminal_prompt_confirm.ogg b/sound/machines/terminal_prompt_confirm.ogg new file mode 100644 index 00000000000..897fec28e9a Binary files /dev/null and b/sound/machines/terminal_prompt_confirm.ogg differ diff --git a/sound/machines/terminal_prompt_deny.ogg b/sound/machines/terminal_prompt_deny.ogg new file mode 100644 index 00000000000..fda065f0d46 Binary files /dev/null and b/sound/machines/terminal_prompt_deny.ogg differ diff --git a/sound/machines/turrets/turret_deploy.ogg b/sound/machines/turrets/turret_deploy.ogg new file mode 100644 index 00000000000..0b2376901b6 Binary files /dev/null and b/sound/machines/turrets/turret_deploy.ogg differ diff --git a/sound/machines/turrets/turret_retract.ogg b/sound/machines/turrets/turret_retract.ogg new file mode 100644 index 00000000000..11d1eecad8c Binary files /dev/null and b/sound/machines/turrets/turret_retract.ogg differ diff --git a/sound/machines/turrets/turret_rotate.ogg b/sound/machines/turrets/turret_rotate.ogg new file mode 100644 index 00000000000..8699fa33168 Binary files /dev/null and b/sound/machines/turrets/turret_rotate.ogg differ diff --git a/sound/voice/YeenCackle.ogg b/sound/voice/YeenCackle.ogg new file mode 100644 index 00000000000..56eb52ebe09 Binary files /dev/null and b/sound/voice/YeenCackle.ogg differ diff --git a/sound/voice/gao.ogg b/sound/voice/gao.ogg new file mode 100644 index 00000000000..49d0a296c36 Binary files /dev/null and b/sound/voice/gao.ogg differ diff --git a/sound/voice/medbot/close.ogg b/sound/voice/medbot/close.ogg new file mode 100644 index 00000000000..9e0efcefd20 Binary files /dev/null and b/sound/voice/medbot/close.ogg differ diff --git a/sound/voice/medbot/dont_like.ogg b/sound/voice/medbot/dont_like.ogg new file mode 100644 index 00000000000..06fc84af2fa Binary files /dev/null and b/sound/voice/medbot/dont_like.ogg differ diff --git a/sound/voice/medbot/forgive.ogg b/sound/voice/medbot/forgive.ogg new file mode 100644 index 00000000000..729eaa5c78e Binary files /dev/null and b/sound/voice/medbot/forgive.ogg differ diff --git a/sound/voice/medbot/fuck_you.ogg b/sound/voice/medbot/fuck_you.ogg new file mode 100644 index 00000000000..5eacff615fe Binary files /dev/null and b/sound/voice/medbot/fuck_you.ogg differ diff --git a/sound/voice/medbot/hey_wait.ogg b/sound/voice/medbot/hey_wait.ogg new file mode 100644 index 00000000000..6c88b761ec7 Binary files /dev/null and b/sound/voice/medbot/hey_wait.ogg differ diff --git a/sound/voice/medbot/i_require_asst.ogg b/sound/voice/medbot/i_require_asst.ogg new file mode 100644 index 00000000000..18fabc630f5 Binary files /dev/null and b/sound/voice/medbot/i_require_asst.ogg differ diff --git a/sound/voice/medbot/i_trusted_you.ogg b/sound/voice/medbot/i_trusted_you.ogg new file mode 100644 index 00000000000..602baa2f674 Binary files /dev/null and b/sound/voice/medbot/i_trusted_you.ogg differ diff --git a/sound/voice/medbot/im_different.ogg b/sound/voice/medbot/im_different.ogg new file mode 100644 index 00000000000..42eb8564f1a Binary files /dev/null and b/sound/voice/medbot/im_different.ogg differ diff --git a/sound/voice/medbot/is_this_the_end.ogg b/sound/voice/medbot/is_this_the_end.ogg new file mode 100644 index 00000000000..a2e0e2330a3 Binary files /dev/null and b/sound/voice/medbot/is_this_the_end.ogg differ diff --git a/sound/voice/medbot/nooo.ogg b/sound/voice/medbot/nooo.ogg new file mode 100644 index 00000000000..102fd1fb042 Binary files /dev/null and b/sound/voice/medbot/nooo.ogg differ diff --git a/sound/voice/medbot/oh_fuck.ogg b/sound/voice/medbot/oh_fuck.ogg new file mode 100644 index 00000000000..95d21ef2550 Binary files /dev/null and b/sound/voice/medbot/oh_fuck.ogg differ diff --git a/sound/voice/medbot/pain_is_real.ogg b/sound/voice/medbot/pain_is_real.ogg new file mode 100644 index 00000000000..9cfa3a71be1 Binary files /dev/null and b/sound/voice/medbot/pain_is_real.ogg differ diff --git a/sound/voice/medbot/please_dont.ogg b/sound/voice/medbot/please_dont.ogg new file mode 100644 index 00000000000..a77ee09cb45 Binary files /dev/null and b/sound/voice/medbot/please_dont.ogg differ diff --git a/sound/voice/medbot/please_im_scared.ogg b/sound/voice/medbot/please_im_scared.ogg new file mode 100644 index 00000000000..7bd53b39c89 Binary files /dev/null and b/sound/voice/medbot/please_im_scared.ogg differ diff --git a/sound/voice/medbot/please_put_me_back.ogg b/sound/voice/medbot/please_put_me_back.ogg new file mode 100644 index 00000000000..84700fbdd57 Binary files /dev/null and b/sound/voice/medbot/please_put_me_back.ogg differ diff --git a/sound/voice/medbot/reported.ogg b/sound/voice/medbot/reported.ogg new file mode 100644 index 00000000000..d5469c19ced Binary files /dev/null and b/sound/voice/medbot/reported.ogg differ diff --git a/sound/voice/medbot/shindemashou.ogg b/sound/voice/medbot/shindemashou.ogg new file mode 100644 index 00000000000..1ee2858eaf9 Binary files /dev/null and b/sound/voice/medbot/shindemashou.ogg differ diff --git a/sound/voice/medbot/thank_you.ogg b/sound/voice/medbot/thank_you.ogg new file mode 100644 index 00000000000..3fabe7d4a63 Binary files /dev/null and b/sound/voice/medbot/thank_you.ogg differ diff --git a/sound/voice/medbot/turn_off.ogg b/sound/voice/medbot/turn_off.ogg new file mode 100644 index 00000000000..87a4d6bdd0e Binary files /dev/null and b/sound/voice/medbot/turn_off.ogg differ diff --git a/sound/voice/medbot/why.ogg b/sound/voice/medbot/why.ogg new file mode 100644 index 00000000000..415020b89b0 Binary files /dev/null and b/sound/voice/medbot/why.ogg differ diff --git a/sound/voice/medbot/youre_good.ogg b/sound/voice/medbot/youre_good.ogg new file mode 100644 index 00000000000..62c325f8341 Binary files /dev/null and b/sound/voice/medbot/youre_good.ogg differ diff --git a/tgui/.editorconfig b/tgui/.editorconfig new file mode 100644 index 00000000000..33092d4928a --- /dev/null +++ b/tgui/.editorconfig @@ -0,0 +1,13 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +max_line_length = 80 diff --git a/tgui/.eslintignore b/tgui/.eslintignore new file mode 100644 index 00000000000..010416b9e88 --- /dev/null +++ b/tgui/.eslintignore @@ -0,0 +1,6 @@ +/**/node_modules +/**/*.bundle.* +/**/*.chunk.* +/**/*.hot-update.* +/packages/inferno/** +/packages/tgui/public/shim-*.js diff --git a/tgui/.eslintrc-harder.yml b/tgui/.eslintrc-harder.yml new file mode 100644 index 00000000000..eb06f5b33db --- /dev/null +++ b/tgui/.eslintrc-harder.yml @@ -0,0 +1,14 @@ +rules: + ## Enforce a maximum cyclomatic complexity allowed in a program + complexity: [error, { max: 25 }] + ## Enforce consistent brace style for blocks + brace-style: [error, stroustrup, { allowSingleLine: false }] + ## Enforce the consistent use of either backticks, double, or single quotes + quotes: [error, single, { + avoidEscape: true, + allowTemplateLiterals: true, + }] + react/jsx-closing-bracket-location: [error, { + selfClosing: after-props, + nonEmpty: after-props, + }] diff --git a/tgui/.eslintrc.yml b/tgui/.eslintrc.yml new file mode 100644 index 00000000000..fe11b8a34c9 --- /dev/null +++ b/tgui/.eslintrc.yml @@ -0,0 +1,757 @@ +parser: babel-eslint +parserOptions: + ecmaVersion: 2019 + sourceType: module + ecmaFeatures: + jsx: true +env: + es6: true + browser: true + node: true +globals: + Byond: readonly +plugins: + - react +settings: + react: + version: '16.10' +rules: + + ## Possible Errors + ## ---------------------------------------- + + ## Enforce “for†loop update clause moving the counter in the right + ## direction. + # for-direction: error + ## Enforce return statements in getters + # getter-return: error + ## Disallow using an async function as a Promise executor + no-async-promise-executor: error + ## Disallow await inside of loops + # no-await-in-loop: error + ## Disallow comparing against -0 + # no-compare-neg-zero: error + ## Disallow assignment operators in conditional expressions + no-cond-assign: error + ## Disallow the use of console + # no-console: error + ## Disallow constant expressions in conditions + # no-constant-condition: error + ## Disallow control characters in regular expressions + # no-control-regex: error + ## Disallow the use of debugger + no-debugger: error + ## Disallow duplicate arguments in function definitions + no-dupe-args: error + ## Disallow duplicate keys in object literals + no-dupe-keys: error + ## Disallow duplicate case labels + no-duplicate-case: error + ## Disallow empty block statements + # no-empty: error + ## Disallow empty character classes in regular expressions + no-empty-character-class: error + ## Disallow reassigning exceptions in catch clauses + no-ex-assign: error + ## Disallow unnecessary boolean casts + no-extra-boolean-cast: error + ## Disallow unnecessary parentheses + # no-extra-parens: warn + ## Disallow unnecessary semicolons + no-extra-semi: error + ## Disallow reassigning function declarations + no-func-assign: error + ## Disallow assigning to imported bindings + no-import-assign: error + ## Disallow variable or function declarations in nested blocks + no-inner-declarations: error + ## Disallow invalid regular expression strings in RegExp constructors + no-invalid-regexp: error + ## Disallow irregular whitespace + no-irregular-whitespace: error + ## Disallow characters which are made with multiple code points in character + ## class syntax + no-misleading-character-class: error + ## Disallow calling global object properties as functions + no-obj-calls: error + ## Disallow calling some Object.prototype methods directly on objects + no-prototype-builtins: error + ## Disallow multiple spaces in regular expressions + no-regex-spaces: error + ## Disallow sparse arrays + no-sparse-arrays: error + ## Disallow template literal placeholder syntax in regular strings + no-template-curly-in-string: error + ## Disallow confusing multiline expressions + no-unexpected-multiline: error + ## Disallow unreachable code after return, throw, continue, and break + ## statements + # no-unreachable: warn + ## Disallow control flow statements in finally blocks + no-unsafe-finally: error + ## Disallow negating the left operand of relational operators + no-unsafe-negation: error + ## Disallow assignments that can lead to race conditions due to usage of + ## await or yield + # require-atomic-updates: error + ## Require calls to isNaN() when checking for NaN + use-isnan: error + ## Enforce comparing typeof expressions against valid strings + valid-typeof: error + + ## Best practices + ## ---------------------------------------- + ## Enforce getter and setter pairs in objects and classes + # accessor-pairs: error + ## Enforce return statements in callbacks of array methods + # array-callback-return: error + ## Enforce the use of variables within the scope they are defined + # block-scoped-var: error + ## Enforce that class methods utilize this + # class-methods-use-this: error + ## Enforce a maximum cyclomatic complexity allowed in a program + complexity: [error, { max: 50 }] + ## Require return statements to either always or never specify values + # consistent-return: error + ## Enforce consistent brace style for all control statements + curly: [error, all] + ## Require default cases in switch statements + # default-case: error + ## Enforce default parameters to be last + # default-param-last: error + ## Enforce consistent newlines before and after dots + dot-location: [error, property] + ## Enforce dot notation whenever possible + # dot-notation: error + ## Require the use of === and !== + eqeqeq: [error, always] + ## Require for-in loops to include an if statement + # guard-for-in: error + ## Enforce a maximum number of classes per file + # max-classes-per-file: error + ## Disallow the use of alert, confirm, and prompt + # no-alert: error + ## Disallow the use of arguments.caller or arguments.callee + # no-caller: error + ## Disallow lexical declarations in case clauses + no-case-declarations: error + ## Disallow division operators explicitly at the beginning of regular + ## expressions + # no-div-regex: error + ## Disallow else blocks after return statements in if statements + # no-else-return: error + ## Disallow empty functions + # no-empty-function: error + ## Disallow empty destructuring patterns + no-empty-pattern: error + ## Disallow null comparisons without type-checking operators + # no-eq-null: error + ## Disallow the use of eval() + # no-eval: error + ## Disallow extending native types + # no-extend-native: error + ## Disallow unnecessary calls to .bind() + # no-extra-bind: error + ## Disallow unnecessary labels + # no-extra-label: error + ## Disallow fallthrough of case statements + no-fallthrough: error + ## Disallow leading or trailing decimal points in numeric literals + # no-floating-decimal: error + ## Disallow assignments to native objects or read-only global variables + no-global-assign: error + ## Disallow shorthand type conversions + # no-implicit-coercion: error + ## Disallow variable and function declarations in the global scope + # no-implicit-globals: error + ## Disallow the use of eval()-like methods + # no-implied-eval: error + ## Disallow this keywords outside of classes or class-like objects + # no-invalid-this: error + ## Disallow the use of the __iterator__ property + # no-iterator: error + ## Disallow labeled statements + # no-labels: error + ## Disallow unnecessary nested blocks + # no-lone-blocks: error + ## Disallow function declarations that contain unsafe references inside + ## loop statements + # no-loop-func: error + ## Disallow magic numbers + # no-magic-numbers: error + ## Disallow multiple spaces + no-multi-spaces: warn + ## Disallow multiline strings + # no-multi-str: error + ## Disallow new operators outside of assignments or comparisons + # no-new: error + ## Disallow new operators with the Function object + # no-new-func: error + ## Disallow new operators with the String, Number, and Boolean objects + # no-new-wrappers: error + ## Disallow octal literals + no-octal: error + ## Disallow octal escape sequences in string literals + no-octal-escape: error + ## Disallow reassigning function parameters + # no-param-reassign: error + ## Disallow the use of the __proto__ property + # no-proto: error + ## Disallow variable redeclaration + no-redeclare: error + ## Disallow certain properties on certain objects + # no-restricted-properties: error + ## Disallow assignment operators in return statements + no-return-assign: error + ## Disallow unnecessary return await + # no-return-await: error + ## Disallow javascript: urls + # no-script-url: error + ## Disallow assignments where both sides are exactly the same + no-self-assign: error + ## Disallow comparisons where both sides are exactly the same + # no-self-compare: error + ## Disallow comma operators + no-sequences: error + ## Disallow throwing literals as exceptions + # no-throw-literal: error + ## Disallow unmodified loop conditions + # no-unmodified-loop-condition: error + ## Disallow unused expressions + # no-unused-expressions: error + ## Disallow unused labels + no-unused-labels: warn + ## Disallow unnecessary calls to .call() and .apply() + # no-useless-call: error + ## Disallow unnecessary catch clauses + # no-useless-catch: error + ## Disallow unnecessary concatenation of literals or template literals + # no-useless-concat: error + ## Disallow unnecessary escape characters + no-useless-escape: warn + ## Disallow redundant return statements + # no-useless-return: error + ## Disallow void operators + # no-void: error + ## Disallow specified warning terms in comments + # no-warning-comments: error + ## Disallow with statements + no-with: error + ## Enforce using named capture group in regular expression + # prefer-named-capture-group: error + ## Require using Error objects as Promise rejection reasons + # prefer-promise-reject-errors: error + ## Disallow use of the RegExp constructor in favor of regular expression + ## literals + # prefer-regex-literals: error + ## Enforce the consistent use of the radix argument when using parseInt() + radix: error + ## Disallow async functions which have no await expression + # require-await: error + ## Enforce the use of u flag on RegExp + # require-unicode-regexp: error + ## Require var declarations be placed at the top of their containing scope + # vars-on-top: error + ## Require parentheses around immediate function invocations + # wrap-iife: error + ## Require or disallow “Yoda†conditions + # yoda: error + + ## Strict mode + ## ---------------------------------------- + ## Require or disallow strict mode directives + strict: error + + ## Variables + ## ---------------------------------------- + ## Require or disallow initialization in variable declarations + # init-declarations: error + ## Disallow deleting variables + no-delete-var: error + ## Disallow labels that share a name with a variable + # no-label-var: error + ## Disallow specified global variables + # no-restricted-globals: error + ## Disallow variable declarations from shadowing variables declared in + ## the outer scope + # no-shadow: error + ## Disallow identifiers from shadowing restricted names + no-shadow-restricted-names: error + ## Disallow the use of undeclared variables unless mentioned + ## in /*global*/ comments + no-undef: error + ## Disallow initializing variables to undefined + no-undef-init: error + ## Disallow the use of undefined as an identifier + # no-undefined: error + ## Disallow unused variables + # no-unused-vars: error + ## Disallow the use of variables before they are defined + # no-use-before-define: error + + ## Code style + ## ---------------------------------------- + ## Enforce linebreaks after opening and before closing array brackets + array-bracket-newline: [error, consistent] + ## Enforce consistent spacing inside array brackets + array-bracket-spacing: [error, never] + ## Enforce line breaks after each array element + # array-element-newline: error + ## Disallow or enforce spaces inside of blocks after opening block and + ## before closing block + block-spacing: [error, always] + ## Enforce consistent brace style for blocks + # brace-style: [error, stroustrup, { allowSingleLine: false }] + ## Enforce camelcase naming convention + # camelcase: error + ## Enforce or disallow capitalization of the first letter of a comment + # capitalized-comments: error + ## Require or disallow trailing commas + comma-dangle: [error, { + arrays: always-multiline, + objects: always-multiline, + imports: always-multiline, + exports: always-multiline, + functions: only-multiline, ## Optional on functions + }] + ## Enforce consistent spacing before and after commas + comma-spacing: [error, { before: false, after: true }] + ## Enforce consistent comma style + comma-style: [error, last] + ## Enforce consistent spacing inside computed property brackets + computed-property-spacing: [error, never] + ## Enforce consistent naming when capturing the current execution context + # consistent-this: error + ## Require or disallow newline at the end of files + # eol-last: error + ## Require or disallow spacing between function identifiers and their + ## invocations + func-call-spacing: [error, never] + ## Require function names to match the name of the variable or property + ## to which they are assigned + # func-name-matching: error + ## Require or disallow named function expressions + # func-names: error + ## Enforce the consistent use of either function declarations or expressions + func-style: [error, expression] + ## Enforce line breaks between arguments of a function call + # function-call-argument-newline: error + ## Enforce consistent line breaks inside function parentheses + ## NOTE: This rule does not honor a newline on opening paren. + # function-paren-newline: [error, never] + ## Disallow specified identifiers + # id-blacklist: error + ## Enforce minimum and maximum identifier lengths + # id-length: error + ## Require identifiers to match a specified regular expression + # id-match: error + ## Enforce the location of arrow function bodies + # implicit-arrow-linebreak: error + ## Enforce consistent indentation + indent: [error, 2, { SwitchCase: 1 }] + ## Enforce the consistent use of either double or single quotes in JSX + ## attributes + jsx-quotes: [error, prefer-double] + ## Enforce consistent spacing between keys and values in object literal + ## properties + key-spacing: [error, { beforeColon: false, afterColon: true }] + ## Enforce consistent spacing before and after keywords + keyword-spacing: [error, { before: true, after: true }] + ## Enforce position of line comments + # line-comment-position: error + ## Enforce consistent linebreak style + # linebreak-style: error + ## Require empty lines around comments + # lines-around-comment: error + ## Require or disallow an empty line between class members + # lines-between-class-members: error + ## Enforce a maximum depth that blocks can be nested + # max-depth: error + ## Enforce a maximum line length + max-len: [error, { + code: 120, # Bump to 140 if this is still too in the way + ## Ignore imports + ignorePattern: '^(import\s.+\sfrom\s|.*require\()', + ignoreUrls: true, + ignoreRegExpLiterals: true, + }] + ## Enforce a maximum number of lines per file + # max-lines: error + ## Enforce a maximum number of line of code in a function + # max-lines-per-function: error + ## Enforce a maximum depth that callbacks can be nested + # max-nested-callbacks: error + ## Enforce a maximum number of parameters in function definitions + # max-params: error + ## Enforce a maximum number of statements allowed in function blocks + # max-statements: error + ## Enforce a maximum number of statements allowed per line + # max-statements-per-line: error + ## Enforce a particular style for multiline comments + # multiline-comment-style: error + ## Enforce newlines between operands of ternary expressions + # multiline-ternary: [error, always-multiline] + ## Require constructor names to begin with a capital letter + # new-cap: error + ## Enforce or disallow parentheses when invoking a constructor with no + ## arguments + # new-parens: error + ## Require a newline after each call in a method chain + # newline-per-chained-call: error + ## Disallow Array constructors + # no-array-constructor: error + ## Disallow bitwise operators + # no-bitwise: error + ## Disallow continue statements + # no-continue: error + ## Disallow inline comments after code + # no-inline-comments: error + ## Disallow if statements as the only statement in else blocks + # no-lonely-if: error + ## Disallow mixed binary operators + # no-mixed-operators: error + ## Disallow mixed spaces and tabs for indentation + no-mixed-spaces-and-tabs: error + ## Disallow use of chained assignment expressions + # no-multi-assign: error + ## Disallow multiple empty lines + # no-multiple-empty-lines: error + ## Disallow negated conditions + # no-negated-condition: error + ## Disallow nested ternary expressions + # no-nested-ternary: error + ## Disallow Object constructors + # no-new-object: error + ## Disallow the unary operators ++ and -- + # no-plusplus: error + ## Disallow specified syntax + # no-restricted-syntax: error + ## Disallow all tabs + # no-tabs: error + ## Disallow ternary operators + # no-ternary: error + ## Disallow trailing whitespace at the end of lines + # no-trailing-spaces: error + ## Disallow dangling underscores in identifiers + # no-underscore-dangle: error + ## Disallow ternary operators when simpler alternatives exist + # no-unneeded-ternary: error + ## Disallow whitespace before properties + no-whitespace-before-property: error + ## Enforce the location of single-line statements + # nonblock-statement-body-position: error + ## Enforce consistent line breaks inside braces + # object-curly-newline: [error, { multiline: true }] + ## Enforce consistent spacing inside braces + object-curly-spacing: [error, always] + ## Enforce placing object properties on separate lines + # object-property-newline: error + ## Enforce variables to be declared either together or separately in + ## functions + # one-var: error + ## Require or disallow newlines around variable declarations + # one-var-declaration-per-line: error + ## Require or disallow assignment operator shorthand where possible + # operator-assignment: error + ## Enforce consistent linebreak style for operators + operator-linebreak: [error, before] + ## Require or disallow padding within blocks + # padded-blocks: error + ## Require or disallow padding lines between statements + # padding-line-between-statements: error + ## Disallow using Object.assign with an object literal as the first + ## argument and prefer the use of object spread instead. + # prefer-object-spread: error + ## Require quotes around object literal property names + # quote-props: error + ## Enforce the consistent use of either backticks, double, or single quotes + # quotes: [error, single] + ## Require or disallow semicolons instead of ASI + semi: error + ## Enforce consistent spacing before and after semicolons + semi-spacing: [error, { before: false, after: true }] + ## Enforce location of semicolons + semi-style: [error, last] + ## Require object keys to be sorted + # sort-keys: error + ## Require variables within the same declaration block to be sorted + # sort-vars: error + ## Enforce consistent spacing before blocks + space-before-blocks: [error, always] + ## Enforce consistent spacing before function definition opening parenthesis + space-before-function-paren: [error, { + anonymous: always, + named: never, + asyncArrow: always, + }] + ## Enforce consistent spacing inside parentheses + space-in-parens: [error, never] + ## Require spacing around infix operators + # space-infix-ops: error + ## Enforce consistent spacing before or after unary operators + # space-unary-ops: error + ## Enforce consistent spacing after the // or /* in a comment + spaced-comment: [error, always] + ## Enforce spacing around colons of switch statements + switch-colon-spacing: [error, { before: false, after: true }] + ## Require or disallow spacing between template tags and their literals + template-tag-spacing: [error, never] + ## Require or disallow Unicode byte order mark (BOM) + # unicode-bom: [error, never] + ## Require parenthesis around regex literals + # wrap-regex: error + + ## ES6 + ## ---------------------------------------- + ## Require braces around arrow function bodies + # arrow-body-style: error + ## Require parentheses around arrow function arguments + arrow-parens: [error, as-needed] + ## Enforce consistent spacing before and after the arrow in arrow functions + arrow-spacing: [error, { before: true, after: true }] + ## Require super() calls in constructors + # constructor-super: error + ## Enforce consistent spacing around * operators in generator functions + generator-star-spacing: [error, { before: false, after: true }] + ## Disallow reassigning class members + no-class-assign: error + ## Disallow arrow functions where they could be confused with comparisons + # no-confusing-arrow: error + ## Disallow reassigning const variables + no-const-assign: error + ## Disallow duplicate class members + no-dupe-class-members: error + ## Disallow duplicate module imports + # no-duplicate-imports: error + ## Disallow new operators with the Symbol object + no-new-symbol: error + ## Disallow specified modules when loaded by import + # no-restricted-imports: error + ## Disallow this/super before calling super() in constructors + no-this-before-super: error + ## Disallow unnecessary computed property keys in object literals + # no-useless-computed-key: error + ## Disallow unnecessary constructors + # no-useless-constructor: error + ## Disallow renaming import, export, and destructured assignments to the + ## same name + # no-useless-rename: error + ## Require let or const instead of var + no-var: error + ## Require or disallow method and property shorthand syntax for object + ## literals + # object-shorthand: error + ## Require using arrow functions for callbacks + prefer-arrow-callback: error + ## Require const declarations for variables that are never reassigned after + ## declared + # prefer-const: error + ## Require destructuring from arrays and/or objects + # prefer-destructuring: error + ## Disallow parseInt() and Number.parseInt() in favor of binary, octal, and + ## hexadecimal literals + # prefer-numeric-literals: error + ## Require rest parameters instead of arguments + # prefer-rest-params: error + ## Require spread operators instead of .apply() + # prefer-spread: error + ## Require template literals instead of string concatenation + # prefer-template: error + ## Require generator functions to contain yield + # require-yield: error + ## Enforce spacing between rest and spread operators and their expressions + # rest-spread-spacing: error + ## Enforce sorted import declarations within modules + # sort-imports: error + ## Require symbol descriptions + # symbol-description: error + ## Require or disallow spacing around embedded expressions of template + ## strings + # template-curly-spacing: error + ## Require or disallow spacing around the * in yield* expressions + yield-star-spacing: [error, { before: false, after: true }] + + ## React + ## ---------------------------------------- + ## Enforces consistent naming for boolean props + react/boolean-prop-naming: error + ## Forbid "button" element without an explicit "type" attribute + react/button-has-type: error + ## Prevent extraneous defaultProps on components + react/default-props-match-prop-types: error + ## Rule enforces consistent usage of destructuring assignment in component + # react/destructuring-assignment: [error, always, { ignoreClassFields: true }] + ## Prevent missing displayName in a React component definition + react/display-name: error + ## Forbid certain props on Components + # react/forbid-component-props: error + ## Forbid certain props on DOM Nodes + # react/forbid-dom-props: error + ## Forbid certain elements + # react/forbid-elements: error + ## Forbid certain propTypes + # react/forbid-prop-types: error + ## Forbid foreign propTypes + # react/forbid-foreign-prop-types: error + ## Prevent using this.state inside this.setState + react/no-access-state-in-setstate: error + ## Prevent using Array index in key props + # react/no-array-index-key: error + ## Prevent passing children as props + react/no-children-prop: error + ## Prevent usage of dangerous JSX properties + react/no-danger: error + ## Prevent problem with children and props.dangerouslySetInnerHTML + react/no-danger-with-children: error + ## Prevent usage of deprecated methods, including component lifecycle + ## methods + react/no-deprecated: error + ## Prevent usage of setState in componentDidMount + react/no-did-mount-set-state: error + ## Prevent usage of setState in componentDidUpdate + react/no-did-update-set-state: error + ## Prevent direct mutation of this.state + react/no-direct-mutation-state: error + ## Prevent usage of findDOMNode + react/no-find-dom-node: error + ## Prevent usage of isMounted + react/no-is-mounted: error + ## Prevent multiple component definition per file + # react/no-multi-comp: error + ## Prevent usage of shouldComponentUpdate when extending React.PureComponent + react/no-redundant-should-component-update: error + ## Prevent usage of the return value of React.render + react/no-render-return-value: error + ## Prevent usage of setState + # react/no-set-state: error + ## Prevent common casing typos + react/no-typos: error + ## Prevent using string references in ref attribute. + react/no-string-refs: error + ## Prevent using this in stateless functional components + react/no-this-in-sfc: error + ## Prevent invalid characters from appearing in markup + react/no-unescaped-entities: error + ## Prevent usage of unknown DOM property (fixable) + # react/no-unknown-property: error + ## Prevent usage of unsafe lifecycle methods + react/no-unsafe: error + ## Prevent definitions of unused prop types + react/no-unused-prop-types: error + ## Prevent definitions of unused state properties + react/no-unused-state: error + ## Prevent usage of setState in componentWillUpdate + react/no-will-update-set-state: error + ## Enforce ES5 or ES6 class for React Components + react/prefer-es6-class: error + ## Enforce that props are read-only + react/prefer-read-only-props: error + ## Enforce stateless React Components to be written as a pure function + react/prefer-stateless-function: error + ## Prevent missing props validation in a React component definition + # react/prop-types: error + ## Prevent missing React when using JSX + # react/react-in-jsx-scope: error + ## Enforce a defaultProps definition for every prop that is not a required + ## prop + # react/require-default-props: error + ## Enforce React components to have a shouldComponentUpdate method + # react/require-optimization: error + ## Enforce ES5 or ES6 class for returning value in render function + react/require-render-return: error + ## Prevent extra closing tags for components without children (fixable) + react/self-closing-comp: error + ## Enforce component methods order (fixable) + # react/sort-comp: error + ## Enforce propTypes declarations alphabetical sorting + # react/sort-prop-types: error + ## Enforce the state initialization style to be either in a constructor or + ## with a class property + react/state-in-constructor: error + ## Enforces where React component static properties should be positioned. + # react/static-property-placement: error + ## Enforce style prop value being an object + react/style-prop-object: error + ## Prevent void DOM elements (e.g. ,
) from receiving children + react/void-dom-elements-no-children: error + + ## JSX-specific rules + ## ---------------------------------------- + ## Enforce boolean attributes notation in JSX (fixable) + react/jsx-boolean-value: error + ## Enforce or disallow spaces inside of curly braces in JSX attributes and + ## expressions. + # react/jsx-child-element-spacing: error + ## Validate closing bracket location in JSX (fixable) + react/jsx-closing-bracket-location: [error, { + ## NOTE: Not really sure about enforcing this one + selfClosing: false, + nonEmpty: after-props, + }] + ## Validate closing tag location in JSX (fixable) + react/jsx-closing-tag-location: error + ## Enforce or disallow newlines inside of curly braces in JSX attributes and + ## expressions (fixable) + react/jsx-curly-newline: error + ## Enforce or disallow spaces inside of curly braces in JSX attributes and + ## expressions (fixable) + react/jsx-curly-spacing: error + ## Enforce or disallow spaces around equal signs in JSX attributes (fixable) + react/jsx-equals-spacing: error + ## Restrict file extensions that may contain JSX + # react/jsx-filename-extension: error + ## Enforce position of the first prop in JSX (fixable) + # react/jsx-first-prop-new-line: error + ## Enforce event handler naming conventions in JSX + react/jsx-handler-names: error + ## Validate JSX indentation (fixable) + react/jsx-indent: [error, 2, { + checkAttributes: true, + }] + ## Validate props indentation in JSX (fixable) + react/jsx-indent-props: [error, 2] + ## Validate JSX has key prop when in array or iterator + react/jsx-key: error + ## Validate JSX maximum depth + react/jsx-max-depth: [error, { max: 10 }] ## Generous + ## Limit maximum of props on a single line in JSX (fixable) + # react/jsx-max-props-per-line: error + ## Prevent usage of .bind() and arrow functions in JSX props + # react/jsx-no-bind: error + ## Prevent comments from being inserted as text nodes + react/jsx-no-comment-textnodes: error + ## Prevent duplicate props in JSX + react/jsx-no-duplicate-props: error + ## Prevent usage of unwrapped JSX strings + # react/jsx-no-literals: error + ## Prevent usage of unsafe target='_blank' + react/jsx-no-target-blank: error + ## Disallow undeclared variables in JSX + react/jsx-no-undef: error + ## Disallow unnecessary fragments (fixable) + react/jsx-no-useless-fragment: error + ## Limit to one expression per line in JSX + # react/jsx-one-expression-per-line: error + ## Enforce curly braces or disallow unnecessary curly braces in JSX + # react/jsx-curly-brace-presence: error + ## Enforce shorthand or standard form for React fragments + react/jsx-fragments: error + ## Enforce PascalCase for user-defined JSX components + react/jsx-pascal-case: error + ## Disallow multiple spaces between inline JSX props (fixable) + react/jsx-props-no-multi-spaces: error + ## Disallow JSX props spreading + # react/jsx-props-no-spreading: error + ## Enforce default props alphabetical sorting + # react/jsx-sort-default-props: error + ## Enforce props alphabetical sorting (fixable) + # react/jsx-sort-props: error + ## Validate whitespace in and around the JSX opening and closing brackets + ## (fixable) + react/jsx-tag-spacing: error + ## Prevent React to be incorrectly marked as unused + react/jsx-uses-react: error + ## Prevent variables used in JSX to be incorrectly marked as unused + react/jsx-uses-vars: error + ## Prevent missing parentheses around multilines JSX (fixable) + react/jsx-wrap-multilines: error diff --git a/tgui/.gitattributes b/tgui/.gitattributes new file mode 100644 index 00000000000..9382416e69f --- /dev/null +++ b/tgui/.gitattributes @@ -0,0 +1,19 @@ +* text=auto + +## Enforce text mode and LF line breaks +*.js text eol=lf +*.jsx text eol=lf +*.ts text eol=lf +*.tsx text eol=lf +*.css text eol=lf +*.scss text eol=lf +*.html text eol=lf +*.json text eol=lf +*.yml text eol=lf +*.md text eol=lf +*.bat text eol=lf +yarn.lock text eol=lf +bin/tgui text eol=lf + +## Treat bundles as binary and ignore them during conflicts +*.bundle.* binary merge=tgui-merge-bundle diff --git a/tgui/.gitignore b/tgui/.gitignore new file mode 100644 index 00000000000..416ca3768da --- /dev/null +++ b/tgui/.gitignore @@ -0,0 +1,7 @@ +node_modules +*.log +package-lock.json + +/packages/tgui/public/.tmp/**/* +/packages/tgui/public/**/*.hot-update.* +/packages/tgui/public/**/*.map diff --git a/tgui/README.md b/tgui/README.md new file mode 100644 index 00000000000..7ae1bddb6aa --- /dev/null +++ b/tgui/README.md @@ -0,0 +1,188 @@ +# tgui + +## Introduction + +tgui is a robust user interface framework of /tg/station. + +tgui is very different from most UIs you will encounter in BYOND programming. +It is heavily reliant on Javascript and web technologies as opposed to DM. +If you are familiar with NanoUI (a library which can be found on almost +every other SS13 codebase), tgui should be fairly easy to pick up. + +## Learn tgui + +People come to tgui from different backgrounds and with different +learning styles. Whether you prefer a more theoretical or a practical +approach, we hope you’ll find this section helpful. + +### Practical Tutorial + +If you are completely new to frontend and prefer to **learn by doing**, +start with our [practical tutorial](docs/tutorial-and-examples.md). + +### Guides + +This project uses **Inferno** - a very fast UI rendering engine with a similar +API to React. Take your time to read these guides: + +- [React guide](https://reactjs.org/docs/hello-world.html) +- [Inferno documentation](https://infernojs.org/docs/guides/components) - +highlights differences with React. + +If you were already familiar with an older, Ractive-based tgui, and want +to translate concepts between old and new tgui, read this +[interface conversion guide](docs/converting-old-tgui-interfaces.md). + +## Pre-requisites + +You will need these programs to start developing in tgui: + +- [Node v12.13+](https://nodejs.org/en/download/) +- [Yarn v1.19+](https://yarnpkg.com/en/docs/install) +- [MSys2](https://www.msys2.org/) (optional) + +> MSys2 closely replicates a unix-like environment which is necessary for +> the `bin/tgui` script to run. It comes with a robust "mintty" terminal +> emulator which is better than any standard Windows shell, it supports +> "git" out of the box (almost like Git for Windows, but better), has +> a "pacman" package manager, and you can install a text editor like "vim" +> for a full boomer experience. + +## Usage + +**For MSys2, Git Bash, WSL, Linux or macOS users:** + +First and foremost, change your directory to `tgui`. + +Run `bin/tgui --install-git-hooks` (optional) to install merge drivers +which will assist you in conflict resolution when rebasing your branches. + +Run one of the following: + +- `bin/tgui` - build the project in production mode. +- `bin/tgui --dev` - launch a development server. + - tgui development server provides you with incremental compilation, + hot module replacement and logging facilities in all running instances + of tgui. In short, this means that you will instantly see changes in the + game as you code it. Very useful, highly recommended. + - In order to use it, you should start the game server first, connect to it + and wait until the world has been properly loaded and you are no longer + in the lobby. Start tgui dev server, and once it has finished building, + press F5 on any tgui window. You'll know that it's hooked correctly if + you see a green bug icon in titlebar and data gets dumped to the console. +- `bin/tgui --dev --reload` - reload byond cache once. +- `bin/tgui --dev --debug` - run server with debug logging enabled. +- `bin/tgui --dev --no-hot` - disable hot module replacement (helps when +doing development on IE8). +- `bin/tgui --lint` - show problems with the code. +- `bin/tgui --lint --fix` - auto-fix problems with the code. +- `bin/tgui --analyze` - run a bundle analyzer. +- `bin/tgui --clean` - clean up project repo. +- `bin/tgui [webpack options]` - build the project with custom webpack +options. + +**For everyone else:** + +If you haven't opened the console already, you can do that by holding +Shift and right clicking on the `tgui` folder, then pressing +either `Open command window here` or `Open PowerShell window here`. + +Run `yarn install` to install npm dependencies, then one of the following: + +- `yarn run build` - build the project in production mode. +- `yarn run watch` - launch a development server. +- `yarn run lint` - show problems with the code. +- `yarn run lint --fix` - auto-fix problems with the code. +- `yarn run analyze` - run a bundle analyzer. + +We also got some batch files in store, for those who don't like fiddling +with the console: + +- `bin/tgui-build.bat` - build the project in production mode. +- `bin/tgui-dev-server.bat` - launch a development server. + +> Remember to always run a full build before submitting a PR. It creates +> a compressed javascript bundle which is then referenced from DM code. +> We prefer to keep it version controlled, so that people could build the +> game just by using Dream Maker. + +## Troubleshooting + +**Development server doesn't find my BYOND cache!** + +This happens if your Documents folder in Windows has a custom location, for +example in `E:\Libraries\Documents`. Development server has no knowledge +of these non-standard locations, therefore you have to run the dev server +with an additional environmental variable, with a full path to BYOND cache. + +``` +export BYOND_CACHE="E:/Libraries/Documents/BYOND/cache" +bin/tgui --dev +``` + +Note that in Windows, you have to go through Advanced System Settings, +System Properties and then open Environment Variables window to do the +same thing. You may need to reboot after this. + +## Developer Tools + +When developing with `tgui-dev-server`, you will have access to certain +development only features. + +**Debug Logs.** +When running server via `bin/tgui --dev --debug`, server will print debug +logs and time spent on rendering. Use this information to optimize your +code, and try to keep re-renders below 16ms. + +**Kitchen Sink.** +Press `F12` to open the KitchenSink interface. This interface is a +playground to test various tgui components. + +**Layout Debugger.** +Press `F11` to toggle the *layout debugger*. It will show outlines of +all tgui elements, which makes it easy to understand how everything comes +together, and can reveal certain layout bugs which are not normally visible. + +## Project Structure + +- `/packages` - Each folder here represents a self-contained Node module. +- `/packages/common` - Helper functions +- `/packages/tgui/index.js` - Application entry point. +- `/packages/tgui/components` - Basic UI building blocks. +- `/packages/tgui/interfaces` - Actual in-game interfaces. +Interface takes data via the `state` prop and outputs an html-like stucture, +which you can build using existing UI components. +- `/packages/tgui/layouts` - Root level UI components, that affect the final +look and feel of the browser window. They usually hold various window +elements, like the titlebar and resize handlers, and control the UI theme. +- `/packages/tgui/routes.js` - This is where tgui decides which interface to +pull and render. +- `/packages/tgui/layout.js` - A root-level component, holding the +window elements, like the titlebar, buttons, resize handlers. Calls +`routes.js` to decide which component to render. +- `/packages/tgui/styles/main.scss` - CSS entry point. +- `/packages/tgui/styles/functions.scss` - Useful SASS functions. +Stuff like `lighten`, `darken`, `luminance` are defined here. +- `/packages/tgui/styles/atomic` - Atomic CSS classes. +These are very simple, tiny, reusable CSS classes which you can use and +combine to change appearance of your elements. Keep them small. +- `/packages/tgui/styles/components` - CSS classes which are used +in UI components. These stylesheets closely follow the +[BEM](https://en.bem.info/methodology/) methodology. +- `/packages/tgui/styles/interfaces` - Custom stylesheets for your interfaces. +Add stylesheets here if you really need a fine control over your UI styles. +- `/packages/tgui/styles/layouts` - Layout-related styles. +- `/packages/tgui/styles/themes` - Contains all the various themes you can +use in tgui. Each theme must be registered in `webpack.config.js` file. + +## Component Reference + +See: [Component Reference](docs/component-reference.md). + +## License + +All code is licensed with the parent license of *tgstation*, **AGPL-3.0**. + +See the main [README](../README.md) for more details. + +The Authors retain all copyright to their respective work here submitted. diff --git a/tgui/bin/tgui b/tgui/bin/tgui new file mode 100644 index 00000000000..97a86159e6b --- /dev/null +++ b/tgui/bin/tgui @@ -0,0 +1,181 @@ +#!/bin/bash +set -e +shopt -s globstar +shopt -s expand_aliases + +## Initial set-up +## -------------------------------------------------------- + +## Returns an absolute path to file +alias tgui-realpath="readlink -f" + +## Fallbacks for GNU readlink +## Detecting GNU coreutils http://stackoverflow.com/a/8748344/319952 +if ! readlink --version >/dev/null 2>&1; then + if hash greadlink 2>/dev/null; then + alias tgui-realpath="greadlink -f" + else + alias tgui-realpath="perl -MCwd -le 'print Cwd::abs_path(shift)'" + fi +fi + +## Find a canonical path to project root +base_dir="$(dirname "$(tgui-realpath "${0}")")/.." +base_dir="$(tgui-realpath "${base_dir}")" + +## Add locally installed node programs to path +PATH="${PATH}:node_modules/.bin" + + +## Functions +## -------------------------------------------------------- + +## Installs node modules +task-install() { + cd "${base_dir}" + yarn install +} + +## Runs webpack +task-webpack() { + cd "${base_dir}/packages/tgui" + webpack "${@}" +} + +## Runs a development server +task-dev-server() { + cd "${base_dir}/packages/tgui-dev-server" + exec node --experimental-modules index.js "${@}" +} + +## Run a linter through all packages +task-eslint() { + cd "${base_dir}" + eslint ./packages "${@}" + echo "tgui: eslint check passed" +} + +## Mr. Proper +task-clean() { + cd "${base_dir}" + rm -rf packages/tgui/public/.tmp + rm -rf **/node_modules + rm -f **/package-lock.json +} + +## Validates current build against the build stored in git +task-validate-build() { + cd "${base_dir}" + local diff + diff="$(git diff packages/tgui/public/tgui.bundle.*)" + if [[ -n ${diff} ]]; then + echo "Error: our build differs from the build committed into git." + echo "Please rebuild tgui." + exit 1 + fi + echo "tgui: build is ok" +} + +## Installs merge drivers and git hooks +task-install-git-hooks() { + cd "${base_dir}" + local git_root + local git_base_dir + git_root="$(git rev-parse --show-toplevel)" + git_base_dir="${base_dir/${git_root}/.}" + git config --replace-all merge.tgui-merge-bundle.driver \ + "${git_base_dir}/bin/tgui --merge=bundle %O %A %B %L" + echo "tgui: Merge drivers have been successfully installed!" +} + +## Bundle merge driver +task-merge-bundle() { + local file_ancestor="${1}" + local file_current="${2}" + local file_other="${3}" + local conflict_marker_size="${4}" + echo "tgui: Discarding a local tgui build" + ## Do nothing (file_current will be merged and is what we want to keep). + exit 0 +} + + +## Main +## -------------------------------------------------------- + +if [[ ${1} == "--merge"* ]]; then + if [[ ${1} == "--merge=bundle" ]]; then + shift 1 + task-merge-bundle "${@}" + fi + echo "Unknown merge strategy: ${1}" + exit 1 +fi + +if [[ ${1} == "--install-git-hooks" ]]; then + shift 1 + task-install-git-hooks + exit 0 +fi + +## Continuous integration scenario +if [[ ${1} == "--ci" ]]; then + task-clean + task-install + task-eslint + task-webpack --mode=production + task-validate-build + exit 0 +fi + +if [[ ${1} == "--clean" ]]; then + task-clean + exit 0 +fi + +if [[ ${1} == "--dev" ]]; then + shift + task-install + task-dev-server "${@}" + exit 0 +fi + +if [[ ${1} == '--lint' ]]; then + shift 1 + task-install + task-eslint "${@}" + exit 0 +fi + +if [[ ${1} == '--lint-harder' ]]; then + shift 1 + task-install + task-eslint -c .eslintrc-harder.yml "${@}" + exit 0 +fi + +if [[ ${1} == '--fix' ]]; then + shift 1 + task-install + task-eslint --fix "${@}" + exit 0 +fi + +## Analyze the bundle +if [[ ${1} == '--analyze' ]]; then + task-install + task-webpack --mode=production --analyze + exit 0 +fi + +## Make a production webpack build +if [[ -z ${1} ]]; then + task-install + task-eslint + task-webpack --mode=production + exit 0 +fi + +## Run webpack with custom flags +task-install +task-webpack "${@}" diff --git a/tgui/bin/tgui-build.bat b/tgui/bin/tgui-build.bat new file mode 100644 index 00000000000..89e1aca9152 --- /dev/null +++ b/tgui/bin/tgui-build.bat @@ -0,0 +1,5 @@ +@echo off +cd "%~dp0\.." +call yarn install +call yarn run build +timeout /t 9 diff --git a/tgui/bin/tgui-dev-server.bat b/tgui/bin/tgui-dev-server.bat new file mode 100644 index 00000000000..1b5bdcfb1db --- /dev/null +++ b/tgui/bin/tgui-dev-server.bat @@ -0,0 +1,4 @@ +@echo off +cd "%~dp0\.." +call yarn install +call yarn run watch diff --git a/tgui/docs/component-reference.md b/tgui/docs/component-reference.md new file mode 100644 index 00000000000..6c10124049b --- /dev/null +++ b/tgui/docs/component-reference.md @@ -0,0 +1,1000 @@ +# Component Reference + +> Notice: This documentation might be out of date, so always check the source +> code to see the most up-to-date information. + + + +- [General Concepts](#general-concepts) +- [`tgui/components`](#tguicomponents) + - [`AnimatedNumber`](#animatednumber) + - [`BlockQuote`](#blockquote) + - [`Box`](#box) + - [`Button`](#button) + - [`Button.Checkbox`](#buttoncheckbox) + - [`Button.Confirm`](#buttonconfirm) + - [`Button.Input`](#buttoninput) + - [`ByondUi`](#byondui) + - [`Collapsible`](#collapsible) + - [`ColorBox`](#colorbox) + - [`Dimmer`](#dimmer) + - [`Divider`](#divider) + - [`Dropdown`](#dropdown) + - [`Flex`](#flex) + - [`Flex.Item`](#flexitem) + - [`Grid`](#grid) + - [`Grid.Column`](#gridcolumn) + - [`Icon`](#icon) + - [`Input`](#input) + - [`Knob`](#knob) + - [`LabeledControls`](#labeledcontrols) + - [`LabeledControls.Item`](#labeledcontrolsitem) + - [`LabeledList`](#labeledlist) + - [`LabeledList.Item`](#labeledlistitem) + - [`LabeledList.Divider`](#labeledlistdivider) + - [`Modal`](#modal) + - [`NoticeBox`](#noticebox) + - [`NumberInput`](#numberinput) + - [`ProgressBar`](#progressbar) + - [`Section`](#section) + - [`Slider`](#slider) + - [`Table`](#table) + - [`Table.Row`](#tablerow) + - [`Table.Cell`](#tablecell) + - [`Tabs`](#tabs) + - [`Tabs.Tab`](#tabstab) + - [`Tooltip`](#tooltip) +- [`tgui/layouts`](#tguilayouts) + - [`Window`](#window) + - [`Window.Content`](#windowcontent) + +## General Concepts + +These are the components which you can use for interface construction. +If you have trouble finding the exact prop you need on a component, +please note, that most of these components inherit from other basic +components, such as [Box](#box). This component in particular provides a lot +of styling options for all components, e.g. `color` and `opacity`, thus +it is used a lot in this framework. + +**Event handlers.** +Event handlers are callbacks that you can attack to various element to +listen for browser events. Inferno supports camelcase (`onClick`) and +lowercase (`onclick`) event names. + +- Camel case names are what's called *synthetic* events, and are the +**preferred way** of handling events in React, for efficiency and +performance reasons. Please read +[Inferno Event Handling](https://infernojs.org/docs/guides/event-handling) +to understand what this is about. +- Lower case names are native browser events and should be used sparingly, +for example when you need an explicit IE8 support. **DO NOT** use +lowercase event handlers unless you really know what you are doing. +- [Button](#button) component does not support the lowercase `onclick` event. +Use the camel case `onClick` instead. + +## `tgui/components` + +### `AnimatedNumber` + +This component provides animations for numeric values. + +**Props:** + +- `value: number` - Value to animate. +- `initial: number` - Initial value to use in animation when element +first appears. If you set initial to `0` for example, number will always +animate starting from `0`, and if omitted, it will not play an initial +animation. +- `format: value => value` - Output formatter. + - Example: `value => Math.round(value)`. +- `children: (formattedValue, rawValue) => any` - Pull the animated number to +animate more complex things deeper in the DOM tree. + - Example: `(_, value) => ` + +### `BlockQuote` + +Just a block quote, just like this example in markdown: + +> Here's an example of a block quote. + +**Props:** + +- See inherited props: [Box](#box) + +### `Box` + +The Box component serves as a wrapper component for most of the CSS utility +needs. It creates a new DOM element, a `
` by default that can be changed +with the `as` property. Let's say you want to use a `` instead: + +```jsx + + +
+ {buttons && ( +
+ {buttons} +
+ )} + + {open && ( + + {children} + + )} + + ); + } +} diff --git a/tgui/packages/tgui/components/ColorBox.js b/tgui/packages/tgui/components/ColorBox.js new file mode 100644 index 00000000000..f37c4e057e4 --- /dev/null +++ b/tgui/packages/tgui/components/ColorBox.js @@ -0,0 +1,28 @@ +import { classes, pureComponentHooks } from 'common/react'; +import { computeBoxClassName, computeBoxProps } from './Box'; + +export const ColorBox = props => { + const { + content, + children, + className, + color, + backgroundColor, + ...rest + } = props; + rest.color = content ? null : 'transparent'; + rest.backgroundColor = color || backgroundColor; + return ( +
+ {content || '.'} +
+ ); +}; + +ColorBox.defaultHooks = pureComponentHooks; diff --git a/tgui/packages/tgui/components/Dimmer.js b/tgui/packages/tgui/components/Dimmer.js new file mode 100644 index 00000000000..f38d0a026a6 --- /dev/null +++ b/tgui/packages/tgui/components/Dimmer.js @@ -0,0 +1,18 @@ +import { classes } from 'common/react'; +import { Box } from './Box'; + +export const Dimmer = props => { + const { className, children, ...rest } = props; + return ( + +
+ {children} +
+
+ ); +}; diff --git a/tgui/packages/tgui/components/Divider.js b/tgui/packages/tgui/components/Divider.js new file mode 100644 index 00000000000..5c807c290b8 --- /dev/null +++ b/tgui/packages/tgui/components/Divider.js @@ -0,0 +1,18 @@ +import { classes } from 'common/react'; + +export const Divider = props => { + const { + vertical, + hidden, + } = props; + return ( +