diff --git a/.editorconfig b/.editorconfig index df93ae3a16..13dcd5e029 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,3 +6,6 @@ indent_size = 4 [*.yml] indent_style = space indent_size = 2 + +[*.txt] +insert_final_newline = false diff --git a/.gitignore b/.gitignore index f67727febb..f65245c021 100644 --- a/.gitignore +++ b/.gitignore @@ -195,6 +195,7 @@ Temporary Items #Visual studio stuff *.vscode/* +!/.vscode/extensions.json tools/MapAtmosFixer/MapAtmosFixer/obj/* tools/MapAtmosFixer/MapAtmosFixer/bin/* diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000000..ca0e6ad997 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "gbasood.byond-dm-language-support", + "platymuus.dm-langclient", + "EditorConfig.EditorConfig" + ] +} diff --git a/Dockerfile b/Dockerfile index ad347079cd..5f755e3dc1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM tgstation/byond:513.1490 as base +FROM tgstation/byond:513.1503 as base FROM base as build_base diff --git a/README.md b/README.md index ed82fb08e6..2a1ffe65ec 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ - -##Citadel Station 13
-Based and maintained from /tg/station.
+## Citadel Station 13 +Based and maintained from /tg/station. [![forthebadge](http://forthebadge.com/images/badges/60-percent-of-the-time-works-every-time.svg)](https://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/pretty-risque.svg)](https://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/you-didnt-ask-for-this.svg)](http://forthebadge.com) @@ -10,18 +9,19 @@ Based and maintained from /tg/station.
[![Percentage of issues still open](http://isitmaintained.com/badge/open/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue") -**Upstream Information**
-**Website:** http://www.tgstation13.org
-**Code:** https://github.com/tgstation/tgstation
-**Wiki** http://tgstation13.org/wiki/Main_Page
-**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus).
- -**Citadel Station Information**
-**Forums:** http://citadel-station.net/forum/
-**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8
-**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13
-**Discord:** [Here](https://discord.gg/E6SQuhz).
- +**Upstream Information** +**Website:** https://tgstation13.org +**Code:** https://github.com/tgstation/tgstation +**Wiki** https://tgstation13.org/wiki/Main_Page +**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus). + +**Citadel Station Information** +**Website:** http://citadel-station.net +**Forums:** http://citadel-station.net/forum +**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8 +**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13 +**Discord:** [Here](https://discord.gg/E6SQuhz) + ## DOWNLOADING There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at http://www.tgstation13.org/wiki/Downloading_the_source_code diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm index bb9bc75d25..b4abf9b535 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm @@ -266,7 +266,7 @@ /turf/open/indestructible/boss, /area/ruin/unpowered/ash_walkers) "aH" = ( -/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker, +/obj/structure/lavaland/ash_walker, /turf/open/lava/smooth{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, diff --git a/_maps/RandomRuins/StationRuins/Box/Engine/budget.dmm b/_maps/RandomRuins/StationRuins/Box/Engine/budget.dmm new file mode 100644 index 0000000000..e241b776e1 --- /dev/null +++ b/_maps/RandomRuins/StationRuins/Box/Engine/budget.dmm @@ -0,0 +1,1554 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"av" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"aW" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space/basic, +/area/space/nearstation) +"cP" = ( +/obj/structure/table, +/obj/item/clothing/gloves/color/yellow, +/obj/item/storage/toolbox/electrical{ + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"cS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/sign/poster/official/safety_eye_protection, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"dl" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"dw" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"er" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"eP" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"fq" = ( +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"gF" = ( +/obj/structure/closet/crate, +/obj/item/stack/sheet/mineral/plasma{ + amount = 50 + }, +/obj/item/stack/sheet/mineral/plasma{ + amount = 10 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ha" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"hS" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"il" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"iB" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"iD" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"jP" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/terminal{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ku" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/terminal{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"kz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"kA" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/engine, +/area/engine/engineering) +"lG" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"mH" = ( +/obj/structure/sign/poster/official/safety_eye_protection, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"mP" = ( +/obj/machinery/power/smes{ + capacity = 9e+006; + charge = 10000 + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"mU" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"mW" = ( +/obj/machinery/power/port_gen/pacman, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"nR" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"nZ" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/terminal{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"oa" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ou" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"oC" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"oS" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/engine, +/area/engine/engineering) +"pL" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers, +/turf/open/floor/plasteel, +/area/engine/engineering) +"qc" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"qo" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"qH" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"rU" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"sj" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"sU" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/terminal{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"tb" = ( +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"tf" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"tw" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"wt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/closet/radiation, +/turf/open/floor/plasteel, +/area/engine/engineering) +"xh" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"yf" = ( +/turf/open/space/basic, +/area/space/nearstation) +"zw" = ( +/obj/structure/closet/crate, +/obj/item/stack/sheet/mineral/plasma{ + amount = 50 + }, +/obj/item/stack/sheet/mineral/plasma{ + amount = 10 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"zS" = ( +/turf/open/space/basic, +/area/space) +"AC" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"AH" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/engine, +/area/engine/engineering) +"Bq" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Bz" = ( +/obj/machinery/power/smes{ + capacity = 9e+006; + charge = 10000 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Cb" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Cx" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"CH" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"DC" = ( +/obj/structure/rack, +/obj/item/clothing/mask/gas{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/clothing/mask/gas, +/obj/item/clothing/mask/gas{ + pixel_x = -3; + pixel_y = -3 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ei" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"EL" = ( +/turf/closed/wall, +/area/engine/engineering) +"EW" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"FG" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"GB" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"GI" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Hn" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"HN" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/terminal{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Jb" = ( +/obj/machinery/power/smes{ + capacity = 9e+006; + charge = 10000 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Jq" = ( +/obj/machinery/power/port_gen/pacman, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ke" = ( +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Kf" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Kl" = ( +/obj/machinery/power/port_gen/pacman, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"KL" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/terminal{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Le" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) +"LS" = ( +/obj/machinery/power/smes{ + capacity = 9e+006; + charge = 10000 + }, +/obj/structure/cable/yellow{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ME" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"MP" = ( +/turf/closed/wall/r_wall, +/area/engine/engineering) +"Ne" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"Nz" = ( +/obj/machinery/power/smes{ + capacity = 9e+006; + charge = 10000 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ND" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"NZ" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Oj" = ( +/turf/closed/wall/r_wall, +/area/space/nearstation) +"Ok" = ( +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ou" = ( +/obj/machinery/power/smes{ + capacity = 9e+006; + charge = 10000 + }, +/obj/structure/cable/yellow{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"OU" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/obj/machinery/meter, +/turf/open/floor/plasteel, +/area/engine/engineering) +"OX" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Pi" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/terminal{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"QQ" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Rh" = ( +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) +"Rs" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Tk" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/closet/emcloset/anchored, +/turf/open/floor/plating, +/area/engine/engineering) +"TC" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"TS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Us" = ( +/obj/structure/cable/yellow{ + icon_state = "1-4" + }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"UD" = ( +/obj/machinery/power/port_gen/pacman, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"VN" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/power/terminal{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"WB" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ys" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"YZ" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space, +/area/space/nearstation) +"Zn" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_x = 32 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"ZT" = ( +/turf/template_noop, +/area/template_noop) + +(1,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +yf +Rh +yf +yf +Rh +yf +yf +Rh +yf +yf +yf +YZ +YZ +YZ +ZT +ZT +ZT +ZT +ZT +"} +(2,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +yf +tw +yf +yf +tw +yf +yf +tw +yf +yf +yf +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(3,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +tw +tw +tw +tw +tw +tw +tw +tw +tw +Rh +Rh +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(4,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +Le +tw +Le +Le +tw +Le +Le +tw +Le +Le +Le +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(5,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +tw +tw +tw +tw +tw +tw +tw +tw +tw +Rh +Rh +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(6,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +Le +tw +Le +Le +tw +Le +Le +tw +Le +Le +Le +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(7,1,1) = {" +ZT +ZT +ZT +ZT +EL +EL +MP +tw +tw +tw +tw +tw +tw +tw +tw +tw +Rh +Rh +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(8,1,1) = {" +ZT +ZT +cP +Ke +EL +Tk +MP +Le +tw +Le +Le +tw +Le +Le +tw +Le +Le +Le +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(9,1,1) = {" +ZT +ZT +dl +Ok +ND +Zn +Ei +tw +tw +tw +tw +tw +tw +tw +tw +tw +Rh +Rh +YZ +YZ +YZ +tw +zS +zS +zS +zS +"} +(10,1,1) = {" +ZT +nR +AH +iD +MP +MP +MP +MP +MP +MP +iD +iD +iD +MP +tw +yf +tw +yf +yf +Rh +yf +yf +zS +zS +zS +zS +"} +(11,1,1) = {" +oC +GB +tf +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +tw +tw +tw +tw +aW +YZ +aW +yf +zS +zS +zS +zS +"} +(12,1,1) = {" +cS +dw +lG +Ok +ha +Ok +Ok +Hn +Ok +Ok +OX +Ok +Ok +MP +tw +yf +tw +yf +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(13,1,1) = {" +ME +dw +lG +LS +nZ +LS +KL +mP +KL +LS +nZ +LS +KL +iD +tw +yf +tw +yf +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(14,1,1) = {" +Ne +Rs +lG +Nz +jP +Nz +sU +Bz +sU +Nz +jP +Nz +sU +iD +tw +tw +tw +tw +YZ +Oj +YZ +Rh +zS +zS +zS +zS +"} +(15,1,1) = {" +MP +dw +lG +Nz +jP +Nz +sU +Bz +sU +Nz +jP +Nz +sU +iD +tw +yf +tw +yf +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(16,1,1) = {" +MP +dw +lG +WB +Jq +WB +UD +Cx +UD +WB +Jq +WB +UD +MP +tw +tw +tw +tw +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(17,1,1) = {" +oS +EW +sj +er +tb +er +Ys +xh +Ys +er +tb +er +il +iD +tw +yf +tw +yf +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(18,1,1) = {" +iD +fq +oa +qH +iB +qH +qc +Bq +qc +qH +iB +Us +Ok +iD +tw +yf +tw +yf +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(19,1,1) = {" +oS +Cb +Kf +rU +kz +rU +TS +pL +TS +rU +kz +rU +QQ +iD +tw +tw +tw +tw +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(20,1,1) = {" +MP +Cb +AC +WB +mW +WB +Kl +Cx +Kl +WB +mW +WB +Kl +MP +tw +tw +tw +tw +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(21,1,1) = {" +MP +Cb +AC +Nz +VN +Nz +Pi +Bz +Pi +Nz +VN +Nz +Pi +iD +tw +yf +tw +yf +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(22,1,1) = {" +iD +Cb +AC +Nz +VN +Nz +Pi +Bz +Pi +Nz +VN +Nz +Pi +iD +tw +tw +tw +tw +YZ +Oj +YZ +Rh +zS +zS +zS +zS +"} +(23,1,1) = {" +iD +Cb +AC +Ou +HN +Ou +ku +Jb +ku +Ou +HN +Ou +ku +iD +tw +tw +tw +tw +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(24,1,1) = {" +mH +Cb +AC +Ok +TC +Ok +Ok +hS +Ok +Ok +TC +Ok +Ok +MP +tw +tw +tw +tw +YZ +Oj +YZ +yf +zS +zS +zS +zS +"} +(25,1,1) = {" +iD +mU +AC +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +iD +tw +yf +tw +yf +YZ +YZ +YZ +yf +zS +zS +zS +zS +"} +(26,1,1) = {" +wt +av +kA +qo +MP +MP +MP +Ok +Ok +Ok +Ok +Ok +Ok +iD +tw +yf +tw +yf +yf +Rh +yf +yf +zS +zS +zS +zS +"} +(27,1,1) = {" +ZT +ZT +ZT +ou +DC +iD +Ok +Ok +Ok +Ok +Ok +Ok +Ok +iD +tw +yf +tw +tw +Rh +Rh +Rh +Rh +zS +zS +zS +zS +"} +(28,1,1) = {" +ZT +ZT +ZT +OU +Ok +CH +GI +Ok +zw +zw +zw +zw +zw +MP +tw +yf +Rh +yf +Rh +Oj +YZ +yf +zS +zS +zS +zS +"} +(29,1,1) = {" +ZT +ZT +ZT +FG +NZ +MP +MP +MP +MP +MP +iD +iD +iD +MP +Rh +Rh +Rh +Rh +Rh +Oj +YZ +yf +zS +zS +zS +zS +"} diff --git a/_maps/RandomRuins/StationRuins/Box/Engine/empty.dmm b/_maps/RandomRuins/StationRuins/Box/Engine/empty.dmm new file mode 100644 index 0000000000..6116e6a3b6 --- /dev/null +++ b/_maps/RandomRuins/StationRuins/Box/Engine/empty.dmm @@ -0,0 +1,1119 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"av" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"cP" = ( +/obj/structure/table, +/obj/item/clothing/gloves/color/yellow, +/obj/item/storage/toolbox/electrical{ + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"cS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/sign/poster/official/safety_eye_protection, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"dl" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"dw" = ( +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/space/nearstation) +"fq" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/plating, +/area/engine/engineering) +"hK" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) +"iD" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"kA" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/engine, +/area/engine/engineering) +"mH" = ( +/obj/structure/sign/poster/official/safety_eye_protection, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"mU" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"nR" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"ou" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"oC" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"oS" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/engine, +/area/engine/engineering) +"qc" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"qo" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"tw" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"uC" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) +"wt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/closet/radiation, +/turf/open/floor/plasteel, +/area/engine/engineering) +"wS" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) +"yf" = ( +/turf/open/space/basic, +/area/space/nearstation) +"yA" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) +"zS" = ( +/turf/open/space/basic, +/area/space) +"AH" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/engine, +/area/engine/engineering) +"CH" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"DC" = ( +/obj/structure/rack, +/obj/item/clothing/mask/gas{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/clothing/mask/gas, +/obj/item/clothing/mask/gas{ + pixel_x = -3; + pixel_y = -3 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ei" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"EL" = ( +/turf/closed/wall, +/area/engine/engineering) +"FG" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"GB" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"GI" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Hn" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/engine_waste{ + dir = 1 + }, +/turf/open/floor/plating/airless, +/area/engine/engineering) +"Ke" = ( +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Le" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) +"LS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/plating/airless, +/area/engine/engineering) +"ME" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"MP" = ( +/turf/closed/wall/r_wall, +/area/engine/engineering) +"Ne" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"ND" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"NZ" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Oj" = ( +/turf/closed/wall/r_wall, +/area/space/nearstation) +"Ok" = ( +/turf/open/floor/plasteel, +/area/engine/engineering) +"OU" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/obj/machinery/meter, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Rh" = ( +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) +"Tk" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/closet/emcloset/anchored, +/turf/open/floor/plating, +/area/engine/engineering) +"WB" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space/basic, +/area/space/nearstation) +"YZ" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space, +/area/space/nearstation) +"Zn" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_x = 32 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"ZT" = ( +/turf/template_noop, +/area/template_noop) + +(1,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +yf +Rh +yf +yf +Rh +yf +yf +Rh +yf +yf +yf +YZ +YZ +YZ +ZT +ZT +ZT +ZT +ZT +"} +(2,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +yf +tw +yf +yf +tw +yf +yf +tw +yf +yf +yf +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(3,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +tw +tw +tw +tw +tw +tw +tw +tw +tw +Rh +Rh +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(4,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +Le +tw +Le +Le +tw +Le +Le +tw +Le +Le +Le +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(5,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +tw +tw +tw +tw +tw +tw +tw +tw +tw +Rh +Rh +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(6,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +Le +tw +Le +Le +tw +Le +Le +tw +Le +Le +Le +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(7,1,1) = {" +ZT +ZT +ZT +ZT +EL +EL +MP +tw +tw +tw +tw +tw +tw +tw +tw +tw +Rh +Rh +YZ +Oj +YZ +yf +yf +yf +yf +zS +"} +(8,1,1) = {" +ZT +ZT +cP +Ke +EL +Tk +MP +Le +tw +Le +Le +tw +Le +Le +tw +Le +Le +Le +YZ +Oj +YZ +yf +yf +Rh +yf +yf +"} +(9,1,1) = {" +ZT +ZT +dl +Ok +ND +Zn +Ei +tw +tw +tw +tw +tw +tw +tw +tw +tw +Rh +Rh +YZ +YZ +YZ +tw +Rh +Rh +Rh +yf +"} +(10,1,1) = {" +ZT +nR +AH +iD +MP +MP +MP +MP +MP +MP +MP +MP +MP +MP +tw +yf +yf +yf +Rh +yf +yf +yf +yf +Rh +yf +yf +"} +(11,1,1) = {" +oC +GB +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +MP +MP +MP +MP +MP +MP +MP +yf +WB +YZ +WB +yf +"} +(12,1,1) = {" +cS +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +yf +YZ +Oj +YZ +yf +"} +(13,1,1) = {" +ME +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +yf +YZ +Oj +YZ +yf +"} +(14,1,1) = {" +Ne +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +Rh +YZ +Oj +YZ +Rh +"} +(15,1,1) = {" +MP +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +yf +YZ +Oj +YZ +yf +"} +(16,1,1) = {" +MP +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +Rh +YZ +Oj +YZ +yf +"} +(17,1,1) = {" +oS +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +yf +YZ +Oj +YZ +yf +"} +(18,1,1) = {" +iD +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +yf +YZ +Oj +YZ +yf +"} +(19,1,1) = {" +oS +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +Rh +YZ +Oj +YZ +yf +"} +(20,1,1) = {" +MP +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +Rh +YZ +Oj +YZ +yf +"} +(21,1,1) = {" +MP +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +yf +YZ +Oj +YZ +yf +"} +(22,1,1) = {" +iD +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +Rh +YZ +Oj +YZ +Rh +"} +(23,1,1) = {" +iD +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +Rh +YZ +Oj +YZ +yf +"} +(24,1,1) = {" +mH +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +Rh +YZ +Oj +YZ +yf +"} +(25,1,1) = {" +iD +mU +Ok +ou +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +MP +MP +MP +MP +MP +MP +MP +yf +YZ +YZ +YZ +yf +"} +(26,1,1) = {" +wt +av +kA +qo +EL +MP +MP +Ok +Ok +Ok +Ok +Ok +qc +fq +LS +Hn +dw +yf +Rh +yf +yf +yf +yf +Rh +yf +yf +"} +(27,1,1) = {" +ZT +ZT +ZT +ou +DC +iD +Ok +Ok +Ok +Ok +Ok +Ok +Ok +MP +dw +dw +dw +Rh +Rh +Rh +Rh +tw +Rh +Rh +Rh +Rh +"} +(28,1,1) = {" +ZT +ZT +ZT +OU +Ok +CH +GI +Ok +Ok +Ok +Ok +Ok +Ok +MP +yf +yf +Rh +yf +Rh +Oj +YZ +yf +yf +Rh +yf +yf +"} +(29,1,1) = {" +ZT +ZT +ZT +FG +NZ +MP +MP +MP +MP +MP +iD +iD +iD +MP +Rh +Rh +Rh +Rh +Rh +Oj +YZ +yf +yf +Rh +yf +zS +"} diff --git a/_maps/RandomRuins/StationRuins/Box/Engine/engine_am.dmm b/_maps/RandomRuins/StationRuins/Box/Engine/engine_am.dmm new file mode 100644 index 0000000000..96e28fbc6f --- /dev/null +++ b/_maps/RandomRuins/StationRuins/Box/Engine/engine_am.dmm @@ -0,0 +1,1423 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aT" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/button/door{ + dir = 4; + id = "engsm"; + name = "Radiation Shutters Control"; + pixel_x = 24; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"cB" = ( +/obj/machinery/button/door{ + dir = 1; + id = "engsm"; + name = "Radiation Shutters Control"; + req_access_txt = "10" + }, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"cP" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"dz" = ( +/turf/open/space/basic, +/area/space/nearstation) +"dN" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"eA" = ( +/obj/structure/table, +/obj/item/clothing/suit/radiation, +/obj/item/clothing/head/radiation, +/obj/item/clothing/glasses/meson, +/turf/open/floor/plasteel, +/area/engine/engineering) +"eJ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"fh" = ( +/turf/open/floor/plasteel, +/area/engine/engineering) +"fH" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"gf" = ( +/obj/item/storage/toolbox/mechanical, +/obj/item/flashlight, +/obj/item/pipe_dispenser, +/obj/structure/table, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"jH" = ( +/obj/structure/sign/warning/radiation/rad_area, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"kh" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"kK" = ( +/turf/closed/wall, +/area/engine/engineering) +"la" = ( +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) +"lY" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/engine/engineering) +"me" = ( +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"mB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"nR" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"nW" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"qH" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_x = -32 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"qP" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/box, +/obj/structure/cable/yellow, +/turf/open/floor/engine, +/area/engine/engineering) +"rj" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"rT" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"tT" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/button/door{ + dir = 4; + id = "engsm"; + name = "Radiation Shutters Control"; + pixel_x = 24; + req_access_txt = "10" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"uG" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"wt" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "engsm"; + name = "Radiation Chamber Shutters" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"xg" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "engsm"; + name = "Radiation Chamber Shutters" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"xx" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"xJ" = ( +/obj/item/tank/internals/emergency_oxygen/engi{ + pixel_x = 5 + }, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/glasses/meson/engine, +/obj/structure/table, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"yo" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"yU" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/engine/engineering) +"zW" = ( +/obj/structure/chair/stool, +/turf/open/floor/plasteel, +/area/engine/engineering) +"zZ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/button/door{ + dir = 8; + id = "engsm"; + name = "Radiation Shutters Control"; + pixel_x = -24; + req_access_txt = "10" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"Aw" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Bb" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light{ + dir = 1; + light_color = "#c1caff" + }, +/obj/machinery/camera/emp_proof{ + c_tag = "Particle Accelerator"; + network = list("ss13","engine") + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"Bh" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "engsm"; + name = "Radiation Chamber Shutters" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"BG" = ( +/obj/structure/closet/emcloset/anchored, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"Ch" = ( +/turf/closed/wall/r_wall, +/area/engine/engineering) +"Eu" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ER" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_x = 32 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"ES" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/item/wrench, +/turf/open/floor/plating, +/area/engine/engineering) +"FK" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"FY" = ( +/obj/structure/table, +/obj/item/book/manual/wiki/engineering_singulo_tesla, +/obj/item/geiger_counter, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"HQ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/button/door{ + dir = 8; + id = "engsm"; + name = "Radiation Shutters Control"; + pixel_x = -24; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"HW" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "engsm"; + name = "Radiation Chamber Shutters" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"In" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"Js" = ( +/obj/structure/closet/crate/engineering{ + name = "Antimatter Engine Crate" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_shielding_container, +/obj/item/am_containment, +/obj/item/am_containment, +/obj/item/am_containment, +/obj/item/am_containment, +/obj/machinery/power/am_control_unit, +/turf/open/floor/plating, +/area/engine/engineering) +"JC" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "engsm"; + name = "Radiation Chamber Shutters" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"JZ" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/closed/wall, +/area/engine/engineering) +"Lr" = ( +/obj/structure/table, +/obj/item/clothing/gloves/color/yellow, +/obj/item/storage/toolbox/electrical{ + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"LO" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"LV" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"Mi" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/engine, +/area/engine/engineering) +"Mn" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"MD" = ( +/obj/structure/reagent_dispensers/fueltank, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/engine, +/area/engine/engineering) +"MJ" = ( +/turf/open/space/basic, +/area/space) +"No" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"Nz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"NS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Og" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"Ox" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"Pg" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Qk" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/on{ + dir = 1 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"Ra" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/closet/emcloset/anchored, +/turf/open/floor/plating, +/area/engine/engineering) +"Rp" = ( +/obj/effect/turf_decal/stripes/corner, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Si" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"SD" = ( +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"Tr" = ( +/obj/structure/sign/warning/radiation/rad_area, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 6 + }, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"Um" = ( +/turf/template_noop, +/area/template_noop) +"Wf" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"Ww" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"WI" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/engine, +/area/engine/engineering) +"WQ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"WX" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Yd" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"YY" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "engsm"; + name = "Radiation Chamber Shutters" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Zb" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"Zx" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"Zz" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"ZF" = ( +/obj/effect/turf_decal/box/red, +/turf/open/floor/engine, +/area/engine/engineering) +"ZK" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"ZY" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/engine/engineering) + +(1,1,1) = {" +Um +Um +Um +Um +Um +Um +Um +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +Um +Um +Um +Um +Um +"} +(2,1,1) = {" +Um +Um +Um +Um +Um +Um +Um +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +Um +Um +Um +Um +Um +"} +(3,1,1) = {" +Um +Um +Um +Um +Um +Um +Um +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +Um +Um +Um +Um +Um +"} +(4,1,1) = {" +Um +Um +Um +Um +Um +Um +Um +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +Um +Um +Um +Um +Um +"} +(5,1,1) = {" +Um +Um +Um +Um +Um +Um +Um +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +Um +Um +Um +Um +Um +"} +(6,1,1) = {" +Um +Um +Um +Um +Um +Um +Um +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +Um +Um +Um +Um +Um +"} +(7,1,1) = {" +Um +Um +Um +Um +kK +kK +Ch +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(8,1,1) = {" +Um +Um +Lr +la +kK +Ra +Ch +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(9,1,1) = {" +Um +Um +fh +fh +In +ER +yU +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(10,1,1) = {" +Um +Si +fh +ZY +jH +Ch +Ch +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(11,1,1) = {" +xJ +gf +fh +dN +YY +MD +Ch +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(12,1,1) = {" +LO +Eu +Pg +cP +JC +WI +rj +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(13,1,1) = {" +NS +xx +fh +zW +JC +WI +rj +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(14,1,1) = {" +yo +me +aT +Aw +JC +WI +rj +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(15,1,1) = {" +jH +FK +Ch +wt +Ch +rj +rj +Og +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(16,1,1) = {" +Ch +ES +ZK +ZK +zZ +ZK +fH +Og +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(17,1,1) = {" +wt +Zz +Wf +Ox +Ox +Zb +lY +Og +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(18,1,1) = {" +cB +Bb +qP +ZF +ZF +Yd +lY +Og +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(19,1,1) = {" +wt +eJ +Zx +Mn +Mn +WQ +lY +Og +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(20,1,1) = {" +Ch +Js +No +No +tT +No +LV +Og +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(21,1,1) = {" +jH +Nz +Ch +wt +Ch +rj +rj +Og +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(22,1,1) = {" +fh +WX +HQ +Aw +JC +WI +rj +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(23,1,1) = {" +fh +kh +fh +fh +JC +WI +rj +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(24,1,1) = {" +fh +kh +uG +cP +JC +WI +rj +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(25,1,1) = {" +eA +FY +mB +Rp +HW +Mi +Ch +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(26,1,1) = {" +fh +kh +mB +ZY +Tr +rT +rT +Qk +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(27,1,1) = {" +Um +Um +Um +fh +Ww +qH +yU +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(28,1,1) = {" +Um +Um +Um +fh +JZ +BG +Ch +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} +(29,1,1) = {" +Um +Um +Um +fh +JZ +kK +Ch +dz +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +MJ +"} diff --git a/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm b/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm new file mode 100644 index 0000000000..42ed0035ce --- /dev/null +++ b/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm @@ -0,0 +1,2743 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"av" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"aG" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/space, +/area/space/nearstation) +"aR" = ( +/obj/machinery/atmospherics/pipe/simple/dark/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"bw" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"bz" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel, +/area/engine/engineering) +"bI" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"bO" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"cK" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"cP" = ( +/obj/structure/table, +/obj/item/clothing/gloves/color/yellow, +/obj/item/storage/toolbox/electrical{ + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"cS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/sign/poster/official/safety_eye_protection, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"di" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall, +/area/engine/engineering) +"dl" = ( +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"do" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ds" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced, +/turf/open/floor/plasteel, +/area/engine/engineering) +"dw" = ( +/obj/structure/lattice/catwalk, +/turf/open/space, +/area/space/nearstation) +"dZ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"eh" = ( +/obj/structure/chair/office/dark, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ek" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/door/poddoor{ + id = "TEG_Vent" + }, +/turf/open/space, +/area/engine/engineering) +"en" = ( +/obj/machinery/button/ignition/incinerator{ + id = "TEG_igniter"; + pixel_x = -5; + pixel_y = 10 + }, +/obj/machinery/button/door{ + id = "TEG_Vent"; + pixel_x = 6; + pixel_y = 10 + }, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"ev" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) +"eD" = ( +/obj/structure/table/reinforced, +/obj/item/clothing/glasses/meson/engine, +/obj/item/clothing/gloves/color/black, +/obj/item/tank/internals/emergency_oxygen/engi{ + pixel_x = 5 + }, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_x = 26 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"fq" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/plating, +/area/engine/engineering) +"fF" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"fO" = ( +/obj/structure/sign/warning/fire, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"go" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced, +/turf/open/floor/plasteel, +/area/engine/engineering) +"gq" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"gA" = ( +/obj/machinery/igniter{ + id = "TEG_igniter" + }, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"hz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"hT" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ij" = ( +/obj/structure/sign/warning/nosmoking{ + pixel_y = -32 + }, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"iD" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"iP" = ( +/obj/structure/sign/warning/securearea, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"iZ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"jc" = ( +/obj/structure/table/reinforced, +/obj/item/clothing/glasses/meson/engine, +/obj/item/clothing/gloves/color/black, +/obj/item/tank/internals/emergency_oxygen/engi{ + pixel_x = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"jg" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) +"jm" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/space, +/area/space/nearstation) +"jN" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/dark/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"kd" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ki" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) +"kA" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/engine, +/area/engine/engineering) +"kB" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"kF" = ( +/obj/machinery/atmospherics/components/binary/valve/digital, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"kH" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/space, +/area/space/nearstation) +"kK" = ( +/obj/machinery/vending/cola/random, +/obj/structure/extinguisher_cabinet{ + pixel_x = 26; + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"kS" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"le" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/dark/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"lw" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"lD" = ( +/obj/structure/table/reinforced, +/obj/machinery/cell_charger, +/obj/item/stock_parts/cell/high, +/obj/machinery/camera{ + c_tag = "TEG - South East"; + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"lI" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"mj" = ( +/obj/machinery/atmospherics/pipe/simple/dark/visible, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"mn" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"mH" = ( +/obj/structure/sign/poster/official/safety_eye_protection, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"mT" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"mU" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"nc" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector{ + dir = 1 + }, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"nk" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"nD" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"nL" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"nR" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"of" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/space, +/area/space/nearstation) +"ou" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"oC" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"oD" = ( +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"oP" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"oQ" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/sign/warning/securearea{ + pixel_x = -32 + }, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"oS" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/engine, +/area/engine/engineering) +"pY" = ( +/obj/machinery/atmospherics/components/unary/portables_connector{ + dir = 8 + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"qb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"qc" = ( +/obj/machinery/atmospherics/components/binary/valve/digital, +/turf/open/floor/plasteel, +/area/engine/engineering) +"qn" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plasteel, +/area/engine/engineering) +"qo" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"qt" = ( +/obj/structure/closet/firecloset, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"qv" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 5 + }, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"qx" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/space, +/area/space/nearstation) +"qJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall, +/area/engine/engineering) +"qN" = ( +/obj/structure/table/reinforced, +/obj/item/stack/cable_coil, +/obj/item/stack/cable_coil/white{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"rf" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"rh" = ( +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"rr" = ( +/obj/item/bot_assembly/firebot, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"sn" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"sw" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) +"sD" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"sH" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"sN" = ( +/obj/machinery/atmospherics/pipe/manifold/dark/visible{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"tf" = ( +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"tl" = ( +/obj/machinery/atmospherics/components/binary/circulator{ + dir = 8 + }, +/turf/open/floor/circuit/green, +/area/engine/engineering) +"tv" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/engine/engineering) +"tw" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"tM" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"tN" = ( +/obj/effect/decal/cleanable/oil, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"tP" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"tQ" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"uw" = ( +/obj/machinery/atmospherics/components/unary/portables_connector{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/engine/engineering) +"uy" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/structure/window/reinforced, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"uB" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"uD" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"uM" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/space, +/area/space/nearstation) +"vf" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"vq" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/lights/mixed, +/obj/item/storage/box/lights/mixed{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/camera{ + c_tag = "TEG - South West"; + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"vG" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"vU" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/space, +/area/space/nearstation) +"wk" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"wt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/closet/radiation, +/turf/open/floor/plasteel, +/area/engine/engineering) +"wv" = ( +/obj/machinery/atmospherics/pipe/simple/dark/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"wz" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 + }, +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"wC" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"wR" = ( +/obj/machinery/atmospherics/pipe/manifold4w/dark/visible, +/obj/machinery/meter, +/turf/open/floor/plasteel, +/area/engine/engineering) +"xD" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Mix to Engine" + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Atmos to Loop" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"yf" = ( +/turf/open/space/basic, +/area/space/nearstation) +"yn" = ( +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"yN" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"yX" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 8 + }, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"zx" = ( +/obj/structure/table/wood, +/obj/item/electronics/apc, +/obj/item/electronics/apc{ + pixel_x = 3; + pixel_y = 3 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"zG" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 10 + }, +/obj/machinery/meter, +/turf/open/floor/plasteel, +/area/engine/engineering) +"zS" = ( +/turf/open/space/basic, +/area/space) +"Am" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"An" = ( +/obj/machinery/atmospherics/components/binary/circulator/cold{ + dir = 4 + }, +/turf/open/floor/circuit/green, +/area/engine/engineering) +"As" = ( +/obj/structure/sign/warning/fire, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall/r_wall, +/area/engine/engineering) +"At" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"AH" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/engine, +/area/engine/engineering) +"AT" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 1 + }, +/obj/machinery/camera{ + c_tag = "TEG - North Center"; + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel, +/area/engine/engineering) +"AX" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Br" = ( +/obj/machinery/portable_atmospherics/pump, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Bs" = ( +/obj/structure/table/reinforced, +/obj/item/stack/cable_coil, +/obj/item/stack/cable_coil/white{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/multitool, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/camera{ + c_tag = "TEG - North West"; + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Bz" = ( +/obj/machinery/atmospherics/components/unary/portables_connector, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/engine/engineering) +"BI" = ( +/obj/machinery/atmospherics/components/unary/portables_connector{ + dir = 8 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/engine/engineering) +"BN" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"BT" = ( +/obj/item/twohanded/required/kirbyplants/random, +/turf/open/floor/plasteel, +/area/engine/engineering) +"BY" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/sign/warning/securearea{ + pixel_x = 32 + }, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"CH" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/engineering/glass{ + name = "Supermatter Engine Room"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"CS" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Dv" = ( +/obj/structure/chair/office/dark{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"DC" = ( +/obj/structure/rack, +/obj/item/clothing/mask/gas{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/clothing/mask/gas, +/obj/item/clothing/mask/gas{ + pixel_x = -3; + pixel_y = -3 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"DI" = ( +/obj/machinery/power/port_gen/pacman, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/engine/engineering) +"DS" = ( +/obj/structure/closet/emcloset, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ef" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 5 + }, +/obj/structure/sign/nanotrasen{ + pixel_y = -32 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ei" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"Eo" = ( +/obj/structure/closet/secure_closet/engineering_personal, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"EH" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"EI" = ( +/obj/effect/turf_decal/delivery, +/obj/structure/reagent_dispensers/fueltank, +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"EL" = ( +/turf/closed/wall, +/area/engine/engineering) +"EN" = ( +/obj/machinery/atmospherics/components/binary/valve/digital, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"EW" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) +"Fi" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/obj/machinery/camera{ + c_tag = "TEG - East"; + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Fk" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced, +/turf/open/floor/plasteel, +/area/engine/engineering) +"FG" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 10 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"FW" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"FY" = ( +/obj/structure/table/reinforced, +/obj/item/clothing/glasses/meson/engine, +/obj/item/clothing/gloves/color/black, +/obj/item/tank/internals/emergency_oxygen/engi{ + pixel_x = 5 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Gb" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Go" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/food/drinks/soda_cans/thirteenloko, +/turf/open/floor/plasteel, +/area/engine/engineering) +"GB" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"GI" = ( +/obj/machinery/firealarm{ + dir = 4; + pixel_x = 24 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/engine/engineering) +"GR" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"GX" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/plasteel, +/area/engine/engineering) +"He" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Hn" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/engine_waste{ + dir = 1 + }, +/turf/open/floor/plating/airless, +/area/engine/engineering) +"Hp" = ( +/obj/machinery/atmospherics/components/binary/pump, +/turf/open/floor/plasteel, +/area/engine/engineering) +"HF" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Im" = ( +/obj/machinery/power/generator, +/obj/structure/cable/yellow, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/circuit/green, +/area/engine/engineering) +"In" = ( +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/mechanical, +/obj/item/flashlight, +/obj/item/pipe_dispenser, +/turf/open/floor/plasteel, +/area/engine/engineering) +"IA" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"IP" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced, +/turf/open/floor/plasteel, +/area/engine/engineering) +"IW" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Jd" = ( +/obj/machinery/light, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/obj/machinery/atmospherics/pipe/manifold/orange/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Jj" = ( +/obj/machinery/vending/snack/random, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Js" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"JR" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ke" = ( +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/item/flashlight{ + pixel_x = 1; + pixel_y = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Kl" = ( +/obj/effect/turf_decal/tile/yellow, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Kr" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/meter, +/obj/machinery/camera{ + c_tag = "TEG - South Center"; + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Kx" = ( +/obj/effect/spawner/structure/window/plasma/reinforced, +/obj/machinery/atmospherics/pipe/heat_exchanging/junction, +/turf/open/floor/plasteel, +/area/engine/engineering) +"KA" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ld" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Le" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/space/nearstation) +"Lq" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 9 + }, +/turf/open/space, +/area/space/nearstation) +"Lw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"LD" = ( +/obj/machinery/atmospherics/components/trinary/mixer, +/turf/open/floor/plasteel, +/area/engine/engineering) +"LS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/plating/airless, +/area/engine/engineering) +"Mf" = ( +/obj/structure/closet/secure_closet/engineering_personal, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ME" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"MP" = ( +/turf/closed/wall/r_wall, +/area/engine/engineering) +"MQ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ne" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/spawner/structure/window/plasma/reinforced, +/turf/open/floor/plating, +/area/engine/engineering) +"Ng" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Nh" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Nz" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) +"ND" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/external{ + name = "Engineering External Access"; + req_access_txt = "10;13" + }, +/turf/open/floor/plating, +/area/engine/engineering) +"NP" = ( +/obj/machinery/atmospherics/components/binary/pump, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"NZ" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Oj" = ( +/turf/closed/wall/r_wall, +/area/space/nearstation) +"Ok" = ( +/turf/open/floor/plasteel, +/area/engine/engineering) +"OK" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"OP" = ( +/obj/structure/closet/firecloset, +/turf/open/floor/plasteel, +/area/engine/engineering) +"OU" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/obj/machinery/meter, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Pp" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Pz" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"PK" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Qr" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/item/radio/intercom{ + name = "Station Intercom"; + pixel_x = -26 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Qu" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/space, +/area/space/nearstation) +"Qy" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"QH" = ( +/obj/machinery/meter, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"QN" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"QS" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Rh" = ( +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) +"Rl" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Rz" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"RD" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"RK" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"RQ" = ( +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Sw" = ( +/obj/machinery/atmospherics/components/unary/portables_connector, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/engine/engineering) +"SB" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = 26; + pixel_y = 32 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"SE" = ( +/obj/machinery/atmospherics/components/binary/pump/on, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ST" = ( +/obj/structure/chair/office/dark{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"SX" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/window/westright{ + dir = 2; + name = "Engineering Desk"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Tk" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/structure/closet/emcloset/anchored, +/turf/open/floor/plating, +/area/engine/engineering) +"TE" = ( +/obj/structure/closet/crate/internals, +/turf/open/floor/plasteel, +/area/engine/engineering) +"TH" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 10 + }, +/obj/machinery/meter, +/turf/open/floor/plasteel, +/area/engine/engineering) +"TN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"TS" = ( +/obj/machinery/portable_atmospherics/canister/nitrogen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Ue" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Um" = ( +/obj/machinery/atmospherics/components/binary/valve/digital, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Uq" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"UQ" = ( +/obj/machinery/portable_atmospherics/canister/toxins, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/window/westright{ + dir = 2; + name = "Engineering Desk"; + req_access_txt = "10" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"UT" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"UY" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Vi" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/space, +/area/space/nearstation) +"Vs" = ( +/obj/machinery/atmospherics/components/binary/valve/digital/on{ + dir = 4; + name = "Output Release" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"VV" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/camera{ + c_tag = "TEG - North" + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Wc" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Wm" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"WB" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space/basic, +/area/space/nearstation) +"Xe" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Xg" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/obj/structure/lattice, +/turf/open/space, +/area/space/nearstation) +"Xs" = ( +/obj/structure/table/wood, +/obj/item/book/manual/wiki/engineering_construction{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/book/manual/wiki/engineering_guide, +/obj/item/book/manual/wiki/engineering_hacking{ + pixel_x = -3; + pixel_y = 3 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"XD" = ( +/obj/machinery/atmospherics/components/binary/valve/digital/on{ + dir = 4; + name = "Output Release" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/camera{ + c_tag = "TEG - West"; + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"XK" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"XM" = ( +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"XP" = ( +/obj/machinery/atmospherics/pipe/manifold4w/cyan/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"XW" = ( +/obj/structure/table/wood, +/obj/item/paper_bin, +/obj/item/pen, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Yh" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Yu" = ( +/obj/structure/rack, +/obj/item/crowbar/large, +/obj/item/flashlight, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/obj/structure/extinguisher_cabinet{ + dir = 4; + pixel_y = -27 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"YC" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"YG" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall, +/area/engine/engineering) +"YO" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"YP" = ( +/obj/structure/rack, +/obj/effect/spawner/lootdrop/maintenance, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/open/floor/plasteel, +/area/engine/engineering) +"YQ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plasteel, +/area/engine/engineering) +"YR" = ( +/obj/effect/decal/cleanable/oil, +/turf/open/floor/plasteel, +/area/engine/engineering) +"YZ" = ( +/obj/structure/lattice, +/obj/structure/grille, +/turf/open/space, +/area/space/nearstation) +"Zm" = ( +/obj/machinery/atmospherics/components/unary/portables_connector{ + dir = 1 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Zn" = ( +/obj/structure/sign/warning/vacuum/external{ + pixel_x = 32 + }, +/turf/open/floor/plating, +/area/engine/engineering) +"Zs" = ( +/obj/machinery/atmospherics/pipe/manifold/orange/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Zu" = ( +/obj/machinery/atmospherics/pipe/manifold/cyan/visible, +/obj/machinery/meter, +/turf/open/floor/plasteel, +/area/engine/engineering) +"Zv" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/sign/warning/securearea{ + pixel_y = -32 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/tile/yellow, +/turf/open/floor/plasteel, +/area/engine/engineering) +"ZC" = ( +/obj/machinery/atmospherics/pipe/simple/dark/visible, +/turf/open/floor/engine/vacuum, +/area/engine/engineering) +"ZT" = ( +/turf/template_noop, +/area/template_noop) +"ZY" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/engineering) + +(1,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +yf +Rh +yf +yf +Rh +yf +yf +Rh +yf +yf +yf +YZ +YZ +YZ +ZT +ZT +ZT +ZT +ZT +"} +(2,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +yf +sw +jm +sw +Xg +uM +Xg +Xg +uM +jg +yf +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(3,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +tw +qx +Qu +qx +kH +Vi +uM +uM +Vi +vU +Rh +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(4,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +Le +Nz +Qu +Nz +EW +Vi +Xg +Xg +Vi +jg +Le +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(5,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +tw +qx +Qu +qx +kH +Vi +uM +uM +Vi +vU +Rh +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(6,1,1) = {" +ZT +ZT +ZT +ZT +ZT +ZT +ZT +Le +aG +Qu +Nz +EW +Vi +Xg +Xg +Vi +jg +Le +YZ +Oj +YZ +ZT +ZT +ZT +ZT +ZT +"} +(7,1,1) = {" +ZT +ZT +ZT +ZT +EL +EL +MP +tw +qx +Qu +qx +kH +Vi +uM +uM +Vi +vU +Rh +YZ +Oj +YZ +yf +yf +yf +yf +zS +"} +(8,1,1) = {" +ZT +ZT +cP +Ke +EL +Tk +MP +Le +aG +Qu +Nz +EW +Vi +Xg +Xg +Vi +jg +Le +YZ +Oj +YZ +yf +yf +Rh +yf +yf +"} +(9,1,1) = {" +ZT +ZT +dl +Ok +ND +Zn +Ei +tw +qx +of +vU +kH +Vi +uM +uM +Vi +Lq +Rh +YZ +YZ +YZ +Rh +Rh +Rh +Rh +yf +"} +(10,1,1) = {" +ZT +nR +AH +iD +MP +MP +MP +ij +yX +qn +qn +yX +MP +MP +tw +yf +yf +yf +Rh +yf +yf +yf +yf +Rh +yf +yf +"} +(11,1,1) = {" +oC +GB +kB +bz +Bs +FY +yn +Qr +Vs +CS +Xe +XD +Yu +ij +MP +MP +MP +MP +MP +MP +MP +Rh +WB +YZ +WB +yf +"} +(12,1,1) = {" +cS +RK +uy +PK +iZ +tf +tf +Bz +XP +mT +Hp +lI +do +MQ +DS +qN +vq +Eo +Mf +BT +MP +yf +YZ +Oj +YZ +yf +"} +(13,1,1) = {" +ME +QS +uB +Ok +Ok +Ok +Ok +Bz +Zu +Wc +Ok +zG +lw +lw +lw +vf +vf +lw +NP +Ef +MP +yf +YZ +Oj +YZ +yf +"} +(14,1,1) = {" +Ne +nL +UQ +Ok +DI +DI +He +Ok +oP +YR +YO +Ok +He +Ok +Ok +PK +Ok +PK +Wc +tv +MP +Rh +YZ +Oj +YZ +Rh +"} +(15,1,1) = {" +iP +wk +go +fF +EI +EI +sn +qc +Nh +ki +An +Rl +Gb +BN +tM +At +At +lw +lw +XK +MP +yf +YZ +Oj +YZ +yf +"} +(16,1,1) = {" +MP +Pz +ds +HF +Ld +Ld +hT +RD +Ng +Ue +Im +YC +hz +EL +EL +pY +BI +Ok +Ok +TE +MP +Rh +YZ +Oj +YZ +yf +"} +(17,1,1) = {" +oS +TN +Wm +ou +KA +KA +Ok +dZ +bO +ev +tl +qb +sH +Kr +JR +sH +sH +sH +sH +Uq +MP +yf +YZ +Oj +YZ +yf +"} +(18,1,1) = {" +iD +YQ +QN +ou +Br +Br +YR +Sw +Js +rf +uD +IW +IW +IW +GX +uw +uw +IW +wC +Pp +MP +yf +YZ +Oj +YZ +yf +"} +(19,1,1) = {" +oS +kd +tP +ou +bI +Ok +Ok +Sw +Js +Bz +sN +Zm +bO +sH +RQ +gq +gq +sH +sH +EH +MP +Rh +YZ +Oj +YZ +yf +"} +(20,1,1) = {" +MP +VV +wz +mn +Rz +fF +AT +Um +Js +Bz +wR +Zm +OK +Ok +OP +rr +kK +Jj +eD +lD +MP +Rh +YZ +Oj +YZ +yf +"} +(21,1,1) = {" +MP +GR +IP +Zs +sD +Jd +EL +YG +AX +PK +cK +Ok +OK +PK +en +MP +MP +MP +MP +MP +fO +Rh +Rh +Oj +YZ +yf +"} +(22,1,1) = {" +iD +TS +SX +ou +vG +Zv +di +qJ +Lw +Xe +aR +ZY +QH +Hp +Kx +kS +oQ +kS +kS +qv +ek +Le +Rh +Oj +YZ +Rh +"} +(23,1,1) = {" +iD +bw +Fk +ou +Ok +FG +UT +kF +jN +wv +LD +wv +mj +SE +le +ZC +nc +gA +Am +XM +ek +Le +Rh +Oj +YZ +yf +"} +(24,1,1) = {" +mH +oD +rh +ou +Ok +tN +Kl +dZ +TH +sH +sH +sH +gq +FW +Kx +kS +BY +kS +IA +nD +ek +Le +Rh +Oj +YZ +yf +"} +(25,1,1) = {" +iD +mU +Wm +xD +qt +In +jc +Yh +PK +Dv +Dv +bO +YP +As +yN +yN +yN +yN +nk +MP +fO +Rh +Rh +YZ +YZ +yf +"} +(26,1,1) = {" +wt +av +kA +qo +MP +MP +MP +UY +eh +Go +Xs +Qy +EN +fq +LS +Hn +dw +yf +Rh +yf +yf +yf +yf +Rh +yf +yf +"} +(27,1,1) = {" +ZT +ZT +ZT +ou +DC +iD +OP +Ok +eh +zx +XW +ST +Ok +MP +dw +dw +dw +Rh +Rh +Rh +Rh +tw +Rh +Rh +Rh +Rh +"} +(28,1,1) = {" +ZT +ZT +ZT +OU +Ok +CH +GI +Ok +SB +Fi +tQ +Ok +BT +MP +yf +yf +Rh +yf +Rh +Oj +YZ +yf +yf +Rh +yf +yf +"} +(29,1,1) = {" +ZT +ZT +ZT +FG +NZ +iP +MP +ij +MP +MP +iD +iD +iD +MP +Rh +Rh +Rh +Rh +Rh +Oj +YZ +yf +yf +Rh +yf +zS +"} diff --git a/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm b/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm new file mode 100644 index 0000000000..75c0434771 --- /dev/null +++ b/_maps/RandomRuins/StationRuins/Lavaland/Mining_Station/Mining_Station_Public_01.dmm @@ -0,0 +1,7550 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"al" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"ap" = ( +/obj/structure/ore_box, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"at" = ( +/obj/structure/gulag_beacon, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"au" = ( +/obj/machinery/door/airlock/mining/glass{ + name = "Mining Station EVA"; + req_access_txt = "54" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"av" = ( +/obj/machinery/door/airlock{ + name = "Closet" + }, +/turf/open/floor/plating, +/area/mine/production) +"aG" = ( +/turf/open/floor/plating, +/area/mine/living_quarters) +"aJ" = ( +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"aK" = ( +/obj/machinery/atmospherics/components/unary/tank/air{ + dir = 8 + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"aN" = ( +/turf/open/floor/plasteel/white, +/area/mine/laborcamp) +"aW" = ( +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"aX" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock{ + name = "Labor Camp External Access" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"bg" = ( +/turf/closed/wall, +/area/mine/eva) +"bH" = ( +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/atmos_waste{ + dir = 4; + piping_layer = 3 + }, +/obj/structure/lattice/catwalk, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/mine/living_quarters) +"bI" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"bX" = ( +/obj/machinery/door/window/southleft, +/obj/machinery/shower{ + pixel_y = 22 + }, +/turf/open/floor/plasteel/freezer, +/area/mine/living_quarters) +"cd" = ( +/turf/closed/wall, +/area/mine/laborcamp) +"cf" = ( +/obj/machinery/mineral/equipment_vendor, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"ci" = ( +/obj/machinery/door/airlock{ + name = "Vending" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"cn" = ( +/obj/machinery/door/airlock{ + id_tag = "miningdorm3"; + name = "Room 3" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"cr" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"cz" = ( +/obj/machinery/door/poddoor/preopen{ + id = "labor"; + name = "labor camp blast door" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"cA" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/mine/eva) +"cD" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"cX" = ( +/obj/structure/statue{ + desc = "A lifelike statue of a horrifying monster."; + dir = 8; + icon = 'icons/mob/lavaland/lavaland_monsters.dmi'; + icon_state = "goliath"; + name = "goliath" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"di" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"dk" = ( +/obj/structure/table, +/obj/item/stack/packageWrap, +/obj/item/stack/packageWrap, +/obj/item/stack/packageWrap, +/obj/item/hand_labeler, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"dC" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"dL" = ( +/obj/machinery/atmospherics/components/binary/pump/on, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"dP" = ( +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/machinery/computer/shuttle/mining{ + req_access = null + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"dZ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/machinery/door/airlock/glass{ + name = "Mining Station Bridge" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"eh" = ( +/obj/structure/table, +/obj/item/storage/firstaid/regular, +/turf/open/floor/plasteel/white, +/area/mine/laborcamp) +"es" = ( +/turf/open/floor/plasteel, +/area/mine/production) +"ez" = ( +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"eE" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/machinery/button/door{ + id = "labor"; + name = "Labor Camp Lockdown"; + pixel_y = 28; + req_access_txt = "2" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"eL" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel, +/area/mine/production) +"eP" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/machinery/door/airlock/glass{ + name = "Mining Station Bridge" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"eS" = ( +/obj/structure/table, +/obj/item/gps/mining, +/obj/item/gps/mining, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"fm" = ( +/obj/structure/sign/warning/docking, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/mine/production) +"fs" = ( +/obj/item/radio/intercom{ + desc = "Talk through this. It looks like it has been modified to not broadcast."; + name = "Prison Intercom (General)"; + pixel_y = 24; + prison_radio = 1 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"fN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"fO" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Shuttle Docking Foyer"; + dir = 8; + network = list("mine") + }, +/obj/machinery/newscaster{ + pixel_x = 30; + pixel_y = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"fU" = ( +/obj/item/radio/intercom{ + dir = 8; + name = "Station Intercom (General)"; + pixel_x = -28 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"gk" = ( +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/mine/production) +"gs" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"gP" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Mining Station Communications"; + req_access_txt = "48" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/maintenance) +"gT" = ( +/obj/structure/bed, +/obj/item/bedsheet/medical, +/obj/machinery/camera{ + c_tag = "Labor Camp Medical"; + dir = 8; + network = list("labor") + }, +/turf/open/floor/plasteel/white, +/area/mine/laborcamp) +"hf" = ( +/obj/item/twohanded/required/kirbyplants/random, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"hm" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"hv" = ( +/obj/machinery/camera{ + c_tag = "Crew Area Hallway West"; + dir = 1; + network = list("mine") + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"hy" = ( +/obj/machinery/camera{ + c_tag = "Labor Camp External"; + dir = 4; + network = list("labor") + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"hH" = ( +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/structure/displaycase, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"hP" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"hQ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"ia" = ( +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"ig" = ( +/obj/structure/table, +/obj/effect/turf_decal/tile/red, +/obj/item/paper_bin, +/obj/item/pen, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"ik" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"iv" = ( +/obj/machinery/camera{ + c_tag = "Dormitories"; + dir = 4; + network = list("mine") + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"iG" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"iQ" = ( +/obj/machinery/light{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"jf" = ( +/obj/structure/table, +/obj/item/storage/firstaid/regular, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/mine/living_quarters) +"jn" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/eva) +"jD" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/table, +/obj/item/restraints/handcuffs, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"jJ" = ( +/turf/closed/mineral/random/labormineral/volcanic, +/area/lavaland/surface/outdoors/explored) +"kb" = ( +/obj/machinery/mineral/processing_unit_console, +/turf/closed/wall, +/area/mine/laborcamp) +"kj" = ( +/obj/machinery/conveyor{ + id = "gulag" + }, +/turf/open/floor/plating, +/area/mine/laborcamp) +"kz" = ( +/obj/machinery/light/small, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"kB" = ( +/obj/machinery/computer/security/labor, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"kE" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/external{ + glass = 1; + name = "Mining External Airlock"; + opacity = 0; + req_access_txt = "54" + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"kF" = ( +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"kH" = ( +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"kR" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"kS" = ( +/obj/structure/table, +/obj/item/storage/firstaid/toxin{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/mine/living_quarters) +"lj" = ( +/turf/open/floor/mech_bay_recharge_floor, +/area/mine/eva) +"lr" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 10 + }, +/turf/open/floor/plasteel/white, +/area/mine/living_quarters) +"lu" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/computer/mech_bay_power_console{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"ly" = ( +/obj/machinery/camera{ + c_tag = "Labor Camp Central"; + network = list("labor") + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"lI" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown, +/turf/open/floor/plasteel, +/area/mine/production) +"lS" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"me" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 6 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"mg" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = -5; + pixel_y = 30 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"mi" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"mp" = ( +/obj/docking_port/stationary{ + dir = 8; + dwidth = 2; + height = 5; + id = "laborcamp_away"; + name = "labor camp"; + width = 9 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"mv" = ( +/obj/machinery/door/window/southright, +/obj/machinery/shower{ + pixel_y = 22 + }, +/turf/open/floor/plasteel/freezer, +/area/mine/living_quarters) +"mw" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"my" = ( +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"mI" = ( +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/mine/production) +"mL" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"mN" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/mine/production) +"nm" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"nv" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"ny" = ( +/obj/machinery/computer/prisoner, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"nH" = ( +/obj/structure/displaycase, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"nI" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"nJ" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"nK" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"nN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light/small, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/mine/living_quarters) +"nR" = ( +/obj/structure/ore_box, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/mine/production) +"oo" = ( +/obj/machinery/conveyor{ + id = "mining_internal" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating, +/area/mine/production) +"ow" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Infirmary" + }, +/turf/open/floor/plasteel/white, +/area/mine/laborcamp) +"oy" = ( +/obj/machinery/light, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"oG" = ( +/obj/machinery/mineral/equipment_vendor, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"oM" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"oY" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"pi" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"pr" = ( +/obj/structure/table, +/obj/item/pickaxe, +/obj/item/gps/mining, +/obj/item/gps/mining, +/obj/item/gps/mining, +/obj/item/gps/mining, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"pK" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"qb" = ( +/obj/structure/tank_dispenser/oxygen, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel, +/area/mine/eva) +"qc" = ( +/obj/machinery/shower{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = 30 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"qg" = ( +/obj/structure/toilet{ + dir = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/mine/living_quarters) +"qh" = ( +/obj/structure/sink{ + dir = 8; + pixel_x = 11 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"qm" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/structure/closet/crate/secure/loot, +/obj/structure/sign/warning/electricshock{ + pixel_y = 32 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"qH" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = 30 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"qM" = ( +/obj/structure/table, +/obj/item/reagent_containers/food/drinks/beer{ + pixel_x = 7; + pixel_y = 5 + }, +/obj/item/reagent_containers/food/drinks/beer{ + pixel_x = -1; + pixel_y = 9 + }, +/obj/item/reagent_containers/food/drinks/beer{ + pixel_x = -8 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"qR" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"qS" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"qZ" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"re" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/structure/closet/secure_closet/labor_camp_security, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"rf" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"rB" = ( +/obj/machinery/mineral/unloading_machine{ + dir = 1; + icon_state = "unloader-corner"; + input_dir = 1; + output_dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plating, +/area/mine/production) +"rK" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"rU" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 5 + }, +/turf/open/floor/plasteel/white, +/area/mine/living_quarters) +"sa" = ( +/obj/machinery/mineral/processing_unit{ + dir = 1 + }, +/turf/open/floor/plating, +/area/mine/laborcamp) +"se" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/mine/living_quarters) +"si" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"sj" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"sm" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"sx" = ( +/obj/item/radio/intercom{ + dir = 8; + name = "Station Intercom (General)"; + pixel_x = 28 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"sz" = ( +/obj/effect/turf_decal/loading_area, +/turf/open/floor/plasteel, +/area/mine/production) +"sE" = ( +/obj/structure/closet/crate, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"sP" = ( +/obj/structure/table, +/obj/machinery/microwave{ + pixel_y = 6 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"sR" = ( +/obj/machinery/light, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"sU" = ( +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"sW" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"tk" = ( +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden/layer3, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"tr" = ( +/obj/structure/chair, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"tJ" = ( +/obj/item/beacon, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"tK" = ( +/obj/structure/closet/crate, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"tY" = ( +/obj/structure/closet/emcloset, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"uh" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"uG" = ( +/obj/structure/table, +/obj/item/clothing/glasses/meson, +/obj/item/storage/bag/ore, +/obj/item/pickaxe, +/obj/item/mining_scanner, +/obj/item/flashlight, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"uI" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Mining Station Maintenance"; + req_access_txt = "48" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"uJ" = ( +/obj/item/bikehorn{ + color = "#000"; + desc = "A horn off of a bicycle. This one has been charred to hell and back, yet somehow it still honks."; + name = "charred bike horn" + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"uR" = ( +/obj/effect/turf_decal/loading_area{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"va" = ( +/obj/machinery/button/door{ + id = "miningbathroom"; + name = "Door Bolt Control"; + normaldoorcontrol = 1; + pixel_y = -25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/mine/living_quarters) +"vo" = ( +/obj/machinery/flasher{ + id = "labor" + }, +/turf/closed/wall, +/area/mine/laborcamp) +"vy" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock{ + name = "Labor Camp External Access" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"vE" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"vJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"wd" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"wg" = ( +/obj/structure/closet/crate, +/obj/item/dice/d4, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"wj" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, +/area/mine/production) +"wt" = ( +/obj/structure/toilet{ + dir = 8 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/mine/laborcamp/security) +"wz" = ( +/turf/closed/mineral/random/volcanic, +/area/lavaland/surface/outdoors) +"wB" = ( +/obj/structure/table, +/turf/open/floor/plasteel/white, +/area/mine/laborcamp) +"wC" = ( +/turf/open/floor/circuit, +/area/mine/maintenance) +"wE" = ( +/obj/machinery/vending/cigarette, +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"wV" = ( +/turf/closed/mineral/random/volcanic, +/area/lavaland/surface/outdoors/explored) +"wX" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"xd" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"xh" = ( +/obj/machinery/vending/sustenance, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"xv" = ( +/obj/machinery/mech_bay_recharge_port, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/mine/eva) +"xA" = ( +/obj/machinery/camera{ + c_tag = "Communications Relay"; + dir = 8; + network = list("mine") + }, +/turf/open/floor/circuit, +/area/mine/maintenance) +"xH" = ( +/obj/structure/table, +/obj/item/cigbutt, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"xP" = ( +/obj/machinery/suit_storage_unit/mining, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"xS" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"yt" = ( +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/machinery/light, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"yF" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/mine/production) +"yR" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel, +/area/mine/production) +"yT" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/mine/living_quarters) +"zh" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"zo" = ( +/obj/structure/table, +/turf/open/floor/carpet, +/area/mine/living_quarters) +"zx" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/mine/laborcamp) +"zy" = ( +/obj/item/twohanded/required/kirbyplants/random, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"zI" = ( +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"zN" = ( +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"zY" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"zZ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Ab" = ( +/obj/structure/ore_box, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/explored) +"Ad" = ( +/obj/machinery/light_switch{ + pixel_y = -25 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/turf/open/floor/circuit, +/area/mine/maintenance) +"Ag" = ( +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Ah" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"Aj" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Al" = ( +/turf/closed/wall/r_wall, +/area/mine/maintenance) +"At" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/mine/production) +"AH" = ( +/obj/machinery/cryopod{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"AJ" = ( +/obj/machinery/door/airlock/glass{ + name = "Break Room" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"AQ" = ( +/obj/machinery/door/airlock{ + id_tag = "miningdorm2"; + name = "Room 2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"AS" = ( +/obj/machinery/door/airlock/external{ + glass = 1; + name = "Mining External Airlock"; + opacity = 0 + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/turf/open/floor/plasteel, +/area/mine/production) +"AZ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Bc" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/mine/production) +"Be" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/mine/eva) +"Bh" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Bo" = ( +/obj/structure/reagent_dispensers/fueltank, +/turf/open/floor/plating, +/area/mine/living_quarters) +"BO" = ( +/obj/machinery/door/airlock{ + name = "Labor Camp Storage" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Ca" = ( +/obj/machinery/power/apc{ + dir = 1; + name = "Mining Station Port Wing APC"; + pixel_x = 1; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Cd" = ( +/turf/closed/wall, +/area/mine/production) +"Cg" = ( +/obj/structure/table, +/obj/item/tank/internals/emergency_oxygen{ + pixel_x = 5; + pixel_y = 3 + }, +/obj/item/tank/internals/emergency_oxygen, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Cj" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Cm" = ( +/obj/machinery/vending/snack, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Cy" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/security/glass{ + name = "Labor Camp Shuttle Security Airlock"; + req_access_txt = "2" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"CA" = ( +/obj/machinery/atmospherics/pipe/manifold4w/supply, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"CH" = ( +/obj/structure/rack, +/obj/item/storage/bag/ore, +/obj/item/pickaxe, +/obj/item/flashlight, +/obj/item/clothing/glasses/meson, +/obj/item/mining_scanner, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"CJ" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"CR" = ( +/obj/structure/chair{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"CV" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel, +/area/mine/eva) +"Dd" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Dr" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = -5; + pixel_y = 30 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/chair, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Dv" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/mine/laborcamp/security) +"DN" = ( +/obj/machinery/computer/shuttle/mining/common{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Ed" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/mine/production) +"Eg" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Em" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Ev" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "miningdorm2"; + name = "Door Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ + dir = 1 + }, +/turf/open/floor/carpet, +/area/mine/living_quarters) +"Ex" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"EB" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/vending/security, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"EH" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Fx" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"FC" = ( +/obj/machinery/airalarm{ + pixel_y = 24 + }, +/turf/open/floor/circuit, +/area/mine/maintenance) +"FE" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Ga" = ( +/obj/machinery/status_display/evac{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Ge" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"Gt" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"GM" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"GN" = ( +/obj/machinery/power/apc{ + dir = 8; + name = "Mining Station Starboard Wing APC"; + pixel_x = -25; + pixel_y = 2 + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Hd" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/mine/eva) +"Hg" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Hh" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "gulag" + }, +/turf/open/floor/plating, +/area/mine/laborcamp) +"Hk" = ( +/obj/docking_port/stationary{ + dir = 8; + dwidth = 3; + height = 7; + id = "lavaland_common_away"; + name = "Mining base public dock"; + width = 7 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"Hm" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/external{ + name = "Lavaland Shuttle Airlock" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Ho" = ( +/obj/machinery/door/airlock{ + name = "Restroom" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"Hq" = ( +/obj/structure/rack, +/obj/item/storage/bag/ore, +/obj/item/flashlight, +/obj/item/pickaxe, +/obj/item/clothing/glasses/meson, +/obj/item/mining_scanner, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Hx" = ( +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"HE" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 10 + }, +/obj/machinery/bluespace_beacon, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/dark, +/area/mine/maintenance) +"HO" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/security/glass{ + name = "Labor Camp Shuttle Prisoner Airlock" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"HR" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable, +/turf/open/floor/plating, +/area/mine/living_quarters) +"HS" = ( +/obj/machinery/conveyor{ + dir = 10; + id = "gulag" + }, +/turf/open/floor/plating, +/area/mine/laborcamp) +"HU" = ( +/obj/machinery/computer/shuttle/labor/one_way{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"HY" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/machinery/iv_drip, +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/mine/living_quarters) +"If" = ( +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Ii" = ( +/obj/structure/table, +/obj/item/storage/box/donkpockets, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Ik" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = -5; + pixel_y = 30 + }, +/obj/machinery/shower{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel, +/area/mine/eva) +"ID" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/obj/machinery/meter, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"IG" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"II" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"IK" = ( +/obj/structure/table, +/obj/effect/turf_decal/tile/red, +/obj/machinery/recharger, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"IS" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/mine/living_quarters) +"IY" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 6 + }, +/turf/open/floor/carpet, +/area/mine/living_quarters) +"Jc" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"Jl" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Jo" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Jr" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"JH" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"JJ" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"JP" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"JV" = ( +/obj/machinery/mineral/processing_unit{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plating, +/area/mine/production) +"JW" = ( +/obj/machinery/power/apc{ + name = "Mining EVA APC"; + pixel_x = 1; + pixel_y = -23 + }, +/obj/machinery/recharge_station, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/structure/cable, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"JY" = ( +/turf/closed/mineral/random/labormineral/volcanic, +/area/lavaland/surface/outdoors) +"Kb" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Kk" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "mining_internal"; + name = "mining conveyor" + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Kl" = ( +/turf/open/floor/plasteel, +/area/mine/eva) +"Kt" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "mining_internal" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plating, +/area/mine/production) +"Kx" = ( +/obj/machinery/camera{ + c_tag = "EVA"; + dir = 4; + network = list("mine") + }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -2; + pixel_y = -1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"KG" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"KO" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"KP" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/external{ + glass = 1; + name = "Mining External Airlock"; + opacity = 0; + req_access_txt = "54" + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"KQ" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/external{ + glass = 1; + name = "Mining Shuttle Airlock"; + opacity = 0 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"KR" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"KS" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/production) +"KU" = ( +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"KV" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/mine/living_quarters) +"Lb" = ( +/obj/docking_port/stationary{ + dir = 8; + dwidth = 3; + height = 10; + id = "mining_away"; + name = "lavaland mine"; + width = 7 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"Lc" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/mine/production) +"Le" = ( +/obj/structure/closet/crate/internals, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/clothing/mask/breath, +/obj/item/clothing/mask/breath, +/obj/item/clothing/mask/breath, +/obj/item/clothing/mask/breath, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Lj" = ( +/obj/machinery/power/port_gen/pacman{ + anchored = 1 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/mine/living_quarters) +"Lm" = ( +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"LC" = ( +/obj/structure/table, +/obj/item/storage/fancy/donut_box, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"LG" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"LL" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/power/apc{ + dir = 1; + name = "Labor Camp Security APC"; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"LZ" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Mc" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/machinery/door/airlock/mining/glass{ + name = "Processing Area"; + req_access_txt = "48" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Mj" = ( +/obj/structure/sink{ + dir = 4; + pixel_x = -12 + }, +/obj/structure/mirror{ + pixel_x = -28 + }, +/turf/open/floor/plasteel/freezer, +/area/mine/living_quarters) +"Mk" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "gulag" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Mn" = ( +/turf/closed/wall/r_wall, +/area/mine/laborcamp/security) +"Ms" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, +/turf/open/floor/plasteel/white, +/area/mine/living_quarters) +"Mw" = ( +/obj/machinery/door/airlock/external{ + glass = 1; + name = "Mining External Airlock"; + opacity = 0 + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"MD" = ( +/turf/closed/mineral/random/volcanic, +/area/lavaland/surface/outdoors/unexplored) +"ME" = ( +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"MF" = ( +/obj/structure/closet/crate/freezer, +/obj/item/reagent_containers/blood, +/obj/item/reagent_containers/blood{ + pixel_x = -3; + pixel_y = -3 + }, +/obj/item/reagent_containers/blood/AMinus, +/obj/item/reagent_containers/blood/BMinus{ + pixel_x = -4; + pixel_y = 4 + }, +/obj/item/reagent_containers/blood/BPlus{ + pixel_x = 1; + pixel_y = 2 + }, +/obj/item/reagent_containers/blood/OMinus, +/obj/item/reagent_containers/blood/OPlus{ + pixel_x = -2; + pixel_y = -1 + }, +/obj/item/reagent_containers/blood/random, +/obj/item/reagent_containers/blood/random, +/obj/item/reagent_containers/blood/random, +/obj/machinery/camera{ + c_tag = "Sleeper Room"; + dir = 1; + network = list("mine") + }, +/turf/open/floor/plasteel/white, +/area/mine/living_quarters) +"MG" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"MH" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"ML" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"MM" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/closet/secure_closet/freezer/gulag_fridge, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"MV" = ( +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Nf" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Nk" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"NB" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "miningdorm3"; + name = "Door Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ + dir = 1 + }, +/turf/open/floor/carpet, +/area/mine/living_quarters) +"NH" = ( +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"NI" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/mine/production) +"Oh" = ( +/obj/structure/chair/office{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"Oj" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "mining_internal" + }, +/obj/structure/plasticflaps, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plating, +/area/mine/production) +"Op" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/security/glass{ + name = "Labor Camp Shuttle Prisoner Airlock" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Os" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Ov" = ( +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"OI" = ( +/obj/machinery/mineral/mint, +/turf/open/floor/plasteel, +/area/mine/production) +"ON" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Pp" = ( +/obj/machinery/camera{ + c_tag = "Public Shuttle Lobby"; + network = list("mine") + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/structure/table, +/obj/item/gps/mining, +/obj/item/gps/mining, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Pq" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"PN" = ( +/obj/machinery/light_switch{ + pixel_x = 27 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"PO" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"PY" = ( +/obj/machinery/shower{ + dir = 8 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/white, +/area/mine/laborcamp) +"Qi" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Qr" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/machinery/door/airlock/security/glass{ + name = "Labor Camp Monitoring"; + req_access_txt = "2" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"Qx" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Qy" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"QD" = ( +/obj/machinery/suit_storage_unit/mining, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"Rf" = ( +/obj/machinery/mineral/unloading_machine{ + dir = 1; + icon_state = "unloader-corner"; + input_dir = 1; + output_dir = 2 + }, +/turf/open/floor/plating, +/area/mine/laborcamp) +"Ro" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/machinery/door/airlock/highsecurity{ + name = "Labor Camp Monitoring"; + req_access_txt = "2"; + security_level = 6 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Ru" = ( +/obj/machinery/newscaster{ + pixel_y = 32 + }, +/obj/structure/chair, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Rv" = ( +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"RC" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"RF" = ( +/turf/closed/wall, +/area/mine/laborcamp/security) +"RH" = ( +/obj/machinery/camera{ + c_tag = "Crew Area"; + dir = 1; + network = list("mine") + }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = -32 + }, +/obj/machinery/light, +/obj/effect/turf_decal/tile/bar, +/obj/effect/turf_decal/tile/bar{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"RI" = ( +/obj/structure/closet/crate, +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/mine/production) +"RP" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Sd" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Sj" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Sp" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/mine/laborcamp/security) +"Sq" = ( +/obj/effect/turf_decal/tile/purple, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Ss" = ( +/obj/machinery/conveyor{ + dir = 10; + id = "mining_internal" + }, +/obj/machinery/light/small{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/plating, +/area/mine/production) +"SO" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ + dir = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/mine/living_quarters) +"SW" = ( +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"SY" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, +/turf/open/floor/plasteel, +/area/mine/eva) +"Te" = ( +/obj/structure/table, +/obj/item/trash/plate, +/obj/item/kitchen/fork, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Tm" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/external{ + glass = 1; + name = "Mining Shuttle Airlock"; + opacity = 0 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"TC" = ( +/obj/structure/chair/comfy/brown{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"TG" = ( +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/machinery/mineral/equipment_vendor, +/turf/open/floor/plasteel, +/area/mine/production) +"TI" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Infirmary" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/turf/open/floor/plasteel/white, +/area/mine/living_quarters) +"TJ" = ( +/obj/structure/bed, +/obj/item/bedsheet/brown, +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/turf/open/floor/carpet, +/area/mine/living_quarters) +"Ue" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 5 + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/circuit, +/area/mine/maintenance) +"Uk" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/mob/living/simple_animal/bot/secbot/beepsky{ + desc = "Powered by the tears and sweat of laborers."; + name = "Prison Ofitser" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"Un" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/obj/machinery/button/door{ + id = "miningdorm1"; + name = "Door Bolt Control"; + normaldoorcontrol = 1; + pixel_x = 25; + specialfunctions = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ + dir = 1 + }, +/turf/open/floor/carpet, +/area/mine/living_quarters) +"Uz" = ( +/obj/machinery/power/apc{ + dir = 1; + name = "Mining Communications APC"; + pixel_x = 1; + pixel_y = 23 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plasteel/dark, +/area/mine/maintenance) +"UE" = ( +/obj/machinery/power/terminal{ + dir = 1 + }, +/obj/machinery/power/port_gen/pacman{ + anchored = 1 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"UI" = ( +/obj/machinery/camera{ + c_tag = "Crew Area Hallway East"; + network = list("mine") + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"UJ" = ( +/obj/effect/turf_decal/tile/red, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"Vj" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = -5; + pixel_y = 30 + }, +/obj/structure/table, +/obj/item/paper/fluff/stations/lavaland/orm_notice, +/turf/open/floor/plasteel, +/area/mine/production) +"Vo" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/plating, +/area/mine/production) +"Vs" = ( +/obj/effect/turf_decal/tile/purple, +/turf/open/floor/plasteel, +/area/mine/production) +"VN" = ( +/turf/closed/wall, +/area/mine/living_quarters) +"VP" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating, +/area/mine/production) +"VR" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/machinery/door/airlock/security/glass{ + name = "Labor Camp Shuttle Security Airlock"; + req_access_txt = "2" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"VT" = ( +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"VY" = ( +/obj/structure/closet/emcloset, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/eva) +"Wf" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Wt" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Ww" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/production) +"WL" = ( +/obj/machinery/computer/secure_data, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"WN" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/turf/open/floor/plasteel/dark, +/area/mine/maintenance) +"WX" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"WY" = ( +/obj/machinery/door/airlock{ + id_tag = "miningdorm1"; + name = "Room 1" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Xo" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel/white, +/area/mine/laborcamp) +"Xr" = ( +/obj/machinery/camera{ + c_tag = "Processing Area Room"; + dir = 8; + network = list("mine") + }, +/obj/item/radio/intercom{ + dir = 8; + name = "Station Intercom (General)"; + pixel_x = 28 + }, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"XG" = ( +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/mine/production) +"XN" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"XP" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"XR" = ( +/obj/structure/sign/poster/official/random{ + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"XU" = ( +/obj/machinery/power/smes{ + charge = 5e+006 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/plating, +/area/mine/living_quarters) +"XX" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/closed/wall, +/area/mine/living_quarters) +"Ya" = ( +/turf/closed/wall/r_wall, +/area/mine/laborcamp) +"Ye" = ( +/turf/closed/mineral/random/high_chance/volcanic, +/area/lavaland/surface/outdoors) +"Yf" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Yg" = ( +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/obj/machinery/camera{ + c_tag = "Labor Camp Security Office"; + dir = 1; + network = list("labor") + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp/security) +"Yi" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, +/obj/machinery/door/airlock/glass, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Yp" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"Yr" = ( +/obj/machinery/light/small, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/mine/laborcamp) +"Yy" = ( +/obj/machinery/door/airlock{ + id_tag = "miningbathroom"; + name = "Restroom" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/mine/living_quarters) +"YH" = ( +/obj/machinery/door/airlock{ + name = "Restroom" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/mine/living_quarters) +"YM" = ( +/obj/item/radio/intercom{ + dir = 8; + name = "Station Intercom (General)"; + pixel_x = -28 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/mine/production) +"YV" = ( +/obj/machinery/airalarm{ + pixel_y = 23 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Zp" = ( +/obj/machinery/camera{ + c_tag = "Crew Area Hallway"; + network = list("mine") + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"Zu" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ + dir = 4 + }, +/obj/structure/lattice/catwalk, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/mine/living_quarters) +"Zw" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/machinery/door/airlock/external{ + name = "Lavaland Shuttle Airlock" + }, +/turf/open/floor/plasteel, +/area/mine/living_quarters) +"ZF" = ( +/obj/machinery/telecomms/relay/preset/mining, +/obj/machinery/light/small{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/mine/maintenance) +"ZK" = ( +/obj/machinery/power/apc{ + dir = 1; + name = "Labor Camp APC"; + pixel_y = 23 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/turf/open/floor/plating, +/area/mine/laborcamp) +"ZN" = ( +/obj/machinery/mineral/processing_unit_console, +/turf/closed/wall, +/area/mine/production) + +(1,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(2,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(3,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(4,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +wz +wz +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(5,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +wz +wz +wz +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(6,1,1) = {" +VT +VT +VT +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +Lm +wz +my +Lm +VT +VT +VT +VT +VT +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(7,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +zI +zI +Lm +my +Lm +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +"} +(8,1,1) = {" +VT +Lm +VT +VT +VT +Lm +VT +VT +VT +zI +zI +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +"} +(9,1,1) = {" +Lm +Lm +VT +Lm +Lm +VT +VT +VT +VT +zI +zI +VT +VT +zI +zI +VT +VT +zI +VT +Lm +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +VT +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(10,1,1) = {" +VT +VT +VT +Lm +Lm +VT +VT +VT +zI +zI +zI +zI +zI +zI +zI +zI +zI +zI +zI +zI +zI +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +"} +(11,1,1) = {" +VT +VT +VT +VT +VT +VT +zI +zI +my +zI +zI +zI +zI +zI +zI +zI +zI +zI +zI +zI +zI +zI +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +Lm +VT +VT +VT +VT +VT +VT +VT +"} +(12,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +zI +zI +zI +my +zI +zI +zI +zI +zI +my +zI +zI +my +zI +zI +zI +VT +zI +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(13,1,1) = {" +VT +VT +VT +VT +VT +VT +Lm +VT +zI +zI +zI +my +my +my +my +my +my +my +my +my +zI +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +"} +(14,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +zI +zI +zI +zI +my +my +my +my +my +my +my +my +my +zI +zI +Lm +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +VT +Lm +VT +VT +VT +VT +VT +"} +(15,1,1) = {" +VT +VT +Lm +VT +VT +VT +VT +zI +zI +zI +zI +my +my +my +my +my +my +my +my +my +zI +zI +zI +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +"} +(16,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +VT +zI +zI +zI +my +my +my +my +my +my +my +my +my +zI +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +"} +(17,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +VT +zI +zI +my +my +my +my +my +my +my +mp +my +my +my +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +Lm +Lm +VT +VT +Lm +VT +VT +VT +VT +"} +(18,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +VT +cd +cd +cd +cd +cd +Cy +cd +cd +cd +HO +cd +zI +zI +VT +VT +VT +VT +VT +Lm +wz +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(19,1,1) = {" +JY +Lm +VT +VT +VT +VT +VT +Lm +cd +Te +CR +xh +cd +eE +cd +HU +cd +Jr +cd +my +wV +VT +VT +uJ +VT +Lm +Lm +wz +wz +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(20,1,1) = {" +JY +JY +Lm +VT +VT +VT +Lm +Lm +cd +Qx +NH +Yf +cd +VR +cd +at +cd +Op +cd +wV +wV +wV +VT +VT +VT +Lm +Lm +wz +wz +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(21,1,1) = {" +JY +JY +JY +JY +zx +zx +zx +cd +cd +cd +ci +cd +cd +cz +cd +Ga +NH +NH +Ya +Mn +Mn +Mn +Dv +Mn +nv +Ge +HR +VN +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(22,1,1) = {" +JY +JY +JY +JY +zx +wB +wB +cd +AH +NH +NH +NH +NH +NH +NH +kR +NH +NH +Ya +jD +EB +MM +LC +Mn +xH +dC +hf +VN +bH +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(23,1,1) = {" +JY +JY +JY +JY +cd +eh +aN +ow +NH +NH +NH +NH +vo +ly +xd +Hg +gs +gs +Ro +Uk +si +fN +TC +Mn +ML +dC +oy +VN +Zu +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(24,1,1) = {" +JY +JY +JY +JY +cd +gT +Xo +cd +fs +NH +Wt +xd +xd +Fx +Yf +uR +NH +NH +Ya +nm +Hx +mL +Yg +Mn +XR +dC +Ag +VN +Jc +HR +VN +Lm +Lm +Lm +Lm +Lm +Hk +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(25,1,1) = {" +JY +JY +JY +JY +cd +cd +cd +cd +cd +NH +NH +PY +NH +Mk +cd +Hh +Ya +Ya +Ya +LL +Hx +xS +Gt +Sp +FE +Em +cD +Ag +sm +uh +VN +Lm +Lm +Lm +Lm +KV +Zw +KV +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(26,1,1) = {" +JY +JY +JY +JY +cd +CH +CH +CH +cd +NH +Yr +cd +cd +kb +cd +Hh +Ya +ZK +Ho +oY +JJ +nJ +Ah +Qr +hQ +bI +hQ +hQ +WX +hv +VN +Lm +Lm +Lm +Lm +KV +Ag +KV +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(27,1,1) = {" +JY +JY +JY +JY +cd +Hq +NH +NH +BO +NH +ia +Rf +kj +sa +kj +HS +Ya +wt +RF +WL +Hx +IG +UJ +Sp +Ag +Ag +di +KR +hP +Ag +VN +VN +VN +XX +VN +KV +Hm +KV +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(28,1,1) = {" +JY +JY +JY +JY +cd +cd +sW +Le +cd +vy +cd +cd +cd +cd +cd +cd +Ya +Ya +Mn +kB +Oh +Hx +sR +Al +Al +Al +Al +LG +hP +Ag +VN +zy +If +DN +If +FE +qZ +KV +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(29,1,1) = {" +JY +JY +JY +JY +JY +cd +cd +cd +cd +NH +cd +Ab +tK +tK +my +my +my +zI +Sp +ny +ig +IK +re +Al +wC +wC +Al +Ag +hP +Ag +VN +Ru +Ag +Ag +Ag +Ag +Ag +KV +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(30,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +cd +Jr +cd +Ab +my +my +my +my +my +zI +Sp +Sp +Sp +Sp +Sp +Al +Uz +Ue +Al +EH +hP +aW +VN +Dr +Ag +uG +uG +Ag +cX +KV +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(31,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +cd +aX +cd +Ab +my +my +my +my +my +VT +VT +VT +VT +VT +Lm +Al +ZF +HE +gP +ON +tk +zY +Yi +MG +KO +uG +uG +Ag +Ag +KV +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(32,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +my +my +hy +my +my +my +my +my +VT +VT +VT +VT +VT +Lm +Ye +Al +WN +Ad +Al +cD +JP +FE +VN +YV +RP +Ag +Ag +Ag +oy +VN +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(33,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +my +my +my +my +my +my +my +my +my +VT +VT +VT +VT +Lm +wz +Al +FC +xA +Al +Zp +Sj +oy +VN +Pp +sx +eS +Cg +nH +hH +VN +wz +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(34,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +my +my +my +my +my +my +my +VT +VT +VT +VT +Lm +Lm +Al +Al +Al +Al +Ov +JP +Ag +VN +VN +VN +VN +VN +VN +VN +VN +VN +VN +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(35,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +my +my +my +my +my +my +my +VT +VT +VT +VT +VT +Lm +VN +HY +MF +VN +Ag +JH +cr +VN +TJ +zo +VN +TJ +zo +VN +TJ +zo +VN +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(36,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +my +my +my +my +my +my +my +my +VT +VT +VT +VT +Lm +KV +Ms +rU +se +EH +JP +Ag +VN +IY +Un +VN +IY +Ev +VN +IY +NB +VN +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(37,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +my +my +Ab +JY +my +jJ +VT +VT +VT +VT +Lm +KV +IS +lr +TI +MG +Qy +Ag +VN +WY +VN +VN +AQ +VN +VN +cn +VN +VN +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(38,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +jJ +jJ +JY +VT +VT +wz +Ye +VN +kS +jf +se +cD +JP +Ag +FE +Os +iv +FE +Os +Pq +FE +Os +cD +KV +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(39,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +VT +VT +wz +VN +VN +VN +VN +VN +Ca +ik +oM +oM +XP +oM +oM +XP +AZ +oM +CA +cr +KV +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(40,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +VT +VT +VT +VT +VN +XU +UE +Lj +VN +mg +JH +cr +VN +VN +se +se +VN +VN +VN +YH +VN +VN +wz +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(41,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +VT +VT +VT +VT +VT +VT +VN +qm +aG +aG +VN +EH +JP +oy +VN +Cm +hm +zZ +fU +VN +bX +yT +VN +wz +Ye +wz +wz +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +"} +(42,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +Lm +VT +VT +VT +VT +VT +VT +VT +VN +MH +ID +dL +uI +Dd +nI +aW +se +hm +hm +Nk +hm +VN +mv +nN +VN +Lm +wz +wz +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(43,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +Lm +VT +VT +VT +VT +Lm +Lm +VT +Lm +VN +aG +zh +pi +VN +UI +Sd +kF +AJ +sU +tr +qM +RH +VN +VN +Yy +VN +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(44,1,1) = {" +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +JY +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +VN +Bo +aK +aK +VN +LZ +Sj +FE +se +hm +hm +rK +MV +VN +Mj +va +VN +VT +VT +VT +VT +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(45,1,1) = {" +JY +JY +JY +JY +JY +JY +Lm +VT +VT +JY +JY +JY +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VN +VN +VN +VN +VN +Ag +JP +Ag +VN +wE +hm +rf +hm +VN +qg +SO +VN +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(46,1,1) = {" +JY +JY +JY +JY +JY +VT +VT +VT +VT +VT +Lm +Lm +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +KV +Ag +JP +Ag +VN +sP +Qi +Ii +qh +VN +VN +VN +VN +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +"} +(47,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +KV +aW +kH +kz +VN +KV +KV +KV +KV +VN +wz +wz +wz +VT +Lm +VT +VT +Lm +Lm +VT +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +"} +(48,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +KV +KV +eP +KV +KV +Lm +Lm +Lm +Lm +wz +wz +wz +Lm +VT +VT +VT +VT +Lm +Lm +Lm +wz +Ye +Ye +Lm +Lm +VT +VT +VT +VT +"} +(49,1,1) = {" +VT +VT +VT +VT +VT +VT +VT +wz +wz +wz +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +Lm +KV +CJ +KV +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Ye +Ye +Ye +Ye +Ye +wz +wz +VT +VT +VT +"} +(50,1,1) = {" +wz +wz +wz +wz +wz +wz +wz +MD +wz +Lm +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +KV +JP +KV +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +Lm +Lm +Ye +Ye +Ye +Ye +Ye +Ye +Ye +Ye +Lm +VT +VT +"} +(51,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +wz +Lm +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +KV +JP +KV +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Ye +Ye +Ye +Ye +Ye +Ye +Ye +Lm +VT +VT +"} +(52,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +wz +Lm +VT +VT +Lm +Lm +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +KV +JP +KV +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Ye +Ye +Ye +Ye +Ye +Ye +Ye +Lm +VT +VT +"} +(53,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +wz +Lm +VT +Lm +Lm +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +Ed +wd +Ed +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Ye +Ye +wz +Ye +Lm +Lm +VT +VT +"} +(54,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +wz +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lb +Lm +Lm +Lm +Lm +VT +VT +VT +Ed +wd +Ed +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +"} +(55,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +wz +VT +Lm +VT +VT +VT +VT +VT +Lm +Lm +fm +Tm +Ed +Lm +Lm +VT +VT +VT +Lm +Ed +wd +Ed +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +VT +VT +VT +VT +VT +"} +(56,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +wz +Lm +Lm +VT +VT +VT +VT +VT +VT +Lm +Ed +es +Ed +Lm +VT +VT +VT +VT +Lm +Ed +aJ +Ed +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +"} +(57,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +Lm +VT +VT +VT +VT +VT +VT +Ed +Ed +KQ +Ed +Ed +Lm +VT +VT +Lm +Ed +Ed +dZ +Ed +Ed +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +"} +(58,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +wz +wz +VT +VT +VT +Cd +Ed +tJ +II +Jo +Ed +Cd +Cd +Cd +Cd +Lc +Wf +Ww +Jo +Ed +Cd +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(59,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +VT +VT +VT +Lm +Cd +dP +RC +es +wX +Wf +YM +GN +II +Nf +mN +Aj +wd +es +TG +Cd +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +"} +(60,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +VT +VT +VT +VT +Lm +Ed +wg +Bh +KG +nK +sj +sj +mi +GM +sj +Mc +pK +ME +Cj +yt +Cd +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(61,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +VT +VT +VT +VT +Lm +Lm +Ed +eL +PO +Aj +zN +Sq +qH +Aj +Eg +es +Vo +Jl +KS +es +sE +Cd +Cd +Cd +Cd +At +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(62,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +VT +VT +wz +Lm +bg +bg +bg +Hd +au +Hd +bg +av +Cd +oG +cf +fO +Vo +es +XN +es +Vs +Ed +tY +Vs +Ed +Lm +Lm +wz +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(63,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +wz +wz +Lm +bg +pr +Kx +dk +vJ +JW +bg +VP +Cd +Cd +Bc +Cd +Bc +es +XN +es +lI +AS +qR +lI +Mw +Lm +Lm +wz +wz +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(64,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +Lm +Lm +cA +xP +SY +jn +Ex +xv +bg +mI +Cd +OI +sz +gk +Wf +Yp +XN +es +Wf +Ed +lS +qc +Ed +Lm +Lm +Lm +wz +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(65,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +VT +VT +Lm +cA +xP +Kl +CV +al +lj +bg +Cd +Cd +mw +es +es +es +es +iG +zN +ez +Cd +Cd +Cd +Cd +At +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(66,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +VT +VT +Lm +bg +QD +PN +qb +KU +lu +bg +Ye +Cd +RI +es +yR +yF +me +Kb +Cd +Oj +Cd +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +"} +(67,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +VT +VT +Lm +bg +bg +bg +cA +kE +cA +bg +wz +Cd +Vj +es +Xr +Kk +iQ +Rv +NI +Kt +Cd +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +"} +(68,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +VT +VT +Lm +Lm +Lm +bg +qS +vE +VY +bg +wz +Cd +nR +SW +Cd +NI +ZN +NI +NI +Kt +Cd +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +"} +(69,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +wz +VT +VT +Lm +Lm +bg +Ik +KU +ap +bg +wz +Cd +XG +wj +rB +oo +JV +oo +oo +Ss +Cd +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(70,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +MD +wz +Lm +wz +wz +VT +VT +Lm +bg +cA +KP +cA +bg +wz +Cd +Cd +Cd +Cd +Cd +Cd +Cd +Cd +Cd +Cd +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +Lm +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +"} +(71,1,1) = {" +MD +MD +MD +MD +MD +MD +MD +MD +wz +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Be +Lm +Lm +Lm +Be +wz +wz +Lm +Lm +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +"} +(72,1,1) = {" +MD +MD +wz +wz +MD +MD +MD +wz +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +Lm +Lm +VT +VT +VT +VT +VT +Lm +VT +VT +VT +VT +VT +"} +(73,1,1) = {" +MD +wz +Lm +Lm +wz +wz +MD +wz +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +Lm +Lm +VT +VT +VT +VT +Lm +Lm +Lm +VT +VT +VT +VT +"} +(74,1,1) = {" +wz +Lm +Lm +Lm +wz +Lm +wz +MD +wz +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +VT +VT +VT +VT +VT +VT +Lm +Lm +Lm +Lm +Lm +Lm +VT +VT +VT +VT +Lm +Lm +VT +VT +VT +VT +Lm +Lm +Lm +VT +VT +VT +VT +"} diff --git a/_maps/RandomZLevels/VR/snowdin_VR.dmm b/_maps/RandomZLevels/VR/snowdin_VR.dmm index bae0b05e3d..222615619e 100644 --- a/_maps/RandomZLevels/VR/snowdin_VR.dmm +++ b/_maps/RandomZLevels/VR/snowdin_VR.dmm @@ -3675,7 +3675,7 @@ /area/awaymission/snowdin/cave/cavern) "im" = ( /obj/effect/decal/cleanable/blood/old, -/mob/living/simple_animal/hostile/spawner/nether{ +/obj/structure/spawner/nether{ max_mobs = 5 }, /turf/open/floor/engine/cult{ @@ -8278,7 +8278,7 @@ /turf/open/floor/engine/cult, /area/awaymission/snowdin/post/cavern2) "sb" = ( -/mob/living/simple_animal/hostile/spawner/nether{ +/obj/structure/spawner/nether{ max_mobs = 4; name = "weak netherworld link" }, @@ -10179,7 +10179,7 @@ /obj/structure/cable/yellow{ icon_state = "2-8" }, -/mob/living/simple_animal/hostile/spawner/nether{ +/obj/structure/spawner/nether{ max_mobs = 4; name = "weak netherworld link" }, diff --git a/_maps/RandomZLevels/caves.dmm b/_maps/RandomZLevels/caves.dmm index 96c1a08b1f..913de0817c 100644 --- a/_maps/RandomZLevels/caves.dmm +++ b/_maps/RandomZLevels/caves.dmm @@ -103,7 +103,7 @@ }, /area/awaymission/caves/BMP_asteroid/level_four) "at" = ( -/mob/living/simple_animal/hostile/spawner/skeleton, +/obj/structure/spawner/skeleton, /turf/open/floor/plating/asteroid/basalt/lava{ initial_gas_mix = "n2=23;o2=14" }, @@ -164,7 +164,7 @@ }, /area/awaymission/caves/BMP_asteroid/level_four) "aB" = ( -/mob/living/simple_animal/hostile/spawner/skeleton, +/obj/structure/spawner/skeleton, /turf/open/floor/engine/cult{ initial_gas_mix = "n2=23;o2=14" }, @@ -374,7 +374,7 @@ }, /area/awaymission/caves/BMP_asteroid/level_three) "be" = ( -/mob/living/simple_animal/hostile/spawner/mining/goliath, +/obj/structure/spawner/mining/goliath, /turf/open/floor/plating/asteroid/basalt{ initial_gas_mix = "n2=23;o2=14" }, @@ -504,7 +504,7 @@ /area/awaymission/caves/BMP_asteroid/level_three) "bw" = ( /obj/effect/decal/cleanable/blood, -/mob/living/simple_animal/hostile/spawner/skeleton, +/obj/structure/spawner/skeleton, /turf/open/floor/engine/cult{ initial_gas_mix = "n2=23;o2=14" }, @@ -930,7 +930,7 @@ /turf/closed/wall, /area/awaymission/caves/BMP_asteroid/level_two) "cL" = ( -/mob/living/simple_animal/hostile/spawner/mining/basilisk, +/obj/structure/spawner/mining/basilisk, /turf/open/floor/plating/asteroid/basalt{ initial_gas_mix = "n2=23;o2=14" }, @@ -1644,7 +1644,7 @@ /turf/open/floor/plasteel, /area/awaymission/caves/listeningpost) "fb" = ( -/mob/living/simple_animal/hostile/spawner/mining/hivelord, +/obj/structure/spawner/mining/hivelord, /turf/open/floor/plating/asteroid/basalt{ initial_gas_mix = "n2=23;o2=14" }, @@ -2133,7 +2133,7 @@ /turf/open/floor/plasteel/recharge_floor, /area/awaymission/caves/BMP_asteroid) "gD" = ( -/mob/living/simple_animal/hostile/spawner/mining/hivelord, +/obj/structure/spawner/mining/hivelord, /turf/open/floor/plating/asteroid/basalt{ initial_gas_mix = "n2=23;o2=14" }, @@ -2206,7 +2206,7 @@ }, /area/awaymission/caves/BMP_asteroid) "gQ" = ( -/mob/living/simple_animal/hostile/spawner/mining/basilisk, +/obj/structure/spawner/mining/basilisk, /turf/open/floor/plating/asteroid/basalt{ initial_gas_mix = "n2=23;o2=14" }, diff --git a/_maps/RandomZLevels/snowdin.dmm b/_maps/RandomZLevels/snowdin.dmm index 57e03061dd..c24bf45f81 100644 --- a/_maps/RandomZLevels/snowdin.dmm +++ b/_maps/RandomZLevels/snowdin.dmm @@ -3670,7 +3670,7 @@ /area/awaymission/snowdin/cave/cavern) "im" = ( /obj/effect/decal/cleanable/blood/old, -/mob/living/simple_animal/hostile/spawner/nether{ +/obj/structure/spawner/nether{ max_mobs = 5 }, /turf/open/floor/engine/cult{ @@ -8333,7 +8333,7 @@ /turf/open/floor/engine/cult, /area/awaymission/snowdin/post/cavern2) "sb" = ( -/mob/living/simple_animal/hostile/spawner/nether{ +/obj/structure/spawner/nether{ max_mobs = 4; name = "weak netherworld link" }, @@ -10243,7 +10243,7 @@ /obj/structure/cable/yellow{ icon_state = "2-8" }, -/mob/living/simple_animal/hostile/spawner/nether{ +/obj/structure/spawner/nether{ max_mobs = 4; name = "weak netherworld link" }, diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index a175c2fc30..4743d12d0e 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -173,6 +173,19 @@ "aay" = ( /turf/open/floor/plating, /area/security/prison) +"aaz" = ( +/obj/structure/lattice/catwalk, +/obj/item/stack/marker_beacon{ + anchored = 1; + icon_state = "markerburgundy-on"; + light_color = "#FA644B"; + light_power = 3; + light_range = 3; + name = "Docking Beacon"; + picked_color = "Burgundy" + }, +/turf/open/space/basic, +/area/space/nearstation) "aaA" = ( /obj/machinery/seed_extractor, /turf/open/floor/plasteel, @@ -234,10 +247,46 @@ /obj/structure/chair/stool, /turf/open/floor/plasteel, /area/security/prison) +"aaK" = ( +/obj/structure/lattice/catwalk, +/obj/item/stack/marker_beacon{ + anchored = 1; + icon_state = "markerburgundy-on"; + light_color = "#FA644B"; + light_power = 3; + light_range = 3; + name = "Docking Beacon"; + picked_color = "Burgundy" + }, +/turf/open/floor/plating, +/area/space/nearstation) +"aaL" = ( +/obj/machinery/photocopier, +/turf/open/floor/wood, +/area/library) +"aaM" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/turf_decal/tile/brown, +/obj/effect/turf_decal/tile/brown{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/quartermaster/office) "aaN" = ( /obj/structure/chair/sofa/right, /turf/open/floor/plasteel, /area/security/prison) +"aaO" = ( +/obj/effect/spawner/lootdrop/keg, +/turf/open/floor/plating, +/area/maintenance/starboard/aft) "aaP" = ( /obj/machinery/computer/cryopod{ dir = 8; @@ -248,6 +297,12 @@ }, /turf/open/floor/plasteel, /area/security/prison) +"aaQ" = ( +/obj/structure/sign/poster/contraband/random{ + pixel_y = 32 + }, +/turf/open/floor/plating, +/area/maintenance/starboard/aft) "aaR" = ( /obj/structure/lattice, /obj/structure/sign/warning/securearea{ @@ -285,6 +340,15 @@ }, /turf/open/floor/plasteel, /area/security/prison) +"aaY" = ( +/obj/structure/closet, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 4; + name = "4maintenance loot spawner" + }, +/obj/item/poster/random_official, +/turf/open/floor/plating, +/area/maintenance/starboard/aft) "aaZ" = ( /turf/closed/wall/r_wall, /area/ai_monitored/security/armory) @@ -505,6 +569,11 @@ "abF" = ( /turf/open/floor/plasteel/freezer, /area/security/prison) +"abG" = ( +/obj/structure/door_assembly/door_assembly_mai, +/obj/item/electronics/airlock, +/turf/open/floor/plating, +/area/maintenance/starboard/aft) "abH" = ( /obj/structure/table, /obj/item/storage/box/chemimp{ @@ -1565,6 +1634,10 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/carpet, /area/crew_quarters/heads/hos) +"adO" = ( +/obj/effect/spawner/structure/window/shuttle, +/turf/open/floor/plating/airless, +/area/space/nearstation) "adP" = ( /obj/structure/cable{ icon_state = "2-8" @@ -1979,6 +2052,34 @@ }, /turf/open/floor/plating, /area/maintenance/fore/secondary) +"aeD" = ( +/obj/structure/grille/broken, +/turf/open/floor/plating/airless, +/area/space/nearstation) +"aeE" = ( +/obj/structure/girder, +/turf/open/floor/plating/airless, +/area/space/nearstation) +"aeF" = ( +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, +/obj/machinery/computer/station_alert{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat_interior) "aeG" = ( /obj/structure/cable, /obj/machinery/power/solar{ @@ -2357,6 +2458,12 @@ }, /turf/open/floor/plasteel, /area/security/main) +"afn" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/turf/open/floor/plasteel/grimy, +/area/ai_monitored/turret_protected/aisat_interior) "afo" = ( /obj/machinery/door/airlock/external{ name = "Escape Pod Three" @@ -2377,6 +2484,39 @@ }, /turf/open/space/basic, /area/space) +"afq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/grimy, +/area/ai_monitored/turret_protected/aisat_interior) +"afr" = ( +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers, +/turf/open/floor/plasteel/grimy, +/area/ai_monitored/turret_protected/aisat_interior) +"afs" = ( +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_x = -31 + }, +/obj/machinery/computer/monitor{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat_interior) "aft" = ( /obj/machinery/atmospherics/pipe/simple/general/visible{ dir = 5 @@ -2687,6 +2827,15 @@ /obj/machinery/atmospherics/pipe/manifold4w/general/visible, /turf/open/floor/plasteel, /area/engine/atmos) +"age" = ( +/obj/structure/chair/office/dark{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/grimy, +/area/ai_monitored/turret_protected/aisat_interior) "agf" = ( /obj/structure/table, /obj/item/stack/sheet/metal, @@ -2836,6 +2985,10 @@ /obj/machinery/suit_storage_unit/security, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) +"agv" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/grimy, +/area/ai_monitored/turret_protected/aisat_interior) "agw" = ( /obj/structure/table, /obj/machinery/syndicatebomb/training, @@ -2965,6 +3118,14 @@ }, /turf/open/floor/plasteel, /area/security/main) +"agH" = ( +/obj/machinery/bluespace_beacon, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/landmark/start/cyborg, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat_interior) "agI" = ( /obj/machinery/airalarm{ pixel_y = 23 @@ -3094,6 +3255,12 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/security/warden) +"agX" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/plasteel/grimy, +/area/ai_monitored/turret_protected/aisat_interior) "agY" = ( /obj/structure/table, /obj/item/storage/fancy/donut_box, @@ -3334,6 +3501,16 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) +"ahw" = ( +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/grimy, +/area/ai_monitored/turret_protected/aisat_interior) "ahx" = ( /obj/structure/cable{ icon_state = "4-8" @@ -4474,6 +4651,16 @@ /obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/brig) +"ajC" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/grimy, +/area/ai_monitored/turret_protected/aisat_interior) "ajD" = ( /obj/structure/cable{ icon_state = "4-8" @@ -4682,6 +4869,18 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, /area/maintenance/solars/port/fore) +"ajX" = ( +/obj/machinery/computer/teleporter{ + dir = 8 + }, +/turf/open/floor/plating, +/area/ai_monitored/turret_protected/aisat_interior) +"ajY" = ( +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/landmark/start/cyborg, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat/atmos) "ajZ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/sign/warning/vacuum/external{ @@ -4965,6 +5164,18 @@ }, /turf/open/floor/plasteel, /area/security/courtroom) +"akz" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/holopad, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/landmark/start/cyborg, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat_interior) "akA" = ( /obj/structure/chair{ dir = 8; @@ -7639,7 +7850,7 @@ /turf/open/floor/wood, /area/lawoffice) "asa" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/red{ @@ -13505,7 +13716,7 @@ /turf/open/floor/plating, /area/chapel/main) "aHu" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /turf/open/floor/plasteel/white/corner{ @@ -16546,7 +16757,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/locker) "aPE" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/crew_quarters/locker) "aPF" = ( @@ -16637,7 +16848,7 @@ /obj/structure/cable{ icon_state = "0-8" }, -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ id = "bridge blast"; @@ -16669,7 +16880,7 @@ /obj/structure/cable{ icon_state = "0-4" }, -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ id = "bridge blast"; @@ -17945,7 +18156,7 @@ /area/hallway/secondary/exit) "aTl" = ( /obj/machinery/vending/cola/random, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ layer = 4; pixel_y = 32 }, @@ -17986,7 +18197,7 @@ /area/hallway/secondary/exit) "aTr" = ( /obj/machinery/door/firedoor, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /turf/open/floor/plasteel, @@ -21160,7 +21371,7 @@ /turf/open/floor/plasteel, /area/quartermaster/warehouse) "baZ" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ layer = 4; pixel_y = 32 }, @@ -21317,7 +21528,7 @@ /turf/open/floor/wood, /area/crew_quarters/heads/captain) "bbv" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/cable{ @@ -21953,7 +22164,7 @@ dir = 4 }, /obj/structure/disposalpipe/segment, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/blue{ @@ -22854,7 +23065,7 @@ /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai_upload) "bfw" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai_upload) "bfx" = ( @@ -24852,7 +25063,7 @@ /obj/machinery/light{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/aug_manipulator, @@ -27115,7 +27326,7 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bpw" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/medical/medbay/central) "bpx" = ( @@ -28423,7 +28634,7 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bsz" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /turf/open/floor/plasteel/white/side{ @@ -29979,17 +30190,6 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/central) -"bwc" = ( -/obj/structure/disposalpipe/segment, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/quartermaster/office) "bwd" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -32396,7 +32596,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /turf/open/floor/plasteel, @@ -35271,7 +35471,7 @@ /area/medical/sleeper) "bIe" = ( /obj/structure/disposalpipe/segment, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -42391,7 +42591,7 @@ /turf/open/floor/plating, /area/tcommsat/computer) "bZr" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/tcommsat/computer) "bZs" = ( @@ -49288,47 +49488,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) -"ctu" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/obj/effect/landmark/start/cyborg, -/turf/open/floor/plasteel/grimy, -/area/ai_monitored/turret_protected/aisat_interior) "ctv" = ( /turf/closed/wall/r_wall, /area/space/nearstation) -"ctw" = ( -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -23 - }, -/obj/machinery/computer/station_alert, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/turret_protected/aisat_interior) -"ctx" = ( -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers, -/obj/effect/landmark/start/cyborg, -/turf/open/floor/plasteel/grimy, -/area/ai_monitored/turret_protected/aisat_interior) -"cty" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/effect/landmark/start/cyborg, -/turf/open/floor/plasteel/grimy, -/area/ai_monitored/turret_protected/aisat_interior) "ctz" = ( /obj/machinery/door/poddoor/shutters{ id = "teledoor"; @@ -49373,41 +49535,6 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) -"ctG" = ( -/obj/structure/chair/office/dark{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/effect/landmark/start/cyborg, -/turf/open/floor/plasteel/grimy, -/area/ai_monitored/turret_protected/aisat_interior) -"ctH" = ( -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_x = -31 - }, -/obj/machinery/computer/monitor, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/turret_protected/aisat_interior) -"ctI" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/landmark/start/cyborg, -/turf/open/floor/plasteel/grimy, -/area/ai_monitored/turret_protected/aisat_interior) "ctJ" = ( /obj/machinery/holopad, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -49431,13 +49558,6 @@ }, /turf/open/floor/plating, /area/ai_monitored/turret_protected/aisat_interior) -"ctM" = ( -/obj/machinery/bluespace_beacon, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/turret_protected/aisat_interior) "ctN" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 10 @@ -49445,13 +49565,6 @@ /obj/structure/lattice, /turf/open/space, /area/space/nearstation) -"ctP" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/obj/effect/landmark/start/cyborg, -/turf/open/floor/plasteel/grimy, -/area/ai_monitored/turret_protected/aisat_interior) "ctQ" = ( /obj/structure/table, /obj/machinery/microwave{ @@ -49477,28 +49590,6 @@ /obj/structure/sign/warning/radiation/rad_area, /turf/closed/wall, /area/engine/engineering) -"ctS" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/effect/landmark/start/cyborg, -/turf/open/floor/plasteel/grimy, -/area/ai_monitored/turret_protected/aisat_interior) -"ctT" = ( -/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/effect/landmark/start/cyborg, -/turf/open/floor/plasteel/grimy, -/area/ai_monitored/turret_protected/aisat_interior) "ctU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -49521,10 +49612,6 @@ /obj/structure/chair, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) -"ctW" = ( -/obj/machinery/computer/teleporter, -/turf/open/floor/plating, -/area/ai_monitored/turret_protected/aisat_interior) "ctX" = ( /obj/machinery/camera{ c_tag = "MiniSat Teleporter"; @@ -49561,7 +49648,7 @@ /area/ai_monitored/turret_protected/aisat_interior) "cuc" = ( /obj/structure/rack, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/item/storage/box/donkpockets, @@ -49805,11 +49892,6 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat/atmos) -"cuC" = ( -/obj/machinery/holopad, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/turret_protected/aisat/atmos) "cuD" = ( /obj/machinery/light/small{ dir = 8 @@ -49858,17 +49940,6 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) -"cuG" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/machinery/holopad, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/turret_protected/aisat_interior) "cuH" = ( /obj/machinery/light/small{ dir = 8 @@ -50157,7 +50228,7 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "cvf" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai) "cvg" = ( @@ -50682,7 +50753,7 @@ /obj/machinery/light{ dir = 8 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /turf/open/floor/circuit, @@ -53259,13 +53330,6 @@ }, /turf/open/floor/mineral/titanium/blue, /area/crew_quarters/dorms) -"dkk" = ( -/obj/machinery/photocopier{ - pixel_x = -5; - pixel_y = -5 - }, -/turf/open/floor/wood, -/area/library) "dok" = ( /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" @@ -53620,10 +53684,6 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"eZP" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/space/basic, -/area/hallway/secondary/entry) "fbm" = ( /obj/structure/chair/comfy/brown{ dir = 4 @@ -53696,18 +53756,6 @@ dir = 1 }, /area/crew_quarters/fitness) -"fsk" = ( -/obj/structure/lattice/catwalk, -/obj/item/stack/marker_beacon{ - anchored = 1; - icon_state = "markerburgundy-on"; - light_power = 3; - light_range = 3; - name = "Docking Beacon"; - picked_color = "Burgundy" - }, -/turf/open/floor/plating, -/area/space/nearstation) "ftv" = ( /obj/structure/table, /obj/effect/spawner/lootdrop/maintenance{ @@ -54207,18 +54255,6 @@ dir = 1 }, /area/crew_quarters/fitness) -"hho" = ( -/obj/structure/lattice/catwalk, -/obj/item/stack/marker_beacon{ - anchored = 1; - icon_state = "markerburgundy-on"; - light_power = 3; - light_range = 3; - name = "Docking Beacon"; - picked_color = "Burgundy" - }, -/turf/open/space/basic, -/area/space/nearstation) "hik" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ @@ -54443,9 +54479,6 @@ "iiW" = ( /turf/open/floor/wood, /area/maintenance/bar) -"ikx" = ( -/turf/open/floor/plating/foam, -/area/space/nearstation) "ilJ" = ( /obj/effect/turf_decal/tile/red, /obj/machinery/light{ @@ -55682,10 +55715,6 @@ /obj/structure/extinguisher_cabinet, /turf/closed/wall/r_wall, /area/hallway/primary/central) -"mwb" = ( -/obj/effect/spawner/structure/window/shuttle, -/turf/open/floor/plating, -/area/space/nearstation) "mwO" = ( /obj/structure/cable{ icon_state = "1-4" @@ -56493,7 +56522,8 @@ icon_state = "4-8" }, /obj/machinery/door/airlock/command{ - name = "Command Access To Vault" + name = "Command Access To Vault"; + req_access = "19" }, /turf/open/floor/plasteel/dark, /area/bridge/meeting_room) @@ -56807,10 +56837,6 @@ /obj/item/target/syndicate, /turf/open/floor/plating, /area/security/prison) -"rxH" = ( -/obj/structure/girder, -/turf/open/floor/plating, -/area/space/nearstation) "rzg" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -57257,12 +57283,6 @@ }, /turf/open/floor/plating, /area/maintenance/port/aft) -"thr" = ( -/obj/structure/frame/computer{ - dir = 1 - }, -/turf/open/floor/plating, -/area/space/nearstation) "tkU" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" @@ -58006,10 +58026,10 @@ }, /obj/item/clothing/head/russobluecamohat, /obj/item/clothing/head/russobluecamohat, -/obj/item/clothing/head/russofurhat, -/obj/item/clothing/head/russofurhat, -/obj/item/clothing/head/russofurhat, -/obj/item/clothing/head/russofurhat, +/obj/item/clothing/head/helmet/rus_ushanka, +/obj/item/clothing/head/helmet/rus_ushanka, +/obj/item/clothing/head/helmet/rus_ushanka, +/obj/item/clothing/head/helmet/rus_ushanka, /obj/item/clothing/under/mw2_russian_para, /obj/item/clothing/under/mw2_russian_para, /obj/item/clothing/under/mw2_russian_para, @@ -58558,10 +58578,6 @@ }, /turf/open/space/basic, /area/space/nearstation) -"xWM" = ( -/obj/structure/grille/broken, -/turf/open/floor/plating, -/area/space/nearstation) "xXY" = ( /obj/structure/closet/lasertag/red, /obj/item/clothing/under/pj/red, @@ -64627,11 +64643,11 @@ aaa aaa aaa aaa -fsk +aaK aaa aaa aaa -fsk +aaK aaa aaa aaa @@ -64878,9 +64894,9 @@ aaa aaa aaa aaa -fsk +aaK aaa -fsk +aaK aaa aaa aaa @@ -64892,9 +64908,9 @@ gXs aaa aaa aaa -fsk +aaK aaa -fsk +aaK aaa aaa aaa @@ -67472,9 +67488,9 @@ aaa aaa aaa aaf -eZP +awW auP -eZP +awW aaf vZs aaa @@ -81107,7 +81123,7 @@ bpB bpB brR bsV -bwc +aaM bxA bvI bwX @@ -95692,9 +95708,9 @@ aaa aaa aaa aaa -hho +aaz aaa -hho +aaz aaa aaa aaa @@ -96076,7 +96092,7 @@ aaf ctZ cui cuq -cuC +ajY cuO cuz cvm @@ -96584,8 +96600,8 @@ czk cti cua cua -ctw -ctH +aeF +afs ctQ cuc cuj @@ -96841,9 +96857,9 @@ ctb cth cua ctr -ctu -ctG -ctP +afn +age +agX cub cuj cur @@ -97098,13 +97114,13 @@ ctc ctc cto ctt -cty +afq ctJ -ctT +ahw cue cul cuu -cuG +akz cuS cve cvo @@ -97355,9 +97371,9 @@ ctb ctj ctk cts -ctx -ctI -ctS +afr +agv +ajC cud cuk cus @@ -98127,7 +98143,7 @@ aaa aaf cua ctF -ctM +agH ctX cuf cum @@ -98385,7 +98401,7 @@ aaf cua ctE ctL -ctW +ajX cuf cum cuw @@ -101383,7 +101399,7 @@ bbE aIr bav aLf -dkk +aaL kLR aRO aQp @@ -101965,10 +101981,10 @@ aaa aaa aaa aaa -ikx -mwb -xWM -rxH +aaH +adO +aeD +aeE aaa aaa aaa @@ -102223,10 +102239,10 @@ xNY kvb aaa aaa -ikx -ikx -ikx -rxH +aaH +aaH +aaH +aeE aaa aaa aaa @@ -102477,13 +102493,13 @@ czZ cOT aaa jmC -dbM -dbM -ikx -ikx -ikx -thr -mwb +aaH +aaH +aaH +aaH +aaH +aaH +adO aaa aaa aaa @@ -102736,8 +102752,8 @@ gXs xNY kvb gJg -dbM -dbM +aaH +aaH aaa aaa gJg @@ -102994,8 +103010,8 @@ aaa aaa gJg gJg -mwb -ikx +adO +aaH gXs aaa aaa @@ -106076,7 +106092,7 @@ cNW clt cQw cNW -cNW +abG cNW cNW aaf @@ -106332,7 +106348,7 @@ aaa cOT clt cQw -cOe +aaO cOe cOe cNW @@ -106589,11 +106605,11 @@ aaa cOT clt cQw +aaQ cOe cOe -cOe -cOe -sQX +cNW +aaa jzi jzi jzi @@ -106846,11 +106862,11 @@ aaa cNW clt cQw -cOe +bNB cOe cOe cNW -aaf +lCL aaS aaa aaf @@ -107103,7 +107119,7 @@ cNW cNW clt cQw -cOe +aaY cOe cOe cNW diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index f29c6afa46..f4135b7566 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -620,7 +620,7 @@ /turf/open/space, /area/solar/starboard/fore) "acV" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/light{ @@ -635,7 +635,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "acW" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/light{ @@ -655,7 +655,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "acX" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/light{ @@ -667,7 +667,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "acY" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/light{ @@ -684,7 +684,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "adb" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/light{ @@ -701,7 +701,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "adc" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/light{ @@ -998,7 +998,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "aeB" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/construction/mining/aux_base) "aeC" = ( @@ -1722,7 +1722,7 @@ /turf/open/floor/plasteel, /area/construction/mining/aux_base) "ahO" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/light{ @@ -1735,7 +1735,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "ahP" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/light{ @@ -1753,7 +1753,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "ahR" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/light{ @@ -1766,7 +1766,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "ahS" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/light{ @@ -1784,7 +1784,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "ahW" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/light{ @@ -1802,7 +1802,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/entry) "ahX" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/light{ @@ -3055,7 +3055,7 @@ /turf/open/floor/plasteel, /area/security/vacantoffice) "akC" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/security/vacantoffice) "akD" = ( @@ -3485,7 +3485,7 @@ /turf/closed/wall, /area/hallway/secondary/entry) "aly" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/hallway/secondary/entry) "alz" = ( @@ -4184,7 +4184,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/electronic_marketing_den) "amP" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/light/small{ @@ -4217,7 +4217,7 @@ /turf/open/floor/wood, /area/crew_quarters/electronic_marketing_den) "amU" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/light/small{ @@ -4307,7 +4307,7 @@ /turf/open/floor/carpet, /area/security/vacantoffice) "ang" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/structure/frame/computer, @@ -4470,7 +4470,7 @@ /obj/machinery/computer/prisoner/management{ dir = 8 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/camera{ @@ -5433,7 +5433,7 @@ /obj/machinery/computer/med_data{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/blue{ @@ -5915,7 +5915,7 @@ /area/crew_quarters/electronic_marketing_den) "apY" = ( /obj/structure/frame/computer, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -9221,7 +9221,7 @@ /turf/open/floor/plasteel, /area/janitor) "avA" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/bot, @@ -9290,7 +9290,7 @@ /area/janitor) "avD" = ( /obj/structure/table/reinforced, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/item/clipboard, @@ -9566,7 +9566,7 @@ /turf/open/floor/plating, /area/engine/supermatter) "awi" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/engine/supermatter) "awj" = ( @@ -10599,7 +10599,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/toilet/auxiliary) "ayd" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/neutral, @@ -12334,7 +12334,7 @@ }) "aBm" = ( /obj/item/twohanded/required/kirbyplants/random, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/delivery, @@ -13659,7 +13659,7 @@ /area/hallway/secondary/service) "aDF" = ( /obj/structure/bed, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/item/bedsheet/clown, @@ -14298,7 +14298,7 @@ /area/crew_quarters/bar) "aER" = ( /obj/structure/closet/secure_closet/bar, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/light/small{ @@ -14358,7 +14358,7 @@ /area/crew_quarters/bar) "aEW" = ( /obj/machinery/vending/boozeomat, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /turf/open/floor/plasteel/dark, @@ -14391,7 +14391,7 @@ /area/crew_quarters/bar) "aEY" = ( /obj/structure/table/wood, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/item/clipboard, @@ -14830,7 +14830,7 @@ name = "Maintenance Garden" }) "aFM" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/delivery, @@ -15204,7 +15204,7 @@ /turf/open/floor/plating, /area/quartermaster/sorting) "aGu" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/reagent_dispensers/peppertank{ @@ -15746,7 +15746,7 @@ /turf/open/floor/plasteel, /area/engine/atmospherics_engine) "aHa" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/machinery/light, @@ -16821,7 +16821,7 @@ /area/hallway/secondary/service) "aIP" = ( /obj/structure/bed, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/item/bedsheet/mime, @@ -16906,7 +16906,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/bar) "aIY" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/crew_quarters/bar) "aIZ" = ( @@ -18124,7 +18124,7 @@ icon_state = "0-8" }, /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -18156,7 +18156,7 @@ /turf/closed/wall/r_wall, /area/maintenance/disposal/incinerator) "aLd" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/atmospherics/components/unary/portables_connector/visible, @@ -18353,7 +18353,7 @@ name = "Engineering Power Monitoring Console" }, /obj/structure/cable/white, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -19179,7 +19179,7 @@ /area/hallway/secondary/service) "aNa" = ( /obj/structure/table/wood, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/item/camera_film{ @@ -19243,7 +19243,7 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/easel, @@ -19356,7 +19356,7 @@ /turf/open/floor/plasteel, /area/quartermaster/sorting) "aNo" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/quartermaster/sorting) "aNp" = ( @@ -19913,7 +19913,7 @@ /turf/open/floor/plasteel, /area/engine/atmos) "aOh" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/light/small{ @@ -20080,7 +20080,7 @@ /obj/machinery/newscaster{ pixel_y = 32 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/red{ @@ -22793,7 +22793,7 @@ dir = 4; pixel_x = -23 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/item/reagent_containers/glass/bottle/morphine{ @@ -24043,7 +24043,7 @@ /turf/open/floor/plasteel, /area/quartermaster/qm) "aUs" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/camera{ @@ -25784,7 +25784,7 @@ /turf/closed/wall, /area/engine/atmos) "aWK" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/engine/atmos) "aWL" = ( @@ -26522,7 +26522,7 @@ /area/security/prison) "aXM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/security/prison) "aXN" = ( @@ -27066,7 +27066,7 @@ /turf/closed/wall, /area/crew_quarters/kitchen) "aYD" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/crew_quarters/kitchen) "aYE" = ( @@ -28509,7 +28509,7 @@ /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "baX" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/quartermaster/qm) "baY" = ( @@ -29246,7 +29246,7 @@ /turf/open/floor/plasteel, /area/quartermaster/office) "bcr" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/quartermaster/office) "bcs" = ( @@ -29578,7 +29578,7 @@ /obj/structure/closet/secure_closet/brig{ name = "Prisoner Locker" }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -33053,7 +33053,7 @@ /obj/machinery/computer/security{ dir = 8 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -34463,7 +34463,7 @@ /turf/open/floor/plasteel/dark, /area/engine/atmos) "bkY" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/light/small{ @@ -34513,7 +34513,7 @@ /area/maintenance/port/fore) "bld" = ( /obj/machinery/hydroponics/constructable, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/delivery, @@ -34680,7 +34680,7 @@ /area/crew_quarters/kitchen) "bls" = ( /obj/machinery/light, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/machinery/vending/dinnerware, @@ -35363,7 +35363,7 @@ "bmB" = ( /obj/structure/bed, /obj/item/bedsheet/hos, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/camera{ @@ -35888,7 +35888,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "bnx" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/hallway/primary/fore) "bny" = ( @@ -36362,7 +36362,7 @@ /obj/machinery/atmospherics/pipe/manifold/cyan/visible{ dir = 8 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /turf/open/floor/plating, @@ -36542,7 +36542,7 @@ /turf/open/floor/plasteel, /area/hydroponics) "boD" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/hydroponics) "boE" = ( @@ -36856,7 +36856,7 @@ /area/security/execution/transfer) "bpf" = ( /obj/machinery/computer/shuttle/labor, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/red{ @@ -39782,7 +39782,7 @@ /turf/open/floor/plasteel/grimy, /area/crew_quarters/heads/hos) "btA" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32; pixel_y = -32 }, @@ -40141,7 +40141,7 @@ /turf/open/floor/plasteel, /area/engine/atmos) "buf" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall/r_wall, /area/engine/atmos) @@ -40254,7 +40254,7 @@ /turf/open/floor/plating, /area/hallway/primary/central) "bur" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/hallway/primary/central) "bus" = ( @@ -41463,7 +41463,7 @@ /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "bwy" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/engine/atmos) "bwz" = ( @@ -42212,7 +42212,7 @@ /turf/closed/wall/r_wall, /area/engine/break_room) "bxH" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, @@ -42574,7 +42574,7 @@ /area/bridge) "byn" = ( /obj/structure/table/reinforced, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/item/storage/toolbox/mechanical, @@ -43177,7 +43177,7 @@ /obj/structure/table/reinforced, /obj/item/storage/toolbox/electrical, /obj/item/wrench/power, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/bot, @@ -43309,7 +43309,7 @@ /turf/closed/wall/r_wall, /area/engine/break_room) "bzt" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/structure/cable/white{ @@ -44096,7 +44096,7 @@ /turf/open/floor/plasteel/dark, /area/aisat) "bAx" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai) "bAy" = ( @@ -44284,7 +44284,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -45837,7 +45837,7 @@ /obj/effect/decal/cleanable/dirt, /obj/item/paper_bin, /obj/item/pen, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/machinery/requests_console{ @@ -46136,7 +46136,7 @@ /turf/open/floor/plasteel, /area/storage/primary) "bDu" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/storage/primary) "bDv" = ( @@ -47422,7 +47422,7 @@ /area/hallway/primary/port) "bES" = ( /obj/item/twohanded/required/kirbyplants/random, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -48334,7 +48334,7 @@ /turf/open/floor/plasteel, /area/engine/gravity_generator) "bGe" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32; pixel_y = -32 }, @@ -48507,7 +48507,7 @@ /turf/open/floor/plasteel, /area/engine/break_room) "bGr" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32; pixel_y = 32 }, @@ -48707,7 +48707,7 @@ /obj/structure/rack, /obj/item/airlock_painter, /obj/item/toner, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/bot, @@ -49450,7 +49450,7 @@ /area/engine/gravity_generator) "bHP" = ( /obj/machinery/light, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -49544,7 +49544,7 @@ /turf/closed/wall, /area/engine/break_room) "bHX" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/engine/break_room) "bHY" = ( @@ -50064,7 +50064,7 @@ /turf/open/floor/plasteel/dark, /area/bridge) "bIN" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/bridge) "bIO" = ( @@ -51288,7 +51288,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "bKy" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/newscaster{ @@ -51457,7 +51457,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/captain) "bKS" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -51998,7 +51998,7 @@ /turf/open/floor/plasteel/dark, /area/engine/transit_tube) "bLH" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/engine/transit_tube) "bLI" = ( @@ -52432,7 +52432,7 @@ /area/storage/tech) "bMj" = ( /obj/item/twohanded/required/kirbyplants/random, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -52458,7 +52458,7 @@ pixel_x = 3; pixel_y = -3 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/bot, @@ -53524,7 +53524,7 @@ /obj/machinery/computer/card/minor/ce{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -53711,7 +53711,7 @@ /turf/open/floor/plasteel, /area/engine/break_room) "bOd" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/yellow, @@ -54108,7 +54108,7 @@ /obj/machinery/computer/telecomms/monitor{ dir = 8 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -54372,7 +54372,7 @@ /obj/machinery/light{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /turf/open/floor/carpet, @@ -54654,7 +54654,7 @@ /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/aisat_interior) "bPI" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/aisat_interior) "bPJ" = ( @@ -56117,7 +56117,7 @@ /area/crew_quarters/heads/chief) "bSg" = ( /obj/structure/dresser, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /turf/open/floor/plasteel/grimy, @@ -57235,7 +57235,7 @@ /obj/machinery/computer/station_alert{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -57942,7 +57942,7 @@ /area/crew_quarters/heads/captain) "bUP" = ( /obj/structure/table/wood, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/item/coin/adamantine{ @@ -60905,7 +60905,7 @@ pixel_x = 26; pixel_y = -32 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/recharger, @@ -61752,7 +61752,7 @@ /area/ai_monitored/turret_protected/aisat_interior) "cac" = ( /obj/machinery/recharge_station, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/stripes/line{ @@ -61895,7 +61895,7 @@ "cal" = ( /obj/structure/table/reinforced, /obj/item/paper_bin, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/item/pen, @@ -62226,7 +62226,7 @@ /area/crew_quarters/heads/hop) "caS" = ( /obj/machinery/pdapainter, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -63159,7 +63159,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "ccz" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/crew_quarters/heads/hop) "ccA" = ( @@ -64330,7 +64330,7 @@ /obj/structure/table/wood, /obj/item/paper_bin, /obj/item/pen, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -64591,7 +64591,7 @@ /obj/structure/table/wood, /obj/item/folder/blue, /obj/item/pen/fourcolor, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -65289,7 +65289,7 @@ /obj/machinery/light{ dir = 8 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/stripes/line{ @@ -66588,7 +66588,7 @@ pixel_x = -24; pixel_y = -32 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/structure/cable/white{ @@ -67083,7 +67083,7 @@ /area/lawoffice) "ciy" = ( /obj/machinery/photocopier, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/camera{ @@ -67301,7 +67301,7 @@ /area/security/brig) "ciL" = ( /obj/structure/closet/secure_closet/security/sec, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/structure/cable/white{ @@ -68044,7 +68044,7 @@ /turf/open/floor/plasteel, /area/security/courtroom) "ckd" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/camera{ @@ -68181,7 +68181,7 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai_upload) "cko" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32; pixel_y = -32 }, @@ -68218,7 +68218,7 @@ /turf/open/floor/circuit/green, /area/ai_monitored/turret_protected/ai_upload) "cks" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32; pixel_y = -32 }, @@ -70115,7 +70115,7 @@ /turf/closed/wall/r_wall, /area/engine/engineering) "cnD" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/engine/engineering) "cnE" = ( @@ -70156,7 +70156,7 @@ /turf/open/floor/plasteel, /area/engine/engineering) "cnH" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/engine/engineering) "cnI" = ( @@ -70506,7 +70506,7 @@ /area/teleporter) "cor" = ( /obj/machinery/teleport/station, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -71327,7 +71327,7 @@ /area/teleporter) "cpV" = ( /obj/structure/table, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/item/paper_bin, @@ -71766,7 +71766,7 @@ /area/library) "cqU" = ( /obj/machinery/libraryscanner, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /turf/open/floor/plasteel/grimy, @@ -72058,7 +72058,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/locker) "crs" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/crew_quarters/locker) "crt" = ( @@ -72935,7 +72935,7 @@ dir = 1; name = "Jury" }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -74329,7 +74329,7 @@ /turf/open/floor/plasteel/grimy, /area/library) "cvk" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/library) "cvl" = ( @@ -74972,7 +74972,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -75859,7 +75859,7 @@ /area/engine/storage) "cxL" = ( /obj/machinery/suit_storage_unit/engine, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/stripes/line{ @@ -76343,7 +76343,7 @@ /obj/machinery/gateway{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/decal/cleanable/dirt, @@ -76578,7 +76578,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/locker) "cyW" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -77058,7 +77058,7 @@ /obj/structure/table/wood, /obj/item/paper_bin, /obj/item/pen, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -78070,7 +78070,7 @@ /turf/open/floor/plasteel/dark, /area/bridge/showroom/corporate) "cBu" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -78615,7 +78615,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /turf/open/floor/wood, @@ -78645,7 +78645,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/spawner/lootdrop/bedsheet, @@ -78951,7 +78951,7 @@ pixel_y = 3 }, /obj/item/newspaper, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -79679,7 +79679,7 @@ /turf/open/floor/plating, /area/crew_quarters/fitness/recreation) "cDR" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -79717,7 +79717,7 @@ /obj/machinery/light{ dir = 8 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/stripes/line{ @@ -80011,7 +80011,7 @@ "cEs" = ( /obj/machinery/light, /obj/structure/dresser, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -80514,7 +80514,7 @@ }, /area/crew_quarters/toilet/restrooms) "cFj" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/structure/cable/white{ @@ -80540,7 +80540,7 @@ /area/crew_quarters/toilet/restrooms) "cFl" = ( /obj/machinery/light, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/structure/cable/white{ @@ -81105,7 +81105,7 @@ /turf/open/floor/plasteel, /area/ai_monitored/storage/eva) "cGm" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/stripes/line{ @@ -81688,7 +81688,7 @@ /area/engine/storage) "cHr" = ( /obj/structure/reagent_dispensers/watertank, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/bot, @@ -82182,7 +82182,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/fitness/recreation) "cIo" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/crew_quarters/fitness/recreation) "cIp" = ( @@ -85300,7 +85300,7 @@ /turf/open/floor/plasteel, /area/science/research) "cNs" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/science/research) "cNt" = ( @@ -85387,7 +85387,7 @@ /turf/open/floor/plasteel, /area/medical/medbay/central) "cNB" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/medical/medbay/central) "cNC" = ( @@ -86958,7 +86958,7 @@ dir = 4; pixel_x = -24 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/extinguisher_cabinet{ @@ -87536,7 +87536,7 @@ /turf/open/floor/plasteel, /area/maintenance/department/electrical) "cRE" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/maintenance/department/electrical) "cRF" = ( @@ -87699,7 +87699,7 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/cable/white{ @@ -88254,7 +88254,7 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "cSM" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/reagent_dispensers/peppertank{ @@ -88626,7 +88626,7 @@ /turf/open/floor/plasteel, /area/maintenance/port) "cTm" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/item/twohanded/required/kirbyplants/random, @@ -89691,7 +89691,7 @@ /obj/item/folder, /obj/item/pen, /obj/machinery/light, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/item/paicard, @@ -89712,7 +89712,7 @@ "cUX" = ( /obj/structure/bed, /obj/machinery/light, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/spawner/lootdrop/bedsheet, @@ -89749,7 +89749,7 @@ name = "trenchcoat" }, /obj/item/clothing/suit/toggle/lawyer/black, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/item/clothing/head/fedora, @@ -89856,7 +89856,7 @@ /turf/open/floor/plating, /area/crew_quarters/fitness/recreation) "cVj" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -90566,7 +90566,7 @@ }, /obj/item/storage/box/syringes, /obj/item/gun/syringe, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/structure/window/reinforced, @@ -90619,7 +90619,7 @@ pixel_x = -3; pixel_y = 2 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/firealarm{ @@ -91099,7 +91099,7 @@ /obj/machinery/computer/camera_advanced/xenobio{ dir = 8 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /turf/open/floor/circuit/green, @@ -91250,7 +91250,7 @@ /obj/structure/table, /obj/item/gps, /obj/item/assembly/flash/handheld, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/purple, @@ -91870,7 +91870,7 @@ "cYE" = ( /obj/machinery/power/smes, /obj/machinery/light/small, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/stripes/line{ @@ -91893,7 +91893,7 @@ "cYH" = ( /obj/machinery/power/smes, /obj/machinery/light/small, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/decal/cleanable/dirt, @@ -93248,7 +93248,7 @@ dir = 1 }, /obj/item/twohanded/required/kirbyplants/random, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/purple{ @@ -93616,7 +93616,7 @@ /area/medical/medbay/central) "dbz" = ( /obj/machinery/vending/cola/random, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/light{ @@ -94444,7 +94444,7 @@ pixel_x = 3; pixel_y = 3 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/yellow{ @@ -95332,7 +95332,7 @@ /turf/open/floor/plasteel/white, /area/medical/chemistry) "der" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/medical/chemistry) "des" = ( @@ -98493,7 +98493,7 @@ /area/science/explab) "djG" = ( /obj/structure/filingcabinet/chestdrawer, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/bot, @@ -98705,7 +98705,7 @@ /obj/item/storage/toolbox/mechanical, /obj/item/stack/cable_coil/white, /obj/item/stack/cable_coil/white, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -99134,7 +99134,7 @@ /area/medical/abandoned) "dkK" = ( /obj/structure/table/reinforced, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/item/storage/firstaid/regular, @@ -99165,7 +99165,7 @@ /area/medical/abandoned) "dkM" = ( /obj/structure/table/reinforced, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/item/reagent_containers/blood/random, @@ -99737,7 +99737,7 @@ /turf/closed/wall, /area/medical/surgery) "dmb" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/medical/surgery) "dmc" = ( @@ -100285,7 +100285,7 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -102730,7 +102730,7 @@ /turf/closed/wall/r_wall, /area/science/explab) "drL" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/science/explab) "drM" = ( @@ -103377,7 +103377,7 @@ /area/crew_quarters/abandoned_gambling_den) "dta" = ( /obj/structure/table/wood, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/item/book/manual/wiki/engineering_hacking, @@ -103584,7 +103584,7 @@ /area/science/research) "dtw" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/bot, @@ -104467,7 +104467,7 @@ /turf/open/floor/plasteel/white, /area/medical/genetics) "dvi" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/medical/genetics) "dvj" = ( @@ -105182,7 +105182,7 @@ dir = 8 }, /obj/machinery/light, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/keycard_auth{ @@ -106597,7 +106597,7 @@ /obj/machinery/computer/crew{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/blue, @@ -106665,7 +106665,7 @@ /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyJ" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -106854,7 +106854,7 @@ /area/crew_quarters/abandoned_gambling_den) "dze" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/delivery, @@ -107749,7 +107749,7 @@ }, /obj/structure/bed, /obj/item/bedsheet/rd, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/purple, @@ -109302,7 +109302,7 @@ pixel_y = 2 }, /obj/structure/table/reinforced, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/stripes/corner{ @@ -109900,7 +109900,7 @@ /area/medical/medbay/central) "dEg" = ( /obj/structure/filingcabinet/chestdrawer, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/blue{ @@ -110678,7 +110678,7 @@ "dFB" = ( /obj/structure/table, /obj/effect/decal/cleanable/dirt, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/item/crowbar, @@ -110763,7 +110763,7 @@ pixel_y = -2 }, /obj/structure/table/reinforced, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/stripes/corner, @@ -112799,7 +112799,7 @@ "dIR" = ( /obj/structure/table/optable, /obj/effect/decal/cleanable/blood/old, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/purple, @@ -114289,7 +114289,7 @@ /obj/machinery/light/small{ dir = 8 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /turf/open/floor/wood{ @@ -114340,7 +114340,7 @@ /obj/machinery/light/small{ dir = 8 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /turf/open/floor/plasteel/grimy, @@ -116346,7 +116346,7 @@ /obj/machinery/computer/med_data{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/blue{ @@ -116735,7 +116735,7 @@ "dPQ" = ( /obj/machinery/vending/cola/random, /obj/machinery/light, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -118303,7 +118303,7 @@ /obj/machinery/light{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/green{ @@ -118977,7 +118977,7 @@ /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/machinery/portable_atmospherics/canister/air, @@ -119222,7 +119222,7 @@ pixel_y = 3 }, /obj/item/reagent_containers/food/snacks/grown/poppy, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /turf/open/floor/plasteel/dark, @@ -119278,7 +119278,7 @@ pixel_y = 3 }, /obj/item/reagent_containers/food/snacks/grown/harebell, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /turf/open/floor/plasteel/dark, @@ -119705,7 +119705,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/item/twohanded/required/kirbyplants/random, @@ -121334,7 +121334,7 @@ /turf/open/floor/grass, /area/hallway/secondary/exit/departure_lounge) "dYF" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/hallway/secondary/exit/departure_lounge) "dYG" = ( @@ -121425,7 +121425,7 @@ /area/medical/virology) "dYT" = ( /obj/machinery/light, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/item/twohanded/required/kirbyplants/random, @@ -122739,7 +122739,7 @@ /turf/open/floor/plasteel/white, /area/medical/virology) "ebx" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/medical/virology) "eby" = ( @@ -123476,7 +123476,7 @@ /turf/open/floor/plasteel/dark, /area/chapel/main) "ecT" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/chapel/main) @@ -124214,7 +124214,7 @@ /turf/open/floor/plating, /area/security/checkpoint/escape) "eee" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/security/checkpoint/escape) "eef" = ( @@ -124430,7 +124430,7 @@ dir = 8; pixel_x = 24 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -125279,7 +125279,7 @@ name = "Chapel RC"; pixel_y = -32 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/camera{ @@ -125358,7 +125358,7 @@ /obj/machinery/computer/security{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/red{ @@ -126227,7 +126227,7 @@ /turf/open/floor/plasteel/dark, /area/maintenance/starboard/fore) "iwL" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/effect/turf_decal/tile/blue{ diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 5dedc7535c..9e6259c1fe 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -421,7 +421,7 @@ }, /area/security/prison) "abr" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/blue{ @@ -2472,7 +2472,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hos) "afj" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32; pixel_y = 32 }, @@ -2501,7 +2501,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hos) "afn" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32; pixel_y = 32 }, @@ -15058,7 +15058,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/red{ @@ -17819,7 +17819,7 @@ /obj/structure/chair{ name = "Judge" }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/light{ @@ -19088,7 +19088,7 @@ "aLO" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/machinery/portable_atmospherics/scrubber, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 30 }, /obj/effect/turf_decal/delivery, @@ -21087,7 +21087,7 @@ /obj/structure/cable/yellow{ icon_state = "0-4" }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/camera{ @@ -21381,7 +21381,7 @@ /obj/machinery/light{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = 32 }, /obj/machinery/flasher{ @@ -23713,7 +23713,7 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "aVm" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, @@ -23740,7 +23740,7 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai) "aVq" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/atmospherics/components/unary/vent_pump/on, @@ -23803,7 +23803,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/stripes/line{ @@ -24135,7 +24135,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -24359,7 +24359,7 @@ pixel_x = -25; pixel_y = 25 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/extinguisher_cabinet{ @@ -27493,7 +27493,7 @@ name = "Station Intercom (General)"; pixel_x = -29 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -28332,7 +28332,7 @@ /turf/open/floor/carpet, /area/crew_quarters/heads/captain/private) "bdI" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -30143,7 +30143,7 @@ /turf/open/floor/plasteel/dark, /area/bridge) "bhk" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/item/folder/yellow{ @@ -30795,7 +30795,7 @@ /obj/structure/chair/office/dark{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /turf/open/floor/plasteel/dark, @@ -32463,7 +32463,7 @@ /area/ai_monitored/turret_protected/aisat/foyer) "blC" = ( /obj/machinery/teleport/station, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -32572,7 +32572,7 @@ /area/ai_monitored/storage/satellite) "blK" = ( /obj/machinery/recharge_station, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/cable/yellow{ @@ -33091,7 +33091,7 @@ /area/crew_quarters/heads/captain/private) "bmJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/structure/disposalpipe/segment, @@ -34052,7 +34052,7 @@ /obj/structure/displaycase/captain{ pixel_y = 5 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /turf/open/floor/wood, @@ -35067,7 +35067,7 @@ /turf/open/floor/wood, /area/crew_quarters/heads/hop) "bqF" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/blue{ @@ -35947,7 +35947,7 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "bse" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/porta_turret/ai, @@ -36179,7 +36179,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = -32 }, /obj/effect/turf_decal/tile/neutral{ @@ -36283,7 +36283,7 @@ /turf/open/floor/carpet, /area/crew_quarters/heads/hop) "bsP" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/bed/dogbed/ian, @@ -37933,7 +37933,7 @@ /area/bridge) "bwu" = ( /obj/machinery/holopad, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/light{ @@ -39063,7 +39063,7 @@ }, /area/engine/atmos) "byS" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/light{ @@ -39533,7 +39533,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/command) "bzN" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/bot, @@ -40057,7 +40057,7 @@ "bAW" = ( /obj/structure/table/wood, /obj/item/folder/blue, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 31 }, /obj/item/folder/blue, @@ -41121,7 +41121,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, @@ -41265,7 +41265,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, @@ -44514,7 +44514,7 @@ /obj/machinery/gateway{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/bot_white, @@ -44934,7 +44934,7 @@ /area/maintenance/port) "bKY" = ( /obj/machinery/power/apc{ - areastring = "/area/vacant_room/office"; + areastring = "/area/security/vacantoffice"; dir = 8; name = "Vacant Office APC"; pixel_x = -25 @@ -45284,7 +45284,7 @@ /area/maintenance/central) "bLH" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/machinery/camera{ @@ -47211,6 +47211,7 @@ dir = 4 }, /obj/item/storage/box/lights/mixed, +/obj/structure/closet/firecloset, /turf/open/floor/plating{ icon_state = "platingdmg2" }, @@ -49141,7 +49142,7 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -49212,7 +49213,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -52536,7 +52537,7 @@ pixel_y = 4 }, /obj/item/pen, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/light/small{ @@ -59309,7 +59310,7 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "cnC" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/table/glass, @@ -62449,7 +62450,7 @@ }, /area/crew_quarters/heads/hor) "ctc" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/landmark/xmastree/rdrod, @@ -65397,7 +65398,7 @@ "cyO" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /turf/open/floor/plasteel/white/side, @@ -73011,7 +73012,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "cMU" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ layer = 4 }, /turf/closed/wall, @@ -76208,7 +76209,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 30 }, /obj/machinery/photocopier{ @@ -78349,7 +78350,7 @@ /turf/open/floor/plasteel/dark, /area/engine/engineering) "deD" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall/r_wall, /area/engine/supermatter) "deI" = ( @@ -79824,7 +79825,7 @@ /area/maintenance/aft) "diD" = ( /obj/machinery/vending/cigarette, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/sign/poster/official/random{ @@ -96215,7 +96216,7 @@ bMA alK bPD asa -pHS +alK aaa aaa aaf diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index b79f05cc69..d4b09ac046 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -74,842 +74,9 @@ "an" = ( /turf/closed/mineral/random/labormineral/volcanic, /area/lavaland/surface/outdoors) -"ao" = ( -/obj/machinery/power/apc{ - dir = 1; - name = "Labor Camp APC"; - pixel_y = 23 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plating, -/area/mine/laborcamp) -"ap" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/mine/laborcamp) -"aq" = ( -/turf/closed/wall, -/area/mine/laborcamp) -"ar" = ( -/obj/structure/table, -/turf/open/floor/plasteel/white, -/area/mine/laborcamp) -"as" = ( -/obj/structure/table, -/obj/item/storage/firstaid/regular, -/turf/open/floor/plasteel/white, -/area/mine/laborcamp) -"at" = ( -/obj/structure/bed, -/obj/item/bedsheet/medical, -/obj/machinery/camera{ - c_tag = "Labor Camp Medical"; - dir = 8; - network = list("labor") - }, -/turf/open/floor/plasteel/white, -/area/mine/laborcamp) -"au" = ( -/obj/structure/rack, -/obj/item/storage/bag/ore, -/obj/item/pickaxe, -/obj/item/flashlight, -/obj/item/clothing/glasses/meson, -/obj/item/mining_scanner, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"av" = ( -/obj/structure/rack, -/obj/item/storage/bag/ore, -/obj/item/flashlight, -/obj/item/pickaxe, -/obj/item/clothing/glasses/meson, -/obj/item/mining_scanner, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aw" = ( -/turf/open/lava/smooth/lava_land_surface, -/area/lavaland/surface/outdoors/explored) -"ax" = ( -/turf/open/floor/plasteel/white, -/area/mine/laborcamp) -"ay" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/mine/laborcamp) -"az" = ( -/turf/open/floor/plasteel, -/area/mine/laborcamp) "aA" = ( -/obj/machinery/portable_atmospherics/canister/oxygen, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aB" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Infirmary" - }, -/turf/open/floor/plasteel/white, -/area/mine/laborcamp) -"aC" = ( -/obj/structure/closet/crate/internals, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/clothing/mask/breath, -/obj/item/clothing/mask/breath, -/obj/item/clothing/mask/breath, -/obj/item/clothing/mask/breath, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aD" = ( -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/explored) -"aE" = ( -/obj/item/radio/intercom{ - desc = "Talk through this. It looks like it has been modified to not broadcast."; - name = "Prison Intercom (General)"; - pixel_y = 24; - prison_radio = 1 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aF" = ( -/obj/machinery/door/airlock{ - name = "Labor Camp Storage" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aG" = ( -/obj/structure/table, -/obj/item/trash/plate, -/obj/item/kitchen/fork, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aH" = ( -/obj/structure/chair{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aI" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock{ - name = "Labor Camp External Access" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aJ" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aK" = ( -/obj/structure/chair{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aL" = ( -/obj/machinery/door/airlock{ - name = "Vending" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aM" = ( -/obj/machinery/light/small, -/obj/effect/turf_decal/loading_area{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aN" = ( -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aO" = ( -/obj/machinery/camera{ - c_tag = "Labor Camp External"; - dir = 4; - network = list("labor") - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"aP" = ( -/obj/machinery/vending/sustenance, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aQ" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aR" = ( -/obj/machinery/shower{ - dir = 8 - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/white, -/area/mine/laborcamp) -"aS" = ( -/obj/machinery/mineral/unloading_machine{ - dir = 1; - icon_state = "unloader-corner"; - input_dir = 1; - output_dir = 2 - }, -/turf/open/floor/plating, -/area/mine/laborcamp) -"aT" = ( -/obj/structure/ore_box, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/explored) -"aU" = ( -/obj/machinery/flasher{ - id = "labor" - }, -/turf/closed/wall, -/area/mine/laborcamp) -"aV" = ( -/obj/machinery/door/airlock{ - name = "Restroom" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"aW" = ( -/obj/machinery/conveyor{ - id = "gulag" - }, -/turf/open/floor/plating, -/area/mine/laborcamp) -"aX" = ( -/obj/structure/closet/crate, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/explored) -"aY" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Shuttle Security Airlock"; - req_access_txt = "2" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"aZ" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/machinery/button/door{ - id = "labor"; - name = "Labor Camp Lockdown"; - pixel_y = 28; - req_access_txt = "2" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"ba" = ( -/obj/machinery/door/poddoor/preopen{ - id = "labor"; - name = "labor camp blast door" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"bb" = ( -/obj/machinery/camera{ - c_tag = "Labor Camp Central"; - network = list("labor") - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"bc" = ( -/obj/machinery/conveyor_switch/oneway{ - id = "gulag" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"bd" = ( -/obj/machinery/mineral/processing_unit_console, -/turf/closed/wall, -/area/mine/laborcamp) -"be" = ( -/obj/machinery/mineral/processing_unit{ - dir = 1 - }, -/turf/open/floor/plating, -/area/mine/laborcamp) -"bf" = ( -/turf/closed/wall, -/area/mine/eva) -"bg" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/mine/eva) -"bh" = ( -/obj/machinery/computer/shuttle/labor/one_way{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"bi" = ( -/obj/structure/gulag_beacon, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"bj" = ( -/obj/machinery/status_display/evac{ - pixel_y = 32 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"bk" = ( -/obj/effect/turf_decal/loading_area{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"bl" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "gulag" - }, -/turf/open/floor/plating, -/area/mine/laborcamp) -"bm" = ( -/obj/machinery/conveyor{ - dir = 10; - id = "gulag" - }, -/turf/open/floor/plating, -/area/mine/laborcamp) -"bn" = ( -/obj/structure/table, -/obj/item/pickaxe, -/obj/item/gps/mining, -/obj/item/gps/mining, -/obj/item/gps/mining, -/obj/item/gps/mining, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bo" = ( -/obj/machinery/suit_storage_unit/mining, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bp" = ( -/obj/machinery/suit_storage_unit/mining, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bq" = ( -/turf/closed/wall, -/area/mine/production) -"br" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/mine/production) -"bs" = ( -/obj/machinery/camera{ - c_tag = "EVA"; - dir = 4; - network = list("mine") - }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -23 - }, -/obj/machinery/light{ - dir = 8 - }, -/obj/structure/table, -/obj/item/storage/toolbox/mechanical{ - pixel_x = -2; - pixel_y = -1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bt" = ( -/turf/open/floor/plasteel, -/area/mine/eva) -"bu" = ( -/obj/machinery/light_switch{ - pixel_x = 27 - }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bv" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/mine/eva) -"bw" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/mine/laborcamp/security) -"bx" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Shuttle Prisoner Airlock" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"by" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"bz" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"bA" = ( -/turf/closed/wall/r_wall, -/area/mine/laborcamp) -"bB" = ( -/obj/structure/toilet{ - dir = 8 - }, -/obj/machinery/light/small{ - dir = 1 - }, -/turf/open/floor/plating, -/area/mine/laborcamp/security) -"bC" = ( -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/obj/machinery/computer/shuttle/mining{ - req_access = null - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"bD" = ( -/obj/structure/closet/crate, -/obj/item/dice/d4, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"bE" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/effect/turf_decal/tile/purple, -/turf/open/floor/plasteel, -/area/mine/production) -"bF" = ( -/obj/effect/spawner/structure/window, -/turf/open/floor/plating, -/area/mine/eva) -"bG" = ( -/obj/structure/table, -/obj/item/stack/packageWrap, -/obj/item/stack/packageWrap, -/obj/item/stack/packageWrap, -/obj/item/hand_labeler, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bH" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel, -/area/mine/eva) -"bI" = ( -/obj/structure/tank_dispenser/oxygen, -/obj/effect/turf_decal/tile/purple, -/turf/open/floor/plasteel, -/area/mine/eva) -"bJ" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bK" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = -5; - pixel_y = 30 - }, -/obj/machinery/shower{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple, -/turf/open/floor/plasteel, -/area/mine/eva) -"bL" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/machinery/door/airlock/highsecurity{ - name = "Labor Camp Monitoring"; - req_access_txt = "2"; - security_level = 6 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"bM" = ( -/turf/closed/wall, -/area/mine/laborcamp/security) -"bN" = ( -/obj/structure/sign/warning/docking, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/mine/production) -"bO" = ( -/obj/item/beacon, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"bP" = ( -/turf/open/floor/plasteel, -/area/mine/production) -"bQ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"bR" = ( -/obj/machinery/door/airlock/mining/glass{ - name = "Mining Station EVA"; - req_access_txt = "54" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bS" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bT" = ( -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/machinery/light{ - dir = 1 - }, -/obj/machinery/power/apc{ - dir = 1; - name = "Labor Camp Security APC"; - pixel_y = 23 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"bU" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bV" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bW" = ( -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bX" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock/external{ - glass = 1; - name = "Mining External Airlock"; - opacity = 0; - req_access_txt = "54" - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bY" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"bZ" = ( -/turf/closed/mineral/random/volcanic, -/area/lavaland/surface/outdoors/explored) -"ca" = ( -/turf/closed/wall/r_wall, -/area/mine/laborcamp/security) -"cb" = ( -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/structure/table, -/obj/item/restraints/handcuffs, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cc" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/mob/living/simple_animal/bot/secbot/beepsky{ - desc = "Powered by the tears and sweat of laborers."; - name = "Prison Ofitser" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cd" = ( -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"ce" = ( -/obj/machinery/computer/secure_data, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cf" = ( -/obj/machinery/computer/security/labor, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cg" = ( -/obj/machinery/computer/prisoner, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"ch" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"ci" = ( -/obj/machinery/power/apc{ - name = "Mining EVA APC"; - pixel_x = 1; - pixel_y = -23 - }, -/obj/machinery/recharge_station, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/structure/cable, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"cj" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock/external{ - glass = 1; - name = "Mining Shuttle Airlock"; - opacity = 0 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"ck" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"cl" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"cm" = ( -/obj/machinery/mech_bay_recharge_port, -/obj/structure/cable{ - icon_state = "0-8" - }, -/turf/open/floor/plating, -/area/mine/eva) -"cn" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"co" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"cp" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cq" = ( -/turf/open/floor/mech_bay_recharge_floor, -/area/mine/eva) -"cr" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/machinery/computer/mech_bay_power_console{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"cs" = ( -/obj/structure/closet/emcloset, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"ct" = ( -/obj/structure/ore_box, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/eva) +/turf/template_noop, +/area/template_noop) "cu" = ( /obj/item/pickaxe, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, @@ -918,1694 +85,6 @@ /obj/structure/ore_box, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"cw" = ( -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/machinery/vending/security, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cx" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cy" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"cz" = ( -/obj/structure/table, -/obj/item/storage/fancy/donut_box, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cA" = ( -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cB" = ( -/obj/structure/chair/office{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cC" = ( -/obj/structure/table, -/obj/effect/turf_decal/tile/red, -/obj/item/paper_bin, -/obj/item/pen, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cD" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"cE" = ( -/obj/structure/chair/comfy/brown{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cF" = ( -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"cG" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/structure/closet/secure_closet/freezer/gulag_fridge, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cH" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"cI" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"cJ" = ( -/obj/machinery/door/airlock{ - name = "Closet" - }, -/turf/open/floor/plating, -/area/mine/production) -"cK" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/open/floor/plating, -/area/mine/production) -"cL" = ( -/obj/machinery/space_heater, -/turf/open/floor/plating, -/area/mine/production) -"cM" = ( -/turf/closed/wall, -/area/mine/living_quarters) -"cN" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"cO" = ( -/obj/item/radio/intercom{ - dir = 8; - name = "Station Intercom (General)"; - pixel_x = -28 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"cP" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = 30 - }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"cQ" = ( -/turf/closed/wall/r_wall, -/area/mine/maintenance) -"cR" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/mine/living_quarters) -"cS" = ( -/obj/effect/turf_decal/tile/red, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/machinery/camera{ - c_tag = "Labor Camp Security Office"; - dir = 1; - network = list("labor") - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cT" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cU" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Monitoring"; - req_access_txt = "2" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"cV" = ( -/turf/open/floor/plating, -/area/mine/living_quarters) -"cW" = ( -/obj/structure/reagent_dispensers/fueltank, -/turf/open/floor/plating, -/area/mine/living_quarters) -"cX" = ( -/obj/machinery/power/smes{ - charge = 5e+006 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"cY" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/structure/closet/crate/secure/loot, -/obj/structure/sign/warning/electricshock{ - pixel_y = 32 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"cZ" = ( -/obj/machinery/mineral/equipment_vendor, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"da" = ( -/obj/machinery/mineral/mint, -/turf/open/floor/plasteel, -/area/mine/production) -"db" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/turf_decal/loading_area{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"dc" = ( -/obj/structure/closet/crate, -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/mine/production) -"dd" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = -5; - pixel_y = 30 - }, -/obj/structure/table, -/obj/item/paper/fluff/stations/lavaland/orm_notice, -/turf/open/floor/plasteel, -/area/mine/production) -"de" = ( -/obj/structure/ore_box, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/mine/production) -"df" = ( -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/mine/production) -"dg" = ( -/turf/open/floor/circuit, -/area/mine/maintenance) -"dh" = ( -/obj/machinery/portable_atmospherics/canister/oxygen, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"di" = ( -/obj/machinery/telecomms/relay/preset/mining, -/obj/machinery/light/small{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/mine/maintenance) -"dj" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel/dark, -/area/mine/maintenance) -"dk" = ( -/obj/machinery/airalarm{ - pixel_y = 24 - }, -/turf/open/floor/circuit, -/area/mine/maintenance) -"dl" = ( -/obj/machinery/light/small{ - dir = 8 - }, -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/obj/machinery/iv_drip, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/mine/living_quarters) -"dm" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/mine/living_quarters) -"dn" = ( -/obj/structure/table, -/obj/item/storage/firstaid/toxin{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/mine/living_quarters) -"do" = ( -/obj/machinery/power/apc{ - dir = 8; - name = "Mining Station Starboard Wing APC"; - pixel_x = -25; - pixel_y = 2 - }, -/obj/machinery/light{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"dp" = ( -/obj/machinery/power/apc{ - dir = 1; - name = "Mining Communications APC"; - pixel_x = 1; - pixel_y = 23 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plasteel/dark, -/area/mine/maintenance) -"dq" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"dr" = ( -/obj/machinery/atmospherics/components/unary/tank/air{ - dir = 8 - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"ds" = ( -/obj/machinery/power/terminal{ - dir = 1 - }, -/obj/machinery/power/port_gen/pacman{ - anchored = 1 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"dt" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/obj/machinery/meter, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"du" = ( -/obj/effect/turf_decal/loading_area, -/turf/open/floor/plasteel, -/area/mine/production) -"dv" = ( -/obj/effect/turf_decal/loading_area{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"dw" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/mine/production) -"dx" = ( -/obj/machinery/mineral/equipment_vendor, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"dy" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"dz" = ( -/obj/machinery/light_switch{ - pixel_y = -25 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/turf/open/floor/circuit, -/area/mine/maintenance) -"dA" = ( -/obj/machinery/camera{ - c_tag = "Communications Relay"; - dir = 8; - network = list("mine") - }, -/turf/open/floor/circuit, -/area/mine/maintenance) -"dB" = ( -/obj/structure/closet/crate/freezer, -/obj/item/reagent_containers/blood, -/obj/item/reagent_containers/blood{ - pixel_x = -3; - pixel_y = -3 - }, -/obj/item/reagent_containers/blood/AMinus, -/obj/item/reagent_containers/blood/BMinus{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/item/reagent_containers/blood/BPlus{ - pixel_x = 1; - pixel_y = 2 - }, -/obj/item/reagent_containers/blood/OMinus, -/obj/item/reagent_containers/blood/OPlus{ - pixel_x = -2; - pixel_y = -1 - }, -/obj/item/reagent_containers/blood/random, -/obj/item/reagent_containers/blood/random, -/obj/item/reagent_containers/blood/random, -/obj/machinery/camera{ - c_tag = "Sleeper Room"; - dir = 1; - network = list("mine") - }, -/turf/open/floor/plasteel/white, -/area/mine/living_quarters) -"dC" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 5 - }, -/turf/open/floor/plasteel/white, -/area/mine/living_quarters) -"dD" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 10 - }, -/turf/open/floor/plasteel/white, -/area/mine/living_quarters) -"dE" = ( -/obj/structure/table, -/obj/item/storage/firstaid/regular, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/mine/living_quarters) -"dF" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"dG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"dH" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 5 - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/circuit, -/area/mine/maintenance) -"dI" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"dJ" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"dK" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/machinery/camera{ - c_tag = "Shuttle Docking Foyer"; - dir = 8; - network = list("mine") - }, -/obj/machinery/newscaster{ - pixel_x = 30; - pixel_y = 1 - }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"dL" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/mine/production) -"dM" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel, -/area/mine/production) -"dN" = ( -/obj/machinery/camera{ - c_tag = "Processing Area Room"; - dir = 8; - network = list("mine") - }, -/obj/item/radio/intercom{ - dir = 8; - name = "Station Intercom (General)"; - pixel_x = 28 - }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"dO" = ( -/obj/machinery/mineral/unloading_machine{ - dir = 1; - icon_state = "unloader-corner"; - input_dir = 1; - output_dir = 2 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plating, -/area/mine/production) -"dP" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 10 - }, -/obj/machinery/bluespace_beacon, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plasteel/dark, -/area/mine/maintenance) -"dQ" = ( -/obj/effect/spawner/structure/window, -/turf/open/floor/plating, -/area/mine/living_quarters) -"dR" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Infirmary" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel/white, -/area/mine/living_quarters) -"dS" = ( -/obj/machinery/power/port_gen/pacman{ - anchored = 1 - }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/mine/living_quarters) -"dT" = ( -/obj/machinery/atmospherics/components/binary/pump/on, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"dU" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Mining Station Communications"; - req_access_txt = "48" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/maintenance) -"dV" = ( -/obj/effect/spawner/structure/window, -/turf/open/floor/plating, -/area/mine/production) -"dW" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/mine/production) -"dX" = ( -/obj/machinery/conveyor_switch/oneway{ - id = "mining_internal"; - name = "mining conveyor" - }, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"dY" = ( -/obj/machinery/conveyor{ - id = "mining_internal" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plating, -/area/mine/production) -"dZ" = ( -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ea" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eb" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Mining Station Maintenance"; - req_access_txt = "48" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"ec" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ed" = ( -/obj/machinery/camera{ - c_tag = "Crew Area Hallway"; - network = list("mine") - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ee" = ( -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ef" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eg" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/machinery/door/airlock/mining/glass{ - name = "Processing Area"; - req_access_txt = "48" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"eh" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = -5; - pixel_y = 30 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ei" = ( -/obj/machinery/power/apc{ - dir = 1; - name = "Mining Station Port Wing APC"; - pixel_x = 1; - pixel_y = 23 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ej" = ( -/obj/machinery/camera{ - c_tag = "Crew Area Hallway East"; - network = list("mine") - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ek" = ( -/obj/effect/turf_decal/tile/purple, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"el" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"em" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"en" = ( -/obj/machinery/mineral/processing_unit_console, -/turf/closed/wall, -/area/mine/production) -"eo" = ( -/obj/machinery/mineral/processing_unit{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plating, -/area/mine/production) -"ep" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eq" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"er" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"es" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"et" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eu" = ( -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden/layer3, -/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ev" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ew" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ex" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ey" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"ez" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eA" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eB" = ( -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eC" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/machinery/door/airlock/glass{ - name = "Mining Station Bridge" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eD" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/production) -"eE" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eF" = ( -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"eG" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"eH" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"eI" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"eJ" = ( -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"eK" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eL" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eM" = ( -/obj/machinery/light, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eN" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eO" = ( -/obj/machinery/light/small, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eP" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"eQ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/machinery/door/airlock/glass, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eR" = ( -/obj/machinery/door/airlock/glass{ - name = "Break Room" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"eS" = ( -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, -/obj/machinery/mineral/equipment_vendor, -/turf/open/floor/plasteel, -/area/mine/production) -"eT" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, -/obj/machinery/light, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"eU" = ( -/obj/structure/closet/crate, -/obj/effect/turf_decal/tile/purple, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"eV" = ( -/obj/effect/turf_decal/tile/purple, -/turf/open/floor/plasteel, -/area/mine/production) -"eW" = ( -/obj/effect/turf_decal/loading_area{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"eX" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining_internal" - }, -/obj/structure/plasticflaps, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/plating, -/area/mine/production) -"eY" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining_internal" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plating, -/area/mine/production) -"eZ" = ( -/obj/machinery/conveyor{ - dir = 10; - id = "mining_internal" - }, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/turf/open/floor/plating, -/area/mine/production) -"fa" = ( -/obj/machinery/newscaster{ - pixel_y = 32 - }, -/obj/structure/chair, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fb" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = -5; - pixel_y = 30 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/machinery/light{ - dir = 1 - }, -/obj/structure/chair, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fc" = ( -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fd" = ( -/obj/machinery/camera{ - c_tag = "Public Shuttle Lobby"; - network = list("mine") - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/structure/table, -/obj/item/gps/mining, -/obj/item/gps/mining, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fe" = ( -/obj/structure/bed, -/obj/item/bedsheet/brown, -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/turf/open/floor/carpet, -/area/mine/living_quarters) -"ff" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 6 - }, -/turf/open/floor/carpet, -/area/mine/living_quarters) -"fg" = ( -/obj/machinery/door/airlock{ - id_tag = "miningdorm1"; - name = "Room 1" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fh" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fi" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fj" = ( -/obj/machinery/vending/snack, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fk" = ( -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fl" = ( -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fm" = ( -/obj/machinery/vending/cigarette, -/obj/machinery/newscaster{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fn" = ( -/obj/structure/table, -/obj/machinery/microwave{ - pixel_y = 6 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fo" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"fp" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fq" = ( -/obj/item/radio/intercom{ - dir = 8; - name = "Station Intercom (General)"; - pixel_x = 28 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fr" = ( -/obj/structure/table, -/turf/open/floor/carpet, -/area/mine/living_quarters) -"fs" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/button/door{ - id = "miningdorm1"; - name = "Door Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 1 - }, -/turf/open/floor/carpet, -/area/mine/living_quarters) -"ft" = ( -/obj/machinery/camera{ - c_tag = "Dormitories"; - dir = 4; - network = list("mine") - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fu" = ( -/obj/structure/chair, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fv" = ( -/obj/structure/table, -/obj/machinery/reagentgrinder, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fw" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"fx" = ( -/turf/closed/mineral/random/labormineral/volcanic, -/area/lavaland/surface/outdoors/explored) -"fy" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/machinery/door/airlock/glass{ - name = "Mining Station Bridge" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"fz" = ( -/obj/structure/table, -/obj/item/clothing/glasses/meson, -/obj/item/storage/bag/ore, -/obj/item/pickaxe, -/obj/item/mining_scanner, -/obj/item/flashlight, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fA" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, -/turf/open/floor/plasteel, -/area/mine/eva) -"fB" = ( -/obj/structure/table, -/obj/item/gps/mining, -/obj/item/gps/mining, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fC" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fD" = ( -/obj/structure/table, -/obj/item/reagent_containers/food/drinks/beer{ - pixel_x = 7; - pixel_y = 5 - }, -/obj/item/reagent_containers/food/drinks/beer{ - pixel_x = -1; - pixel_y = 9 - }, -/obj/item/reagent_containers/food/drinks/beer{ - pixel_x = -8 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 5 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fE" = ( -/obj/structure/chair{ - dir = 8 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fF" = ( -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fG" = ( -/obj/structure/table, -/obj/item/storage/box/donkpockets, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fH" = ( -/obj/machinery/door/airlock{ - id_tag = "miningdorm2"; - name = "Room 2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fI" = ( -/obj/item/radio/intercom{ - dir = 8; - name = "Station Intercom (General)"; - pixel_x = -28 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fJ" = ( -/obj/machinery/camera{ - c_tag = "Crew Area"; - dir = 1; - network = list("mine") - }, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = -32 - }, -/obj/machinery/light, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fK" = ( -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fL" = ( -/obj/structure/sink{ - dir = 8; - pixel_x = 11 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fM" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/button/door{ - id = "miningdorm2"; - name = "Door Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 1 - }, -/turf/open/floor/carpet, -/area/mine/living_quarters) -"fN" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/light{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fO" = ( -/obj/machinery/door/airlock{ - id_tag = "miningdorm3"; - name = "Room 3" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"fP" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/button/door{ - id = "miningdorm3"; - name = "Door Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 1 - }, -/turf/open/floor/carpet, -/area/mine/living_quarters) "fQ" = ( /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors/unexplored/danger) @@ -2624,24 +103,6 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"fU" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/production) "fV" = ( /turf/closed/indestructible/riveted/boss/see_through, /area/lavaland/surface/outdoors) @@ -2650,14 +111,6 @@ /obj/structure/stone_tile/slab, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) -"fX" = ( -/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel, -/area/mine/production) "gj" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 1 @@ -2786,23 +239,6 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"gX" = ( -/obj/structure/toilet{ - dir = 8 - }, -/turf/open/floor/plasteel/freezer, -/area/mine/living_quarters) -"gY" = ( -/obj/docking_port/stationary{ - dir = 8; - dwidth = 2; - height = 5; - id = "laborcamp_away"; - name = "labor camp"; - width = 9 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/explored) "hg" = ( /obj/structure/stone_tile/surrounding, /obj/structure/stone_tile/center/cracked, @@ -2848,19 +284,6 @@ }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) -"ie" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"il" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/eva) "ir" = ( /obj/structure/stone_tile/slab/cracked{ dir = 5 @@ -3028,15 +451,6 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) -"jI" = ( -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/living_quarters) "jL" = ( /obj/structure/stone_tile/surrounding_tile, /obj/structure/stone_tile/surrounding_tile{ @@ -3059,17 +473,6 @@ /obj/structure/stone_tile/center/cracked, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) -"jO" = ( -/obj/docking_port/stationary{ - dir = 8; - dwidth = 3; - height = 7; - id = "lavaland_common_away"; - name = "Mining base public dock"; - width = 7 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) "jQ" = ( /obj/structure/stone_tile{ dir = 1 @@ -3105,12 +508,6 @@ /obj/structure/fluff/drake_statue/falling, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"km" = ( -/obj/structure/chair{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) "ko" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 @@ -3302,13 +699,6 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) -"lB" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/production) "lD" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 @@ -3352,13 +742,6 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) -"lN" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown, -/turf/open/floor/plasteel, -/area/mine/living_quarters) "lP" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 @@ -3396,14 +779,6 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) -"lU" = ( -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/atmos_waste{ - dir = 4; - piping_layer = 3 - }, -/obj/structure/lattice/catwalk, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/mine/living_quarters) "lW" = ( /obj/structure/stone_tile/block/cracked, /obj/structure/stone_tile/block/cracked{ @@ -3439,15 +814,6 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) -"mi" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 5 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) "mk" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 @@ -3813,579 +1179,10 @@ }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) -"ns" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/mine/production) -"nE" = ( -/obj/structure/sink{ - dir = 4; - pixel_x = -12 - }, -/obj/structure/mirror{ - pixel_x = -28 - }, -/turf/open/floor/plasteel/freezer, -/area/mine/living_quarters) -"nG" = ( -/obj/item/twohanded/required/kirbyplants/random, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"nJ" = ( -/obj/structure/sign/poster/official/random{ - pixel_y = 32 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"nO" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel/freezer, -/area/mine/living_quarters) -"nZ" = ( -/obj/machinery/door/window/southright, -/obj/machinery/shower{ - pixel_y = 22 - }, -/turf/open/floor/plasteel/freezer, -/area/mine/living_quarters) -"oZ" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 8 - }, -/turf/open/floor/plasteel/freezer, -/area/mine/living_quarters) -"pg" = ( -/obj/machinery/door/airlock/external{ - glass = 1; - name = "Mining External Airlock"; - opacity = 0 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plasteel, -/area/mine/production) -"pm" = ( -/obj/structure/table, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = 5; - pixel_y = 3 - }, -/obj/item/tank/internals/emergency_oxygen, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"qq" = ( -/obj/machinery/light, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"qE" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"qZ" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/obj/effect/turf_decal/tile/bar, -/obj/effect/turf_decal/tile/bar{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"rf" = ( -/obj/machinery/door/airlock/external{ - glass = 1; - name = "Mining External Airlock"; - opacity = 0 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"rs" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"rF" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"rY" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"sF" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"sL" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock/external{ - name = "Lavaland Shuttle Airlock" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"sV" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"tg" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/turf/open/floor/plating, -/area/mine/production) -"uy" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/mine/laborcamp/security) -"vk" = ( -/obj/effect/turf_decal/tile/red, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"vE" = ( -/obj/item/twohanded/required/kirbyplants/random, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"vP" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"xc" = ( -/obj/machinery/light/small{ - dir = 1 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/mine/production) -"zc" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"zS" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"CS" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/mine/production) -"Dn" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"DM" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"Et" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"EH" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"FB" = ( -/obj/structure/table, -/obj/effect/turf_decal/tile/red, -/obj/machinery/recharger, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"FX" = ( -/obj/structure/chair{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"Gr" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"GC" = ( -/obj/machinery/camera{ - c_tag = "Crew Area Hallway West"; - dir = 1; - network = list("mine") - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"Hk" = ( -/obj/structure/displaycase, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"HO" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/machinery/door/airlock/external{ - name = "Lavaland Shuttle Airlock" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"Iv" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"IY" = ( -/obj/machinery/cryopod{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"Ki" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, -/turf/open/floor/plasteel/white, -/area/mine/living_quarters) -"Ky" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"KS" = ( -/obj/structure/closet/emcloset, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"LW" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable, -/turf/open/floor/plating, -/area/mine/living_quarters) -"Mc" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"My" = ( -/obj/machinery/door/airlock{ - id_tag = "miningbathroom"; - name = "Restroom" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel/freezer, -/area/mine/living_quarters) -"MX" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"NC" = ( -/obj/effect/turf_decal/tile/brown, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/structure/displaycase, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"NU" = ( -/obj/machinery/atmospherics/pipe/manifold4w/supply, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"OJ" = ( -/obj/structure/table, -/obj/item/cigbutt, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"Pd" = ( -/obj/machinery/button/door{ - id = "miningbathroom"; - name = "Door Bolt Control"; - normaldoorcontrol = 1; - pixel_y = -25; - specialfunctions = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel/freezer, -/area/mine/living_quarters) -"Pr" = ( -/obj/machinery/light/small{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"PR" = ( -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red, -/obj/structure/closet/secure_closet/labor_camp_security, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"Qj" = ( -/obj/machinery/computer/shuttle/mining/common{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"Qo" = ( -/obj/machinery/shower{ - dir = 8 - }, -/obj/structure/extinguisher_cabinet{ - pixel_x = 30 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"Rn" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/production) -"RD" = ( -/obj/machinery/door/airlock{ - name = "Restroom" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel/freezer, -/area/mine/living_quarters) -"RR" = ( -/obj/item/bikehorn{ - color = "#000"; - desc = "A horn off of a bicycle. This one has been charred to hell and back, yet somehow it still honks."; - name = "charred bike horn" - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors/explored) -"RW" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"Se" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plating, -/area/mine/living_quarters) -"Sj" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/light/small, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/turf/open/floor/plasteel/freezer, -/area/mine/living_quarters) -"SI" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"Tp" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 4 - }, -/obj/structure/lattice/catwalk, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/mine/living_quarters) -"Ty" = ( -/obj/machinery/door/window/southleft, -/obj/machinery/shower{ - pixel_y = 22 - }, -/turf/open/floor/plasteel/freezer, -/area/mine/living_quarters) -"Tz" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) -"TW" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"TX" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3{ - dir = 5 - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"Ub" = ( -/obj/structure/statue{ - desc = "A lifelike statue of a horrifying monster."; - dir = 8; - icon = 'icons/mob/lavaland/lavaland_monsters.dmi'; - icon_state = "goliath"; - name = "goliath" - }, -/turf/open/floor/plasteel, -/area/mine/living_quarters) +"ol" = ( +/obj/effect/landmark/stationroom/lavaland/station, +/turf/template_noop, +/area/template_noop) "Uq" = ( /obj/docking_port/stationary{ area_type = /area/lavaland/surface/outdoors; @@ -4398,108 +1195,6 @@ }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"UP" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/obj/effect/turf_decal/tile/brown, -/turf/open/floor/plasteel, -/area/mine/production) -"US" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3, -/turf/open/floor/plasteel, -/area/mine/living_quarters) -"Vk" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"Vz" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-8" - }, -/turf/open/floor/plating, -/area/mine/production) -"Wp" = ( -/obj/docking_port/stationary{ - dir = 8; - dwidth = 3; - height = 10; - id = "mining_away"; - name = "lavaland mine"; - width = 7 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"WA" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/machinery/door/airlock{ - name = "Labor Camp External Access" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"WB" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Shuttle Security Airlock"; - req_access_txt = "2" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"WC" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Shuttle Prisoner Airlock" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp) -"WD" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/machinery/door/airlock/external{ - glass = 1; - name = "Mining External Airlock"; - opacity = 0; - req_access_txt = "54" - }, -/turf/open/floor/plasteel, -/area/mine/eva) -"WE" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/machinery/door/airlock/external{ - glass = 1; - name = "Mining Shuttle Airlock"; - opacity = 0 - }, -/turf/open/floor/plasteel, -/area/mine/production) -"YT" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/closed/wall, -/area/mine/living_quarters) -"Zt" = ( -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/plasteel, -/area/mine/laborcamp/security) (1,1,1) = {" aa @@ -4702,61 +1397,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +ol "} (2,1,1) = {" aa @@ -4959,61 +1654,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (3,1,1) = {" aa @@ -5216,61 +1911,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (4,1,1) = {" aa @@ -5473,61 +2168,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ai -ai -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (5,1,1) = {" aa @@ -5730,61 +2425,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ai -ai -ai -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (6,1,1) = {" aa @@ -5987,61 +2682,61 @@ aj aj aj aj -aj -aj -aj -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -ab -ai -aD -ab -aj -aj -aj -aj -aj -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (7,1,1) = {" aa @@ -6244,61 +2939,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aw -aw -ab -aD -ab -aj -aj -aj -aj -aj -aj -aj -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (8,1,1) = {" aa @@ -6501,61 +3196,61 @@ aj aj aj aj -aj -ab -aj -aj -aj -ab -aj -aj -aj -aw -aw -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (9,1,1) = {" aa @@ -6758,61 +3453,61 @@ aj aj aj aj -ab -ab -aj -ab -ab -aj -aj -aj -aj -aw -aw -aj -aj -aw -aw -aj -aj -aw -aj -ab -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -aj -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (10,1,1) = {" aa @@ -7015,61 +3710,61 @@ aj aj aj aj -aj -aj -aj -ab -ab -aj -aj -aj -aw -aw -aw -aw -aw -aw -aw -aw -aw -aw -aw -aw -aw -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (11,1,1) = {" aa @@ -7272,61 +3967,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aw -aw -aD -aw -aw -aw -aw -aw -aw -aw -aw -aw -aw -aw -aw -aw -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -ab -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (12,1,1) = {" aa @@ -7529,61 +4224,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aw -aw -aw -aD -aw -aw -aw -aw -aw -aD -aw -aw -aD -aw -aw -aw -aj -aw -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (13,1,1) = {" aa @@ -7786,61 +4481,61 @@ aj aj aj ab -aj -aj -aj -aj -aj -aj -ab -aj -aw -aw -aw -aD -aD -aD -aD -aD -aD -aD -aD -aD -aw -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (14,1,1) = {" aa @@ -8043,61 +4738,61 @@ aj aj ab ab -aj -aj -aj -aj -aj -aj -aj -aw -aw -aw -aw -aD -aD -aD -aD -aD -aD -aD -aD -aD -aw -aw -ab -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -aj -ab -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (15,1,1) = {" aa @@ -8300,61 +4995,61 @@ aj aj aj aj -aj -aj -ab -aj -aj -aj -aj -aw -aw -aw -aw -aD -aD -aD -aD -aD -aD -aD -aD -aD -aw -aw -aw -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (16,1,1) = {" aa @@ -8557,61 +5252,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aw -aw -aw -aD -aD -aD -aD -aD -aD -aD -aD -aD -aw -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (17,1,1) = {" aa @@ -8814,61 +5509,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aw -aw -aD -aD -aD -aD -aD -aD -aD -gY -aD -aD -aD -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -ab -ab -aj -aj -ab -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (18,1,1) = {" aa @@ -9071,61 +5766,61 @@ aj aj ab aj -aj -aj -aj -aj -aj -aj -aj -aj -aq -aq -aq -aq -aq -aY -aq -aq -aq -bx -aq -aw -aw -aj -aj -aj -aj -aj -ab -ai -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (19,1,1) = {" aa @@ -9328,61 +6023,61 @@ an an ab ab -an -ab -aj -aj -aj -aj -aj -ab -aq -aG -aK -aP -aq -aZ -aq -bh -aq -aJ -aq -aD -bZ -aj -aj -RR -aj -ab -ab -ai -ai -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (20,1,1) = {" aa @@ -9585,61 +6280,61 @@ an an an an -an -an -ab -aj -aj -aj -ab -ab -aq -aH -az -aQ -aq -WB -aq -bi -aq -WC -aq -bZ -bZ -bZ -aj -aj -aj -ab -ab -ai -ai -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (21,1,1) = {" aa @@ -9842,61 +6537,61 @@ an an an an -an -an -an -an -ap -ap -ap -aq -aq -aq -aL -aq -aq -ba -aq -bj -az -az -bA -ca -ca -ca -uy -ca -Se -Mc -LW -cM -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (22,1,1) = {" aa @@ -10099,61 +6794,61 @@ an an an an -an -an -an -an -ap -ar -ar -aq -IY -az -az -az -az -az -az -el -az -az -bA -cb -cw -cG -cz -ca -OJ -SI -nG -cM -lU -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (23,1,1) = {" aa @@ -10356,61 +7051,61 @@ an an an an -an -an -an -an -aq -as -ax -aB -az -az -az -az -aU -bb -cN -fo -by -by -bL -cc -cx -mi -cE -ca -km -SI -eM -cM -Tp -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (24,1,1) = {" aa @@ -10613,61 +7308,61 @@ an an an an -an -an -an -an -aq -at -ay -aq -aE -az -cl -cN -cN -dG -aQ -bk -az -az -bA -cd -cA -fw -cS -ca -nJ -SI -dZ -cM -er -LW -cM -ab -ab -ab -ab -ab -jO -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (25,1,1) = {" aa @@ -10870,61 +7565,61 @@ an an an an -an -an -an -an -aq -aq -aq -aq -aq -az -az -aR -az -bc -aq -bl -bA -bA -bA -bT -cA -qE -cT -bw -eL -dy -ec -dZ -ie -DM -cM -ab -ab -ab -ab -cR -sL -cR -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (26,1,1) = {" aa @@ -11127,61 +7822,61 @@ an an an an -an -an -an -an -aq -au -au -au -aq -az -aM -aq -aq -bd -aq -bl -bA -ao -aV -Zt -Tz -cp -sF -cU -EH -dF -EH -EH -es -GC -cM -ab -ab -ab -ab -cR -dZ -cR -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (27,1,1) = {" aa @@ -11384,61 +8079,61 @@ an an an an -an -an -an -an -aq -av -az -az -aF -az -aN -aS -aW -be -aW -bm -bA -bB -bM -ce -cA -Iv -vk -bw -dZ -dZ -lN -rF -et -dZ -cM -cM -cM -YT -cM -cR -HO -cR -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (28,1,1) = {" aa @@ -11641,61 +8336,61 @@ an an an an -an -an -an -an -aq -aq aA -aC -aq -aI -aq -aq -aq -aq -aq -aq -bA -bA -ca -cf -cB -cA -qq -cQ -cQ -cQ -cQ -rs -et -dZ -cM -vE -FX -Qj -FX -eL -Dn -cR -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA "} (29,1,1) = {" aa @@ -11898,61 +8593,61 @@ an an an an -an -an -an -an -an -aq -aq -aq -aq -az -aq -aT -aX -aX -aD -aD -aD -aw -bw -cg -cC -FB -PR -cQ -dg -dg -cQ -dZ -et -dZ -cM -fa -dZ -dZ -dZ -dZ -dZ -cR -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (30,1,1) = {" aa @@ -12155,61 +8850,61 @@ an an an an -an -an -an -an -an -an -an -an -aq -aJ -aq -aT -aD -aD -aD -aD -aD -aw -bw -bw -bw -bw -bw -cQ -dp -dH -cQ -ea -et -ek -cM -fb -dZ -fz -fz -dZ -Ub -cR -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (31,1,1) = {" aa @@ -12412,61 +9107,61 @@ an an an an -an -an -an -an -an -an -an -an -aq -WA -aq -aT -aD -aD -aD -aD -aD -aj -aj -aj -aj -aj -ab -cQ -di -dP -dU -rY -eu -eK -eQ -ef -TX -fz -fz -dZ -dZ -cR -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (32,1,1) = {" aa @@ -12669,61 +9364,61 @@ an an an an -an -an -an -an -an -an -an -an -aD -aD -aO -aD -aD -aD -aD -aD -aj -aj -aj -aj -aj -ab -ad -cQ -dj -dz -cQ -ec -ev -eL -cM -fc -zS -dZ -dZ -dZ -eM -cM -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (33,1,1) = {" aa @@ -12926,61 +9621,61 @@ an an an an -an -an -an -an -an -an -an -an -aD -aD -aD -aD -aD -aD -aD -aD -aD -aj -aj -aj -aj -ab -ai -cQ -dk -dA -cQ -ed -ew -eM -cM -fd -fq -fB -pm -Hk -NC -cM -ai -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (34,1,1) = {" aa @@ -13183,61 +9878,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -aD -aD -aD -aD -aD -aD -aD -aj -aj -aj -aj -ab -ab -cQ -cQ -cQ -cQ -ee -ev -dZ -cM -cM -cM -cM -cM -cM -cM -cM -cM -cM -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (35,1,1) = {" aa @@ -13440,61 +10135,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -aD -aD -aD -aD -aD -aD -aD -aj -aj -aj -aj -aj -ab -cM -dl -dB -cM -dZ -ex -fp -cM -fe -fr -cM -fe -fr -cM -fe -fr -cM -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (36,1,1) = {" aa @@ -13697,61 +10392,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -aD -aD -aD -aD -aD -aD -aD -aD -aj -aj -aj -aj -ab -cR -Ki -dC -dQ -ea -ev -dZ -cM -ff -fs -cM -ff -fM -cM -ff -fP -cM -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (37,1,1) = {" aa @@ -13954,61 +10649,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -an -an -aD -aD -aT -an -aD -fx -aj -aj -aj -aj -ab -cR -dm -dD -dR -ef -ey -dZ -cM -fg -cM -cM -fH -cM -cM -fO -cM -cM -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (38,1,1) = {" aa @@ -14211,61 +10906,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -fx -fx -an -aj -aj -ai -ad -cM -dn -dE -dQ -ec -ev -dZ -eL -fh -ft -eL -fh -zc -eL -fh -ec -cR -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (39,1,1) = {" aa @@ -14468,61 +11163,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -aj -aj -ai -cM -cM -cM -cM -cM -ei -ez -eN -eN -fi -eN -eN -fi -fN -eN -NU -fp -cR -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (40,1,1) = {" aa @@ -14725,61 +11420,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -aj -aj -aj -aj -cM -cX -ds -dS -cM -eh -ex -fp -cM -cM -dQ -dQ -cM -cM -cM -RD -cM -cM -ai -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (41,1,1) = {" aa @@ -14982,61 +11677,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -aj -aj -aj -aj -aj -aj -cM -cY -cV -cV -cM -ea -ev -eM -cM -fj -fk -qZ -fI -cM -Ty -nO -cM -ai -ad -ai -ai -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (42,1,1) = {" aa @@ -15239,61 +11934,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -an -an -an -an -ab -aj -aj -aj -aj -aj -aj -aj -cM -dh -dt -dT -eb -ep -eA -ek -dQ -fk -fk -fC -fk -cM -nZ -Sj -cM -ab -ai -ai -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (43,1,1) = {" aa @@ -15496,61 +12191,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -an -an -an -ab -aj -aj -aj -aj -ab -ab -aj -ab -cM -cV -dq -dI -cM -ej -Et -jI -eR -fl -fu -fD -fJ -cM -cM -My -cM -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (44,1,1) = {" aa @@ -15753,61 +12448,61 @@ an an an an -an -an -an -an -an -an -an -an -an -an -an -an -an -aj -aj -aj -ab -ab -ab -ab -ab -ab -cM -cW -dr -dr -cM -US -ew -eL -dQ -fk -fk -fE -fK -cM -nE -Pd -cM -aj -aj -aj -aj -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (45,1,1) = {" aa @@ -16010,61 +12705,61 @@ an an an an -an -an -an -an -an -an -ab -aj -aj -an -an -an -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -cM -cM -cM -cM -cM -dZ -ev -dZ -cM -fm -fk -fF -fk -cM -gX -oZ -cM -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (46,1,1) = {" aa @@ -16267,61 +12962,61 @@ aj aj aj aj -an -an -an -an -an -aj -aj -aj -aj -aj -ab -ab -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -cR -dZ -ev -dZ -cM -fn -fv -fG -fL -cM -cM -cM -cM -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (47,1,1) = {" aa @@ -16524,61 +13219,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -cR -ek -eB -eO -cM -cR -cR -cR -cR -cM -ai -ai -ai -aj -ab -aj -aj -ab -ab -aj -ab -ab -ab -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (48,1,1) = {" aa @@ -16781,61 +13476,61 @@ aj aj aj aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -cR -cR -eC -cR -cR -ab -ab -ab -ab -ai -ai -ai -ab -aj -aj -aj -aj -ab -ab -ab -ai -ad -ad -ab -ab -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (49,1,1) = {" aa @@ -17038,61 +13733,61 @@ aj aj ai ai -aj -aj -aj -aj -aj -aj -aj -ai -ai -ai -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -ab -cR -eE -cR -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ad -ad -ad -ad -ad -ai -ai -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (50,1,1) = {" aa @@ -17295,61 +13990,61 @@ ab ab ai am -ai -ai -ai -ai -ai -ai -ai -am -ai -ab -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -cR -ev -cR -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -ab -ab -ad -ad -ad -ad -ad -ad -ad -ad -ab -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (51,1,1) = {" aa @@ -17552,61 +14247,61 @@ ai ai am am -am -am -am -am -am -am -am -ai -ab -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -cR -ev -cR -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ad -ad -ad -ad -ad -ad -ad -ab -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (52,1,1) = {" aa @@ -17809,61 +14504,61 @@ am am am am -am -am -am -am -am -am -am -ai -ab -aj -aj -ab -ab -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -cR -ev -cR -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ad -ad -ad -ad -ad -ad -ad -ab -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (53,1,1) = {" aa @@ -18066,61 +14761,61 @@ am am am am -am -am -am -am -am -am -am -ai -ab -aj -ab -ab -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -br -vP -br -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ad -ad -ai -ad -ab -ab -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (54,1,1) = {" aa @@ -18323,61 +15018,61 @@ am am am am -am -am -am -am -am -am -am -ai -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -Wp -ab -ab -ab -ab -aj -aj -aj -br -vP -br -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (55,1,1) = {" aa @@ -18580,61 +15275,61 @@ am am am am -am -am -am -am -am -am -am -am -ai -aj -ab -aj -aj -aj -aj -aj -ab -ab -bN -cj -br -ab -ab -aj -aj -aj -ab -br -vP -br -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (56,1,1) = {" aa @@ -18837,61 +15532,61 @@ ak am am am -am -am -am -am -am -am -am -am -ai -ab -ab -aj -aj -aj -aj -aj -aj -ab -br -bP -br -ab -aj -aj -aj -aj -ab -br -eF -br -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (57,1,1) = {" aa @@ -19094,61 +15789,61 @@ ak ak am am -am -am -am -am -am -am -am -am -am -ai -ab -aj -aj -aj -aj -aj -aj -br -br -WE -br -br -ab -aj -aj -ab -br -br -fy -br -br -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (58,1,1) = {" aa @@ -19351,61 +16046,61 @@ ak ak ak am -am -am -am -am -am -am -am -am -am -am -ai -ai -ai -aj -aj -aj -bq -br -bO -ck -cD -br -bq -bq -bq -bq -ns -cH -fU -cD -br -bq -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (59,1,1) = {" aa @@ -19608,61 +16303,61 @@ ak ak ak am -am -am -am -am -am -am -am -am -am -am -am -ai -aj -aj -aj -ab -bq -bC -Gr -bP -TW -cH -cO -do -ck -dJ -CS -cn -vP -bP -eS -bq -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (60,1,1) = {" aa @@ -19865,61 +16560,61 @@ ak ak ak am -am -am -am -am -am -am -am -am -am -am -ai -aj -aj -aj -aj -ab -br -bD -bz -ch -co -cy -cy -MX -sV -cy -eg -eq -fX -eP -eT -bq -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (61,1,1) = {" aa @@ -20122,61 +16817,61 @@ ak ak ak am -am -am -am -am -am -am -am -am -am -ai -aj -aj -aj -aj -ab -ab -br -bE -bQ -cn -cF -cI -cP -cn -Rn -bP -tg -lB -eD -bP -eU -bq -bq -bq -bq -xc -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (62,1,1) = {" aa @@ -20379,61 +17074,61 @@ ak ak ak am -am -am -am -am -am -am -am -am -am -ai -aj -aj -ai -ab -bf -bf -bf -bF -bR -bF -bf -cJ -bq -cZ -dx -dK -tg -bP -eG -bP -eV -br -KS -eV -br -ab -ab -ai -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (63,1,1) = {" aa @@ -20636,61 +17331,61 @@ ak ak ak am -am -am -am -am -am -am -am -am -am -am -ai -ai -ai -ab -bf -bn -bs -bG -bS -ci -bf -cK -bq -bq -Vz -bq -Vz -bP -eG -bP -UP -pg -RW -UP -rf -ab -ab -ai -ai -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (64,1,1) = {" aa @@ -20893,61 +17588,61 @@ ak ak ak am -am -am -am -am -am -am -am -am -am -am -am -ai -ab -ab -bg -bo -fA -il -bU -cm -bf -cL -bq -da -du -dL -cH -Vk -eG -bP -cH -br -Pr -Qo -br -ab -ab -ab -ai -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (65,1,1) = {" aa @@ -21150,61 +17845,61 @@ ak ak am am -am -am -am -am -am -am -am -am -am -am -ai -aj -aj -ab -bg -bo -bt -bH -bV -cq -bf -bq -bq -db -bP -bP -bP -bP -eH -cF -eW -bq -bq -bq -bq -xc -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (66,1,1) = {" aa @@ -21407,61 +18102,61 @@ am am am am -am -am -am -am -am -am -am -am -am -am -ai -aj -aj -ab -bf -bp -bu -bI -bW -cr -bf -ad -bq -dc -bP -dM -dW -Ky -eI -bq -eX -bq -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (67,1,1) = {" aa @@ -21664,61 +18359,61 @@ am am am am -am -am -am -am -am -am -am -am -am -am -ai -aj -aj -ab -bf -bf -bf -bg -bX -bg -bf -ai -bq -dd -bP -dN -dX -em -eJ -dV -eY -bq -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (68,1,1) = {" aa @@ -21921,61 +18616,61 @@ am am am am -am -am -am -am -am -am -am -am -am -am -ai -aj -aj -ab -ab -ab -bf -bJ -bY -cs -bf -ai -bq -de -dv -bq -dV -en -dV -dV -eY -bq -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (69,1,1) = {" aa @@ -22178,61 +18873,61 @@ am am am am -am -am -am -am -am -am -am -am -am -am -ai -ai -aj -aj -ab -ab -bf -bK -bW -ct -bf -ai -bq -df -dw -dO -dY -eo -dY -dY -eZ -bq -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (70,1,1) = {" aa @@ -22435,61 +19130,61 @@ am am am am -am -am -am -am -am -am -am -am -am -ai -ab -ai -ai -aj -aj -ab -bf -bg -WD -bg -bf -ai -bq -bq -bq -bq -bq -bq -bq -bq -bq -bq -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -ab -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (71,1,1) = {" aa @@ -22692,61 +19387,61 @@ am am am am -am -am -am -am -am -am -am -am -ai -ab -ab -ab -ab -ab -ab -ab -bv -ab -ab -ab -bv -ai -ai -ab -ab -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (72,1,1) = {" aa @@ -22949,61 +19644,61 @@ am am am am -am -am -ai -ai -am -am -am -ai -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -ab -ab -aj -aj -aj -aj -aj -ab -aj -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (73,1,1) = {" aa @@ -23206,61 +19901,61 @@ am am am am -am -ai -ab -ab -ai -ai -am -ai -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -ab -ab -aj -aj -aj -aj -ab -ab -ab -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (74,1,1) = {" aa @@ -23463,61 +20158,61 @@ am am am am -ai -ab -ab -ab -ai -ab -ai -am -ai -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -aj -aj -aj -aj -aj -aj -ab -ab -ab -ab -ab -ab -aj -aj -aj -aj -ab -ab -aj -aj -aj -aj -ab -ab -ab -aj -aj -aj -aj +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 +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 +aA +aA +aA +aA +aA "} (75,1,1) = {" aa diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 2947395ccb..c3e7ba0890 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -3086,7 +3086,7 @@ /area/security/main) "ajo" = ( /obj/machinery/vending/coffee, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/red{ @@ -3427,7 +3427,7 @@ "akc" = ( /obj/structure/table/wood, /obj/machinery/recharger, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/machinery/light{ @@ -6882,7 +6882,7 @@ /turf/open/floor/plasteel/dark, /area/bridge) "arK" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/item/folder/yellow{ @@ -9248,7 +9248,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/blue{ @@ -11380,7 +11380,7 @@ /turf/open/floor/wood, /area/crew_quarters/heads/hop) "aBF" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/structure/bed/dogbed/ian, @@ -14151,7 +14151,7 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /obj/effect/turf_decal/tile/neutral{ @@ -17493,7 +17493,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "aQt" = ( -/obj/machinery/status_display, +/obj/machinery/status_display/evac, /turf/closed/wall, /area/hallway/secondary/exit/departure_lounge) "aQu" = ( @@ -24292,7 +24292,7 @@ /obj/structure/cable{ icon_state = "0-2" }, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 30 }, /turf/open/floor/plasteel/dark, @@ -36929,7 +36929,7 @@ /area/medical/surgery) "bHc" = ( /obj/machinery/computer/med_data, -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_y = 32 }, /turf/open/floor/plasteel/freezer, @@ -48691,7 +48691,7 @@ /turf/open/space, /area/space/nearstation) "cmu" = ( -/obj/machinery/status_display{ +/obj/machinery/status_display/evac{ pixel_x = -32 }, /obj/structure/table, diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index ee4288d7fc..905b2cdb1b 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -506,6 +506,7 @@ "bx" = ( /obj/structure/table, /obj/machinery/readybutton, +/obj/item/storage/lockbox/dueling/hugbox/stamina, /turf/open/floor/holofloor/basalt, /area/holodeck/rec_center/thunderdome) "by" = ( @@ -522,6 +523,7 @@ /area/holodeck/rec_center/thunderdome) "bA" = ( /obj/machinery/readybutton, +/obj/item/storage/lockbox/dueling/hugbox/stamina, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -2925,6 +2927,13 @@ /obj/machinery/capture_the_flag/red, /turf/open/floor/circuit/green/anim, /area/ctf) +"hH" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/machinery/computer/slot_machine, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "hI" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -6760,6 +6769,14 @@ }, /turf/open/floor/plasteel/dark, /area/centcom/control) +"px" = ( +/obj/structure/table, +/obj/item/storage/backpack/duffelbag/med/surgery, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/plasteel/white, +/area/centcom/holding) "py" = ( /obj/machinery/smartfridge, /turf/closed/indestructible{ @@ -6775,20 +6792,6 @@ }, /turf/open/floor/plasteel/dark, /area/centcom/supplypod) -"pE" = ( -/obj/machinery/plantgenes/seedvault, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "pH" = ( /obj/structure/table/wood, /obj/machinery/recharger, @@ -6921,11 +6924,6 @@ }, /turf/open/floor/plasteel/dark, /area/centcom/ferry) -"pS" = ( -/obj/structure/table, -/obj/item/stack/packageWrap, -/turf/open/floor/plasteel/cafeteria, -/area/centcom/holding) "pU" = ( /obj/structure/sign/map/right{ pixel_y = -32 @@ -7906,6 +7904,14 @@ }, /turf/open/floor/plating, /area/syndicate_mothership) +"sf" = ( +/obj/machinery/vending/wallmed{ + name = "Emergency NanoMed"; + pixel_y = 28; + use_power = 0 + }, +/turf/open/floor/plasteel/white, +/area/centcom/holding) "si" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/beer{ @@ -8708,6 +8714,9 @@ /area/centcom/supplypod) "tZ" = ( /obj/structure/chair/wood/normal, +/obj/machinery/light{ + dir = 8 + }, /turf/open/indestructible/hotelwood, /area/centcom/holding) "uc" = ( @@ -9339,6 +9348,17 @@ }, /turf/open/floor/plasteel, /area/syndicate_mothership) +"vv" = ( +/obj/structure/closet, +/obj/item/storage/backpack/duffelbag/med/surgery, +/obj/machinery/iv_drip, +/obj/item/roller, +/obj/item/storage/firstaid/regular, +/obj/item/reagent_containers/medspray/synthflesh, +/obj/item/reagent_containers/medspray/synthflesh, +/obj/item/reagent_containers/medspray/synthflesh, +/turf/open/floor/plasteel/white, +/area/centcom/holding) "vw" = ( /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ @@ -9713,13 +9733,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/centcom/supplypod/loading/three) -"wj" = ( -/obj/structure/closet/secure_closet/personal/cabinet{ - desc = "Swipe your ID on the closet to claim it. First come first serve, this one is wooden and fancy. Store your stuff here."; - name = "Personal ID-Locked Closet" - }, -/turf/open/floor/carpet/royalblue, -/area/centcom/holding) "wl" = ( /obj/structure/table/wood, /obj/item/paicard, @@ -10598,12 +10611,6 @@ /obj/effect/decal/cleanable/blood/splatter, /turf/open/floor/grass, /area/wizard_station) -"yM" = ( -/obj/structure/table/wood/bar, -/obj/structure/safe/floor, -/obj/item/seeds/cherry/bomb, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "yN" = ( /obj/structure/table/reinforced, /obj/item/paper/pamphlet/centcom/visitor_info, @@ -10640,6 +10647,15 @@ /obj/item/kitchen/rollingpin, /turf/open/floor/plasteel/cafeteria, /area/syndicate_mothership) +"yW" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/grass, +/area/centcom/holding) "yY" = ( /obj/structure/table/wood, /obj/item/storage/fancy/donut_box, @@ -11049,6 +11065,12 @@ }, /turf/open/floor/plating, /area/syndicate_mothership) +"zS" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/freezer, +/area/centcom/holding) "zT" = ( /turf/open/indestructible/boss/air, /area/centcom/holding) @@ -11345,6 +11367,10 @@ }, /turf/open/floor/plasteel, /area/syndicate_mothership) +"AE" = ( +/obj/machinery/vending/coffee, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "AG" = ( /obj/structure/ladder/unbreakable/binary/space, /turf/open/indestructible/airblock, @@ -11563,21 +11589,11 @@ /obj/machinery/mech_bay_recharge_port, /turf/open/floor/plating, /area/syndicate_mothership) -"Bo" = ( -/obj/structure/table, -/obj/machinery/reagentgrinder, -/obj/item/reagent_containers/glass/beaker/large, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/tile/green{ +"Bq" = ( +/obj/machinery/sleeper{ dir = 8 }, -/turf/open/indestructible/hotelwood, +/turf/open/floor/plasteel/white, /area/centcom/holding) "Bs" = ( /obj/structure/table/wood, @@ -13463,20 +13479,6 @@ /obj/item/instrument/guitar, /turf/open/indestructible/hotelwood, /area/centcom/holding) -"Fb" = ( -/obj/structure/piano, -/obj/machinery/light{ - dir = 8 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) -"Fc" = ( -/obj/structure/sign/barsign{ - pixel_y = 32 - }, -/obj/structure/chair/stool, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "Fg" = ( /obj/structure/flora/grass/brown, /obj/effect/light_emitter, @@ -13485,18 +13487,9 @@ "Fh" = ( /turf/open/floor/plasteel/cafeteria, /area/centcom/holding) -"Fi" = ( -/obj/structure/chair/wood/wings{ - dir = 3 - }, -/obj/machinery/light{ - dir = 1 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) -"Fj" = ( -/obj/machinery/vending/cigarette, -/turf/open/indestructible/hotelwood, +"Fl" = ( +/obj/structure/bedsheetbin/towel, +/turf/open/floor/plasteel/white, /area/centcom/holding) "Fm" = ( /obj/machinery/shower{ @@ -13784,6 +13777,7 @@ /obj/structure/window/reinforced{ dir = 4 }, +/obj/structure/table/wood, /turf/open/indestructible/hotelwood, /area/centcom/holding) "FX" = ( @@ -14409,6 +14403,24 @@ }, /turf/open/floor/plasteel/white, /area/tdome/tdomeobserve) +"Hj" = ( +/obj/machinery/light{ + dir = 8 + }, +/obj/structure/piano, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) +"Hk" = ( +/obj/structure/table/wood, +/obj/item/camera/detective{ + desc = "A polaroid camera with extra capacity for social media marketing."; + name = "Professional camera" + }, +/obj/item/camera_film, +/obj/item/paper_bin, +/obj/item/pen/fountain, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "Hm" = ( /obj/structure/flora/ausbushes/fernybush, /obj/structure/flora/ausbushes/ppflowers, @@ -14747,24 +14759,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/tdome/tdomeobserve) -"HQ" = ( -/obj/structure/sink/kitchen{ - desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; - name = "sink"; - pixel_y = 28 - }, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "HR" = ( /obj/structure/sink{ dir = 4; @@ -15769,6 +15763,12 @@ }, /turf/open/floor/plasteel/dark, /area/tdome/tdomeadmin) +"JV" = ( +/obj/structure/table, +/obj/item/stack/packageWrap, +/obj/item/reagent_containers/glass/beaker, +/turf/open/floor/plasteel/cafeteria, +/area/centcom/holding) "JX" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/stripes/line{ @@ -15826,10 +15826,9 @@ /area/tdome/tdomeadmin) "Kf" = ( /obj/structure/closet/secure_closet/personal/cabinet, -/obj/item/lighter, -/obj/item/stack/sheet/mineral/wood{ - amount = 10 - }, +/obj/item/reagent_containers/rag/towel, +/obj/item/reagent_containers/rag/towel, +/obj/item/reagent_containers/rag/towel, /turf/open/floor/carpet/red, /area/centcom/holding) "Kg" = ( @@ -15848,6 +15847,16 @@ }, /turf/open/floor/plasteel, /area/tdome/tdomeadmin) +"Ki" = ( +/obj/structure/closet/secure_closet/personal/cabinet{ + desc = "Swipe your ID on the closet to claim it. First come first serve, this one is wooden and fancy. Store your stuff here."; + name = "Personal ID-Locked Closet" + }, +/obj/item/reagent_containers/rag/towel, +/obj/item/reagent_containers/rag/towel, +/obj/item/reagent_containers/rag/towel, +/turf/open/floor/carpet/royalblue, +/area/centcom/holding) "Kj" = ( /obj/machinery/door/airlock/external{ name = "Backup Emergency Escape Shuttle" @@ -16202,6 +16211,7 @@ /obj/structure/window/reinforced{ dir = 1 }, +/obj/structure/table/wood, /turf/open/indestructible/hotelwood, /area/centcom/holding) "KU" = ( @@ -16273,6 +16283,20 @@ }, /turf/open/floor/mineral/titanium/blue, /area/centcom/evac) +"Lk" = ( +/obj/structure/table, +/obj/item/storage/box/bodybags, +/obj/item/storage/box/bodybags, +/obj/item/storage/box/bodybags, +/obj/item/storage/box/bodybags, +/turf/open/floor/plasteel/white, +/area/centcom/holding) +"Lm" = ( +/obj/machinery/shower{ + dir = 4 + }, +/turf/open/floor/plasteel/freezer, +/area/centcom/holding) "Ln" = ( /obj/structure/toilet{ dir = 4 @@ -16285,6 +16309,11 @@ }, /turf/open/floor/mineral/titanium/blue, /area/centcom/evac) +"Lr" = ( +/obj/structure/mopbucket, +/obj/item/mop, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "Ls" = ( /obj/docking_port/stationary{ dir = 4; @@ -16570,22 +16599,6 @@ }, /turf/open/indestructible/boss/air, /area/centcom/holding) -"Mu" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "Mv" = ( /obj/structure/table/reinforced, /obj/item/storage/fancy/donut_box, @@ -16616,6 +16629,16 @@ }, /turf/open/floor/plating/asteroid/snow/airless, /area/syndicate_mothership) +"Mz" = ( +/obj/structure/closet/crate, +/obj/item/stack/sheet/paperframes/fifty, +/obj/item/stack/sheet/paperframes/fifty, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/fancy/candle_box, +/obj/item/storage/box/lights/mixed, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "MB" = ( /turf/open/indestructible/binary, /area/fabric_of_reality) @@ -16692,10 +16715,6 @@ /obj/item/reagent_containers/food/condiment/enzyme, /turf/open/floor/plasteel/cafeteria, /area/syndicate_mothership) -"MT" = ( -/obj/machinery/processor, -/turf/open/floor/plasteel/cafeteria, -/area/centcom/holding) "MU" = ( /obj/effect/turf_decal/tile/brown{ dir = 8 @@ -16749,44 +16768,24 @@ }, /turf/open/floor/plasteel, /area/tdome/tdomeobserve) -"Nm" = ( -/obj/structure/closet/crate, -/obj/item/vending_refill/autodrobe, -/obj/item/stack/sheet/paperframes/fifty, -/obj/item/stack/sheet/paperframes/fifty, -/obj/item/storage/fancy/candle_box, -/obj/item/storage/fancy/candle_box, -/obj/item/storage/fancy/candle_box, -/obj/item/storage/box/lights/mixed, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) -"Nn" = ( -/obj/structure/closet/secure_closet/hydroponics{ - locked = 0 - }, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, +"Nt" = ( +/obj/structure/bedsheetbin/color, /turf/open/indestructible/hotelwood, /area/centcom/holding) "Nu" = ( /turf/open/floor/wood, /area/syndicate_mothership) -"Nv" = ( -/obj/structure/table, -/turf/open/floor/plasteel/cafeteria, -/area/centcom/holding) "Nw" = ( /obj/machinery/recharge_station, /turf/open/floor/plasteel/white, /area/centcom/holding) +"Nx" = ( +/obj/machinery/processor, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/cafeteria, +/area/centcom/holding) "Nz" = ( /obj/effect/turf_decal/tile/brown{ dir = 8 @@ -16796,16 +16795,11 @@ }, /turf/open/floor/plasteel, /area/centcom/supplypod/loading/two) -"ND" = ( -/obj/structure/closet, -/obj/item/storage/backpack/duffelbag/med/surgery, -/obj/machinery/iv_drip, -/obj/item/roller, -/obj/item/storage/firstaid/regular, -/obj/item/reagent_containers/medspray/synthflesh, -/obj/item/reagent_containers/medspray/synthflesh, -/obj/item/reagent_containers/medspray/synthflesh, -/turf/open/indestructible/hotelwood, +"NE" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/plasteel/white, /area/centcom/holding) "NF" = ( /obj/structure/ladder/unbreakable/binary, @@ -16822,21 +16816,9 @@ }, /turf/open/floor/plasteel, /area/centcom/control) -"NJ" = ( -/obj/structure/table, -/obj/item/book/manual/hydroponics_pod_people, -/obj/item/seeds/pumpkin/blumpkin, -/obj/item/paper/guides/jobs/hydroponics, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, +"NN" = ( +/obj/item/storage/box/bodybags, +/obj/item/storage/box/bodybags, /turf/open/indestructible/hotelwood, /area/centcom/holding) "NT" = ( @@ -16863,6 +16845,13 @@ /obj/machinery/vending/cola/sodie, /turf/open/floor/plasteel, /area/syndicate_mothership) +"NZ" = ( +/obj/structure/table/wood/bar, +/obj/structure/safe/floor, +/obj/item/seeds/cherry/bomb, +/obj/item/key/janitor, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "Oa" = ( /obj/structure/table/wood, /turf/open/floor/wood, @@ -16933,12 +16922,26 @@ name = "Lock Control"; pixel_y = -28 }, +/mob/living/simple_animal/bot/cleanbot, /turf/open/floor/plasteel/white, /area/centcom/holding) "Or" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/centcom/supplypod/loading/two) +"Os" = ( +/obj/structure/chair/wood/normal{ + dir = 1 + }, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) +"Ot" = ( +/obj/machinery/washing_machine, +/turf/open/floor/mineral/titanium/blue, +/area/centcom/holding) "Ou" = ( /turf/closed/indestructible/fakedoor{ name = "Cold Storage" @@ -17009,6 +17012,10 @@ /obj/structure/mecha_wreckage/mauler, /turf/open/floor/plasteel/dark, /area/syndicate_mothership) +"OT" = ( +/obj/structure/table, +/turf/open/floor/plasteel/white, +/area/centcom/holding) "OU" = ( /obj/item/clothing/under/jabroni, /obj/item/clothing/under/geisha, @@ -17023,13 +17030,36 @@ }, /turf/open/floor/wood, /area/syndicate_mothership) +"OW" = ( +/obj/structure/bedsheetbin/towel, +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/mineral/titanium/blue, +/area/centcom/holding) "OZ" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/plating, /area/syndicate_mothership) -"Pa" = ( -/obj/machinery/washing_machine, -/turf/open/floor/plasteel/white, +"Pc" = ( +/obj/structure/sink/kitchen{ + desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; + name = "sink"; + pixel_y = 28 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/item/paper/guides/jobs/hydroponics, +/obj/item/book/manual/hydroponics_pod_people, +/turf/open/indestructible/hotelwood, /area/centcom/holding) "Pg" = ( /obj/machinery/light{ @@ -17059,12 +17089,6 @@ }, /turf/open/indestructible/boss/air, /area/centcom/holding) -"Pq" = ( -/obj/structure/urinal{ - pixel_y = 28 - }, -/turf/open/floor/plasteel/white, -/area/centcom/holding) "Pr" = ( /obj/structure/table, /obj/item/book/manual/chef_recipes, @@ -17088,12 +17112,6 @@ /obj/machinery/light/small, /turf/open/floor/wood, /area/syndicate_mothership) -"Px" = ( -/obj/structure/mineral_door/paperframe{ - name = "Arcade" - }, -/turf/open/floor/wood, -/area/centcom/holding) "PA" = ( /obj/structure/window/reinforced{ dir = 4 @@ -17158,6 +17176,11 @@ }, /turf/open/floor/plating, /area/syndicate_mothership) +"PQ" = ( +/obj/structure/closet/secure_closet, +/obj/item/coin/silver, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "PS" = ( /obj/machinery/computer/shuttle/syndicate/recall, /obj/effect/turf_decal/tile/bar, @@ -17235,6 +17258,10 @@ "Qo" = ( /turf/open/floor/mineral/plastitanium/red, /area/centcom/evac) +"Qp" = ( +/obj/structure/bedsheetbin, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "Qq" = ( /turf/open/floor/plasteel/freezer, /area/syndicate_mothership) @@ -17253,6 +17280,32 @@ }, /turf/open/floor/wood, /area/centcom/holding) +"Qw" = ( +/turf/open/floor/plasteel/freezer, +/area/centcom/holding) +"Qy" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/plasteel/white, +/area/centcom/holding) +"Qz" = ( +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "QA" = ( /obj/machinery/deepfryer, /turf/open/floor/plasteel/cafeteria, @@ -17283,30 +17336,12 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) -"QH" = ( -/obj/machinery/chem_master/condimaster{ - desc = "Used to separate out liquids - useful for purifying botanical extracts. Also dispenses condiments."; - name = "BrewMaster 2199"; - pixel_x = -4 - }, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/tile/green{ - dir = 8 +"QJ" = ( +/obj/structure/sign/barsign{ + pixel_y = 32 }, /turf/open/indestructible/hotelwood, /area/centcom/holding) -"QI" = ( -/obj/structure/toilet{ - dir = 4 - }, -/turf/open/floor/plasteel/white, -/area/centcom/holding) "QK" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, @@ -17379,20 +17414,6 @@ }, /turf/open/floor/plating, /area/syndicate_mothership) -"Rd" = ( -/obj/machinery/light, -/obj/effect/turf_decal/tile/green{ - dir = 1 - }, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "Re" = ( /obj/structure/mineral_door/paperframe, /turf/open/floor/wood, @@ -17489,6 +17510,31 @@ }, /turf/open/floor/holofloor, /area/holodeck/rec_center/basketball) +"RK" = ( +/obj/structure/closet/crate/freezer/blood, +/turf/open/floor/plasteel/white, +/area/centcom/holding) +"RL" = ( +/obj/machinery/vending/cola, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) +"RN" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder, +/obj/item/reagent_containers/glass/beaker/large, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/light, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "RO" = ( /obj/machinery/shower{ dir = 1 @@ -17579,6 +17625,13 @@ /obj/item/toy/nuke, /turf/open/floor/wood, /area/syndicate_mothership) +"Sj" = ( +/obj/machinery/vending/autodrobe/all_access{ + extended_inventory = 1 + }, +/obj/machinery/light, +/turf/open/floor/wood, +/area/centcom/holding) "So" = ( /obj/structure/chair/wood/wings{ dir = 4 @@ -17672,21 +17725,16 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/space/basic, /area/centcom/supplypod) +"SR" = ( +/obj/machinery/door/airlock/wood{ + id_tag = "Ninja7"; + name = "Dorm 7" + }, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "ST" = ( /turf/open/floor/mineral/titanium/blue, /area/centcom/holding) -"SU" = ( -/obj/structure/table/wood, -/obj/item/camera/detective{ - desc = "A polaroid camera with extra capacity for social media marketing."; - name = "Professional camera" - }, -/obj/item/camera_film, -/obj/item/wallframe/newscaster, -/obj/item/paper_bin, -/obj/item/pen/fountain, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "SV" = ( /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ @@ -17720,10 +17768,6 @@ }, /turf/open/floor/wood, /area/centcom/holding) -"Tb" = ( -/obj/structure/closet/crate/freezer/blood, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "Tc" = ( /obj/machinery/button/door{ id = "Ninja2"; @@ -17734,6 +17778,12 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"Tf" = ( +/obj/machinery/shower{ + dir = 8 + }, +/turf/open/floor/plasteel/freezer, +/area/centcom/holding) "Tj" = ( /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ @@ -17765,6 +17815,16 @@ /obj/structure/closet/chefcloset, /turf/open/floor/plasteel/cafeteria, /area/centcom/holding) +"Tt" = ( +/obj/structure/toilet{ + dir = 4 + }, +/obj/structure/window/reinforced/tinted{ + icon_state = "twindow"; + dir = 1 + }, +/turf/open/floor/plasteel/white, +/area/centcom/holding) "Tu" = ( /obj/structure/flora/ausbushes/fernybush, /obj/structure/flora/ausbushes/fullgrass, @@ -17790,6 +17850,21 @@ /obj/item/clothing/head/helmet/space/plasmaman, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"Tx" = ( +/obj/machinery/plantgenes/seedvault, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/structure/table, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "Tz" = ( /obj/effect/light_emitter, /turf/open/floor/plating/asteroid/snow/airless, @@ -17804,6 +17879,10 @@ /obj/structure/reagent_dispensers/cooking_oil, /turf/open/floor/plasteel/cafeteria, /area/centcom/holding) +"TC" = ( +/obj/machinery/light, +/turf/open/floor/plasteel/freezer, +/area/centcom/holding) "TF" = ( /obj/effect/turf_decal/tile/red{ dir = 8 @@ -17813,12 +17892,16 @@ }, /turf/open/floor/holofloor, /area/holodeck/rec_center/basketball) -"TK" = ( -/obj/structure/table/wood/bar, -/obj/structure/mirror{ - pixel_y = 28 +"TG" = ( +/obj/machinery/light{ + dir = 8 }, -/turf/open/indestructible/hotelwood, +/obj/structure/window/reinforced/tinted{ + icon_state = "twindow"; + dir = 1 + }, +/obj/machinery/washing_machine, +/turf/open/floor/plasteel/white, /area/centcom/holding) "TM" = ( /mob/living/simple_animal/bot/medbot{ @@ -17845,12 +17928,19 @@ }, /turf/open/floor/plasteel/freezer, /area/syndicate_mothership) -"Ud" = ( -/obj/effect/landmark/holding_facility, +"TY" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/item/soap, +/obj/item/soap, +/obj/item/soap, +/obj/item/janiupgrade, +/obj/vehicle/ridden/janicart, /turf/open/indestructible/hotelwood, /area/centcom/holding) -"Uf" = ( -/obj/structure/closet/secure_closet, +"Ud" = ( +/obj/effect/landmark/holding_facility, /turf/open/indestructible/hotelwood, /area/centcom/holding) "Ug" = ( @@ -17879,6 +17969,25 @@ }, /turf/open/floor/plasteel, /area/syndicate_mothership) +"Uk" = ( +/obj/structure/closet/crate, +/obj/item/vending_refill/autodrobe, +/obj/item/vending_refill/autodrobe, +/obj/item/vending_refill/boozeomat, +/obj/item/vending_refill/boozeomat, +/obj/item/vending_refill/cigarette, +/obj/item/vending_refill/cigarette, +/obj/item/vending_refill/clothing, +/obj/item/vending_refill/coffee, +/obj/item/vending_refill/coffee, +/obj/item/vending_refill/cola, +/obj/item/vending_refill/cola, +/obj/item/vending_refill/wallmed, +/obj/item/vending_refill/wallmed, +/obj/item/vending_refill/snack, +/obj/item/vending_refill/snack, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "Ul" = ( /obj/structure/table, /obj/machinery/microwave{ @@ -17916,6 +18025,17 @@ /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plasteel, /area/tdome/tdomeobserve) +"Uq" = ( +/obj/structure/table/wood, +/obj/item/soap, +/obj/item/soap, +/obj/item/soap, +/obj/item/lightreplacer, +/obj/item/lightreplacer, +/obj/item/storage/bag/trash, +/obj/item/storage/bag/trash, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "Ur" = ( /turf/open/floor/carpet/royalblue, /area/centcom/holding) @@ -17940,6 +18060,11 @@ /obj/effect/light_emitter, /turf/open/floor/plating/asteroid/snow/airless, /area/syndicate_mothership) +"Uz" = ( +/obj/structure/table, +/obj/machinery/dish_drive, +/turf/open/floor/plasteel/cafeteria, +/area/centcom/holding) "UC" = ( /obj/machinery/vending/cola, /turf/open/floor/plasteel, @@ -17949,6 +18074,9 @@ desc = "Swipe your ID on the closet to claim it. First come first serve, this one is wooden and fancy. Store your stuff here."; name = "Personal ID-Locked Closet" }, +/obj/item/coin/silver, +/obj/item/coin/silver, +/obj/item/coin/silver, /turf/open/indestructible/hotelwood, /area/centcom/holding) "UE" = ( @@ -17971,6 +18099,17 @@ }, /turf/open/floor/plasteel, /area/centcom/supplypod) +"UN" = ( +/obj/structure/mirror{ + pixel_y = 28 + }, +/obj/structure/sink{ + dir = 1; + pixel_y = 25 + }, +/mob/living/simple_animal/bot/cleanbot, +/turf/open/floor/mineral/titanium/blue, +/area/centcom/holding) "UO" = ( /obj/machinery/door/airlock/centcom{ name = "CentCom Security"; @@ -17994,6 +18133,10 @@ }, /turf/open/floor/plasteel, /area/centcom/supplypod/loading/one) +"US" = ( +/obj/machinery/gibber, +/turf/open/floor/plasteel/cafeteria, +/area/centcom/holding) "UT" = ( /obj/structure/chair/wood/wings{ dir = 1 @@ -18061,13 +18204,6 @@ /obj/structure/window/reinforced/tinted, /turf/open/floor/plasteel/freezer, /area/syndicate_mothership) -"Vm" = ( -/obj/machinery/gibber, -/obj/machinery/light{ - dir = 1 - }, -/turf/open/floor/plasteel/cafeteria, -/area/centcom/holding) "Vt" = ( /obj/item/paper/fluff/stations/centcom/disk_memo, /obj/structure/noticeboard{ @@ -18232,11 +18368,26 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"Wz" = ( +/obj/structure/table, +/obj/item/storage/backpack/duffelbag/med/surgery, +/turf/open/floor/plasteel/white, +/area/centcom/holding) "WC" = ( /obj/structure/table/reinforced, /obj/item/pen, /turf/open/floor/mineral/plastitanium/red, /area/centcom/evac) +"WD" = ( +/obj/structure/mopbucket, +/obj/item/mop, +/obj/structure/sink/kitchen{ + desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; + name = "sink"; + pixel_y = 28 + }, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "WE" = ( /obj/machinery/vending/kink{ extended_inventory = 1 @@ -18321,6 +18472,13 @@ /obj/machinery/processor, /turf/open/floor/plasteel/cafeteria, /area/syndicate_mothership) +"WY" = ( +/obj/machinery/vending/cigarette, +/obj/machinery/light{ + dir = 4 + }, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "Xd" = ( /obj/structure/flora/ausbushes/fernybush, /obj/structure/flora/ausbushes/fullgrass, @@ -18332,6 +18490,19 @@ /obj/machinery/vending/autodrobe, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"Xf" = ( +/obj/structure/table/wood/bar, +/obj/structure/mirror{ + pixel_y = 28 + }, +/obj/item/lightreplacer, +/obj/item/lightreplacer, +/obj/item/lightreplacer, +/obj/item/storage/bag/trash, +/obj/item/storage/bag/trash, +/obj/item/storage/bag/trash, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "Xg" = ( /obj/effect/turf_decal/tile/red{ dir = 4 @@ -18443,6 +18614,26 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"XS" = ( +/obj/structure/closet/secure_closet/hydroponics{ + locked = 0 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/item/seeds/ambrosia/gaia, +/obj/item/seeds/ambrosia/gaia, +/obj/item/seeds/pumpkin/blumpkin, +/obj/item/seeds/pumpkin/blumpkin, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "XT" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/sashimi, @@ -18515,6 +18706,10 @@ /obj/structure/dresser, /turf/open/floor/plasteel/dark, /area/syndicate_mothership) +"Yj" = ( +/obj/structure/table/optable, +/turf/open/floor/plasteel/white, +/area/centcom/holding) "Ym" = ( /obj/machinery/computer/arcade/orion_trail, /turf/open/indestructible/hotelwood, @@ -18580,11 +18775,6 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) -"YQ" = ( -/obj/structure/table, -/obj/item/reagent_containers/glass/beaker, -/turf/open/floor/plasteel/cafeteria, -/area/centcom/holding) "YU" = ( /obj/structure/window/reinforced{ dir = 1 @@ -18636,12 +18826,6 @@ /obj/machinery/light, /turf/open/floor/plasteel/dark, /area/syndicate_mothership) -"Zu" = ( -/obj/machinery/vending/autodrobe/all_access{ - extended_inventory = 1 - }, -/turf/open/floor/wood, -/area/centcom/holding) "Zw" = ( /obj/structure/bed, /obj/item/bedsheet/syndie, @@ -18705,6 +18889,30 @@ }, /turf/open/floor/mineral/plastitanium/red, /area/syndicate_mothership) +"ZL" = ( +/obj/structure/closet, +/obj/item/stack/sheet/mineral/wood/fifty, +/obj/item/stack/tile/wood{ + amount = 24 + }, +/obj/item/stack/tile/carpet/black/fifty, +/obj/item/stack/tile/carpet/blackred/fifty, +/obj/item/stack/tile/carpet/blue/fifty, +/obj/item/stack/tile/carpet/cyan/fifty, +/obj/item/stack/tile/carpet/fifty, +/obj/item/stack/tile/carpet/green/fifty, +/obj/item/stack/tile/carpet/monochrome/fifty, +/obj/item/stack/tile/carpet/orange/fifty, +/obj/item/stack/tile/carpet/purple/fifty, +/obj/item/stack/tile/carpet/red/fifty, +/obj/item/stack/tile/carpet/royalblack/fifty, +/obj/item/stack/tile/carpet/royalblue/fifty, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) +"ZN" = ( +/obj/machinery/vending/snack, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "ZP" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -18717,6 +18925,10 @@ "ZQ" = ( /turf/open/floor/plasteel, /area/centcom/supplypod/loading/two) +"ZR" = ( +/obj/structure/bed/dogbed, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "ZT" = ( /mob/living/simple_animal/cow, /turf/open/floor/grass, @@ -18752,6 +18964,27 @@ }, /turf/open/floor/plasteel, /area/centcom/supply) +"ZZ" = ( +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green{ + dir = 1 + }, +/obj/effect/turf_decal/tile/green, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/obj/effect/turf_decal/tile/green{ + dir = 8 + }, +/obj/machinery/chem_master/condimaster{ + desc = "Used to separate out liquids - useful for purifying botanical extracts. Also dispenses condiments."; + name = "BrewMaster 2199"; + pixel_x = -4 + }, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) (1,1,1) = {" aa @@ -42833,8 +43066,6 @@ aa aa aa aa -aa -aa Nd Nd Nd @@ -42872,13 +43103,15 @@ Nd Nd Nd Nd -aa Nd Nd Nd Nd Nd -aa +Nd +Nd +Nd +Nd aa aa aa @@ -43090,19 +43323,19 @@ aa aa aa aa -aa -aa Nd -PO +SW PO PO Sw PO PO PO +PO Nd -QI -VA +Tt +Tt +TG Op Nd Rm @@ -43116,27 +43349,27 @@ NT UV CV Sd -NT -Sd -Sd -Sd -Sd -Sd -Sd +Nd +OW +Ln +Nd +Lm +Lm +Lm +Nd +PQ Sd +ZR +Nd +RL +Yo +Uq Nd VL Ww -Sd +NN Nd aa -Nd -Uf -Sd -Sd -Nd -aa -aa aa aa aa @@ -43347,10 +43580,9 @@ aa aa aa aa -aa -aa Nd -HQ +Pc +PY PY PY PY @@ -43358,7 +43590,8 @@ PY PY PY Nd -Pq +ZW +ZW ZW ZW Za @@ -43373,26 +43606,26 @@ NT RQ Sd Sd -NT -Sd -Sd -Sd -Sd -Sd -Sd -Sd Nd -Gs -Sd -HH +UN +ST Nd -aa +zS +Qw +TC Nd MJ Sd Sd Nd -aa +AE +Sd +Ph +Nd +Gs +Sd +HH +Nd aa aa aa @@ -43604,18 +43837,18 @@ aa aa aa aa -aa -aa Nd -Mu -QH -Bo -vs -Rj -PI -Rd +ZZ +PY +PY +PY +PY +PY +PY +RN Nd -Pa +SB +ZW ZW ZW Nd @@ -43630,26 +43863,26 @@ NT UV CV Sd -NT -Sd -MR -Sd -Sd -Sd -MR -Sd Nd -Sd -Sd -Sd +Ot +ST Nd -aa +Tf +Qw +Tf Nd ma Sd Sd Nd -aa +ZN +Sd +Sd +Nd +ZL +Sd +Lr +Nd aa aa aa @@ -43861,19 +44094,19 @@ aa aa aa aa -aa -aa Nd +PI PY PY PY PY PY PY -PY +Rj Nd SB -ZW +NE +Fl Nw Nd Sd @@ -43884,29 +44117,29 @@ Sd Tu Vu Nd -Gs +hH Sd Sd Nd Nd +Wl Nd Nd -Px -Nd -Nd -Nd -Nd -Nd -Ox -Nd -Nd +Wl Nd Nd Nd yS Nd Nd -aa +WD +Sd +HH +Nd +Nd +Ox +Nd +Nd aa aa aa @@ -44118,16 +44351,16 @@ aa aa aa aa -aa -aa Nd -pE -NJ -SW +Tx +PY +PY PY Um -Nn +XS PY +vs +Nd Nd Nd Nd @@ -44146,19 +44379,20 @@ CV Sd NT Sd -Yo Sd Sd Sd -Yo +Sd Sd Nd Sd Sd -Yo Sd Sd -Yo +Sd +Sd +Sd +Sd Sd Sd WE @@ -44168,7 +44402,6 @@ aa aa aa aa -aa KK KN KS @@ -44375,8 +44608,6 @@ aa aa aa aa -aa -aa Nd Nd Nd @@ -44386,6 +44617,8 @@ Nd Nd py Nd +Nd +Yh Sd Yo Sd @@ -44408,7 +44641,6 @@ Sd Sd Sd Sd -Sd Qu Sd Sd @@ -44418,14 +44650,15 @@ Sd Sd Sd Sd -Zu +Sd +Sd +Sj Nd aa aa aa aa aa -aa KH KH KS @@ -44632,18 +44865,18 @@ aa aa aa aa -aa -aa Nd -PL +Lr Sd Yo Sd Sd Sd Sd -Yh Sd +Sd +Sd +Nd Nd Nd Nd @@ -44663,7 +44896,6 @@ Sd MR Sd Sd -Sd MR Sd Nd @@ -44675,6 +44907,8 @@ Sd Sd Sd Sd +Sd +Sd PM Nd aa @@ -44683,7 +44917,6 @@ aa aa aa aa -aa KH KU Lb @@ -44889,19 +45122,19 @@ aa aa aa aa -aa -aa Nd Tq Sd MG YN Nd -Vm +US +Fh Fh zV Nd Nd +Hj Fa KT Sd @@ -44928,6 +45161,7 @@ Nd Nd Nd Rq +Sd HH Nd Nd @@ -44939,7 +45173,6 @@ aa aa aa aa -aa KL KO KV @@ -45146,19 +45379,19 @@ aa aa aa aa -aa -aa Nd -Nf +ZL Sd Rh Mm Nd -MT +Nx +Fh Fh Yu Nd -Fb +AE +CV Sd KT Sd @@ -45186,9 +45419,10 @@ SY Nd Sd Sd +Sd Nd SY -Ri +Os UD Nd aa @@ -45197,7 +45431,6 @@ aa aa aa aa -aa KH KW Lb @@ -45403,19 +45636,19 @@ aa aa aa aa -aa -aa Nd +ZN Sd -Sd -Rh +yW ZT Nd Pr Fh +Fh QW Nd -Fc +QJ +Sd Sd KT Sd @@ -45437,16 +45670,17 @@ Sd Sd Sd Nd -Gs +Sd Sd Sd lS Sd Sd +Sd RP Sd Sd -HH +Sd Nd aa aa @@ -45454,7 +45688,6 @@ aa aa aa aa -aa KP KX Lb @@ -45660,8 +45893,6 @@ aa aa aa aa -aa -aa Nd Nd XL @@ -45670,9 +45901,11 @@ Nd Nd JE Fh -YQ +Fh +Vv Nd -MR +Sd +Sd Sd FW Sd @@ -45700,6 +45933,7 @@ Ya Nd Sd Sd +Sd Nd XD Sd @@ -45711,7 +45945,6 @@ aa aa aa aa -aa KH KY Lb @@ -45917,19 +46150,19 @@ aa aa aa aa -aa -aa Nd -yM +NZ Sd Yo -Sd +PL Nd SG Fh -Vv -Nd -Nd +Fh +Fh +Wl +Sd +MR Sd FX Sd @@ -45957,6 +46190,7 @@ Nd Nd Sd Sd +Sd Nd Nd Nd @@ -45967,7 +46201,6 @@ aa aa aa aa -aa KM KO KV @@ -46174,18 +46407,18 @@ aa aa aa aa -aa -aa Nd OG Sd Sd -Sd +Tq Nd zX Fh -pS +Fh +JV Nd +Dl Nd Nd Nd @@ -46214,9 +46447,10 @@ SY Nd Sd Sd +Sd Nd SY -Ri +Os UD Nd aa @@ -46225,7 +46459,6 @@ aa aa aa aa -aa KH KU Lb @@ -46431,18 +46664,18 @@ aa aa aa aa -aa -aa Nd -TK -Sd +Xf Sd Sd +Nf Nd QA Fh -Nv +Fh +Uz ED +Sd Yo Yf UE @@ -46454,7 +46687,7 @@ Sd Sd Tn NT -Ro +Sd Ud Ud NT @@ -46465,23 +46698,23 @@ zT MM TM Nd -Gs +Sd Sd Sd uh Sd Sd +Sd zW Sd Sd -HH +Sd Nd aa aa aa aa aa -aa KH KH KS @@ -46688,19 +46921,19 @@ aa aa aa aa -aa -aa Nd YL Sd Sd -Sd +Uk Nd Xo Fh Fh +Fh py Sd +Sd SY UE Sd @@ -46711,7 +46944,7 @@ Sd Sd GY NT -Tw +Sd Ud Ud NT @@ -46728,6 +46961,7 @@ Tc Nd Sd Sd +Sd Nd AC Sd @@ -46738,7 +46972,6 @@ aa aa aa aa -aa KI KN KS @@ -46945,19 +47178,19 @@ aa aa aa aa -aa -aa Nd Xe Sd Sd -Sd +ZL Nd TB Fh Fh +Fh BV Sd +Sd XT UE Sd @@ -46984,6 +47217,7 @@ Nd Nd Nd Rq +Sd HH Nd Nd @@ -46995,7 +47229,6 @@ aa aa aa aa -aa KJ KN KZ @@ -47202,19 +47435,19 @@ aa aa aa aa -aa -aa Nd -Gs +TY Sd Sd Sd Nd Vz Fh +Fh YJ QT Sd +Sd SY UE Sd @@ -47242,6 +47475,7 @@ YO Nd Sd Sd +Sd Nd RX Xw @@ -47252,7 +47486,6 @@ aa aa aa aa -aa KK KN KQ @@ -47459,8 +47692,6 @@ aa aa aa aa -aa -aa Nd Bs Ri @@ -47470,8 +47701,10 @@ XL Fh Fh Fh +Fh XL Sd +Sd XX UE Sd @@ -47499,6 +47732,7 @@ Sd SZ Sd Sd +Sd Ws Sd Sd @@ -47509,7 +47743,6 @@ aa aa aa aa -aa KH KH KH @@ -47716,22 +47949,22 @@ aa aa aa aa -aa -aa Nd -SU +Hk Sd MR -Nm +Mz Nd SN pV +pV Tr Nd -Fj +WY +Ph Nd Nd -Fi +Rm Tn UT Hm @@ -47739,14 +47972,14 @@ Sd Sd GY NT -Sd +Tw Ms -Sd +Ro NT vt Mx -ND -Tb +Sd +Sd Uh tW Nd @@ -47755,11 +47988,12 @@ Of QF Nd Sd -sa +Sd +Sd Nd WN Ur -wj +Ki Nd aa aa @@ -47792,7 +48026,6 @@ aa aa aa aa -aa "} (114,1,1) = {" aa @@ -47973,8 +48206,6 @@ aa aa aa aa -aa -aa Nd Nd Nd @@ -48004,6 +48235,8 @@ Nd Nd Nd Nd +Sd +Sd Nd Nd Nd @@ -48011,8 +48244,9 @@ Kf WV Sd Nd -Nd -Nd +sa +Sd +Sd Nd Sd zY @@ -48049,7 +48283,6 @@ aa aa aa aa -aa "} (115,1,1) = {" aa @@ -48256,20 +48489,21 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa +Nd +vv +VA +ZW +ZW +px +Lk Nd Nd Nd QC Nd -aa -aa +Nd +SR +Nd Nd QC Nd @@ -48306,7 +48540,6 @@ aa aa aa aa -aa "} (116,1,1) = {" aa @@ -48513,20 +48746,21 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa +Nd +sf +ZW +ZW +ZW +ZW +OT Nd Ln ST ST Nd -aa -aa +Qp +Sd +Nt Nd ST ST @@ -48563,7 +48797,6 @@ aa aa aa aa -aa "} (117,1,1) = {" aa @@ -48770,20 +49003,21 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa +Nd +Bq +RK +Qy +Yj +ZW +Wz Nd xO QN ZE Nd -aa -aa +Qp +Qz +Nt Nd ZE QN @@ -48820,7 +49054,6 @@ aa aa aa aa -aa "} (118,1,1) = {" aa @@ -49027,26 +49260,26 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa Nd Nd Nd Nd Nd -aa -aa Nd Nd Nd Nd Nd -aa +Nd +Nd +Nd +Nd +Nd +Nd +Nd +Nd +Nd +Nd aa aa aa diff --git a/_maps/shuttles/infiltrator_basic.dmm b/_maps/shuttles/infiltrator_basic.dmm index f7ec35c667..1dffe12884 100644 --- a/_maps/shuttles/infiltrator_basic.dmm +++ b/_maps/shuttles/infiltrator_basic.dmm @@ -924,25 +924,16 @@ /turf/open/floor/plasteel/dark, /area/shuttle/syndicate/medical) "ce" = ( -/obj/item/sbeacondrop/bomb{ - pixel_y = 5 - }, -/obj/item/sbeacondrop/bomb, /obj/structure/table/reinforced, /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/landmark/start/nuclear_equipment, +/obj/effect/landmark/start/nuclear_equipment, /turf/open/floor/plasteel/dark, /area/shuttle/syndicate/armory) "cf" = ( -/obj/item/grenade/syndieminibomb{ - pixel_x = 4; - pixel_y = 2 - }, -/obj/item/grenade/syndieminibomb{ - pixel_x = -1 - }, /obj/structure/table/reinforced, /obj/structure/window/reinforced{ dir = 4 @@ -956,6 +947,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/landmark/start/nuclear_equipment/minibomb, /turf/open/floor/plasteel/dark, /area/shuttle/syndicate/armory) "cg" = ( diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 4052dce40d..6913473e88 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -136,8 +136,12 @@ #define ORGAN_SLOT_TESTICLES "testicles" #define ORGAN_SLOT_BREASTS "breasts" - ////organ defines #define STANDARD_ORGAN_THRESHOLD 100 #define STANDARD_ORGAN_HEALING 0.001 -#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes \ No newline at end of file +#define STANDARD_ORGAN_DECAY 0.00222 //designed to fail organs when left to decay for ~15 minutes + +#define G_MALE 1 +#define G_FEMALE 2 +#define G_PLURAL 3 +#define G_NEUTER 4 diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 3acd1443af..0b46f21a97 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -73,6 +73,7 @@ #define ADMIN_PUNISHMENT_SUPPLYPOD "Supply Pod" #define ADMIN_PUNISHMENT_MAZING "Puzzle" #define ADMIN_PUNISHMENT_PIE "Cream Pie" +#define ADMIN_PUNISHMENT_CUSTOM_PIE "Custom Cream Pie" #define AHELP_ACTIVE 1 #define AHELP_CLOSED 2 @@ -87,5 +88,5 @@ #define MAX_KEYPRESS_COMMANDLENGTH 16 ///Max amount of keypress messages per second over two seconds before client is autokicked #define MAX_KEYPRESS_AUTOKICK 100 -///Length of held key rolling buffer -#define HELD_KEY_BUFFER_LENGTH 15 +///Length of max held keys +#define MAX_HELD_KEYS 15 diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 456582c6a5..e728d49956 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -149,9 +149,9 @@ //OPEN TURF ATMOS #define OPENTURF_DEFAULT_ATMOS "o2=22;n2=82;TEMP=293.15" //the default air mix that open turfs spawn -#define TCOMMS_ATMOS "n2=100;TEMP=80" //-193,15C telecommunications. also used for xenobiology slime killrooms +#define TCOMMS_ATMOS "n2=100;TEMP=80" //-193,15degC telecommunications. also used for xenobiology slime killrooms #define AIRLESS_ATMOS "TEMP=2.7" //space -#define FROZEN_ATMOS "o2=22;n2=82;TEMP=180" //-93.15C snow and ice turfs +#define FROZEN_ATMOS "o2=22;n2=82;TEMP=180" //-93.15degC snow and ice turfs #define BURNMIX_ATMOS "o2=2500;plasma=5000;TEMP=370" //used in the holodeck burn test program //ATMOSPHERICS DEPARTMENT GAS TANK TURFS @@ -254,6 +254,18 @@ #define PIPING_CARDINAL_AUTONORMALIZE (1<<3) //north/south east/west doesn't matter, auto normalize on build. //HELPERS +#define PIPING_LAYER_SHIFT(T, PipingLayer) \ + if(T.dir & NORTH || T.dir & SOUTH) { \ + T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\ + } \ + if(T.dir & WEST || T.dir & EAST) { \ + T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;\ + } + +#define PIPING_LAYER_DOUBLE_SHIFT(T, PipingLayer) \ + T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\ + T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y; + #define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity()) #define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */ diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index cc1b474c49..4304af77f3 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -184,7 +184,7 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define BODY_ZONE_PRECISE_R_FOOT "r_foot" //We will round to this value in damage calculations. -#define DAMAGE_PRECISION 0.1 +#define DAMAGE_PRECISION 0.01 //items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25) #define TOTAL_MASS_TINY_ITEM 1.25 @@ -202,4 +202,4 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define BULLET_ACT_HIT "HIT" //It's a successful hit, whatever that means in the context of the thing it's hitting. #define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting. #define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default. -#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs. \ No newline at end of file +#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs. diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 20679a95e6..0d2e88042d 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -123,6 +123,7 @@ #define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" //from base of turf/New(): (turf/source, direction) // /atom/movable signals +#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" //from base of atom/movable/Moved(): (/atom) #define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir) #define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable) #define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable) @@ -197,6 +198,7 @@ #define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living) #define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage) #define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: () +#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" //sent when a mob/login() finishes: (client) #define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override) // /mob/living/carbon signals @@ -274,8 +276,6 @@ #define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool. #define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength) -//Blood color -#define COMSIG_BLOOD_COLOR "blood_DNA_to_color" //RGB blood stuff //Food #define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder) diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index 3034876e36..6b70eb1e0f 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -1,6 +1,7 @@ //config files #define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X) #define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y) +#define CONFIG_GET_ENTRY(X) global.config.GetEntryDatum(/datum/config_entry/##X) #define CONFIG_MAPS_FILE "maps.txt" diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index 2756be76fb..f4954f8f05 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -110,6 +110,7 @@ #define HIDENECK (1<<10) #define HIDETAUR (1<<11) //gotta hide that snowflake #define HIDESNOUT (1<<12) //or do we actually hide our snoots +#define HIDEACCESSORY (1<<13) //hides the jumpsuit accessory. //bitflags for clothing coverage - also used for limbs #define HEAD (1<<0) diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 8ae4e5c167..eee0676dec 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -96,12 +96,22 @@ #define NUKESTATE_CORE_EXPOSED 1 #define NUKESTATE_CORE_REMOVED 0 +#define NUKEUI_AWAIT_DISK 0 +#define NUKEUI_AWAIT_CODE 1 +#define NUKEUI_AWAIT_TIMER 2 +#define NUKEUI_AWAIT_ARM 3 +#define NUKEUI_TIMING 4 +#define NUKEUI_EXPLODED 5 + #define NUKE_OFF_LOCKED 0 #define NUKE_OFF_UNLOCKED 1 #define NUKE_ON_TIMING 2 #define NUKE_ON_EXPLODING 3 +#define MACHINE_NOT_ELECTRIFIED 0 +#define MACHINE_ELECTRIFIED_PERMANENT -1 +#define MACHINE_DEFAULT_ELECTRIFY_TIME 30 //these flags are used to tell the DNA modifier if a plant gene cannot be extracted or modified. #define PLANT_GENE_REMOVABLE (1<<0) -#define PLANT_GENE_EXTRACTABLE (1<<1) \ No newline at end of file +#define PLANT_GENE_EXTRACTABLE (1<<1) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index d68fb9b490..e2d93aebf5 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -25,30 +25,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s #define NOT_IMPLEMENTED "NOT_IMPLEMENTED" -#define MIDNIGHT_ROLLOVER 864000 //number of deciseconds in a day - -#define JANUARY 1 -#define FEBRUARY 2 -#define MARCH 3 -#define APRIL 4 -#define MAY 5 -#define JUNE 6 -#define JULY 7 -#define AUGUST 8 -#define SEPTEMBER 9 -#define OCTOBER 10 -#define NOVEMBER 11 -#define DECEMBER 12 - -//Select holiday names -- If you test for a holiday in the code, make the holiday's name a define and test for that instead -#define NEW_YEAR "New Year" -#define VALENTINES "Valentine's Day" -#define APRIL_FOOLS "April Fool's Day" -#define EASTER "Easter" -#define HALLOWEEN "Halloween" -#define CHRISTMAS "Christmas" -#define FESTIVE_SEASON "Festive Season" - //Human Overlays Indexes///////// //LOTS OF CIT CHANGES HERE. BE CAREFUL WHEN UPSTREAM ADDS MORE LAYERS #define MUTATIONS_LAYER 32 //mutations. Tk headglows, cold resistance glow, etc diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 8d2913629a..a7d6056ab9 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -200,9 +200,11 @@ #define NO_SLIP_WHEN_WALKING (1<<0) #define SLIDE (1<<1) #define GALOSHES_DONT_HELP (1<<2) -#define SLIDE_ICE (1<<3) -#define SLIP_WHEN_CRAWLING (1<<4) //clown planet ruin -#define SLIP_WHEN_JOGGING (1<<5) //slips prevented by walking are also dodged if the mob is not sprinting or fatigued... unless this flag is on. +#define FLYING_DOESNT_HELP (1<<3) +#define SLIDE_ICE (1<<4) +#define SLIP_WHEN_CRAWLING (1<<5) //clown planet ruin amongst others +#define SLIP_WHEN_JOGGING (1<<6) //slips prevented by walking are also dodged if the mob is nor sprinting or fatigued... unless this flag is on. + #define MAX_CHICKENS 50 diff --git a/code/__DEFINES/move_force.dm b/code/__DEFINES/move_force.dm new file mode 100644 index 0000000000..ec31388c72 --- /dev/null +++ b/code/__DEFINES/move_force.dm @@ -0,0 +1,20 @@ +//Defaults +#define MOVE_FORCE_DEFAULT 1000 +#define MOVE_RESIST_DEFAULT 1000 +#define PULL_FORCE_DEFAULT 1000 + +//Factors/modifiers +#define MOVE_FORCE_PULL_RATIO 1 //Same move force to pull objects +#define MOVE_FORCE_PUSH_RATIO 1 //Same move force to normally push +#define MOVE_FORCE_FORCEPUSH_RATIO 2 //2x move force to forcefully push +#define MOVE_FORCE_CRUSH_RATIO 3 //3x move force to do things like crush objects +#define MOVE_FORCE_THROW_RATIO 1 //Same force throw as resist to throw objects + +#define MOVE_FORCE_OVERPOWERING (MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO * 10) +#define MOVE_FORCE_EXTREMELY_STRONG (MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO * 3) +#define MOVE_FORCE_VERY_STRONG ((MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO) - 1) +#define MOVE_FORCE_STRONG (MOVE_FORCE_DEFAULT * 2) +#define MOVE_FORCE_NORMAL MOVE_FORCE_DEFAULT +#define MOVE_FORCE_WEAK (MOVE_FORCE_DEFAULT / 2) +#define MOVE_FORCE_VERY_WEAK ((MOVE_FORCE_DEFAULT / MOVE_FORCE_CRUSH_RATIO) + 1) +#define MOVE_FORCE_EXTREMELY_WEAK (MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3)) \ No newline at end of file diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index 36ea64de2c..54f4648006 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -8,7 +8,7 @@ #define REAGENT_PURITY_ACCURACY 0.001 #define DEFAULT_SPECIFIC_HEAT 200 -// container_type defines +//reagents_holder_flags defines #define INJECTABLE (1<<0) // Makes it possible to add reagents through droppers and syringes. #define DRAWABLE (1<<1) // Makes it possible to remove reagents through syringes. @@ -29,6 +29,11 @@ #define PATCH 4 // patches #define INJECT 5 // injection +//container_flags +#define PH_WEAK (1 << 0) +#define TEMP_WEAK (1 << 1) +#define APTFT_VERB (1 << 2) //APTFT stands for "amount per transfer from this" +#define APTFT_ALTCLICK (1 << 3) //defines passed through to the on_reagent_change proc #define DEL_REAGENT 1 // reagent deleted (fully cleared) diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index d5e3f828b8..28a04c2a51 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -37,7 +37,7 @@ #define ROLE_GANG "gangster" #define ROLE_BLOODSUCKER "bloodsucker" //#define ROLE_MONSTERHUNTER "monster hunter" Disabled for now - +#define ROLE_GHOSTCAFE "ghostcafe" //Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR. //The gamemode specific ones are just so the gamemodes can query whether a player is old enough //(in game days played) to play that role diff --git a/code/__DEFINES/time.dm b/code/__DEFINES/time.dm index f13f13510b..af618cf828 100644 --- a/code/__DEFINES/time.dm +++ b/code/__DEFINES/time.dm @@ -1,3 +1,27 @@ +#define MIDNIGHT_ROLLOVER 864000 //number of deciseconds in a day + +#define JANUARY 1 +#define FEBRUARY 2 +#define MARCH 3 +#define APRIL 4 +#define MAY 5 +#define JUNE 6 +#define JULY 7 +#define AUGUST 8 +#define SEPTEMBER 9 +#define OCTOBER 10 +#define NOVEMBER 11 +#define DECEMBER 12 + +//Select holiday names -- If you test for a holiday in the code, make the holiday's name a define and test for that instead +#define NEW_YEAR "New Year" +#define VALENTINES "Valentine's Day" +#define APRIL_FOOLS "April Fool's Day" +#define EASTER "Easter" +#define HALLOWEEN "Halloween" +#define CHRISTMAS "Christmas" +#define FESTIVE_SEASON "Festive Season" + /* Days of the week to make it easier to reference them. @@ -30,5 +54,5 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using #define WORLDTIME2TEXT(format) GAMETIMESTAMP(format, world.time) #define WORLDTIMEOFDAY2TEXT(format) GAMETIMESTAMP(format, world.timeofday) #define TIME_STAMP(format, showds) showds ? "[WORLDTIMEOFDAY2TEXT(format)]:[world.timeofday % 10]" : WORLDTIMEOFDAY2TEXT(format) -#define STATION_TIME(display_only) ((((world.time - SSticker.round_start_time) * SSticker.station_time_rate_multiplier) + SSticker.gametime_offset) % 864000) - (display_only? GLOB.timezoneOffset : 0) -#define STATION_TIME_TIMESTAMP(format) time2text(STATION_TIME(TRUE), format) +#define STATION_TIME(display_only, wtime) ((((wtime - SSticker.round_start_time) * SSticker.station_time_rate_multiplier) + SSticker.gametime_offset) % 864000) - (display_only? GLOB.timezoneOffset : 0) +#define STATION_TIME_TIMESTAMP(format, wtime) time2text(STATION_TIME(TRUE, wtime), format) diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm index 3fd6b069d4..7e391caaed 100644 --- a/code/__DEFINES/tools.dm +++ b/code/__DEFINES/tools.dm @@ -14,7 +14,9 @@ #define TOOL_DRILL "drill" #define TOOL_SCALPEL "scalpel" #define TOOL_SAW "saw" - +//Glasswork Tools +#define TOOL_BLOW "blowing_rod" +#define TOOL_GLASS_CUT "glasskit" // If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY, // tool sound is only played when op is started. If not, it's played twice. diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index e48eea451d..d707f7e58a 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -173,6 +173,7 @@ #define TRAIT_AUTO_CATCH_ITEM "auto_catch_item" #define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman. #define TRAIT_FREESPRINT "free_sprinting" +#define TRAIT_NO_TELEPORT "no-teleport" //you just can't #define TRAIT_NO_ALCOHOL "alcohol_intolerance" // common trait sources @@ -233,5 +234,7 @@ #define ABDUCTOR_ANTAGONIST "abductor-antagonist" #define NUKEOP_ANTAGONIST "nukeop-antagonist" #define MADE_UNCLONEABLE "made-uncloneable" +#define TIMESTOP_TRAIT "timestop" #define NUKEOP_TRAIT "nuke-op" +#define MEGAFAUNA_TRAIT "megafauna" #define DEATHSQUAD_TRAIT "deathsquad" diff --git a/code/__DEFINES/typeids.dm b/code/__DEFINES/typeids.dm index 8bfe6216e2..275f7719f0 100644 --- a/code/__DEFINES/typeids.dm +++ b/code/__DEFINES/typeids.dm @@ -2,7 +2,7 @@ #define TYPEID_NULL "0" #define TYPEID_NORMAL_LIST "f" //helper macros -#define GET_TYPEID(ref) ( ( (length(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, length(ref)-6) ) ) +#define GET_TYPEID(ref) ( ( (length(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, -7) ) ) #define IS_NORMAL_LIST(L) (GET_TYPEID("\ref[L]") == TYPEID_NORMAL_LIST) diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 0aa9476fad..db8f4a1d0d 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -165,10 +165,21 @@ /proc/log_mapping(text) WRITE_LOG(GLOB.world_map_error_log, text) +/proc/log_reagent(text) + WRITE_LOG(GLOB.reagent_log, text) + +/proc/log_reagent_transfer(text) + log_reagent("TRANSFER: [text]") + /* For logging round startup. */ /proc/start_log(log) WRITE_LOG(log, "Starting up round ID [GLOB.round_id].\n-------------------------") +/* ui logging */ + +/proc/log_tgui(text) + WRITE_LOG(GLOB.tgui_log, text) + /* Close open log handles. This should be called as late as possible, and no logging should hapen after. */ /proc/shutdown_logging() rustg_log_close_all() diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm index 4b52187e13..d7378abfa6 100644 --- a/code/__HELPERS/areas.dm +++ b/code/__HELPERS/areas.dm @@ -1,5 +1,81 @@ #define BP_MAX_ROOM_SIZE 300 +//Repopulates sortedAreas list +/proc/repopulate_sorted_areas() + GLOB.sortedAreas = list() + + for(var/area/A in world) + GLOB.sortedAreas.Add(A) + + sortTim(GLOB.sortedAreas, /proc/cmp_name_asc) + +/area/proc/addSorted() + GLOB.sortedAreas.Add(src) + sortTim(GLOB.sortedAreas, /proc/cmp_name_asc) + +//Takes: Area type as a text string from a variable. +//Returns: Instance for the area in the world. +/proc/get_area_instance_from_text(areatext) + if(istext(areatext)) + areatext = text2path(areatext) + return GLOB.areas_by_type[areatext] + +//Takes: Area type as text string or as typepath OR an instance of the area. +//Returns: A list of all areas of that type in the world. +/proc/get_areas(areatype, subtypes=TRUE) + if(istext(areatype)) + areatype = text2path(areatype) + else if(isarea(areatype)) + var/area/areatemp = areatype + areatype = areatemp.type + else if(!ispath(areatype)) + return null + + var/list/areas = list() + if(subtypes) + var/list/cache = typecacheof(areatype) + for(var/V in GLOB.sortedAreas) + var/area/A = V + if(cache[A.type]) + areas += V + else + for(var/V in GLOB.sortedAreas) + var/area/A = V + if(A.type == areatype) + areas += V + return areas + +//Takes: Area type as text string or as typepath OR an instance of the area. +//Returns: A list of all turfs in areas of that type of that type in the world. +/proc/get_area_turfs(areatype, target_z = 0, subtypes=FALSE) + if(istext(areatype)) + areatype = text2path(areatype) + else if(isarea(areatype)) + var/area/areatemp = areatype + areatype = areatemp.type + else if(!ispath(areatype)) + return null + + var/list/turfs = list() + if(subtypes) + var/list/cache = typecacheof(areatype) + for(var/V in GLOB.sortedAreas) + var/area/A = V + if(!cache[A.type]) + continue + for(var/turf/T in A) + if(target_z == 0 || target_z == T.z) + turfs += T + else + for(var/V in GLOB.sortedAreas) + var/area/A = V + if(A.type != areatype) + continue + for(var/turf/T in A) + if(target_z == 0 || target_z == T.z) + turfs += T + return turfs + // Gets an atmos isolated contained space // Returns an associative list of turf|dirs pairs // The dirs are connected turfs in the same space @@ -103,4 +179,62 @@ to_chat(creator, "You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered.") return TRUE + +/** + * Returns the base area the target is located in if there is one. + * Alternatively, returns the area as is. + */ +/proc/get_base_area(atom/target) + var/area/A = get_area(target) + if(A?.base_area) + return A.base_area + return A + +/** + * Returns either null, or a list containing every sub area associated with our base area. + * If include_base is TRUE, the base area will also be added to the return list. + */ +/proc/get_sub_areas(atom/target, include_base = TRUE) + var/area/A = get_area(target) + if(!A) + return + . = list() + if(A.base_area) + A = A.base_area + if(include_base) + . += A + if(A.sub_areas) + . += A.sub_areas + +/** + * Proc used for purposes similar to get_areas_turfs(), but aimed to include associated areas. + * Only accepts area instances and paths for the first arg, no text strings. + * Returns a list of all turfs found in the sub areas (including the base's if include_base is TRUE) + * and located in a z level matching target_z, or anywhere if target_z is 0 + */ + +/proc/get_sub_areas_turfs(area/A, target_z = 0, include_base = TRUE) + var/list/contents = get_sub_areas_contents(A, include_base) + . = list() + for(var/turf/T in contents) + if(target_z == 0 || target_z == T.z) + . += T +/** + * Simple proc that returns a sum of all contents from every sub area, + * Think of the above but for all contents, not just turfs, and without target z. + */ + +/proc/get_sub_areas_contents(area/A, include_base = TRUE) + if(ispath(A)) + A = GLOB.areas_by_type[A] + else + A = get_area(A) //in case it's called on other atoms. + if(!A) + return + if(A.base_area) + A = A.base_area + . = list(A.contents) + for(var/i in A.sub_areas) + . += A.sub_areas[i].contents + #undef BP_MAX_ROOM_SIZE diff --git a/code/__HELPERS/files.dm b/code/__HELPERS/files.dm index 4160c1976a..7c6c186bca 100644 --- a/code/__HELPERS/files.dm +++ b/code/__HELPERS/files.dm @@ -20,7 +20,7 @@ continue path += choice - if(copytext(path,-1,0) != "/") //didn't choose a directory, no need to iterate again + if(copytext_char(path, -1) != "/") //didn't choose a directory, no need to iterate again break var/extensions for(var/i in valid_extensions) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index ca4b913369..605f7f8ae7 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -8,8 +8,8 @@ #define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL)) #define CULT_POLL_WAIT 2400 -/proc/get_area_name(atom/X, format_text = FALSE) - var/area/A = isarea(X) ? X : get_area(X) +/proc/get_area_name(atom/X, format_text = FALSE, get_base_area = FALSE) + var/area/A = get_base_area ? get_base_area(X) : get_area(X) if(!A) return null return format_text ? format_text(A.name) : A.name @@ -145,20 +145,6 @@ turfs += T return turfs - -//This is the new version of recursive_mob_check, used for say(). -//The other proc was left intact because morgue trays use it. -//Sped this up again for real this time -/proc/recursive_hear_check(O) - var/list/processing_list = list(O) - . = list() - while(processing_list.len) - var/atom/A = processing_list[1] - if(A.flags_1 & HEAR_1) - . += A - processing_list.Cut(1, 2) - processing_list += A.contents - /** recursive_organ_check * inputs: O (object to start with) * outputs: @@ -238,35 +224,30 @@ return found_mobs - /proc/get_hearers_in_view(R, atom/source) - // Returns a list of hearers in view(R) from source (ignoring luminosity). Used in saycode. var/turf/T = get_turf(source) . = list() - if(!T) return - - var/list/processing_list = list() - if (R == 0) // if the range is zero, we know exactly where to look for, we can skip view - processing_list += T.contents // We can shave off one iteration by assuming turfs cannot hear - else // A variation of get_hear inlined here to take advantage of the compiler's fastpath for obj/mob in view + var/list/processing = list() + if(R == 0) + processing += T.contents + else var/lum = T.luminosity - T.luminosity = 6 // This is the maximum luminosity - var/list/cachedview = view(R, T) - for(var/mob/M in cachedview) - processing_list += M - for(var/obj/O in cachedview) - processing_list += O + T.luminosity = 6 + var/list/cached_view = view(R, T) + for(var/mob/M in cached_view) + processing += M + for(var/obj/O in cached_view) + processing += O T.luminosity = lum - - while(processing_list.len) // recursive_hear_check inlined here - var/atom/A = processing_list[1] + var/i = 0 + while(i < length(processing)) + var/atom/A = processing[++i] if(A.flags_1 & HEAR_1) . += A - SEND_SIGNAL(A, COMSIG_ATOM_HEARER_IN_VIEW, processing_list, .) - processing_list.Cut(1, 2) - processing_list += A.contents + SEND_SIGNAL(A, COMSIG_ATOM_HEARER_IN_VIEW, processing, .) + processing += A.contents /proc/get_mobs_in_radio_ranges(list/obj/item/radio/radios) . = list() diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 8e88f869a9..aee0f3d7f7 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -985,7 +985,7 @@ world var/icon/atom_icon = new(A.icon, A.icon_state) if(!letter) - letter = copytext(A.name, 1, 2) + letter = A.name[1] if(uppercase == 1) letter = uppertext(letter) else if(uppercase == -1) @@ -1113,7 +1113,7 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0 WRITE_FILE(GLOB.iconCache[iconKey], icon) var/iconData = GLOB.iconCache.ExportText(iconKey) var/list/partial = splittext(iconData, "{") - return replacetext(copytext(partial[2], 3, -5), "\n", "") + return replacetext(copytext_char(partial[2], 3, -5), "\n", "") /proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE) if (!thing) diff --git a/code/__HELPERS/pronouns.dm b/code/__HELPERS/pronouns.dm index d1add9cb4c..bab286bafe 100644 --- a/code/__HELPERS/pronouns.dm +++ b/code/__HELPERS/pronouns.dm @@ -28,10 +28,10 @@ . = "does" /datum/proc/p_theyve(capitalized, temp_gender) - . = p_they(capitalized, temp_gender) + "'" + copytext(p_have(temp_gender), 3) + . = p_they(capitalized, temp_gender) + "'" + copytext_char(p_have(temp_gender), 3) /datum/proc/p_theyre(capitalized, temp_gender) - . = p_they(capitalized, temp_gender) + "'" + copytext(p_are(temp_gender), 2) + . = p_they(capitalized, temp_gender) + "'" + copytext_char(p_are(temp_gender), 2) /datum/proc/p_s(temp_gender) //is this a descriptive proc name, or what? . = "s" diff --git a/code/__HELPERS/radio.dm b/code/__HELPERS/radio.dm index 7ab21d0402..5fe87bdf5b 100644 --- a/code/__HELPERS/radio.dm +++ b/code/__HELPERS/radio.dm @@ -1,6 +1,6 @@ // Ensure the frequency is within bounds of what it should be sending/receiving at /proc/sanitize_frequency(frequency, free = FALSE) - . = round(frequency) + frequency = round(frequency) if(free) . = CLAMP(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ) else diff --git a/code/__HELPERS/reagents.dm b/code/__HELPERS/reagents.dm index f1208abdd3..50c866b30b 100644 --- a/code/__HELPERS/reagents.dm +++ b/code/__HELPERS/reagents.dm @@ -72,3 +72,26 @@ if(!GLOB.chemical_reactions_list[primary_reagent]) GLOB.chemical_reactions_list[primary_reagent] = list() GLOB.chemical_reactions_list[primary_reagent] += R + +/proc/choose_reagent_id(mob/user) + var/chosen_id + switch(alert(user, "Choose a method.", "Add Reagents", "Search", "Choose from a list", "I'm feeling lucky")) + if("Search") + var/valid_id + while(!valid_id) + chosen_id = input(user, "Enter the ID of the reagent you want to add.", "Search reagents") as null|text + if(isnull(chosen_id)) //Get me out of here! + break + if(!ispath(text2path(chosen_id))) + chosen_id = pick_closest_path(chosen_id, make_types_fancy(subtypesof(/datum/reagent))) + if(ispath(chosen_id)) + valid_id = TRUE + else + valid_id = TRUE + if(!valid_id) + to_chat(user, "A reagent with that ID doesn't exist!") + if("Choose from a list") + chosen_id = input(user, "Choose a reagent to add.", "Choose a reagent.") as null|anything in subtypesof(/datum/reagent) + if("I'm feeling lucky") + chosen_id = pick(subtypesof(/datum/reagent)) + return chosen_id \ No newline at end of file diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 535f1154e7..04e7ffd721 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -185,7 +185,7 @@ if(!C.credits) C.RollCredits() C.playtitlemusic(40) - + CONFIG_SET(flag/suicide_allowed,TRUE) // EORG suicides allowed var/popcount = gather_roundend_feedback() display_report(popcount) diff --git a/code/__HELPERS/sanitize_values.dm b/code/__HELPERS/sanitize_values.dm index b511c61971..601ed966bf 100644 --- a/code/__HELPERS/sanitize_values.dm +++ b/code/__HELPERS/sanitize_values.dm @@ -43,24 +43,24 @@ if(!istext(color)) color = "" - var/start = 1 + (text2ascii(color,1)==35) + var/start = 1 + (text2ascii(color, 1) == 35) var/len = length(color) - var/step_size = 1 + ((len+1)-start != desired_format) + var/char = "" . = "" - for(var/i=start, i<=len, i+=step_size) - var/ascii = text2ascii(color,i) - switch(ascii) - if(48 to 57) - . += ascii2text(ascii) //numbers 0 to 9 - if(97 to 102) - . += ascii2text(ascii) //letters a to f - if(65 to 70) - . += ascii2text(ascii+32) //letters A to F - translates to lowercase + for(var/i = start, i <= len, i += length(char)) + char = color[i] + switch(text2ascii(char)) + if(48 to 57) //numbers 0 to 9 + . += char + if(97 to 102) //letters a to f + . += char + if(65 to 70) //letters A to F - translates to lowercase + . += lowertext(char) else break - if(length(.) != desired_format) + if(length_char(.) != desired_format) if(default) return default return crunch + repeat_string(desired_format, "0") @@ -68,7 +68,9 @@ return crunch + . /proc/sanitize_ooccolor(color) - var/list/HSL = rgb2hsl(hex2num(copytext(color,2,4)),hex2num(copytext(color,4,6)),hex2num(copytext(color,6,8))) + if(length(color) != length_char(color)) + CRASH("Invalid characters in color '[color]'") + var/list/HSL = rgb2hsl(hex2num(copytext(color, 2, 4)), hex2num(copytext(color, 4, 6)), hex2num(copytext(color, 6, 8))) HSL[3] = min(HSL[3],0.4) var/list/RGB = hsl2rgb(arglist(HSL)) return "#[num2hex(RGB[1],2)][num2hex(RGB[2],2)][num2hex(RGB[3],2)]" \ No newline at end of file diff --git a/code/__HELPERS/shell.dm b/code/__HELPERS/shell.dm index 8b615eac0a..3438f38b85 100644 --- a/code/__HELPERS/shell.dm +++ b/code/__HELPERS/shell.dm @@ -52,6 +52,6 @@ if(bad_chars) bad_match = url_encode(bad_chars_regex.match) scrubbed_url += bad_match - last_good = bad_chars + length(bad_match) + last_good = bad_chars + length(bad_chars_regex.match) while(bad_chars) . = scrubbed_url diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 60c43b0869..3985659b71 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -40,8 +40,8 @@ for(var/char in repl_chars) var/index = findtext(t, char) while(index) - t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index+1) - index = findtext(t, char, index+1) + 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) @@ -63,22 +63,28 @@ //Returns null if there is any bad text in the string -/proc/reject_bad_text(text, max_length=512) - if(length(text) > max_length) - return //message too long - var/non_whitespace = 0 - for(var/i=1, i<=length(text), i++) - switch(text2ascii(text,i)) - if(62,60,92,47) - return //rejects the text if it contains these bad characters: <, >, \ or / - if(127 to 255) - return //rejects weird letters like � +/proc/reject_bad_text(text, max_length = 512, ascii_only = TRUE) + var/char_count = 0 + var/non_whitespace = FALSE + var/lenbytes = length(text) + var/char = "" + for(var/i = 1, i <= lenbytes, i += length(char)) + char = text[i] + char_count++ + if(char_count > max_length) + return + switch(text2ascii(char)) + if(62,60,92,47) // <, >, \, / + return if(0 to 31) - return //more weird stuff + return if(32) continue //whitespace + if(127 to INFINITY) + if(ascii_only) + return else - non_whitespace = 1 + non_whitespace = TRUE if(non_whitespace) return text //only accepts the text if it has some non-spaces @@ -101,73 +107,84 @@ else return trim(html_encode(name), max_length) +#define NO_CHARS_DETECTED 0 +#define SPACES_DETECTED 1 +#define SYMBOLS_DETECTED 2 +#define NUMBERS_DETECTED 3 +#define LETTERS_DETECTED 4 + //Filters out undesirable characters from names -/proc/reject_bad_name(t_in, allow_numbers=0, max_length=MAX_NAME_LEN) - if(!t_in || length(t_in) > max_length) - return //Rejects the input if it is null or if it is longer then the max length allowed +/proc/reject_bad_name(t_in, allow_numbers = FALSE, max_length = MAX_NAME_LEN, ascii_only = TRUE) + if(!t_in) + return //Rejects the input if it is null - var/number_of_alphanumeric = 0 - var/last_char_group = 0 + var/number_of_alphanumeric = 0 + var/last_char_group = NO_CHARS_DETECTED var/t_out = "" + var/t_len = length(t_in) + var/charcount = 0 + var/char = "" - for(var/i=1, i<=length(t_in), i++) - var/ascii_char = text2ascii(t_in,i) - switch(ascii_char) + + for(var/i = 1, i <= t_len, i += length(char)) + char = t_in[i] + + switch(text2ascii(char)) // A .. Z if(65 to 90) //Uppercase Letters - t_out += ascii2text(ascii_char) number_of_alphanumeric++ - last_char_group = 4 + last_char_group = LETTERS_DETECTED // a .. z if(97 to 122) //Lowercase Letters - if(last_char_group<2) - t_out += ascii2text(ascii_char-32) //Force uppercase first character - else - t_out += ascii2text(ascii_char) + if(last_char_group == NO_CHARS_DETECTED || last_char_group == SPACES_DETECTED || last_char_group == SYMBOLS_DETECTED) //start of a word + char = uppertext(char) number_of_alphanumeric++ - last_char_group = 4 + last_char_group = LETTERS_DETECTED // 0 .. 9 if(48 to 57) //Numbers - if(!last_char_group) - continue //suppress at start of string - if(!allow_numbers) + if(last_char_group == NO_CHARS_DETECTED || !allow_numbers) //suppress at start of string continue - t_out += ascii2text(ascii_char) number_of_alphanumeric++ - last_char_group = 3 + last_char_group = NUMBERS_DETECTED // ' - . if(39,45,46) //Common name punctuation - if(!last_char_group) + if(last_char_group == NO_CHARS_DETECTED) continue - t_out += ascii2text(ascii_char) - last_char_group = 2 + last_char_group = SYMBOLS_DETECTED // ~ | @ : # $ % & * + if(126,124,64,58,35,36,37,38,42,43) //Other symbols that we'll allow (mainly for AI) - if(!last_char_group) - continue //suppress at start of string - if(!allow_numbers) + if(last_char_group == NO_CHARS_DETECTED || !allow_numbers) //suppress at start of string continue - t_out += ascii2text(ascii_char) - last_char_group = 2 + last_char_group = SYMBOLS_DETECTED //Space if(32) - if(last_char_group <= 1) - continue //suppress double-spaces and spaces at start of string - t_out += ascii2text(ascii_char) - last_char_group = 1 + if(last_char_group == NO_CHARS_DETECTED || last_char_group == SPACES_DETECTED) //suppress double-spaces and spaces at start of string + continue + last_char_group = SPACES_DETECTED + + if(127 to INFINITY) + if(ascii_only) + continue + last_char_group = SYMBOLS_DETECTED //for now, we'll treat all non-ascii characters like symbols even though most are letters + else - return + continue + + t_out += char + charcount++ + if(charcount >= max_length) + break if(number_of_alphanumeric < 2) return //protects against tiny names like "A" and also names like "' ' ' ' ' ' ' '" - if(last_char_group == 1) - t_out = copytext(t_out,1,length(t_out)) //removes the last character (in this case a space) + if(last_char_group == SPACES_DETECTED) + t_out = copytext_char(t_out, 1, -1) //removes the last character (in this case a space) for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai")) //prevents these common metagamey names if(cmptext(t_out,bad_name)) @@ -175,6 +192,11 @@ return t_out +#undef NO_CHARS_DETECTED +#undef SPACES_DETECTED +#undef NUMBERS_DETECTED +#undef LETTERS_DETECTED + //html_encode helper proc that returns the smallest non null of two numbers //or 0 if they're both null (needed because of findtext returning 0 when a value is not present) /proc/non_zero_min(a, b) @@ -184,39 +206,6 @@ return a return (a < b ? a : b) -/* - * Text searches - */ - -//Checks the beginning of a string for a specified sub-string -//Returns the position of the substring or 0 if it was not found -/proc/dd_hasprefix(text, prefix) - var/start = 1 - var/end = length(prefix) + 1 - return findtext(text, prefix, start, end) - -//Checks the beginning of a string for a specified sub-string. This proc is case sensitive -//Returns the position of the substring or 0 if it was not found -/proc/dd_hasprefix_case(text, prefix) - var/start = 1 - var/end = length(prefix) + 1 - return findtextEx(text, prefix, start, end) - -//Checks the end of a string for a specified substring. -//Returns the position of the substring or 0 if it was not found -/proc/dd_hassuffix(text, suffix) - var/start = length(text) - length(suffix) - if(start) - return findtext(text, suffix, start, null) - return - -//Checks the end of a string for a specified substring. This proc is case sensitive -//Returns the position of the substring or 0 if it was not found -/proc/dd_hassuffix_case(text, suffix) - var/start = length(text) - length(suffix) - if(start) - return findtextEx(text, suffix, start, null) - //Checks if any of a given list of needles is in the haystack /proc/text_in_list(haystack, list/needle_list, start=1, end=0) for(var/needle in needle_list) @@ -231,23 +220,19 @@ return 1 return 0 -//Adds 'u' number of zeros ahead of the text 't' -/proc/add_zero(t, u) - while (length(t) < u) - t = "0[t]" - return t +//Adds 'char' ahead of 'text' until there are 'count' characters total +/proc/add_leading(text, count, char = " ") + text = "[text]" + var/charcount = count - length_char(text) + var/list/chars_to_add[max(charcount + 1, 0)] + return jointext(chars_to_add, char) + text -//Adds 'u' number of spaces ahead of the text 't' -/proc/add_lspace(t, u) - while(length(t) < u) - t = " [t]" - return t - -//Adds 'u' number of spaces behind the text 't' -/proc/add_tspace(t, u) - while(length(t) < u) - t = "[t] " - return t +//Adds 'char' behind 'text' until there are 'count' characters total +/proc/add_trailing(text, count, char = " ") + text = "[text]" + var/charcount = count - length_char(text) + var/list/chars_to_add[max(charcount + 1, 0)] + return text + jointext(chars_to_add, char) //Returns a string with reserved characters and spaces before the first letter removed /proc/trim_left(text) @@ -267,57 +252,41 @@ //Returns a string with reserved characters and spaces before the first word and after the last word removed. /proc/trim(text, max_length) if(max_length) - text = copytext(text, 1, max_length) + text = copytext_char(text, 1, max_length) return trim_left(trim_right(text)) //Returns a string with the first element of the string capitalized. /proc/capitalize(t as text) - return uppertext(copytext(t, 1, 2)) + copytext(t, 2) - -//Centers text by adding spaces to either side of the string. -/proc/dd_centertext(message, length) - var/new_message = message - var/size = length(message) - var/delta = length - size - if(size == length) - return new_message - if(size > length) - return copytext(new_message, 1, length + 1) - if(delta == 1) - return new_message + " " - if(delta % 2) - new_message = " " + new_message - delta-- - var/spaces = add_lspace("",delta/2-1) - return spaces + new_message + spaces - -//Limits the length of the text. Note: MAX_MESSAGE_LEN and MAX_NAME_LEN are widely used for this purpose -/proc/dd_limittext(message, length) - var/size = length(message) - if(size <= length) - return message - return copytext(message, 1, length + 1) - + . = t + if(t) + . = t[1] + return uppertext(.) + copytext(t, 1 + length(.)) /proc/stringmerge(text,compare,replace = "*") //This proc fills in all spaces with the "replace" var (* by default) with whatever //is in the other string at the same spot (assuming it is not a replace char). //This is used for fingerprints var/newtext = text - if(length(text) != length(compare)) - return 0 - for(var/i = 1, i < length(text), i++) - var/a = copytext(text,i,i+1) - var/b = copytext(compare,i,i+1) + var/text_it = 1 //iterators + var/comp_it = 1 + var/newtext_it = 1 + var/text_length = length(text) + var/comp_length = length(compare) + while(comp_it <= comp_length && text_it <= text_length) + var/a = text[text_it] + var/b = compare[comp_it] //if it isn't both the same letter, or if they are both the replacement character //(no way to know what it was supposed to be) if(a != b) if(a == replace) //if A is the replacement char - newtext = copytext(newtext,1,i) + b + copytext(newtext, i+1) + newtext = copytext(newtext, 1, newtext_it) + b + copytext(newtext, newtext_it + length(newtext[newtext_it])) else if(b == replace) //if B is the replacement char - newtext = copytext(newtext,1,i) + a + copytext(newtext, i+1) + newtext = copytext(newtext, 1, newtext_it) + a + copytext(newtext, newtext_it + length(newtext[newtext_it])) else //The lists disagree, Uh-oh! return 0 + text_it += length(a) + comp_it += length(b) + newtext_it += length(newtext[newtext_it]) return newtext /proc/stringpercent(text,character = "*") @@ -326,16 +295,21 @@ if(!text || !character) return 0 var/count = 0 - for(var/i = 1, i <= length(text), i++) - var/a = copytext(text,i,i+1) + var/lentext = length(text) + var/a = "" + for(var/i = 1, i <= lentext, i += length(a)) + a = text[i] if(a == character) count++ return count /proc/reverse_text(text = "") var/new_text = "" - for(var/i = length(text); i > 0; i--) - new_text += copytext(text, i, i+1) + var/lentext = length(text) + var/letter = "" + for(var/i = 1, i <= lentext, i += length(letter)) + letter = text[i] + new_text = letter + new_text return new_text GLOBAL_LIST_INIT(zero_character_only, list("0")) @@ -358,15 +332,6 @@ GLOBAL_LIST_INIT(binary, list("0","1")) /proc/random_color() return random_string(6, GLOB.hex_characters) -/proc/add_zero2(t, u) - var/temp1 - while (length(t) < u) - t = "0[t]" - temp1 = t - if (length(t) > u) - temp1 = copytext(t,2,u+1) - return temp1 - //merges non-null characters (3rd argument) from "from" into "into". Returns result //e.g. into = "Hello World" // from = "Seeya______" @@ -379,41 +344,48 @@ GLOBAL_LIST_INIT(binary, list("0","1")) into = "" if(!istext(from)) from = "" - var/null_ascii = istext(null_char) ? text2ascii(null_char,1) : null_char - - var/previous = 0 + var/null_ascii = istext(null_char) ? text2ascii(null_char, 1) : null_char + var/copying_into = FALSE + var/char = "" var/start = 1 - var/end = length(into) + 1 - - for(var/i=1, i= text2ascii("a") && ca <= text2ascii("m")) - ca += 13 - else if(ca >= text2ascii("n") && ca <= text2ascii("z")) - ca -= 13 - else if(ca >= text2ascii("A") && ca <= text2ascii("M")) - ca += 13 - else if(ca >= text2ascii("N") && ca <= text2ascii("Z")) - ca -= 13 - result += ascii2text(ca) - return jointext(result, "") + var/lentext = length(text) + var/char = "" + var/ascii = 0 + . = "" + for(var/i = 1, i <= lentext, i += length(char)) + char = text[i] + ascii = text2ascii(char) + switch(ascii) + if(65 to 77, 97 to 109) //A to M, a to m + ascii += 13 + if(78 to 90, 110 to 122) //N to Z, n to z + ascii -= 13 + . += ascii2text(ascii) //Takes a list of values, sanitizes it down for readability and character count, //then exports it as a json file at data/npc_saves/[filename].json. @@ -599,7 +576,8 @@ GLOBAL_LIST_INIT(binary, list("0","1")) return //Regular expressions are, as usual, absolute magic - var/regex/all_invalid_symbols = new("\[^ -~]+") + //Any characters outside of 32 (space) to 126 (~) because treating things you don't understand as "magic" is really stupid + var/regex/all_invalid_symbols = new(@"[^ -~]{1}") var/list/accepted = list() for(var/string in proposed) @@ -607,34 +585,44 @@ GLOBAL_LIST_INIT(binary, list("0","1")) continue var/buffer = "" var/early_culling = TRUE - for(var/pos = 1, pos <= length(string), pos++) - var/let = copytext(string, pos, (pos + 1) % length(string)) - if(early_culling && !findtext(let,GLOB.is_alphanumeric)) + var/lentext = length(string) + var/let = "" + + for(var/pos = 1, pos <= lentext, pos += length(let)) + let = string[pos] + if(!findtext(let, GLOB.is_alphanumeric)) continue early_culling = FALSE - buffer += let - if(!findtext(buffer,GLOB.is_alphanumeric)) + buffer = copytext(string, pos) + break + if(early_culling) //Never found any letters! Bail! continue + var/punctbuffer = "" - var/cutoff = length(buffer) - for(var/pos = length(buffer), pos >= 0, pos--) - var/let = copytext(buffer, pos, (pos + 1) % length(buffer)) - if(findtext(let,GLOB.is_alphanumeric)) + var/cutoff = 0 + lentext = length_char(buffer) + for(var/pos = 1, pos <= lentext, pos++) + let = copytext_char(buffer, -pos, -pos + 1) + if(!findtext(let, GLOB.is_punctuation)) //This won't handle things like Nyaaaa!~ but that's fine break - if(findtext(let,GLOB.is_punctuation)) - punctbuffer = let + punctbuffer //Note this isn't the same thing as using += - cutoff = pos + punctbuffer += let + cutoff += length(let) if(punctbuffer) //We clip down excessive punctuation to get the letter count lower and reduce repeats. It's not perfect but it helps. var/exclaim = FALSE var/question = FALSE var/periods = 0 - for(var/pos = length(punctbuffer), pos >= 0, pos--) - var/punct = copytext(punctbuffer, pos, (pos + 1) % length(punctbuffer)) - if(!exclaim && findtext(punct,"!")) + lentext = length(punctbuffer) + for(var/pos = 1, pos <= lentext, pos += length(let)) + let = punctbuffer[pos] + if(!exclaim && findtext(let, "!")) exclaim = TRUE - if(!question && findtext(punct,"?")) + if(question) + break + if(!question && findtext(let, "?")) question = TRUE - if(!exclaim && !question && findtext(punct,".")) + if(exclaim) + break + if(!exclaim && !question && findtext(let, ".")) //? and ! take priority over periods periods += 1 if(exclaim) if(question) @@ -643,15 +631,13 @@ GLOBAL_LIST_INIT(binary, list("0","1")) punctbuffer = "!" else if(question) punctbuffer = "?" - else if(periods) - if(periods > 1) - punctbuffer = "..." - else - punctbuffer = "" //Grammer nazis be damned - buffer = copytext(buffer, 1, cutoff) + punctbuffer - if(!findtext(buffer,GLOB.is_alphanumeric)) - continue - if(!buffer || length(buffer) > 280 || length(buffer) <= cullshort || buffer in accepted) + else if(periods > 1) + punctbuffer = "..." + else + punctbuffer = "" //Grammer nazis be damned + buffer = copytext(buffer, 1, -cutoff) + punctbuffer + lentext = length_char(buffer) + if(!buffer || lentext > 280 || lentext <= cullshort || (buffer in accepted)) continue accepted += buffer @@ -688,7 +674,7 @@ GLOBAL_LIST_INIT(binary, list("0","1")) var/leng = length(string) - var/next_space = findtext(string, " ", next_backslash + 1) + var/next_space = findtext(string, " ", next_backslash + length(string[next_backslash])) if(!next_space) next_space = leng - next_backslash @@ -696,8 +682,8 @@ GLOBAL_LIST_INIT(binary, list("0","1")) return string var/base = next_backslash == 1 ? "" : copytext(string, 1, next_backslash) - var/macro = lowertext(copytext(string, next_backslash + 1, next_space)) - var/rest = next_backslash > leng ? "" : copytext(string, next_space + 1) + var/macro = lowertext(copytext(string, next_backslash + length(string[next_space]), next_space)) + var/rest = next_backslash > leng ? "" : copytext(string, next_space + length(string[next_space])) //See https://secure.byond.com/docs/ref/info.html#/DM/text/macros switch(macro) @@ -769,28 +755,24 @@ GLOBAL_LIST_INIT(binary, list("0","1")) return "[number]\th" /proc/unintelligize(message) - var/prefix=copytext(message,1,2) + var/regex/word_boundaries = regex(@"\b[\S]+\b", "g") + var/prefix = message[1] if(prefix == ";") - message = copytext(message,2) - else if(prefix in list(":","#")) - prefix += copytext(message,2,3) - message = copytext(message,3) + message = copytext(message, 1 + length(prefix)) + else if(prefix in list(":", "#")) + prefix += message[1 + length(prefix)] + message = copytext(message, length(prefix)) else - prefix="" + prefix = "" - var/list/words = splittext(message," ") var/list/rearranged = list() - for(var/i=1;i<=words.len;i++) - var/cword = pick(words) - words.Remove(cword) - var/suffix = copytext(cword,length(cword)-1,length(cword)) - while(length(cword)>0 && suffix in list(".",",",";","!",":","?")) - cword = copytext(cword,1 ,length(cword)-1) - suffix = copytext(cword,length(cword)-1,length(cword) ) + while(word_boundaries.Find(message)) + var/cword = word_boundaries.match if(length(cword)) rearranged += cword - message = "[prefix][jointext(rearranged," ")]" - . = message + shuffle_inplace(rearranged) + return "[prefix][jointext(rearranged, " ")]" + #define is_alpha(X) ((text2ascii(X) <= 122) && (text2ascii(X) >= 97)) #define is_digit(X) ((length(X) == 1) && (length(text2num(X)) == 1)) \ No newline at end of file diff --git a/code/__HELPERS/text_vr.dm b/code/__HELPERS/text_vr.dm index 9be806fc54..3c1e1eff12 100644 --- a/code/__HELPERS/text_vr.dm +++ b/code/__HELPERS/text_vr.dm @@ -8,14 +8,15 @@ index = findtext(t, char) return t -proc/TextPreview(var/string,var/len=40) - if(length(string) <= len) - if(!length(string)) +/proc/TextPreview(string, len = 40) + var/char_len = length_char(string) + if(char_len <= len) + if(char_len) return "\[...\]" else return string else - return "[copytext(string, 1, 37)]..." + return "[copytext_char(string, 1, 37)]..." GLOBAL_LIST_EMPTY(mentorlog) GLOBAL_PROTECT(mentorlog) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 823e893670..09047d32bf 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -542,17 +542,17 @@ //assumes format #RRGGBB #rrggbb /proc/color_hex2num(A) - if(!A) + if(!A || length(A) != length_char(A)) return 0 - var/R = hex2num(copytext(A,2,4)) - var/G = hex2num(copytext(A,4,6)) - var/B = hex2num(copytext(A,6,0)) + var/R = hex2num(copytext(A, 2, 4)) + var/G = hex2num(copytext(A, 4, 6)) + var/B = hex2num(copytext(A, 6, 0)) return R+G+B //word of warning: using a matrix like this as a color value will simplify it back to a string after being set /proc/color_hex2color_matrix(string) var/length = length(string) - if(length != 7 && length != 9) + if((length != 7 && length != 9) || length != length_char(string)) return color_matrix_identity() var/r = hex2num(copytext(string, 2, 4))/255 var/g = hex2num(copytext(string, 4, 6))/255 diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index e64ed8fd55..86dde3d6a6 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -6,25 +6,18 @@ //Inverts the colour of an HTML string /proc/invertHTML(HTMLstring) - - if (!( istext(HTMLstring) )) + if(!istext(HTMLstring)) CRASH("Given non-text argument!") return - else - if (length(HTMLstring) != 7) - CRASH("Given non-HTML argument!") - return + else if(length(HTMLstring) != 7) + CRASH("Given non-HTML argument!") + return + else if(length_char(HTMLstring) != 7) + CRASH("Given non-hex symbols in argument!") var/textr = copytext(HTMLstring, 2, 4) var/textg = copytext(HTMLstring, 4, 6) var/textb = copytext(HTMLstring, 6, 8) - var/r = hex2num(textr) - var/g = hex2num(textg) - var/b = hex2num(textb) - textr = num2hex(255 - r, 2) - textg = num2hex(255 - g, 2) - textb = num2hex(255 - b, 2) - return text("#[][][]", textr, textg, textb) - return + return rgb(255 - hex2num(textr), 255 - hex2num(textg), 255 - hex2num(textb)) /proc/Get_Angle(atom/movable/start,atom/movable/end)//For beams. if(!start || !end) @@ -184,15 +177,15 @@ Turf and target are separate in case you want to teleport some distance from a t //Returns whether or not a player is a guest using their ckey as an input /proc/IsGuestKey(key) if (findtext(key, "Guest-", 1, 7) != 1) //was findtextEx - return 0 + return FALSE var/i, ch, len = length(key) - for (i = 7, i <= len, ++i) + for (i = 7, i <= len, ++i) //we know the first 6 chars are Guest- ch = text2ascii(key, i) - if (ch < 48 || ch > 57) - return 0 - return 1 + if (ch < 48 || ch > 57) //0-9 + return FALSE + return TRUE //Generalised helper proc for letting mobs rename themselves. Used to be clname() and ainame() /mob/proc/apply_pref_name(role, client/C) @@ -457,36 +450,35 @@ Turf and target are separate in case you want to teleport some distance from a t /atom/proc/GetAllContents(var/T) var/list/processing_list = list(src) - var/list/assembled = list() if(T) - while(processing_list.len) - var/atom/A = processing_list[1] - processing_list.Cut(1, 2) + . = list() + var/i = 0 + while(i < length(processing_list)) + var/atom/A = processing_list[++i] //Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed //This is also why we don't need to check against assembled as we go along processing_list += A.contents if(istype(A,T)) - assembled += A + . += A else - while(processing_list.len) - var/atom/A = processing_list[1] - processing_list.Cut(1, 2) + var/i = 0 + while(i < length(processing_list)) + var/atom/A = processing_list[++i] processing_list += A.contents - assembled += A - return assembled + return processing_list /atom/proc/GetAllContentsIgnoring(list/ignore_typecache) if(!length(ignore_typecache)) return GetAllContents() var/list/processing = list(src) - var/list/assembled = list() - while(processing.len) - var/atom/A = processing[1] - processing.Cut(1,2) + . = list() + var/i = 0 + while(i < length(processing)) + var/atom/A = processing[++i] if(!ignore_typecache[A.type]) processing += A.contents - assembled += A - return assembled + . += A + //Step-towards method of determining whether one atom can see another. Similar to viewers() /proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate. @@ -566,82 +558,6 @@ Turf and target are separate in case you want to teleport some distance from a t else return 0 -//Repopulates sortedAreas list -/proc/repopulate_sorted_areas() - GLOB.sortedAreas = list() - - for(var/area/A in world) - GLOB.sortedAreas.Add(A) - - sortTim(GLOB.sortedAreas, /proc/cmp_name_asc) - -/area/proc/addSorted() - GLOB.sortedAreas.Add(src) - sortTim(GLOB.sortedAreas, /proc/cmp_name_asc) - -//Takes: Area type as a text string from a variable. -//Returns: Instance for the area in the world. -/proc/get_area_instance_from_text(areatext) - if(istext(areatext)) - areatext = text2path(areatext) - return GLOB.areas_by_type[areatext] - -//Takes: Area type as text string or as typepath OR an instance of the area. -//Returns: A list of all areas of that type in the world. -/proc/get_areas(areatype, subtypes=TRUE) - if(istext(areatype)) - areatype = text2path(areatype) - else if(isarea(areatype)) - var/area/areatemp = areatype - areatype = areatemp.type - else if(!ispath(areatype)) - return null - - var/list/areas = list() - if(subtypes) - var/list/cache = typecacheof(areatype) - for(var/V in GLOB.sortedAreas) - var/area/A = V - if(cache[A.type]) - areas += V - else - for(var/V in GLOB.sortedAreas) - var/area/A = V - if(A.type == areatype) - areas += V - return areas - -//Takes: Area type as text string or as typepath OR an instance of the area. -//Returns: A list of all turfs in areas of that type of that type in the world. -/proc/get_area_turfs(areatype, target_z = 0, subtypes=FALSE) - if(istext(areatype)) - areatype = text2path(areatype) - else if(isarea(areatype)) - var/area/areatemp = areatype - areatype = areatemp.type - else if(!ispath(areatype)) - return null - - var/list/turfs = list() - if(subtypes) - var/list/cache = typecacheof(areatype) - for(var/V in GLOB.sortedAreas) - var/area/A = V - if(!cache[A.type]) - continue - for(var/turf/T in A) - if(target_z == 0 || target_z == T.z) - turfs += T - else - for(var/V in GLOB.sortedAreas) - var/area/A = V - if(A.type != areatype) - continue - for(var/turf/T in A) - if(target_z == 0 || target_z == T.z) - turfs += T - return turfs - /proc/get_cardinal_dir(atom/A, atom/B) var/dx = abs(B.x - A.x) var/dy = abs(B.y - A.y) @@ -1276,7 +1192,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) invisibility = 101 density = FALSE see_in_dark = 1e6 - anchored = TRUE + move_resist = INFINITY var/ready_to_die = FALSE /mob/dview/Initialize() //Properly prevents this mob from gaining huds or joining any global lists @@ -1391,7 +1307,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) /proc/GUID() var/const/GUID_VERSION = "b" var/const/GUID_VARIANT = "d" - var/node_id = copytext(md5("[rand()*rand(1,9999999)][world.name][world.hub][world.hub_password][world.internet_address][world.address][world.contents.len][world.status][world.port][rand()*rand(1,9999999)]"), 1, 13) + var/node_id = copytext_char(md5("[rand()*rand(1,9999999)][world.name][world.hub][world.hub_password][world.internet_address][world.address][world.contents.len][world.status][world.port][rand()*rand(1,9999999)]"), 1, 13) var/time_high = "[num2hex(text2num(time2text(world.realtime,"YYYY")), 2)][num2hex(world.realtime, 6)]" @@ -1578,3 +1494,47 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) return -1 else return 0 + +// Converts browser keycodes to BYOND keycodes. +/proc/browser_keycode_to_byond(keycode) + keycode = text2num(keycode) + switch(keycode) + // letters and numbers + if(65 to 90, 48 to 57) + return ascii2text(keycode) + if(17) + return "Ctrl" + if(18) + return "Alt" + if(16) + return "Shift" + if(37) + return "West" + if(38) + return "North" + if(39) + return "East" + if(40) + return "South" + if(45) + return "Insert" + if(46) + return "Delete" + if(36) + return "Northwest" + if(35) + return "Southwest" + if(33) + return "Northeast" + if(34) + return "Southeast" + if(112 to 123) + return "F[keycode-111]" + if(96 to 105) + return "Numpad[keycode-96]" + if(188) + return "," + if(190) + return "." + if(189) + return "-" \ No newline at end of file diff --git a/code/_compile_options.dm b/code/_compile_options.dm index af948086df..fe4761ddcd 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -39,6 +39,26 @@ #error You need version 512 or higher #endif +//Compatability -- These procs were added in 513.1493, not 513.1490 +//Which really shoulda bumped us up to 514 right then and there but instead Lummox is a dumb dumb +#if DM_BUILD < 1493 +#define length_char(args...) length(args) +#define text2ascii_char(args...) text2ascii(args) +#define copytext_char(args...) copytext(args) +#define splittext_char(args...) splittext(args) +#define spantext_char(args...) spantext(args) +#define nonspantext_char(args...) nonspantext(args) +#define findtext_char(args...) findtext(args) +#define findtextEx_char(args...) findtextEx(args) +#define findlasttext_char(args...) findlasttext(args) +#define findlasttextEx_char(args...) findlasttextEx(args) +#define replacetext_char(args...) replacetext(args) +#define replacetextEx_char(args...) replacetextEx(args) +// /regex procs +#define Find_char(args...) Find(args) +#define Replace_char(args...) Replace(args) +#endif + //Additional code for the above flags. #ifdef TESTING #warn compiling in TESTING mode. testing() debug messages will be visible. diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index ae385339be..ffad931cd8 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -91,13 +91,7 @@ GLOBAL_LIST_INIT(all_types_bloods,list( "BUG" )) -GLOBAL_LIST_INIT(blood_types, list( - "blood", - "jellyblood" +GLOBAL_LIST_INIT(blood_reagent_types, list( + /datum/reagent/blood, + /datum/reagent/blood/jellyblood )) - -GLOBAL_LIST_INIT(blood_id_types, list( - "blood" = /datum/reagent/blood, - "jellyblood" = /datum/reagent/blood/jellyblood - )) - diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index a13a958ef7..ba75fbfc9c 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -32,6 +32,8 @@ GLOBAL_VAR(world_map_error_log) GLOBAL_PROTECT(world_map_error_log) GLOBAL_VAR(subsystem_log) GLOBAL_PROTECT(subsystem_log) +GLOBAL_VAR(reagent_log) +GLOBAL_PROTECT(reagent_log) GLOBAL_VAR(world_crafting_log) GLOBAL_PROTECT(world_crafting_log) @@ -44,6 +46,9 @@ GLOBAL_PROTECT(lastsignalers) GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was GLOBAL_PROTECT(lawchanges) +GLOBAL_VAR(tgui_log) +GLOBAL_PROTECT(tgui_log) + GLOBAL_LIST_EMPTY(combatlog) GLOBAL_PROTECT(combatlog) GLOBAL_LIST_EMPTY(IClog) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 2a8289697b..ec4784bd1f 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -140,10 +140,7 @@ if(obj_flags & EMAGGED) return - if(locked) - bolt_raise(usr) - else - bolt_drop(usr) + toggle_bolt(usr) /obj/machinery/door/airlock/AIAltClick() // Eletrifies doors. if(obj_flags & EMAGGED) @@ -165,10 +162,7 @@ if(obj_flags & EMAGGED) return - if(!emergency) - emergency_on(usr) - else - emergency_off(usr) + toggle_emergency(usr) /* APC */ /obj/machinery/power/apc/AICtrlClick() // turns off/on APCs. diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index dba9a59748..e9f325fb10 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -50,11 +50,6 @@ zone_select.update_icon() static_inventory += zone_select - using = new /obj/screen/craft - using.icon = ui_style - using.hud = src - static_inventory += using - using = new /obj/screen/area_creator using.icon = ui_style using.hud = src diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 23e820457c..a6d7286e80 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -91,13 +91,6 @@ var/obj/screen/using var/obj/screen/inventory/inv_box - using = new /obj/screen/craft - using.icon = ui_style - if(!widescreenlayout) // CIT CHANGE - using.screen_loc = ui_boxcraft // CIT CHANGE - using.hud = src - static_inventory += using - using = new/obj/screen/language_menu using.icon = ui_style if(!widescreenlayout) // CIT CHANGE diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 8592383a4f..25a49c8d6b 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -146,6 +146,8 @@ /datum/hud/proc/update_parallax_motionblur(client/C, animatedir, new_parallax_movedir, matrix/newtransform) + if(!C) + return C.parallax_animate_timer = FALSE for(var/thing in C.parallax_layers) var/obj/screen/parallax_layer/L = thing @@ -167,7 +169,7 @@ /datum/hud/proc/update_parallax() var/client/C = mymob.client var/turf/posobj = get_turf(C.eye) - if(!posobj) + if(!posobj) return var/area/areaobj = posobj.loc diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index c8926507bc..14e1794b4d 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -66,12 +66,6 @@ icon_state = "craft" screen_loc = ui_crafting -/obj/screen/craft/Click() - var/mob/living/M = usr - if(isobserver(usr)) - return - M.OpenCraftingMenu() - /obj/screen/area_creator name = "create new area" icon = 'icons/mob/screen_midnight.dmi' diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index d97e7c379a..d7323700e4 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -171,7 +171,8 @@ key_name = copytext(str_val, 1, key_pos) if(lowercase) key_name = lowertext(key_name) - key_value = copytext(str_val, key_pos + 1) + if(key_pos) + key_value = copytext(str_val, key_pos + length(str_val[key_pos])) var/new_key var/new_value var/continue_check_value diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 4ce0ccf361..79d125f608 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -109,13 +109,13 @@ if(!L) continue - var/firstchar = copytext(L, 1, 2) + var/firstchar = L[1] if(firstchar == "#") continue var/lockthis = firstchar == "@" if(lockthis) - L = copytext(L, 2) + L = copytext(L, length(firstchar) + 1) var/pos = findtext(L, " ") var/entry = null @@ -123,7 +123,7 @@ if(pos) entry = lowertext(copytext(L, 1, pos)) - value = copytext(L, pos + 1) + value = copytext(L, pos + length(L[pos])) else entry = lowertext(L) @@ -193,6 +193,13 @@ stat("[name]:", statclick) /datum/controller/configuration/proc/Get(entry_type) + var/datum/config_entry/E = GetEntryDatum(entry_type) + if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") + log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]") + return + return E.config_entry_value + +/datum/controller/configuration/proc/GetEntryDatum(entry_type) var/datum/config_entry/E = entry_type var/entry_is_abstract = initial(E.abstract_type) == entry_type if(entry_is_abstract) @@ -200,10 +207,7 @@ E = entries_by_type[entry_type] if(!E) CRASH("Missing config entry for [entry_type]!") - if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") - log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]") - return - return E.config_entry_value + return E /datum/controller/configuration/proc/Set(entry_type, new_val) var/datum/config_entry/E = entry_type @@ -265,7 +269,7 @@ t = trim(t) if(length(t) == 0) continue - else if(copytext(t, 1, 2) == "#") + else if(t[1] == "#") continue var/pos = findtext(t, " ") @@ -274,7 +278,7 @@ if(pos) command = lowertext(copytext(t, 1, pos)) - data = copytext(t, pos + 1) + data = copytext(t, pos + length(t[pos])) else command = lowertext(t) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index aeca31ebd2..a3bc47ac91 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -249,6 +249,18 @@ /datum/config_entry/number/movedelay/walk_delay +/datum/config_entry/number/movedelay/sprint_speed_increase + config_entry_value = 1 + +/datum/config_entry/number/movedelay/sprint_buffer_max + config_entry_value = 42 + +/datum/config_entry/number/movedelay/sprint_stamina_cost + config_entry_value = 0.7 + +/datum/config_entry/number/movedelay/sprint_buffer_regen_per_ds + config_entry_value = 0.3 + /////////////////////////////////////////////////Outdated move delay /datum/config_entry/number/outdated_movedelay deprecated_by = /datum/config_entry/keyed_list/multiplicative_movespeed @@ -408,3 +420,5 @@ /datum/config_entry/number/dropped_modes config_entry_value = 3 + +/datum/config_entry/flag/suicide_allowed diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 2a59558bcd..52d2fe45cd 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -239,7 +239,6 @@ SUBSYSTEM_DEF(air) if (MC_TICK_CHECK) return - /datum/controller/subsystem/air/proc/remove_from_active(turf/open/T) active_turfs -= T SSair_turfs.currentrun -= T @@ -257,7 +256,7 @@ SUBSYSTEM_DEF(air) #ifdef VISUALIZE_ACTIVE_TURFS T.add_atom_colour("#00ff00", TEMPORARY_COLOUR_PRIORITY) #endif - T.excited = 1 + T.excited = TRUE active_turfs |= T SSair_turfs.currentrun |= T if(blockchanges && T.excited_group) diff --git a/code/controllers/subsystem/air_turfs.dm b/code/controllers/subsystem/air_turfs.dm index 2902940bf9..9dd41aede5 100644 --- a/code/controllers/subsystem/air_turfs.dm +++ b/code/controllers/subsystem/air_turfs.dm @@ -11,7 +11,6 @@ SUBSYSTEM_DEF(air_turfs) /datum/controller/subsystem/air_turfs/fire(resumed = 0) var/fire_count = times_fired - //cache for sanic speed if (!resumed) src.currentrun = SSair.active_turfs.Copy() //cache for sanic speed (lists are references anyways) diff --git a/code/controllers/subsystem/fail2topic.dm b/code/controllers/subsystem/fail2topic.dm index a589ae2462..b358cc2c5f 100644 --- a/code/controllers/subsystem/fail2topic.dm +++ b/code/controllers/subsystem/fail2topic.dm @@ -31,10 +31,9 @@ SUBSYSTEM_DEF(fail2topic) return ..() /datum/controller/subsystem/fail2topic/fire() - while (rate_limiting.len) - var/ip = rate_limiting[1] + for(var/i in 1 to length(rate_limiting)) + var/ip = rate_limiting[i] var/last_attempt = rate_limiting[ip] - if (world.time - last_attempt > rate_limit) rate_limiting -= ip fail_counts -= ip diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm index cc09ca816e..0970b23a16 100644 --- a/code/controllers/subsystem/input.dm +++ b/code/controllers/subsystem/input.dm @@ -114,6 +114,6 @@ SUBSYSTEM_DEF(input) /datum/controller/subsystem/input/fire() var/list/clients = GLOB.clients // Let's sing the list cache song - for(var/i in 1 to clients.len) + for(var/i in 1 to length(clients)) var/client/C = clients[i] C.keyLoop() diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 8c8ad2d337..4850a67646 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -37,6 +37,8 @@ SUBSYSTEM_DEF(mapping) var/datum/space_level/empty_space var/num_of_res_levels = 1 + var/stat_map_name = "Loading..." + //dlete dis once #39770 is resolved /datum/controller/subsystem/mapping/proc/HACK_LoadMapConfig() if(!config) @@ -45,6 +47,7 @@ SUBSYSTEM_DEF(mapping) #else config = load_map_config(error_if_missing = FALSE) #endif + stat_map_name = config.map_name /datum/controller/subsystem/mapping/Initialize(timeofday) HACK_LoadMapConfig() @@ -330,7 +333,10 @@ GLOBAL_LIST_EMPTY(the_station_areas) return next_map_config = VM - return TRUE + + . = TRUE + + stat_map_name = "[config.map_name] (Next: [next_map_config.map_name])" /datum/controller/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup var/list/filelist = flist(path) diff --git a/code/controllers/subsystem/nightshift.dm b/code/controllers/subsystem/nightshift.dm index 1ecbbede1f..78b2e63cf2 100644 --- a/code/controllers/subsystem/nightshift.dm +++ b/code/controllers/subsystem/nightshift.dm @@ -26,7 +26,7 @@ SUBSYSTEM_DEF(nightshift) /datum/controller/subsystem/nightshift/proc/check_nightshift() var/emergency = GLOB.security_level >= SEC_LEVEL_RED var/announcing = TRUE - var/time = STATION_TIME(FALSE) + var/time = STATION_TIME(FALSE, world.time) var/night_time = (time < nightshift_end_time) || (time > nightshift_start_time) if(high_security_mode != emergency) high_security_mode = emergency diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm index 5aa109b63a..dd9848e465 100644 --- a/code/controllers/subsystem/pai.dm +++ b/code/controllers/subsystem/pai.dm @@ -39,34 +39,34 @@ SUBSYSTEM_DEF(pai) switch(option) if("name") - t = input("Enter a name for your pAI", "pAI Name", candidate.name) as text + t = reject_bad_name(stripped_input(usr, "Enter a name for your pAI", "pAI Name", candidate.name, MAX_NAME_LEN), TRUE) if(t) - candidate.name = copytext(sanitize(t),1,MAX_NAME_LEN) + candidate.name = t if("desc") - t = input("Enter a description for your pAI", "pAI Description", candidate.description) as message + t = stripped_multiline_input(usr, "Enter a description for your pAI", "pAI Description", candidate.description, MAX_MESSAGE_LEN) if(t) - candidate.description = copytext(sanitize(t),1,MAX_MESSAGE_LEN) + candidate.description = t if("role") - t = input("Enter a role for your pAI", "pAI Role", candidate.role) as text + t = stripped_input(usr, "Enter a role for your pAI", "pAI Role", candidate.role, MAX_MESSAGE_LEN) if(t) - candidate.role = copytext(sanitize(t),1,MAX_MESSAGE_LEN) + candidate.role = t if("ooc") - t = input("Enter any OOC comments", "pAI OOC Comments", candidate.comments) as message + t = stripped_multiline_input(usr, "Enter any OOC comments", "pAI OOC Comments", candidate.comments, MAX_MESSAGE_LEN) if(t) - candidate.comments = copytext(sanitize(t),1,MAX_MESSAGE_LEN) + candidate.comments = t if("save") candidate.savefile_save(usr) if("load") candidate.savefile_load(usr) //In case people have saved unsanitized stuff. if(candidate.name) - candidate.name = copytext(sanitize(candidate.name),1,MAX_NAME_LEN) + candidate.name = copytext_char(sanitize(candidate.name),1,MAX_NAME_LEN) if(candidate.description) - candidate.description = copytext(sanitize(candidate.description),1,MAX_MESSAGE_LEN) + candidate.description = copytext_char(sanitize(candidate.description),1,MAX_MESSAGE_LEN) if(candidate.role) - candidate.role = copytext(sanitize(candidate.role),1,MAX_MESSAGE_LEN) + candidate.role = copytext_char(sanitize(candidate.role),1,MAX_MESSAGE_LEN) if(candidate.comments) - candidate.comments = copytext(sanitize(candidate.comments),1,MAX_MESSAGE_LEN) + candidate.comments = copytext_char(sanitize(candidate.comments),1,MAX_MESSAGE_LEN) if("submit") if(isobserver(usr)) diff --git a/code/controllers/subsystem/processing/networks.dm b/code/controllers/subsystem/processing/networks.dm index 03276d5b26..f7f16538a6 100644 --- a/code/controllers/subsystem/processing/networks.dm +++ b/code/controllers/subsystem/processing/networks.dm @@ -46,6 +46,6 @@ PROCESSING_SUBSYSTEM_DEF(networks) var/hex = md5(string) if(!hex) return //errored - . = "[copytext(hex, 1, 9)]" //16 ^ 8 possibilities I think. + . = "[copytext_char(hex, 1, 9)]" //16 ^ 8 possibilities I think. if(interfaces_by_id[.]) return resolve_collisions? make_address("[num2text(rand(HID_RESTRICTED_END, 999999999), 12)]"):null diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index b406a8ccad..4d9eefae5b 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -30,6 +30,7 @@ SUBSYSTEM_DEF(shuttle) var/list/hostileEnvironments = list() //Things blocking escape shuttle from leaving var/list/tradeBlockade = list() //Things blocking cargo from leaving. var/supplyBlocked = FALSE + var/emergency_shuttle_stat_text //supply shuttle stuff var/obj/docking_port/mobile/supply/supply @@ -118,6 +119,9 @@ SUBSYSTEM_DEF(shuttle) points += point_gain //Cargo stuff end + var/esETA = emergency?.getModeStr() + emergency_shuttle_stat_text = "[esETA? "[esETA] [emergency.getTimerStr()]" : ""]" + if(!SSmapping.clearing_reserved_turfs) while(transit_requesters.len) var/requester = popleft(transit_requesters) diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm index b10d0af8c5..dacbac409d 100644 --- a/code/controllers/subsystem/tgui.dm +++ b/code/controllers/subsystem/tgui.dm @@ -11,7 +11,7 @@ SUBSYSTEM_DEF(tgui) var/basehtml // The HTML base used for all UIs. /datum/controller/subsystem/tgui/PreInit() - basehtml = file2text('tgui/tgui.html') + basehtml = file2text('tgui-next/packages/tgui/public/tgui-main.html') /datum/controller/subsystem/tgui/Shutdown() close_all_uis() diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 48da15f67e..d757b00493 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -55,6 +55,7 @@ SUBSYSTEM_DEF(throwing) var/dist_y var/dx var/dy + var/force = MOVE_FORCE_DEFAULT var/pure_diagonal var/diagonal_error var/datum/callback/callback diff --git a/code/controllers/subsystem/time_track.dm b/code/controllers/subsystem/time_track.dm index 3b19ae31cd..cd53c8f0ba 100644 --- a/code/controllers/subsystem/time_track.dm +++ b/code/controllers/subsystem/time_track.dm @@ -1,6 +1,6 @@ SUBSYSTEM_DEF(time_track) name = "Time Tracking" - wait = 600 + wait = 1 SECONDS flags = SS_NO_INIT|SS_NO_TICK_CHECK runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT @@ -16,23 +16,33 @@ SUBSYSTEM_DEF(time_track) var/last_tick_byond_time = 0 var/last_tick_tickcount = 0 + var/last_measurement = 0 + var/measurement_delay = 60 + + var/stat_time_text + var/time_dilation_text + /datum/controller/subsystem/time_track/fire() + stat_time_text = "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]\n\nRound Time: [WORLDTIME2TEXT("hh:mm:ss")]\n\nStation Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]\n\n[time_dilation_text]" - var/current_realtime = REALTIMEOFDAY - var/current_byondtime = world.time - var/current_tickcount = world.time/world.tick_lag + if(++last_measurement == measurement_delay) + last_measurement = 0 + var/current_realtime = REALTIMEOFDAY + var/current_byondtime = world.time + var/current_tickcount = world.time/world.tick_lag - if (!first_run) - var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag)) + if (!first_run) + var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag)) - time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100 + time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100 - time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current) - time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast) - time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg) - else - first_run = FALSE - last_tick_realtime = current_realtime - last_tick_byond_time = current_byondtime - last_tick_tickcount = current_tickcount - SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[SQLtime()]" = list("current" = "[time_dilation_current]", "avg_fast" = "[time_dilation_avg_fast]", "avg" = "[time_dilation_avg]", "avg_slow" = "[time_dilation_avg_slow]"))) + time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current) + time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast) + time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg) + else + first_run = FALSE + last_tick_realtime = current_realtime + last_tick_byond_time = current_byondtime + last_tick_tickcount = current_tickcount + SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[SQLtime()]" = list("current" = "[time_dilation_current]", "avg_fast" = "[time_dilation_avg_fast]", "avg" = "[time_dilation_avg]", "avg_slow" = "[time_dilation_avg_slow]"))) + time_dilation_text = "Time Dilation: [round(time_dilation_current,1)]% AVG:([round(time_dilation_avg_fast,1)]%, [round(time_dilation_avg,1)]%, [round(time_dilation_avg_slow,1)]%)" diff --git a/code/datums/action.dm b/code/datums/action.dm index cb56c26b91..8659a9e7c4 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -544,6 +544,9 @@ cooldown = world.time owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE) +/datum/action/item_action/flash + name = "Flash" + //Preset for spells /datum/action/spell_action check_flags = 0 diff --git a/code/datums/brain_damage/brain_trauma.dm b/code/datums/brain_damage/brain_trauma.dm index 1aa1341c9c..eaaab8da45 100644 --- a/code/datums/brain_damage/brain_trauma.dm +++ b/code/datums/brain_damage/brain_trauma.dm @@ -14,7 +14,7 @@ var/can_gain = TRUE var/random_gain = TRUE //can this be gained through random traumas? var/resilience = TRAUMA_RESILIENCE_BASIC //how hard is this to cure? - var/clonable = TRUE // will this transfer if the brain is cloned? + var/clonable = TRUE // will this transfer if the brain is cloned? - currently has no effect /datum/brain_trauma/Destroy() if(brain && brain.traumas) diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm index 9005a788b7..d8bfe2c35c 100644 --- a/code/datums/brain_damage/imaginary_friend.dm +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -153,7 +153,7 @@ to_chat(src, compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode, FALSE, source)) /mob/camera/imaginary_friend/proc/friend_talk(message) - message = capitalize(trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))) + message = capitalize(trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))) if(!message) return diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm index 235417d62c..d653671b5a 100644 --- a/code/datums/brain_damage/mild.dm +++ b/code/datums/brain_damage/mild.dm @@ -199,13 +199,16 @@ var/list/new_message = list() for(var/word in message_split) - var/suffix = copytext(word,-1) + var/suffix = "" + var/suffix_foundon = 0 + for(var/potential_suffix in list("." , "," , ";" , "!" , ":" , "?")) + suffix_foundon = findtext(word, potential_suffix, -length(potential_suffix)) + if(suffix_foundon) + suffix = potential_suffix + break - // Check if we have a suffix and break it out of the word - if(suffix in list("." , "," , ";" , "!" , ":" , "?")) - word = copytext(word,1,-1) - else - suffix = "" + if(suffix_foundon) + word = copytext(word, 1, suffix_foundon) word = html_decode(word) @@ -216,10 +219,9 @@ new_message += pick("uh","erm") break else - var/list/charlist = string2charlist(word) // Stupid shit code + var/list/charlist = text2charlist(word) shuffle_inplace(charlist) - charlist.len = round(charlist.len * 0.5,1) - new_message += html_encode(jointext(charlist,"")) + suffix + new_message += jointext(charlist, "") + suffix message = jointext(new_message, " ") diff --git a/code/datums/browser.dm b/code/datums/browser.dm index b226d85112..779391c4de 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -39,12 +39,12 @@ //title_image = ntitle_image /datum/browser/proc/add_stylesheet(name, file) - stylesheets["[ckey(name)].css"] = file - register_asset("[ckey(name)].css", file) - -/datum/browser/proc/add_script(name, file) - scripts["[ckey(name)].js"] = file - register_asset("[ckey(name)].js", file) + if(istype(name, /datum/asset/spritesheet)) + var/datum/asset/spritesheet/sheet = name + stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]" + else + stylesheets["[ckey(name)].css"] = file + register_asset("[ckey(name)].css", file) /datum/browser/proc/set_content(ncontent) content = ncontent diff --git a/code/modules/crafting/craft.dm b/code/datums/components/crafting/craft.dm similarity index 86% rename from code/modules/crafting/craft.dm rename to code/datums/components/crafting/craft.dm index 9f14b07bb5..8e42c48a8a 100644 --- a/code/modules/crafting/craft.dm +++ b/code/datums/components/crafting/craft.dm @@ -1,4 +1,17 @@ -/datum/personal_crafting +/datum/component/personal_crafting/Initialize() + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, .proc/create_mob_button) + +/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL) + var/datum/hud/H = user.hud_used + var/obj/screen/craft/C = new() + C.icon = H.ui_style + H.static_inventory += C + CL.screen += C + RegisterSignal(C, COMSIG_CLICK, .proc/component_ui_interact) + +/datum/component/personal_crafting var/busy var/viewing_category = 1 //typical powergamer starting on the Weapons tab var/viewing_subcategory = 1 @@ -38,9 +51,6 @@ var/display_craftable_only = FALSE var/display_compact = TRUE - - - /* This is what procs do: get_environment - gets a list of things accessable for crafting by user get_surroundings - takes a list of things and makes a list of key-types to values-amounts of said type in the list @@ -50,16 +60,15 @@ del_reqs - takes recipe and a user, loops over the recipes reqs var and tries to find everything in the list make by get_environment and delete it/add to parts list, then returns the said list */ - - - -/datum/personal_crafting/proc/check_contents(datum/crafting_recipe/R, list/contents) +/datum/component/personal_crafting/proc/check_contents(datum/crafting_recipe/R, list/contents) contents = contents["other"] main_loop: for(var/A in R.reqs) var/needed_amount = R.reqs[A] for(var/B in contents) if(ispath(B, A)) + if (R.blacklist.Find(B)) + continue if(contents[B] >= R.reqs[A]) continue main_loop else @@ -74,7 +83,7 @@ return 0 return 1 -/datum/personal_crafting/proc/get_environment(mob/user) +/datum/component/personal_crafting/proc/get_environment(mob/user) . = list() for(var/obj/item/I in user.held_items) . += I @@ -89,8 +98,10 @@ if(AM.flags_1 & HOLOGRAM_1) continue . += AM + for(var/slot in list(SLOT_R_STORE, SLOT_L_STORE)) + . += user.get_item_by_slot(slot) -/datum/personal_crafting/proc/get_surroundings(mob/user) +/datum/component/personal_crafting/proc/get_surroundings(mob/user) . = list() .["tool_behaviour"] = list() .["other"] = list() @@ -111,7 +122,7 @@ .["other"][A.type] += A.volume .["other"][I.type] += 1 -/datum/personal_crafting/proc/check_tools(mob/user, datum/crafting_recipe/R, list/contents) +/datum/component/personal_crafting/proc/check_tools(mob/user, datum/crafting_recipe/R, list/contents) if(!R.tools.len) return TRUE var/list/possible_tools = list() @@ -142,7 +153,7 @@ return FALSE return TRUE -/datum/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R) +/datum/component/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R) var/list/contents = get_surroundings(user) var/send_feedback = 1 if(check_contents(R, contents)) @@ -156,9 +167,11 @@ var/list/parts = del_reqs(R, user) var/atom/movable/I = new R.result (get_turf(user.loc)) I.CheckParts(parts, R) + if(isitem(I)) + user.put_in_hands(I) if(send_feedback) SSblackbox.record_feedback("tally", "object_crafted", 1, I.type) - log_craft("[I] crafted by [user] at [loc_name(I.loc)]") + log_craft("[I] crafted by [user] at [loc_name(I.loc)]") return 0 return "." return ", missing tool." @@ -189,7 +202,7 @@ del_reqs return the list of parts resulting object will receive as argument of CheckParts proc, on the atom level it will add them all to the contents, on all other levels it calls ..() and does whatever is needed afterwards but from contents list already */ -/datum/personal_crafting/proc/del_reqs(datum/crafting_recipe/R, mob/user) +/datum/component/personal_crafting/proc/del_reqs(datum/crafting_recipe/R, mob/user) var/list/surroundings var/list/Deletion = list() . = list() @@ -287,15 +300,18 @@ Deletion.Cut(Deletion.len) qdel(DL) +/datum/component/personal_crafting/proc/component_ui_interact(obj/screen/craft/image, location, control, params, user) + if(user == parent) + ui_interact(user) -/datum/personal_crafting/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_turf_state) +/datum/component/personal_crafting/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_turf_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "personal_crafting", "Crafting Menu", 700, 800, master_ui, state) ui.open() -/datum/personal_crafting/ui_data(mob/user) +/datum/component/personal_crafting/ui_data(mob/user) var/list/data = list() var/list/subs = list() var/cur_subcategory = CAT_NONE @@ -331,21 +347,20 @@ return data -/datum/personal_crafting/ui_act(action, params) +/datum/component/personal_crafting/ui_act(action, params) if(..()) return switch(action) if("make") - var/datum/crafting_recipe/TR = locate(params["recipe"]) + var/datum/crafting_recipe/TR = locate(params["recipe"]) in GLOB.crafting_recipes busy = TRUE - ui_interact(usr) //explicit call to show the busy display + ui_interact(usr) var/fail_msg = construct_item(usr, TR) if(!fail_msg) to_chat(usr, "[TR.name] constructed.") else to_chat(usr, "Construction failed[fail_msg]") busy = FALSE - ui_interact(usr) if("forwardCat") //Meow viewing_category = next_cat(FALSE) . = TRUE @@ -365,21 +380,20 @@ display_compact = !display_compact . = TRUE - //Next works nicely with modular arithmetic -/datum/personal_crafting/proc/next_cat(readonly = TRUE) +/datum/component/personal_crafting/proc/next_cat(readonly = TRUE) if (!readonly) viewing_subcategory = 1 . = viewing_category % categories.len + 1 -/datum/personal_crafting/proc/next_subcat() +/datum/component/personal_crafting/proc/next_subcat() if(islist(subcategories[viewing_category])) var/list/subs = subcategories[viewing_category] . = viewing_subcategory % subs.len + 1 //Previous can go fuck itself -/datum/personal_crafting/proc/prev_cat(readonly = TRUE) +/datum/component/personal_crafting/proc/prev_cat(readonly = TRUE) if (!readonly) viewing_subcategory = 1 if(viewing_category == categories.len) @@ -389,7 +403,7 @@ if(. <= 0) . = categories.len -/datum/personal_crafting/proc/prev_subcat() +/datum/component/personal_crafting/proc/prev_subcat() if(islist(subcategories[viewing_category])) var/list/subs = subcategories[viewing_category] if(viewing_subcategory == subs.len) @@ -402,7 +416,7 @@ . = null -/datum/personal_crafting/proc/build_recipe_data(datum/crafting_recipe/R) +/datum/component/personal_crafting/proc/build_recipe_data(datum/crafting_recipe/R) var/list/data = list() data["name"] = R.name data["ref"] = "[REF(R)]" @@ -441,3 +455,4 @@ if(!learned_recipes) learned_recipes = list() learned_recipes |= R + \ No newline at end of file diff --git a/code/datums/components/crafting/glassware.dm b/code/datums/components/crafting/glassware.dm new file mode 100644 index 0000000000..22d7e01f8a --- /dev/null +++ b/code/datums/components/crafting/glassware.dm @@ -0,0 +1,299 @@ +//This file is for glass working types of things! + +/obj/item/glasswork + name = "This is a bug report it!" + desc = "Failer to code. Contact your local bug remover..." + icon = 'icons/obj/glassworks.dmi' + w_class = WEIGHT_CLASS_SMALL + force = 1 + throw_speed = 1 + throw_range = 3 + tool_behaviour = null + +/obj/item/glasswork/glasskit + name = "Glass working tools" + desc = "A lovely belt of most the tools you will need to shape, mold, and refine glass into more advanced shapes." + icon_state = "glass_tools" + tool_behaviour = TOOL_GLASS_CUT + +/obj/item/glasswork/blowing_rod + name = "Glass working blow rod" + desc = "A hollow metal stick made for glass blowing." + icon_state = "blowing_rods_unused" + tool_behaviour = TOOL_BLOW + +/obj/item/glasswork/glass_base + name = "Glass fodder sheet" + desc = "A sheet of glass set aside for glass working" + icon_state = "glass_base" + var/next_step = null + var/rod = /obj/item/glasswork/blowing_rod + +/obj/item/lens + name = "Optical lens" + desc = "Good for selling or crafting, by itself its useless" + icon = 'icons/obj/chemical.dmi' + icon_state = "glass_optics" + +//////////////////////Chem Disk///////////////////// +//Two Steps // +//Sells for 300 cr, takes 10 glass shets // +//Usefull for chem spliting // +//////////////////////////////////////////////////// + +/obj/item/glasswork/glass_base/dish + name = "Glass fodder sheet" + desc = "A set of glass sheets set aside for glass working, this one is ideal for a small glass dish. Needs to be cut with some tools." + next_step = /obj/item/glasswork/glass_base/dish_part1 + +/obj/item/glasswork/glass_base/dish/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_GLASS_CUT) + new next_step(user.loc, 1) + qdel(src) + +/obj/item/glasswork/glass_base/dish_part1 + name = "Half chem dish sheet" + desc = "A sheet of glass cut in half, looks like it still needs some more cutting down" + icon_state = "glass_base_half" + next_step = /obj/item/reagent_containers/glass/beaker/glass_dish + +/obj/item/glasswork/glass_base/dish_part1/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_GLASS_CUT) + new next_step(user.loc, 1) + qdel(src) + +//////////////////////Lens////////////////////////// +//Six Steps // +//Sells for 1800 cr, takes 15 glass shets // +//Usefull for selling and later crafting // +//////////////////////////////////////////////////// + +/obj/item/glasswork/glass_base/glass_lens + name = "Glass fodder sheet" + desc = "A set of glass sheets set aside for glass working, this one is ideal for a small glass lens. Needs to be cut with some tools." + next_step = /obj/item/glasswork/glass_base/glass_lens_part1 + +/obj/item/glasswork/glass_base/glass_lens/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_GLASS_CUT) + new next_step(user.loc, 1) + qdel(src) + +/obj/item/glasswork/glass_base/glass_lens_part1 + name = "Glass fodder sheet" + desc = "Cut glass ready to be heated. Needs to be heated with some tools." + icon_state = "glass_base_half" + next_step = /obj/item/glasswork/glass_base/glass_lens_part2 + +/obj/item/glasswork/glass_base/glass_lens_part1/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_WELDER) + new next_step(user.loc, 1) + qdel(src) + +/obj/item/glasswork/glass_base/glass_lens_part2 + name = "Glass fodder sheet" + desc = "Cut glass that has been heated. Needs to be heated more with some tools." + icon_state = "glass_base_heat" + next_step = /obj/item/glasswork/glass_base/glass_lens_part3 + +/obj/item/glasswork/glass_base/glass_lens_part2/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_WELDER) + new next_step(user.loc, 1) + qdel(src) + +/obj/item/glasswork/glass_base/glass_lens_part3 + name = "Glass fodder sheet" + desc = "Cut glass that has been heated into a blob of hot glass. Needs to be placed onto a blow tube." + icon_state = "glass_base_molding" + next_step = /obj/item/glasswork/glass_base/glass_lens_part4 + +/obj/item/glasswork/glass_base/glass_lens_part3/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_BLOW) + new next_step(user.loc, 1) + qdel(src) + qdel(I) + +/obj/item/glasswork/glass_base/glass_lens_part4 + name = "Glass fodder sheet" + desc = "Cut glass that has been heated into a blob of hot glass. Needs to be cut off onto a blow tube." + icon_state = "blowing_rods_inuse" + next_step = /obj/item/glasswork/glass_base/glass_lens_part5 + +/obj/item/glasswork/glass_base/glass_lens_part4/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_GLASS_CUT) + new next_step(user.loc, 1) + new rod(user.loc, 1) + qdel(src) + +/obj/item/glasswork/glass_base/glass_lens_part5 + name = "Unpolished glass lens" + desc = "A small unpolished glass lens. Could be polished with some cloth." + icon = 'icons/obj/chemical.dmi' + icon_state = "glass_optics" + next_step = /obj/item/glasswork/glass_base/glass_lens_part6 + +/obj/item/glasswork/glass_base/glass_lens_part5/attackby(obj/item/I, mob/user, params) + ..() + if(istype(I, /obj/item/stack/sheet/cloth)) + new next_step(user.loc, 1) + qdel(src) + +/obj/item/glasswork/glass_base/glass_lens_part6 + name = "Unrefined glass lens" + desc = "A small polished glass lens. Just needs to be refined with some sandstone." + icon = 'icons/obj/chemical.dmi' + icon_state = "glass_optics" + next_step = /obj/item/lens + +/obj/item/glasswork/glass_base/glass_lens_part6/attackby(obj/item/I, mob/user, params) + ..() + if(istype(I, /obj/item/stack/sheet/mineral/sandstone)) + new next_step(user.loc, 1) + qdel(src) + +//////////////////////Spouty Flask////////////////// +//Four Steps // +//Sells for 1200 cr, takes 20 glass shets // +//Usefull for selling and chemical things // +//////////////////////////////////////////////////// + +/obj/item/glasswork/glass_base/spouty + name = "Glass fodder sheet" + desc = "A set of glass sheets set aside for glass working, this one is ideal for a spout beaker. Needs to be cut with some tools." + next_step = /obj/item/glasswork/glass_base/spouty_part2 + +/obj/item/glasswork/glass_base/spouty/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_GLASS_CUT) + new next_step(user.loc, 1) + qdel(src) + +/obj/item/glasswork/glass_base/spouty_part2 + name = "Glass fodder sheet" + desc = "Cut glass that has been heated. Needs to be heated with some tools." + icon_state = "glass_base_half" + next_step = /obj/item/glasswork/glass_base/spouty_part3 + +/obj/item/glasswork/glass_base/spouty_part2/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_WELDER) + new next_step(user.loc, 1) + qdel(src) + +/obj/item/glasswork/glass_base/spouty_part3 + name = "Glass fodder sheet" + desc = "Cut glass that has been heated into a blob of hot glass. Needs to be placed onto a blow tube." + icon_state = "glass_base_molding" + next_step = /obj/item/glasswork/glass_base/spouty_part4 + +/obj/item/glasswork/glass_base/spouty_part3/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_BLOW) + new next_step(user.loc, 1) + qdel(src) + qdel(I) + +/obj/item/glasswork/glass_base/spouty_part4 + name = "Glass fodder sheet" + desc = "Cut glass that has been heated into a blob of hot glass. Needs to be cut off onto a blow tube." + icon_state = "blowing_rods_inuse" + next_step = /obj/item/reagent_containers/glass/beaker/flask/spouty + +/obj/item/glasswork/glass_base/spouty_part4/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_GLASS_CUT) + new next_step(user.loc, 1) + new rod(user.loc, 1) + qdel(src) + +//////////////////////Small Bulb Flask////////////// +//Two Steps // +//Sells for 600 cr, takes 5 glass shets // +//Usefull for selling and chemical things // +//////////////////////////////////////////////////// + +/obj/item/glasswork/glass_base/flask_small + name = "Glass fodder sheet" + desc = "A set of glass sheets set aside for glass working, this one is ideal for a small flask. Needs to be heated with some tools." + next_step = /obj/item/glasswork/glass_base/flask_small_part1 + +/obj/item/glasswork/glass_base/flask_small/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_WELDER) + new next_step(user.loc, 1) + qdel(src) + +/obj/item/glasswork/glass_base/flask_small_part1 + name = "Metled glass" + desc = "A blob of metled glass, this one is ideal for a small flask. Needs to be blown with some tools." + icon_state = "glass_base_molding" + next_step = /obj/item/glasswork/glass_base/flask_small_part2 + +/obj/item/glasswork/glass_base/flask_small_part1/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_BLOW) + new next_step(user.loc, 1) + qdel(src) + qdel(I) + +/obj/item/glasswork/glass_base/flask_small_part2 + name = "Metled glass" + desc = "A blob of metled glass on the end of a blowing rod. Needs to be cut off with some tools." + icon_state = "blowing_rods_inuse" + next_step = /obj/item/reagent_containers/glass/beaker/flask + +/obj/item/glasswork/glass_base/flask_small_part2/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_GLASS_CUT) + new next_step(user.loc, 1) + new rod(user.loc, 1) + qdel(src) + +//////////////////////Large Bulb Flask////////////// +//Two Steps // +//Sells for 1000 cr, takes 15 glass shets // +//Usefull for selling and chemical things // +//////////////////////////////////////////////////// + +/obj/item/glasswork/glass_base/flask_large + name = "Glass fodder sheet" + desc = "A set of glass sheets set aside for glass working, this one is ideal for a large flask. Needs to be heated with some tools." + next_step = /obj/item/glasswork/glass_base/flask_large_part1 + +/obj/item/glasswork/glass_base/flask_large/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_WELDER) + new next_step(user.loc, 1) + qdel(src) + +/obj/item/glasswork/glass_base/flask_large_part1 + name = "Metled glass" + desc = "A blob of metled glass, this one is ideal for a large flask. Needs to be blown with some tools." + icon_state = "glass_base_molding" + next_step = /obj/item/glasswork/glass_base/flask_large_part2 + +/obj/item/glasswork/glass_base/flask_large_part1/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_BLOW) + new next_step(user.loc, 1) + qdel(src) + qdel(I) + +/obj/item/glasswork/glass_base/flask_large_part2 + name = "Metled glass" + desc = "A blob of metled glass on the end of a blowing rod. Needs to be cut off with some tools." + icon_state = "blowing_rods_inuse" + next_step = /obj/item/reagent_containers/glass/beaker/flask/large + +/obj/item/glasswork/glass_base/flask_large_part2/attackby(obj/item/I, mob/user, params) + ..() + if(I.tool_behaviour == TOOL_GLASS_CUT) + new next_step(user.loc, 1) + new rod(user.loc, 1) + qdel(src) diff --git a/code/modules/crafting/guncrafting.dm b/code/datums/components/crafting/guncrafting.dm similarity index 100% rename from code/modules/crafting/guncrafting.dm rename to code/datums/components/crafting/guncrafting.dm diff --git a/code/datums/components/crafting/recipes.dm b/code/datums/components/crafting/recipes.dm new file mode 100644 index 0000000000..2b6f1a5b81 --- /dev/null +++ b/code/datums/components/crafting/recipes.dm @@ -0,0 +1,25 @@ +/datum/crafting_recipe + var/name = "" //in-game display name + var/list/reqs = list() //type paths of items consumed associated with how many are needed + var/list/blacklist = list() //type paths of items explicitly not allowed as an ingredient + var/result //type path of item resulting from this craft + var/list/tools = list() //type paths of items needed but not consumed + var/time = 30 //time in deciseconds + var/list/parts = list() //type paths of items that will be placed in the result + var/list/chem_catalysts = list() //like tools but for reagents + var/category = CAT_NONE //where it shows up in the crafting UI + var/subcategory = CAT_NONE + var/always_availible = TRUE //Set to FALSE if it needs to be learned first. + +/datum/crafting_recipe/New() + if(!(result in reqs)) + blacklist += result + +/** + * Run custom pre-craft checks for this recipe + * + * user: The /mob that initiated the crafting + * collected_requirements: A list of lists of /obj/item instances that satisfy reqs. Top level list is keyed by requirement path. + */ +/datum/crafting_recipe/proc/check_requirements(mob/user, list/collected_requirements) + return TRUE diff --git a/code/modules/crafting/recipes/recipes_clothing.dm b/code/datums/components/crafting/recipes/recipes_clothing.dm similarity index 92% rename from code/modules/crafting/recipes/recipes_clothing.dm rename to code/datums/components/crafting/recipes/recipes_clothing.dm index 26de5f380d..3e036c7b29 100644 --- a/code/modules/crafting/recipes/recipes_clothing.dm +++ b/code/datums/components/crafting/recipes/recipes_clothing.dm @@ -86,7 +86,17 @@ tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER) reqs = list(/obj/item/clothing/glasses/sunglasses/reagent = 1) category = CAT_CLOTHING - +/* //Kevinz doesn't want it as a recipe for now, leaving it in if anything ever changes to let it in +/datum/crafting_recipe/stunglasses + name = "Stunglasses" + result = /obj/item/clothing/glasses/sunglasses/stunglasses + time = 60 + tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER) + reqs = list(/obj/item/assembly/flash = 1, + /obj/item/clothing/glasses/sunglasses = 1, + /obj/item/stack/cable_coil = 5) + category = CAT_CLOTHING +*/ /datum/crafting_recipe/ghostsheet name = "Ghost Sheet" result = /obj/item/clothing/suit/ghost_sheet diff --git a/code/modules/crafting/recipes/recipes_misc.dm b/code/datums/components/crafting/recipes/recipes_misc.dm similarity index 100% rename from code/modules/crafting/recipes/recipes_misc.dm rename to code/datums/components/crafting/recipes/recipes_misc.dm diff --git a/code/modules/crafting/recipes/recipes_primal.dm b/code/datums/components/crafting/recipes/recipes_primal.dm similarity index 100% rename from code/modules/crafting/recipes/recipes_primal.dm rename to code/datums/components/crafting/recipes/recipes_primal.dm diff --git a/code/modules/crafting/recipes/recipes_robot.dm b/code/datums/components/crafting/recipes/recipes_robot.dm similarity index 100% rename from code/modules/crafting/recipes/recipes_robot.dm rename to code/datums/components/crafting/recipes/recipes_robot.dm diff --git a/code/modules/crafting/recipes/recipes_weapon_and_ammo.dm b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm similarity index 95% rename from code/modules/crafting/recipes/recipes_weapon_and_ammo.dm rename to code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm index bc3a3dcf05..06f79396b8 100644 --- a/code/modules/crafting/recipes/recipes_weapon_and_ammo.dm +++ b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm @@ -18,6 +18,10 @@ category = CAT_WEAPONRY subcategory = CAT_WEAPON +/datum/crafting_recipe/strobeshield/New() + ..() + blacklist |= subtypesof(/obj/item/shield/riot/) + /datum/crafting_recipe/makeshiftshield name = "Makeshift Metal Shield" result = /obj/item/shield/makeshift @@ -109,6 +113,18 @@ category = CAT_WEAPONRY subcategory = CAT_WEAPON +/datum/crafting_recipe/switchblade_ms + name = "Switchblade" + result = /obj/item/switchblade/crafted + reqs = list(/obj/item/weaponcrafting/stock = 1, + /obj/item/weaponcrafting/receiver = 1, + /obj/item/kitchen/knife = 1, + /obj/item/stack/cable_coil = 2) + tools = list(TOOL_WELDER) + time = 45 + category = CAT_WEAPONRY + subcategory = CAT_WEAPON + ////////////////// ///BOMB CRAFTING// ////////////////// diff --git a/code/datums/components/dejavu.dm b/code/datums/components/dejavu.dm new file mode 100644 index 0000000000..1bad589c97 --- /dev/null +++ b/code/datums/components/dejavu.dm @@ -0,0 +1,107 @@ +/** + * A component to reset the parent to its previous state after some time passes + */ +/datum/component/dejavu + /// The turf the parent was on when this components was applied, they get moved back here after the duration + var/turf/starting_turf + /// Determined by the type of the parent so different behaviours can happen per type + var/rewind_type + /// How many rewinds will happen before the effect ends + var/rewinds_remaining + /// How long to wait between each rewind + var/rewind_interval + + /// The starting value of clone loss at the beginning of the effect + var/clone_loss = 0 + /// The starting value of toxin loss at the beginning of the effect + var/tox_loss = 0 + /// The starting value of oxygen loss at the beginning of the effect + var/oxy_loss = 0 + /// The starting value of brain loss at the beginning of the effect + var/brain_loss = 0 + /// The starting value of brute loss at the beginning of the effect + /// This only applies to simple animals + var/brute_loss + /// The starting value of integrity at the beginning of the effect + /// This only applies to objects + var/integrity + /// A list of body parts saved at the beginning of the effect + var/list/datum/saved_bodypart/saved_bodyparts + +/datum/component/dejavu/Initialize(rewinds = 1, interval = 10 SECONDS) + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + + starting_turf = get_turf(parent) + rewinds_remaining = rewinds + rewind_interval = interval + + if(isliving(parent)) + var/mob/living/L = parent + clone_loss = L.getCloneLoss() + tox_loss = L.getToxLoss() + oxy_loss = L.getOxyLoss() + brain_loss = L.getOrganLoss(ORGAN_SLOT_BRAIN) + rewind_type = .proc/rewind_living + + if(iscarbon(parent)) + var/mob/living/carbon/C = parent + saved_bodyparts = C.save_bodyparts() + rewind_type = .proc/rewind_carbon + + else if(isanimal(parent)) + var/mob/living/simple_animal/M = parent + brute_loss = M.bruteloss + rewind_type = .proc/rewind_animal + + else if(isobj(parent)) + var/obj/O = parent + integrity = O.obj_integrity + rewind_type = .proc/rewind_obj + + addtimer(CALLBACK(src, rewind_type), rewind_interval) + +/datum/component/dejavu/Destroy() + starting_turf = null + saved_bodyparts = null + return ..() + +/datum/component/dejavu/proc/rewind() + to_chat(parent, "You remember a time not so long ago...") + + //comes after healing so new limbs comically drop to the floor + if(starting_turf) + var/atom/movable/master = parent + master.forceMove(starting_turf) + + rewinds_remaining -- + if(rewinds_remaining) + addtimer(CALLBACK(src, rewind_type), rewind_interval) + else + to_chat(parent, "But the memory falls out of your reach.") + qdel(src) + +/datum/component/dejavu/proc/rewind_living() + var/mob/living/master = parent + master.setCloneLoss(clone_loss) + master.setToxLoss(tox_loss) + master.setOxyLoss(oxy_loss) + master.setOrganLoss(ORGAN_SLOT_BRAIN, brain_loss) + rewind() + +/datum/component/dejavu/proc/rewind_carbon() + if(saved_bodyparts) + var/mob/living/carbon/master = parent + master.apply_saved_bodyparts(saved_bodyparts) + rewind_living() + +/datum/component/dejavu/proc/rewind_animal() + var/mob/living/simple_animal/master = parent + master.bruteloss = brute_loss + master.updatehealth() + rewind_living() + +/datum/component/dejavu/proc/rewind_obj() + var/obj/master = parent + master.obj_integrity = integrity + rewind() diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm index 6682c3901d..c7ceab671d 100644 --- a/code/datums/components/slippery.dm +++ b/code/datums/components/slippery.dm @@ -9,7 +9,8 @@ callback = _callback RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip) -/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM) +/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM, extra_flags = NONE) var/mob/victim = AM - if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags) && callback) + var/lube = lube_flags | extra_flags + if(istype(victim) && victim.slip(intensity, parent, lube) && callback) callback.Invoke(victim) diff --git a/code/datums/components/spawner.dm b/code/datums/components/spawner.dm new file mode 100644 index 0000000000..fe86b60375 --- /dev/null +++ b/code/datums/components/spawner.dm @@ -0,0 +1,49 @@ +/datum/component/spawner + var/mob_types = list(/mob/living/simple_animal/hostile/carp) + var/spawn_time = 300 //30 seconds default + var/list/spawned_mobs = list() + var/spawn_delay = 0 + var/max_mobs = 5 + var/spawn_text = "emerges from" + var/list/faction = list("mining") + +/datum/component/spawner/Initialize(_mob_types, _spawn_time, _faction, _spawn_text, _max_mobs) + if(_spawn_time) + spawn_time=_spawn_time + if(_mob_types) + mob_types=_mob_types + if(_faction) + faction=_faction + if(_spawn_text) + spawn_text=_spawn_text + if(_max_mobs) + max_mobs=_max_mobs + + RegisterSignal(parent, list(COMSIG_PARENT_QDELETING), .proc/stop_spawning) + START_PROCESSING(SSprocessing, src) + +/datum/component/spawner/process() + try_spawn_mob() + + +/datum/component/spawner/proc/stop_spawning(force, hint) + STOP_PROCESSING(SSprocessing, src) + for(var/mob/living/simple_animal/L in spawned_mobs) + if(L.nest == src) + L.nest = null + spawned_mobs = null + +/datum/component/spawner/proc/try_spawn_mob() + var/atom/P = parent + if(spawned_mobs.len >= max_mobs) + return 0 + if(spawn_delay > world.time) + return 0 + spawn_delay = world.time + spawn_time + var/chosen_mob_type = pick(mob_types) + var/mob/living/simple_animal/L = new chosen_mob_type(P.loc) + L.flags_1 |= (P.flags_1 & ADMIN_SPAWNED_1) + spawned_mobs += L + L.nest = src + L.faction = src.faction + P.visible_message("[L] [spawn_text] [P].") \ No newline at end of file diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index 2c3b7518ba..5057253522 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -294,4 +294,4 @@ GLOBAL_LIST_EMPTY(uplinks) if(!T) return explosion(T,1,2,3) - qdel(parent) //Alternatively could brick the uplink. + qdel(parent) //Alternatively could brick the uplink. \ No newline at end of file diff --git a/code/datums/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm index 2f0405af2e..63e4f4f092 100644 --- a/code/datums/components/virtual_reality.dm +++ b/code/datums/components/virtual_reality.dm @@ -229,7 +229,7 @@ UnregisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER) mastermind = null if(cleanup) - var/obj/effect/vr_clean_master/cleanbot = locate() in get_area(M) + var/obj/effect/vr_clean_master/cleanbot = locate() in get_base_area(M) if(cleanbot) LAZYOR(cleanbot.corpse_party, M) qdel(src) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index ebfba43852..1622cc9dbf 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -236,7 +236,12 @@ G.fields["fingerprint"] = md5(H.dna.uni_identity) G.fields["p_stat"] = "Active" G.fields["m_stat"] = "Stable" - G.fields["sex"] = H.gender + if(H.gender == MALE) + G.fields["gender"] = "Male" + else if(H.gender == FEMALE) + G.fields["gender"] = "Female" + else + G.fields["gender"] = "Other" G.fields["photo_front"] = photo_front G.fields["photo_side"] = photo_side general += G @@ -274,7 +279,12 @@ L.fields["name"] = H.real_name L.fields["rank"] = H.mind.assigned_role L.fields["age"] = H.age - L.fields["sex"] = H.gender + if(H.gender == MALE) + G.fields["gender"] = "Male" + else if(H.gender == FEMALE) + G.fields["gender"] = "Female" + else + G.fields["gender"] = "Other" L.fields["blood_type"] = H.dna.blood_type L.fields["b_dna"] = H.dna.unique_enzymes L.fields["enzymes"] = H.dna.struc_enzymes diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index e387acbd0b..b7ec8f38dc 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -945,26 +945,7 @@ A.create_reagents(amount) if(A.reagents) - var/chosen_id - switch(alert(usr, "Choose a method.", "Add Reagents", "Search", "Choose from a list", "I'm feeling lucky")) - if("Search") - var/valid_id - while(!valid_id) - chosen_id = input(usr, "Enter the ID of the reagent you want to add.", "Search reagents") as null|text - if(isnull(chosen_id)) //Get me out of here! - break - if(!ispath(text2path(chosen_id))) - chosen_id = pick_closest_path(chosen_id, make_types_fancy(subtypesof(/datum/reagent))) - if(ispath(chosen_id)) - valid_id = TRUE - else - valid_id = TRUE - if(!valid_id) - to_chat(usr, "A reagent with that ID doesn't exist!") - if("Choose from a list") - chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in subtypesof(/datum/reagent) - if("I'm feeling lucky") - chosen_id = pick(subtypesof(/datum/reagent)) + var/chosen_id = choose_reagent_id(usr) if(chosen_id) var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num if(amount) diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 6b72f2fdfc..1c21fb9528 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -110,7 +110,7 @@ // Randomly pick a symptom to activate. /datum/disease/advance/stage_act() ..() - if(carrier) + if(carrier || QDELETED(src)) // Could be cured in parent call. return if(symptoms && symptoms.len) diff --git a/code/datums/diseases/advance/symptoms/choking.dm b/code/datums/diseases/advance/symptoms/choking.dm index 559d8f4754..c34ab566cf 100644 --- a/code/datums/diseases/advance/symptoms/choking.dm +++ b/code/datums/diseases/advance/symptoms/choking.dm @@ -22,14 +22,16 @@ Bonus stealth = -3 resistance = -2 stage_speed = -2 - transmittable = -4 + transmittable = -2 level = 3 severity = 3 base_message_chance = 15 symptom_delay_min = 10 symptom_delay_max = 30 - threshold_desc = "Stage Speed 8: Causes choking more frequently.
\ - Stealth 4: The symptom remains hidden until active." + threshold_desc = list( + "Stage Speed 8" = "Causes choking more frequently.", + "Stealth 4" = "The symptom remains hidden until active." + ) /datum/symptom/choking/Start(datum/disease/advance/A) if(!..()) @@ -41,7 +43,7 @@ Bonus suppress_warning = TRUE /datum/symptom/choking/Activate(datum/disease/advance/A) - if(!..()) + if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH)) return var/mob/living/M = A.affected_mob switch(A.stage) @@ -99,8 +101,10 @@ Bonus symptom_delay_min = 14 symptom_delay_max = 30 var/paralysis = FALSE - threshold_desc = "Stage Speed 8: Additionally synthesizes pancuronium and sodium thiopental inside the host.
\ - Transmission 8: Doubles the damage caused by the symptom." + threshold_desc = list( + "Stage Speed 8" = "Additionally synthesizes pancuronium and sodium thiopental inside the host.", + "Transmission 8" = "Doubles the damage caused by the symptom." + ) /datum/symptom/asphyxiation/Start(datum/disease/advance/A) @@ -112,7 +116,7 @@ Bonus power = 2 /datum/symptom/asphyxiation/Activate(datum/disease/advance/A) - if(!..()) + if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH)) return var/mob/living/M = A.affected_mob switch(A.stage) diff --git a/code/datums/diseases/advance/symptoms/confusion.dm b/code/datums/diseases/advance/symptoms/confusion.dm index eb6c5342f9..b8a1064c34 100644 --- a/code/datums/diseases/advance/symptoms/confusion.dm +++ b/code/datums/diseases/advance/symptoms/confusion.dm @@ -29,9 +29,11 @@ Bonus symptom_delay_min = 10 symptom_delay_max = 30 var/brain_damage = FALSE - threshold_desc = "Resistance 6: Causes brain damage over time.
\ - Transmission 6: Increases confusion duration.
\ - Stealth 4: The symptom remains hidden until active." + threshold_desc = list( + "Resistance 6" = "Causes brain damage over time.", + "Transmission 6" = "Increases confusion duration and strength.", + "Stealth 4" = "The symptom remains hidden until active.", + ) /datum/symptom/confusion/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm index b1767d7cb5..cf15ec407a 100644 --- a/code/datums/diseases/advance/symptoms/cough.dm +++ b/code/datums/diseases/advance/symptoms/cough.dm @@ -29,12 +29,13 @@ BONUS symptom_delay_min = 2 symptom_delay_max = 15 var/infective = FALSE - threshold_desc = "Resistance 3: Host will drop small items when coughing.
\ - Resistance 10: Occasionally causes coughing fits that stun the host.
\ - Stage Speed 6: Increases cough frequency.
\ - If Airborne: Coughing will infect bystanders.
\ - Stealth 4: The symptom remains hidden until active." - + threshold_desc = list( + "Resistance 11" = "The host will drop small items when coughing.", + "Resistance 15" = "Occasionally causes coughing fits that stun the host. The extra coughs do not spread the virus.", + "Stage Speed 6" = "Increases cough frequency.", + "Transmission 7" = "Coughing will now infect bystanders up to 2 tiles away.", + "Stealth 4" = "The symptom remains hidden until active.", + ) /datum/symptom/cough/Start(datum/disease/advance/A) if(!..()) return @@ -50,7 +51,7 @@ BONUS symptom_delay_max = 10 /datum/symptom/cough/Activate(datum/disease/advance/A) - if(!..()) + if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH)) return var/mob/living/M = A.affected_mob switch(A.stage) diff --git a/code/datums/diseases/advance/symptoms/deafness.dm b/code/datums/diseases/advance/symptoms/deafness.dm index e0336506e3..b6dd185b36 100644 --- a/code/datums/diseases/advance/symptoms/deafness.dm +++ b/code/datums/diseases/advance/symptoms/deafness.dm @@ -28,8 +28,10 @@ Bonus base_message_chance = 100 symptom_delay_min = 25 symptom_delay_max = 80 - threshold_desc = "Resistance 9: Causes permanent deafness, instead of intermittent.
\ - Stealth 4: The symptom remains hidden until active." + threshold_desc = list( + "Resistance 9" = "Causes permanent deafness, instead of intermittent.", + "Stealth 4" = "The symptom remains hidden until active.", + ) /datum/symptom/deafness/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/dizzy.dm b/code/datums/diseases/advance/symptoms/dizzy.dm index b4b06be5ac..be444e3916 100644 --- a/code/datums/diseases/advance/symptoms/dizzy.dm +++ b/code/datums/diseases/advance/symptoms/dizzy.dm @@ -27,8 +27,10 @@ Bonus base_message_chance = 50 symptom_delay_min = 15 symptom_delay_max = 40 - threshold_desc = "Transmission 6: Also causes druggy vision.
\ - Stealth 4: The symptom remains hidden until active." + threshold_desc = list( + "Transmission 6" = "Also causes druggy vision.", + "Stealth 4" = "The symptom remains hidden until active.", + ) /datum/symptom/dizzy/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/fever.dm b/code/datums/diseases/advance/symptoms/fever.dm index a178cba196..0348e39818 100644 --- a/code/datums/diseases/advance/symptoms/fever.dm +++ b/code/datums/diseases/advance/symptoms/fever.dm @@ -28,9 +28,10 @@ Bonus symptom_delay_min = 10 symptom_delay_max = 30 var/unsafe = FALSE //over the heat threshold - threshold_desc = "Resistance 5: Increases fever intensity, fever can overheat and harm the host.
\ - Resistance 10: Further increases fever intensity." - + threshold_desc = list( + "Resistance 5" = "Increases fever intensity, fever can overheat and harm the host.", + "Resistance 10" = "Further increases fever intensity.", + ) /datum/symptom/fever/Start(datum/disease/advance/A) if(!..()) return diff --git a/code/datums/diseases/advance/symptoms/fire.dm b/code/datums/diseases/advance/symptoms/fire.dm index 6429db9439..ea1897b67d 100644 --- a/code/datums/diseases/advance/symptoms/fire.dm +++ b/code/datums/diseases/advance/symptoms/fire.dm @@ -19,9 +19,9 @@ Bonus name = "Spontaneous Combustion" desc = "The virus turns fat into an extremely flammable compound, and raises the body's temperature, making the host burst into flames spontaneously." - stealth = 1 + stealth = -1 resistance = -4 - stage_speed = -4 + stage_speed = -3 transmittable = -4 level = 6 severity = 5 @@ -29,11 +29,12 @@ Bonus symptom_delay_min = 20 symptom_delay_max = 75 var/infective = FALSE - threshold_desc = "Stage Speed 4: Increases the intensity of the flames.
\ - Stage Speed 8: Further increases flame intensity.
\ - Transmission 8: Host will spread the virus through skin flakes when bursting into flame.
\ - Stealth 4: The symptom remains hidden until active." - + threshold_desc = list( + "Stage Speed 4" = "Increases the intensity of the flames.", + "Stage Speed 8" = "Further increases flame intensity.", + "Transmission 8" = "Host will spread the virus through skin flakes when bursting into flame.", + "Stealth 4" = "The symptom remains hidden until active.", + ) /datum/symptom/fire/Start(datum/disease/advance/A) if(!..()) return diff --git a/code/datums/diseases/advance/symptoms/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm index 48668afc90..774d97202e 100644 --- a/code/datums/diseases/advance/symptoms/flesh_eating.dm +++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm @@ -22,7 +22,7 @@ Bonus stealth = -3 resistance = -4 stage_speed = 0 - transmittable = -4 + transmittable = -3 level = 6 severity = 5 base_message_chance = 50 @@ -30,8 +30,11 @@ Bonus symptom_delay_max = 60 var/bleed = FALSE var/pain = FALSE - threshold_desc = "Resistance 7: Host will bleed profusely during necrosis.
\ - Transmission 8: Causes extreme pain to the host, weakening it." + threshold_desc = list( + "Resistance 9" = "Doubles the intensity of the immolation effect, but reduces the frequency of all of this symptom's effects.", + "Stage Speed 8" = "Increases explosion radius and explosion damage to the host when the host is wet.", + "Transmission 8" = "Additionally synthesizes chlorine trifluoride and napalm inside the host. More chemicals are synthesized if the resistance 9 threshold has been met." + ) /datum/symptom/flesh_eating/Start(datum/disease/advance/A) if(!..()) @@ -96,8 +99,11 @@ Bonus symptom_delay_max = 6 var/chems = FALSE var/zombie = FALSE - threshold_desc = "Stage Speed 7: Synthesizes Heparin and Lipolicide inside the host, causing increased bleeding and hunger.
\ - Stealth 5: The symptom remains hidden until active." + threshold_desc = list( + "Stage Speed 7" = "Synthesizes Heparin and Lipolicide inside the host, causing increased bleeding and hunger.", + "Stealth 5" = "The symptom remains hidden until active.", + ) + /datum/symptom/flesh_death/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/genetics.dm b/code/datums/diseases/advance/symptoms/genetics.dm index 7f21b03dff..f6780df3fa 100644 --- a/code/datums/diseases/advance/symptoms/genetics.dm +++ b/code/datums/diseases/advance/symptoms/genetics.dm @@ -30,9 +30,12 @@ Bonus symptom_delay_min = 60 symptom_delay_max = 120 var/no_reset = FALSE - threshold_desc = "Resistance 8: Causes two harmful mutations at once.
\ - Stage Speed 10: Increases mutation frequency.
\ - Stealth 5: The mutations persist even if the virus is cured." + threshold_desc = list( + "Resistance 8" = "The negative and mildly negative mutations caused by the virus are mutadone-proof (but will still be undone when the virus is cured if the resistance 14 threshold is not met).", + "Resistance 14" = "The host's genetic alterations are not undone when the virus is cured.", + "Stage Speed 10" = "The virus activates dormant mutations at a much faster rate.", + "Stealth 5" = "Only activates negative mutations in hosts." + ) /datum/symptom/genetic_mutation/Activate(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/hallucigen.dm b/code/datums/diseases/advance/symptoms/hallucigen.dm index 873d960524..4778e7d863 100644 --- a/code/datums/diseases/advance/symptoms/hallucigen.dm +++ b/code/datums/diseases/advance/symptoms/hallucigen.dm @@ -18,7 +18,7 @@ Bonus /datum/symptom/hallucigen name = "Hallucigen" desc = "The virus stimulates the brain, causing occasional hallucinations." - stealth = -2 + stealth = -1 resistance = -3 stage_speed = -3 transmittable = -1 @@ -28,8 +28,10 @@ Bonus symptom_delay_min = 25 symptom_delay_max = 90 var/fake_healthy = FALSE - threshold_desc = "Stage Speed 7: Increases the amount of hallucinations.
\ - Stealth 4: The virus mimics positive symptoms.." + threshold_desc = list( + "Stage Speed 7" = "Increases the amount of hallucinations.", + "Stealth 4" = "The virus mimics positive symptoms.", + ) /datum/symptom/hallucigen/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/headache.dm b/code/datums/diseases/advance/symptoms/headache.dm index 72b03000ed..944333d9cf 100644 --- a/code/datums/diseases/advance/symptoms/headache.dm +++ b/code/datums/diseases/advance/symptoms/headache.dm @@ -29,9 +29,11 @@ BONUS base_message_chance = 100 symptom_delay_min = 15 symptom_delay_max = 30 - threshold_desc = "Stage Speed 6: Headaches will cause severe pain, that weakens the host.
\ - Stage Speed 9: Headaches become less frequent but far more intense, preventing any action from the host.
\ - Stealth 4: Reduces headache frequency until later stages." + threshold_desc = list( + "Stage Speed 6" = "Headaches will cause severe pain, that weakens the host.", + "Stage Speed 9" = "Headaches become less frequent but far more intense, preventing any action from the host.", + "Stealth 4" = "Reduces headache frequency until later stages.", + ) /datum/symptom/headache/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index c1b3526f41..cf14da36a0 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -10,9 +10,10 @@ symptom_delay_min = 1 symptom_delay_max = 1 var/passive_message = "" //random message to infected but not actively healing people - threshold_desc = "Stage Speed 6: Doubles healing speed.
\ - Stealth 4: Healing will no longer be visible to onlookers." - + threshold_desc = list( + "Stage Speed 6" = "Doubles healing speed.", + "Stealth 4" = "Healing will no longer be visible to onlookers.", + ) /datum/symptom/heal/Start(datum/disease/advance/A) if(!..()) return @@ -54,8 +55,10 @@ level = 6 passive_message = "You miss the feeling of starlight on your skin." var/nearspace_penalty = 0.3 - threshold_desc = "Stage Speed 6: Increases healing speed.
\ - Transmission 6: Removes penalty for only being close to space." + threshold_desc = list( + "Stage Speed 6" = "Increases healing speed.", + "Transmission 6" = "Removes penalty for only being close to space.", + ) /datum/symptom/heal/starlight/Start(datum/disease/advance/A) if(!..()) @@ -105,8 +108,10 @@ level = 7 var/food_conversion = FALSE desc = "The virus rapidly breaks down any foreign chemicals in the bloodstream." - threshold_desc = "Resistance 7: Increases chem removal speed.
\ - Stage Speed 6: Consumed chemicals nourish the host." + threshold_desc = list( + "Resistance 7" = "Increases chem removal speed.", + "Stage Speed 6" = "Consumed chemicals nourish the host.", + ) /datum/symptom/heal/chem/Start(datum/disease/advance/A) if(!..()) @@ -139,9 +144,10 @@ var/reduced_hunger = FALSE desc = "The virus causes the host's metabolism to accelerate rapidly, making them process chemicals twice as fast,\ but also causing increased hunger." - threshold_desc = "Stealth 3: Reduces hunger rate.
\ - Stage Speed 10: Chemical metabolization is tripled instead of doubled." - + threshold_desc = list( + "Stealth 3" = "Reduces hunger rate.", + "Stage Speed 10" = "Chemical metabolization is tripled instead of doubled.", + ) /datum/symptom/heal/metabolism/Start(datum/disease/advance/A) if(!..()) return @@ -172,8 +178,9 @@ transmittable = -1 level = 6 passive_message = "You feel tingling on your skin as light passes over it." - threshold_desc = "Stage Speed 8: Doubles healing speed." - + threshold_desc = list( + "Stage Speed 8" = "Doubles healing speed.", + ) /datum/symptom/heal/darkness/Start(datum/disease/advance/A) if(!..()) return @@ -222,9 +229,11 @@ var/deathgasp = FALSE var/stabilize = FALSE var/active_coma = FALSE //to prevent multiple coma procs - threshold_desc = "Stealth 2: Host appears to die when falling into a coma.
\ - Resistance 4: The virus also stabilizes the host while they are in critical condition.
\ - Stage Speed 7: Increases healing speed." + threshold_desc = list( + "Stealth 2" = "Host appears to die when falling into a coma.", + "Resistance 4" = "The virus also stabilizes the host while they are in critical condition.", + "Stage Speed 7" = "Increases healing speed.", + ) /datum/symptom/heal/coma/Start(datum/disease/advance/A) if(!..()) @@ -313,8 +322,10 @@ level = 6 passive_message = "Your skin feels oddly dry..." var/absorption_coeff = 1 - threshold_desc = "Resistance 5: Water is consumed at a much slower rate.
\ - Stage Speed 7: Increases healing speed." + threshold_desc = list( + "Resistance 5" = "Water is consumed at a much slower rate.", + "Stage Speed 7" = "Increases healing speed.", + ) /datum/symptom/heal/water/Start(datum/disease/advance/A) if(!..()) @@ -369,9 +380,10 @@ level = 8 passive_message = "You feel an odd attraction to plasma." var/temp_rate = 1 - threshold_desc = "Transmission 6: Increases temperature adjustment rate and heals toxin lovers.
\ - Stage Speed 7: Increases healing speed." - + threshold_desc = list( + "Transmission 6" = "Additionally increases temperature adjustment rate and heals those who love toxins", + "Resistance 7" = "Increases healing speed.", + ) /datum/symptom/heal/plasma/Start(datum/disease/advance/A) if(!..()) return diff --git a/code/datums/diseases/advance/symptoms/itching.dm b/code/datums/diseases/advance/symptoms/itching.dm index b0812e0235..c0c312cbc2 100644 --- a/code/datums/diseases/advance/symptoms/itching.dm +++ b/code/datums/diseases/advance/symptoms/itching.dm @@ -29,8 +29,10 @@ BONUS symptom_delay_min = 5 symptom_delay_max = 25 var/scratch = FALSE - threshold_desc = "Transmission 6: Increases frequency of itching.
\ - Stage Speed 7: The host will scrath itself when itching, causing superficial damage." + threshold_desc = list( + "Transmission 6" = "Increases frequency of itching.", + "Stage Speed 7" = "The host will scrath itself when itching, causing superficial damage.", + ) /datum/symptom/itching/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/nanites.dm b/code/datums/diseases/advance/symptoms/nanites.dm index b18e089a41..9598b3fd33 100644 --- a/code/datums/diseases/advance/symptoms/nanites.dm +++ b/code/datums/diseases/advance/symptoms/nanites.dm @@ -10,8 +10,10 @@ symptom_delay_min = 1 symptom_delay_max = 1 var/reverse_boost = FALSE - threshold_desc = "Transmission 5: Increases the virus' growth rate while nanites are present.
\ - Stage Speed 7: Increases the replication boost." + threshold_desc = list( + "Transmission 5" = "Increases the virus' growth rate while nanites are present.", + "Stage Speed 7" = "Increases the replication boost." + ) /datum/symptom/nano_boost/Start(datum/disease/advance/A) if(!..()) @@ -42,8 +44,10 @@ symptom_delay_min = 1 symptom_delay_max = 1 var/reverse_boost = FALSE - threshold_desc = "Stage Speed 5: Increases the virus' growth rate while nanites are present.
\ - Resistance 7: Severely increases the rate at which the nanites are destroyed." + threshold_desc = list( + "Stage Speed 5" = "Increases the virus' growth rate while nanites are present.", + "Resistance 7" = "Severely increases the rate at which the nanites are destroyed." + ) /datum/symptom/nano_destroy/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/narcolepsy.dm b/code/datums/diseases/advance/symptoms/narcolepsy.dm index 24ba024aa6..3f9405328a 100644 --- a/code/datums/diseases/advance/symptoms/narcolepsy.dm +++ b/code/datums/diseases/advance/symptoms/narcolepsy.dm @@ -18,7 +18,7 @@ Bonus stealth = -1 resistance = -2 stage_speed = -3 - transmittable = -4 + transmittable = 0 level = 6 symptom_delay_min = 15 symptom_delay_max = 80 @@ -26,8 +26,10 @@ Bonus var/sleep_level = 0 var/sleepy_ticks = 0 var/stamina = FALSE - threshold_desc = "Transmission 7: Also relaxes the muscles, weakening and slowing the host.
\ - Resistance 10: Causes narcolepsy more often, increasing the chance of the host falling asleep." + threshold_desc = list( + "Transmission 4" = "Causes the host to periodically emit a yawn that spreads the virus in a manner similar to that of a sneeze.", + "Stage Speed 10" = "Causes narcolepsy more often, increasing the chance of the host falling asleep.", + ) /datum/symptom/narcolepsy/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/oxygen.dm b/code/datums/diseases/advance/symptoms/oxygen.dm index e66bdf5ee0..3821c0585e 100644 --- a/code/datums/diseases/advance/symptoms/oxygen.dm +++ b/code/datums/diseases/advance/symptoms/oxygen.dm @@ -28,7 +28,9 @@ Bonus symptom_delay_min = 1 symptom_delay_max = 1 var/regenerate_blood = FALSE - threshold_desc = "Resistance 8:Additionally regenerates lost blood.
" + threshold_desc = list( + "Resistance 8" = "Additionally regenerates lost blood." + ) /datum/symptom/oxygen/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index 1f8cc8d7af..bbacdd885d 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -11,9 +11,11 @@ var/purge_alcohol = FALSE var/trauma_heal_mild = FALSE var/trauma_heal_severe = FALSE - threshold_desc = "Resistance 6: Heals minor brain traumas.
\ - Resistance 9: Heals severe brain traumas.
\ - Transmission 8: Purges alcohol in the bloodstream." + threshold_desc = list( + "Resistance 6" = "Heals minor brain traumas.", + "Resistance 9" = "Heals severe brain traumas.", + "Transmission 8" = "Purges alcohol in the bloodstream.", + ) /datum/symptom/mind_restoration/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/shivering.dm b/code/datums/diseases/advance/symptoms/shivering.dm index 741e2a1e16..da14ed87cf 100644 --- a/code/datums/diseases/advance/symptoms/shivering.dm +++ b/code/datums/diseases/advance/symptoms/shivering.dm @@ -20,15 +20,17 @@ Bonus desc = "The virus inhibits the body's thermoregulation, cooling the body down." stealth = 0 resistance = 2 - stage_speed = 2 + stage_speed = 3 transmittable = 2 level = 2 severity = 2 symptom_delay_min = 10 symptom_delay_max = 30 var/unsafe = FALSE //over the cold threshold - threshold_desc = "Stage Speed 5: Increases cooling speed; the host can fall below safe temperature levels.
\ - Stage Speed 10: Further increases cooling speed." + threshold_desc = list( + "Stage Speed 5" = "Increases cooling speed,; the host can fall below safe temperature levels.", + "Stage Speed 10" = "Further increases cooling speed." + ) /datum/symptom/fever/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm index 5d4d40fb95..439f391fe4 100644 --- a/code/datums/diseases/advance/symptoms/sneeze.dm +++ b/code/datums/diseases/advance/symptoms/sneeze.dm @@ -27,8 +27,10 @@ Bonus severity = 1 symptom_delay_min = 5 symptom_delay_max = 35 - threshold_desc = "Transmission 9: Increases sneezing range, spreading the virus over a larger area.
\ - Stealth 4: The symptom remains hidden until active." + threshold_desc = list( + "Transmission 9" = "Increases sneezing range, spreading the virus over 6 meter cone instead of over a 4 meter cone.", + "Stealth 4" = "The symptom remains hidden until active.", + ) /datum/symptom/sneeze/Start(datum/disease/advance/A) if(!..()) @@ -39,7 +41,7 @@ Bonus suppress_warning = TRUE /datum/symptom/sneeze/Activate(datum/disease/advance/A) - if(!..()) + if(!..() || HAS_TRAIT(A.affected_mob,TRAIT_NOBREATH)) return var/mob/living/M = A.affected_mob switch(A.stage) diff --git a/code/datums/diseases/advance/symptoms/viral.dm b/code/datums/diseases/advance/symptoms/viral.dm index 55807aed6b..28ac491fcd 100644 --- a/code/datums/diseases/advance/symptoms/viral.dm +++ b/code/datums/diseases/advance/symptoms/viral.dm @@ -26,7 +26,7 @@ BONUS ////////////////////////////////////// Viral evolution - Moderate stealth reductopn. + Moderate stealth reduction. Major decreases to resistance. increases stage speed. increase to transmission diff --git a/code/datums/diseases/advance/symptoms/vision.dm b/code/datums/diseases/advance/symptoms/vision.dm index b4a33cb837..6c9ad5a941 100644 --- a/code/datums/diseases/advance/symptoms/vision.dm +++ b/code/datums/diseases/advance/symptoms/vision.dm @@ -29,9 +29,10 @@ Bonus symptom_delay_min = 25 symptom_delay_max = 80 var/remove_eyes = FALSE - threshold_desc = "Resistance 12: Weakens extraocular muscles, eventually leading to complete detachment of the eyes.
\ - Stealth 4: The symptom remains hidden until active." - + threshold_desc = list( + "Resistance 12" = "Weakens extraocular muscles, eventually leading to complete detachment of the eyes.", + "Stealth 4" = "The symptom remains hidden until active.", + ) /datum/symptom/visionloss/Start(datum/disease/advance/A) if(!..()) return diff --git a/code/datums/diseases/advance/symptoms/voice_change.dm b/code/datums/diseases/advance/symptoms/voice_change.dm index 8b9b7d069a..9be484d99a 100644 --- a/code/datums/diseases/advance/symptoms/voice_change.dm +++ b/code/datums/diseases/advance/symptoms/voice_change.dm @@ -31,9 +31,11 @@ Bonus var/scramble_language = FALSE var/datum/language/current_language var/datum/language_holder/original_language - threshold_desc = "Transmission 14: The host's language center of the brain is damaged, leading to complete inability to speak or understand any language.
\ - Stage Speed 7: Changes voice more often.
\ - Stealth 3: The symptom remains hidden until active." + threshold_desc = list( + "Transmission 14" = "The host's language center of the brain is damaged, leading to complete inability to speak or understand any language.", + "Stage Speed 7" = "Changes voice more often.", + "Stealth 3" = "The symptom remains hidden until active." + ) /datum/symptom/voice_change/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm index f53638bc12..22e249a388 100644 --- a/code/datums/diseases/advance/symptoms/vomit.dm +++ b/code/datums/diseases/advance/symptoms/vomit.dm @@ -25,8 +25,8 @@ Bonus desc = "The virus causes nausea and irritates the stomach, causing occasional vomit." stealth = -2 resistance = -1 - stage_speed = 0 - transmittable = 1 + stage_speed = -1 + transmittable = 2 level = 3 severity = 3 base_message_chance = 100 @@ -34,9 +34,11 @@ Bonus symptom_delay_max = 80 var/vomit_blood = FALSE var/proj_vomit = 0 - threshold_desc = "Resistance 7: Host will vomit blood, causing internal damage.
\ - Transmission 7: Host will projectile vomit, increasing vomiting range.
\ - Stealth 4: The symptom remains hidden until active." + threshold_desc = list( + "Resistance 7" = "Host will vomit blood, causing internal damage.", + "Transmission 7" = "Host will projectile vomit, increasing vomiting range.", + "Stealth 4" = "The symptom remains hidden until active." + ) /datum/symptom/vomit/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm index 66fc90f1f8..5eab698750 100644 --- a/code/datums/diseases/advance/symptoms/weight.dm +++ b/code/datums/diseases/advance/symptoms/weight.dm @@ -29,7 +29,9 @@ Bonus base_message_chance = 100 symptom_delay_min = 15 symptom_delay_max = 45 - threshold_desc = "Stealth 4: The symptom is less noticeable." + threshold_desc = list( + "Stealth 4" = "The symptom is less noticeable." + ) /datum/symptom/weight_loss/Start(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm index 230a074bb1..71a5bcb99e 100644 --- a/code/datums/diseases/wizarditis.dm +++ b/code/datums/diseases/wizarditis.dm @@ -94,7 +94,7 @@ STI KALY - blind var/area/thearea = pick(theareas) var/list/L = list() - for(var/turf/T in get_area_turfs(thearea.type)) + for(var/turf/T in thearea) if(T.z != affected_mob.z) continue if(T.name == "space") diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 67dbbdfef7..68c6839482 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -92,7 +92,15 @@ . = "" var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS) - L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2) + switch(holder.gender) + if(MALE) + L[DNA_GENDER_BLOCK] = construct_block(G_MALE, 4) + if(FEMALE) + L[DNA_GENDER_BLOCK] = construct_block(G_FEMALE, 4) + if(PLURAL) + L[DNA_GENDER_BLOCK] = construct_block(G_PLURAL, 4) + else + L[DNA_GENDER_BLOCK] = construct_block(G_NEUTER, 4) if(ishuman(holder)) var/mob/living/carbon/human/H = holder if(!GLOB.hair_styles_list.len) @@ -165,7 +173,15 @@ if(DNA_EYE_COLOR_BLOCK) setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color)) if(DNA_GENDER_BLOCK) - setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2)) + switch(H.gender) + if(MALE) + setblock(uni_identity, blocknumber, construct_block(G_MALE, 4)) + if(FEMALE) + setblock(uni_identity, blocknumber, construct_block(G_FEMALE, 4)) + if(PLURAL) + setblock(uni_identity, blocknumber, construct_block(G_PLURAL, 4)) + else + setblock(uni_identity, blocknumber, construct_block(G_NEUTER, 4)) if(DNA_FACIAL_HAIR_STYLE_BLOCK) setblock(uni_identity, blocknumber, construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len)) if(DNA_HAIR_STYLE_BLOCK) @@ -307,7 +323,16 @@ /mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) if(!has_dna()) return - gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE + + switch(deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 4)) + if(G_MALE) + gender = MALE + if(G_FEMALE) + gender = FEMALE + if(G_PLURAL) + gender = PLURAL + else + gender = NEUTER /mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) ..() @@ -345,14 +370,14 @@ /////////////////////////// DNA HELPER-PROCS ////////////////////////////// /proc/getleftblocks(input,blocknumber,blocksize) if(blocknumber > 1) - return copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) + return copytext_char(input,1,((blocksize*blocknumber)-(blocksize-1))) /proc/getrightblocks(input,blocknumber,blocksize) if(blocknumber < (length(input)/blocksize)) - return copytext(input,blocksize*blocknumber+1,length(input)+1) + return copytext_char(input,blocksize*blocknumber+1,length(input)+1) /proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE) - return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1) + return copytext_char(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1) /proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE) if(!istring || !blocknumber || !replacement || !blocksize) diff --git a/code/datums/elements/dusts_on_catatonia.dm b/code/datums/elements/dusts_on_catatonia.dm new file mode 100644 index 0000000000..f5ca5722c4 --- /dev/null +++ b/code/datums/elements/dusts_on_catatonia.dm @@ -0,0 +1,26 @@ +/datum/element/dusts_on_catatonia + element_flags = ELEMENT_DETACH + var/list/mob/attached_mobs = list() + +/datum/element/dusts_on_catatonia/Attach(datum/target,penalize = FALSE) + . = ..() + if(!ismob(target)) + return ELEMENT_INCOMPATIBLE + var/mob/M = target + if(!(M in attached_mobs)) + attached_mobs += M + START_PROCESSING(SSprocessing,src) + +/datum/element/dusts_on_catatonia/Detach(mob/M) + . = ..() + if(M in attached_mobs) + attached_mobs -= M + if(!attached_mobs.len) + STOP_PROCESSING(SSprocessing,src) + +/datum/element/dusts_on_catatonia/process() + for(var/m in attached_mobs) + var/mob/M = m + if(!M.key && !M.get_ghost()) + M.dust(force = TRUE) + Detach(M) diff --git a/code/datums/elements/dusts_on_leaving_area.dm b/code/datums/elements/dusts_on_leaving_area.dm new file mode 100644 index 0000000000..9527e1fd3a --- /dev/null +++ b/code/datums/elements/dusts_on_leaving_area.dm @@ -0,0 +1,28 @@ +/datum/element/dusts_on_leaving_area + element_flags = ELEMENT_DETACH | ELEMENT_BESPOKE + id_arg_index = 2 + var/list/attached_mobs = list() + var/list/area_types = list() + +/datum/element/dusts_on_leaving_area/Attach(datum/target,types) + . = ..() + if(!ismob(target)) + return ELEMENT_INCOMPATIBLE + attached_mobs += target + area_types = types + START_PROCESSING(SSprocessing,src) + +/datum/element/dusts_on_leaving_area/Detach(mob/M) + . = ..() + if(M in attached_mobs) + attached_mobs -= M + if(!attached_mobs.len) + STOP_PROCESSING(SSprocessing,src) + +/datum/element/dusts_on_leaving_area/process() + for(var/m in attached_mobs) + var/mob/M = m + var/area/A = get_area(M) + if(!(A.type in area_types)) + M.dust(force = TRUE) + Detach(M) diff --git a/code/datums/elements/ghost_role_eligibility.dm b/code/datums/elements/ghost_role_eligibility.dm index 8ecb579bc8..e57aaddd5a 100644 --- a/code/datums/elements/ghost_role_eligibility.dm +++ b/code/datums/elements/ghost_role_eligibility.dm @@ -22,6 +22,8 @@ if(!(M.ckey in timeouts)) timeouts += M.ckey timeouts[M.ckey] = 0 + else if(timeouts[M.ckey] == CANT_REENTER_ROUND) + return timeouts[M.ckey] = max(timeouts[M.ckey],penalty) /datum/element/ghost_role_eligibility/Detach(mob/M) diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm index 599c492d4c..e653e3e36b 100644 --- a/code/datums/emotes.dm +++ b/code/datums/emotes.dm @@ -18,6 +18,7 @@ var/list/mob_type_ignore_stat_typecache var/stat_allowed = CONSCIOUS var/static/list/emote_list = list() + var/static/regex/stop_bad_mime = regex(@"says|exclaims|yells|asks") /datum/emote/New() if(key_third_person) diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index 420602cc7f..7d040a4982 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -43,7 +43,7 @@ for(var/line in testmerge) var/datum/tgs_revision_information/test_merge/tm = line var/cm = tm.pull_request_commit - var/details = ": '" + html_encode(tm.title) + "' by " + html_encode(tm.author) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 11))) + var/details = ": '" + html_encode(tm.title) + "' by " + html_encode(tm.author) + " at commit " + html_encode(copytext_char(cm, 1, 11)) if(details && findtext(details, "\[s\]") && (!usr || !usr.client.holder)) continue . += "#[tm.number][details]
" @@ -57,11 +57,11 @@ // Round ID if(GLOB.round_id) msg += "Round ID: [GLOB.round_id]" - + msg += "BYOND Version: [world.byond_version].[world.byond_build]" if(DM_VERSION != world.byond_version || DM_BUILD != world.byond_build) msg += "Compiled with BYOND Version: [DM_VERSION].[DM_BUILD]" - + // Revision information var/datum/getrev/revdata = GLOB.revdata msg += "Server revision compiled on: [revdata.date]" diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 1c2ce851fe..6b0981665d 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -66,7 +66,7 @@ var/area/A = get_area(curturf) var/area/B = get_area(destturf) - if(!forced && (A.noteleport || B.noteleport)) + if(!forced && (HAS_TRAIT(teleatom, TRAIT_NO_TELEPORT) || A.noteleport || B.noteleport)) return FALSE if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf)) diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm index 5a4600432d..72fe6f5a1c 100644 --- a/code/datums/holocall.dm +++ b/code/datums/holocall.dm @@ -257,8 +257,8 @@ var/splitpoint = findtext(prepared_line," ") if(!splitpoint) continue - var/command = copytext(prepared_line,1,splitpoint) - var/value = copytext(prepared_line,splitpoint+1) + var/command = copytext(prepared_line, 1, splitpoint) + var/value = copytext(prepared_line, splitpoint + length(prepared_line[splitpoint])) switch(command) if("DELAY") var/delay_value = text2num(value) diff --git a/code/datums/martial.dm b/code/datums/martial.dm index c8caa853c3..cf2adfce8c 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -31,7 +31,7 @@ reset_streak(D) streak = streak+element if(length(streak) > max_streak_length) - streak = copytext(streak,2) + streak = copytext(streak, 1 + length(streak[1])) return /datum/martial_art/proc/reset_streak(mob/living/carbon/human/new_target) diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm index b98bc4f951..ea883c5637 100644 --- a/code/datums/martial/boxing.dm +++ b/code/datums/martial/boxing.dm @@ -50,6 +50,12 @@ D.forcesay(GLOB.hit_appends) return 1 +/datum/martial_art/boxing/teach(mob/living/carbon/human/H, make_temporary = TRUE) + . = ..() + if(.) + if(H.pulling && ismob(H.pulling)) + H.stop_pulling() + /obj/item/clothing/gloves/boxing var/datum/martial_art/boxing/style = new @@ -58,7 +64,7 @@ return if(slot == SLOT_GLOVES) var/mob/living/carbon/human/H = user - style.teach(H,1) + style.teach(H,TRUE) return /obj/item/clothing/gloves/boxing/dropped(mob/user) diff --git a/code/datums/martial/psychotic_brawl.dm b/code/datums/martial/psychotic_brawl.dm index 45d73353f9..f0ad7aedfd 100644 --- a/code/datums/martial/psychotic_brawl.dm +++ b/code/datums/martial/psychotic_brawl.dm @@ -26,7 +26,7 @@ if(A.grab_state >= GRAB_AGGRESSIVE) D.grabbedby(A, 1) else - A.start_pulling(D, 1) + A.start_pulling(D, supress_message = TRUE) if(A.pulling) D.drop_all_held_items() D.stop_pulling() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 628e698ae0..61d467a20d 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -132,14 +132,14 @@ //CIT CHANGE - makes arousal update when transfering bodies if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs. var/mob/living/L = new_character - if(L.client && L.client.prefs & L.client.prefs.auto_ooc & L.client.prefs.chat_toggles & CHAT_OOC) + if(L.client?.prefs && L.client.prefs.auto_ooc && L.client.prefs.chat_toggles & CHAT_OOC) DISABLE_BITFIELD(L.client.prefs.chat_toggles,CHAT_OOC) SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character, old_character) SEND_SIGNAL(new_character, COMSIG_MOB_ON_NEW_MIND) /datum/mind/proc/store_memory(new_text) - if((length(memory) + length(new_text)) <= MAX_MESSAGE_LEN) + if((length_char(memory) + length_char(new_text)) <= MAX_MESSAGE_LEN) memory += "[new_text]
" /datum/mind/proc/wipe_memory() @@ -409,7 +409,7 @@ assigned_role = new_role else if (href_list["memory_edit"]) - var/new_memo = copytext(sanitize(input("Write new memory", "Memory", memory) as null|message),1,MAX_MESSAGE_LEN) + var/new_memo = stripped_multiline_input(usr, "Write new memory", "Memory", memory, MAX_MESSAGE_LEN) if (isnull(new_memo)) return memory = new_memo diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index f689ff903e..6397bbe66b 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -32,9 +32,9 @@ GLOBAL_LIST_EMPTY(mutations_list) /datum/mutation/human/proc/set_se(se_string, on = 1) if(!se_string || length(se_string) < DNA_STRUC_ENZYMES_BLOCKS * DNA_BLOCK_SIZE) return - var/before = copytext(se_string, 1, ((dna_block - 1) * DNA_BLOCK_SIZE) + 1) + var/before = copytext_char(se_string, 1, ((dna_block - 1) * DNA_BLOCK_SIZE) + 1) var/injection = num2hex(on ? rand(lowest_value, (256 * 16) - 1) : rand(0, lowest_value - 1), DNA_BLOCK_SIZE) - var/after = copytext(se_string, (dna_block * DNA_BLOCK_SIZE) + 1, 0) + var/after = copytext_char(se_string, (dna_block * DNA_BLOCK_SIZE) + 1, 0) return before + injection + after /datum/mutation/human/proc/set_block(mob/living/carbon/owner, on = 1) diff --git a/code/datums/ruins/station.dm b/code/datums/ruins/station.dm index e637b6178f..17d5a9e1e2 100644 --- a/code/datums/ruins/station.dm +++ b/code/datums/ruins/station.dm @@ -34,3 +34,30 @@ id = "engine_tesla" suffix = "Box/Engine/engine_tesla.dmm" name = "Box Tesla" + +/datum/map_template/ruin/station/box/engine/teg + id = "engine_teg" + suffix = "Box/Engine/engine_tesla.dmm" + name = "Box TEG" + +/datum/map_template/ruin/station/box/engine/empty + id = "engine_empty" + suffix = "Box/Engine/engine_tesla.dmm" + name = "Box Empty" + +/datum/map_template/ruin/station/box/engine/am + id = "engine_am" + suffix = "Box/Engine/engine_tesla.dmm" + name = "Box Antimatter" + +/datum/map_template/ruin/station/box/engine/budget + id = "engine_budget" + suffix = "Box/Engine/engine_tesla.dmm" + name = "Box P.A.C.M.A.N" + +// Lavaland + // Mining Base +/datum/map_template/ruin/station/lavaland/mining_base + id = "mining_public_01" + suffix = "Lavaland/Mining_Station/Mining_Station_Public_01.dmm" + name = "Public Mining Base" \ No newline at end of file diff --git a/code/datums/spawners_menu.dm b/code/datums/spawners_menu.dm index bb7dc4cdb7..1adcb6fde6 100644 --- a/code/datums/spawners_menu.dm +++ b/code/datums/spawners_menu.dm @@ -18,14 +18,18 @@ for(var/spawner in GLOB.mob_spawners) var/list/this = list() this["name"] = spawner - this["desc"] = "" + this["short_desc"] = "" + this["flavor_text"] = "" + this["important_warning"] = "" this["refs"] = list() for(var/spawner_obj in GLOB.mob_spawners[spawner]) this["refs"] += "[REF(spawner_obj)]" if(!this["desc"]) if(istype(spawner_obj, /obj/effect/mob_spawn)) var/obj/effect/mob_spawn/MS = spawner_obj - this["desc"] = MS.flavour_text + this["short_desc"] = MS.short_desc + this["flavor_text"] = MS.flavour_text + this["important_info"] = MS.important_info else var/obj/O = spawner_obj this["desc"] = O.desc diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 751f5faa94..2e46046a7e 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -615,7 +615,7 @@ if(do_after(mob_viewer, 35, null, mob_viewer)) if(isliving(mob_viewer)) var/mob/living/L = mob_viewer - to_chat(mob_viewer, "You succesfuly remove the durathread strand.") + to_chat(mob_viewer, "You successfully remove the durathread strand.") L.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) diff --git a/code/datums/traits/_quirk.dm b/code/datums/traits/_quirk.dm index d73fa3c825..c6466fdd96 100644 --- a/code/datums/traits/_quirk.dm +++ b/code/datums/traits/_quirk.dm @@ -16,6 +16,7 @@ /datum/quirk/New(mob/living/quirk_mob, spawn_effects) if(!quirk_mob || (human_only && !ishuman(quirk_mob)) || quirk_mob.has_quirk(type)) qdel(src) + return quirk_holder = quirk_mob SSquirks.quirk_objects += src to_chat(quirk_holder, gain_text) diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index b74f24c469..0d4a6a7b3f 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -201,13 +201,12 @@ medical_record_text = "Patient's blood tests report an abnormal concentration of red blood cells in their bloodstream." /datum/quirk/bloodpressure/add() - var/mob/living/M = quirk_holder - M.blood_ratio = 1.2 - M.blood_volume += 150 + quirk_holder.blood_ratio = 1.2 + quirk_holder.blood_volume += 150 /datum/quirk/bloodpressure/remove() - var/mob/living/M = quirk_holder - M.blood_ratio = 1 + if(quirk_holder) + quirk_holder.blood_ratio = 1 /datum/quirk/night_vision name = "Night Vision" diff --git a/code/datums/traits/negative.dm b/code/datums/traits/negative.dm index f1d394ee2e..faa7eec392 100644 --- a/code/datums/traits/negative.dm +++ b/code/datums/traits/negative.dm @@ -396,3 +396,12 @@ GLOBAL_LIST_EMPTY(family_heirlooms) /datum/quirk/blindness/remove() quirk_holder?.cure_blind(ROUNDSTART_TRAIT) + +/datum/quirk/coldblooded + name = "Cold-blooded" + desc = "Your body doesn't create its own internal heat, requiring external heat regulation." + value = -2 + medical_record_text = "Patient is ectothermic." + mob_trait = TRAIT_COLDBLOODED + gain_text = "You feel cold-blooded." + lose_text = "You feel more warm-blooded." diff --git a/code/datums/traits/neutral.dm b/code/datums/traits/neutral.dm index d19efe486d..ab2a69e7e9 100644 --- a/code/datums/traits/neutral.dm +++ b/code/datums/traits/neutral.dm @@ -104,15 +104,6 @@ gain_text = "You desire to be hurt." lose_text = "Pain has become less exciting for you." -/datum/quirk/coldblooded - name = "Cold-blooded" - desc = "Your body doesn't create its own internal heat, requiring external heat regulation." - value = 0 - medical_record_text = "Patient is ectothermic." - mob_trait = TRAIT_COLDBLOODED - gain_text = "You feel cold-blooded." - lose_text = "You feel more warm-blooded." - /datum/quirk/alcohol_intolerance name = "Alcohol Intolerance" desc = "You take toxin damage from alcohol rather than getting drunk." diff --git a/code/datums/verbs.dm b/code/datums/verbs.dm index 442997288a..39afde14d0 100644 --- a/code/datums/verbs.dm +++ b/code/datums/verbs.dm @@ -88,8 +88,8 @@ var/list/entry = list() entry["parent"] = "[type]" entry["name"] = verbpath.desc - if (copytext(verbpath.name,1,2) == "@") - entry["command"] = copytext(verbpath.name,2) + if (verbpath.name[1] == "@") + entry["command"] = copytext(verbpath.name, length(verbpath.name[1]) + 1) else entry["command"] = replacetext(verbpath.name, " ", "-") diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index a3b666dcc6..01b9facbb8 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -50,7 +50,10 @@ stage = STARTUP_STAGE var/list/affectareas = list() for(var/V in get_areas(area_type)) - affectareas += V + var/area/A = V + affectareas |= A + if(A.sub_areas) + affectareas |= A.sub_areas for(var/V in protected_areas) affectareas -= get_areas(V) for(var/V in affectareas) diff --git a/code/datums/wires/_wires.dm b/code/datums/wires/_wires.dm index fab5a1313c..d4a5dcdeb3 100644 --- a/code/datums/wires/_wires.dm +++ b/code/datums/wires/_wires.dm @@ -118,7 +118,7 @@ return TRUE /datum/wires/proc/is_dud(wire) - return dd_hasprefix(wire, WIRE_DUD_PREFIX) + return findtext(wire, WIRE_DUD_PREFIX) /datum/wires/proc/is_dud_color(color) return is_dud(get_wire(color)) @@ -215,8 +215,8 @@ /datum/wires/ui_interact(mob/user, ui_key = "wires", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if (!ui) - ui = new(user, src, ui_key, "wires", "[holder.name] wires", 350, 150 + wires.len * 30, master_ui, state) + if(!ui) + ui = new(user, src, ui_key, "wires", "[holder.name] Wires", 350, 150 + wires.len * 30, master_ui, state) ui.open() /datum/wires/ui_data(mob/user) diff --git a/code/datums/wires/airalarm.dm b/code/datums/wires/airalarm.dm index 6eb4dc04db..0c4715e27e 100644 --- a/code/datums/wires/airalarm.dm +++ b/code/datums/wires/airalarm.dm @@ -46,7 +46,7 @@ A.mode = 1 // AALARM_MODE_SCRUB A.apply_mode() if(WIRE_ALARM) // Clear alarms. - var/area/AA = get_area(A) + var/area/AA = get_base_area(A) if(AA.atmosalert(0, holder)) A.post_alert(0) A.update_icon() @@ -68,7 +68,7 @@ A.mode = 3 // AALARM_MODE_PANIC A.apply_mode() if(WIRE_ALARM) // Post alarm. - var/area/AA = get_area(A) + var/area/AA = get_base_area(A) if(AA.atmosalert(2, holder)) A.post_alert(2) A.update_icon() \ No newline at end of file diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 2d256aad27..99b8165306 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -63,6 +63,15 @@ var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default? var/list/canSmoothWithAreas //typecache to limit the areas that atoms in this area can smooth with +/** + * These two vars allow for multiple unique areas to be linked to a master area + * and share some functionalities such as APC powernet nodes, fire alarms etc, without sacrificing + * their own flags, statuses, variables and more snowflakes. + * Friendly reminder: no map edited areas. + */ + var/list/area/sub_areas //list of typepaths of the areas you wish to link here, will be replaced with a list of references on mapload. + var/area/base_area //The area we wish to use in place of src for certain actions such as APC area linking. + var/nightshift_public_area = NIGHTSHIFT_AREA_NONE //considered a public area for nightshift /*Adding a wizard area teleport list because motherfucking lag -- Urist*/ @@ -123,10 +132,35 @@ GLOBAL_LIST_EMPTY(teleportlocs) reg_in_areas_in_z() + //so far I'm only implementing it on mapped unique areas, it's easier this way. + if(unique && sub_areas) + if(type in sub_areas) + WARNING("\"[src]\" typepath found inside its own sub-areas list, please make sure it doesn't share its parent type initial sub-areas value.") + sub_areas = null + else + var/paths = sub_areas.Copy() + sub_areas = null + for(var/type in paths) + var/area/A = GLOB.areas_by_type[type] + if(!A) //By chance an area not loaded in the current world, no warning report. + continue + if(A == src) + WARNING("\"[src]\" area a attempted to link with itself.") + continue + if(A.base_area) + WARNING("[src] attempted to link with [A] while the latter is already linked to another area ([A.base_area]).") + continue + LAZYADD(sub_areas, A) + A.base_area = src + else if(LAZYLEN(sub_areas)) + WARNING("sub-areas are currently not supported for non-unique areas such as [src].") + sub_areas = null + return INITIALIZE_HINT_LATELOAD /area/LateInitialize() - power_change() // all machines set to current power level, also updates icon + if(!base_area) //we don't want to run it twice. + power_change() // all machines set to current power level, also updates icon /area/proc/reg_in_areas_in_z() if(contents.len) @@ -149,6 +183,19 @@ GLOBAL_LIST_EMPTY(teleportlocs) /area/Destroy() if(GLOB.areas_by_type[type] == src) GLOB.areas_by_type[type] = null + if(base_area) + LAZYREMOVE(base_area, src) + base_area = null + if(sub_areas) + for(var/i in sub_areas) + var/area/A = i + A.base_area = null + sub_areas -= A + if(A.requires_power) + A.power_light = FALSE + A.power_equip = FALSE + A.power_environ = FALSE + INVOKE_ASYNC(A, .proc/power_change) STOP_PROCESSING(SSobj, src) return ..() @@ -214,9 +261,12 @@ GLOBAL_LIST_EMPTY(teleportlocs) var/datum/computer_file/program/alarm_monitor/p = item p.cancelAlarm("Atmosphere", src, source) - src.atmosalm = danger_level - return 1 - return 0 + atmosalm = danger_level + for(var/i in sub_areas) + var/area/A = i + A.atmosalm = danger_level + return TRUE + return FALSE /area/proc/ModifyFiredoors(opening) if(firedoors) @@ -241,11 +291,8 @@ GLOBAL_LIST_EMPTY(teleportlocs) return if (!fire) - set_fire_alarm_effect() + set_fire_alarm_effects(TRUE) ModifyFiredoors(FALSE) - for(var/item in firealarms) - var/obj/machinery/firealarm/F = item - F.update_icon() for (var/item in GLOB.alert_consoles) var/obj/machinery/computer/station_alert/a = item @@ -264,11 +311,8 @@ GLOBAL_LIST_EMPTY(teleportlocs) /area/proc/firereset(obj/source) if (fire) - unset_fire_alarm_effects() + set_fire_alarm_effects(FALSE) ModifyFiredoors(TRUE) - for(var/item in firealarms) - var/obj/machinery/firealarm/F = item - F.update_icon() for (var/item in GLOB.silicon_mobs) var/mob/living/silicon/aiPlayer = item @@ -300,9 +344,9 @@ GLOBAL_LIST_EMPTY(teleportlocs) return //Trigger alarm effect - set_fire_alarm_effect() + set_fire_alarm_effects(TRUE) //Lockdown airlocks - for(var/obj/machinery/door/DOOR in src) + for(var/obj/machinery/door/DOOR in get_sub_areas_contents(src)) close_and_lock_door(DOOR) for (var/i in GLOB.silicon_mobs) @@ -311,23 +355,20 @@ GLOBAL_LIST_EMPTY(teleportlocs) //Cancel silicon alert after 1 minute addtimer(CALLBACK(SILICON, /mob/living/silicon.proc/cancelAlarm,"Burglar",src,trigger), 600) -/area/proc/set_fire_alarm_effect() - fire = TRUE +/area/proc/set_fire_alarm_effects(boolean) + fire = boolean + for(var/i in sub_areas) + var/area/A = i + A.fire = boolean mouse_opacity = MOUSE_OPACITY_TRANSPARENT for(var/alarm in firealarms) var/obj/machinery/firealarm/F = alarm F.update_fire_light(fire) - for(var/obj/machinery/light/L in src) + F.update_icon() + for(var/obj/machinery/light/L in get_sub_areas_contents(src)) L.update() -/area/proc/unset_fire_alarm_effects() - fire = FALSE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - for(var/alarm in firealarms) - var/obj/machinery/firealarm/F = alarm - F.update_fire_light(fire) - for(var/obj/machinery/light/L in src) - L.update() +/area/proc/updateicon() /** * Update the icon state of the area * @@ -380,26 +421,35 @@ GLOBAL_LIST_EMPTY(teleportlocs) /area/proc/power_change() for(var/obj/machinery/M in src) // for each machine in the area M.power_change() // reverify power status (to update icons etc.) + if(sub_areas) + for(var/i in sub_areas) + var/area/A = i + A.power_light = power_light + A.power_equip = power_equip + A.power_environ = power_environ + INVOKE_ASYNC(A, .proc/power_change) update_icon() /area/proc/usage(chan) - var/used = 0 switch(chan) if(LIGHT) - used += used_light + . += used_light if(EQUIP) - used += used_equip + . += used_equip if(ENVIRON) - used += used_environ + . += used_environ if(TOTAL) - used += used_light + used_equip + used_environ + . += used_light + used_equip + used_environ if(STATIC_EQUIP) - used += static_equip + . += static_equip if(STATIC_LIGHT) - used += static_light + . += static_light if(STATIC_ENVIRON) - used += static_environ - return used + . += static_environ + if(sub_areas) + for(var/i in sub_areas) + var/area/A = i + . += A.usage(chan) /area/proc/addStaticPower(value, powerchannel) switch(powerchannel) @@ -414,6 +464,10 @@ GLOBAL_LIST_EMPTY(teleportlocs) used_equip = 0 used_light = 0 used_environ = 0 + if(sub_areas) + for(var/i in sub_areas) + var/area/A = i + A.clear_usage() /area/proc/use_power(amount, chan) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 9a6d992991..960e1cc513 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -360,7 +360,7 @@ SEND_SIGNAL(src, COMSIG_ATOM_FIRE_ACT, exposed_temperature, exposed_volume) return -/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked) +/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...). addtimer(CALLBACK(src, .proc/hitby_react, AM), 2) @@ -505,9 +505,8 @@ return final_rgb /atom/proc/clean_blood() - if(islist(blood_DNA)) - blood_DNA = null - return TRUE + . = blood_DNA? TRUE : FALSE + blood_DNA = null /atom/proc/wash_cream() return TRUE @@ -728,6 +727,13 @@ /atom/proc/multitool_act(mob/living/user, obj/item/I) return +/atom/proc/multitool_check_buffer(user, obj/item/I, silent = FALSE) + if(!istype(I, /obj/item/multitool)) + if(user && !silent) + to_chat(user, "[I] has no data buffer!") + return FALSE + return TRUE + /atom/proc/screwdriver_act(mob/living/user, obj/item/I) SEND_SIGNAL(src, COMSIG_ATOM_SCREWDRIVER_ACT, user, I) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 00a08d62b2..42ccc4bbba 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -3,6 +3,9 @@ var/last_move = null var/last_move_time = 0 var/anchored = FALSE + var/move_resist = MOVE_RESIST_DEFAULT + var/move_force = MOVE_FORCE_DEFAULT + var/pull_force = PULL_FORCE_DEFAULT var/datum/thrownthing/throwing = null var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported var/throw_range = 7 @@ -115,20 +118,20 @@ return FALSE return ..() -/atom/movable/proc/start_pulling(atom/movable/AM,gs) +/atom/movable/proc/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE) if(QDELETED(AM)) return FALSE - if(!(AM.can_be_pulled(src))) + if(!(AM.can_be_pulled(src, state, force))) return FALSE // If we're pulling something then drop what we're currently pulling and pull this instead. if(pulling) - if(gs==0) + if(state == 0) stop_pulling() return FALSE // Are we trying to pull something we are already pulling? Then enter grab cycle and end. if(AM == pulling) - grab_state = gs + grab_state = state if(istype(AM,/mob/living)) var/mob/living/AMob = AM AMob.grabbedby(src) @@ -139,11 +142,12 @@ AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once. pulling = AM AM.pulledby = src - grab_state = gs + grab_state = state if(ismob(AM)) var/mob/M = AM log_combat(src, M, "grabbed", addition="passive grab") - visible_message("[src] has grabbed [M] passively!") + if(!supress_message) + visible_message("[src] has grabbed [M] passively!") return TRUE /atom/movable/proc/stop_pulling() @@ -159,7 +163,7 @@ /atom/movable/proc/Move_Pulled(atom/A) if(!pulling) return - if(pulling.anchored || !pulling.Adjacent(src)) + if(pulling.anchored || pulling.move_resist > move_force || !pulling.Adjacent(src)) stop_pulling() return if(isliving(pulling)) @@ -186,7 +190,7 @@ log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.") stop_pulling() return - if(pulling.anchored) + if(pulling.anchored || pulling.move_resist > move_force) stop_pulling() return @@ -508,17 +512,19 @@ /atom/movable/proc/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) set waitfor = 0 SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) - return hit_atom.hitby(src) + return hit_atom.hitby(src, throwingdatum=throwingdatum) -/atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked) - if(!anchored && hitpush) +/atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked, datum/thrownthing/throwingdatum) + if(!anchored && hitpush && (!throwingdatum || (throwingdatum.force >= (move_resist * MOVE_FORCE_PUSH_RATIO)))) step(src, AM.dir) ..() -/atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback, messy_throw = TRUE) - return throw_at(target, range, speed, thrower, spin, diagonals_first, callback, messy_throw) +/atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = INFINITY, messy_throw = TRUE) + if((force < (move_resist * MOVE_FORCE_THROW_RATIO)) || (move_resist == INFINITY)) + return + return throw_at(target, range, speed, thrower, spin, diagonals_first, callback, force, messy_throw) -/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback, messy_throw = TRUE) //If this returns FALSE then callback will not be called. +/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = INFINITY, messy_throw = TRUE) //If this returns FALSE then callback will not be called. . = FALSE if (!target || speed <= 0) return @@ -564,6 +570,7 @@ TT.speed = speed TT.thrower = thrower TT.diagonals_first = diagonals_first + TT.force = force TT.callback = callback if(!QDELETED(thrower)) TT.target_zone = thrower.zone_selected @@ -614,6 +621,22 @@ return 0 return 1 +/atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction) + return FALSE + +/atom/movable/proc/force_push(atom/movable/AM, force = move_force, direction, silent = FALSE) + . = AM.force_pushed(src, force, direction) + if(!silent && .) + visible_message("[src] forcefully pushes against [AM]!", "You forcefully push against [AM]!") + +/atom/movable/proc/move_crush(atom/movable/AM, force = move_force, direction, silent = FALSE) + . = AM.move_crushed(src, force, direction) + if(!silent && .) + visible_message("[src] crushes past [AM]!", "You crush [AM]!") + +/atom/movable/proc/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction) + return FALSE + /atom/movable/CanPass(atom/movable/mover, turf/target) if(mover in buckled_mobs) return 1 @@ -833,14 +856,15 @@ /atom/movable/proc/get_cell() return -/atom/movable/proc/can_be_pulled(user) +/atom/movable/proc/can_be_pulled(user, grab_state, force) if(src == user || !isturf(loc)) return FALSE if(anchored || throwing) return FALSE + if(force < (move_resist * MOVE_FORCE_PULL_RATIO)) + return FALSE return TRUE - /obj/item/proc/do_pickup_animation(atom/target) set waitfor = FALSE if(!istype(loc, /turf)) diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index df4a38cf60..718ed2c103 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -5,6 +5,7 @@ /datum/game_mode/traitor/bros name = "traitor+brothers" config_tag = "traitorbro" + required_players = 25 restricted_jobs = list("AI", "Cyborg") protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm index 0945875ac9..af57372129 100644 --- a/code/game/gamemodes/clown_ops/clown_weapons.dm +++ b/code/game/gamemodes/clown_ops/clown_weapons.dm @@ -57,10 +57,8 @@ /obj/item/melee/transforming/energy/sword/bananium name = "bananium sword" desc = "An elegant weapon, for a more civilized age." - force = 0 - throwforce = 0 - force_on = 0 - throwforce_on = 0 + force_on = 15 + throwforce_on = 15 hitsound = null attack_verb_on = list("slipped") clumsy_check = FALSE @@ -72,7 +70,7 @@ /obj/item/melee/transforming/energy/sword/bananium/Initialize() . = ..() - AddComponent(/datum/component/slippery, 60, GALOSHES_DONT_HELP) + AddComponent(/datum/component/slippery, 81, GALOSHES_DONT_HELP) var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery) slipper.signal_enabled = active @@ -80,13 +78,13 @@ ..() if(active) var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery) - slipper.Slip(M) + slipper.Slip(src, M, FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING) /obj/item/melee/transforming/energy/sword/bananium/throw_impact(atom/hit_atom, throwingdatum) . = ..() if(active) var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery) - slipper.Slip(hit_atom) + slipper.Slip(src, hit_atom, FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING) /obj/item/melee/transforming/energy/sword/bananium/attackby(obj/item/I, mob/living/user, params) if((world.time > next_trombone_allowed) && istype(I, /obj/item/melee/transforming/energy/sword/bananium)) @@ -109,7 +107,7 @@ transform_weapon(user, TRUE) user.visible_message("[user] is [pick("slitting [user.p_their()] stomach open with", "falling on")] [src]! It looks like [user.p_theyre()] trying to commit seppuku, but the blade slips off of [user.p_them()] harmlessly!") var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery) - slipper.Slip(user) + slipper.Slip(src, user, FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING) return SHAME //BANANIUM SHIELD @@ -129,7 +127,7 @@ /obj/item/shield/energy/bananium/Initialize() . = ..() - AddComponent(/datum/component/slippery, 60, GALOSHES_DONT_HELP) + AddComponent(/datum/component/slippery, 81, GALOSHES_DONT_HELP) var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery) slipper.signal_enabled = active @@ -145,12 +143,12 @@ C.throw_mode_on() //so they can catch it on the return. return ..() -/obj/item/shield/energy/bananium/throw_impact(atom/hit_atom) +/obj/item/shield/energy/bananium/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(active) - var/caught = hit_atom.hitby(src, 0, 0) + var/caught = hit_atom.hitby(src, FALSE, FALSE, throwingdatum=throwingdatum) if(iscarbon(hit_atom) && !caught)//if they are a carbon and they didn't catch it var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery) - slipper.Slip(hit_atom) + slipper.Slip(src, hit_atom, FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING) if(thrownby && !caught) throw_at(thrownby, throw_range+2, throw_speed, null, 1) else @@ -212,7 +210,7 @@ M.equip_to_slot_or_del(the_stash, SLOT_WEAR_MASK, TRUE, TRUE, TRUE, TRUE) /obj/item/clothing/mask/fakemoustache/sticky - var/unstick_time = 600 + var/unstick_time = 2 MINUTES /obj/item/clothing/mask/fakemoustache/sticky/Initialize() . = ..() diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index d010da465e..b296ba7273 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -12,7 +12,7 @@ var/list/skipped_areas = list(/area/engine/engineering, /area/engine/supermatter, /area/engine/atmospherics_engine, /area/ai_monitored/turret_protected/ai) for(var/area/A in world) - if( !A.requires_power || A.always_unpowered ) + if( !A.requires_power || A.always_unpowered || A.base_area) continue var/skip = 0 @@ -61,8 +61,9 @@ S.output_attempt = 1 S.update_icon() S.power_change() + for(var/area/A in world) - if(!istype(A, /area/space) && !istype(A, /area/shuttle) && !istype(A, /area/arrival)) + if(!istype(A, /area/space) && !istype(A, /area/shuttle) && !istype(A, /area/arrival) && !A.always_unpowered && !A.base_area) A.power_light = TRUE A.power_equip = TRUE A.power_environ = TRUE diff --git a/code/game/gamemodes/gangs/dominator.dm b/code/game/gamemodes/gangs/dominator.dm index 8c1272dcbd..db060a6539 100644 --- a/code/game/gamemodes/gangs/dominator.dm +++ b/code/game/gamemodes/gangs/dominator.dm @@ -101,7 +101,7 @@ playsound(loc, 'sound/items/timer.ogg', 10, 0) if(!warned && (time_remaining < 180)) warned = TRUE - var/area/domloc = get_area(loc) + var/area/domloc = get_base_area(loc) gang.message_gangtools("Less than 3 minutes remains in hostile takeover. Defend your dominator at [domloc.map_name]!") for(var/G in GLOB.gangs) var/datum/team/gang/tempgang = G @@ -179,7 +179,7 @@ if((tempgang.domination_time != NOT_DOMINATING) || !tempgang.dom_attempts || !in_range(src, user) || !isturf(loc)) return 0 - var/area/A = get_area(loc) + var/area/A = get_base_area(loc) var/locname = A.map_name gang = tempgang diff --git a/code/game/gamemodes/gangs/gang_decals.dm b/code/game/gamemodes/gangs/gang_decals.dm index 6e5cb58891..7aaed769d9 100644 --- a/code/game/gamemodes/gangs/gang_decals.dm +++ b/code/game/gamemodes/gangs/gang_decals.dm @@ -19,7 +19,7 @@ return INITIALIZE_HINT_QDEL gang = G var/newcolor = G.color - var/area/territory = get_area(src) + var/area/territory = get_base_area(src) icon_state = G.name G.new_territories |= list(territory.type = territory.name) //If this isn't tagged by a specific gangster there's no bonus income. @@ -27,7 +27,7 @@ /obj/effect/decal/cleanable/crayon/gang/Destroy() if(gang) - var/area/territory = get_area(src) + var/area/territory = get_base_area(src) gang.territories -= territory.type gang.new_territories -= territory.type gang.lost_territories |= list(territory.type = territory.name) diff --git a/code/game/gamemodes/gangs/gang_items.dm b/code/game/gamemodes/gangs/gang_items.dm index 2e9ca4dcc0..4dba8dae93 100644 --- a/code/game/gamemodes/gangs/gang_items.dm +++ b/code/game/gamemodes/gangs/gang_items.dm @@ -290,12 +290,6 @@ datum/gang_item/clothing/shades //Addition: Why not have cool shades on a gang m cost = 5 item_path = /obj/item/grenade/syndieminibomb/concussion/frag -/datum/gang_item/equipment/stimpack - name = "Black Market Stimulants" - id = "stimpack" - cost = 12 - item_path = /obj/item/reagent_containers/syringe/stimulants - /datum/gang_item/equipment/implant_breaker name = "Implant Breaker" id = "implant_breaker" @@ -401,7 +395,7 @@ datum/gang_item/equipment/gangsheild return "This device requires a 5x5 area clear of walls to FUNCTION. (Estimated Takeover Time: [round(gang.determine_domination_time()/60,0.1)] minutes)" /datum/gang_item/equipment/dominator/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - var/area/userarea = get_area(user) + var/area/userarea = get_base_area(user) if(!(userarea.type in gang.territories|gang.new_territories)) to_chat(user,"The dominator can be spawned only on territory controlled by your gang!") return FALSE diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index 6d681f8108..cfb4c9a120 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -21,16 +21,16 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event //Meteor spawning global procs /////////////////////////////// -/proc/spawn_meteors(number = 10, list/meteortypes) +/proc/spawn_meteors(number = 10, list/meteortypes, dir) for(var/i = 0; i < number; i++) - spawn_meteor(meteortypes) + spawn_meteor(meteortypes, dir) -/proc/spawn_meteor(list/meteortypes) +/proc/spawn_meteor(list/meteortypes, dir) var/turf/pickedstart var/turf/pickedgoal var/max_i = 10//number of tries to spawn meteor. while(!isspaceturf(pickedstart)) - var/startSide = pick(GLOB.cardinals) + var/startSide = dir || pick(GLOB.cardinals) var/startZ = pick(SSmapping.levels_by_trait(ZTRAIT_STATION)) pickedstart = spaceDebrisStartLoc(startSide, startZ) pickedgoal = spaceDebrisFinishLoc(startSide, startZ) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index db6d0a6672..c713c71b49 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -574,7 +574,7 @@ GLOBAL_LIST_EMPTY(possible_items) else if(targetinfo.check_special_completion(I))//Returns 1 by default. Items with special checks will return 1 if the conditions are fulfilled. return TRUE - if(targetinfo && I.type in targetinfo.altitems) //Ok, so you don't have the item. Do you have an alternative, at least? + if(targetinfo && (I.type in targetinfo.altitems)) //Ok, so you don't have the item. Do you have an alternative, at least? if(targetinfo.check_special_completion(I))//Yeah, we do! Don't return 0 if we don't though - then you could fail if you had 1 item that didn't pass and got checked first! return TRUE return FALSE diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 5f44fccdac..a0666b3133 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -113,6 +113,11 @@ Class Procs: var/atom/movable/occupant = null var/speed_process = FALSE // Process as fast as possible? var/obj/item/circuitboard/circuit // Circuit to be created and inserted when the machinery is created + // For storing and overriding ui id and dimensions + var/tgui_id // ID of TGUI interface + var/ui_style // ID of custom TGUI style (optional) + var/ui_x + var/ui_y var/interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 016f226399..495e90d305 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -220,6 +220,12 @@ T -= M.rating*0.2 prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4 +/obj/machinery/autolathe/examine(mob/user) + . += ..() + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Storing up to [materials.max_amount] material units.
Material consumption at [prod_coeff*100]%.
" + /obj/machinery/autolathe/proc/main_win(mob/user) var/dat = "

Autolathe Menu:


" dat += materials_printout() @@ -380,4 +386,4 @@ //Called when the object is constructed by an autolathe //Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes /obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A) - return \ No newline at end of file + return diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm index 0b9ed6bb3f..41867a8520 100644 --- a/code/game/machinery/bank_machine.dm +++ b/code/game/machinery/bank_machine.dm @@ -46,34 +46,37 @@ new /obj/item/stack/spacecash/c200(drop_location()) // will autostack playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1) SSshuttle.points -= 200 - if(next_warning < world.time && prob(15)) - var/area/A = get_area(loc) - var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!" - radio.talk_into(src, message, radio_channel) - next_warning = world.time + minimum_time_between_warnings + if(next_warning < world.time && prob(15)) + var/area/A = get_area(loc) + var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!" + radio.talk_into(src, message, radio_channel) + next_warning = world.time + minimum_time_between_warnings -/obj/machinery/computer/bank_machine/ui_interact(mob/user) - . = ..() - var/dat = "[station_name()] secure vault. Authorized personnel only.
" - dat += "Current Balance: [SSshuttle.points] credits.
" - if(!siphoning) - dat += "Siphon Credits
" - else - dat += "Halt Credit Siphon
" +/obj/machinery/computer/bank_machine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "bank_machine", name, 320, 165, master_ui, state) + ui.open() - dat += "Close" +/obj/machinery/computer/bank_machine/ui_data(mob/user) + var/list/data = list() + data["current_balance"] = SSshuttle.points + data["siphoning"] = siphoning + data["station_name"] = station_name() - var/datum/browser/popup = new(user, "computer", "Bank Vault", 300, 200) - popup.set_content("
[dat]
") - popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() + return data -/obj/machinery/computer/bank_machine/Topic(href, href_list) +/obj/machinery/computer/bank_machine/ui_act(action, params) if(..()) return - if(href_list["siphon"]) - say("Siphon of station credits has begun!") - siphoning = TRUE - if(href_list["halt"]) - say("Station credit withdrawal halted.") - siphoning = FALSE + + switch(action) + if("siphon") + say("Siphon of station credits has begun!") + siphoning = TRUE + . = TRUE + if("halt") + say("Station credit withdrawal halted.") + siphoning = FALSE + . = TRUE diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index bef5effb54..22c1ff811c 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -319,7 +319,8 @@ if(status) change_msg = "reactivates" triggerCameraAlarm() - addtimer(CALLBACK(src, .proc/cancelCameraAlarm), 100) + if(!QDELETED(src)) //We'll be doing it anyway in destroy + addtimer(CALLBACK(src, .proc/cancelCameraAlarm), 100) if(displaymessage) if(user) visible_message("[user] [change_msg] [src]!") diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index a982411692..991577e123 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -28,6 +28,8 @@ . += "There's [charging ? "a" : "no"] cell in the charger." if(charging) . += "Current charge: [round(charging.percent(), 1)]%." + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Charge rate at [charge_rate]J per cycle." /obj/machinery/cell_charger/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/stock_parts/cell) && !panel_open) @@ -44,7 +46,7 @@ var/area/a = loc.loc // Gets our locations location, like a dream within a dream if(!isarea(a)) return - if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power! + if(!a.powered(EQUIP)) // There's no APC in this area, don't try to cheat power! to_chat(user, "[src] blinks red as you try to insert the cell!") return if(!user.transferItemToLoc(W,src)) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 413621d8b9..afb882598e 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -4,7 +4,7 @@ //Potential replacement for genetics revives or something I dunno (?) #define CLONE_INITIAL_DAMAGE 150 //Clones in clonepods start with 150 cloneloss damage and 150 brainloss damage, thats just logical -#define MINIMUM_HEAL_LEVEL 40 +#define MINIMUM_HEAL_LEVEL 20 #define SPEAK(message) radio.talk_into(src, message, radio_channel) @@ -61,18 +61,15 @@ QDEL_LIST(unattached_flesh) . = ..() -/obj/machinery/clonepod/RefreshParts() +/obj/machinery/clonepod/RefreshParts() speed_coeff = 0 efficiency = 0 for(var/obj/item/stock_parts/scanning_module/S in component_parts) efficiency += S.rating for(var/obj/item/stock_parts/manipulator/P in component_parts) - speed_coeff += P.rating - heal_level = (efficiency * 15) + 10 - if(heal_level < MINIMUM_HEAL_LEVEL) - heal_level = MINIMUM_HEAL_LEVEL - if(heal_level > 100) - heal_level = 100 + speed_coeff += (P.rating / 2) + speed_coeff = max(1, speed_coeff) + heal_level = CLAMP((efficiency * 10) + 10, MINIMUM_HEAL_LEVEL, 100) //The return of data disks?? Just for transferring between genetics machine/cloning machine. //TO-DO: Make the genetics machine accept them. @@ -102,8 +99,13 @@ /obj/machinery/clonepod/examine(mob/user) . = ..() var/mob/living/mob_occupant = occupant + . += "The linking device can be scanned with a multitool." if(mess) . += "It's filled with blood and viscera. You swear you can see it moving..." + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Cloning speed at [speed_coeff*50]%.
Predicted amount of cellular damage: [100-heal_level]%.
" + if(efficiency > 5) + to_chat(user, "Pod has been upgraded to support autoprocessing.") if(is_operational() && mob_occupant) if(mob_occupant.stat != DEAD) . += "Current clone cycle is [round(get_completion())]% complete." @@ -164,9 +166,7 @@ var/mob/living/carbon/human/H = new /mob/living/carbon/human(src) H.hardset_dna(ui, se, H.real_name, null, mrace, features) - - if(prob(50 - efficiency*10)) //Chance to give a bad mutation. - H.randmutb() //100% bad mutation. Can be cured with mutadone. + H.randmutb() //100% bad mutation. Can be cured with mutadone. H.silent = 20 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment. occupant = H diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 3c021d0bd1..7439fd1b8b 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -11,7 +11,6 @@ var/obj/structure/table/optable/table var/list/advanced_surgeries = list() var/datum/techweb/linked_techweb - var/menu = MENU_OPERATION light_color = LIGHT_COLOR_BLUE /obj/machinery/computer/operating/Initialize() @@ -54,8 +53,6 @@ var/list/data = list() data["table"] = table if(table) - data["menu"] = menu - var/list/surgeries = list() for(var/X in advanced_surgeries) var/datum/surgery/S = X @@ -64,9 +61,8 @@ surgery["desc"] = initial(S.desc) surgeries += list(surgery) data["surgeries"] = surgeries - - data["patient"] = list() if(table.check_patient()) + data["patient"] = list() patient = table.patient switch(patient.stat) if(CONSCIOUS) @@ -110,15 +106,14 @@ "alternative_step" = alternative_step, "alt_chems_needed" = alt_chems_needed )) + else + data["patient"] = null return data /obj/machinery/computer/operating/ui_act(action, params) if(..()) return switch(action) - if("change_menu") - menu = text2num(params["menu"]) - . = TRUE if("sync") sync_surgeries() . = TRUE diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm index 8ddbd68c7b..6d22f9d6c8 100644 --- a/code/game/machinery/computer/apc_control.dm +++ b/code/game/machinery/computer/apc_control.dm @@ -198,7 +198,7 @@ /obj/machinery/computer/apc_control/proc/log_activity(log_text) var/op_string = operator && !(obj_flags & EMAGGED) ? operator : "\[NULL OPERATOR\]" - LAZYADD(logs, "([STATION_TIME_TIMESTAMP("hh:mm:ss")]) [op_string] [log_text]") + LAZYADD(logs, "([STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]) [op_string] [log_text]") /mob/proc/using_power_flow_console() for(var/obj/machinery/computer/apc_control/A in range(1, src)) diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index f9d2a3c103..d6ce850da8 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -91,6 +91,8 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) icon_screen = "tank" icon_keyboard = "atmos_key" circuit = /obj/item/circuitboard/computer/atmos_control + ui_x = 400 + ui_y = 925 var/frequency = FREQ_ATMOS_STORAGE var/list/sensors = list( @@ -125,7 +127,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_control", name, 400, 925, master_ui, state) + ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/atmos_control/ui_data(mob/user) @@ -161,6 +163,20 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) frequency = new_frequency radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) +//Incinerator sensor only +/obj/machinery/computer/atmos_control/incinerator + name = "Incinerator Air Control" + sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber") + ui_x = 400 + ui_y = 300 + +//Toxins mix sensor only +/obj/machinery/computer/atmos_control/toxinsmix + name = "Toxins Mixing Air Control" + sensors = list(ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB = "Toxins Mixing Chamber") + ui_x = 400 + ui_y = 300 + ///////////////////////////////////////////////////////////// // LARGE TANK CONTROL ///////////////////////////////////////////////////////////// @@ -174,6 +190,9 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) var/list/input_info var/list/output_info + ui_x = 500 + ui_y = 315 + /obj/machinery/computer/atmos_control/tank/oxygen_tank name = "Oxygen Supply Control" input_tag = ATMOS_GAS_MONITOR_INPUT_O2 @@ -216,12 +235,6 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) output_tag = ATMOS_GAS_MONITOR_OUTPUT_CO2 sensors = list(ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank") -/obj/machinery/computer/atmos_control/tank/incinerator - name = "Incinerator Air Control" - input_tag = ATMOS_GAS_MONITOR_INPUT_INCINERATOR - output_tag = ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR - sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber") - // This hacky madness is the evidence of the fact that a lot of machines were never meant to be constructable, im so sorry you had to see this /obj/machinery/computer/atmos_control/tank/proc/reconnect(mob/user) var/list/IO = list() @@ -235,7 +248,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) IO |= text[1] if(!IO.len) to_chat(user, "No machinery detected.") - var/S = input("Select the device set: ", "Selection", IO[1]) as anything in IO + var/S = input("Select the device set: ", "Selection", IO[1]) as anything in sortList(IO) if(src) src.input_tag = "[S]_in" src.output_tag = "[S]_out" @@ -256,7 +269,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_control", name, 500, 305, master_ui, state) + ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/atmos_control/tank/ui_data(mob/user) @@ -280,13 +293,19 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) if("input") signal.data += list("tag" = input_tag, "power_toggle" = TRUE) . = TRUE + if("rate") + var/target = text2num(params["rate"]) + if(!isnull(target)) + target = CLAMP(target, 0, MAX_TRANSFER_RATE) + signal.data += list("tag" = input_tag, "set_volume_rate" = target) + . = TRUE if("output") signal.data += list("tag" = output_tag, "power_toggle" = TRUE) . = TRUE if("pressure") - var/target = input("New target pressure:", name, output_info ? output_info["internal"] : 0) as num|null - if(!isnull(target) && !..()) - target = CLAMP(target, 0, 50 * ONE_ATMOSPHERE) + var/target = text2num(params["pressure"]) + if(!isnull(target)) + target = CLAMP(target, 0, MAX_OUTPUT_PRESSURE) signal.data += list("tag" = output_tag, "set_internal_pressure" = target) . = TRUE radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 90969bf4a1..4d21ae77b0 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -482,7 +482,7 @@ R.fields["ckey"] = mob_occupant.ckey R.fields["name"] = mob_occupant.real_name - R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6) + R.fields["id"] = copytext_char(md5(mob_occupant.real_name), 2, 6) R.fields["UE"] = dna.unique_enzymes R.fields["UI"] = dna.uni_identity R.fields["SE"] = dna.struc_enzymes diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 1bc8a82147..59574bc603 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -443,7 +443,7 @@ var/dat = "" if(SSshuttle.emergency.mode == SHUTTLE_CALL) var/timeleft = SSshuttle.emergency.timeLeft() - dat += "Emergency shuttle\n
\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]" + dat += "Emergency shuttle\n
\nETA: [timeleft / 60 % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]" var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 7330ae26e7..9cf988884f 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -274,13 +274,18 @@ var/max_line_len = 7*DNA_BLOCK_SIZE if(viable_occupant) temp_html += "
1
" - var/len = length(viable_occupant.dna.uni_identity) - for(var/i=1, i<=len, i++) - temp_html += "[copytext(viable_occupant.dna.uni_identity,i,i+1)]" - if ((i % max_line_len) == 0) + var/char = "" + var/ui_text = viable_occupant.dna.uni_identity + var/len_byte = length(ui_text) + var/char_it = 0 + for(var/byte_it = 1, byte_it <= len_byte, byte_it += length(char)) + char_it++ + char = ui_text[byte_it] + temp_html += "[char]" + if((char_it % max_line_len) == 0) temp_html += "
" - if((i % DNA_BLOCK_SIZE) == 0 && i < len) - temp_html += "
[(i / DNA_BLOCK_SIZE) + 1]
" + if((char_it % DNA_BLOCK_SIZE) == 0 && byte_it < len_byte) + temp_html += "
[(char_it / DNA_BLOCK_SIZE) + 1]
" else temp_html += "----" temp_html += "

" @@ -288,13 +293,16 @@ temp_html += "
Structural Enzymes:
" if(viable_occupant) temp_html += "
1
" - var/len = length(viable_occupant.dna.struc_enzymes) - for(var/i=1, i<=len, i++) - temp_html += "[copytext(viable_occupant.dna.struc_enzymes,i,i+1)]" - if ((i % max_line_len) == 0) + var/char = "" + var/ui_text = viable_occupant.dna.uni_identity + var/len_byte = length(ui_text) + var/char_it = 0 + for(var/byte_it = 1, byte_it <= len_byte, byte_it += length(char)) + temp_html += "[char]" + if((char_it % max_line_len) == 0) temp_html += "
" - if((i % DNA_BLOCK_SIZE) == 0 && i < len) - temp_html += "
[(i / DNA_BLOCK_SIZE) + 1]
" + if((char_it % DNA_BLOCK_SIZE) == 0 && byte_it < len_byte) + temp_html += "
[(char_it / DNA_BLOCK_SIZE) + 1]
" else temp_html += "----" temp_html += "
" @@ -465,7 +473,7 @@ viable_occupant.radiation += (RADIATION_IRRADIATION_MULTIPLIER*radduration*radstrength)/(connected.damage_coeff ** 2) //Read comment in "transferbuffer" section above for explanation switch(href_list["task"]) //Same thing as there but values are even lower, on best part they are about 0.0*, effectively no damage if("pulseui") - var/len = length(viable_occupant.dna.uni_identity) + var/len = length_char(viable_occupant.dna.uni_identity) num = WRAP(num, 1, len+1) num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2 //Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low @@ -473,12 +481,12 @@ var/subblock = num - block*DNA_BLOCK_SIZE last_change = "UI #[block]-[subblock]; " - var/hex = copytext(viable_occupant.dna.uni_identity, num, num+1) + var/hex = copytext_char(viable_occupant.dna.uni_identity, num, num+1) last_change += "[hex]" hex = scramble(hex, radstrength, radduration) last_change += "->[hex]" - viable_occupant.dna.uni_identity = copytext(viable_occupant.dna.uni_identity, 1, num) + hex + copytext(viable_occupant.dna.uni_identity, num+1, 0) + viable_occupant.dna.uni_identity = copytext_char(viable_occupant.dna.uni_identity, 1, num) + hex + copytext_char(viable_occupant.dna.uni_identity, num + 1) viable_occupant.updateappearance(mutations_overlay_update=1) if("pulsese") var/len = length(viable_occupant.dna.struc_enzymes) @@ -489,12 +497,12 @@ var/subblock = num - block*DNA_BLOCK_SIZE last_change = "SE #[block]-[subblock]; " - var/hex = copytext(viable_occupant.dna.struc_enzymes, num, num+1) + var/hex = copytext_char(viable_occupant.dna.struc_enzymes, num, num+1) last_change += "[hex]" hex = scramble(hex, radstrength, radduration) last_change += "->[hex]" - viable_occupant.dna.struc_enzymes = copytext(viable_occupant.dna.struc_enzymes, 1, num) + hex + copytext(viable_occupant.dna.struc_enzymes, num+1, 0) + viable_occupant.dna.struc_enzymes = copytext_char(viable_occupant.dna.struc_enzymes, 1, num) + hex + copytext_char(viable_occupant.dna.struc_enzymes, num + 1) viable_occupant.domutcheck() else current_screen = "mainmenu" diff --git a/code/game/machinery/computer/launchpad_control.dm b/code/game/machinery/computer/launchpad_control.dm index b5d393bce0..1924cd9f23 100644 --- a/code/game/machinery/computer/launchpad_control.dm +++ b/code/game/machinery/computer/launchpad_control.dm @@ -1,11 +1,13 @@ /obj/machinery/computer/launchpad - name = "\improper launchpad control console" + name = "launchpad control console" desc = "Used to teleport objects to and from a launchpad." icon_screen = "teleport" icon_keyboard = "teleport_key" circuit = /obj/item/circuitboard/computer/launchpad_console - var/sending = TRUE - var/current_pad //current pad viewed on the screen + ui_x = 475 + ui_y = 260 + + var/selected_id var/list/obj/machinery/launchpad/launchpads var/maximum_pads = 4 @@ -18,7 +20,9 @@ return /obj/machinery/computer/launchpad/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/multitool)) + if(W.tool_behaviour == TOOL_MULTITOOL) + if(!multitool_check_buffer(user, W)) + return var/obj/item/multitool/M = W if(M.buffer && istype(M.buffer, /obj/machinery/launchpad)) if(LAZYLEN(launchpads) < maximum_pads) @@ -36,55 +40,7 @@ return FALSE return TRUE -/obj/machinery/computer/launchpad/proc/get_pad(number) - var/obj/machinery/launchpad/pad = launchpads[number] - return pad - -/obj/machinery/computer/launchpad/ui_interact(mob/user) - . = ..() - var/list/t = list() - if(!LAZYLEN(launchpads)) - obj_flags &= ~IN_USE //Yeah so if you deconstruct teleporter while its in the process of shooting it wont disable the console - t += "
No launchpad located.

" - else - for(var/i in 1 to LAZYLEN(launchpads)) - if(pad_exists(i)) - var/obj/machinery/launchpad/pad = get_pad(i) - if(pad.stat & NOPOWER) - t+= "[pad.display_name]" - else - t+= "[pad.display_name]" - else - launchpads -= get_pad(i) - t += "
" - - if(current_pad) - var/obj/machinery/launchpad/pad = get_pad(current_pad) - t += "
[pad.display_name]
" - t += "Rename" - t += "Remove

" - t += "O" //up-left - t += "^" //up - t += "O
" //up-right - t += "<"//left - t += "R"//reset to 0 - t += ">
"//right - t += "O"//down-left - t += "v"//down - t += "O
"//down-right - t += "
" - t += "
Current offset:

" - t += "
[abs(pad.y_offset)] [pad.y_offset > 0 ? "N":"S"] \[SET\]

" - t += "
[abs(pad.x_offset)] [pad.x_offset > 0 ? "E":"W"] \[SET\]

" - - t += "
Launch" - t += " Pull" - - var/datum/browser/popup = new(user, "launchpad", name, 300, 500) - popup.set_content(t.Join()) - popup.open() - -/obj/machinery/computer/launchpad/proc/teleport(mob/user, obj/machinery/launchpad/pad) +/obj/machinery/computer/launchpad/proc/teleport(mob/user, obj/machinery/launchpad/pad, sending) if(QDELETED(pad)) to_chat(user, "ERROR: Launchpad not responding. Check launchpad integrity.") return @@ -93,66 +49,83 @@ return pad.doteleport(user, sending) -/obj/machinery/computer/launchpad/Topic(href, href_list) - var/obj/machinery/launchpad/pad - if(href_list["pad"]) - pad = get_pad(text2num(href_list["pad"])) +/obj/machinery/computer/launchpad/proc/get_pad(number) + var/obj/machinery/launchpad/pad = launchpads[number] + return pad +/obj/machinery/computer/launchpad/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "launchpad_console", name, ui_x, ui_y, master_ui, state) + ui.open() + +/obj/machinery/computer/launchpad/ui_data(mob/user) + var/list/data = list() + var/list/pad_list = list() + for(var/i in 1 to LAZYLEN(launchpads)) + if(pad_exists(i)) + var/obj/machinery/launchpad/pad = get_pad(i) + var/list/this_pad = list() + this_pad["name"] = pad.display_name + this_pad["id"] = i + if(pad.stat & NOPOWER) + this_pad["inactive"] = TRUE + pad_list += list(this_pad) + else + launchpads -= get_pad(i) + data["launchpads"] = pad_list + data["selected_id"] = selected_id + if(selected_id) + var/obj/machinery/launchpad/current_pad = launchpads[selected_id] + data["x"] = current_pad.x_offset + data["y"] = current_pad.y_offset + data["pad_name"] = current_pad.display_name + data["range"] = current_pad.range + data["selected_pad"] = current_pad + if(QDELETED(current_pad) || (current_pad.stat & NOPOWER)) + data["pad_active"] = FALSE + return data + data["pad_active"] = TRUE + + return data + +/obj/machinery/computer/launchpad/ui_act(action, params) if(..()) return - if(!LAZYLEN(launchpads)) - updateDialog() - return + var/obj/machinery/launchpad/current_pad = launchpads[selected_id] + switch(action) + if("select_pad") + selected_id = text2num(params["id"]) + . = TRUE + if("set_pos") + var/new_x = text2num(params["x"]) + var/new_y = text2num(params["y"]) + current_pad.set_offset(new_x, new_y) + . = TRUE + if("move_pos") + var/plus_x = text2num(params["x"]) + var/plus_y = text2num(params["y"]) + current_pad.set_offset( + x = current_pad.x_offset + plus_x, + y = current_pad.y_offset + plus_y + ) + . = TRUE + if("rename") + . = TRUE + var/new_name = params["name"] + if(!new_name) + return + current_pad.display_name = new_name + if("remove") + if(usr && alert(usr, "Are you sure?", "Unlink Launchpad", "I'm Sure", "Abort") != "Abort") + launchpads -= current_pad + selected_id = null + . = TRUE + if("launch") + teleport(usr, current_pad, TRUE) + . = TRUE - if(href_list["choose_pad"]) - current_pad = text2num(href_list["pad"]) - - if(href_list["raisex"]) - if(pad.x_offset < pad.range) - pad.x_offset++ - - if(href_list["lowerx"]) - if(pad.x_offset > (pad.range * -1)) - pad.x_offset-- - - if(href_list["raisey"]) - if(pad.y_offset < pad.range) - pad.y_offset++ - - if(href_list["lowery"]) - if(pad.y_offset > (pad.range * -1)) - pad.y_offset-- - - if(href_list["reset"]) - pad.y_offset = 0 - pad.x_offset = 0 - - if(href_list["change_name"]) - var/new_name = stripped_input(usr, "What do you wish to name the launchpad?", "Launchpad", pad.display_name, 15) - if(!new_name) - return - pad.display_name = new_name - - if(href_list["setx"]) - var/newx = input(usr, "Input new x offset", pad.display_name, pad.x_offset) as null|num - if(!isnull(newx)) - pad.x_offset = CLAMP(newx, -pad.range, pad.range) - - if(href_list["sety"]) - var/newy = input(usr, "Input new y offset", pad.display_name, pad.y_offset) as null|num - if(!isnull(newy)) - pad.y_offset = CLAMP(newy, -pad.range, pad.range) - - if(href_list["remove"]) - if(usr && alert(usr, "Are you sure?", "Remove Launchpad", "I'm Sure", "Abort") != "Abort") - launchpads -= pad - - if(href_list["launch"]) - sending = TRUE - teleport(usr, pad) - - if(href_list["pull"]) - sending = FALSE - teleport(usr, pad) - - updateDialog() + if("pull") + teleport(usr, current_pad, FALSE) + . = TRUE + . = TRUE \ No newline at end of file diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 29055e87c3..ecbde43044 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -478,7 +478,7 @@ var/counter = 1 while(active2.fields[text("com_[]", counter)]) counter++ - active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []
[]", authenticated, rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1) + active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []
[]", authenticated, rank, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1) else if(href_list["del_c"]) if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])])) diff --git a/code/game/machinery/computer/prisoner/gulag_teleporter.dm b/code/game/machinery/computer/prisoner/gulag_teleporter.dm index f6e164efe9..e4a6a0b2d4 100644 --- a/code/game/machinery/computer/prisoner/gulag_teleporter.dm +++ b/code/game/machinery/computer/prisoner/gulag_teleporter.dm @@ -6,6 +6,9 @@ icon_keyboard = "security_key" req_access = list(ACCESS_ARMORY) circuit = /obj/item/circuitboard/computer/gulag_teleporter_console + ui_x = 350 + ui_y = 295 + var/default_goal = 200 var/obj/machinery/gulag_teleporter/teleporter = null var/obj/structure/gulag_beacon/beacon = null @@ -22,7 +25,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "gulag_console", name, 455, 440, master_ui, state) + ui = new(user, src, ui_key, "gulag_console", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/prisoner/gulag_teleporter_computer/ui_data(mob/user) @@ -50,13 +53,19 @@ data["teleporter_location"] = "([teleporter.x], [teleporter.y], [teleporter.z])" data["teleporter_lock"] = teleporter.locked data["teleporter_state_open"] = teleporter.state_open + else + data["teleporter"] = null if(beacon) data["beacon"] = beacon data["beacon_location"] = "([beacon.x], [beacon.y], [beacon.z])" + else + data["beacon"] = null if(contained_id) data["id"] = contained_id data["id_name"] = contained_id.registered_name data["goal"] = contained_id.goal + else + data["id"] = null data["can_teleport"] = can_teleport return data @@ -72,36 +81,41 @@ switch(action) if("scan_teleporter") teleporter = findteleporter() + return TRUE if("scan_beacon") beacon = findbeacon() + return TRUE if("handle_id") if(contained_id) id_eject(usr) else id_insert(usr) + return TRUE if("set_goal") - var/new_goal = input("Set the amount of points:", "Points", contained_id.goal) as num|null + var/new_goal = text2num(params["value"]) if(!isnum(new_goal)) return if(!new_goal) new_goal = default_goal - if (new_goal > 1000) - to_chat(usr, "The entered amount of points is too large. Points have instead been set to the maximum allowed amount.") contained_id.goal = CLAMP(new_goal, 0, 1000) //maximum 1000 points + return TRUE if("toggle_open") if(teleporter.locked) - to_chat(usr, "The teleporter is locked") + to_chat(usr, "The teleporter must be unlocked first.") return teleporter.toggle_open() + return TRUE if("teleporter_lock") if(teleporter.state_open) - to_chat(usr, "Close the teleporter before locking!") + to_chat(usr, "The teleporter must be closed first.") return teleporter.locked = !teleporter.locked + return TRUE if("teleport") if(!teleporter || !beacon) return addtimer(CALLBACK(src, .proc/teleport, usr), 5) + return TRUE /obj/machinery/computer/prisoner/gulag_teleporter_computer/proc/scan_machinery() teleporter = findteleporter() @@ -129,12 +143,12 @@ say("[contained_id]'s ID card goal defaulting to [contained_id.goal] points.") log_game("[key_name(user)] teleported [key_name(prisoner)] to the Labor Camp [COORD(beacon)] for [id_goal_not_set ? "default goal of ":""][contained_id.goal] points.") teleporter.handle_prisoner(contained_id, temporary_record) - playsound(src, 'sound/weapons/emitter.ogg', 50, 1) + playsound(src, 'sound/weapons/emitter.ogg', 50, TRUE) prisoner.forceMove(get_turf(beacon)) prisoner.Stun(40) // small travel dizziness to_chat(prisoner, "The teleportation makes you a little dizzy.") new /obj/effect/particle_effect/sparks(get_turf(prisoner)) - playsound(src, "sparks", 50, 1) + playsound(src, "sparks", 50, TRUE) if(teleporter.locked) teleporter.locked = FALSE teleporter.toggle_open() diff --git a/code/game/machinery/computer/prisoner/management.dm b/code/game/machinery/computer/prisoner/management.dm index 653f6bf48b..496e14b8f1 100644 --- a/code/game/machinery/computer/prisoner/management.dm +++ b/code/game/machinery/computer/prisoner/management.dm @@ -125,7 +125,7 @@ to_chat(usr, "Unauthorized access.") else if(href_list["warn"]) - var/warning = copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN) + var/warning = stripped_input(usr, "Message:", "Enter your message here!", "", MAX_MESSAGE_LEN) if(!warning) return var/obj/item/implant/I = locate(href_list["warn"]) in GLOB.tracked_implants diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index aabb1fe408..42e31b2ea6 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -456,7 +456,7 @@ What a mess.*/ var/counter = 1 while(active2.fields[text("com_[]", counter)]) counter++ - active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []
[]", src.authenticated, src.rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1) + active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []
[]", src.authenticated, src.rank, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1) if("Delete Record (ALL)") if(active1) @@ -544,7 +544,7 @@ What a mess.*/ switch(href_list["field"]) if("name") if(istype(active1, /datum/data/record) || istype(active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please input name:", "Secure. records", active1.fields["name"], null) as text),1,MAX_MESSAGE_LEN) + var/t1 = stripped_input(usr, "Please input name:", "Secure. records", active1.fields["name"], MAX_MESSAGE_LEN) if(!canUseSecurityRecordsConsole(usr, t1, a1)) return if(istype(active1, /datum/data/record)) @@ -636,7 +636,7 @@ What a mess.*/ var/t2 = stripped_input(usr, "Please input minor crime details:", "Secure. records", "", null) if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) return - var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss")) + var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)) GLOB.data_core.addMinorCrime(active1.fields["id"], crime) investigate_log("New Minor Crime: [t1]: [t2] | Added to [active1.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) if("mi_crim_delete") @@ -651,7 +651,7 @@ What a mess.*/ var/t2 = stripped_input(usr, "Please input major crime details:", "Secure. records", "", null) if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) return - var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss")) + var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)) GLOB.data_core.addMajorCrime(active1.fields["id"], crime) investigate_log("New Major Crime: [t1]: [t2] | Added to [active1.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) if("ma_crim_delete") diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 1b700fdf36..c3fef3ff92 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -20,17 +20,18 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "station_alert", name, 300, 500, master_ui, state) + ui = new(user, src, ui_key, "station_alert", name, 325, 500, master_ui, state) ui.open() /obj/machinery/computer/station_alert/ui_data(mob/user) - . = list() + var/list/data = list() - .["alarms"] = list() + data["alarms"] = list() for(var/class in alarms) - .["alarms"][class] = list() + data["alarms"][class] = list() for(var/area in alarms[class]) - .["alarms"][class] += area + data["alarms"][class] += area + return data /obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source) if(source.z != z) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 768faa8301..72c8979006 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -136,7 +136,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E var/list/transferlog = list() /obj/machinery/computer/telecrystals/boss/proc/logTransfer(logmessage) - transferlog += ("[STATION_TIME_TIMESTAMP("hh:mm:ss")] [logmessage]") + transferlog += ("[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)] [logmessage]") /obj/machinery/computer/telecrystals/boss/proc/scanUplinkers() for(var/obj/machinery/computer/telecrystals/uplinker/A in urange(scanrange, src.loc)) diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm index 21fb70c38c..518f38fc35 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -5,6 +5,8 @@ icon_keyboard = "teleport_key" light_color = LIGHT_COLOR_BLUE circuit = /obj/item/circuitboard/computer/teleporter + ui_x = 475 + ui_y = 130 var/regime_set = "Teleporter" var/id var/obj/machinery/teleport/station/power_station @@ -32,34 +34,30 @@ break return power_station -/obj/machinery/computer/teleporter/ui_interact(mob/user) - . = ..() - var/data = "

Teleporter Status

" - if(!power_station) - data += "
No power station linked.
" - else if(!power_station.teleporter_hub) - data += "
No hub linked.
" +obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "teleporter", name, ui_x, ui_y, master_ui, state) + ui.open() + +/obj/machinery/computer/teleporter/ui_data(mob/user) + var/list/data = list() + data["power_station"] = power_station ? TRUE : FALSE + data["teleporter_hub"] = power_station?.teleporter_hub ? TRUE : FALSE + data["regime_set"] = regime_set + data["target"] = !target ? "None" : "[get_area(target)] [(regime_set != "Gate") ? "" : "Teleporter"]" + data["calibrating"] = calibrating + + if(power_station?.teleporter_hub?.calibrated || power_station?.teleporter_hub?.accuracy >= 3) + data["calibrated"] = TRUE else - data += "
Current regime: [regime_set]
" - data += "Current target: [(!target) ? "None" : "[get_area(target)] [(regime_set != "Gate") ? "" : "Teleporter"]"]
" - if(calibrating) - data += "Calibration: In Progress" - else if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3) - data += "Calibration: Optimal" - else - data += "Calibration: Sub-Optimal" - data += "

" + data["calibrated"] = FALSE - data += "Change regime
" - data += "Set target
" + return data - data += "
Calibrate Hub" - var/datum/browser/popup = new(user, "teleporter", name, 400, 400) - popup.set_content(data) - popup.open() - -/obj/machinery/computer/teleporter/Topic(href, href_list) +/obj/machinery/computer/teleporter/ui_act(action, params) if(..()) return @@ -70,38 +68,39 @@ say("Error: Calibration in progress. Stand by.") return - if(href_list["regimeset"]) - power_station.engaged = 0 - power_station.teleporter_hub.update_icon() - power_station.teleporter_hub.calibrated = 0 - reset_regime() - if(href_list["settarget"]) - power_station.engaged = 0 - power_station.teleporter_hub.update_icon() - power_station.teleporter_hub.calibrated = 0 - set_target(usr) - if(href_list["calibrate"]) - if(!target) - say("Error: No target set to calibrate to.") - return - if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3) - say("Hub is already calibrated!") - return - say("Processing hub calibration to target...") + switch(action) + if("regimeset") + power_station.engaged = FALSE + power_station.teleporter_hub.update_icon() + power_station.teleporter_hub.calibrated = FALSE + reset_regime() + . = TRUE + if("settarget") + power_station.engaged = FALSE + power_station.teleporter_hub.update_icon() + power_station.teleporter_hub.calibrated = FALSE + set_target(usr) + . = TRUE + if("calibrate") + if(!target) + say("Error: No target set to calibrate to.") + return + if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accuracy >= 3) + say("Hub is already calibrated!") + return - calibrating = 1 - power_station.update_icon() - spawn(50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration - calibrating = 0 - if(check_hub_connection()) - power_station.teleporter_hub.calibrated = 1 - say("Calibration complete.") - else - say("Error: Unable to detect hub.") + say("Processing hub calibration to target...") + calibrating = TRUE power_station.update_icon() - updateDialog() - - updateDialog() + spawn(50 * (3 - power_station.teleporter_hub.accuracy)) //Better parts mean faster calibration + calibrating = FALSE + if(check_hub_connection()) + power_station.teleporter_hub.calibrated = TRUE + say("Calibration complete.") + else + say("Error: Unable to detect hub.") + power_station.update_icon() + . = TRUE /obj/machinery/computer/teleporter/proc/check_hub_connection() if(!power_station) diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 96487915dd..b007bc0161 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -119,6 +119,9 @@ if(istype(P, /obj/item/circuitboard/machine)) var/obj/item/circuitboard/machine/B = P + if(!B.build_path) + to_chat(user, "This circuitboard seems to be broken.") + return if(!anchored && B.needs_anchored) to_chat(user, "The frame needs to be secured first!") return @@ -181,6 +184,9 @@ if(component_check) P.play_tool_sound(src) var/obj/machinery/new_machine = new circuit.build_path(loc) + if(new_machine.circuit) + QDEL_NULL(new_machine.circuit) + new_machine.circuit = circuit new_machine.setAnchored(anchored) new_machine.on_construction() for(var/obj/O in new_machine.component_parts) @@ -189,9 +195,6 @@ for(var/obj/O in src) O.moveToNullspace() new_machine.component_parts += O - if(new_machine.circuit) - QDEL_NULL(new_machine.circuit) - new_machine.circuit = circuit circuit.moveToNullspace() new_machine.RefreshParts() qdel(src) diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index 91306585b8..c6b4f2fcf5 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -406,12 +406,11 @@ lying_prev = 0 /obj/machinery/jukebox/proc/dance_over() - SSjukeboxes.removejukebox(SSjukeboxes.findjukeboxindex(src)) + var/position = SSjukeboxes.findjukeboxindex(src) + if(!position) + return + SSjukeboxes.removejukebox(position) STOP_PROCESSING(SSobj, src) - for(var/mob/living/L in rangers) - if(!L || !L.client) - continue - L.stop_sound_channel(CHANNEL_JUKEBOX) rangers = list() /obj/machinery/jukebox/disco/dance_over() diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index f62dceff6c..cff2e361bd 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -27,6 +27,13 @@ for(var/obj/item/stock_parts/micro_laser/P in component_parts) damage_coeff = P.rating +/obj/machinery/dna_scannernew/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Radiation pulse accuracy increased by factor [precision_coeff**2].
Radiation pulse damage decreased by factor [damage_coeff**2].
" + if(scan_level >= 3) + . += "Scanner has been upgraded to support autoprocessing." + /obj/machinery/dna_scannernew/update_icon() //no power or maintenance diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 3e88223037..f28d520114 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1434,7 +1434,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "ai_airlock", name, 550, 456, master_ui, state) + ui = new(user, src, ui_key, "ai_airlock", name, 500, 390, master_ui, state) ui.open() return TRUE @@ -1503,83 +1503,24 @@ if("shock-perm") shock_perm(usr) . = TRUE - if("idscan-on") - if(wires.is_cut(WIRE_IDSCAN)) - to_chat(usr, "You can't enable IdScan - The IdScan wire has been cut.") - else if(src.aiDisabledIdScanner) - aiDisabledIdScanner = FALSE - else - to_chat(usr, "The IdScan feature is not disabled.") + if("idscan-toggle") + aiDisabledIdScanner = !aiDisabledIdScanner . = TRUE - if("idscan-off") - if(wires.is_cut(WIRE_IDSCAN)) - to_chat(usr, "The IdScan wire has been cut - So, you can't disable it, but it is already disabled anyways.") - else if(aiDisabledIdScanner) - to_chat(usr, "You've already disabled the IdScan feature.") - else - aiDisabledIdScanner = TRUE + if("emergency-toggle") + toggle_emergency(usr) . = TRUE - if("emergency-on") - emergency_on(usr) + if("bolt-toggle") + toggle_bolt(usr) . = TRUE - if("emergency-off") - emergency_off(usr) + if("light-toggle") + lights = !lights + update_icon() . = TRUE - if("bolt-raise") - bolt_raise(usr) + if("safe-toggle") + safe = !safe . = TRUE - if("bolt-drop") - bolt_drop(usr) - . = TRUE - if("light-on") - if(wires.is_cut(WIRE_LIGHT)) - to_chat(usr, "Control to door bolt lights has been severed.") - else if (!src.lights) - lights = TRUE - update_icon() - else - to_chat(usr, text("Door bolt lights are already enabled!")) - . = TRUE - if("light-off") - if(wires.is_cut(WIRE_LIGHT)) - to_chat(usr, "Control to door bolt lights has been severed.") - else if (lights) - lights = FALSE - update_icon() - else - to_chat(usr, "Door bolt lights are already disabled!") - . = TRUE - if("safe-on") - if(wires.is_cut(WIRE_SAFETY)) - to_chat(usr, "Control to door sensors is disabled.") - else if (!src.safe) - safe = TRUE - else - to_chat(usr, "Firmware reports safeties already in place.") - . = TRUE - if("safe-off") - if(wires.is_cut(WIRE_SAFETY)) - to_chat(usr, "Control to door sensors is disabled.") - else if (safe) - safe = FALSE - else - to_chat(usr, "Firmware reports safeties already overridden.") - . = TRUE - if("speed-on") - if(wires.is_cut(WIRE_TIMING)) - to_chat(usr, "Control to door timing circuitry has been severed.") - else if (!src.normalspeed) - normalspeed = 1 - else - to_chat(usr,"Door timing circuitry currently operating normally.") - . = TRUE - if("speed-off") - if(wires.is_cut(WIRE_TIMING)) - to_chat(usr, "Control to door timing circuitry has been severed.") - else if (normalspeed) - normalspeed = 0 - else - to_chat(usr, "Door timing circuitry already accelerated.") + if("speed-toggle") + normalspeed = !normalspeed . = TRUE if("open-close") @@ -1617,45 +1558,26 @@ log_combat(user, src, "electrified") set_electrified(ELECTRIFIED_PERMANENT) -/obj/machinery/door/airlock/proc/emergency_on(mob/user) - if(!user_allowed(user)) - return - if (!emergency) - emergency = TRUE - update_icon() - else - to_chat(user, "Emergency access is already enabled!") - -/obj/machinery/door/airlock/proc/emergency_off(mob/user) - if(!user_allowed(user)) - return - if (emergency) - emergency = FALSE - update_icon() - else - to_chat(user, "Emergency access is already disabled!") - -/obj/machinery/door/airlock/proc/bolt_raise(mob/user) +/obj/machinery/door/airlock/proc/toggle_bolt(mob/user) if(!user_allowed(user)) return if(wires.is_cut(WIRE_BOLTS)) - to_chat(user, "The door bolt drop wire is cut - you can't raise the door bolts") - else if(!src.locked) - to_chat(user, "The door bolts are already up") - else - if(src.hasPower()) - unbolt() + to_chat(user, "The door bolt drop wire is cut - you can't toggle the door bolts.") + return + if(locked) + if(!hasPower()) + to_chat(user, "The door has no power - you can't raise the door bolts.") else - to_chat(user, "Cannot raise door bolts due to power failure") - -/obj/machinery/door/airlock/proc/bolt_drop(mob/user) - if(!user_allowed(user)) - return - if(wires.is_cut(WIRE_BOLTS)) - to_chat(user, "You can't drop the door bolts - The door bolt dropping wire has been cut.") + unbolt() else bolt() +/obj/machinery/door/airlock/proc/toggle_emergency(mob/user) + if(!user_allowed(user)) + return + emergency = !emergency + update_icon() + /obj/machinery/door/airlock/proc/user_toggle_open(mob/user) if(!user_allowed(user)) return diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index 54774a8f99..7b90715f2b 100644 --- a/code/game/machinery/doors/airlock_electronics.dm +++ b/code/game/machinery/doors/airlock_electronics.dm @@ -14,7 +14,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "airlock_electronics", name, 975, 420, master_ui, state) + ui = new(user, src, ui_key, "airlock_electronics", name, 420, 485, master_ui, state) ui.open() /obj/item/electronics/airlock/ui_data() @@ -43,13 +43,16 @@ if(..()) return switch(action) - if("clear") + if("clear_all") accesses = list() one_access = 0 . = TRUE if("one_access") one_access = !one_access . = TRUE + if("grant_all") + accesses = get_all_accesses() + . = TRUE if("set") var/access = text2num(params["access"]) if (!(access in accesses)) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index beaf47d0a3..3bfcececda 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -149,7 +149,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "brig_timer", name, 300, 200, master_ui, state) + ui = new(user, src, ui_key, "brig_timer", name, 300, 138, master_ui, state) ui.open() //icon update function @@ -168,7 +168,7 @@ if(timing) var/disp1 = id var/time_left = time_left(seconds = TRUE) - var/disp2 = "[add_zero(num2text((time_left / 60) % 60),2)]~[add_zero(num2text(time_left % 60), 2)]" + var/disp2 = "[add_leading(num2text((time_left / 60) % 60), 2, "0")]:[add_leading(num2text(time_left % 60), 2, "0")]" if(length(disp2) > CHARS_PER_LINE) disp2 = "Error" update_display(disp1, disp2) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 2e43670624..9db98b8314 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -5,6 +5,7 @@ icon_state = "door1" opacity = 1 density = TRUE + move_resist = MOVE_FORCE_VERY_STRONG layer = OPEN_DOOR_LAYER power_channel = ENVIRON max_integrity = 350 @@ -287,9 +288,10 @@ return operating = TRUE - do_animate("closing") layer = closingLayer + if(!safe) + crush() sleep(5) density = TRUE sleep(5) @@ -301,8 +303,6 @@ update_freelook_sight() if(safe) CheckForMobs() - else - crush() return 1 /obj/machinery/door/proc/CheckForMobs() diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 0429db5792..cb133978b2 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -32,7 +32,7 @@ CalculateAffectingAreas() /obj/machinery/door/firedoor/examine(mob/user) - ..() + . = ..() if(!density) . += "It is open, but could be pried closed." else if(!welded) @@ -44,7 +44,7 @@ /obj/machinery/door/firedoor/proc/CalculateAffectingAreas() remove_from_areas() - affecting_areas = get_adjacent_open_areas(src) | get_area(src) + affecting_areas = get_adjacent_open_areas(src) | get_base_area(src) for(var/I in affecting_areas) var/area/A = I LAZYADD(A.firedoors, src) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 1ef3fc0a74..5555e05eb0 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -44,7 +44,7 @@ pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 update_icon() - myarea = get_area(src) + myarea = get_base_area(src) LAZYADD(myarea.firealarms, src) /obj/machinery/firealarm/Destroy() @@ -124,7 +124,7 @@ if(!is_operational() || (last_alarm+FIREALARM_COOLDOWN > world.time)) return last_alarm = world.time - var/area/A = get_area(src) + var/area/A = get_base_area(src) A.firealert(src) playsound(loc, 'goon/sound/machinery/FireAlarm.ogg', 75) if(user) @@ -133,7 +133,7 @@ /obj/machinery/firealarm/proc/reset(mob/user) if(!is_operational()) return - var/area/A = get_area(src) + var/area/A = get_base_area(src) A.firereset(src) if(user) log_game("[user] reset a fire alarm at [COORD(src)]") @@ -142,7 +142,7 @@ if(buildstage != 2) return ..() add_fingerprint(user) - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(A.fire) reset(user) else @@ -198,7 +198,7 @@ return else if(W.force) //hit and turn it on ..() - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(!A.fire) alarm() return @@ -322,7 +322,7 @@ /obj/machinery/firealarm/partyalarm/reset() if (stat & (NOPOWER|BROKEN)) return - var/area/A = get_area(src) + var/area/A = get_base_area(src) if (!A || !A.party) return A.party = FALSE @@ -331,7 +331,7 @@ /obj/machinery/firealarm/partyalarm/alarm() if (stat & (NOPOWER|BROKEN)) return - var/area/A = get_area(src) + var/area/A = get_base_area(src) if (!A || A.party || A.name == "Space") return A.party = TRUE diff --git a/code/game/machinery/gulag_item_reclaimer.dm b/code/game/machinery/gulag_item_reclaimer.dm index f51c145635..55b1e34022 100644 --- a/code/game/machinery/gulag_item_reclaimer.dm +++ b/code/game/machinery/gulag_item_reclaimer.dm @@ -31,7 +31,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "gulag_item_reclaimer", name, 455, 440, master_ui, state) + ui = new(user, src, ui_key, "gulag_item_reclaimer", name, 300, 400, master_ui, state) ui.open() /obj/machinery/gulag_item_reclaimer/ui_data(mob/user) diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index e1f9824524..40430b37b7 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -129,7 +129,7 @@ /obj/machinery/harvester/proc/end_harvesting() harvesting = FALSE open_machine() - say("Subject has been succesfuly harvested.") + say("Subject has been successfully harvested.") playsound(src, 'sound/machines/microwave/microwave-end.ogg', 100, 0) /obj/machinery/harvester/screwdriver_act(mob/living/user, obj/item/I) @@ -191,4 +191,6 @@ if(state_open) . += "[src] must be closed before harvesting." else if(!harvesting) - . += "Alt-click [src] to start harvesting." \ No newline at end of file + . += "Alt-click [src] to start harvesting." + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Harvest speed at [interval*0.1] seconds per organ." diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 40fc52d6a1..f3e446c686 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -143,6 +143,11 @@ GLOBAL_LIST_EMPTY(network_holopads) holograph_range += 1 * B.rating holo_range = holograph_range +/obj/machinery/holopad/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Current projection range: [holo_range] units." + /obj/machinery/holopad/attackby(obj/item/P, mob/user, params) if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", P)) return diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 5418dcdb97..0f5e51215d 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -16,6 +16,7 @@ var/power_efficiency = 1 var/x_offset = 0 var/y_offset = 0 + var/indicator_icon = "launchpad_target" /obj/machinery/launchpad/RefreshParts() var/E = 0 @@ -23,23 +24,39 @@ E += M.rating*15 range = E +/obj/machinery/launchpad/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Maximum range: [range] units." + /obj/machinery/launchpad/attackby(obj/item/I, mob/user, params) if(stationary) if(default_deconstruction_screwdriver(user, "lpad-idle-o", "lpad-idle", I)) return if(panel_open) - if(istype(I, /obj/item/multitool)) + if(I.tool_behaviour == TOOL_MULTITOOL) + if(!multitool_check_buffer(user, I)) + return var/obj/item/multitool/M = I M.buffer = src to_chat(user, "You save the data in the [I.name]'s buffer.") - return 1 + return TRUE if(default_deconstruction_crowbar(I)) return return ..() +/obj/machinery/launchpad/attack_ghost(mob/dead/observer/ghost) + . = ..() + if(.) + return + var/target_x = x + x_offset + var/target_y = y + y_offset + var/turf/target = locate(target_x, target_y, z) + ghost.forceMove(target) + /obj/machinery/launchpad/proc/isAvailable() if(stat & NOPOWER) return FALSE @@ -47,6 +64,14 @@ return FALSE return TRUE +/obj/machinery/launchpad/proc/set_offset(x, y) + if(teleporting) + return + if(!isnull(x)) + x_offset = CLAMP(x, -range, range) + if(!isnull(y)) + y_offset = CLAMP(y, -range, range) + /obj/machinery/launchpad/proc/doteleport(mob/user, sending) if(teleporting) to_chat(user, "ERROR: Launchpad busy.") @@ -64,12 +89,22 @@ var/area/A = get_area(target) flick(icon_teleport, src) - playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, 1) + + //Change the indicator's icon to show that we're teleporting + if(sending) + indicator_icon = "launchpad_launch" + else + indicator_icon = "launchpad_pull" + + playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, TRUE) teleporting = TRUE sleep(teleport_speed) + //Set the indicator icon back to normal + indicator_icon = "launchpad_target" + if(QDELETED(src) || !isAvailable()) return @@ -86,25 +121,25 @@ source = dest dest = target - playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1) + playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, TRUE) var/first = TRUE for(var/atom/movable/ROI in source) if(ROI == src) continue - // if it's anchored, don't teleport + if(!istype(ROI) || isdead(ROI) || iscameramob(ROI) || istype(ROI, /obj/effect/dummy/phased_mob)) + continue//don't teleport these var/on_chair = "" - if(ROI.anchored) + if(ROI.anchored)// if it's anchored, don't teleport if(isliving(ROI)) var/mob/living/L = ROI if(L.buckled) // TP people on office chairs if(L.buckled.anchored) continue - on_chair = " (on a chair)" else continue - else if(!isobserver(ROI)) + else continue if(!first) log_msg += ", " @@ -153,11 +188,11 @@ var/obj/item/storage/briefcase/launchpad/briefcase /obj/machinery/launchpad/briefcase/Initialize(mapload, briefcase) - . = ..() - if(!briefcase) - log_game("[src] has been spawned without a briefcase.") - return INITIALIZE_HINT_QDEL - src.briefcase = briefcase + . = ..() + if(!briefcase) + log_game("[src] has been spawned without a briefcase.") + return INITIALIZE_HINT_QDEL + src.briefcase = briefcase /obj/machinery/launchpad/briefcase/Destroy() QDEL_NULL(briefcase) @@ -250,7 +285,7 @@ /obj/item/launchpad_remote/ui_interact(mob/user, ui_key = "launchpad_remote", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "launchpad_remote", "Briefcase Launchpad Remote", 550, 400, master_ui, state) //width, height + ui = new(user, src, ui_key, "launchpad_remote", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height ui.set_style("syndicate") ui.open() @@ -265,10 +300,9 @@ return data data["pad_name"] = pad.display_name - data["abs_x"] = abs(pad.x_offset) - data["abs_y"] = abs(pad.y_offset) - data["north_south"] = pad.y_offset > 0 ? "N":"S" - data["east_west"] = pad.x_offset > 0 ? "E":"W" + data["range"] = pad.range + data["x"] = pad.x_offset + data["y"] = pad.y_offset return data /obj/item/launchpad_remote/proc/teleport(mob/user, obj/machinery/launchpad/pad) @@ -284,76 +318,33 @@ if(..()) return switch(action) - if("right") - if(pad.x_offset < pad.range) - pad.x_offset++ + if("set_pos") + var/new_x = text2num(params["x"]) + var/new_y = text2num(params["y"]) + pad.set_offset(new_x, new_y) . = TRUE - - if("left") - if(pad.x_offset > (pad.range * -1)) - pad.x_offset-- + if("move_pos") + var/plus_x = text2num(params["x"]) + var/plus_y = text2num(params["y"]) + pad.set_offset( + x = pad.x_offset + plus_x, + y = pad.y_offset + plus_y + ) . = TRUE - - if("up") - if(pad.y_offset < pad.range) - pad.y_offset++ - . = TRUE - - if("down") - if(pad.y_offset > (pad.range * -1)) - pad.y_offset-- - . = TRUE - - if("up-right") - if(pad.y_offset < pad.range) - pad.y_offset++ - if(pad.x_offset < pad.range) - pad.x_offset++ - . = TRUE - - if("up-left") - if(pad.y_offset < pad.range) - pad.y_offset++ - if(pad.x_offset > (pad.range * -1)) - pad.x_offset-- - . = TRUE - - if("down-right") - if(pad.y_offset > (pad.range * -1)) - pad.y_offset-- - if(pad.x_offset < pad.range) - pad.x_offset++ - . = TRUE - - if("down-left") - if(pad.y_offset > (pad.range * -1)) - pad.y_offset-- - if(pad.x_offset > (pad.range * -1)) - pad.x_offset-- - . = TRUE - - if("reset") - pad.y_offset = 0 - pad.x_offset = 0 - . = TRUE - if("rename") . = TRUE - var/new_name = stripped_input(usr, "How do you want to rename the launchpad?", "Launchpad", pad.display_name, 15) + var/new_name = params["name"] if(!new_name) return pad.display_name = new_name - if("remove") . = TRUE if(usr && alert(usr, "Are you sure?", "Unlink Launchpad", "I'm Sure", "Abort") != "Abort") pad = null - if("launch") sending = TRUE teleport(usr, pad) . = TRUE - if("pull") sending = FALSE teleport(usr, pad) diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index bf9400219b..28afea817b 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -144,7 +144,7 @@ // Set this limb up using the specias name and body zone limb.icon_state = "[selected_category]_[limb.body_zone]" limb.name = "\improper synthetic [selected_category] [parse_zone(limb.body_zone)]" - limb.desc = "A synthetic [selected_category] limb that will morph on its first use in surgery. This one is for the [parse_zone(limb.body_zone)]" + limb.desc = "A synthetic [selected_category] limb that will morph on its first use in surgery. This one is for the [parse_zone(limb.body_zone)]." limb.species_id = selected_category limb.update_icon_dropped() @@ -158,6 +158,11 @@ T -= M.rating*0.2 prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4 +/obj/machinery/limbgrower/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Storing up to [reagents.maximum_volume]u of synthflesh.
Synthflesh consumption at [prod_coeff*100]%." + /obj/machinery/limbgrower/proc/main_win(mob/user) var/dat = "

Limb Grower Menu:


" dat += "Chemical Storage" diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 9a10ede1ac..b010f77cac 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -306,7 +306,7 @@ if(speed <= 0) speed = 1 if("setpath") - var/newpath = copytext(sanitize(input(usr, "Please define a new path!",,path) as text|null),1,MAX_MESSAGE_LEN) + var/newpath = stripped_input(usr, "Please define a new path!", "New Path", path, MAX_MESSAGE_LEN) if(newpath && newpath != "") moving = 0 // stop moving path = newpath @@ -368,13 +368,19 @@ // Generates the rpath variable using the path string, think of this as "string2list" // Doesn't use params2list() because of the akward way it stacks entities rpath = list() // clear rpath - var/maximum_character = min( 50, length(path) ) // chooses the maximum length of the iterator. 50 max length + var/maximum_characters = 50 - for(var/i=1, i<=maximum_character, i++) // iterates through all characters in path + var/lentext = length(path) + var/nextchar = "" + var/charcount = 0 - var/nextchar = copytext(path, i, i+1) // find next character - - if(!(nextchar in list(";", "&", "*", " "))) // if char is a separator, ignore - rpath += copytext(path, i, i+1) // else, add to list + for(var/i = 1, i <= lentext, i += length(nextchar)) // iterates through all characters in path + nextchar = path[i] // find next character + if(nextchar in list(";", "&", "*", " ")) // if char is a separator, ignore + continue + rpath += nextchar // else, add to list // there doesn't HAVE to be separators but it makes paths syntatically visible + charcount++ + if(charcount >= maximum_characters) + break diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 5a567886b8..93c94ae8b6 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -62,7 +62,7 @@ var/index = findtext(e, "=") // format is "key=value" if(index) var/key = copytext(e, 1, index) - var/val = copytext(e, index+1) + var/val = copytext(e, index + length(e[index])) codes[key] = val else codes[e] = "1" @@ -167,7 +167,7 @@ Transponder Codes:
    "} usr.set_machine(src) if(href_list["locedit"]) - var/newloc = copytext(sanitize(input("Enter New Location", "Navigation Beacon", location) as text|null),1,MAX_MESSAGE_LEN) + var/newloc = stripped_input(usr, "Enter New Location", "Navigation Beacon", location, MAX_MESSAGE_LEN) if(newloc) location = newloc updateDialog() diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 6bf9930eec..a9b4461085 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -122,7 +122,7 @@ GLOBAL_LIST_EMPTY(allCasters) var/datum/newscaster/feed_message/newMsg = new /datum/newscaster/feed_message newMsg.author = author newMsg.body = msg - newMsg.time_stamp = "[STATION_TIME_TIMESTAMP("hh:mm:ss")]" + newMsg.time_stamp = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time) newMsg.is_admin_message = adminMessage newMsg.locked = !allow_comments if(picture) @@ -162,7 +162,7 @@ GLOBAL_LIST_EMPTY(allCasters) NEWSCASTER.update_icon() /datum/newscaster/feed_network/proc/save_photo(icon/photo) - var/photo_file = copytext(md5("\icon[photo]"), 1, 6) + var/photo_file = copytext_char(md5("\icon[photo]"), 1, 6) if(!fexists("[GLOB.log_directory]/photos/[photo_file].png")) //Clean up repeated frames var/icon/clean = new /icon() @@ -514,8 +514,6 @@ GLOBAL_LIST_EMPTY(allCasters) scan_user(usr) if(href_list["set_channel_name"]) channel_name = stripped_input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "", MAX_NAME_LEN) - while (findtext(channel_name," ") == 1) - channel_name = copytext(channel_name,2,length(channel_name)+1) updateUsrDialog() else if(href_list["set_channel_lock"]) c_locked = !c_locked @@ -690,13 +688,13 @@ GLOBAL_LIST_EMPTY(allCasters) updateUsrDialog() else if(href_list["new_comment"]) var/datum/newscaster/feed_message/FM = locate(href_list["new_comment"]) - var/cominput = copytext(stripped_input(usr, "Write your message:", "New comment", null),1,141) + var/cominput = copytext_char(stripped_input(usr, "Write your message:", "New comment", null), 140) if(cominput) scan_user(usr) var/datum/newscaster/feed_comment/FC = new/datum/newscaster/feed_comment FC.author = scanned_user FC.body = cominput - FC.time_stamp = STATION_TIME_TIMESTAMP("hh:mm:ss") + FC.time_stamp = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time) FM.comments += FC usr.log_message("(as [scanned_user]) commented on message [FM.returnBody(-1)] -- [FC.body]", LOG_COMMENT) updateUsrDialog() diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index b8c537a4fc..937e3909b0 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -75,8 +75,7 @@ Buildable meters new_layer = PIPING_LAYER_DEFAULT piping_layer = new_layer - pixel_x += (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X - pixel_y += (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y + PIPING_LAYER_SHIFT(src, piping_layer) layer = initial(layer) + ((piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE) /obj/item/pipe/proc/update() @@ -232,5 +231,4 @@ Buildable meters /obj/item/pipe_meter/proc/setAttachLayer(new_layer = PIPING_LAYER_DEFAULT) piping_layer = new_layer - pixel_x = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X - pixel_y = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y + PIPING_LAYER_DOUBLE_SHIFT(src, piping_layer) diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index a581981746..f777c893f8 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -23,6 +23,23 @@ for(var/obj/item/stock_parts/capacitor/C in component_parts) recharge_coeff = C.rating +/obj/machinery/recharger/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(charging) + . += {"\The [src] contains: + - \A [charging]."} + + if(!(stat & (NOPOWER|BROKEN))) + . += "The status display reads:" + . += "- Recharging [recharge_coeff*10]% cell charge per cycle." + if(charging) + var/obj/item/stock_parts/cell/C = charging.get_cell() + . += "- \The [charging]'s cell is at [C.percent()]%." + /obj/machinery/recharger/proc/setCharging(new_charging) charging = new_charging if (new_charging) @@ -53,7 +70,7 @@ //Checks to make sure he's not in space doing it, and that the area got proper power. var/area/a = get_area(src) - if(!isarea(a) || a.power_equip == 0) + if(!a || !a.powered(EQUIP)) to_chat(user, "[src] blinks red as you try to insert [G].") return 1 diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index cd5f7ad6bf..374c0c71b9 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -50,6 +50,13 @@ for(var/obj/item/stock_parts/cell/C in component_parts) recharge_speed *= C.maxcharge / 10000 +/obj/machinery/recharge_station/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Recharging [recharge_speed]J per cycle." + if(repairs) + to_chat(user, "[src] has been upgraded to support automatic repairs.") + /obj/machinery/recharge_station/process() if(!is_operational()) return diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index c879ca73e8..538017eaef 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -41,9 +41,10 @@ /obj/machinery/recycler/examine(mob/user) . = ..() - . += "The power light is [(stat & NOPOWER) ? "off" : "on"]." - . += "The safety-mode light is [safety_mode ? "on" : "off"]." - . += "The safety-sensors status light is [obj_flags & EMAGGED ? "off" : "on"]." + . += "Reclaiming [amount_produced]% of materials salvaged." + . += {"The power light is [(stat & NOPOWER) ? "off" : "on"]. + The safety-mode light is [safety_mode ? "on" : "off"]. + The safety-sensors status light is [obj_flags & EMAGGED ? "off" : "on"]."} /obj/machinery/recycler/power_change() ..() diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index ec5d0343aa..6b191ef14d 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -263,10 +263,9 @@ GLOBAL_LIST_EMPTY(allConsoles) usr.set_machine(src) add_fingerprint(usr) - if(reject_bad_text(href_list["write"])) - dpt = ckey(href_list["write"]) //write contains the string of the receiving department's name - - var/new_message = copytext(reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")),1,MAX_MESSAGE_LEN) + if(href_list["write"]) + dpt = ckey(reject_bad_text(href_list["write"])) //write contains the string of the receiving department's name + var/new_message = stripped_input(usr, "Write your message:", "Awaiting Input", "", MAX_MESSAGE_LEN) if(new_message) message = new_message screen = 9 @@ -282,7 +281,7 @@ GLOBAL_LIST_EMPTY(allConsoles) priority = -1 if(href_list["writeAnnouncement"]) - var/new_message = copytext(reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")),1,MAX_MESSAGE_LEN) + var/new_message = reject_bad_text(stripped_input(usr, "Write your message:", "Awaiting Input", "", MAX_MESSAGE_LEN)) if(new_message) message = new_message if (text2num(href_list["priority"]) < 2) @@ -438,9 +437,8 @@ GLOBAL_LIST_EMPTY(allConsoles) return /obj/machinery/requests_console/say_mod(input, message_mode) - var/ending = copytext(input, length(input) - 2) - if (ending == "!!!") - . = "blares" + if(spantext_char(input, "!", -3)) + return "blares" else . = ..() diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index fc6577a4f1..16016b8e18 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -4,6 +4,7 @@ icon = 'icons/effects/effects.dmi' icon_state = "shield-old" density = TRUE + move_resist = INFINITY opacity = 0 anchored = TRUE resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF @@ -93,6 +94,7 @@ /obj/machinery/shieldgen/proc/shields_up() active = TRUE update_icon() + move_resist = INFINITY for(var/turf/target_tile in range(shield_range, src)) if(isspaceturf(target_tile) && !(locate(/obj/structure/emergency_shield) in target_tile)) @@ -101,6 +103,7 @@ /obj/machinery/shieldgen/proc/shields_down() active = FALSE + move_resist = initial(move_resist) update_icon() QDEL_LIST(deployed_shields) diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 984a911d32..6eca52aa0e 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -52,6 +52,8 @@ . += "The charge meter reads [cell ? round(cell.percent(), 1) : 0]%." else . += "There is no power cell installed." + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Temperature range at [settableTemperatureRange]°C.
    Heating power at [heatingPower*0.001]kJ.
    Power consumption at [(efficiency*-0.0025)+150]%." //100%, 75%, 50%, 25% /obj/machinery/space_heater/update_icon() if(on) diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index a722fcafc3..746c17f225 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -15,7 +15,7 @@ #define SD_AI_EMOTE 1 // 1 = AI emoticon #define SD_AI_BSOD 2 // 2 = Blue screen of death -/// Status display which can show images and scrolling text. +/// Status display which can show images and scrolling text. !!!USE /obj/machinery/status_display/evac NOT THIS!!! /obj/machinery/status_display name = "status display" desc = null @@ -55,14 +55,14 @@ /// Call with no arguments to disable. /obj/machinery/status_display/proc/set_message(m1, m2) if(m1) - index1 = (length(m1) > CHARS_PER_LINE) + index1 = (length_char(m1) > CHARS_PER_LINE) message1 = m1 else message1 = "" index1 = 0 if(m2) - index2 = (length(m2) > CHARS_PER_LINE) + index2 = (length_char(m2) > CHARS_PER_LINE) message2 = m2 else message2 = "" @@ -77,19 +77,19 @@ var/line1 = message1 if(index1) - line1 = copytext("[message1]|[message1]", index1, index1+CHARS_PER_LINE) - var/message1_len = length(message1) + line1 = copytext_char("[message1]|[message1]", index1, index1+CHARS_PER_LINE) + var/message1_len = length_char(message1) index1 += SCROLL_SPEED - if(index1 > message1_len) - index1 -= message1_len + if(index1 > message1_len + 1) + index1 -= (message1_len + 1) var/line2 = message2 if(index2) - line2 = copytext("[message2]|[message2]", index2, index2+CHARS_PER_LINE) + line2 = copytext_char("[message2]|[message2]", index2, index2+CHARS_PER_LINE) var/message2_len = length(message2) index2 += SCROLL_SPEED - if(index2 > message2_len) - index2 -= message2_len + if(index2 > message2_len + 1) + index2 -= (message2_len + 1) update_display(line1, line2) if (!index1 && !index2) @@ -130,7 +130,7 @@ var/line1 = "-[shuttle.getModeStr()]-" var/line2 = shuttle.getTimerStr() - if(length(line2) > CHARS_PER_LINE) + if(length_char(line2) > CHARS_PER_LINE) line2 = "error" update_display(line1, line2) else @@ -242,7 +242,7 @@ else line1 = "CARGO" line2 = SSshuttle.supply.getTimerStr() - if(length(line2) > CHARS_PER_LINE) + if(length_char(line2) > CHARS_PER_LINE) line2 = "Error" update_display(line1, line2) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 670ce91674..3a2ce43315 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -266,7 +266,7 @@ for(var/atom/movable/AM in things_to_clear) //Scorches away blood and forensic evidence, although the SSU itself is unaffected SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG) AM.clean_blood() - AM.fingerprints = list() + AM.fingerprints = null var/datum/component/radioactive/contamination = AM.GetComponent(/datum/component/radioactive) if(contamination) qdel(contamination) @@ -390,14 +390,24 @@ data["uv_super"] = uv_super if(helmet) data["helmet"] = helmet.name + else + data["helmet"] = null if(suit) data["suit"] = suit.name + else + data["suit"] = null if(mask) data["mask"] = mask.name + else + data["mask"] = null if(storage) data["storage"] = storage.name + else + data["storage"] = null if(occupant) - data["occupied"] = 1 + data["occupied"] = TRUE + else + data["occupied"] = FALSE return data /obj/machinery/suit_storage_unit/ui_act(action, params) diff --git a/code/game/machinery/telecomms/broadcasting.dm b/code/game/machinery/telecomms/broadcasting.dm index 0771963b07..4e3e11d1e2 100644 --- a/code/game/machinery/telecomms/broadcasting.dm +++ b/code/game/machinery/telecomms/broadcasting.dm @@ -132,7 +132,7 @@ set waitfor = FALSE // Perform final composition steps on the message. - var/message = copytext(data["message"], 1, MAX_BROADCAST_LEN) + var/message = copytext_char(data["message"], 1, MAX_BROADCAST_LEN) if(!message) return var/compression = data["compression"] diff --git a/code/game/machinery/telecomms/computers/message.dm b/code/game/machinery/telecomms/computers/message.dm index 07028ba2d3..884c2bb37d 100644 --- a/code/game/machinery/telecomms/computers/message.dm +++ b/code/game/machinery/telecomms/computers/message.dm @@ -421,7 +421,7 @@ "name" = "[customsender]", "job" = "[customjob]", "message" = custommessage, - "emoji_message" = emoji_parse(custommessage), + "emojis" = TRUE, "targets" = list("[customrecepient.owner] ([customrecepient.ownjob])") )) // this will log the signal and transmit it to the target diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index 1ad80ccbed..8cd8b479d8 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -179,7 +179,7 @@ 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) + var/newid = reject_bad_text(stripped_input(usr, "Specify the new ID for this machine", src, id, MAX_MESSAGE_LEN)) if(newid && canAccess(usr)) id = newid temp = "-% New ID assigned: \"[id]\" %-" diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm index 0cf356ad3d..1960080856 100644 --- a/code/game/machinery/telecomms/machines/message_server.dm +++ b/code/game/machinery/telecomms/machines/message_server.dm @@ -106,11 +106,10 @@ return "Everyone" return data["targets"][1] -/datum/signal/subspace/pda/proc/format_message(emojify = FALSE) - var/message = emojify ? data["emoji_message"] : data["message"] +/datum/signal/subspace/pda/proc/format_message() if (logged && data["photo"]) - return "\"[message]\" (Photo)" - return "\"[message]\"" + return "\"[data["message"]]\" (Photo)" + return "\"[data["message"]]\"" /datum/signal/subspace/pda/broadcast() if (!logged) // Can only go through if a message server logs it diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index ae71a0b844..3cc71df0f1 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -11,7 +11,7 @@ idle_power_usage = 10 active_power_usage = 2000 circuit = /obj/item/circuitboard/machine/teleporter_hub - var/accurate = FALSE + var/accuracy = 0 var/obj/machinery/teleport/station/power_station var/calibrated //Calibration prevents mutation @@ -29,7 +29,12 @@ var/A = 0 for(var/obj/item/stock_parts/matter_bin/M in component_parts) A += M.rating - accurate = A + accuracy = A + +/obj/machinery/teleport/hub/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Probability of malfunction decreased by [(accuracy*25)-25]%." /obj/machinery/teleport/hub/proc/link_power_station() if(power_station) @@ -69,13 +74,13 @@ if(do_teleport(M, com.target, channel = TELEPORT_CHANNEL_BLUESPACE)) use_power(5000) - if(!calibrated && iscarbon(M) && prob(30 - ((accurate) * 10))) //oh dear a problem + if(!calibrated && iscarbon(M) && prob(30 - ((accuracy) * 10))) //oh dear a problem var/mob/living/carbon/C = M if(C.dna?.species && C.dna.species.id != "fly" && !HAS_TRAIT(C, TRAIT_RADIMMUNE)) to_chat(C, "You hear a buzzing in your ears.") C.set_species(/datum/species/fly) log_game("[C] ([key_name(C)]) was turned into a fly person") - C.apply_effect((rand(120 - accurate * 40, 180 - accurate * 60)), EFFECT_IRRADIATE, 0) + C.apply_effect((rand(120 - accuracy * 40, 180 - accuracy * 60)), EFFECT_IRRADIATE, 0) calibrated = FALSE return @@ -102,7 +107,7 @@ /obj/machinery/teleport/station - name = "station" + name = "teleporter station" desc = "The power control station for a bluespace teleporter. Used for toggling power, and can activate a test-fire to prevent malfunctions." icon_state = "controller" use_power = IDLE_POWER_USE @@ -125,6 +130,15 @@ E += C.rating efficiency = E - 1 +/obj/machinery/teleport/station/examine(mob/user) + . = ..() + if(!panel_open) + . += "The panel is screwed in, obstructing the linking device and wiring panel." + else + . += "The linking device is now able to be scanned with a multitool.
    The wiring can be connected to a nearby console and hub with a pair of wirecutters.
    " + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: This station can be linked to [efficiency] other station(s)." + /obj/machinery/teleport/station/proc/link_console_and_hub() for(var/direction in GLOB.cardinals) teleporter_hub = locate(/obj/machinery/teleport/hub, get_step(src, direction)) diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index a8ba9850ff..5a907804ce 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -84,7 +84,7 @@ switch(mode) if(1) if(!locked) - if(!istype(target) || target.anchored) + if(!istype(target) || target.anchored || target.move_resist >= MOVE_FORCE_EXTREMELY_STRONG) occupant_message("Unable to lock on [target]") return locked = target @@ -110,7 +110,7 @@ else atoms = orange(3, target) for(var/atom/movable/A in atoms) - if(A.anchored) + if(A.anchored || A.move_resist >= MOVE_FORCE_EXTREMELY_STRONG) continue spawn(0) var/iter = 5-get_dist(A,target) @@ -283,7 +283,7 @@ /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_charge() if(equip_ready) //disabled return - var/area/A = get_area(chassis) + var/area/A = get_base_area(chassis) var/pow_chan = get_power_channel(A) if(pow_chan) return 1000 //making magic @@ -328,7 +328,7 @@ occupant_message("No powercell detected.") return if(cur_charge < chassis.cell.maxcharge) - var/area/A = get_area(chassis) + var/area/A = get_base_area(chassis) if(A) var/pow_chan for(var/c in list(EQUIP,ENVIRON,LIGHT)) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 95fc96e119..2e93fc3a49 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -436,7 +436,7 @@ throwforce = 35 icon_state = "punching_glove" -/obj/item/punching_glove/throw_impact(atom/hit_atom) +/obj/item/punching_glove/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) if(ismovableatom(hit_atom)) var/atom/movable/AM = hit_atom diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index bc8a675085..facf687cc4 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -36,6 +36,11 @@ MC += C.rating max_charge = MC * 25 +/obj/machinery/mech_bay_recharge_port/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Base recharge rate at [max_charge]J per cycle." + /obj/machinery/mech_bay_recharge_port/process() if(stat & NOPOWER || !recharge_console) return @@ -79,7 +84,7 @@ /obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "mech_bay_power_console", "Mech Bay Power Control Console", 400, 170, master_ui, state) + ui = new(user, src, ui_key, "mech_bay_power_console", "Mech Bay Power Control Console", 400, 200, master_ui, state) ui.open() /obj/machinery/computer/mech_bay_power_console/ui_act(action, params) @@ -96,7 +101,7 @@ if(recharge_port && !QDELETED(recharge_port)) data["recharge_port"] = list("mech" = null) if(recharge_port.recharging_mech && !QDELETED(recharge_port.recharging_mech)) - data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "maxhealth" = recharge_port.recharging_mech.max_integrity, "cell" = null) + data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "maxhealth" = recharge_port.recharging_mech.max_integrity, "cell" = null, "name" = recharge_port.recharging_mech.name,) if(recharge_port.recharging_mech.cell && !QDELETED(recharge_port.recharging_mech.cell)) data["recharge_port"]["mech"]["cell"] = list( "critfail" = recharge_port.recharging_mech.cell.crit_fail, diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 61c0a8bd37..a2b36f90b2 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -62,6 +62,11 @@ T += Ml.rating time_coeff = round(initial(time_coeff) - (initial(time_coeff)*(T))/5,0.01) +/obj/machinery/mecha_part_fabricator/examine(mob/user) + . = ..() + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Storing up to [materials.max_amount] material units.
    Material consumption at [component_coeff*100]%.
    Build time reduced by [100-time_coeff*100]%.
    " /obj/machinery/mecha_part_fabricator/emag_act() . = ..() @@ -411,7 +416,7 @@ return ..() /obj/machinery/mecha_part_fabricator/proc/material2name(ID) - return copytext(ID,2) + return copytext_char(ID,2) /obj/machinery/mecha_part_fabricator/proc/is_insertion_ready(mob/user) if(panel_open) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index f556a75434..87ce892375 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -49,6 +49,7 @@ var/lights = FALSE var/lights_power = 6 var/last_user_hud = 1 // used to show/hide the mecha hud while preserving previous preference + var/completely_disabled = FALSE //stops the mech from doing anything var/breach_time = 0 var/recharge_rate = 0 @@ -431,6 +432,8 @@ return if(!locate(/turf) in list(target,target.loc)) // Prevents inventory from being drilled return + if(completely_disabled) + return if(phasing) occupant_message("Unable to interact with objects while phasing") return @@ -508,6 +511,8 @@ return 1 /obj/mecha/relaymove(mob/user,direction) + if(completely_disabled) + return if(!direction) return if(user != occupant) //While not "realistic", this piece is player friendly. @@ -1025,7 +1030,7 @@ /obj/mecha/log_message(message as text, message_type=LOG_GAME, color=null, log_globally) log.len++ - log[log.len] = list("time"="[STATION_TIME_TIMESTAMP("hh:mm:ss")]","date","year"="[GLOB.year_integer]","message"="[color?"":null][message][color?"":null]") + log[log.len] = list("time"="[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]","date","year"="[GLOB.year_integer]","message"="[color?"":null][message][color?"":null]") ..() return log.len diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index dd335e8b37..e5e578b0e8 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -108,8 +108,8 @@ /obj/mecha/attack_tk() return -/obj/mecha/hitby(atom/movable/A as mob|obj) //wrapper - log_message("Hit by [A].", color="red") +/obj/mecha/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) //wrapper + log_message("Hit by [AM].", color="red") . = ..() diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm index f9e04990fc..65edf1ec9a 100644 --- a/code/game/mecha/mecha_topic.dm +++ b/code/game/mecha/mecha_topic.dm @@ -294,11 +294,11 @@ onclose(occupant, "exosuit_log") if (href_list["change_name"]) - var/newname = stripped_input(occupant,"Choose new exosuit name","Rename exosuit","", MAX_NAME_LEN) - if(newname && trim(newname)) - name = newname - else - alert(occupant, "nope.avi") + var/userinput = stripped_input(occupant,"Choose new exosuit name","Rename exosuit","", MAX_NAME_LEN) + if(!userinput || usr != occupant || usr.incapacitated()) + return + name = userinput + return if (href_list["toggle_id_upload"]) add_req_access = !add_req_access diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm index 50d40697f8..6e8387c07b 100644 --- a/code/game/objects/effects/contraband.dm +++ b/code/game/objects/effects/contraband.dm @@ -128,7 +128,7 @@ if (smooth & SMOOTH_DIAGONAL) for (var/O in overlays) var/image/I = O - if (copytext(I.icon_state, 1, 3) == "d-") + if(copytext(I.icon_state, 1, 3) == "d-") //3 == length("d-") + 1 return var/stuff_on_wall = 0 diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm index 748b8c9453..3afc0ef671 100644 --- a/code/game/objects/effects/decals/cleanable/aliens.dm +++ b/code/game/objects/effects/decals/cleanable/aliens.dm @@ -29,13 +29,19 @@ var/list/diseases = list() SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases) var/direction = pick(directions) - for(var/i in 0 to pick(0, 200; 1, 150; 2, 50)) - sleep(2) - if(i > 0) + var/dist = 0 + if(prob(50)) //yes this and the one below are different for a reason. + if(prob(25)) + dist = 2 + else + dist = 1 + if(dist) + for(var/i in 1 to dist) + sleep(2) var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases) splat.transfer_blood_dna(blood_DNA, diseases) - if(!step_to(src, get_step(src, direction), 0)) - break + if(!step_to(src, get_step(src, direction), 0)) + break /obj/effect/decal/cleanable/blood/gibs/xeno/up random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1") diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm index 9680dc2034..b6b93850f1 100644 --- a/code/game/objects/effects/decals/cleanable/gibs.dm +++ b/code/game/objects/effects/decals/cleanable/gibs.dm @@ -5,6 +5,7 @@ layer = LOW_OBJ_LAYER random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") mergeable_decal = FALSE + bloodiness = 0 //This isn't supposed to be bloody. var/body_colors = "#e3ba84" //a default color just in case. var/gibs_reagent_id = /datum/reagent/liquidgibs var/gibs_bloodtype = "A+" @@ -19,7 +20,6 @@ add_blood_DNA(list("Non-human DNA" = gibs_bloodtype, diseases)) update_icon() - /obj/effect/decal/cleanable/blood/gibs/update_icon() add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY) cut_overlays() @@ -44,13 +44,18 @@ var/list/diseases = list() SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases) var/direction = pick(directions) - for(var/i in 0 to pick(0, 200; 1, 150; 2, 50)) - sleep(2) - if(i > 0) + var/dist = 0 + if(prob(50)) //yes this and the one below are different for a reason. + if(prob(25)) + dist = 2 + else + dist = 1 + if(dist) + for(var/i in 1 to dist) var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases) splat.transfer_blood_dna(blood_DNA, diseases) - if(!step_to(src, get_step(src, direction), 0)) - break + if(!step_to(src, get_step(src, direction), 0)) + break /obj/effect/decal/cleanable/blood/gibs/up random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1") diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index d42d7d6b88..ab0d1caca4 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -5,12 +5,12 @@ icon_state = "floor1" random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7") blood_state = BLOOD_STATE_BLOOD - bloodiness = MAX_SHOE_BLOODINESS + bloodiness = BLOOD_AMOUNT_PER_DECAL color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere. /obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C) if (C.blood_DNA) - blood_DNA |= C.blood_DNA.Copy() + blood_DNA |= C.blood_DNA update_icon() ..() diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm index ddc805f3ff..05077bf898 100644 --- a/code/game/objects/effects/effect_system/effect_system.dm +++ b/code/game/objects/effects/effect_system/effect_system.dm @@ -48,6 +48,8 @@ would spawn and follow the beaker, even if it is carried or thrown. holder = atom /datum/effect_system/proc/start() + if(QDELETED(src)) + return for(var/i in 1 to number) if(total_effects > 20) return @@ -69,7 +71,8 @@ would spawn and follow the beaker, even if it is carried or thrown. for(var/j in 1 to steps_amt) sleep(5) step(E,direction) - addtimer(CALLBACK(src, .proc/decrement_total_effect), 20) + if(!QDELETED(src)) + addtimer(CALLBACK(src, .proc/decrement_total_effect), 20) /datum/effect_system/proc/decrement_total_effect() total_effects-- diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index aabf9acafa..38a1a6089e 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -126,7 +126,7 @@ T.PlaceOnTop(/turf/open/floor/plating/foam, flags = CHANGETURF_INHERIT_AIR) for(var/direction in GLOB.cardinals) var/turf/cardinal_turf = get_step(T, direction) - if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf! + if(get_base_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf! new/obj/structure/foamedmetal(T) break flick("[icon_state]-disolve", src) diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index d48013d472..6057d1b418 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -4,6 +4,7 @@ /obj/effect icon = 'icons/effects/effects.dmi' resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF + move_resist = INFINITY obj_flags = 0 /obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 3ef89c4b96..7a45bdcf0c 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -273,6 +273,27 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) GLOB.newplayer_start += loc return INITIALIZE_HINT_QDEL +/obj/effect/landmark/start/nuclear_equipment + name = "bomb or clown beacon spawner" + var/nukie_path = /obj/item/sbeacondrop/bomb + var/clown_path = /obj/item/sbeacondrop/clownbomb + +/obj/effect/landmark/start/nuclear_equipment/after_round_start() + var/npath = nukie_path + if(istype(SSticker.mode, /datum/game_mode/nuclear/clown_ops)) + npath = clown_path + else if(istype(SSticker.mode, /datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/D = SSticker.mode + if(locate(/datum/dynamic_ruleset/roundstart/nuclear/clown_ops) in D.current_rules) + npath = clown_path + new npath(loc) + return ..() + +/obj/effect/landmark/start/nuclear_equipment/minibomb + name = "minibomb or bombanana spawner" + nukie_path = /obj/item/storage/box/minibombs + clown_path = /obj/item/storage/box/bombananas + /obj/effect/landmark/latejoin name = "JoinLate" @@ -456,7 +477,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) if(!SSmapping.station_room_templates[t]) log_world("Station room spawner placed at ([T.x], [T.y], [T.z]) has invalid ruin name of \"[t]\" in its list") templates -= t - template_name = pickweight(templates) + template_name = pickweightAllowZero(templates) if(!template_name) GLOB.stationroom_landmarks -= src qdel(src) @@ -481,3 +502,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/stationroom/box/engine/New() . = ..() templates = CONFIG_GET(keyed_list/box_random_engine) + +// Landmark for the mining station +/obj/effect/landmark/stationroom/lavaland/station + templates = list("Public Mining Base" = 3) + icon = 'icons/rooms/Lavaland/Mining.dmi' diff --git a/code/game/objects/effects/proximity.dm b/code/game/objects/effects/proximity.dm index e367514f6b..ab35d213ea 100644 --- a/code/game/objects/effects/proximity.dm +++ b/code/game/objects/effects/proximity.dm @@ -109,4 +109,4 @@ /obj/effect/abstract/proximity_checker/Crossed(atom/movable/AM) set waitfor = FALSE - monitor.hasprox_receiver.HasProximity(AM) + monitor?.hasprox_receiver.HasProximity(AM) diff --git a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm index 0360c4ccc2..a98c40d4fc 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/impact.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/impact.dm @@ -39,4 +39,8 @@ /obj/effect/projectile/impact/laser/wavemotion name = "particle impact" - icon_state = "impact_wavemotion" \ No newline at end of file + icon_state = "impact_wavemotion" + +/obj/effect/projectile/impact/laser/emitter + name = "emitter impact" + icon_state = "impact_emitter" diff --git a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm index cbd4b21d39..a7ff399734 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/muzzle.dm @@ -31,4 +31,8 @@ /obj/effect/projectile/muzzle/laser/wavemotion name = "particle backblast" - icon_state = "muzzle_wavemotion" \ No newline at end of file + icon_state = "muzzle_wavemotion" + +/obj/effect/projectile/muzzle/laser/emitter + name = "emitter flash" + icon_state = "muzzle_emitter" diff --git a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm index 0cd4589d4c..bd2c6c6e87 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm @@ -70,3 +70,7 @@ /obj/effect/projectile/tracer/laser/wavemotion name = "particle trail" icon_state = "tracer_wavemotion" + +/obj/effect/projectile/tracer/laser/emitter + name = "emitter beam" + icon_state = "emitter" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 78dde8d206..aa4e45dee6 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -568,21 +568,21 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) else return -/obj/item/throw_impact(atom/A, datum/thrownthing/throwingdatum) - if(A && !QDELETED(A)) - SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, A, throwingdatum) - if(get_temperature() && isliving(A)) - var/mob/living/L = A +/obj/item/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + if(hit_atom && !QDELETED(hit_atom)) + SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) + if(get_temperature() && isliving(hit_atom)) + var/mob/living/L = hit_atom L.IgniteMob() var/itempush = 1 if(w_class < 4) itempush = 0 //too light to push anything - return A.hitby(src, 0, itempush) + return hit_atom.hitby(src, 0, itempush, throwingdatum=throwingdatum) -/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, messy_throw = TRUE) +/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE) thrownby = thrower callback = CALLBACK(src, .proc/after_throw, callback, (spin && messy_throw)) //replace their callback with our own - . = ..(target, range, speed, thrower, spin, diagonals_first, callback) + . = ..(target, range, speed, thrower, spin, diagonals_first, callback, force) /obj/item/proc/after_throw(datum/callback/callback, messy_throw) if (callback) //call the original callback @@ -674,7 +674,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) else . = "" -/obj/item/hitby(atom/movable/AM) +/obj/item/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) return /obj/item/attack_hulk(mob/living/carbon/human/user) diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index e6e39d3ff1..237aca02a9 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -7,35 +7,35 @@ RPD #define DISPOSALS_CATEGORY 1 #define TRANSIT_CATEGORY 2 -#define BUILD_MODE 1 -#define WRENCH_MODE 2 -#define DESTROY_MODE 4 -#define PAINT_MODE 8 +#define BUILD_MODE (1<<0) +#define WRENCH_MODE (1<<1) +#define DESTROY_MODE (1<<2) +#define PAINT_MODE (1<<3) GLOBAL_LIST_INIT(atmos_pipe_recipes, list( "Pipes" = list( new /datum/pipe_info/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple), new /datum/pipe_info/pipe("Manifold", /obj/machinery/atmospherics/pipe/manifold), - new /datum/pipe_info/pipe("Manual Valve", /obj/machinery/atmospherics/components/binary/valve), - new /datum/pipe_info/pipe("Digital Valve", /obj/machinery/atmospherics/components/binary/valve/digital), - new /datum/pipe_info/pipe("Relief Valve", /obj/machinery/atmospherics/components/binary/relief_valve), new /datum/pipe_info/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/manifold4w), new /datum/pipe_info/pipe("Layer Manifold", /obj/machinery/atmospherics/pipe/layer_manifold), ), "Devices" = list( new /datum/pipe_info/pipe("Connector", /obj/machinery/atmospherics/components/unary/portables_connector), - new /datum/pipe_info/pipe("Unary Vent", /obj/machinery/atmospherics/components/unary/vent_pump), - new /datum/pipe_info/pipe("Relief Valve", /obj/machinery/atmospherics/components/unary/relief_valve), new /datum/pipe_info/pipe("Gas Pump", /obj/machinery/atmospherics/components/binary/pump), - new /datum/pipe_info/pipe("Passive Gate", /obj/machinery/atmospherics/components/binary/passive_gate), new /datum/pipe_info/pipe("Volume Pump", /obj/machinery/atmospherics/components/binary/volume_pump), - new /datum/pipe_info/pipe("Scrubber", /obj/machinery/atmospherics/components/unary/vent_scrubber), - new /datum/pipe_info/pipe("Injector", /obj/machinery/atmospherics/components/unary/outlet_injector), - new /datum/pipe_info/meter("Meter"), new /datum/pipe_info/pipe("Gas Filter", /obj/machinery/atmospherics/components/trinary/filter), new /datum/pipe_info/pipe("Gas Mixer", /obj/machinery/atmospherics/components/trinary/mixer), + new /datum/pipe_info/pipe("Passive Gate", /obj/machinery/atmospherics/components/binary/passive_gate), + new /datum/pipe_info/pipe("Injector", /obj/machinery/atmospherics/components/unary/outlet_injector), + new /datum/pipe_info/pipe("Scrubber", /obj/machinery/atmospherics/components/unary/vent_scrubber), + new /datum/pipe_info/pipe("Unary Vent", /obj/machinery/atmospherics/components/unary/vent_pump), new /datum/pipe_info/pipe("Passive Vent", /obj/machinery/atmospherics/components/unary/passive_vent), + new /datum/pipe_info/pipe("Manual Valve", /obj/machinery/atmospherics/components/binary/valve), + new /datum/pipe_info/pipe("Digital Valve", /obj/machinery/atmospherics/components/binary/valve/digital), + new /datum/pipe_info/pipe("Relief Valve (Binary)", /obj/machinery/atmospherics/components/binary/relief_valve), + new /datum/pipe_info/pipe("Relief Valve (Unary)", /obj/machinery/atmospherics/components/unary/relief_valve), + new /datum/pipe_info/meter("Meter"), ), "Heat Exchange" = list( new /datum/pipe_info/pipe("Pipe", /obj/machinery/atmospherics/pipe/heat_exchanging/simple), @@ -102,22 +102,22 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( 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") + "[SOUTHWEST]" = "South to West", "[SOUTHEAST]" = "East to South") if(PIPE_TRINARY) - dirs = list("[NORTH]" = "West South East", "[EAST]" = "North West South", - "[SOUTH]" = "East North West", "[WEST]" = "South East North") + 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", "[EAST]" = "East South West", - "[SOUTH]" = "South West North", "[WEST]" = "West North East", - "[SOUTHEAST]" = "West South East", "[NORTHEAST]" = "South East North", - "[NORTHWEST]" = "East North West", "[SOUTHWEST]" = "North West South") + 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_UNARY) - dirs = list("[NORTH]" = "North", "[EAST]" = "East", "[SOUTH]" = "South", "[WEST]" = "West") + 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", "[NORTHEAST]" = "North Flipped", "[EAST]" = "East", "[SOUTHEAST]" = "East Flipped", - "[SOUTH]" = "South", "[SOUTHWEST]" = "South Flipped", "[WEST]" = "West", "[NORTHWEST]" = "West Flipped") + dirs = list("[NORTH]" = "North", "[EAST]" = "East", "[SOUTH]" = "South", "[WEST]" = "West", + "[NORTHEAST]" = "North Flipped", "[SOUTHEAST]" = "East Flipped", "[SOUTHWEST]" = "South Flipped", "[NORTHWEST]" = "West Flipped") var/list/rows = list() @@ -208,7 +208,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( var/static/datum/pipe_info/first_atmos var/static/datum/pipe_info/first_disposal var/static/datum/pipe_info/first_transit - var/mode = BUILD_MODE | PAINT_MODE | DESTROY_MODE | WRENCH_MODE + var/mode = BUILD_MODE | DESTROY_MODE | WRENCH_MODE /obj/item/pipe_dispenser/New() . = ..() @@ -249,7 +249,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/pipes) assets.send(user) - ui = new(user, src, ui_key, "rpd", name, 300, 550, master_ui, state) + ui = new(user, src, ui_key, "rpd", name, 425, 472, master_ui, state) ui.open() /obj/item/pipe_dispenser/ui_data(mob/user) @@ -316,9 +316,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( playeffect = FALSE if("mode") var/n = text2num(params["mode"]) - if(n == 2 && !(mode&1) && !(mode&2)) - mode |= 3 - else if(mode&n) + if(mode & n) mode &= ~n else mode |= n @@ -327,9 +325,11 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( spark_system.start() effectcooldown = world.time + 100 playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0) + return TRUE /obj/item/pipe_dispenser/pre_attack(atom/A, mob/user) - if(!user.IsAdvancedToolUser() || istype(A, /turf/open/space/transit)) + var/turf/T = get_turf(A) + if(!user.IsAdvancedToolUser() || !T || istype(T, /turf/open/space/transit) || isindestructiblewall(T)) return ..() //So that changing the menu settings doesn't affect the pipes already being built. @@ -341,11 +341,13 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( var/static/list/make_pipe_whitelist if(!make_pipe_whitelist) make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe, /obj/structure/window, /obj/structure/grille)) + if(istype(A, /obj/machinery/atmospherics) && (mode & BUILD_MODE && !(mode & PAINT_MODE))) //Reduces pixelhunt when coloring is off. + A = get_turf(A) var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist)) . = FALSE - if((mode&DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter)) + if((mode & DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter)) to_chat(user, "You start destroying a pipe...") playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) if(do_after(user, destroy_speed, target = A)) @@ -353,7 +355,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( qdel(A) return - if((mode&PAINT_MODE)) + if((mode & PAINT_MODE)) if(istype(A, /obj/machinery/atmospherics/pipe) && !istype(A, /obj/machinery/atmospherics/pipe/layer_manifold)) var/obj/machinery/atmospherics/pipe/P = A to_chat(user, "You start painting \the [P] [paint_color]...") @@ -371,19 +373,23 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( user.visible_message("[user] paints \the [A] [paint_color].","You paint \the [A] [paint_color].") return - if(mode&BUILD_MODE) + if(mode & BUILD_MODE) switch(category) //if we've gotten this var, the target is valid if(ATMOS_CATEGORY) //Making pipes if(!can_make_pipe) return ..() + A = T + if(is_type_in_typecache(recipe, GLOB.ventcrawl_machinery) && isclosedturf(A)) //wall escapism sanity check. + to_chat(user, "[src]'s error light flickers; there's something in the way!") + return playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) if (recipe.type == /datum/pipe_info/meter) to_chat(user, "You start building a meter...") if(do_after(user, atmos_build_speed, target = A)) activate() - var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A)) + var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(A) PM.setAttachLayer(piping_layer) - if(mode&WRENCH_MODE) + if(mode & WRENCH_MODE) PM.wrench_act(user, src) else to_chat(user, "You start building a pipe...") @@ -391,7 +397,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( activate() var/obj/machinery/atmospherics/path = queued_p_type var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe - var/obj/item/pipe/P = new pipe_item_type(get_turf(A), queued_p_type, queued_p_dir) + var/obj/item/pipe/P = new pipe_item_type(A, queued_p_type, queued_p_dir) if(queued_p_flipped && istype(P, /obj/item/pipe/trinary/flippable)) var/obj/item/pipe/trinary/flippable/F = P @@ -402,13 +408,13 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( P.setPipingLayer(piping_layer) if(findtext("[queued_p_type]", "/obj/machinery/atmospherics/pipe") && !findtext("[queued_p_type]", "layer_manifold")) P.add_atom_colour(GLOB.pipe_paint_colors[paint_color], FIXED_COLOUR_PRIORITY) - if(mode&WRENCH_MODE) + if(mode & WRENCH_MODE) P.wrench_act(user, src) if(DISPOSALS_CATEGORY) //Making disposals pipes if(!can_make_pipe) return ..() - A = get_turf(A) + A = T if(isclosedturf(A)) to_chat(user, "[src]'s error light flickers; there's something in the way!") return @@ -426,14 +432,14 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( C.add_fingerprint(usr) C.update_icon() - if(mode&WRENCH_MODE) + if(mode & WRENCH_MODE) C.wrench_act(user, src) return if(TRANSIT_CATEGORY) //Making transit tubes if(!can_make_pipe) return ..() - A = get_turf(A) + A = T if(isclosedturf(A)) to_chat(user, "[src]'s error light flickers; there's something in the way!") return @@ -448,7 +454,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( if(queued_p_type == /obj/structure/c_transit_tube_pod) var/obj/structure/c_transit_tube_pod/pod = new /obj/structure/c_transit_tube_pod(A) pod.add_fingerprint(usr) - if(mode&WRENCH_MODE) + if(mode & WRENCH_MODE) pod.wrench_act(user, src) else @@ -460,7 +466,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( tube.simple_rotate_flip() tube.add_fingerprint(usr) - if(mode&WRENCH_MODE) + if(mode & WRENCH_MODE) tube.wrench_act(user, src) return diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 5ec989ab73..1bef477a30 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -272,14 +272,11 @@ update_label("John Doe", "Clowny") if(isliving(user) && user.mind) if(user.mind.special_role || anyone) if(alert(user, "Action", "Agent ID", "Show", "Forge") == "Forge") - var/t = copytext(sanitize(input(user, "What name would you like to put on this card?", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name))as text | null),1,26) - if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall") //Same as mob/dead/new_player/prefrences.dm - if (t) - alert("Invalid name.") + var/input_name = reject_bad_name(stripped_input(user, "What name would you like to put on this card?", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name), MAX_NAME_LEN), TRUE) + if(!input_name) return - registered_name = t - var/u = copytext(sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant")as text | null),1,MAX_MESSAGE_LEN) + var/u = stripped_input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant", MAX_MESSAGE_LEN) if(!u) registered_name = "" return diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 49985f5c23..1186ea8001 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -146,7 +146,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(!proximity || lit) //can't dip if cigarette is lit (it will heat the reagents in the glass instead) return if(istype(glass)) //you can dip cigarettes into beakers - if(glass.reagents.trans_to(src, chem_volume)) //if reagents were transfered, show the message + if(glass.reagents.trans_to(src, chem_volume, log = "cigar fill: dip cigarette")) //if reagents were transfered, show the message to_chat(user, "You dip \the [src] into \the [glass].") else //if not, either the beaker was empty, or the cigarette was full if(!glass.reagents.total_volume) @@ -154,7 +154,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM else to_chat(user, "[src] is full.") - /obj/item/clothing/mask/cigarette/proc/light(flavor_text = null) if(lit) return @@ -438,7 +437,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM packeditem = 1 name = "[O.name]-packed [initial(name)]" if(O.reagents) - O.reagents.trans_to(src, O.reagents.total_volume) + O.reagents.trans_to(src, O.reagents.total_volume, log = "cigar fill: pipe pack") qdel(O) else to_chat(user, "It has to be dried first!") @@ -687,7 +686,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(O.dry) var/obj/item/clothing/mask/cigarette/rollie/R = new /obj/item/clothing/mask/cigarette/rollie(user.loc) R.chem_volume = target.reagents.total_volume - target.reagents.trans_to(R, R.chem_volume) + target.reagents.trans_to(R, R.chem_volume, log = "cigar fill: rolling paper afterattack") qdel(target) qdel(src) user.put_in_active_hand(R) @@ -903,7 +902,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM //Transfer reagents and remove the plant user.show_message("You stuff the [DP] into the [src]'s bowl.", MSG_VISUAL) - DP.reagents.trans_to(src, 100) + DP.reagents.trans_to(src, 100, log = "cigar fill: bong") qdel(DP) return else diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index 3e4a8743da..5621a946bb 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -308,6 +308,7 @@ /obj/item/circuitboard/machine/thermomachine name = "Thermomachine (Machine Board)" desc = "You can use a screwdriver to switch between heater and freezer." + var/pipe_layer = PIPING_LAYER_DEFAULT req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/micro_laser = 2, @@ -342,8 +343,18 @@ build_path = initial(new_type.build_path) I.play_tool_sound(src) to_chat(user, "You change the circuitboard setting to \"[new_setting]\".") - else - return ..() + return + + if(I.tool_behaviour == TOOL_MULTITOOL) + pipe_layer = (pipe_layer >= PIPING_LAYER_MAX) ? PIPING_LAYER_MIN : (pipe_layer + 1) + to_chat(user, "You change the circuitboard to layer [pipe_layer].") + return + + . = ..() + +/obj/item/circuitboard/machine/thermomachine/examine() + . = ..() + . += "It is set to layer [pipe_layer]." /obj/item/circuitboard/machine/thermomachine/heater name = "Heater (Machine Board)" diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 143354b496..81c5083ef7 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -407,7 +407,7 @@ to_chat(user, "You spray a [temp] on \the [target.name]") if(length(text_buffer) > 1) - text_buffer = copytext(text_buffer,2) + text_buffer = copytext(text_buffer, length(text_buffer[1]) + 1) SStgui.update_uis(src) if(post_noise) @@ -427,7 +427,7 @@ /obj/item/toy/crayon/proc/can_claim_for_gang(mob/user, atom/target) // Check area validity. // Reject space, player-created areas, and non-station z-levels. - var/area/A = get_area(target) + var/area/A = get_base_area(target) if(!A || (!is_station_level(A.z)) || !A.valid_territory) to_chat(user, "[A] is unsuitable for tagging.") return FALSE @@ -461,7 +461,7 @@ qdel(old_marking) var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) - var/area/territory = get_area(target) + var/area/territory = get_base_area(target) new /obj/effect/decal/cleanable/crayon/gang(target,G.gang,"graffiti",0,user) // Heres the gang tag. to_chat(user, "You tagged [territory] for your gang!") @@ -619,8 +619,7 @@ is_capped = TRUE self_contained = FALSE // Don't disappear when they're empty can_change_colour = TRUE - gang = TRUE //Gang check is true for all things upon the honored hierarchy of spraycans, except those that are FALSE. - + reagent_contents = list(/datum/reagent/fuel = 1, /datum/reagent/consumable/ethanol = 1) pre_noise = TRUE @@ -774,7 +773,6 @@ icon_capped = "deathcan2_cap" icon_uncapped = "deathcan2" use_overlays = FALSE - gang = FALSE volume_multiplier = 25 charges = 100 @@ -789,7 +787,6 @@ icon_capped = "clowncan2_cap" icon_uncapped = "clowncan2" use_overlays = FALSE - gang = FALSE reagent_contents = list(/datum/reagent/lube = 1, /datum/reagent/consumable/banana = 1) volume_multiplier = 5 @@ -804,7 +801,6 @@ icon_capped = "mimecan_cap" icon_uncapped = "mimecan" use_overlays = FALSE - gang = FALSE can_change_colour = FALSE paint_color = "#FFFFFF" //RGB diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 07d58c1754..386b1fe668 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -452,14 +452,15 @@ return TRUE /obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H) - if(req_defib) - if(defib.pullshocksafely && isliving(H.pulledby)) - H.visible_message("The defibrillator safely discharges the excessive charge into the floor!") - else - var/mob/living/M = H.pulledby - if(M.electrocute_act(30, src)) - M.visible_message("[M] is electrocuted by [M.p_their()] contact with [H]!") - M.emote("scream") + if(!H.pulledby || !isliving(H.pulledby)) + return + if(req_defib && defib.pullshocksafely) + H.visible_message("The defibrillator safely discharges the excessive charge into the floor!") + return + var/mob/living/M = H.pulledby + if(M.electrocute_act(30, src)) + M.visible_message("[M] is electrocuted by [M.p_their()] contact with [H]!") + M.emote("scream") /obj/item/twohanded/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user) if(req_defib && defib.safety) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index c0b510111f..6bac77258d 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1,4 +1,3 @@ - //The advanced pea-green monochrome lcd of tomorrow. GLOBAL_LIST_EMPTY(PDAs) @@ -77,6 +76,7 @@ GLOBAL_LIST_EMPTY(PDAs) var/hidden = FALSE // Is the PDA hidden from the PDA list? var/emped = FALSE var/equipped = FALSE //used here to determine if this is the first time its been picked up + var/allow_emojis = TRUE //if the pda can send emojis and actually have them parsed as such var/obj/item/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both. var/ownjob = null //related to above @@ -93,6 +93,8 @@ GLOBAL_LIST_EMPTY(PDAs) var/underline_flag = TRUE //flag for underline + var/list/blocked_pdas + /obj/item/pda/suicide_act(mob/living/carbon/user) var/deathMessage = msg_input(user) if (!deathMessage) @@ -253,10 +255,14 @@ GLOBAL_LIST_EMPTY(PDAs) var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/simple/pda) assets.send(user) + var/datum/asset/spritesheet/emoji_s = get_asset_datum(/datum/asset/spritesheet/goonchat) + emoji_s.send(user) //Already sent by chat but no harm doing this + user.set_machine(src) var/dat = "Personal Data Assistant" dat += assets.css_tag() + dat += emoji_s.css_tag() dat += "[PDAIMG(refresh)]Refresh" @@ -286,7 +292,7 @@ GLOBAL_LIST_EMPTY(PDAs) dat += text("ID: [id ? "[id.registered_name], [id.assignment]" : "----------"]") dat += text("
    [id ? "Update PDA Info" : ""]

    ") - dat += "[STATION_TIME_TIMESTAMP("hh:mm:ss")]
    " //:[world.time / 100 % 6][world.time / 100 % 10]" + dat += "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]
    " //:[world.time / 100 % 6][world.time / 100 % 10]" dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer]" dat += "

    " @@ -336,6 +342,8 @@ GLOBAL_LIST_EMPTY(PDAs) dat += "
  • [PDAIMG(medbot)]Bots Access
  • " if (cartridge.access & CART_JANITOR) dat += "
  • [PDAIMG(bucket)]Custodial Locator
  • " + if(cartridge.access & CART_MIME) + dat += "
  • [PDAIMG(emoji)]Emoji Guidebook
  • " if (istype(cartridge.radio)) dat += "
  • [PDAIMG(signaler)]Signaler System
  • " if (cartridge.access & CART_NEWSCASTER) @@ -387,7 +395,10 @@ GLOBAL_LIST_EMPTY(PDAs) for (var/obj/item/pda/P in sortNames(get_viewable_pdas())) if (P == src) continue - dat += "
  • [P]" + if(P.owner in blocked_pdas) + dat += "
  • (BLOCKED - CLICK TO UNBLOCK) [P]" + else + dat += "
  • [P]" if(cartridge) dat += cartridge.message_special(P) dat += "
  • " @@ -630,13 +641,13 @@ GLOBAL_LIST_EMPTY(PDAs) if("Clear")//Clears messages tnote = null if("Ringtone") - var/t = input(U, "Please enter new ringtone", name, ttone) as text + var/t = stripped_input(U, "Please enter new ringtone", name, ttone, 20) if(in_range(src, U) && loc == U && t) if(SEND_SIGNAL(src, COMSIG_PDA_CHANGE_RINGTONE, U, t) & COMPONENT_STOP_RINGTONE_CHANGE) U << browse(null, "window=pda") return else - ttone = copytext(sanitize(t), 1, 20) + ttone = t else U << browse(null, "window=pda") return @@ -646,6 +657,15 @@ GLOBAL_LIST_EMPTY(PDAs) if("MessageAll") send_to_all(U) + if("toggle_block") + toggle_blocking(usr, href_list["target"]) + + if("block_pda") + block_pda(usr, href_list["target"]) + + if("unblock_pda") + unblock_pda(usr, href_list["target"]) + if("cart") if(cartridge) cartridge.special(U, href_list) @@ -739,14 +759,20 @@ GLOBAL_LIST_EMPTY(PDAs) return if((last_text && world.time < last_text + 10) || (everyone && last_everyone && world.time < last_everyone + PDA_SPAM_DELAY)) return - var/emoji_message = emoji_parse(message) if(prob(1)) message += "\nSent from my PDA" // Send the signal var/list/string_targets = list() - for (var/obj/item/pda/P in targets) - if (P.owner && P.ownjob) // != src is checked by the UI + var/list/string_blocked + for(var/obj/item/pda/P in targets) + if(owner in P.blocked_pdas) + LAZYADD(string_blocked, P.owner) + continue + if(P.owner && P.ownjob) // != src is checked by the UI string_targets += "[P.owner] ([P.ownjob])" + if(string_blocked) + string_blocked = english_list(string_blocked) + to_chat(user, "[icon2html(src, user)] The following recipients have blocked your message: [string_blocked].") for (var/obj/machinery/computer/message_monitor/M in targets) // In case of "Reply" to a message from a console, this will make the // message be logged successfully. If the console is impersonating @@ -761,7 +787,7 @@ GLOBAL_LIST_EMPTY(PDAs) "job" = "[ownjob]", "message" = message, "targets" = string_targets, - "emoji_message" = emoji_message + "emojis" = allow_emojis )) if (picture) signal.data["photo"] = picture @@ -775,16 +801,20 @@ GLOBAL_LIST_EMPTY(PDAs) playsound(src, 'sound/machines/terminal_error.ogg', 15, 1) var/target_text = signal.format_target() + if(allow_emojis) + message = emoji_parse(message)//already sent- this just shows the sent emoji as one to the sender in the to_chat + signal.data["message"] = emoji_parse(signal.data["message"]) // Log it in our logs tnote += "→ To [target_text]:
    [signal.format_message()]
    " // Show it to ghosts - var/ghost_message = "[owner] PDA Message --> [target_text]: [signal.format_message(TRUE)]" - for(var/mob/M in GLOB.player_list) - if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTPDA)) + var/ghost_message = "[owner] PDA Message --> [target_text]: [signal.format_message()]" + for(var/i in GLOB.dead_mob_list) + var/mob/M = i + if(M?.client && M.client.prefs.chat_toggles & CHAT_GHOSTPDA) to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]") + to_chat(user, "Message sent to [target_text]: \"[message]\"") // Log in the talk log - user.log_talk(message, LOG_PDA, tag="PDA: [initial(name)] to [target_text]") - to_chat(user, "Message sent to [target_text]: \"[emoji_message]\"") + user.log_talk(message, LOG_PDA, tag="PDA: [initial(name)] to [target_text] (BLOCKED:[string_blocked])") if (!silent) playsound(src, 'sound/machines/terminal_success.ogg', 15, 1) // Reset the photo @@ -794,8 +824,7 @@ GLOBAL_LIST_EMPTY(PDAs) last_everyone = world.time /obj/item/pda/proc/receive_message(datum/signal/subspace/pda/signal) - tnote += "← From [signal.data["name"]] ([signal.data["job"]]):
    [signal.format_message()]
    " - + tnote += "← From [signal.data["name"]] ([signal.data["job"]]): (BLOCK/UNBLOCK)
    [signal.format_message()]
    " if (!silent) playsound(src, 'sound/machines/twobeep.ogg', 50, 1) audible_message("[icon2html(src, hearers(src))] *[ttone]*", null, 3) @@ -814,7 +843,11 @@ GLOBAL_LIST_EMPTY(PDAs) hrefstart = "" hrefend = "" - to_chat(L, "[icon2html(src)] Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], [signal.format_message(TRUE)] (Reply)") + var/inbound_message = signal.format_message() + if(signal.data["emojis"] == TRUE)//so will not parse emojis as such from pdas that don't send emojis + inbound_message = emoji_parse(inbound_message) + + to_chat(L, "[icon2html(src)] Message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], [inbound_message] (Reply) (BLOCK/UNBLOCK)") update_icon(TRUE) @@ -827,6 +860,20 @@ GLOBAL_LIST_EMPTY(PDAs) /obj/item/pda/proc/create_message(mob/living/U, obj/item/pda/P) send_message(U,list(P)) +/obj/item/pda/proc/toggle_blocking(mob/user, target) + if(target in blocked_pdas) + unblock_pda(user, target) + else + block_pda(user, target) + +/obj/item/pda/proc/block_pda(mob/user, target) + to_chat(user, "[icon2html(src, user)] [target] blocked from messages. Use the messenger PDA list to unblock.") + LAZYOR(blocked_pdas, target) + +/obj/item/pda/proc/unblock_pda(mob/user, target) + to_chat(user, "[icon2html(src, user)] [target] unblocked from messages.") + LAZYREMOVE(blocked_pdas, target) + /obj/item/pda/AltClick(mob/user) . = ..() if(id) @@ -1172,4 +1219,4 @@ GLOBAL_LIST_EMPTY(PDAs) #undef PDA_OVERLAY_ID #undef PDA_OVERLAY_ITEM #undef PDA_OVERLAY_LIGHT -#undef PDA_OVERLAY_PAI \ No newline at end of file +#undef PDA_OVERLAY_PAI diff --git a/code/game/objects/items/devices/PDA/PDA_types.dm b/code/game/objects/items/devices/PDA/PDA_types.dm index 2da47d481e..b604bec258 100644 --- a/code/game/objects/items/devices/PDA/PDA_types.dm +++ b/code/game/objects/items/devices/PDA/PDA_types.dm @@ -19,6 +19,26 @@ if(istype(cart) && cart.charges < 5) cart.charges++ +//Mime PDA sends "silent" messages. +/obj/item/pda/mime + name = "mime PDA" + default_cartridge = /obj/item/cartridge/virus/mime + inserted_item = /obj/item/toy/crayon/mime + icon_state = "pda-mime" + desc = "A portable microcomputer by Thinktronic Systems, LTD. The hardware has been modified for compliance with the vows of silence." + silent = TRUE + ttone = "silence" + +/obj/item/pda/mime/msg_input(mob/living/U = usr) + if(emped || toff) + return + var/emojis = emoji_sanitize(stripped_input(U, "Please enter emojis", name)) + if(!emojis) + return + if(!U.canUseTopic(src, BE_CLOSE)) + return + return emojis + // Special AI/pAI PDAs that cannot explode. /obj/item/pda/ai icon = null @@ -79,14 +99,6 @@ icon_state = "pda-science" ttone = "boom" -/obj/item/pda/mime - name = "mime PDA" - default_cartridge = /obj/item/cartridge/virus/mime - inserted_item = /obj/item/toy/crayon/mime - icon_state = "pda-mime" - silent = TRUE - ttone = "silence" - /obj/item/pda/heads default_cartridge = /obj/item/cartridge/head icon_state = "pda-hop" diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index e4fa241907..b186c29539 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -309,9 +309,14 @@ Code: var/list/S = list(" Off","AOff"," On", " AOn") var/list/chg = list("N","C","F") +//Neither copytext nor copytext_char is appropriate here; neither 30 UTF-8 code units nor 30 code points equates to 30 columns of output. +//Some glyphs are very tall or very wide while others are small or even take up no space at all. +//Emojis can take modifiers which are many characters but render as only one glyph. +//A proper solution here (as far as Unicode goes, maybe not ideal as far as markup goes, a table would be better) +//would be to use [A.area.name] for(var/obj/machinery/power/apc/A in L) - menu += copytext(add_tspace(A.area.name, 30), 1, 30) - menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_lspace(DisplayPower(A.lastused_total), 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]
    " + menu += copytext_char(add_trailing(A.area.name, 30, " "), 1, 30) + menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_leading(DisplayPower(A.lastused_total), 6, " ")] [A.cell ? "[add_leading(round(A.cell.percent()), 3, " ")]% [chg[A.charging+1]]" : " N/C"]
    " menu += "" @@ -326,7 +331,7 @@ Code: if(active1 in GLOB.data_core.general) menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]
    " - menu += "Sex: [active1.fields["sex"]]
    " + menu += "Sex: [active1.fields["gender"]]
    " menu += "Age: [active1.fields["age"]]
    " menu += "Rank: [active1.fields["rank"]]
    " menu += "Fingerprint: [active1.fields["fingerprint"]]
    " @@ -370,7 +375,7 @@ Code: if(active1 in GLOB.data_core.general) menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]
    " - menu += "Sex: [active1.fields["sex"]]
    " + menu += "Sex: [active1.fields["gender"]]
    " menu += "Age: [active1.fields["age"]]
    " menu += "Rank: [active1.fields["rank"]]
    " menu += "Fingerprint: [active1.fields["fingerprint"]]
    " @@ -579,6 +584,22 @@ Code: if (54) // Beepsky, Medibot, Floorbot, and Cleanbot access menu = "

    [PDAIMG(medbot)] Bots Interlink

    " bot_control() + if (55) // Emoji Guidebook for mimes + menu = "

    [PDAIMG(emoji)] Emoji Guidebook

    " + var/static/list/emoji_icon_states + var/static/emoji_table + if(!emoji_table) + var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat) + var/list/collate = list("
    ") + for(var/emoji in sortList(icon_states(icon('icons/emoji.dmi')))) + var/tag = sheet.icon_tag("emoji-[emoji]") + collate += "" + collate += "
    [emoji][tag]

    " + emoji_table = collate.Join() + + menu += "
    To use an emoji in a pda message, refer to the guide and add \":\" around the emoji. Your PDA supports the following emoji:
    " + menu += emoji_table + if (99) //Newscaster message permission error menu = "
    ERROR : NOT AUTHORIZED [host_pda.id ? "" : "- ID SLOT EMPTY"]
    " @@ -679,6 +700,11 @@ Code: return playsound(src, 'sound/machines/terminal_select.ogg', 50, 1) + //emoji previews + if(href_list["emoji"]) + var/parse = emoji_parse(":[href_list["emoji"]]:") + to_chat(usr, parse) + //Bot control section! Viciously ripped from radios for being laggy and terrible. if(href_list["op"]) switch(href_list["op"]) diff --git a/code/game/objects/items/devices/desynchronizer.dm b/code/game/objects/items/devices/desynchronizer.dm index ff58af2405..0fa557f666 100644 --- a/code/game/objects/items/devices/desynchronizer.dm +++ b/code/game/objects/items/devices/desynchronizer.dm @@ -14,6 +14,7 @@ var/last_use = 0 var/next_use = 0 var/obj/effect/abstract/sync_holder/sync_holder + var/resync_timer /obj/item/desynchronizer/attack_self(mob/living/user) if(world.time < next_use) @@ -56,16 +57,20 @@ SEND_SIGNAL(AM, COMSIG_MOVABLE_SECLUDED_LOCATION) last_use = world.time icon_state = "desynchronizer-on" - addtimer(CALLBACK(src, .proc/resync), duration) + resync_timer = addtimer(CALLBACK(src, .proc/resync), duration , TIMER_STOPPABLE) /obj/item/desynchronizer/proc/resync() new /obj/effect/temp_visual/desynchronizer(sync_holder.drop_location()) QDEL_NULL(sync_holder) + if(resync_timer) + deltimer(resync_timer) + resync_timer = null icon_state = initial(icon_state) next_use = world.time + (world.time - last_use) // Could be 2*world.time-last_use but that would just be confusing /obj/item/desynchronizer/Destroy() - resync() + if(sync_holder) + resync() return ..() /obj/effect/abstract/sync_holder diff --git a/code/game/objects/items/devices/forcefieldprojector.dm b/code/game/objects/items/devices/forcefieldprojector.dm index df17a51c1b..905428ae1f 100644 --- a/code/game/objects/items/devices/forcefieldprojector.dm +++ b/code/game/objects/items/devices/forcefieldprojector.dm @@ -1,6 +1,6 @@ /obj/item/forcefield_projector name = "forcefield projector" - desc = "An experimental device that can create several forcefields at a distance." + desc = "An experimental device that can create several forcefields at a short distance." icon = 'icons/obj/device.dmi' icon_state = "signmaker_forcefield" slot_flags = ITEM_SLOT_BELT @@ -14,7 +14,7 @@ var/shield_integrity = 250 var/max_fields = 3 var/list/current_fields - var/field_distance_limit = 7 + var/field_distance_limit = 2 /obj/item/forcefield_projector/afterattack(atom/target, mob/user, proximity_flag) . = ..() diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index eff8f1b7dc..9a09be093d 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -73,8 +73,10 @@ GLOBAL_LIST_EMPTY(GPS_list) return ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show - ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height + // Variable window height, depending on how many GPS units there are + // to show, clamped to relatively safe range. + var/gps_window_height = CLAMP(325 + GLOB.GPS_list.len * 14, 325, 700) + ui = new(user, src, ui_key, "gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height ui.open() ui.set_autoupdate(state = updating) @@ -91,6 +93,8 @@ GLOBAL_LIST_EMPTY(GPS_list) var/turf/curr = get_turf(src) data["current"] = "[get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])" + data["currentArea"] = "[get_area_name(curr, TRUE)]" + data["currentCoords"] = "[curr.x], [curr.y], [curr.z]" var/list/signals = list() data["signals"] = list() @@ -104,16 +108,10 @@ GLOBAL_LIST_EMPTY(GPS_list) continue var/list/signal = list() signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS - signal["area"] = get_area_name(G, TRUE) - signal["coord"] = "[pos.x], [pos.y], [pos.z]" + signal["coords"] = "[pos.x], [pos.y], [pos.z]" if(pos.z == curr.z) //Distance/Direction calculations for same z-level only signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision. - var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful. - if(!direction) - direction = "CENTER" - signal["degrees"] = "N/A" - signal["direction"] = direction signals += list(signal) //Add this signal to the list of signals data["signals"] = signals diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index cc470466df..1f2f1ddda2 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -56,6 +56,14 @@ else return ..() +/obj/item/laser_pointer/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + if(!diode) + . += "The diode is missing." + else + . += "A class [diode.rating] laser diode is installed. It is screwed in place." + /obj/item/laser_pointer/afterattack(atom/target, mob/living/user, flag, params) . = ..() laser_act(target, user, params) diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index cef75942a0..f28aacc46c 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -101,7 +101,7 @@ if(href_list["reset_radio_short"]) pai.unshort_radio() if(href_list["setlaws"]) - var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1]) as message),1,MAX_MESSAGE_LEN) + var/newlaws = stripped_multiline_input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", MAX_MESSAGE_LEN) if(newlaws && pai) pai.add_supplied_law(0,newlaws) if(href_list["toggle_holo"]) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index d5cf6daabb..d499683fbc 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -61,7 +61,7 @@ var/mob/living/carbon/C = usr if(usr.stat || usr.restrained() || C.back == src) return - + if(!usr.canUseTopic(src, BE_CLOSE)) usr << browse(null, "window=radio") onclose(usr, "radio") @@ -127,7 +127,7 @@ /obj/item/electropack/ui_interact(mob/user) if(!ishuman(user)) return - + user.set_machine(src) var/dat = {" @@ -200,14 +200,14 @@ Code: /obj/item/electropack/shockcollar/attackby(obj/item/W, mob/user, params) //moves it here because on_click is being bad if(istype(W, /obj/item/pen)) - var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text + var/t = stripped_input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot", MAX_NAME_LEN) if(t) - tagname = copytext(sanitize(t), 1, MAX_NAME_LEN) - name = "[initial(name)] - [tagname]" + tagname = t + name = "[initial(name)] - [t]" else return ..() -/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this +/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this var/dat = {" Frequency/Code for shock collar:
    diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 8c6666085e..e04501144e 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -26,6 +26,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( slot_flags = ITEM_SLOT_EARS var/obj/item/encryptionkey/keyslot2 = null dog_fashion = null + var/bowman = FALSE /obj/item/radio/headset/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins putting \the [src]'s antenna up [user.p_their()] nose! It looks like [user.p_theyre()] trying to give [user.p_them()]self cancer!") @@ -52,6 +53,11 @@ GLOBAL_LIST_INIT(channel_tokens, list( else . += "A small screen on the headset flashes, it's too small to read without holding or wearing the headset." +/obj/item/radio/headset/ComponentInitialize() + . = ..() + if (bowman) + AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) + /obj/item/radio/headset/Initialize() . = ..() recalculateChannels() @@ -81,10 +87,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs." icon_state = "syndie_headset" item_state = "syndie_headset" - -/obj/item/radio/headset/syndicate/alt/ComponentInitialize() - . = ..() - AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) + bowman = TRUE /obj/item/radio/headset/syndicate/alt/leader name = "team leader headset" @@ -112,10 +115,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( desc = "This is used by your elite security force. Protects ears from flashbangs." icon_state = "sec_headset_alt" item_state = "sec_headset_alt" - -/obj/item/radio/headset/headset_sec/alt/ComponentInitialize() - . = ..() - AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) + bowman = TRUE /obj/item/radio/headset/headset_eng name = "engineering radio headset" @@ -161,10 +161,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( desc = "The headset of the boss. Protects ears from flashbangs." icon_state = "com_headset_alt" item_state = "com_headset_alt" - -/obj/item/radio/headset/heads/captain/alt/ComponentInitialize() - . = ..() - AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) + bowman = TRUE /obj/item/radio/headset/heads/rd name = "\proper the research director's headset" @@ -183,10 +180,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs." icon_state = "com_headset_alt" item_state = "com_headset_alt" - -/obj/item/radio/headset/heads/hos/ComponentInitialize() - . = ..() - AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) + bowman = TRUE /obj/item/radio/headset/heads/ce name = "\proper the chief engineer's headset" @@ -258,10 +252,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( icon_state = "cent_headset_alt" item_state = "cent_headset_alt" keyslot = null - -/obj/item/radio/headset/headset_cent/alt/ComponentInitialize() - . = ..() - AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) + bowman = TRUE /obj/item/radio/headset/ai name = "\proper Integrated Subspace Transceiver " @@ -273,7 +264,11 @@ GLOBAL_LIST_INIT(channel_tokens, list( /obj/item/radio/headset/attackby(obj/item/W, mob/user, params) user.set_machine(src) - + if (istype(W,/obj/item/headsetupgrader)) + if (!bowman) + to_chat(user,"You upgrade [src].") + bowmanize() + qdel(W) if(istype(W, /obj/item/screwdriver)) if(keyslot || keyslot2) for(var/ch_name in channels) @@ -341,3 +336,24 @@ GLOBAL_LIST_INIT(channel_tokens, list( use_command = !use_command to_chat(user, "You toggle high-volume mode [use_command ? "on" : "off"].") return TRUE + +/obj/item/radio/headset/proc/bowmanize() + cut_overlays() + var/icon/yeas = icon(icon,icon_state) + icon_state = "antenna_alt" + var/mutable_appearance/center = mutable_appearance(icon,"center_alt") + center.color = yeas.GetPixel(15,18) + var/mutable_appearance/centeralt = mutable_appearance(icon,"centeralt_alt") + centeralt.color = yeas.GetPixel(14,22) + var/mutable_appearance/centercenter = mutable_appearance(icon,"centercenter_alt") + centercenter.color = yeas.GetPixel(13,19) + var/mutable_appearance/centerpixel = mutable_appearance(icon,"centerpixel_alt") + centerpixel.color = yeas.GetPixel(13,21) + add_overlay(center) + add_overlay(centeralt) + add_overlay(centercenter) + add_overlay(centerpixel) + name = replacetext(name,"headset", "bowman headset") + desc = "[desc] Protects ears from flashbangs." + bowman = TRUE + AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 8ccd15e397..b87b7b11bd 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -112,7 +112,14 @@ . = ..() ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "radio", name, 370, 220 + channels.len * 22, master_ui, state) + var/ui_width = 360 + var/ui_height = 106 + if(subspace_transmission) + if(channels.len > 0) + ui_height += 6 + channels.len * 21 + else + ui_height += 24 + ui = new(user, src, ui_key, "radio", name, ui_width, ui_height, master_ui, state) ui.open() /obj/item/radio/ui_data(mob/user) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 57c5a22de0..c23311cf22 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -28,7 +28,7 @@ SLIME SCANNER /obj/item/t_scanner/attack_self(mob/user) on = !on - icon_state = copytext(icon_state, 1, length(icon_state))+"[on]" + icon_state = copytext_char(icon_state, 1, -1) + "[on]" if(on) START_PROCESSING(SSobj, src) @@ -407,19 +407,17 @@ SLIME SCANNER // Blood Level if(M.has_dna()) var/mob/living/carbon/C = M - var/blood_id = C.get_blood_id() - if(blood_id) + var/blood_typepath = C.get_blood_id() + if(blood_typepath) if(ishuman(C)) if(H.bleed_rate) msg += "Subject is bleeding!\n" var/blood_percent = round((C.scan_blood_volume() / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100) var/blood_type = C.dna.blood_type - if(blood_id != ("blood" || "jellyblood"))//special blood substance - var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id] + if(!(blood_typepath in GLOB.blood_reagent_types)) + var/datum/reagent/R = GLOB.chemical_reagents_list[blood_typepath] if(R) blood_type = R.name - else - blood_type = blood_id if(C.scan_blood_volume() <= (BLOOD_VOLUME_SAFE*C.blood_ratio) && C.scan_blood_volume() > (BLOOD_VOLUME_OKAY*C.blood_ratio)) msg += "LOW blood level [blood_percent] %, [C.scan_blood_volume()] cl, type: [blood_type]\n" else if(C.scan_blood_volume() <= (BLOOD_VOLUME_OKAY*C.blood_ratio)) diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index fc768cd38e..64e2830dd4 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -251,3 +251,9 @@ effective or pretty fucking useless. else GLOB.active_jammers -= src update_icon() + +/obj/item/headsetupgrader + name = "headset upgrader" + desc = "A tool that can be used to upgrade a normal headset to be able to protect from flashbangs." + icon = 'icons/obj/device.dmi' + icon_state = "headset_upgrade" diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index f27884d3ae..b1dd9be376 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -160,7 +160,7 @@ /obj/item/dice/attack_self(mob/user) diceroll(user) -/obj/item/dice/throw_impact(atom/target) +/obj/item/dice/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) diceroll(thrownby) . = ..() diff --git a/code/game/objects/items/eightball.dm b/code/game/objects/items/eightball.dm index b37c147357..c4a15a1871 100644 --- a/code/game/objects/items/eightball.dm +++ b/code/game/objects/items/eightball.dm @@ -54,7 +54,7 @@ to_chat(user, "[src] was shaken recently, it needs time to settle.") return - user.visible_message("[user] starts shaking [src].", "You start shaking [src].", "You hear shaking and sloshing.") + user.visible_message("[user] starts shaking [src].", "You start shaking [src].", "You hear shaking and sloshing.") shaking = TRUE @@ -95,16 +95,47 @@ // except it actually ASKS THE DEAD (wooooo) /obj/item/toy/eightball/haunted - shake_time = 150 - cooldown_time = 1800 + shake_time = 30 SECONDS + cooldown_time = 3 MINUTES flags_1 = HEAR_1 var/last_message var/selected_message - var/list/votes + //these kind of store the same thing but one is easier to work with. + var/list/votes = list() + var/list/voted = list() + var/static/list/haunted_answers = list( + "yes" = list( + "It is certain", + "It is decidedly so", + "Without a doubt", + "Yes definitely", + "You may rely on it", + "As I see it, yes", + "Most likely", + "Outlook good", + "Yes", + "Signs point to yes" + ), + "maybe" = list( + "Reply hazy try again", + "Ask again later", + "Better not tell you now", + "Cannot predict now", + "Concentrate and ask again" + ), + "no" = list( + "Don't count on it", + "My reply is no", + "My sources say no", + "Outlook not so good", + "Very doubtful" + ) + ) /obj/item/toy/eightball/haunted/Initialize(mapload) . = ..() - votes = list() + for (var/answer in haunted_answers) + votes[answer] = 0 GLOB.poi_list |= src /obj/item/toy/eightball/haunted/Destroy() @@ -122,7 +153,7 @@ interact(user) return ..() -/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode, atom/movable/source) +/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode) . = ..() last_message = raw_message @@ -137,38 +168,31 @@ if(isobserver(usr)) interact(usr) -/obj/item/toy/eightball/haunted/proc/get_vote_tallies() - var/list/answers = list() - for(var/ckey in votes) - var/selected = votes[ckey] - if(selected in answers) - answers[selected]++ - else - answers[selected] = 1 - - return answers - - /obj/item/toy/eightball/haunted/get_answer() - if(!votes.len) - return pick(possible_answers) + var/top_amount = 0 + var/top_vote - var/list/tallied_votes = get_vote_tallies() + for(var/vote in votes) + var/amount_of_votes = length(votes[vote]) + if(amount_of_votes > top_amount) + top_vote = vote + top_amount = amount_of_votes + //If one option actually has votes and there's a tie, pick between them 50/50 + else if(top_amount && amount_of_votes == top_amount && prob(50)) + top_vote = vote + top_amount = amount_of_votes - // I miss python sorting, then I wouldn't have to muck about with - // all this - var/most_popular_answer - var/most_amount = 0 - // yes, if there is a tie, there is an arbitary decision - // but we never said the spirit world was fair - for(var/A in tallied_votes) - var/amount = tallied_votes[A] - if(amount > most_amount) - most_popular_answer = A + if(isnull(top_vote)) + top_vote = pick(votes) - return most_popular_answer + for(var/vote in votes) + votes[vote] = 0 -/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.observer_state) + voted.Cut() + + return top_vote + +/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.always_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) @@ -179,21 +203,13 @@ var/list/data = list() data["shaking"] = shaking data["question"] = selected_message - var/list/tallied_votes = get_vote_tallies() data["answers"] = list() - - for(var/pa in possible_answers) + for(var/pa in haunted_answers) var/list/L = list() L["answer"] = pa - var/amount = 0 - if(pa in tallied_votes) - amount = tallied_votes[pa] - L["amount"] = amount - var/selected = FALSE - if(votes[user.ckey] == pa) - selected = TRUE - L["selected"] = selected + L["amount"] = votes[pa] + L["selected"] = voted[user.ckey] data["answers"] += list(L) return data @@ -206,8 +222,11 @@ switch(action) if("vote") var/selected_answer = params["answer"] - if(!(selected_answer in possible_answers)) + if(!(selected_answer in haunted_answers)) + return + if(user.ckey in voted) return else - votes[user.ckey] = selected_answer - . = TRUE + votes[selected_answer] += 1 + voted[user.ckey] = selected_answer + . = TRUE \ No newline at end of file diff --git a/code/game/objects/items/grenades/grenade.dm b/code/game/objects/items/grenades/grenade.dm index 033ea9e791..77b4b33a8c 100644 --- a/code/game/objects/items/grenades/grenade.dm +++ b/code/game/objects/items/grenades/grenade.dm @@ -34,12 +34,12 @@ /obj/item/grenade/proc/clown_check(mob/living/carbon/human/user) var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY) - if(clumsy && (clumsy_check == GRENADE_CLUMSY_FUMBLE)) - if(prob(50)) + if(clumsy) + if(clumsy_check == GRENADE_CLUMSY_FUMBLE && prob(50)) to_chat(user, "Huh? How does this thing work?") preprime(user, 5, FALSE) return FALSE - else if(!clumsy && (clumsy_check == GRENADE_NONCLUMSY_FUMBLE)) + else if(clumsy_check == GRENADE_NONCLUMSY_FUMBLE && !(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY))) to_chat(user, "You pull the pin on [src]. Attached to it is a pink ribbon that says, \"HONK\"") preprime(user, 5, FALSE) return FALSE @@ -93,9 +93,8 @@ var/obj/item/I = loc I.grenade_prime_react(src) - -/obj/item/grenade/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/screwdriver)) +/obj/item/grenade/tool_act(mob/living/user, obj/item/I, tool_behaviour) + if(tool_behaviour == TOOL_SCREWDRIVER) switch(det_time) if ("1") det_time = 10 diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 849e14b476..8ce0f33307 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -310,6 +310,7 @@ trap_damage = 0 item_flags = DROPDEL flags_1 = NONE + breakouttime = 50 /obj/item/restraints/legcuffs/beartrap/energy/New() ..() @@ -340,7 +341,7 @@ return playsound(src.loc,'sound/weapons/bolathrow.ogg', 75, 1) -/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom) +/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed, return//abort var/mob/living/carbon/C = hit_atom @@ -368,7 +369,7 @@ w_class = WEIGHT_CLASS_SMALL breakouttime = 60 -/obj/item/restraints/legcuffs/bola/energy/throw_impact(atom/hit_atom) +/obj/item/restraints/legcuffs/bola/energy/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(iscarbon(hit_atom)) var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(hit_atom)) B.Crossed(hit_atom) diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index e92c9b2d2e..47cf6f4ba7 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -92,6 +92,14 @@ creation_time = 0 max_signs = 3 +/obj/item/holosign_creator/combifan + name = "ATMOS holo-combifan projector" + desc = "A holographic projector that creates holographic combi-fans that prevent changes in atmosphere and temperature conditions. Somehow." + icon_state = "signmaker_atmos" + holosign_type = /obj/structure/holosign/barrier/combifan + creation_time = 0 + max_signs = 3 + /obj/item/holosign_creator/medical name = "\improper PENLITE barrier projector" desc = "A holographic projector that creates PENLITE holobarriers. Useful during quarantines since they halt those with malicious diseases." diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 5367f3461c..45abd4fb49 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -72,20 +72,21 @@ display_names += list(initial(A.name) = A) var/choice = input(M,"What holy armor kit would you like to order?","Holy Armor Theme") as null|anything in display_names - if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type) + var/turf/T = get_turf(M) + if(!T || QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type) return var/index = display_names.Find(choice) var/A = holy_armor_list[index] GLOB.holy_armor_type = A - var/holy_armor_box = new A + var/holy_armor_box = new A(T) SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]") if(holy_armor_box) qdel(src) - M.put_in_active_hand(holy_armor_box)///YOU COMPILED + M.put_in_hands(holy_armor_box) /obj/item/storage/box/holy name = "Templar Kit" diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index fde14a85d9..4b071d6a34 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -333,13 +333,13 @@ if(proximity_flag) consume_everything(target) -/obj/item/melee/supermatter_sword/throw_impact(target) +/obj/item/melee/supermatter_sword/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() - if(ismob(target)) - var/mob/M + if(ismob(hit_atom)) + var/mob/M = hit_atom if(src.loc == M) M.dropItemToGround(src) - consume_everything(target) + consume_everything(hit_atom) /obj/item/melee/supermatter_sword/pickup(user) ..() diff --git a/code/game/objects/items/miscellaneous.dm b/code/game/objects/items/miscellaneous.dm index 9837936e5f..ee169cc661 100644 --- a/code/game/objects/items/miscellaneous.dm +++ b/code/game/objects/items/miscellaneous.dm @@ -19,3 +19,11 @@ icon_state = "skub" w_class = WEIGHT_CLASS_BULKY attack_verb = list("skubbed") + +/obj/item/supermatterspray + name = "supermatter spray" + desc = "A spray bottle containing some kind of magical spray to fix the SM. \"Do not inhale.\" is written on the side. Unless aimed at the supermatter, it does nothing." + icon = 'icons/obj/supermatter.dmi' + icon_state = "supermatterspray" + w_class = WEIGHT_CLASS_SMALL + var/usesleft = 2 \ No newline at end of file diff --git a/code/game/objects/items/singularityhammer.dm b/code/game/objects/items/singularityhammer.dm index f55dae67db..86f0ad4936 100644 --- a/code/game/objects/items/singularityhammer.dm +++ b/code/game/objects/items/singularityhammer.dm @@ -105,10 +105,10 @@ playsound(src.loc, "sparks", 50, 1) shock(M) -/obj/item/twohanded/mjollnir/throw_impact(atom/target) +/obj/item/twohanded/mjollnir/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() - if(isliving(target)) - shock(target) + if(isliving(hit_atom)) + shock(hit_atom) /obj/item/twohanded/mjollnir/update_icon() //Currently only here to fuck with the on-mob icons. icon_state = "mjollnir[wielded]" diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index bb1a475f1f..e2357e8f6d 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -35,7 +35,7 @@ /obj/item/stack/ore/bluespace_crystal/proc/blink_mob(mob/living/L) do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) -/obj/item/stack/ore/bluespace_crystal/throw_impact(atom/hit_atom) +/obj/item/stack/ore/bluespace_crystal/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) // not caught in mid-air visible_message("[src] fizzles and disappears upon impact!") var/turf/T = get_turf(hit_atom) diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index a33ae9c4a9..21de34faa1 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -10,7 +10,15 @@ */ GLOBAL_LIST_INIT(glass_recipes, list ( \ new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \ - new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \ + new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \ + null, \ + new/datum/stack_recipe_list("glass working bases", list( \ + new/datum/stack_recipe("chem dish", /obj/item/glasswork/glass_base/dish, 10), \ + new/datum/stack_recipe("lens", /obj/item/glasswork/glass_base/glass_lens, 15), \ + new/datum/stack_recipe("spout flask", /obj/item/glasswork/glass_base/spouty, 20), \ + new/datum/stack_recipe("small bulb flask", /obj/item/glasswork/glass_base/flask_small, 5), \ + new/datum/stack_recipe("large bottle flask", /obj/item/glasswork/glass_base/flask_large, 15), \ + )), \ )) /obj/item/stack/sheet/glass @@ -26,6 +34,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ grind_results = list(/datum/reagent/silicon = 20) point_value = 1 tableVariant = /obj/structure/table/glass + shard_type = /obj/item/shard /obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins to slice [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -93,6 +102,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ merge_type = /obj/item/stack/sheet/plasmaglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10) tableVariant = /obj/structure/table/plasmaglass + shard_type = /obj/item/shard/plasma /obj/item/stack/sheet/plasmaglass/fifty amount = 50 @@ -120,7 +130,9 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ else return ..() - +/obj/item/stack/sheet/plasmaglass/on_solar_construction(obj/machinery/power/solar/S) + S.obj_integrity *= 1.2 + S.efficiency *= 1.2 /* * Reinforced glass sheets @@ -145,11 +157,15 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ merge_type = /obj/item/stack/sheet/rglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10) point_value = 4 + shard_type = /obj/item/shard /obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) add_fingerprint(user) ..() +/obj/item/stack/sheet/rglass/on_solar_construction(obj/machinery/power/solar/S) + S.obj_integrity *= 2 + /obj/item/stack/sheet/rglass/cyborg materials = list() var/datum/robot_energy_storage/glasource @@ -188,6 +204,11 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ merge_type = /obj/item/stack/sheet/plasmarglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10) point_value = 23 + shard_type = /obj/item/shard/plasma + +/obj/item/stack/sheet/plasmarglass/on_solar_construction(obj/machinery/power/solar/S) + S.obj_integrity *= 2.2 + S.efficiency *= 1.2 /obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.prglass_recipes @@ -207,6 +228,11 @@ GLOBAL_LIST_INIT(titaniumglass_recipes, list( armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/titaniumglass + shard_type = /obj/item/shard + +/obj/item/stack/sheet/titaniumglass/on_solar_construction(obj/machinery/power/solar/S) + S.obj_integrity *= 2.5 + S.efficiency *= 1.5 /obj/item/stack/sheet/titaniumglass/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.titaniumglass_recipes @@ -226,11 +252,16 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plastitaniumglass + shard_type = /obj/item/shard /obj/item/stack/sheet/plastitaniumglass/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.plastitaniumglass_recipes return ..() +/obj/item/stack/sheet/titaniumglass/on_solar_construction(obj/machinery/power/solar/S) + S.obj_integrity *= 2 + S.efficiency *= 2 + /obj/item/shard name = "shard" desc = "A nasty looking shard of glass." diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index a80f0d5a3b..2bd7dd0d38 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -154,6 +154,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = TRUE), \ new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 50), \ + new/datum/stack_recipe("crate", /obj/structure/closet/crate, 5, time = 90, one_per_turf = TRUE), \ null, \ new /datum/stack_recipe_list("airlock assemblies", list( \ new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 6, time = 50, one_per_turf = 1, on_floor = 1), \ @@ -277,6 +278,9 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ recipes = GLOB.wood_recipes return ..() +/obj/item/stack/sheet/mineral/wood/twenty + amount = 20 + /obj/item/stack/sheet/mineral/wood/fifty amount = 50 @@ -306,6 +310,15 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \ recipes = GLOB.bamboo_recipes return ..() +/obj/item/stack/sheet/mineral/bamboo/ten + amount = 10 + +/obj/item/stack/sheet/mineral/bamboo/twenty + amount = 20 + +/obj/item/stack/sheet/mineral/bamboo/fifty + amount = 50 + /* * Cloth */ @@ -782,3 +795,4 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra merge_type = /obj/item/stack/sheet/cotton/durathread pull_effort = 70 loom_result = /obj/item/stack/sheet/durathread + diff --git a/code/game/objects/items/stacks/sheets/sheets.dm b/code/game/objects/items/stacks/sheets/sheets.dm index af0dca02d3..b7ab760659 100644 --- a/code/game/objects/items/stacks/sheets/sheets.dm +++ b/code/game/objects/items/stacks/sheets/sheets.dm @@ -15,4 +15,15 @@ var/point_value = 0 //turn-in value for the gulag stacker - loosely relative to its rarity var/is_fabric = FALSE //is this a valid material for the loom? var/loom_result //result from pulling on the loom - var/pull_effort = 0 //amount of delay when pulling on the loom \ No newline at end of file + var/pull_effort = 0 //amount of delay when pulling on the loom + var/shard_type // the shard debris typepath left over by solar panels and windows etc. + +/** + * Called on the glass sheet upon solar construction (duh): + * Different glass sheets can modify different stas/vars, such as obj_integrity or efficiency + * and possibly extra effects if you wish to code them. + * Keep in mind the solars' max_integrity is set equal to the obj_integrity later, + * so you won't have to do so here. + */ +/obj/item/stack/sheet/proc/on_solar_construction(/obj/machinery/power/solar/S) + return diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 8065cd5723..36c4992e8f 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -342,7 +342,7 @@ merge(o) . = ..() -/obj/item/stack/hitby(atom/movable/AM, skip, hitpush) +/obj/item/stack/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(istype(AM, merge_type)) merge(AM) . = ..() @@ -399,11 +399,14 @@ . = ..() /obj/item/stack/proc/copy_evidences(obj/item/stack/from) - blood_DNA = from.blood_DNA - fingerprints = from.fingerprints - fingerprintshidden = from.fingerprintshidden - fingerprintslast = from.fingerprintslast - //TODO bloody overlay + if(from.blood_DNA) + blood_DNA = from.blood_DNA.Copy() + if(from.fingerprints) + fingerprints = from.fingerprints.Copy() + if(from.fingerprintshidden) + fingerprintshidden = from.fingerprintshidden.Copy() + if(from.fingerprintslast) + fingerprintslast = from.fingerprintslast /obj/item/stack/microwave_act(obj/machinery/microwave/M) if(istype(M) && M.dirty < 100) diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 18acb5e14d..fa4e5a3886 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -233,39 +233,111 @@ turf_type = /turf/open/floor/carpet/royalblue tableVariant = /obj/structure/table/wood/fancy/royalblue +/obj/item/stack/tile/carpet/ten + amount = 10 + +/obj/item/stack/tile/carpet/twenty + amount = 20 + /obj/item/stack/tile/carpet/fifty amount = 50 +/obj/item/stack/tile/carpet/black/ten + amount = 10 + +/obj/item/stack/tile/carpet/black/twenty + amount = 20 + /obj/item/stack/tile/carpet/black/fifty amount = 50 +/obj/item/stack/tile/carpet/blackred/ten + amount = 10 + +/obj/item/stack/tile/carpet/blackred/twenty + amount = 20 + /obj/item/stack/tile/carpet/blackred/fifty amount = 50 +/obj/item/stack/tile/carpet/monochrome/ten + amount = 10 + +/obj/item/stack/tile/carpet/monochrome/twenty + amount = 20 + /obj/item/stack/tile/carpet/monochrome/fifty amount = 50 +/obj/item/stack/tile/carpet/blue/ten + amount = 10 + +/obj/item/stack/tile/carpet/blue/twenty + amount = 20 + /obj/item/stack/tile/carpet/blue/fifty amount = 50 +/obj/item/stack/tile/carpet/cyan/ten + amount = 10 + +/obj/item/stack/tile/carpet/cyan/twenty + amount = 20 + /obj/item/stack/tile/carpet/cyan/fifty amount = 50 +/obj/item/stack/tile/carpet/green/ten + amount = 10 + +/obj/item/stack/tile/carpet/green/twenty + amount = 20 + /obj/item/stack/tile/carpet/green/fifty amount = 50 +/obj/item/stack/tile/carpet/orange/ten + amount = 10 + +/obj/item/stack/tile/carpet/orange/twenty + amount = 20 + /obj/item/stack/tile/carpet/orange/fifty amount = 50 +/obj/item/stack/tile/carpet/purple/ten + amount = 10 + +/obj/item/stack/tile/carpet/purple/twenty + amount = 20 + /obj/item/stack/tile/carpet/purple/fifty amount = 50 +/obj/item/stack/tile/carpet/red/ten + amount = 10 + +/obj/item/stack/tile/carpet/red/twenty + amount = 20 + /obj/item/stack/tile/carpet/red/fifty amount = 50 +/obj/item/stack/tile/carpet/royalblack/ten + amount = 10 + +/obj/item/stack/tile/carpet/royalblack/twenty + amount = 20 + /obj/item/stack/tile/carpet/royalblack/fifty amount = 50 +/obj/item/stack/tile/carpet/royalblue/ten + amount = 10 + +/obj/item/stack/tile/carpet/royalblue/twenty + amount = 20 + /obj/item/stack/tile/carpet/royalblue/fifty amount = 50 diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index d5aa43148c..daddc403b2 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -322,6 +322,26 @@ for(var/i in 1 to 5) new /obj/item/grenade/empgrenade(src) +/obj/item/storage/box/minibombs + name = "box of syndicate minibombs" + desc = "A box containing 2 highly explosive syndicate minibombs." + icon_state = "syndiebox" + illustration = "frag" + +/obj/item/storage/box/minibombs/PopulateContents() + new /obj/item/grenade/syndieminibomb(src) + new /obj/item/grenade/syndieminibomb(src) + +/obj/item/storage/box/bombananas + name = "box of bombananas" + desc = "A box containing 2 highly explosive bombananas. Discard peel at enemy after consumption." + icon_state = "syndiebox" + illustration = "frag" + +/obj/item/storage/box/bombananas/PopulateContents() + new /obj/item/reagent_containers/food/snacks/grown/banana/bombanana(src) + new /obj/item/reagent_containers/food/snacks/grown/banana/bombanana(src) + /obj/item/storage/box/trackimp name = "boxed tracking implant kit" desc = "Box full of scum-bag tracking utensils." @@ -1267,4 +1287,4 @@ /obj/item/storage/box/marshmallow/PopulateContents() for (var/i in 1 to 5) - new /obj/item/reagent_containers/food/snacks/marshmallow(src) \ No newline at end of file + new /obj/item/reagent_containers/food/snacks/marshmallow(src) diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm index 78f306df6e..92e09022b2 100644 --- a/code/game/objects/items/storage/fancy.dm +++ b/code/game/objects/items/storage/fancy.dm @@ -12,6 +12,7 @@ * Cigarette Box * Cigar Case * Heart Shaped Box w/ Chocolates + * Ring Box */ /obj/item/storage/fancy @@ -352,3 +353,33 @@ var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.max_items = 8 STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/tinychocolate)) + +/* + * Ring Box + */ + +/obj/item/storage/fancy/ringbox + name = "ring box" + desc = "A tiny box covered in soft red felt made for holding rings." + icon = 'icons/obj/ring.dmi' + icon_state = "gold ringbox" + icon_type = "gold ring" + w_class = WEIGHT_CLASS_TINY + spawn_type = /obj/item/clothing/gloves/ring + +/obj/item/storage/fancy/ringbox/ComponentInitialize() + . = ..() + var/datum/component/storage/STR = GetComponent(/datum/component/storage) + STR.max_items = 1 + STR.can_hold = typecacheof(list(/obj/item/clothing/gloves/ring)) + +/obj/item/storage/fancy/ringbox/diamond + icon_state = "diamond ringbox" + icon_type = "diamond ring" + spawn_type = /obj/item/clothing/gloves/ring/diamond + +/obj/item/storage/fancy/ringbox/silver + icon_state = "silver ringbox" + icon_type = "silver ring" + spawn_type = /obj/item/clothing/gloves/ring/silver + diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 31efabf210..bfffe0fc60 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -35,7 +35,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) /obj/item/storage/toolbox/update_icon() ..() cut_overlays() - if(blood_DNA && blood_DNA.len) + if(length(blood_DNA)) add_blood_overlay() if(has_latches) var/icon/I = icon('icons/obj/storage.dmi', latches) @@ -251,16 +251,12 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) new /obj/item/ammo_box/a762(src) new /obj/item/ammo_box/a762(src) -/obj/item/storage/toolbox/gold_real +/obj/item/storage/toolbox/plastitanium/gold_real name = "golden toolbox" desc = "A larger then normal toolbox made of gold plated plastitanium." icon_state = "gold" item_state = "toolbox_gold" has_latches = FALSE - force = 16 // Less then a spear - throwforce = 14 - throw_speed = 5 - throw_range = 10 /obj/item/storage/toolbox/gold_real/PopulateContents() new /obj/item/screwdriver/nuke(src) @@ -293,7 +289,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) desc = replacetext(desc, "robust", "safe") desc = replacetext(desc, "heavier", "bouncier") DISABLE_BITFIELD(flags_1, CONDUCT_1) - materials = null + materials = typelist("materials", null) damtype = STAMINA force += 3 //to compensate the higher stamina K.O. threshold compared to actual health. throwforce += 3 @@ -317,8 +313,8 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) flags_1 = null materials = null damtype = STAMINA - force = 17 - throwforce = 17 + force = 15 + throwforce = 15 attack_verb = list("robusted", "bounced") can_rubberify = FALSE //we are already the future. diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 35429c2f42..611870912c 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -343,7 +343,7 @@ new /obj/item/implanter/radio/syndicate(src) /obj/item/storage/box/syndie_kit/centcom_costume/PopulateContents() - new /obj/item/clothing/under/rank/centcom_officer(src) + new /obj/item/clothing/under/rank/centcom_officer/syndicate(src) new /obj/item/clothing/shoes/sneakers/black(src) new /obj/item/clothing/gloves/color/black(src) new /obj/item/radio/headset/headset_cent/empty(src) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index f34fc6a9a3..946eb1eb7b 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -41,7 +41,7 @@ cell = new preload_cell_type(src) update_icon() -/obj/item/melee/baton/throw_impact(atom/hit_atom) +/obj/item/melee/baton/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() //Only mob/living types have stun handling if(status && prob(throw_hit_chance) && iscarbon(hit_atom)) diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index f763fe87fc..55d8c8256b 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -156,7 +156,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "tanks", name, 420, 200, master_ui, state) + ui = new(user, src, ui_key, "tanks", name, 400, 120, master_ui, state) ui.open() /obj/item/tank/ui_data(mob/user) diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index d52c280f1b..9b9fae7c8f 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -259,7 +259,7 @@ if(proximity && ismovableatom(O) && O != sliver) Consume(O, user) -/obj/item/hemostat/supermatter/throw_impact(atom/hit_atom) // no instakill supermatter javelins +/obj/item/hemostat/supermatter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) // no instakill supermatter javelins if(sliver) sliver.forceMove(loc) to_chat(usr, "\The [sliver] falls out of \the [src] as you throw them.") diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index cf891f5a47..8f5a6e8e0b 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -84,7 +84,7 @@ else return ..() -/obj/item/toy/balloon/throw_impact(atom/hit_atom) +/obj/item/toy/balloon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) //was it caught by a mob? balloon_burst(hit_atom) @@ -531,7 +531,7 @@ /obj/item/toy/snappop/fire_act(exposed_temperature, exposed_volume) pop_burst() -/obj/item/toy/snappop/throw_impact(atom/hit_atom) +/obj/item/toy/snappop/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) pop_burst() @@ -1152,7 +1152,7 @@ icon_state = "minimeteor" w_class = WEIGHT_CLASS_SMALL -/obj/item/toy/minimeteor/throw_impact(atom/hit_atom) +/obj/item/toy/minimeteor/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) playsound(src, 'sound/effects/meteorimpact.ogg', 40, 1) for(var/mob/M in urange(10, src)) @@ -1201,7 +1201,7 @@ if(user.dropItemToGround(src)) throw_at(target, throw_range, throw_speed) -/obj/item/toy/snowball/throw_impact(atom/hit_atom) +/obj/item/toy/snowball/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) playsound(src, 'sound/effects/pop.ogg', 20, 1) qdel(src) @@ -1244,7 +1244,7 @@ /obj/item/toy/clockwork_watch/examine(mob/user) . = ..() - . += "Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]" + . += "Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]" /* * Toy Dagger diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index b9862c3423..fc9e138f4b 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -25,8 +25,8 @@ */ /obj/item/twohanded var/wielded = 0 - var/force_unwielded = 0 - var/force_wielded = 0 + var/force_unwielded // default to null, the number force will be set to on unwield() + var/force_wielded // same as above but for wield() var/wieldsound = null var/unwieldsound = null var/slowdown_wielded = 0 @@ -38,9 +38,9 @@ wielded = 0 if(!isnull(force_unwielded)) force = force_unwielded - var/sf = findtext(name," (Wielded)") + var/sf = findtext(name, " (Wielded)", -10)//10 == length(" (Wielded)") if(sf) - name = copytext(name,1,sf) + name = copytext(name, 1, sf) else //something wrong name = "[initial(name)]" update_icon() @@ -73,7 +73,7 @@ to_chat(user, "You don't have enough intact hands.") return wielded = 1 - if(force_wielded) + if(!isnull(force_wielded)) force = force_wielded name = "[name] (Wielded)" update_icon() @@ -347,7 +347,6 @@ icon_state = "dualsaber[item_color][wielded]" else icon_state = "dualsaber0" - clean_blood() /obj/item/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user) @@ -738,7 +737,7 @@ on = !on to_chat(user, "As you pull the starting cord dangling from [src], [on ? "it begins to whirr." : "the chain stops moving."]") force = on ? force_on : initial(force) - throwforce = on ? force_on : initial(force) + throwforce = on ? force_on : force icon_state = "chainsaw_[on ? "on" : "off"]" var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering) butchering.butchering_enabled = on diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index b7b25f0b5a..cd6cc5f520 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -312,23 +312,27 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 attack_verb = list("stubbed", "poked") resistance_flags = FIRE_PROOF var/extended = 0 + var/extended_force = 20 + var/extended_throwforce = 23 + var/extended_icon_state = "switchblade_ext" + var/retracted_icon_state = "switchblade" /obj/item/switchblade/attack_self(mob/user) extended = !extended playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1) if(extended) - force = 20 + force = extended_force w_class = WEIGHT_CLASS_NORMAL - throwforce = 23 - icon_state = "switchblade_ext" + throwforce = extended_throwforce + icon_state = extended_icon_state attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' sharpness = IS_SHARP else - force = 3 + force = initial(force) w_class = WEIGHT_CLASS_SMALL - throwforce = 5 - icon_state = "switchblade" + throwforce = initial(throwforce) + icon_state = retracted_icon_state attack_verb = list("stubbed", "poked") hitsound = 'sound/weapons/genhit.ogg' sharpness = IS_BLUNT @@ -337,6 +341,25 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 user.visible_message("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!") return (BRUTELOSS) +/obj/item/switchblade/crafted + icon_state = "switchblade_ms" + desc = "A concealable spring-loaded knife." + force = 2 + throwforce = 3 + extended_force = 15 + extended_throwforce = 18 + extended_icon_state = "switchblade_ext_ms" + retracted_icon_state = "switchblade_ms" + +/obj/item/switchblade/crafted/attackby(obj/item/I, mob/user, params) + . = ..() + if(istype(I, /obj/item/stack/sheet/mineral/silver)) + icon_state = extended ? "switchblade_ext_msf" : "switchblade_msf" + extended_icon_state = "switchblade_ext_msf" + retracted_icon_state = "switchblade_msf" + icon_state = "switchblade_msf" + to_chat(user, "You use part of the silver to improve your Switchblade. Stylish!") + /obj/item/phone name = "red phone" desc = "Should anything ever go wrong..." diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 70a05a8d40..2d99f0e073 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -46,7 +46,7 @@ if(BURN) playsound(src.loc, 'sound/items/welder.ogg', 100, 1) -/obj/hitby(atom/movable/AM) +/obj/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) ..() var/throwdamage = AM.throwforce if(isobj(AM)) @@ -126,6 +126,17 @@ if(. && !play_soundeffect) playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) +/obj/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction) + return TRUE + +/obj/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction) + collision_damage(pusher, force, direction) + return TRUE + +/obj/proc/collision_damage(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction) + var/amt = max(0, ((force - (move_resist * MOVE_FORCE_CRUSH_RATIO)) / (move_resist * MOVE_FORCE_CRUSH_RATIO)) * 10) + take_damage(amt, BRUTE) + /obj/attack_slime(mob/living/simple_animal/slime/user) if(!user.is_adult) return diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 8899f2f79f..45b9715b04 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -60,8 +60,8 @@ var/flagslist = splittext(set_obj_flags,";") var/list/string_to_objflag = GLOB.bitfields["obj_flags"] for (var/flag in flagslist) - if (findtext(flag,"!",1,2)) - flag = copytext(flag,1-(length(flag))) // Get all but the initial ! + if(flag[1] == "!") + flag = copytext(flag, length(flag[1]) + 1) // Get all but the initial ! obj_flags &= ~string_to_objflag[flag] else obj_flags |= string_to_objflag[flag] @@ -80,7 +80,7 @@ SEND_SIGNAL(src, COMSIG_OBJ_SETANCHORED, anchorvalue) anchored = anchorvalue -/obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, messy_throw) +/obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE) . = ..() if(obj_flags & FROZEN) visible_message("[src] shatters into a million pieces!") @@ -178,7 +178,7 @@ machine = null //called when the user unsets the machine. -/atom/movable/proc/on_unset_machine(mob/user) +/atom/proc/on_unset_machine(mob/user) return /mob/proc/set_machine(obj/O) diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 5b9a764925..fcd1f80a4f 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -52,7 +52,7 @@ var/area/A = get_area(src) if(!A.blob_allowed) return FALSE - if(!A.power_equip) + if(!A.powered(EQUIP)) return FALSE if(!SSmapping.level_trait(T.z,ZTRAIT_STATION)) return FALSE diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 053512a256..b72a4b816e 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -305,7 +305,7 @@ /datum/barsign/meow_mix name = "Meow Mix" - icon = "meow_mix" + icon = "Meow Mix" desc = "No, we don't serve catnip, officer!" /datum/barsign/hiddensigns diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 9a095bf69d..daf15832fb 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -532,7 +532,7 @@ /obj/structure/closet/CtrlShiftClick(mob/living/user) if(!HAS_TRAIT(user, TRAIT_SKITTISH)) return ..() - if(!user.canUseTopic(src) || !isturf(user.loc)) + if(!user.canUseTopic(src) || !isturf(user.loc) || !user.Adjacent(src) || !user.CanReach(src)) return dive_into(user) diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index 9d554181eb..63c8856ac3 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -126,8 +126,10 @@ new /obj/item/clothing/mask/bandana/black(src) if(prob(40)) new /obj/item/clothing/under/assistantformal(src) + new /obj/item/clothing/suit/hooded/wintercoat/aformal(src) if(prob(40)) new /obj/item/clothing/under/assistantformal(src) + new /obj/item/clothing/suit/hooded/wintercoat/aformal(src) if(prob(30)) new /obj/item/clothing/suit/hooded/wintercoat(src) new /obj/item/clothing/shoes/winterboots(src) @@ -169,4 +171,6 @@ if(prob(30)) new /obj/item/clothing/suit/hooded/wintercoat(src) new /obj/item/clothing/shoes/winterboots(src) + if (prob(30)) + new /obj/item/clothing/suit/hooded/wintercoat/polychromic(src) return diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index eaa9074bd8..f6b2b6cd51 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -13,6 +13,8 @@ climb_time = 10 //real fast, because let's be honest stepping into or onto a crate is easy climb_stun = 0 //climbing onto crates isn't hard, guys delivery_icon = "deliverycrate" + material_drop = /obj/item/stack/sheet/plasteel + material_drop_amount = 5 var/obj/item/paper/fluff/jobs/cargo/manifest/manifest /obj/structure/closet/crate/New() @@ -142,6 +144,9 @@ new /obj/item/reagent_containers/blood/OMinus(src) new /obj/item/reagent_containers/blood/OPlus(src) new /obj/item/reagent_containers/blood/lizard(src) + new /obj/item/reagent_containers/blood/jellyblood(src) + new /obj/item/reagent_containers/blood/insect(src) + new /obj/item/reagent_containers/blood/synthetics(src) for(var/i in 1 to 3) new /obj/item/reagent_containers/blood/random(src) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 8c25a2ca5c..70533df0ad 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -80,7 +80,7 @@ /obj/structure/displaycase/proc/trigger_alarm() //Activate Anti-theft if(alert) - var/area/alarmed = get_area(src) + var/area/alarmed = get_base_area(src) alarmed.burglaralert(src) playsound(src, 'sound/effects/alert.ogg', 50, 1) diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 271ae72d47..f35e9e7d55 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -205,6 +205,9 @@ if(!mineral) if(istype(G, /obj/item/stack/sheet/mineral) && G.sheettype) var/M = G.sheettype + var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]") + if(!mineralassembly) + return if(G.get_amount() >= 2) playsound(src, 'sound/items/crowbar.ogg', 100, 1) user.visible_message("[user] adds [G.name] to the airlock assembly.", \ @@ -214,7 +217,6 @@ return to_chat(user, "You install [M] plating into the airlock assembly.") G.use(2) - var/mineralassembly = text2path("/obj/structure/door_assembly/door_assembly_[M]") var/obj/structure/door_assembly/MA = new mineralassembly(loc) transfer_assembly_vars(src, MA, TRUE) else diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index d7e2d5564a..52441c2987 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -7,7 +7,7 @@ anchored = TRUE icon = 'icons/turf/walls/wall.dmi' icon_state = "wall" - layer = CLOSED_TURF_LAYER + layer = LOW_OBJ_LAYER density = TRUE opacity = 1 max_integrity = 100 diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 0cce1de41b..e9d9e4ce77 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -12,9 +12,11 @@ roundstart = FALSE death = FALSE mob_species = /datum/species/pod - flavour_text = "You are a sentient ecosystem, an example of the mastery over life that your creators possessed. Your masters, benevolent as they were, created uncounted \ - seed vaults and spread them across the universe to every planet they could chart. You are in one such seed vault. Your goal is to cultivate and spread life wherever it will go while waiting \ - for contact from your creators. Estimated time of last contact: Deployment, 5x10^3 millennia ago." + short_desc = "You are a sentient ecosystem, an example of the mastery over life that your creators possessed." + flavour_text = "Your masters, benevolent as they were, created uncounted seed vaults and spread them across \ + the universe to every planet they could chart. You are in one such seed vault. \ + Your goal is to cultivate and spread life wherever it will go while waiting for contact from your creators. \ + Estimated time of last contact: Deployment, 5000 millennia ago." assignedrole = "Lifebringer" /obj/effect/mob_spawn/human/seed_vault/special(mob/living/new_spawn) @@ -46,9 +48,12 @@ roundstart = FALSE death = FALSE anchored = FALSE + move_resist = MOVE_FORCE_NORMAL density = FALSE - flavour_text = "You are an ash walker. Your tribe worships the Necropolis. The wastes are sacred ground, its monsters a blessed bounty. You would never leave its beautiful expanse. \ - You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest." + short_desc = "You are an ash walker. Your tribe worships the Necropolis." + flavour_text = "The wastes are sacred ground, its monsters a blessed bounty. You would never leave its sacred ground. \ + You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. \ + Fresh sacrifices for your nest." assignedrole = "Ash Walker" /obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn) @@ -87,8 +92,9 @@ roundstart = FALSE death = FALSE mob_species = /datum/species/shadow - flavour_text = "You are cursed. Years ago, you sacrificed the lives of your trusted friends and the humanity of yourself to reach the Wish Granter. Though you \ - did so, it has come at a cost: your very body rejects the light, dooming you to wander endlessly in this horrible wasteland." + short_desc = "You are cursed." + flavour_text = "Years ago, you sacrificed the lives of your trusted friends and the humanity of yourself to reach the Wish Granter. Though you \ + did so, it has come at a cost: your very body rejects the light, dooming you to wander endlessly in this horrible wasteland." assignedrole = "Exile" /obj/effect/mob_spawn/human/exile/Destroy() @@ -120,13 +126,15 @@ roundstart = FALSE death = FALSE anchored = FALSE + move_resist = MOVE_FORCE_NORMAL density = FALSE var/has_owner = FALSE var/can_transfer = TRUE //if golems can switch bodies to this new shell var/mob/living/owner = null //golem's owner if it has one - flavour_text = "You are a Free Golem. Your family worships The Liberator. In his infinite and divine wisdom, he set your clan free to \ + short_desc = "You are a Free Golem. Your family worships The Liberator." + flavour_text = "In his infinite and divine wisdom, he set your clan free to \ travel the stars with a single declaration: \"Yeah go do whatever.\" Though you are bound to the one who created you, it is customary in your society to repeat those same words to newborn \ - golems, so that no golem may ever be forced to serve again." + golems, so that no golem may ever be forced to serve again." /obj/effect/mob_spawn/human/golem/Initialize(mapload, datum/species/golem/species = null, mob/creator = null) if(species) //spawners list uses object name to register so this goes before ..() @@ -137,8 +145,9 @@ if(!mapload && A) notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_GOLEM, ignore_dnr_observers = TRUE) if(has_owner && creator) - flavour_text = "You are a Golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \ - Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost." + short_desc = "You are a golem." + flavour_text = "You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools." + important_info = "Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost." owner = creator /obj/effect/mob_spawn/human/golem/special(mob/living/new_spawn, name) @@ -211,8 +220,9 @@ death = FALSE random = TRUE mob_species = /datum/species/human - flavour_text = "You've been stranded in this godless prison of a planet for longer than you can remember. Each day you barely scrape by, and between the terrible \ - conditions of your makeshift shelter, the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \ + short_desc = "You've been stranded in this godless prison of a planet for longer than you can remember." + flavour_text = "Each day you barely scrape by, and between the terrible conditions of your makeshift shelter, \ + the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \ the fresh air of Earth. These thoughts are dispelled by yet another recollection of how you got here... " assignedrole = "Hermit" @@ -223,20 +233,20 @@ if(1) flavour_text += "you were a [pick("arms dealer", "shipwright", "docking manager")]'s assistant on a small trading station several sectors from here. Raiders attacked, and there was \ only one pod left when you got to the escape bay. You took it and launched it alone, and the crowd of terrified faces crowding at the airlock door as your pod's engines burst to \ - life and sent you to this hell are forever branded into your memory." + life and sent you to this hell are forever branded into your memory." outfit.uniform = /obj/item/clothing/under/assistantformal outfit.shoes = /obj/item/clothing/shoes/sneakers/black outfit.back = /obj/item/storage/backpack if(2) flavour_text += "you're an exile from the Tiger Cooperative. Their technological fanaticism drove you to question the power and beliefs of the Exolitics, and they saw you as a \ heretic and subjected you to hours of horrible torture. You were hours away from execution when a high-ranking friend of yours in the Cooperative managed to secure you a pod, \ - scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since." + scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since." outfit.uniform = /obj/item/clothing/under/rank/prisoner outfit.shoes = /obj/item/clothing/shoes/sneakers/orange outfit.back = /obj/item/storage/backpack if(3) flavour_text += "you were a doctor on one of Nanotrasen's space stations, but you left behind that damn corporation's tyranny and everything it stood for. From a metaphorical hell \ - to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there." + to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there." outfit.uniform = /obj/item/clothing/under/rank/medical outfit.suit = /obj/item/clothing/suit/toggle/labcoat outfit.back = /obj/item/storage/backpack/medic @@ -244,7 +254,7 @@ if(4) flavour_text += "you were always joked about by your friends for \"not playing with a full deck\", as they so kindly put it. It seems that they were right when you, on a tour \ at one of Nanotrasen's state-of-the-art research facilities, were in one of the escape pods alone and saw the red button. It was big and shiny, and it caught your eye. You pressed \ - it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now." + it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now." outfit.uniform = /obj/item/clothing/under/color/grey/glorf outfit.shoes = /obj/item/clothing/shoes/sneakers/black outfit.back = /obj/item/storage/backpack @@ -262,9 +272,10 @@ desc = "A small sleeper typically used to instantly restore minor wounds. This one seems broken, and its occupant is comatose." job_description = "Lavaland Veterinarian" mob_name = "a translocated vet" - flavour_text = "What...? Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \ - everyone's gone. One of the cats scratched you just a few minutes ago. That's why you were in the pod - to heal the scratch. The scabs are still fresh; you see them right now. So where is \ - everyone? Where did they go? What happened to the hospital? And is that smoke you smell? You need to find someone else. Maybe they can tell you what happened." + short_desc = "You are a animal doctor who just woke up in lavaland" + flavour_text = "What...? Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \ + you see them right now. So where is \ + everyone? Where did they go? What happened to the hospital? And is that smoke you smell? You need to find someone else. Maybe they c everyone's gone. One of the cats scratched you just a few minutes ago. That's why you were in the pod - to heal the scratch. The scabs are still fresh; an tell you what happened." assignedrole = "Translocated Vet" /obj/effect/mob_spawn/human/doctor/alive/lavaland/Destroy() @@ -283,8 +294,9 @@ outfit = /datum/outfit/lavalandprisoner roundstart = FALSE death = FALSE - flavour_text = "Good. It seems as though your ship crashed. You're a prisoner, sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \ - though fate has other plans for you. You remember that you were convicted of " + short_desc = "You're a prisoner, sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \ + though fate has other plans for you." + flavour_text = "Good. It seems as though your ship crashed. You remember that you were convicted of " assignedrole = "Escaped Prisoner" /obj/effect/mob_spawn/human/prisoner_transport/special(mob/living/L) @@ -296,7 +308,7 @@ var/list/crimes = list("murder", "larceny", "embezzlement", "unionization", "dereliction of duty", "kidnapping", "gross incompetence", "grand theft", "collaboration with the Syndicate", \ "worship of a forbidden deity", "interspecies relations", "mutiny") flavour_text += "[pick(crimes)]. but regardless of that, it seems like your crime doesn't matter now. You don't know where you are, but you know that it's out to kill you, and you're not going \ - to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]." + to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]." /datum/outfit/lavalandprisoner name = "Lavaland Prisoner" @@ -323,8 +335,9 @@ roundstart = FALSE random = TRUE outfit = /datum/outfit/hotelstaff - flavour_text = "You are a staff member of a top-of-the-line space hotel! Cater to guests and DON'T leave the hotel, lest the manager fire you for\ - dereliction of duty!" + short_desc = "You are a staff member of a top-of-the-line space hotel!" + flavour_text = "You are a staff member of a top-of-the-line space hotel! Cater to guests and make sure the manager doesn't fire you." + important_info = "DON'T leave the hotel" assignedrole = "Hotel Staff" /datum/outfit/hotelstaff @@ -341,8 +354,10 @@ mob_name = "hotel security member" job_description = "Hotel Security" outfit = /datum/outfit/hotelstaff/security - flavour_text = "You are a peacekeeper assigned to this hotel to protect the interests of the company while keeping the peace between \ - guests and the staff. Do NOT leave the hotel, as that is grounds for contract termination." + short_desc = "You are a peacekeeper." + flavour_text = "You have been assigned to this hotel to protect the interests of the company while keeping the peace between \ + guests and the staff." + important_info = "Do NOT leave the hotel, as that is grounds for contract termination." objectives = "Do not leave your assigned hotel. Try and keep the peace between staff and guests, non-lethal force heavily advised if possible." /datum/outfit/hotelstaff/security @@ -381,7 +396,8 @@ /obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell) . = ..() owner = owner_mind - flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil. Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell." + flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil." + important_info = "Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell." var/area/A = get_area(src) if(!mapload && A) notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE) @@ -439,9 +455,9 @@ /obj/effect/mob_spawn/human/syndicate/battlecruiser name = "Syndicate Battlecruiser Ship Operative" - flavour_text = "You are a crewmember aboard the syndicate flagship: the SBC Starfury. Your job is to follow your captain's orders, maintain the ship, and keep the engine running. If you are not familiar with how the supermatter engine functions: do not attempt to start it.
    \ -
    \ - The armory is not a candy store, and your role is not to assault the station directly, leave that work to the assault operatives." + short_desc = "You are a crewmember aboard the syndicate flagship: the SBC Starfury." + flavour_text = "Your job is to follow your captain's orders, maintain the ship, and keep the engine running. If you are not familiar with how the supermatter engine functions: do not attempt to start it." + important_info = "The armory is not a candy store, and your role is not to assault the station directly, leave that work to the assault operatives." outfit = /datum/outfit/syndicate_empty/SBC /datum/outfit/syndicate_empty/SBC @@ -451,10 +467,9 @@ belt = /obj/item/storage/belt/military/assault /obj/effect/mob_spawn/human/syndicate/battlecruiser/assault - name = "Syndicate Battlecruiser Assault Operative" - flavour_text = "You are an assault operative aboard the syndicate flagship: the SBC Starfury. Your job is to follow your captain's orders, keep intruders out of the ship, and assault Space Station 13. There is an armory, multiple assault ships, and beam cannons to attack the station with.
    \ -
    \ - Work as a team with your fellow operatives and work out a plan of attack. If you are overwhelmed, escape back to your ship!
    " + short_desc = "You are an assault operative aboard the syndicate flagship: the SBC Starfury." + flavour_text = "Your job is to follow your captain's orders, keep intruders out of the ship, and assault Space Station 13. There is an armory, multiple assault ships, and beam cannons to attack the station with." + important_info = "Work as a team with your fellow operatives and work out a plan of attack. If you are overwhelmed, escape back to your ship!" outfit = /datum/outfit/syndicate_empty/SBC/assault /datum/outfit/syndicate_empty/SBC/assault @@ -470,9 +485,9 @@ /obj/effect/mob_spawn/human/syndicate/battlecruiser/captain name = "Syndicate Battlecruiser Captain" - flavour_text = "You are the captain aboard the syndicate flagship: the SBC Starfury. Your job is to oversee your crew, defend the ship, and destroy Space Station 13. The ship has an armory, multiple ships, beam cannons, and multiple crewmembers to accomplish this goal.
    \ -
    \ - As the captain, this whole operation falls on your shoulders. You do not need to nuke the station, causing sufficient damage and preventing your ship from being destroyed will be enough.
    " + short_desc = "You are the captain aboard the syndicate flagship: the SBC Starfury." + flavour_text = "Your job is to oversee your crew, defend the ship, and destroy Space Station 13. The ship has an armory, multiple ships, beam cannons, and multiple crewmembers to accomplish this goal." + important_info = "As the captain, this whole operation falls on your shoulders. You do not need to nuke the station, causing sufficient damage and preventing your ship from being destroyed will be enough." outfit = /datum/outfit/syndicate_empty/SBC/assault/captain id_access_list = list(150,151) @@ -498,10 +513,11 @@ death = FALSE random = TRUE mob_species = /datum/species/human - flavour_text = "You are a security officer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ - cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." + short_desc = "You are a security officer working for Nanotrasen, stationed onboard a state of the art research station." + flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. \ + The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod." + important_info = "Work as a team with your fellow survivors and do not abandon them." uniform = /obj/item/clothing/under/rank/security shoes = /obj/item/clothing/shoes/jackboots id = /obj/item/card/id/away/old/sec @@ -525,10 +541,11 @@ death = FALSE random = TRUE mob_species = /datum/species/human - flavour_text = "You are an engineer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ - cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." + short_desc = "You are an engineer working for Nanotrasen, stationed onboard a state of the art research station." + flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. The last thing \ + you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod." + important_info = "Work as a team with your fellow survivors and do not abandon them." uniform = /obj/item/clothing/under/rank/engineer shoes = /obj/item/clothing/shoes/workboots id = /obj/item/card/id/away/old/eng @@ -550,10 +567,11 @@ death = FALSE random = TRUE mob_species = /datum/species/human - flavour_text = "You are a scientist working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ - cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." + short_desc = "You are a scientist working for Nanotrasen, stationed onboard a state of the art research station." + flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. \ + The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod." + important_info = "Work as a team with your fellow survivors and do not abandon them." uniform = /obj/item/clothing/under/rank/scientist shoes = /obj/item/clothing/shoes/laceup id = /obj/item/card/id/away/old/sci @@ -580,7 +598,8 @@ anchored = TRUE density = FALSE show_flavour = FALSE //Flavour only exists for spawners menu - flavour_text = "You are a space pirate. The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot." + short_desc = "You are a space pirate." + flavour_text = "The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot." assignedrole = "Space Pirate" var/rank = "Mate" @@ -615,9 +634,10 @@ density = FALSE death = FALSE assignedrole = "Ghost Cafe Visitor" - flavour_text = "Is this what life after death is like?" + short_desc = "You are a Ghost Cafe Visitor!" + flavour_text = "You know one thing for sure. You arent actually alive. Are you in a simulation?" skip_reentry_check = TRUE - banType = "ghostcafe" + banType = ROLE_GHOSTCAFE /datum/action/toggle_dead_chat_mob icon_icon = 'icons/mob/mob.dmi' @@ -640,11 +660,14 @@ /obj/effect/mob_spawn/human/ghostcafe/special(mob/living/carbon/human/new_spawn) if(new_spawn.client) new_spawn.client.prefs.copy_to(new_spawn) + var/area/A = get_area(src) var/datum/outfit/O = new /datum/outfit/ghostcafe() O.equip(new_spawn, FALSE, new_spawn.client) SSjob.equip_loadout(null, new_spawn, FALSE) SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn) new_spawn.AddElement(/datum/element/ghost_role_eligibility) + new_spawn.AddElement(/datum/element/dusts_on_catatonia) + new_spawn.AddElement(/datum/element/dusts_on_leaving_area,list(A.type,/area/hilbertshotel)) ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT) ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT) ADD_TRAIT(new_spawn,TRAIT_PACIFISM,GHOSTROLE_TRAIT) diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 94619e1858..7c373f2734 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -166,6 +166,9 @@ if(S.sheettype && S.sheettype != "runed") var/M = S.sheettype if(state == GIRDER_DISPLACED) + var/F = text2path("/obj/structure/falsewall/[M]") + if(!F) + return if(S.get_amount() < 2) to_chat(user, "You need at least two sheets to create a false wall!") return @@ -174,11 +177,13 @@ return S.use(2) to_chat(user, "You create a false wall. Push on it to open or close the passage.") - var/F = text2path("/obj/structure/falsewall/[M]") var/obj/structure/FW = new F (loc) transfer_fingerprints_to(FW) qdel(src) else + var/F = text2path("/turf/closed/wall/mineral/[M]") + if(!F) + return if(S.get_amount() < 2) to_chat(user, "You need at least two sheets to add plating!") return @@ -189,7 +194,7 @@ S.use(2) to_chat(user, "You add the plating.") var/turf/T = get_turf(src) - T.PlaceOnTop(text2path("/turf/closed/wall/mineral/[M]")) + T.PlaceOnTop(F) transfer_fingerprints_to(T) qdel(src) return diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 205e87329b..0d4444303e 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -258,7 +258,7 @@ take_damage(1, BURN, 0, 0) ..() -/obj/structure/grille/hitby(AM as mob|obj) +/obj/structure/grille/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(isobj(AM)) if(prob(50) && anchored && !broken) var/obj/O = AM diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index 3b4bbea559..611a6d024d 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -97,7 +97,7 @@ icon_state = "guillotine_raised" /obj/structure/guillotine/proc/drop_blade(mob/user) - if (buckled_mobs.len && blade_sharpness) + if (has_buckled_mobs() && blade_sharpness) var/mob/living/carbon/human/H = buckled_mobs[1] if (!H) diff --git a/code/game/objects/structures/headpike.dm b/code/game/objects/structures/headpike.dm index ceed9cb759..81433b562d 100644 --- a/code/game/objects/structures/headpike.dm +++ b/code/game/objects/structures/headpike.dm @@ -42,8 +42,9 @@ if(.) return to_chat(user, "You take down [src].") - victim.forceMove(drop_location()) - victim = null + if(victim) + victim.forceMove(drop_location()) + victim = null spear.forceMove(drop_location()) spear = null qdel(src) \ No newline at end of file diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index 617f42ed29..9d22f669d5 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -93,6 +93,24 @@ /obj/structure/holosign/barrier/firelock/blocksTemperature() return TRUE +/obj/structure/holosign/barrier/combifan + name = "holo combifan" + desc = "A holographic barrier resembling a blue-accented tiny fan. Though it does not prevent solid objects from passing through, gas and temperature changes are kept out." + icon_state = "holo_combifan" + max_integrity = 30 + density = FALSE + anchored = TRUE + alpha = 150 + CanAtmosPass = ATMOS_PASS_NO + resistance_flags = FIRE_PROOF + +/obj/structure/holosign/barrier/combolock/blocksTemperature() + return TRUE + +/obj/structure/holosign/barrier/combolock/Initialize() + . = ..() + air_update_turf(TRUE) + /obj/structure/holosign/barrier/cyborg name = "Energy Field" desc = "A fragile energy field that blocks movement. Excels at blocking lethal projectiles." diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm similarity index 71% rename from code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm rename to code/game/objects/structures/lavaland/necropolis_tendril.dm index 27ebb71c0e..6ce0228f54 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm +++ b/code/game/objects/structures/lavaland/necropolis_tendril.dm @@ -1,39 +1,32 @@ //Necropolis Tendrils, which spawn lavaland monsters and break into a chasm when killed -/obj/effect/light_emitter/tendril - set_luminosity = 4 - set_cap = 2.5 - light_color = LIGHT_COLOR_LAVA - -/mob/living/simple_animal/hostile/spawner/lavaland +/obj/structure/spawner/lavaland name = "necropolis tendril" desc = "A vile tendril of corruption, originating deep underground. Terrible monsters are pouring out of it." + icon = 'icons/mob/nest.dmi' icon_state = "tendril" - icon_living = "tendril" - icon_dead = "tendril" + faction = list("mining") - weather_immunities = list("lava","ash") - health = 250 - maxHealth = 250 max_mobs = 3 - spawn_time = 300 //30 seconds default + max_integrity = 250 mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril) - spawn_text = "emerges from" - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) - minbodytemp = 0 - maxbodytemp = INFINITY - loot = list(/obj/effect/collapse, /obj/structure/closet/crate/necropolis/tendril) - del_on_death = 1 + + move_resist=INFINITY // just killing it tears a massive hole in the ground, let's not move it + anchored = TRUE + resistance_flags = FIRE_PROOF | LAVA_PROOF + var/gps = null var/obj/effect/light_emitter/tendril/emitted_light -/mob/living/simple_animal/hostile/spawner/lavaland/goliath + +/obj/structure/spawner/lavaland/goliath mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril) -/mob/living/simple_animal/hostile/spawner/lavaland/legion +/obj/structure/spawner/lavaland/legion mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril) -/mob/living/simple_animal/hostile/spawner/lavaland/Initialize() +GLOBAL_LIST_INIT(tendrils, list()) +/obj/structure/spawner/lavaland/Initialize() . = ..() emitted_light = new(loc) for(var/F in RANGE_TURFS(1, src)) @@ -41,18 +34,19 @@ var/turf/closed/mineral/M = F M.ScrapeAway(null, CHANGETURF_IGNORE_AIR) gps = new /obj/item/gps/internal(src) + GLOB.tendrils += src -/mob/living/simple_animal/hostile/spawner/lavaland/Destroy() - QDEL_NULL(emitted_light) - QDEL_NULL(gps) +/obj/structure/spawner/lavaland/deconstruct(disassembled) + new /obj/effect/collapse(loc) + new /obj/structure/closet/crate/necropolis/tendril(loc) return ..() -/mob/living/simple_animal/hostile/spawner/lavaland/death() + +/obj/structure/spawner/lavaland/Destroy() var/last_tendril = TRUE - for(var/mob/living/simple_animal/hostile/spawner/lavaland/other in GLOB.mob_living_list) - if(other != src) - last_tendril = FALSE - break + if(GLOB.tendrils.len>1) + last_tendril = FALSE + if(last_tendril && !(flags_1 & ADMIN_SPAWNED_1)) if(SSmedals.hub_enabled) for(var/mob/living/L in view(7,src)) @@ -60,7 +54,15 @@ continue SSmedals.UnlockMedal("[BOSS_MEDAL_TENDRIL] [ALL_KILL_MEDAL]", L.client) SSmedals.SetScore(TENDRIL_CLEAR_SCORE, L.client, 1) - ..() + GLOB.tendrils -= src + QDEL_NULL(emitted_light) + QDEL_NULL(gps) + return ..() + +/obj/effect/light_emitter/tendril + set_luminosity = 4 + set_cap = 2.5 + light_color = LIGHT_COLOR_LAVA /obj/effect/collapse name = "collapsing necropolis tendril" @@ -92,4 +94,4 @@ for(var/turf/T in range(2,src)) if(!T.density) T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland, flags = CHANGETURF_INHERIT_AIR) - qdel(src) + qdel(src) \ No newline at end of file diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 0a5794c59d..d4645ec69a 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -20,14 +20,14 @@ return if(broken || !Adjacent(user)) return - + if(ishuman(user)) var/mob/living/carbon/human/H = user //see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments! //this is largely copypasted from there. //handle facial hair (if necessary) - if(H.gender == MALE) + if(H.gender != FEMALE) var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return //no tele-grooming @@ -133,7 +133,7 @@ switch(choice) if("name") - var/newname = copytext(sanitize(input(H, "Who are we again?", "Name change", H.name) as null|text),1,MAX_NAME_LEN) + var/newname = reject_bad_name(stripped_input(H, "Who are we again?", "Name change", H.name, MAX_NAME_LEN)) if(!newname) return diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 4c85e7464e..df6d033af4 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -109,8 +109,10 @@ var/cur_note = text2ascii(note) - 96 if(cur_note < 1 || cur_note > 7) continue - for(var/i=2 to length(note)) - var/ni = copytext(note,i,i+1) + var/notelen = length(note) + var/ni = "" + for(var/i = length(note[1]) + 1, i <= notelen, i += length(ni)) + ni = note[i] if(!text2num(ni)) if(ni == "#" || ni == "b" || ni == "n") cur_acc[cur_note] = ni @@ -199,9 +201,10 @@ //split into lines lines = splittext(text, "\n") if(lines.len) - if(copytext(lines[1],1,6) == "BPM: ") - tempo = sanitize_tempo(600 / text2num(copytext(lines[1],6))) - lines.Cut(1,2) + var/bpm_string = "BPM: " + if(findtext(lines[1], bpm_string, 1, length(bpm_string) + 1)) + tempo = sanitize_tempo(600 / text2num(copytext(lines[1], length(bpm_string) + 1))) + lines.Cut(1, 2) else tempo = sanitize_tempo(5) // default 120 BPM if(lines.len > MUSIC_MAXLINES) @@ -209,7 +212,7 @@ lines.Cut(MUSIC_MAXLINES + 1) var/linenum = 1 for(var/l in lines) - if(length(l) > MUSIC_MAXLINECHARS) + if(length_char(l) > MUSIC_MAXLINECHARS) to_chat(usr, "Line [linenum] too long!") lines.Remove(l) else @@ -236,11 +239,11 @@ if(!in_range(instrumentObj, usr)) return - if(length(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS) + if(length_char(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS) var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") if(cont == "no") break - while(length(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS) + while(length_char(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS) ParseSong(t) else if(href_list["help"]) @@ -284,11 +287,9 @@ else if(href_list["modifyline"]) var/num = round(text2num(href_list["modifyline"]),1) - var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null) + var/content = stripped_input(usr, "Enter your line: ", instrumentObj.name, lines[num], MUSIC_MAXLINECHARS) if(!content || !in_range(instrumentObj, usr)) return - if(length(content) > MUSIC_MAXLINECHARS) - content = copytext(content, 1, MUSIC_MAXLINECHARS) if(num > lines.len || num < 1) return lines[num] = content diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm new file mode 100644 index 0000000000..e67ef7af60 --- /dev/null +++ b/code/game/objects/structures/spawner.dm @@ -0,0 +1,75 @@ +/obj/structure/spawner + name = "monster nest" + icon = 'icons/mob/animal.dmi' + icon_state = "hole" + max_integrity = 100 + + move_resist = MOVE_FORCE_EXTREMELY_STRONG + anchored = TRUE + density = TRUE + + var/max_mobs = 5 + var/spawn_time = 300 //30 seconds default + var/mob_types = list(/mob/living/simple_animal/hostile/carp) + var/spawn_text = "emerges from" + var/faction = list("hostile") + +/obj/structure/spawner/Initialize() + . = ..() + AddComponent(/datum/component/spawner, mob_types, spawn_time, faction, spawn_text, max_mobs) + +/obj/structure/spawner/syndicate + name = "warp beacon" + icon = 'icons/obj/device.dmi' + icon_state = "syndbeacon" + spawn_text = "warps in from" + mob_types = list(/mob/living/simple_animal/hostile/syndicate/ranged) + faction = list(ROLE_SYNDICATE) + +/obj/structure/spawner/skeleton + name = "bone pit" + desc = "A pit full of bones, and some still seem to be moving..." + icon_state = "hole" + icon = 'icons/mob/nest.dmi' + max_integrity = 150 + max_mobs = 15 + spawn_time = 150 + mob_types = list(/mob/living/simple_animal/hostile/skeleton) + spawn_text = "climbs out of" + faction = list("skeleton") + +/obj/structure/spawner/mining + name = "monster den" + desc = "A hole dug into the ground, harboring all kinds of monsters found within most caves or mining asteroids." + icon_state = "hole" + max_integrity = 200 + max_mobs = 3 + icon = 'icons/mob/nest.dmi' + spawn_text = "crawls out of" + mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub, /mob/living/simple_animal/hostile/asteroid/goliath, /mob/living/simple_animal/hostile/asteroid/hivelord, /mob/living/simple_animal/hostile/asteroid/basilisk, /mob/living/simple_animal/hostile/asteroid/fugu) + faction = list("mining") + +/obj/structure/spawner/mining/goldgrub + name = "goldgrub den" + desc = "A den housing a nest of goldgrubs, annoying but arguably much better than anything else you'll find in a nest." + mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub) + +/obj/structure/spawner/mining/goliath + name = "goliath den" + desc = "A den housing a nest of goliaths, oh god why?" + mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath) + +/obj/structure/spawner/mining/hivelord + name = "hivelord den" + desc = "A den housing a nest of hivelords." + mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord) + +/obj/structure/spawner/mining/basilisk + name = "basilisk den" + desc = "A den housing a nest of basilisks, bring a coat." + mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk) + +/obj/structure/spawner/mining/wumborian + name = "wumborian fugu den" + desc = "A den housing a nest of wumborian fugus, how do they all even fit in there?" + mob_types = list(/mob/living/simple_animal/hostile/asteroid/fugu) \ No newline at end of file diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index f156287d43..5fabcafd75 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -71,7 +71,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "tank_dispenser", name, 275, 100, master_ui, state) + ui = new(user, src, ui_key, "tank_dispenser", name, 275, 103, master_ui, state) ui.open() /obj/structure/tank_dispenser/ui_data(mob/user) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 58588c5693..14a7e445c1 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -15,7 +15,8 @@ var/decon_speed = 30 var/wtype = "glass" var/fulltile = FALSE - var/glass_type = /obj/item/stack/sheet/glass + var/obj/item/stack/sheet/glass_type = /obj/item/stack/sheet/glass + var/cleanable_type = /obj/effect/decal/cleanable/glass var/glass_amount = 1 var/mutable_appearance/crack_overlay can_be_unanchored = TRUE @@ -277,12 +278,15 @@ /obj/structure/window/proc/spawnDebris(location) . = list() - . += new /obj/item/shard(location) - . += new /obj/effect/decal/cleanable/glass(location) + var/shard = initial(glass_type.shard_type) + if(shard) + . += new shard(location) + if (fulltile) + . += new shard(location) + if(cleanable_type) + . += new cleanable_type(location) if (reinf) . += new /obj/item/stack/rods(location, (fulltile ? 2 : 1)) - if (fulltile) - . += new /obj/item/shard(location) /obj/structure/window/proc/can_be_rotated(mob/user,rotation_type) if (get_dist(src,user) > 1) @@ -416,17 +420,9 @@ max_integrity = 150 explosion_block = 1 glass_type = /obj/item/stack/sheet/plasmaglass + cleanable_type = /obj/effect/decal/cleanable/glass/plasma rad_insulation = RAD_NO_INSULATION -/obj/structure/window/plasma/spawnDebris(location) - . = list() - . += new /obj/item/shard/plasma(location) - . += new /obj/effect/decal/cleanable/glass/plasma(location) - if (reinf) - . += new /obj/item/stack/rods(location, (fulltile ? 2 : 1)) - if (fulltile) - . += new /obj/item/shard/plasma(location) - /obj/structure/window/plasma/spawner/east dir = EAST @@ -662,11 +658,6 @@ level = 3 glass_amount = 2 -/obj/structure/window/reinforced/clockwork/spawnDebris(location) - . = list() - for(var/i in 1 to 4) - . += new /obj/item/clockwork/alloy_shards/medium/gear_bit(location) - /obj/structure/window/reinforced/clockwork/Initialize(mapload, direct) made_glow = TRUE new /obj/effect/temp_visual/ratvar/window(get_turf(src)) diff --git a/code/game/say.dm b/code/game/say.dm index 7f01bf163d..b275d8b69c 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -75,8 +75,8 @@ GLOBAL_LIST_INIT(freqtospan, list( return "" /atom/movable/proc/say_mod(input, message_mode) - var/ending = copytext(input, length(input)) - if(copytext(input, length(input) - 1) == "!!") + var/ending = copytext_char(input, -1) + if(copytext_char(input, -2) == "!!") return verb_yell else if(ending == "?") return verb_ask @@ -89,7 +89,7 @@ GLOBAL_LIST_INIT(freqtospan, list( if(!input) input = "..." - if(copytext(input, length(input) - 1) == "!!") + if(copytext_char(input, -2) == "!!") spans |= SPAN_YELL var/spanned = attach_spans(input, spans) @@ -124,12 +124,12 @@ GLOBAL_LIST_INIT(freqtospan, list( var/returntext = GLOB.reverseradiochannels["[freq]"] if(returntext) return returntext - return "[copytext("[freq]", 1, 4)].[copytext("[freq]", 4, 5)]" + return "[copytext_char("[freq]", 1, 4)].[copytext_char("[freq]", 4, 5)]" /atom/movable/proc/attach_spans(input, list/spans) var/customsayverb = findtext(input, "*") if(customsayverb) - input = capitalize(copytext(input, customsayverb+1)) + input = capitalize(copytext(input, length(input[customsayverb]) + 1)) if(input) return "[message_spans_start(spans)][input]
    " else @@ -143,7 +143,7 @@ GLOBAL_LIST_INIT(freqtospan, list( return output /proc/say_test(text) - var/ending = copytext(text, length(text)) + var/ending = copytext_char(text, -1) if (ending == "?") return "1" else if (ending == "!") diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index 577c45a7f0..c4c7ab2d7b 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -245,48 +245,47 @@ return TRUE /turf/open/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube) - if(C.movement_type & FLYING) - return 0 - if(has_gravity(src)) - var/obj/buckled_obj - if(C.buckled) - buckled_obj = C.buckled - if(!(lube&GALOSHES_DONT_HELP)) //can't slip while buckled unless it's lube. - return 0 - else - if(!(lube&SLIP_WHEN_CRAWLING) && (C.lying || !(C.status_flags & CANKNOCKDOWN))) // can't slip unbuckled mob if they're lying or can't fall. - return 0 - if(lube & NO_SLIP_WHEN_WALKING) - if(C.m_intent == MOVE_INTENT_WALK) - return 0 - if(ishuman(C) && !(lube & SLIP_WHEN_JOGGING)) - var/mob/living/carbon/human/H = C - if(!H.sprinting && H.getStaminaLoss() <= 20) - return 0 - if(!(lube&SLIDE_ICE)) - to_chat(C, "You slipped[ O ? " on the [O.name]" : ""]!") - playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3) + if(!(lube & FLYING_DOESNT_HELP) && (C.movement_type & FLYING || !has_gravity(src))) + return FALSE + var/obj/buckled_obj + if(C.buckled) + buckled_obj = C.buckled + if(!(lube&GALOSHES_DONT_HELP)) //can't slip while buckled unless it's lube. + return FALSE + else + if(!(lube&SLIP_WHEN_CRAWLING) && (C.lying || !(C.status_flags & CANKNOCKDOWN))) // can't slip unbuckled mob if they're lying or can't fall. + return FALSE + if(lube & NO_SLIP_WHEN_WALKING) + if(C.m_intent == MOVE_INTENT_WALK) + return FALSE + if(ishuman(C) && !(lube & SLIP_WHEN_JOGGING)) + var/mob/living/carbon/human/H = C + if(!H.sprinting && H.getStaminaLoss() <= 20) + return FALSE + if(!(lube&SLIDE_ICE)) + to_chat(C, "You slipped[ O ? " on the [O.name]" : ""]!") + playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3) - SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "slipped", /datum/mood_event/slipped) - for(var/obj/item/I in C.held_items) - C.accident(I) + SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "slipped", /datum/mood_event/slipped) + for(var/obj/item/I in C.held_items) + C.accident(I) - var/olddir = C.dir - if(!(lube & SLIDE_ICE)) - C.Knockdown(knockdown_amount) - C.stop_pulling() - else - C.Stun(20) + var/olddir = C.dir + if(!(lube & SLIDE_ICE)) + C.Knockdown(knockdown_amount) + C.stop_pulling() + else + C.Stun(20) - if(buckled_obj) - buckled_obj.unbuckle_mob(C) - lube |= SLIDE_ICE + if(buckled_obj) + buckled_obj.unbuckle_mob(C) + lube |= SLIDE_ICE - if(lube&SLIDE) - new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 4), 1, FALSE, CALLBACK(C, /mob/living/carbon/.proc/spin, 1, 1)) - else if(lube&SLIDE_ICE) - new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 1), 1, FALSE) //spinning would be bad for ice, fucks up the next dir - return 1 + if(lube&SLIDE) + new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 4), 1, FALSE, CALLBACK(C, /mob/living/carbon/.proc/spin, 1, 1)) + else if(lube&SLIDE_ICE) + new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 1), 1, FALSE) //spinning would be bad for ice, fucks up the next dir + return TRUE /turf/open/proc/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0, max_wet_time = MAXIMUM_WET_TIME, permanent) AddComponent(/datum/component/wet_floor, wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent) diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm index ecc8ee5e8d..053b18d8d2 100644 --- a/code/game/turfs/simulated/floor/plating/asteroid.dm +++ b/code/game/turfs/simulated/floor/plating/asteroid.dm @@ -151,9 +151,9 @@ has_data = TRUE /turf/open/floor/plating/asteroid/airless/cave/volcanic - mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/random = 50, /mob/living/simple_animal/hostile/spawner/lavaland/goliath = 3, \ - /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random = 40, /mob/living/simple_animal/hostile/spawner/lavaland = 2, \ - /mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30, /mob/living/simple_animal/hostile/spawner/lavaland/legion = 3, \ + mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/random = 50, /obj/structure/spawner/lavaland/goliath = 3, \ + /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random = 40, /obj/structure/spawner/lavaland = 2, \ + /mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30, /obj/structure/spawner/lavaland/legion = 3, \ SPAWN_MEGAFAUNA = 6, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10) data_having_type = /turf/open/floor/plating/asteroid/airless/cave/volcanic/has_data @@ -274,7 +274,7 @@ return //if there's a megafauna within standard view don't spawn anything at all if(ispath(randumb, /mob/living/simple_animal/hostile/asteroid) || istype(H, /mob/living/simple_animal/hostile/asteroid)) return //if the random is a standard mob, avoid spawning if there's another one within 12 tiles - if((ispath(randumb, /mob/living/simple_animal/hostile/spawner/lavaland) || istype(H, /mob/living/simple_animal/hostile/spawner/lavaland)) && get_dist(src, H) <= 2) + if((ispath(randumb, /obj/structure/spawner/lavaland) || istype(H, /obj/structure/spawner/lavaland)) && get_dist(src, H) <= 2) return //prevents tendrils spawning in each other's collapse range new randumb(T) diff --git a/code/game/turfs/simulated/lava.dm b/code/game/turfs/simulated/lava.dm index 2f8ae0cb93..3a474f339c 100644 --- a/code/game/turfs/simulated/lava.dm +++ b/code/game/turfs/simulated/lava.dm @@ -36,7 +36,7 @@ if(burn_stuff(AM)) START_PROCESSING(SSobj, src) -/turf/open/lava/hitby(atom/movable/AM) +/turf/open/lava/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(burn_stuff(AM)) START_PROCESSING(SSobj, src) diff --git a/code/game/turfs/simulated/wall/mineral_walls.dm b/code/game/turfs/simulated/wall/mineral_walls.dm index be46d124ea..d55cb0b475 100644 --- a/code/game/turfs/simulated/wall/mineral_walls.dm +++ b/code/game/turfs/simulated/wall/mineral_walls.dm @@ -138,7 +138,8 @@ var/duration = (48/W.force) * 2 //In seconds, for now. if(istype(W, /obj/item/hatchet) || istype(W, /obj/item/twohanded/fireaxe)) duration /= 4 //Much better with hatchets and axes. - if(do_after(user, duration*10, target=src)) //Into deciseconds. + var/src_type = type + if(do_after(user, duration*10, target=src) && type == src_type) //Into deciseconds. dismantle_wall(FALSE,FALSE) return return ..() diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm index 8b63d60939..d445be91cb 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -25,7 +25,7 @@ if(stored_pulling) stored_pulling.setDir(get_dir(stored_pulling.loc, newloc)) stored_pulling.forceMove(src) - H.start_pulling(stored_pulling, TRUE) + H.start_pulling(stored_pulling, supress_message = TRUE) /turf/closed/wall/mineral/cult/ratvar_act() . = ..() diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 5278374abd..26daa32107 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -88,8 +88,9 @@ /turf/open/space/proc/CanBuildHere() return TRUE -/turf/open/space/handle_slip() - return +/turf/open/space/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube) + if(lube & FLYING_DOESNT_HELP) + return ..() /turf/open/space/attackby(obj/item/C, mob/user, params) ..() diff --git a/code/game/world.dm b/code/game/world.dm index 7afaf62bb8..8e18f2ea51 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -115,9 +115,12 @@ GLOBAL_LIST(topic_status_cache) GLOB.world_runtime_log = "[GLOB.log_directory]/runtime.log" GLOB.query_debug_log = "[GLOB.log_directory]/query_debug.log" GLOB.world_job_debug_log = "[GLOB.log_directory]/job_debug.log" + GLOB.tgui_log = "[GLOB.log_directory]/tgui.log" GLOB.subsystem_log = "[GLOB.log_directory]/subsystem.log" + GLOB.reagent_log = "[GLOB.log_directory]/reagents.log" GLOB.world_crafting_log = "[GLOB.log_directory]/crafting.log" + #ifdef UNIT_TESTS GLOB.test_log = file("[GLOB.log_directory]/tests.log") start_log(GLOB.test_log) @@ -131,7 +134,9 @@ GLOBAL_LIST(topic_status_cache) start_log(GLOB.world_qdel_log) start_log(GLOB.world_runtime_log) start_log(GLOB.world_job_debug_log) + start_log(GLOB.tgui_log) start_log(GLOB.subsystem_log) + start_log(GLOB.reagent_log) start_log(GLOB.world_crafting_log) GLOB.changelog_hash = md5('html/changelog.html') //for telling if the changelog has changed recently diff --git a/code/modules/NTNet/network.dm b/code/modules/NTNet/network.dm index 645f05ac90..d86ad792fe 100644 --- a/code/modules/NTNet/network.dm +++ b/code/modules/NTNet/network.dm @@ -133,14 +133,14 @@ return FALSE /datum/ntnet/proc/log_data_transfer(datum/netdata/data) - logs += "[STATION_TIME_TIMESTAMP("hh:mm:ss")] - [data.generate_netlog()]" + logs += "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)] - [data.generate_netlog()]" if(logs.len > setting_maxlogcount) logs = logs.Copy(logs.len - setting_maxlogcount, 0) return // Simplified logging: Adds a log. log_string is mandatory parameter, source is optional. /datum/ntnet/proc/add_log(log_string, obj/item/computer_hardware/network_card/source = null) - var/log_text = "[STATION_TIME_TIMESTAMP("hh:mm:ss")] - " + var/log_text = "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)] - " if(source) log_text += "[source.get_network_tag()] - " else @@ -202,6 +202,11 @@ if(filename == P.filename) return P +/datum/ntnet/proc/get_chat_channel_by_id(id) + for(var/datum/ntnet_conversation/chan in chat_channels) + if(chan.id == id) + return chan + // Resets the IDS alarm /datum/ntnet/proc/resetIDS() intrusion_detection_alarm = FALSE diff --git a/code/modules/NTNet/relays.dm b/code/modules/NTNet/relays.dm index eaf2aa466b..373f6451b9 100644 --- a/code/modules/NTNet/relays.dm +++ b/code/modules/NTNet/relays.dm @@ -9,6 +9,9 @@ icon_state = "bus" density = TRUE circuit = /obj/item/circuitboard/machine/ntnet_relay + ui_x = 400 + ui_y = 300 + var/datum/ntnet/NTNet = null // This is mostly for backwards reference and to allow varedit modifications from ingame. var/enabled = 1 // Set to 0 if the relay was turned off var/dos_failure = 0 // Set to 1 if the relay failed due to (D)DoS attack @@ -66,7 +69,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "ntnet_relay", "NTNet Quantum Relay", 500, 300, master_ui, state) + ui = new(user, src, ui_key, "ntnet_relay", "NTNet Quantum Relay", ui_x, ui_y, master_ui, state) ui.open() @@ -88,10 +91,12 @@ dos_failure = 0 update_icon() SSnetworks.station_network.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.") + return TRUE if("toggle") enabled = !enabled SSnetworks.station_network.add_log("Quantum relay manually [enabled ? "enabled" : "disabled"].") update_icon() + return TRUE /obj/machinery/ntnet_relay/Initialize() uid = gl_uid++ @@ -113,4 +118,4 @@ D.target = null D.error = "Connection to quantum relay severed" - return ..() + return ..() \ No newline at end of file diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm index 7cda24d98b..29d7224950 100644 --- a/code/modules/VR/vr_sleeper.dm +++ b/code/modules/VR/vr_sleeper.dm @@ -222,18 +222,23 @@ /obj/effect/vr_clean_master/Initialize() . = ..() - vr_area = get_area(src) - addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES) + vr_area = get_base_area(src) + if(!vr_area) + return INITIALIZE_HINT_QDEL + addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES, TIMER_LOOP) /obj/effect/vr_clean_master/proc/clean_up() - if (vr_area) - for (var/obj/item/ammo_casing/casing in vr_area) - qdel(casing) - for(var/obj/effect/decal/cleanable/C in vr_area) - qdel(C) - for (var/A in corpse_party) - var/mob/M = A - if(M && M.stat == DEAD && get_area(M) == vr_area) - qdel(M) - corpse_party -= M - addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES) + if (!vr_area) + qdel(src) + return + var/list/contents = get_sub_areas_contents(vr_area) + for (var/obj/item/ammo_casing/casing in contents) + qdel(casing) + for(var/obj/effect/decal/cleanable/C in contents) + qdel(C) + for (var/A in corpse_party) + var/mob/M = A + if(!QDELETED(M) && (M in contents) && M.stat == DEAD) + qdel(M) + corpse_party -= M + addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 88e68158ed..372902e8d6 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -185,7 +185,6 @@ body += "Shade" body += "
    " - if (M.client) body += "

    " body += "Other actions:" body += "
    " @@ -194,9 +193,9 @@ body += "Thunderdome 2 | " body += "Thunderdome Admin | " body += "Thunderdome Observer | " - - body += usr.client.citaPPoptions(M) // CITADEL - + body += "Make mentor | " + body += "Remove mentor" + body += "Allow reentering round" body += "
    " body += "" @@ -1009,3 +1008,36 @@ "Admin login: [key_name(src)]") if(string) message_admins("[string]") + +/client/proc/cmd_admin_man_up(mob/M in GLOB.mob_list) + set category = "Special Verbs" + set name = "Man Up" + + if(!M) + return + if(!check_rights(R_ADMIN)) + return + + to_chat(M, "Man up, and deal with it.
    Move on.") + M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE) + + log_admin("Man up: [key_name(usr)] told [key_name(M)] to man up") + var/message = "[key_name_admin(usr)] told [key_name_admin(M)] to man up." + message_admins(message) + admin_ticket_log(M, message) + SSblackbox.record_feedback("tally", "admin_verb", 1, "Man Up") + +/client/proc/cmd_admin_man_up_global() + set category = "Special Verbs" + set name = "Man Up Global" + + if(!check_rights(R_ADMIN)) + return + + to_chat(world, "Man up, and deal with it.
    Move on.") + for(var/mob/M in GLOB.player_list) + M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE) + + log_admin("Man up global: [key_name(usr)] told everybody to man up") + message_admins("[key_name_admin(usr)] told everybody to man up.") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Man Up Global") diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 4f2aa35860..8856982cf2 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -135,10 +135,10 @@ GLOBAL_PROTECT(protected_ranks) var/previous_rights = 0 //load text from file and process each line separately for(var/line in world.file2list("[global.config.directory]/admin_ranks.txt")) - if(!line || findtextEx(line,"#",1,2)) + if(!line || findtextEx_char(line,"#",1,2)) continue var/next = findtext(line, "=") - var/datum/admin_rank/R = new(ckeyEx(copytext(line, 1, next))) + var/datum/admin_rank/R = new(ckeyEx(copytext(line, 1, line[next]))) if(!R) continue GLOB.admin_ranks += R @@ -146,7 +146,7 @@ GLOBAL_PROTECT(protected_ranks) var/prev = findchar(line, "+-*", next, 0) while(prev) next = findchar(line, "+-*", prev + 1, 0) - R.process_keyword(copytext(line, prev, next), previous_rights) + R.process_keyword(copytext_char(line, prev, next), previous_rights) prev = next previous_rights = R.rights if(!CONFIG_GET(flag/admin_legacy_system) || dbfail) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 8a7269ccad..c3ed9991d5 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -448,11 +448,9 @@ GLOBAL_PROTECT(admin_verbs_hideable) mob.name = initial(mob.name) mob.mouse_opacity = initial(mob.mouse_opacity) else - var/new_key = ckeyEx(input("Enter your desired display name.", "Fake Key", key) as text|null) + var/new_key = ckeyEx(stripped_input(usr, "Enter your desired display name.", "Fake Key", key, 26)) if(!new_key) return - if(length(new_key) >= 26) - new_key = copytext(new_key, 1, 26) holder.fakekey = new_key createStealthKey() if(isobserver(mob)) @@ -559,9 +557,9 @@ GLOBAL_PROTECT(admin_verbs_hideable) set desc = "Gives a spell to a mob." var/list/spell_list = list() - var/type_length = length("/obj/effect/proc_holder/spell") + 2 + var/type_length = length_char("/obj/effect/proc_holder/spell") + 2 for(var/A in GLOB.spells) - spell_list[copytext("[A]", type_length)] = A + spell_list[copytext_char("[A]", type_length)] = A var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_list if(!S) return diff --git a/code/modules/admin/check_antagonists.dm b/code/modules/admin/check_antagonists.dm index 30fa664f42..8cb2a9a477 100644 --- a/code/modules/admin/check_antagonists.dm +++ b/code/modules/admin/check_antagonists.dm @@ -149,10 +149,10 @@ else var/timeleft = SSshuttle.emergency.timeLeft() if(SSshuttle.emergency.mode == SHUTTLE_CALL) - dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]
    " + dat += "ETA: [(timeleft / 60) % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]
    " dat += "Send Back
    " else - dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]
    " + dat += "ETA: [(timeleft / 60) % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]
    " dat += "Continuous Round Status
    " dat += "[CONFIG_GET(keyed_list/continuous)[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]" if(CONFIG_GET(keyed_list/continuous)[SSticker.mode.config_tag]) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 70ae133a31..68ae3568af 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -345,7 +345,7 @@ if(!SSticker.HasRoundStarted()) alert("The game hasn't started yet!") return - var/objective = copytext(sanitize(input("Enter an objective")),1,MAX_MESSAGE_LEN) + var/objective = stripped_input(usr, "Enter an objective") if(!objective) return SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Traitor All", "[objective]")) @@ -408,7 +408,7 @@ var/obj/item/organ/tail/cat/tail = new ears.Insert(H, drop_if_replaced=FALSE) tail.Insert(H, drop_if_replaced=FALSE) - var/list/honorifics = list("[MALE]" = list("kun"), "[FEMALE]" = list("chan","tan"), "[NEUTER]" = list("san")) //John Robust -> Robust-kun + var/list/honorifics = list("[MALE]" = list("kun"), "[FEMALE]" = list("chan","tan"), "[NEUTER]" = list("san"), "[PLURAL]" = list("san")) //John Robust -> Robust-kun var/list/names = splittext(H.real_name," ") var/forename = names.len > 1 ? names[2] : names[1] var/newname = "[forename]-[pick(honorifics["[H.gender]"])]" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 88d4105124..00a95cdbc7 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -22,7 +22,10 @@ if(!CheckAdminHref(href, href_list)) return - citaTopic(href, href_list) //CITADEL EDIT, MENTORS + if(href_list["makementor"]) + makeMentor(href_list["makementor"]) + else if(href_list["removementor"]) + removeMentor(href_list["removementor"]) if(href_list["ahelp"]) if(!check_rights(R_ADMIN, TRUE)) @@ -842,7 +845,11 @@ dat += "Lavaland" else dat += "Lavaland" - + // Ghost cafe + if(jobban_isbanned(M,ROLE_GHOSTCAFE)) + dat += "Lavaland" + else + dat += "Lavaland" dat += "" //Antagonist (Orange) @@ -907,12 +914,16 @@ dat += "Alien" else dat += "Alien" - //Gang if(jobban_isbanned(M, ROLE_GANG) || isbanned_dept) dat += "Gang" else dat += "Gang" + //Bloodsucker + if(jobban_isbanned(M, ROLE_BLOODSUCKER) || isbanned_dept) + dat += "Bloodsucker" + else + dat += "Bloodsucker" //Other Roles (black) @@ -1715,6 +1726,16 @@ log_admin("[key_name(usr)] forced [key_name(M)] to say: [speech]") message_admins("[key_name_admin(usr)] forced [key_name_admin(M)] to say: [speech]") + else if(href_list["makeeligible"]) + if(!check_rights(R_ADMIN)) + return + var/mob/M = locate(href_list["makeeligible"]) + if(!ismob(M)) + to_chat(usr, "this can only be used on instances of type /mob.") + var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(/datum/element/ghost_role_eligibility) + if(M.ckey in eli.timeouts) + eli.timeouts -= M.ckey + else if(href_list["sendtoprison"]) if(!check_rights(R_ADMIN)) return @@ -2448,8 +2469,6 @@ if(!check_rights(R_ADMIN)) return src.admincaster_feed_channel.channel_name = stripped_input(usr, "Provide a Feed Channel Name.", "Network Channel Handler", "") - while (findtext(src.admincaster_feed_channel.channel_name," ") == 1) - src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,length(src.admincaster_feed_channel.channel_name)+1) src.access_news_network() else if(href_list["ac_set_channel_lock"]) @@ -2489,9 +2508,7 @@ else if(href_list["ac_set_new_message"]) if(!check_rights(R_ADMIN)) return - src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story.", "Network Channel Handler", "")) - while (findtext(src.admincaster_feed_message.returnBody(-1)," ") == 1) - src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,length(src.admincaster_feed_message.returnBody(-1))+1) + src.admincaster_feed_message.body = adminscrub(stripped_input(usr, "Write your Feed story.", "Network Channel Handler", "")) src.access_news_network() else if(href_list["ac_submit_new_message"]) @@ -2550,17 +2567,13 @@ else if(href_list["ac_set_wanted_name"]) if(!check_rights(R_ADMIN)) return - src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person.", "Network Security Handler", "")) - while(findtext(src.admincaster_wanted_message.criminal," ") == 1) - src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,length(admincaster_wanted_message.criminal)+1) + src.admincaster_wanted_message.criminal = adminscrub(stripped_input(usr, "Provide the name of the Wanted person.", "Network Security Handler", "")) src.access_news_network() else if(href_list["ac_set_wanted_desc"]) if(!check_rights(R_ADMIN)) return - src.admincaster_wanted_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important.", "Network Security Handler", "")) - while (findtext(src.admincaster_wanted_message.body," ") == 1) - src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,length(src.admincaster_wanted_message.body)+1) + src.admincaster_wanted_message.body = adminscrub(stripped_input(usr, "Provide the a description of the Wanted person and any other details you deem important.", "Network Security Handler", "")) src.access_news_network() else if(href_list["ac_submit_wanted"]) @@ -2846,3 +2859,59 @@ dat += {"Random (default)
    "} dat += {"Now: [GLOB.secret_force_mode]"} usr << browse(dat, "window=f_secret") + +/datum/admins/proc/makeMentor(ckey) + if(!usr.client) + return + if (!check_rights(0)) + return + if(!ckey) + return + var/client/C = GLOB.directory[ckey] + if(C) + if(check_rights_for(C, R_ADMIN,0)) + to_chat(usr, "The client chosen is an admin! Cannot mentorize.") + return + if(SSdbcore.Connect()) + var/datum/DBQuery/query_get_mentor = SSdbcore.NewQuery("SELECT id FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'") + if(!query_get_mentor.warn_execute()) + return + if(query_get_mentor.NextRow()) + to_chat(usr, "[ckey] is already a mentor.") + return + var/datum/DBQuery/query_add_mentor = SSdbcore.NewQuery("INSERT INTO `[format_table_name("mentor")]` (`id`, `ckey`) VALUES (null, '[ckey]')") + if(!query_add_mentor.warn_execute()) + return + var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new mentor [ckey]');") + if(!query_add_admin_log.warn_execute()) + return + else + to_chat(usr, "Failed to establish database connection. The changes will last only for the current round.") + new /datum/mentors(ckey) + to_chat(usr, "New mentor added.") + +/datum/admins/proc/removeMentor(ckey) + if(!usr.client) + return + if (!check_rights(0)) + return + if(!ckey) + return + var/client/C = GLOB.directory[ckey] + if(C) + if(check_rights_for(C, R_ADMIN,0)) + to_chat(usr, "The client chosen is an admin, not a mentor! Cannot de-mentorize.") + return + C.remove_mentor_verbs() + C.mentor_datum = null + GLOB.mentors -= C + if(SSdbcore.Connect()) + var/datum/DBQuery/query_remove_mentor = SSdbcore.NewQuery("DELETE FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'") + if(!query_remove_mentor.warn_execute()) + return + var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed mentor [ckey]');") + if(!query_add_admin_log.warn_execute()) + return + else + to_chat(usr, "Failed to establish database connection. The changes will last only for the current round.") + to_chat(usr, "Mentor removed.") diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index d2693a83b6..da7c264774 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -869,8 +869,8 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null else if(ispath(expression[i])) val = expression[i] - else if(copytext(expression[i], 1, 2) in list("'", "\"")) - val = copytext(expression[i], 2, length(expression[i])) + else if(expression[i][1] in list("'", "\"")) + val = copytext_char(expression[i], 2, -1) else if(expression[i] == "\[") var/list/expressions_list = expression[++i] @@ -961,11 +961,11 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null if(is_proper_datum(object)) D = object - if (object == world && (!long || expression[start + 1] == ".") && !(expression[start] in exclude)) + if (object == world && (!long || expression[start + 1] == ".") && !(expression[start] in exclude)) //3 == length("SS") + 1 to_chat(usr, "World variables are not allowed to be accessed. Use global.") return null - else if(expression [start] == "{" && long) + else if(expression [start] == "{" && long) //3 == length("0x") + 1 if(lowertext(copytext(expression[start + 1], 1, 3)) != "0x") to_chat(usr, "Invalid pointer syntax: [expression[start + 1]]") return null @@ -1070,9 +1070,10 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null var/word = "" var/list/query_list = list() var/len = length(query_text) + var/char = "" - for(var/i = 1, i <= len, i++) - var/char = copytext(query_text, i, i + 1) + for(var/i = 1, i <= len, i += length(char)) + char = query_text[i] if(char in whitespace) if(word != "") @@ -1091,7 +1092,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null query_list += word word = "" - var/char2 = copytext(query_text, i + 1, i + 2) + var/char2 = query_text[i + length(char)] if(char2 in multi[char]) query_list += "[char][char2]" @@ -1107,13 +1108,13 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null word = "'" - for(i++, i <= len, i++) - char = copytext(query_text, i, i + 1) + for(i += length(char), i <= len, i += length(char)) + char = query_text[i] if(char == "'") - if(copytext(query_text, i + 1, i + 2) == "'") + if(query_text[i + length(char)] == "'") word += "'" - i++ + i += length(query_text[i + length(char)]) else break @@ -1135,13 +1136,13 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null word = "\"" - for(i++, i <= len, i++) - char = copytext(query_text, i, i + 1) + for(i += length(char), i <= len, i += length(char)) + char = query_text[i] if(char == "\"") - if(copytext(query_text, i + 1, i + 2) == "'") + if(query_text[i + length(char)] == "'") word += "\"" - i++ + i += length(query_text[i + length(char)]) else break diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm index 272bf83ca4..64d0c00010 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm @@ -256,7 +256,7 @@ node += "*" i++ - else if (copytext(token(i), 1, 2) == "/") + else if(token(i)[1] == "/") i = object_type(i, node) else @@ -377,7 +377,7 @@ //object_type: /datum/SDQL_parser/proc/object_type(i, list/node) - if (copytext(token(i), 1, 2) != "/") + if(token(i)[1] != "/") return parse_error("Expected type, but it didn't begin with /") var/path = text2path(token(i)) @@ -416,7 +416,7 @@ //string: ''' ''' | '"' '"' /datum/SDQL_parser/proc/string(i, list/node) - if(copytext(token(i), 1, 2) in list("'", "\"")) + if(token(i)[1] in list("'", "\"")) node += token(i) else @@ -427,7 +427,7 @@ //array: '[' expression, expression, ... ']' /datum/SDQL_parser/proc/array(var/i, var/list/node) // Arrays get turned into this: list("[", list(exp_1a = exp_1b, ...), ...), "[" is to mark the next node as an array. - if(copytext(token(i), 1, 2) != "\[") + if(token(i)[1] != "\[") parse_error("Expected an array but found '[token(i)]'") return i + 1 @@ -613,7 +613,7 @@ node += "null" i++ - else if(lowertext(copytext(token(i), 1, 3)) == "0x" && isnum(hex2num(copytext(token(i), 3)))) + else if(lowertext(copytext(token(i), 1, 3)) == "0x" && isnum(hex2num(copytext(token(i), 3))))//3 == length("0x") + 1 node += hex2num(copytext(token(i), 3)) i++ @@ -621,12 +621,12 @@ node += text2num(token(i)) i++ - else if(copytext(token(i), 1, 2) in list("'", "\"")) + else if(token(i)[1] in list("'", "\"")) i = string(i, node) - else if(copytext(token(i), 1, 2) == "\[") // Start a list. + else if(token(i)[1] == "\[") // Start a list. i = array(i, node) - else if(copytext(token(i), 1, 2) == "/") + else if(token(i)[1] == "/") i = object_type(i, node) else i = variable(i, node) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 2f842263c7..1800824564 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -165,7 +165,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) //is_bwoink is TRUE if this ticket was started by an admin PM /datum/admin_help/New(msg, client/C, is_bwoink) //clean the input msg - msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN)) + msg = sanitize(copytext_char(msg,1,MAX_MESSAGE_LEN)) if(!msg || !C || !C.mob) qdel(src) return diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index e2b994f769..bbd6b55e4f 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -41,7 +41,7 @@ return var/client/C if(istext(whom)) - if(cmptext(copytext(whom,1,2),"@")) + if(whom[1] == "@") whom = findStealthKey(whom) C = GLOB.directory[whom] else if(istype(whom, /client)) @@ -76,7 +76,7 @@ var/client/recipient var/irc = 0 if(istext(whom)) - if(cmptext(copytext(whom,1,2),"@")) + if(whom[1] == "@") whom = findStealthKey(whom) if(whom == "IRCKEY") irc = 1 @@ -133,7 +133,7 @@ //clean the message if it's not sent by a high-rank admin if(!check_rights(R_SERVER|R_DEBUG,0)||irc)//no sending html to the poor bots - msg = trim(sanitize(copytext(msg,1,MAX_MESSAGE_LEN))) + msg = trim(sanitize(msg), MAX_MESSAGE_LEN) if(!msg) return @@ -287,7 +287,7 @@ if(!stealthkey) stealthkey = GenIrcStealthKey() - msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN)) + msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN)) if(!msg) return "Error: No message" diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm index 1ebd632c23..9081357ef6 100644 --- a/code/modules/admin/verbs/adminsay.dm +++ b/code/modules/admin/verbs/adminsay.dm @@ -5,7 +5,7 @@ if(!check_rights(0)) return - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) + msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) if(!msg) return msg = emoji_parse(msg) diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm index 52c5284cbb..4df6f22686 100644 --- a/code/modules/admin/verbs/deadsay.dm +++ b/code/modules/admin/verbs/deadsay.dm @@ -14,7 +14,7 @@ if (src.handle_spam_prevention(msg,MUTE_DEADCHAT)) return - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) + msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) mob.log_talk(msg, LOG_DSAY) if (!msg) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index f08112939a..ad2eeb7289 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -541,7 +541,9 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) var/list/areas_all = list() var/list/areas_with_APC = list() var/list/areas_with_multiple_APCs = list() + var/list/sub_areas_APC = list() var/list/areas_with_air_alarm = list() + var/list/sub_areas_air_alarm = list() var/list/areas_with_RC = list() var/list/areas_with_light = list() var/list/areas_with_LS = list() @@ -578,6 +580,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(!A) dat += "Skipped over [APC] in invalid location, [APC.loc]." continue + LAZYSET(sub_areas_APC, A.type, get_sub_areas(A, FALSE)) if(!(A.type in areas_with_APC)) areas_with_APC.Add(A.type) else if(A.type in areas_all) @@ -585,10 +588,11 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) CHECK_TICK for(var/obj/machinery/airalarm/AA in GLOB.machines) - var/area/A = get_area(AA) + var/area/A = get_base_area(AA) if(!A) //Make sure the target isn't inside an object, which results in runtimes. dat += "Skipped over [AA] in invalid location, [AA.loc].
    " continue + LAZYSET(sub_areas_air_alarm, A.type, get_sub_areas(A, FALSE)) if(!(A.type in areas_with_air_alarm)) areas_with_air_alarm.Add(A.type) CHECK_TICK @@ -638,8 +642,8 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) areas_with_camera.Add(A.type) CHECK_TICK - var/list/areas_without_APC = areas_all - areas_with_APC - var/list/areas_without_air_alarm = areas_all - areas_with_air_alarm + var/list/areas_without_APC = areas_all - (areas_with_APC + flatten_list(sub_areas_APC)) + var/list/areas_without_air_alarm = areas_all - (areas_with_air_alarm + flatten_list(sub_areas_air_alarm)) var/list/areas_without_RC = areas_all - areas_with_RC var/list/areas_without_light = areas_all - areas_with_light var/list/areas_without_LS = areas_all - areas_with_LS @@ -656,12 +660,18 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) dat += "

    AREAS WITH MULTIPLE APCS:

    " for(var/areatype in areas_with_multiple_APCs) dat += "[areatype]
    " + if(sub_areas_APC[areatype]) + dat += "  SUB-AREAS:
      " + dat += jointext(sub_areas_APC[areatype], "
      ") CHECK_TICK if(areas_without_air_alarm.len) dat += "

    AREAS WITHOUT AN AIR ALARM:

    " for(var/areatype in areas_without_air_alarm) dat += "[areatype]
    " + if(sub_areas_air_alarm[areatype]) + dat += "  SUB-AREAS:
      " + dat += jointext(sub_areas_air_alarm[areatype], "
      ") CHECK_TICK if(areas_without_RC.len) diff --git a/code/modules/admin/verbs/map_template_loadverb.dm b/code/modules/admin/verbs/map_template_loadverb.dm index c5c9a0daf4..d71cdca991 100644 --- a/code/modules/admin/verbs/map_template_loadverb.dm +++ b/code/modules/admin/verbs/map_template_loadverb.dm @@ -33,7 +33,7 @@ var/map = input(src, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file if(!map) return - if(copytext("[map]",-4) != ".dmm") + if(copytext("[map]", -4) != ".dmm")//4 == length(".dmm") to_chat(src, "Filename must end in '.dmm': [map]") return var/datum/map_template/M diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 611ebcf7bf..537c31d3b4 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -307,9 +307,9 @@ GLOBAL_PROTECT(VVpixelmovement) // the type with the base type removed from the begaining var/fancytype = types[D.type] if (findtext(fancytype, types[type])) - fancytype = copytext(fancytype, length(types[type])+1) - var/shorttype = copytext("[D.type]", length("[type]")+1) - if (length(shorttype) > length(fancytype)) + fancytype = copytext(fancytype, length(types[type]) + 1) + var/shorttype = copytext("[D.type]", length("[type]") + 1) + if (length_char(shorttype) > length_char(fancytype)) shorttype = fancytype if (!length(shorttype)) shorttype = "/" diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 0555f6b40a..f3da1954a9 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -6,7 +6,7 @@ to_chat(usr, "Speech is currently admin-disabled.") return - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) + msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) if(!msg) return log_prayer("[src.key]/([src.name]): [msg]") @@ -54,21 +54,21 @@ //log_admin("HELP: [key_name(src)]: [msg]") /proc/CentCom_announce(text , mob/Sender) - var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN) + var/msg = copytext_char(sanitize(text), 1, MAX_MESSAGE_LEN) msg = "CENTCOM:[ADMIN_FULLMONTY(Sender)] [ADMIN_CENTCOM_REPLY(Sender)]: [msg]" to_chat(GLOB.admins, msg) for(var/obj/machinery/computer/communications/C in GLOB.machines) C.overrideCooldown() /proc/Syndicate_announce(text , mob/Sender) - var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN) + var/msg = copytext_char(sanitize(text), 1, MAX_MESSAGE_LEN) msg = "SYNDICATE:[ADMIN_FULLMONTY(Sender)] [ADMIN_SYNDICATE_REPLY(Sender)]: [msg]" to_chat(GLOB.admins, msg) for(var/obj/machinery/computer/communications/C in GLOB.machines) C.overrideCooldown() /proc/Nuke_request(text , mob/Sender) - var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN) + var/msg = copytext_char(sanitize(text), 1, MAX_MESSAGE_LEN) msg = "NUKE CODE REQUEST:[ADMIN_FULLMONTY(Sender)] [ADMIN_CENTCOM_REPLY(Sender)] [ADMIN_SET_SD_CODE]: [msg]" to_chat(GLOB.admins, msg) for(var/obj/machinery/computer/communications/C in GLOB.machines) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 1437555af1..37c79b1123 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -419,7 +419,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if(record_found)//If they have a record we can determine a few things. new_character.real_name = record_found.fields["name"] - new_character.gender = record_found.fields["sex"] + new_character.gender = record_found.fields["gender"] new_character.age = record_found.fields["age"] new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], new record_found.fields["species"], record_found.fields["features"]) else @@ -1249,7 +1249,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(!check_rights(R_ADMIN) || !check_rights(R_FUN)) return - var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_SUPPLYPOD_QUICK, ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING, ADMIN_PUNISHMENT_ROD) + var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE, ADMIN_PUNISHMENT_CUSTOM_PIE, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_SUPPLYPOD_QUICK, ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING, ADMIN_PUNISHMENT_ROD) var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list @@ -1314,6 +1314,19 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if(ADMIN_PUNISHMENT_PIE) var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/creamy = new(get_turf(target)) creamy.splat(target) + if (ADMIN_PUNISHMENT_CUSTOM_PIE) + var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/A = new(get_turf(target)) + if(!A.reagents) + var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num + if(amount) + A.create_reagents(amount) + if(A.reagents) + var/chosen_id = choose_reagent_id(usr) + if(chosen_id) + var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num + if(amount) + A.reagents.add_reagent(chosen_id, amount) + A.splat(target) punish_log(target, punishment) diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 5921b465e2..f019858319 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -222,7 +222,7 @@ GLOBAL_LIST_EMPTY(antagonists) return /datum/antagonist/proc/edit_memory(mob/user) - var/new_memo = copytext(trim(input(user,"Write new memory", "Memory", antag_memory) as null|message),1,MAX_MESSAGE_LEN) + var/new_memo = stripped_multiline_input(user, "Write new memory", "Memory", antag_memory, MAX_MESSAGE_LEN) if (isnull(new_memo)) return antag_memory = new_memo diff --git a/code/modules/antagonists/abductor/abductee/abductee.dm b/code/modules/antagonists/abductor/abductee/abductee.dm new file mode 100644 index 0000000000..901d2f5b11 --- /dev/null +++ b/code/modules/antagonists/abductor/abductee/abductee.dm @@ -0,0 +1,34 @@ +/datum/antagonist/abductee + name = "Abductee" + roundend_category = "abductees" + antagpanel_category = "Abductee" + var/datum/brain_trauma/abductee/brain_trauma + +/datum/antagonist/abductee/on_gain() + give_objective() + . = ..() + +/datum/antagonist/abductee/greet() + to_chat(owner, "Your mind snaps!") + to_chat(owner, "You can't remember how you got here...") + owner.announce_objectives() + +/datum/antagonist/abductee/proc/give_objective() + var/mob/living/carbon/human/H = owner.current + if(istype(H)) + H.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_LOBOTOMY) + var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random)) + var/datum/objective/abductee/O = new objtype() + objectives += O + +/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override) + update_abductor_icons_added(mob_override ? mob_override.mind : owner,"abductee") + var/mob/living/carbon/C = mob_override || owner?.current + if(istype(C)) + if(brain_trauma) + qdel(brain_trauma) //make sure there's no lingering trauma + brain_trauma = C.gain_trauma(/datum/brain_trauma/abductee, TRAUMA_RESILIENCE_SURGERY) + +/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override) + update_abductor_icons_removed(mob_override ? mob_override.mind : owner) + qdel(brain_trauma) diff --git a/code/modules/antagonists/abductor/abductee/abductee_objectives.dm b/code/modules/antagonists/abductor/abductee/abductee_objectives.dm index f188319644..2d62bf1ac9 100644 --- a/code/modules/antagonists/abductor/abductee/abductee_objectives.dm +++ b/code/modules/antagonists/abductor/abductee/abductee_objectives.dm @@ -18,7 +18,7 @@ /datum/objective/abductee/paint/New() var/color = pick(list("red", "blue", "green", "yellow", "orange", "purple", "black", "in rainbows", "in blood")) - explanation_text+= " [color]!" + explanation_text = " [color]!" /datum/objective/abductee/speech explanation_text = "Your brain is broken... you can only communicate in" diff --git a/code/modules/antagonists/abductor/abductee/trauma.dm b/code/modules/antagonists/abductor/abductee/trauma.dm new file mode 100644 index 0000000000..1518825e1b --- /dev/null +++ b/code/modules/antagonists/abductor/abductee/trauma.dm @@ -0,0 +1,18 @@ +/datum/brain_trauma/abductee + name = "abductee mindsnapped" + desc = "The patient's brain has been scrambled by experimental procedures." + scan_desc = "brain scrambling" + gain_text = "Your mind snaps.. you feel fragmented." + lose_text = "Your mind heals itself and you feel whole again." + random_gain = FALSE + clonable = TRUE + +/datum/brain_trauma/abductee/on_gain() + . = ..() + if(owner.mind) + if(!owner.mind.has_antag_datum(/datum/antagonist/abductee)) + owner.mind.add_antag_datum(/datum/antagonist/abductee) + +/datum/brain_trauma/abductee/on_lose() + . = ..() + owner.mind?.remove_antag_datum(/datum/antagonist/abductee) diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm index 92504641a9..564e9a8617 100644 --- a/code/modules/antagonists/abductor/abductor.dm +++ b/code/modules/antagonists/abductor/abductor.dm @@ -159,35 +159,6 @@ return "
    [result.Join("
    ")]
    " -/datum/antagonist/abductee - name = "Abductee" - roundend_category = "abductees" - antagpanel_category = "Abductee" - -/datum/antagonist/abductee/on_gain() - give_objective() - . = ..() - -/datum/antagonist/abductee/greet() - to_chat(owner, "Your mind snaps!") - to_chat(owner, "You can't remember how you got here...") - owner.announce_objectives() - -/datum/antagonist/abductee/proc/give_objective() - var/mob/living/carbon/human/H = owner.current - if(istype(H)) - H.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_LOBOTOMY) - var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random)) - var/datum/objective/abductee/O = new objtype() - objectives += O - -/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override) - update_abductor_icons_added(mob_override ? mob_override.mind : owner,"abductee") - -/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override) - update_abductor_icons_removed(mob_override ? mob_override.mind : owner) - - // LANDMARKS /obj/effect/landmark/abductor var/team_number = 1 diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm index dc6d12453d..332329a221 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm @@ -29,6 +29,11 @@ var/stealth_armor = list("melee" = 15, "bullet" = 15, "laser" = 15, "energy" = 15, "bomb" = 15, "bio" = 15, "rad" = 15, "fire" = 70, "acid" = 70) var/combat_armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 90, "acid" = 90) +/obj/item/clothing/suit/armor/abductor/vest/Initialize() + . = ..() + stealth_armor = getArmor(arglist(stealth_armor)) + combat_armor = getArmor(arglist(combat_armor)) + /obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop() if(HAS_TRAIT_FROM(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)) REMOVE_TRAIT(src, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) @@ -629,15 +634,12 @@ icon_state = "abductor_headset" item_state = "abductor_headset" keyslot2 = new /obj/item/encryptionkey/heads/captain + bowman = TRUE /obj/item/radio/headset/abductor/Initialize(mapload) . = ..() make_syndie() -/obj/item/radio/headset/abductor/ComponentInitialize() - . = ..() - AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS)) - /obj/item/radio/headset/abductor/attackby(obj/item/W, mob/user, params) if(W.tool_behaviour == TOOL_SCREWDRIVER) return // Stops humans from disassembling abductor headsets. diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm index 47294bc766..b8d5b1bf6d 100644 --- a/code/modules/antagonists/abductor/machinery/console.dm +++ b/code/modules/antagonists/abductor/machinery/console.dm @@ -46,7 +46,6 @@ dat += "Advanced Baton (2 Credits)
    " dat += "Mental Interface Device (2 Credits)
    " dat += "Reagent Synthesizer (2 Credits)
    " - dat += "Shrink Ray Blaster (2 Credits)
    " dat += "Agent Helmet (1 Credit)
    " dat += "Agent Vest (1 Credit)
    " dat += "Radio Silencer (1 Credit)
    " @@ -119,8 +118,6 @@ Dispense(/obj/item/abductor_machine_beacon/chem_dispenser,cost=2) if("tongue") Dispense(/obj/item/organ/tongue/abductor) - if("shrink_ray") - Dispense(/obj/item/gun/energy/shrink_ray,cost=2) updateUsrDialog() /obj/machinery/abductor/console/proc/TeleporterRetrieve() @@ -245,4 +242,4 @@ new item(drop_location) else - say("Insufficent data!") \ No newline at end of file + say("Insufficent data!") diff --git a/code/modules/antagonists/abductor/machinery/experiment.dm b/code/modules/antagonists/abductor/machinery/experiment.dm index 10581e7bbb..b5233606cf 100644 --- a/code/modules/antagonists/abductor/machinery/experiment.dm +++ b/code/modules/antagonists/abductor/machinery/experiment.dm @@ -174,7 +174,7 @@ if(!GlandTest) say("Experimental dissection not detected!") return "No glands detected!" - if(H.mind != null && H.ckey != null) + if(H.mind != null && (H.voluntary_ghosted || (H.ckey != null))) LAZYINITLIST(abductee_minds) LAZYADD(history, H) LAZYADD(abductee_minds, H.mind) diff --git a/code/modules/antagonists/blob/blob/overmind.dm b/code/modules/antagonists/blob/blob/overmind.dm index f094fa83db..5d3c8cd8ca 100644 --- a/code/modules/antagonists/blob/blob/overmind.dm +++ b/code/modules/antagonists/blob/blob/overmind.dm @@ -203,7 +203,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) /mob/camera/blob/proc/blob_talk(message) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) if (!message) return diff --git a/code/modules/antagonists/bloodsucker/datum_hunter.dm b/code/modules/antagonists/bloodsucker/datum_hunter.dm index 2d680d0e09..5fc6716a7d 100644 --- a/code/modules/antagonists/bloodsucker/datum_hunter.dm +++ b/code/modules/antagonists/bloodsucker/datum_hunter.dm @@ -283,8 +283,8 @@ streak = "" restraining = 0 streak = streak+element - if(length(streak) > max_streak_length) - streak = copytext(streak,2) + if(length_char(streak) > max_streak_length) + streak = streak[1] return diff --git a/code/modules/antagonists/changeling/powers/fakedeath.dm b/code/modules/antagonists/changeling/powers/fakedeath.dm index 88328c582c..8ed5b5e39c 100644 --- a/code/modules/antagonists/changeling/powers/fakedeath.dm +++ b/code/modules/antagonists/changeling/powers/fakedeath.dm @@ -15,7 +15,7 @@ to_chat(user, "We begin our stasis, preparing energy to arise once more.") if(user.stat != DEAD) user.emote("deathgasp") - user.tod = STATION_TIME_TIMESTAMP("hh:mm:ss") + user.tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time) user.fakedeath("changeling") //play dead user.update_stat() user.update_canmove() diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm index 7534f7c043..05516cc6a2 100644 --- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm +++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm @@ -45,10 +45,10 @@ bonus_damage *= 3 //total 30 damage on cultists, 50 with ratvar GLOB.clockwork_vitality += target.adjustFireLoss(bonus_damage) //adds the damage done to existing vitality -/obj/item/clockwork/weapon/ratvarian_spear/throw_impact(atom/target) - var/turf/T = get_turf(target) - if(isliving(target)) - var/mob/living/L = target +/obj/item/clockwork/weapon/ratvarian_spear/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + var/turf/T = get_turf(hit_atom) + if(isliving(hit_atom)) + var/mob/living/L = hit_atom if(is_servant_of_ratvar(L)) if(L.put_in_active_hand(src)) L.visible_message("[L] catches [src] out of the air!") diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm index e01156ba44..5bc04173b9 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm @@ -70,6 +70,7 @@ resistance_flags = FIRE_PROOF | ACID_PROOF armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel, /obj/item/reagent_containers/food/drinks/bottle/holyoil) + mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC /obj/item/clothing/suit/armor/clockwork/Initialize() . = ..() diff --git a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm index 86099d8c79..e4722dbcb0 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm @@ -83,7 +83,7 @@ return if(client.handle_spam_prevention(message,MUTE_IC)) return - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) if(!message) return src.log_talk(message, LOG_SAY, tag="clockwork eminence") diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index 794010d9c0..1bb1b8533a 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -753,7 +753,7 @@ var/turf/T = get_turf(target) if(T) for(var/obj/effect/decal/cleanable/blood/B in view(T, 2)) - if(B.blood_state == "blood") + if(B.blood_state == BLOOD_STATE_BLOOD) if(B.bloodiness == 100) //Bonus for "pristine" bloodpools, also to prevent cheese with footprint spam temp += 30 else diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index f5be94a0e7..f14aeede9a 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -265,7 +265,7 @@ to_chat(user, "The bola seems to take on a life of its own!") throw_impact(user) -/obj/item/restraints/legcuffs/bola/cult/throw_impact(atom/hit_atom) +/obj/item/restraints/legcuffs/bola/cult/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(iscultist(hit_atom)) return . = ..() @@ -690,10 +690,10 @@ /obj/item/twohanded/cult_spear/update_icon() icon_state = "bloodspear[wielded]" -/obj/item/twohanded/cult_spear/throw_impact(atom/target) - var/turf/T = get_turf(target) - if(isliving(target)) - var/mob/living/L = target +/obj/item/twohanded/cult_spear/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + var/turf/T = get_turf(hit_atom) + if(isliving(hit_atom)) + var/mob/living/L = hit_atom if(iscultist(L)) playsound(src, 'sound/weapons/throwtap.ogg', 50) if(L.put_in_active_hand(src)) @@ -987,11 +987,11 @@ return TRUE return FALSE -/obj/item/shield/mirror/throw_impact(atom/target, throwingdatum) - var/turf/T = get_turf(target) +/obj/item/shield/mirror/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + var/turf/T = get_turf(hit_atom) var/datum/thrownthing/D = throwingdatum - if(isliving(target)) - var/mob/living/L = target + if(isliving(hit_atom)) + var/mob/living/L = hit_atom if(iscultist(L)) playsound(src, 'sound/weapons/throwtap.ogg', 50) if(L.put_in_active_hand(src)) diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index da002e568c..7948b30035 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -22,7 +22,7 @@ Runes can either be invoked by one's self or with many different cultists. Each icon = 'icons/obj/rune.dmi' icon_state = "1" resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF - layer = LOW_OBJ_LAYER + layer = SIGIL_LAYER color = RUNE_COLOR_RED var/invocation = "Aiy ele-mayo." //This is said by cultists when the rune is invoked. diff --git a/code/modules/antagonists/disease/disease_abilities.dm b/code/modules/antagonists/disease/disease_abilities.dm index dc2249006c..7b30d10c5d 100644 --- a/code/modules/antagonists/disease/disease_abilities.dm +++ b/code/modules/antagonists/disease/disease_abilities.dm @@ -57,7 +57,7 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list( var/short_desc = "" var/long_desc = "" var/stat_block = "" - var/threshold_block = "" + var/threshold_block = list() var/category = "" var/list/symptoms @@ -76,7 +76,7 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list( resistance += initial(S.resistance) stage_speed += initial(S.stage_speed) transmittable += initial(S.transmittable) - threshold_block += "

    [initial(S.threshold_desc)]" + threshold_block += initial(S.threshold_desc) stat_block = "Resistance: [resistance]
    Stealth: [stealth]
    Stage Speed: [stage_speed]
    Transmissibility: [transmittable]

    " if(symptoms.len == 1) //lazy boy's dream name = initial(S.name) diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm index 516f30d896..a20a9cef85 100644 --- a/code/modules/antagonists/disease/disease_mob.dm +++ b/code/modules/antagonists/disease/disease_mob.dm @@ -318,7 +318,11 @@ the new instance inside the host to be updated to the template's stats. var/list/dat = list() if(examining_ability) - dat += "Back

    [examining_ability.name]

    [examining_ability.stat_block][examining_ability.long_desc][examining_ability.threshold_block]" + dat += "Back
    " + dat += "

    [examining_ability.name]

    " + dat += "[examining_ability.stat_block][examining_ability.long_desc][examining_ability.threshold_block]" + for(var/entry in examining_ability.threshold_block) + dat += "[entry]: [examining_ability.threshold_block[entry]]
    " else dat += "

    Disease Statistics


    \ Resistance: [DT.totalResistance()]
    \ diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index 2186e8b49e..fe3b5a3aeb 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -11,9 +11,10 @@ var/default_timer_set = 90 var/minimum_timer_set = 90 var/maximum_timer_set = 3600 - var/ui_style = "nanotrasen" + ui_style = "nanotrasen" var/numeric_input = "" + var/ui_mode = NUKEUI_AWAIT_DISK var/timing = FALSE var/exploding = FALSE var/exploded = FALSE @@ -97,6 +98,8 @@ if(!user.transferItemToLoc(I, src)) return auth = I + update_ui_mode() + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) add_fingerprint(user) return @@ -233,113 +236,159 @@ var/volume = (get_time_left() <= 20 ? 30 : 5) playsound(loc, 'sound/items/timer.ogg', volume, 0) +/obj/machinery/nuclearbomb/proc/update_ui_mode() + if(exploded) + ui_mode = NUKEUI_EXPLODED + return + + if(!auth) + ui_mode = NUKEUI_AWAIT_DISK + return + + if(timing) + ui_mode = NUKEUI_TIMING + return + + if(!safety) + ui_mode = NUKEUI_AWAIT_ARM + return + + if(!yes_code) + ui_mode = NUKEUI_AWAIT_CODE + return + + ui_mode = NUKEUI_AWAIT_TIMER + + /obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state=GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "nuclear_bomb", name, 500, 600, master_ui, state) + ui = new(user, src, ui_key, "nuclear_bomb", name, 350, 442, master_ui, state) ui.set_style(ui_style) ui.open() /obj/machinery/nuclearbomb/ui_data(mob/user) var/list/data = list() data["disk_present"] = auth - data["code_approved"] = yes_code - var/first_status - if(auth) - if(yes_code) - first_status = timing ? "Func/Set" : "Functional" - else - first_status = "Auth S2." + var/hidden_code = (ui_mode == NUKEUI_AWAIT_CODE && numeric_input != "ERROR") + var/current_code = "" + if(hidden_code) + while(length(current_code) < length(numeric_input)) + current_code = "[current_code]*" else - if(timing) - first_status = "Set" - else - first_status = "Auth S1." - var/second_status = exploded ? "Warhead triggered, thanks for flying Nanotrasen" : (safety ? "Safe" : "Engaged") + current_code = numeric_input + while(length(current_code) < 5) + current_code = "[current_code]-" + + var/first_status + var/second_status + switch(ui_mode) + if(NUKEUI_AWAIT_DISK) + first_status = "DEVICE LOCKED" + if(timing) + second_status = "TIME: [get_time_left()]" + else + second_status = "AWAIT DISK" + if(NUKEUI_AWAIT_CODE) + first_status = "INPUT CODE" + second_status = "CODE: [current_code]" + if(NUKEUI_AWAIT_TIMER) + first_status = "INPUT TIME" + second_status = "TIME: [current_code]" + if(NUKEUI_AWAIT_ARM) + first_status = "DEVICE READY" + second_status = "TIME: [get_time_left()]" + if(NUKEUI_TIMING) + first_status = "DEVICE ARMED" + second_status = "TIME: [get_time_left()]" + if(NUKEUI_EXPLODED) + first_status = "DEVICE DEPLOYED" + second_status = "THANK YOU" + data["status1"] = first_status data["status2"] = second_status data["anchored"] = anchored - data["safety"] = safety - data["timing"] = timing - data["time_left"] = get_time_left() - - data["timer_set"] = timer_set - data["timer_is_not_default"] = timer_set != default_timer_set - data["timer_is_not_min"] = timer_set != minimum_timer_set - data["timer_is_not_max"] = timer_set != maximum_timer_set - - var/message = "AUTH" - if(auth) - message = "[numeric_input]" - if(yes_code) - message = "*****" - data["message"] = message return data /obj/machinery/nuclearbomb/ui_act(action, params) if(..()) return + playsound(src, "terminal_type", 20, FALSE) switch(action) if("eject_disk") if(auth && auth.loc == src) + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE) auth.forceMove(get_turf(src)) auth = null . = TRUE - if("insert_disk") - if(!auth) + else var/obj/item/I = usr.is_holding_item_of_type(/obj/item/disk/nuclear) if(I && disk_check(I) && usr.transferItemToLoc(I, src)) + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE) auth = I . = TRUE + update_ui_mode() if("keypad") if(auth) var/digit = params["digit"] switch(digit) - if("R") + if("C") + if(auth && ui_mode == NUKEUI_AWAIT_ARM) + set_safety() + yes_code = FALSE + playsound(src, 'sound/machines/nuke/confirm_beep.ogg', 50, FALSE) + update_ui_mode() + else + playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE) numeric_input = "" - yes_code = FALSE . = TRUE if("E") - if(numeric_input == r_code) - numeric_input = "" - yes_code = TRUE - . = TRUE - else - numeric_input = "ERROR" + switch(ui_mode) + if(NUKEUI_AWAIT_CODE) + if(numeric_input == r_code) + numeric_input = "" + yes_code = TRUE + playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE) + . = TRUE + else + playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE) + numeric_input = "ERROR" + if(NUKEUI_AWAIT_TIMER) + var/number_value = text2num(numeric_input) + if(number_value) + timer_set = CLAMP(number_value, minimum_timer_set, maximum_timer_set) + playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE) + set_safety() + . = TRUE + else + playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE) + update_ui_mode() if("0","1","2","3","4","5","6","7","8","9") if(numeric_input != "ERROR") numeric_input += digit if(length(numeric_input) > 5) numeric_input = "ERROR" + else + playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE) . = TRUE - if("timer") - if(auth && yes_code) - var/change = params["change"] - if(change == "reset") - timer_set = default_timer_set - else if(change == "decrease") - timer_set = max(minimum_timer_set, timer_set - 10) - else if(change == "increase") - timer_set = min(maximum_timer_set, timer_set + 10) - else if(change == "input") - var/user_input = input(usr, "Set time to detonation.", name) as null|num - if(!user_input) - return - var/N = text2num(user_input) - if(!N) - return - timer_set = CLAMP(N,minimum_timer_set,maximum_timer_set) - . = TRUE - if("safety") - if(auth && yes_code && !exploded) - set_safety() + else + playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE) + if("arm") + if(auth && yes_code && !safety && !exploded) + playsound(src, 'sound/machines/nuke/confirm_beep.ogg', 50, FALSE) + set_active() + update_ui_mode() + else + playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE) if("anchor") if(auth && yes_code) + playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE) set_anchor() - if("toggle_timer") - if(auth && yes_code && !safety && !exploded) - set_active() + else + playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE) /obj/machinery/nuclearbomb/proc/set_anchor() diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index 1d6a31b072..9754d146c3 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -44,7 +44,7 @@ wander = FALSE density = FALSE movement_type = FLYING - anchored = TRUE + move_resist = MOVE_FORCE_OVERPOWERING mob_size = MOB_SIZE_TINY pass_flags = PASSTABLE | PASSGRILLE | PASSMOB speed = 1 @@ -361,7 +361,7 @@ user.dropItemToGround(src) scatter() -/obj/item/ectoplasm/revenant/throw_impact(atom/hit_atom) +/obj/item/ectoplasm/revenant/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() if(inert) return diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm index ce455d9e67..7680d61034 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -19,6 +19,7 @@ job_description = "Swarmer" death = FALSE roundstart = FALSE + short_desc = "You are a swarmer, a weapon of a long dead civilization." flavour_text = {" You are a swarmer, a weapon of a long dead civilization. Until further orders from your original masters are received, you must continue to consume and replicate. Clicking on any object will try to consume it, either deconstructing it into its components, destroying it, or integrating any materials it has into you if successful. @@ -274,7 +275,8 @@ /obj/machinery/camera/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) S.DisIntegrate(src) - toggle_cam(S, 0) + if(!QDELETED(S)) //If it got blown up no need to turn it off. + toggle_cam(S, 0) return TRUE /obj/machinery/particle_accelerator/control_box/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm index 3cc3b48e50..e6ca95472e 100644 --- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm +++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm @@ -22,11 +22,19 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( desc = "You aren't entirely sure what this does, but it's very beepy and boopy." background_icon_state = "bg_tech_blue" icon_icon = 'icons/mob/actions/actions_AI.dmi' + check_flags = AB_CHECK_CONSCIOUS //can't doomsday if dead. var/mob/living/silicon/ai/owner_AI //The owner AI, so we don't have to typecast every time var/uses //If we have multiple uses of the same power var/auto_use_uses = TRUE //If we automatically use up uses on each activation var/cooldown_period //If applicable, the time in deciseconds we have to wait before using any more modules + +/datum/action/innate/ai/New() + ..() + if(uses > 1) + desc = "[desc] It has [uses] use\s remaining." + button.desc = desc + /datum/action/innate/ai/Grant(mob/living/L) . = ..() if(!isAI(owner)) @@ -38,7 +46,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( /datum/action/innate/ai/IsAvailable() . = ..() if(owner_AI && owner_AI.malf_cooldown > world.time) - return + return FALSE /datum/action/innate/ai/Trigger() . = ..() @@ -49,12 +57,16 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( /datum/action/innate/ai/proc/adjust_uses(amt, silent) uses += amt - if(!silent && uses) - to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.") - if(!uses) - if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway! - to_chat(owner, "[name] has run out of uses!") - qdel(src) + if(uses) + if(!silent) + to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.") + desc = "[initial(desc)] It has [uses] use\s remaining." + UpdateButtonIcon() + return + if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway! + to_chat(owner, "[name] has run out of uses!") + qdel(src) + //Framework for ranged abilities that can have different effects by left-clicking stuff. /datum/action/innate/ai/ranged @@ -74,13 +86,16 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( /datum/action/innate/ai/ranged/adjust_uses(amt, silent) uses += amt - if(!silent && uses) - to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.") - if(!uses) - if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway! - to_chat(owner, "[name] has run out of uses!") - Remove(owner) - QDEL_IN(src, 100) //let any active timers on us finish up + if(uses) + if(!silent) + to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.") + desc = "[initial(desc)] It has [uses] use\s remaining." + UpdateButtonIcon() + return + if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway! + to_chat(owner, "[name] has run out of uses!") + Remove(owner) + QDEL_IN(src, 100) //let any active timers on us finish up /datum/action/innate/ai/ranged/Destroy() QDEL_NULL(linked_ability) @@ -97,7 +112,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( var/datum/action/innate/ai/ranged/attached_action /obj/effect/proc_holder/ranged_ai/Destroy() - QDEL_NULL(attached_action) + attached_action = null return ..() /obj/effect/proc_holder/ranged_ai/proc/toggle(mob/user) @@ -185,6 +200,8 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( A.playsound_local(A, AM.unlock_sound, 50, 0) else //Adding uses to an existing module action.uses += initial(action.uses) + action.desc = "[initial(action.desc)] It has [action.uses] use\s remaining." + action.UpdateButtonIcon() temp = "Additional use[action.uses > 1 ? "s" : ""] added to [action.name]!" processing_time -= AM.cost @@ -238,6 +255,8 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( return if(alert(owner, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", "confirm = TRUE;", "confirm = FALSE;") != "confirm = TRUE;") return + if (active) + return //prevent the AI from activating an already active doomsday active = TRUE set_us_up_the_bomb(owner) @@ -245,64 +264,64 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( set waitfor = FALSE to_chat(owner, "run -o -a 'selfdestruct'") sleep(5) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "Running executable 'selfdestruct'...") sleep(rand(10, 30)) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return owner.playsound_local(owner, 'sound/misc/bloblarm.ogg', 50, 0) to_chat(owner, "!!! UNAUTHORIZED SELF-DESTRUCT ACCESS !!!") to_chat(owner, "This is a class-3 security violation. This incident will be reported to Central Command.") for(var/i in 1 to 3) sleep(20) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "Sending security report to Central Command.....[rand(0, 9) + (rand(20, 30) * i)]%") sleep(3) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "auth 'akjv9c88asdf12nb' ******************") owner.playsound_local(owner, 'sound/items/timer.ogg', 50, 0) sleep(30) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "Credentials accepted. Welcome, akjv9c88asdf12nb.") owner.playsound_local(owner, 'sound/misc/server-ready.ogg', 50, 0) sleep(5) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "Arm self-destruct device? (Y/N)") owner.playsound_local(owner, 'sound/misc/compiler-stage1.ogg', 50, 0) sleep(20) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "Y") sleep(15) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "Confirm arming of self-destruct device? (Y/N)") owner.playsound_local(owner, 'sound/misc/compiler-stage2.ogg', 50, 0) sleep(10) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "Y") sleep(rand(15, 25)) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "Please repeat password to confirm.") owner.playsound_local(owner, 'sound/misc/compiler-stage2.ogg', 50, 0) sleep(14) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "******************") sleep(40) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return to_chat(owner, "Credentials accepted. Transmitting arming signal...") owner.playsound_local(owner, 'sound/misc/server-ready.ogg', 50, 0) sleep(30) - if(!owner || QDELETED(owner)) + if(QDELETED(owner) || owner.stat == DEAD) return priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", "aimalf") set_security_level("delta") @@ -724,9 +743,10 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( /datum/action/innate/ai/blackout name = "Blackout" - desc = "Overloads lights across the station." + desc = "Overloads random lights across the station." button_icon_state = "blackout" uses = 3 + auto_use_uses = FALSE /datum/action/innate/ai/blackout/Activate() for(var/obj/machinery/power/apc/apc in GLOB.apcs_list) @@ -736,6 +756,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( apc.overload++ to_chat(owner, "Overcurrent applied to the powernet.") owner.playsound_local(owner, "sparks", 50, 0) + adjust_uses(-1) //Disable Emergency Lights @@ -784,11 +805,6 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( auto_use_uses = FALSE cooldown_period = 30 -/datum/action/innate/ai/reactivate_cameras/New() - ..() - desc = "[desc] There are 30 reactivations remaining." - button.desc = desc - /datum/action/innate/ai/reactivate_cameras/Activate() var/fixed_cameras = 0 for(var/V in GLOB.cameranet.cameras) @@ -803,8 +819,6 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( to_chat(owner, "Diagnostic complete! Cameras reactivated: [fixed_cameras]. Reactivations remaining: [uses].") owner.playsound_local(owner, 'sound/items/wirecutter.ogg', 50, 0) adjust_uses(0, TRUE) //Checks the uses remaining - if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe - desc = "[initial(desc)] There are [uses] reactivations remaining." //Upgrade Camera Network: EMP-proofs all cameras, in addition to giving them X-ray vision. diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index e6bb3f1295..492da73e66 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -246,7 +246,7 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' var/mob/living/carbon/human/target = null - var/list/mob/living/carbon/human/possible = list() + var/list/mob/living/carbon/human/possible var/obj/item/voodoo_link = null var/cooldown_time = 30 //3s var/cooldown = 0 @@ -284,7 +284,7 @@ user.unset_machine() /obj/item/voodoo/attack_self(mob/user) - if(!target && possible.len) + if(!target && length(possible)) target = input(user, "Select your victim!", "Voodoo") as null|anything in possible return @@ -324,12 +324,12 @@ cooldown = world.time + cooldown_time /obj/item/voodoo/proc/update_targets() - LAZYINITLIST(possible) + possible = null if(!voodoo_link) return for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) if(md5(H.dna.uni_identity) in voodoo_link.fingerprints) - possible |= H + LAZYOR(possible, H) /obj/item/voodoo/proc/GiveHint(mob/victim,force=0) if(prob(50) || force) diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index bd4f1a8acd..70cb29e7a3 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -163,7 +163,7 @@ /datum/spellbook_entry/timestop name = "Time Stop" - spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop + spell_type = /obj/effect/proc_holder/spell/aoe_turf/timestop category = "Defensive" /datum/spellbook_entry/smoke diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm index c5e365d4eb..5e4cc17541 100644 --- a/code/modules/antagonists/wizard/wizard.dm +++ b/code/modules/antagonists/wizard/wizard.dm @@ -110,7 +110,7 @@ var/wizard_name_second = pick(GLOB.wizard_second) var/randomname = "[wizard_name_first] [wizard_name_second]" var/mob/living/wiz_mob = owner.current - var/newname = copytext(sanitize(input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN) + var/newname = reject_bad_name(stripped_input(wiz_mob, "You are the [name]. Would you like to change your name to something else?", "Name change", randomname, MAX_NAME_LEN)) if (!newname) newname = randomname diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 9079b79c3d..b223992d2c 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -142,7 +142,7 @@ . = ..() olddir = dir -/obj/item/assembly/infra/throw_impact() +/obj/item/assembly/infra/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() if(!olddir) return diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index a42fad82c0..7c8952eb33 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -46,7 +46,7 @@ return FALSE switch(type) if("feet") - if(!H.shoes) + if(!H.shoes || !(H.shoes.body_parts_covered & FEET)) affecting = H.get_bodypart(pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) H.Knockdown(60) if(BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND) @@ -130,10 +130,10 @@ return FALSE -/obj/item/assembly/mousetrap/hitby(A as mob|obj) +/obj/item/assembly/mousetrap/hitby(atom/hit_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(!armed) return ..() - visible_message("[src] is triggered by [A].") + visible_message("[src] is triggered by [hit_atom].") triggered(null) diff --git a/code/modules/assembly/playback.dm b/code/modules/assembly/playback.dm index eecb991434..42135f7ff9 100644 --- a/code/modules/assembly/playback.dm +++ b/code/modules/assembly/playback.dm @@ -25,12 +25,13 @@ listening = FALSE languages = message_language say("The recorded message is '[recorded]'.", language = message_language) + activate_cooldown = max(round(length(recorded) * 0.5), 3 SECONDS) /obj/item/assembly/playback/activate() - if(recorded == "") // Why say anything when there isn't anything to say + . = ..() + if(!. || !recorded) // Why say anything when there isn't anything to say return FALSE say("[recorded]", language = languages) // Repeat the message in the language it was said in - return TRUE /obj/item/assembly/playback/proc/record() if(!secured || holder) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 4fba44a3f2..53cbb8ea2a 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -11,7 +11,6 @@ var/code = DEFAULT_SIGNALER_CODE var/frequency = FREQ_SIGNALER - var/delay = 0 var/datum/radio_frequency/radio_connection var/suicider = null var/hearing_range = 1 @@ -48,64 +47,50 @@ holder.update_icon() return -/obj/item/assembly/signaler/ui_interact(mob/user, flag1) - . = ..() - if(is_secured(user)) - var/t1 = "-------" - var/dat = {" - - -Send Signal
    -Frequency/Code for signaler:
    -Frequency: -[format_frequency(src.frequency)] -Set
    - -Code: -[src.code] -Set
    -[t1] -
    "} - user << browse(dat, "window=radio") - onclose(user, "radio") +/obj/item/assembly/signaler/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + if(!is_secured(user)) return + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + var/ui_width = 280 + var/ui_height = 132 + ui = new(user, src, ui_key, "signaler", name, ui_width, ui_height, master_ui, state) + ui.open() +/obj/item/assembly/signaler/ui_data(mob/user) + var/list/data = list() + data["frequency"] = frequency + data["code"] = code + data["minFrequency"] = MIN_FREE_FREQ + data["maxFrequency"] = MAX_FREE_FREQ -/obj/item/assembly/signaler/Topic(href, href_list) - ..() + return data - if(!usr.canUseTopic(src, BE_CLOSE)) - usr << browse(null, "window=radio") - onclose(usr, "radio") +/obj/item/assembly/signaler/ui_act(action, params) + if(..()) return + switch(action) + if("signal") + INVOKE_ASYNC(src, .proc/signal) + . = TRUE + if("freq") + frequency = unformat_frequency(params["freq"]) + frequency = sanitize_frequency(frequency, TRUE) + set_frequency(frequency) + . = TRUE + if("code") + code = text2num(params["code"]) + code = round(code) + . = TRUE + if("reset") + if(params["reset"] == "freq") + frequency = initial(frequency) + else + code = initial(code) + . = TRUE - if (href_list["set"]) - - if(href_list["set"] == "freq") - var/new_freq = input(usr, "Input a new signalling frequency", "Remote Signaller Frequency", format_frequency(frequency)) as num|null - if(!usr.canUseTopic(src, BE_CLOSE)) - return - new_freq = unformat_frequency(new_freq) - new_freq = sanitize_frequency(new_freq, TRUE) - set_frequency(new_freq) - - if(href_list["set"] == "code") - var/new_code = input(usr, "Input a new signalling code", "Remote Signaller Code", code) as num|null - if(!usr.canUseTopic(src, BE_CLOSE)) - return - new_code = round(new_code) - new_code = CLAMP(new_code, 1, 100) - code = new_code - - if(href_list["send"]) - spawn( 0 ) - signal() - - if(usr) - attack_self(usr) - - return - + update_icon() + /obj/item/assembly/signaler/attackby(obj/item/W, mob/user, params) if(issignaler(W)) var/obj/item/assembly/signaler/signaler2 = W diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index 389f1a69f3..632542f605 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -267,12 +267,13 @@ /atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0) var/const/PROBABILITY_OFFSET = 25 var/const/PROBABILITY_BASE_PRECENT = 75 + var/max_force = sqrt(pressure_difference)*(MOVE_FORCE_DEFAULT / 5) set waitfor = 0 var/move_prob = 100 if (pressure_resistance > 0) move_prob = (pressure_difference/pressure_resistance*PROBABILITY_BASE_PRECENT)-PROBABILITY_OFFSET move_prob += pressure_resistance_prob_delta - if (move_prob > PROBABILITY_OFFSET && prob(move_prob)) + if (move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO)))) step(src, direction) last_high_pressure_movement_air_cycle = SSair.times_fired diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index e49368016b..f7c5dce30f 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -207,7 +207,7 @@ pixel_y = (dir & 3)? (dir == 1 ? -24 : 24) : 0 if(name == initial(name)) - name = "[get_area_name(src)] Air Alarm" + name = "[get_area_name(src, get_base_area = TRUE)] Air Alarm" power_change() set_frequency(frequency) @@ -250,7 +250,7 @@ "danger_level" = danger_level, ) - var/area/A = get_area(src) + var/area/A = get_base_area(src) data["atmos_alarm"] = A.atmosalm data["fire_alarm"] = A.fire @@ -386,9 +386,10 @@ send_signal(device_id, list("checks" = text2num(params["val"])^2), usr) . = TRUE if("set_external_pressure", "set_internal_pressure") - var/area/A = get_area(src) - var/target = input("New target pressure:", name, A.air_vent_info[device_id][(action == "set_external_pressure" ? "external" : "internal")]) as num|null - if(!isnull(target) && !..()) + + var/target = params["value"] + if(!isnull(target)) + send_signal(device_id, list("[action]" = target), usr) . = TRUE if("reset_external_pressure") @@ -420,12 +421,12 @@ apply_mode() . = TRUE if("alarm") - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(A.atmosalert(2, src)) post_alert(2) . = TRUE if("reset") - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(A.atmosalert(0, src)) post_alert(0) . = TRUE @@ -456,7 +457,7 @@ return 0 /obj/machinery/airalarm/proc/refresh_all() - var/area/A = get_area(src) + var/area/A = get_base_area(src) for(var/id_tag in A.air_vent_names) var/list/I = A.air_vent_info[id_tag] if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time) @@ -507,7 +508,7 @@ return "Flood" /obj/machinery/airalarm/proc/apply_mode() - var/area/A = get_area(src) + var/area/A = get_base_area(src) switch(mode) if(AALARM_MODE_SCRUBBING) for(var/device_id in A.air_scrub_names) @@ -645,7 +646,7 @@ icon_state = "alarm1" var/overlay_state = AALARM_OVERLAY_OFF - var/area/A = get_area(src) + var/area/A = get_base_area(src) switch(max(danger_level, A.atmosalm)) if(0) add_overlay(AALARM_OVERLAY_GREEN) @@ -715,7 +716,7 @@ return var/datum/signal/alert_signal = new(list( - "zone" = get_area_name(src), + "zone" = get_area_name(src, get_base_area = TRUE), "type" = "Atmospheric" )) if(alert_level==2) @@ -728,7 +729,7 @@ frequency.post_signal(src, alert_signal, range = -1) /obj/machinery/airalarm/proc/apply_danger_level() - var/area/A = get_area(src) + var/area/A = get_base_area(src) var/new_area_danger_level = 0 for(var/obj/machinery/airalarm/AA in A) diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 0450e7e8dd..0904808f51 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -1,19 +1,18 @@ -/* -Quick overview: +// Quick overview: +// +// Pipes combine to form pipelines +// Pipelines and other atmospheric objects combine to form pipe_networks +// Note: A single pipe_network represents a completely open space +// +// Pipes -> Pipelines +// Pipelines + Other Objects -> Pipe network -Pipes combine to form pipelines -Pipelines and other atmospheric objects combine to form pipe_networks - Note: A single pipe_network represents a completely open space - -Pipes -> Pipelines -Pipelines + Other Objects -> Pipe network - -*/ #define PIPE_VISIBLE_LEVEL 2 #define PIPE_HIDDEN_LEVEL 1 /obj/machinery/atmospherics anchored = TRUE + move_resist = INFINITY //Moving a connected machine without actually doing the normal (dis)connection things will probably cause a LOT of issues. idle_power_usage = 0 active_power_usage = 0 power_channel = ENVIRON @@ -100,13 +99,14 @@ Pipelines + Other Objects -> Pipe network return node_connects /obj/machinery/atmospherics/proc/normalize_cardinal_directions() - if(dir==SOUTH) - setDir(NORTH) - else if(dir==WEST) - setDir(EAST) + switch(dir) + if(SOUTH) + setDir(NORTH) + if(WEST) + setDir(EAST) //this is called just after the air controller sets up turfs -/obj/machinery/atmospherics/proc/atmosinit(var/list/node_connects) +/obj/machinery/atmospherics/proc/atmosinit(list/node_connects) if(!node_connects) //for pipes where order of nodes doesn't matter node_connects = getNodeConnects() @@ -118,12 +118,8 @@ Pipelines + Other Objects -> Pipe network update_icon() /obj/machinery/atmospherics/proc/setPipingLayer(new_layer) - if(pipe_flags & PIPING_DEFAULT_LAYER_ONLY) - new_layer = PIPING_LAYER_DEFAULT - piping_layer = new_layer - pixel_x = (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X - pixel_y = (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y - layer = initial(layer) + ((piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE) + piping_layer = (pipe_flags & PIPING_DEFAULT_LAYER_ONLY) ? PIPING_LAYER_DEFAULT : new_layer + update_icon() /obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target, iteration) return connection_check(target, piping_layer) @@ -175,9 +171,6 @@ Pipelines + Other Objects -> Pipe network nodes[nodes.Find(reference)] = null update_icon() -/obj/machinery/atmospherics/update_icon() - return - /obj/machinery/atmospherics/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pipe)) //lets you autodrop var/obj/item/pipe/pipe = W @@ -234,15 +227,13 @@ Pipelines + Other Objects -> Pipe network var/datum/gas_mixture/env_air = loc.return_air() pressures = int_air.return_pressure() - env_air.return_pressure() - var/fuck_you_dir = get_dir(src, user) // Because fuck you... - if(!fuck_you_dir) - fuck_you_dir = pick(GLOB.cardinals) - var/turf/target = get_edge_target_turf(user, fuck_you_dir) - var/range = pressures/250 - var/speed = range/5 - user.visible_message("[user] is sent flying by pressure!","The pressure sends you flying!") - user.throw_at(target, range, speed) + + // if get_dir(src, user) is not 0, target is the edge_target_turf on that dir + // otherwise, edge_target_turf uses a random cardinal direction + // range is pressures / 250 + // speed is pressures / 1250 + user.throw_at(get_edge_target_turf(user, get_dir(src, user) || pick(GLOB.cardinals)), pressures / 250, pressures / 1250) /obj/machinery/atmospherics/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) @@ -254,30 +245,20 @@ Pipelines + Other Objects -> Pipe network transfer_fingerprints_to(stored) ..() -/obj/machinery/atmospherics/proc/getpipeimage(iconset, iconstate, direction, col=rgb(255,255,255)) +/obj/machinery/atmospherics/proc/getpipeimage(iconset, iconstate, direction, col=rgb(255,255,255), piping_layer=2) //Add identifiers for the iconset if(iconsetids[iconset] == null) iconsetids[iconset] = num2text(iconsetids.len + 1) //Generate a unique identifier for this image combination - var/identifier = iconsetids[iconset] + "_[iconstate]_[direction]_[col]" + var/identifier = iconsetids[iconset] + "_[iconstate]_[direction]_[col]_[piping_layer]" if((!(. = pipeimages[identifier]))) var/image/pipe_overlay pipe_overlay = . = pipeimages[identifier] = image(iconset, iconstate, dir = direction) pipe_overlay.color = col - -/obj/machinery/atmospherics/proc/icon_addintact(var/obj/machinery/atmospherics/node) - var/image/img = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', "pipe_intact", get_dir(src,node), node.pipe_color) - underlays += img - return img.dir - -/obj/machinery/atmospherics/proc/icon_addbroken(var/connected = FALSE) - var/unconnected = (~connected) & initialize_directions - for(var/direction in GLOB.cardinals) - if(unconnected & direction) - underlays += getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', "pipe_exposed", direction) + PIPING_LAYER_SHIFT(pipe_overlay, piping_layer) /obj/machinery/atmospherics/on_construction(obj_color, set_layer) if(can_unwrench) @@ -319,7 +300,7 @@ Pipelines + Other Objects -> Pipe network if(target_move.can_crawl_through()) if(is_type_in_typecache(target_move, GLOB.ventcrawl_machinery)) user.forceMove(target_move.loc) //handle entering and so on. - user.visible_message("You hear something squeezing through the ducts...","You climb out the ventilation system.") + user.visible_message("You hear something squeezing through the ducts...", "You climb out the ventilation system.") else var/list/pipenetdiff = returnPipenets() ^ target_move.returnPipenets() if(pipenetdiff.len) @@ -331,7 +312,7 @@ Pipelines + Other Objects -> Pipe network playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3) else if(is_type_in_typecache(src, GLOB.ventcrawl_machinery) && can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent user.forceMove(loc) - user.visible_message("You hear something squeezing through the ducts...","You climb out the ventilation system.") + user.visible_message("You hear something squeezing through the ducts...", "You climb out the ventilation system.") user.canmove = FALSE addtimer(VARSET_CALLBACK(user, canmove, TRUE), 1) @@ -355,3 +336,6 @@ Pipelines + Other Objects -> Pipe network //Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it. /obj/machinery/atmospherics/proc/can_see_pipes() return TRUE + +/obj/machinery/atmospherics/proc/update_layer() + layer = initial(layer) + (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm b/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm index 486a57450b..45ccaf1e86 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm @@ -8,24 +8,14 @@ /obj/machinery/atmospherics/components/binary/SetInitDirections() switch(dir) - if(NORTH) + if(NORTH, SOUTH) initialize_directions = NORTH|SOUTH - if(SOUTH) - initialize_directions = NORTH|SOUTH - if(EAST) + if(EAST, WEST) initialize_directions = EAST|WEST - if(WEST) - initialize_directions = EAST|WEST -/* -Iconnery -*/ + /obj/machinery/atmospherics/components/binary/hide(intact) update_icon() - - ..(intact) -/* -Housekeeping and pipe network stuff -*/ + ..() /obj/machinery/atmospherics/components/binary/getNodeConnects() return list(turn(dir, 180), dir) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm index 9f38757a89..9238b8602b 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm @@ -1,13 +1,12 @@ -/* -Acts like a normal vent, but has an input AND output. -*/ +//Acts like a normal vent, but has an input AND output. + #define EXT_BOUND 1 #define INPUT_MIN 2 #define OUTPUT_MAX 4 /obj/machinery/atmospherics/components/binary/dp_vent_pump icon = 'icons/obj/atmospherics/components/unary_devices.dmi' //We reuse the normal vent icons! - icon_state = "dpvent_map" + icon_state = "dpvent_map-2" //node2 is output port //node1 is input port @@ -27,97 +26,25 @@ Acts like a normal vent, but has an input AND output. var/output_pressure_max = 0 var/pressure_checks = EXT_BOUND + //EXT_BOUND: Do not pass external_pressure_bound //INPUT_MIN: Do not pass input_pressure_min //OUTPUT_MAX: Do not pass output_pressure_max -/obj/machinery/atmospherics/components/binary/dp_vent_pump/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/on - on = TRUE - icon_state = "dpvent_map_on" - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/components/binary/dp_vent_pump/Destroy() SSradio.remove_object(src, frequency) return ..() -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume - name = "large dual-port air vent" - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_toxmix - id = INCINERATOR_TOXMIX_DP_VENTPUMP - frequency = FREQ_AIRLOCK_CONTROL - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_atmos - id = INCINERATOR_ATMOS_DP_VENTPUMP - frequency = FREQ_AIRLOCK_CONTROL - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_syndicatelava - id = INCINERATOR_SYNDICATELAVA_DP_VENTPUMP - frequency = FREQ_AIRLOCK_CONTROL - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/on - on = TRUE - icon_state = "dpvent_map_on" - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/New() - ..() - var/datum/gas_mixture/air1 = airs[1] - var/datum/gas_mixture/air2 = airs[2] - air1.volume = 1000 - air2.volume = 1000 - /obj/machinery/atmospherics/components/binary/dp_vent_pump/update_icon_nopipes() cut_overlays() if(showpipe) - add_overlay(getpipeimage('icons/obj/atmospherics/components/unary_devices.dmi', "dpvent_cap")) + var/image/cap = getpipeimage(icon, "dpvent_cap", dir, piping_layer = piping_layer) + add_overlay(cap) if(!on || !is_operational()) icon_state = "vent_off" - return - - if(pump_direction) - icon_state = "vent_out" else - icon_state = "vent_in" + icon_state = pump_direction ? "vent_out" : "vent_in" /obj/machinery/atmospherics/components/binary/dp_vent_pump/process_atmos() ..() @@ -248,6 +175,70 @@ Acts like a normal vent, but has an input AND output. broadcast_status() update_icon() +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume + name = "large dual-port air vent" + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/New() + ..() + var/datum/gas_mixture/air1 = airs[1] + var/datum/gas_mixture/air2 = airs[2] + air1.volume = 1000 + air2.volume = 1000 + +// Mapping + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/layer1 + piping_layer = 1 + icon_state = "dpvent_map-1" + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/layer3 + piping_layer = 3 + icon_state = "dpvent_map-3" + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/on + on = TRUE + icon_state = "dpvent_map_on-2" + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/on/layer1 + piping_layer = 1 + icon_state = "dpvent_map_on-1" + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/on/layer3 + piping_layer = 3 + icon_state = "dpvent_map_on-3" + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_toxmix + id = INCINERATOR_TOXMIX_DP_VENTPUMP + frequency = FREQ_AIRLOCK_CONTROL + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_atmos + id = INCINERATOR_ATMOS_DP_VENTPUMP + frequency = FREQ_AIRLOCK_CONTROL + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_syndicatelava + id = INCINERATOR_SYNDICATELAVA_DP_VENTPUMP + frequency = FREQ_AIRLOCK_CONTROL + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/layer1 + piping_layer = 1 + icon_state = "dpvent_map-1" + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/layer3 + piping_layer = 3 + icon_state = "dpvent_map-3" + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/on + on = TRUE + icon_state = "dpvent_map_on-2" + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/on/layer1 + piping_layer = 1 + icon_state = "dpvent_map_on-1" + +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/on/layer3 + piping_layer = 3 + icon_state = "dpvent_map_on-3" + #undef EXT_BOUND #undef INPUT_MIN #undef OUTPUT_MAX diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 329ef33637..02eb95acab 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -7,12 +7,13 @@ Passive gate is similar to the regular pump except: */ /obj/machinery/atmospherics/components/binary/passive_gate - icon_state = "passgate_map" + icon_state = "passgate_map-2" name = "passive gate" desc = "A one-way air valve that does not require power." can_unwrench = TRUE + shift_underlay_only = FALSE interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE @@ -25,27 +26,15 @@ Passive gate is similar to the regular pump except: construction_type = /obj/item/pipe/directional pipe_state = "passivegate" -/obj/machinery/atmospherics/components/binary/passive_gate/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/passive_gate/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/components/binary/passive_gate/Destroy() SSradio.remove_object(src,frequency) return ..() /obj/machinery/atmospherics/components/binary/passive_gate/update_icon_nopipes() - if(!on) - icon_state = "passgate_off" - cut_overlays() - return - - add_overlay(getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', "passgate_on")) + cut_overlays() + icon_state = "passgate_off" + if(on) + add_overlay(getpipeimage(icon, "passgate_on")) /obj/machinery/atmospherics/components/binary/passive_gate/process_atmos() ..() @@ -176,3 +165,11 @@ Passive gate is similar to the regular pump except: if(. && on) to_chat(user, "You cannot unwrench [src], turn it off first!") return FALSE + +/obj/machinery/atmospherics/components/binary/passive_gate/layer1 + piping_layer = 1 + icon_state = "passgate_map-1" + +/obj/machinery/atmospherics/components/binary/passive_gate/layer3 + piping_layer = 3 + icon_state = "passgate_map-3" \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index c05c3bb3c9..9e49953df5 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -1,23 +1,22 @@ -/* -Every cycle, the pump uses the air in air_in to try and make air_out the perfect pressure. - -node1, air1, network1 correspond to input -node2, air2, network2 correspond to output - -Thus, the two variables affect pump operation are set in New(): - air1.volume - This is the volume of gas available to the pump that may be transfered to the output - air2.volume - Higher quantities of this cause more air to be perfected later - but overall network volume is also increased as this increases... -*/ +// Every cycle, the pump uses the air in air_in to try and make air_out the perfect pressure. +// +// node1, air1, network1 correspond to input +// node2, air2, network2 correspond to output +// +// Thus, the two variables affect pump operation are set in New(): +// air1.volume +// This is the volume of gas available to the pump that may be transfered to the output +// air2.volume +// Higher quantities of this cause more air to be perfected later +// but overall network volume is also increased as this increases... /obj/machinery/atmospherics/components/binary/pump - icon_state = "pump_map" + icon_state = "pump_map-2" name = "gas pump" desc = "A pump that moves gas by pressure." can_unwrench = TRUE + shift_underlay_only = FALSE var/target_pressure = ONE_ATMOSPHERE @@ -54,30 +53,6 @@ Thus, the two variables affect pump operation are set in New(): message_admins("Pump, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") return TRUE -/obj/machinery/atmospherics/components/binary/pump/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/pump/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/pump/on - on = TRUE - icon_state = "pump_on_map" - -/obj/machinery/atmospherics/components/binary/pump/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/pump/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/components/binary/pump/Destroy() SSradio.remove_object(src,frequency) if(radio_connection) @@ -85,11 +60,7 @@ Thus, the two variables affect pump operation are set in New(): return ..() /obj/machinery/atmospherics/components/binary/pump/update_icon_nopipes() - if(!is_operational()) - icon_state = "pump_off" - return - - icon_state = "pump_[on?"on":"off"]" + icon_state = (on && is_operational()) ? "pump_on" : "pump_off" /obj/machinery/atmospherics/components/binary/pump/process_atmos() // ..() @@ -222,3 +193,23 @@ Thus, the two variables affect pump operation are set in New(): investigate_log("Pump, [src.name], was unwrenched by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) message_admins("Pump, [src.name], was unwrenched by [ADMIN_LOOKUPFLW(user)] at [A]") return TRUE + +/obj/machinery/atmospherics/components/binary/pump/layer1 + piping_layer = 1 + icon_state= "pump_map-1" + +/obj/machinery/atmospherics/components/binary/pump/layer3 + piping_layer = 3 + icon_state= "pump_map-3" + +/obj/machinery/atmospherics/components/binary/pump/on + on = TRUE + icon_state = "pump_on_map-2" + +/obj/machinery/atmospherics/components/binary/pump/on/layer1 + piping_layer = 1 + icon_state= "pump_on_map-1" + +/obj/machinery/atmospherics/components/binary/pump/on/layer3 + piping_layer = 3 + icon_state= "pump_on_map-3" \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/binary_devices/relief_valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/relief_valve.dm index 5835912cd3..bc58ef158f 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/relief_valve.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/relief_valve.dm @@ -5,6 +5,7 @@ icon_state = "relief_valve-t-map" can_unwrench = TRUE construction_type = /obj/item/pipe/binary + interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE var/opened = FALSE var/open_pressure = ONE_ATMOSPHERE * 3 var/close_pressure = ONE_ATMOSPHERE @@ -50,9 +51,11 @@ if(!is_operational()) return - var/datum/gas_mixture/air_contents = airs[1] - var/our_pressure = air_contents.return_pressure() - if(opened && our_pressure < close_pressure) + var/datum/gas_mixture/air_one = airs[1] + var/datum/gas_mixture/air_two = airs[2] + var/air_one_pressure = air_one.return_pressure() + var/our_pressure = abs(air_one_pressure - air_two.return_pressure()) + if(opened && air_one_pressure < close_pressure) close() else if(!opened && our_pressure >= open_pressure) open() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm index f22ac62106..43cb658210 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm @@ -3,12 +3,15 @@ It's like a regular ol' straight pipe, but you can turn it on and off. */ /obj/machinery/atmospherics/components/binary/valve - icon_state = "mvalve_map" + icon_state = "mvalve_map-2" name = "manual valve" desc = "A pipe with a valve that can be used to disable flow of gas through it." can_unwrench = TRUE - interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_OPEN //Intentionally no allow_silicon flag + shift_underlay_only = FALSE + + interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_OPEN //Intentionally no allow_silicon flag + pipe_flags = PIPING_CARDINAL_AUTONORMALIZE var/frequency = 0 var/id = null @@ -20,101 +23,87 @@ It's like a regular ol' straight pipe, but you can turn it on and off. var/switching = FALSE +/obj/machinery/atmospherics/components/binary/valve/update_icon_nopipes(animation = FALSE) + normalize_cardinal_directions() + if(animation) + flick("[valve_type]valve_[on][!on]", src) + icon_state = "[valve_type]valve_[on ? "on" : "off"]" + +/obj/machinery/atmospherics/components/binary/valve/proc/toggle() + if(on) + on = FALSE + update_icon_nopipes() + investigate_log("was closed by [usr ? key_name(usr) : "a remote signal"]", INVESTIGATE_ATMOS) + else + on = TRUE + update_icon_nopipes() + update_parents() + var/datum/pipeline/parent1 = parents[1] + parent1.reconcile_air() + investigate_log("was opened by [usr ? key_name(usr) : "a remote signal"]", INVESTIGATE_ATMOS) + +/obj/machinery/atmospherics/components/binary/valve/interact(mob/user) + add_fingerprint(usr) + if(switching) + return + update_icon_nopipes(TRUE) + switching = TRUE + addtimer(CALLBACK(src, .proc/finish_interact), 10) + +/obj/machinery/atmospherics/components/binary/valve/proc/finish_interact() + toggle() + switching = FALSE + +/obj/machinery/atmospherics/components/binary/valve/digital // can be controlled by AI + icon_state = "dvalve_map-2" + name = "digital valve" + desc = "A digitally controlled valve." + valve_type = "d" + pipe_state = "dvalve" + interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_OPEN | INTERACT_MACHINE_OPEN_SILICON + +/obj/machinery/atmospherics/components/binary/valve/digital/update_icon_nopipes(animation) + if(!is_operational()) + normalize_cardinal_directions() + icon_state = "dvalve_nopower" + return + ..() + + /obj/machinery/atmospherics/components/binary/valve/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y + piping_layer = 1 + icon_state = "mvalve_map-1" /obj/machinery/atmospherics/components/binary/valve/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y + piping_layer = 3 + icon_state = "mvalve_map-3" /obj/machinery/atmospherics/components/binary/valve/on on = TRUE /obj/machinery/atmospherics/components/binary/valve/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y + piping_layer = 1 + icon_state = "mvalve_map-1" /obj/machinery/atmospherics/components/binary/valve/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/valve/update_icon_nopipes(animation = 0) - normalize_dir() - if(animation) - flick("[valve_type]valve_[on][!on]",src) - icon_state = "[valve_type]valve_[on?"on":"off"]" - -/obj/machinery/atmospherics/components/binary/valve/proc/open() - on = TRUE - update_icon_nopipes() - update_parents() - var/datum/pipeline/parent1 = parents[1] - parent1.reconcile_air() - investigate_log("was opened by [usr ? key_name(usr) : "a remote signal"]", INVESTIGATE_ATMOS) - -/obj/machinery/atmospherics/components/binary/valve/proc/close() - on = FALSE - update_icon_nopipes() - investigate_log("was closed by [usr ? key_name(usr) : "a remote signal"]", INVESTIGATE_ATMOS) - -/obj/machinery/atmospherics/components/binary/valve/proc/normalize_dir() - if(dir==SOUTH) - setDir(NORTH) - else if(dir==WEST) - setDir(EAST) - -/obj/machinery/atmospherics/components/binary/valve/interact(mob/user) - add_fingerprint(usr) - update_icon_nopipes(1) - if(switching) - return - switching = TRUE - sleep(10) - if(on) - close() - else - open() - switching = FALSE - -/obj/machinery/atmospherics/components/binary/valve/digital // can be controlled by AI - name = "digital valve" - desc = "A digitally controlled valve." - icon_state = "dvalve_map" - valve_type = "d" - pipe_state = "dvalve" - interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_OPEN | INTERACT_MACHINE_OPEN_SILICON + piping_layer = 3 + icon_state = "mvalve_map-3" /obj/machinery/atmospherics/components/binary/valve/digital/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y + piping_layer = 1 + icon_state = "dvalve_map-1" /obj/machinery/atmospherics/components/binary/valve/digital/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y + piping_layer = 3 + icon_state = "dvalve_map-3" /obj/machinery/atmospherics/components/binary/valve/digital/on on = TRUE /obj/machinery/atmospherics/components/binary/valve/digital/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y + piping_layer = 1 + icon_state = "dvalve_map-1" /obj/machinery/atmospherics/components/binary/valve/digital/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/valve/digital/update_icon_nopipes(animation) - if(!is_operational()) - normalize_dir() - icon_state = "dvalve_nopower" - return - ..() + piping_layer = 3 + icon_state = "dvalve_map-3" \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index e9fa52fd23..864e3eef5e 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -1,23 +1,22 @@ -/* -Every cycle, the pump uses the air in air_in to try and make air_out the perfect pressure. - -node1, air1, network1 correspond to input -node2, air2, network2 correspond to output - -Thus, the two variables affect pump operation are set in New(): - air1.volume - This is the volume of gas available to the pump that may be transfered to the output - air2.volume - Higher quantities of this cause more air to be perfected later - but overall network volume is also increased as this increases... -*/ +// Every cycle, the pump uses the air in air_in to try and make air_out the perfect pressure. +// +// node1, air1, network1 correspond to input +// node2, air2, network2 correspond to output +// +// Thus, the two variables affect pump operation are set in New(): +// air1.volume +// This is the volume of gas available to the pump that may be transfered to the output +// air2.volume +// Higher quantities of this cause more air to be perfected later +// but overall network volume is also increased as this increases... /obj/machinery/atmospherics/components/binary/volume_pump - icon_state = "volpump_map" + icon_state = "volpump_map-2" name = "volumetric gas pump" desc = "A pump that moves gas by volume." can_unwrench = TRUE + shift_underlay_only = FALSE var/transfer_rate = MAX_TRANSFER_RATE @@ -43,40 +42,12 @@ Thus, the two variables affect pump operation are set in New(): message_admins("Volume Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") return ..() -/obj/machinery/atmospherics/components/binary/volume_pump/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/volume_pump/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/components/binary/volume_pump/Destroy() SSradio.remove_object(src,frequency) return ..() -/obj/machinery/atmospherics/components/binary/volume_pump/on - on = TRUE - icon_state = "volpump_on_map" - -/obj/machinery/atmospherics/components/binary/volume_pump/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/binary/volume_pump/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/components/binary/volume_pump/update_icon_nopipes() - if(!is_operational()) - icon_state = "volpump_off" - return - - icon_state = "volpump_[on?"on":"off"]" + icon_state = on && is_operational() ? "volpump_on" : "volpump_off" /obj/machinery/atmospherics/components/binary/volume_pump/process_atmos() // ..() @@ -208,3 +179,25 @@ Thus, the two variables affect pump operation are set in New(): investigate_log("Pump, [src.name], was unwrenched by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) message_admins("Pump, [src.name], was unwrenched by [ADMIN_LOOKUPFLW(user)] at [A]") return TRUE + +// Mapping + +/obj/machinery/atmospherics/components/binary/volume_pump/layer1 + piping_layer = 1 + icon_state = "volpump_map-1" + +/obj/machinery/atmospherics/components/binary/volume_pump/layer3 + piping_layer = 3 + icon_state = "volpump_map-3" + +/obj/machinery/atmospherics/components/binary/volume_pump/on + on = TRUE + icon_state = "volpump_on_map" + +/obj/machinery/atmospherics/components/binary/volume_pump/on/layer1 + piping_layer = 1 + icon_state = "volpump_map-1" + +/obj/machinery/atmospherics/components/binary/volume_pump/on/layer3 + piping_layer = 3 + icon_state = "volpump_map-3" \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm index e31d96a0c2..86e8863b2b 100644 --- a/code/modules/atmospherics/machinery/components/components_base.dm +++ b/code/modules/atmospherics/machinery/components/components_base.dm @@ -1,11 +1,10 @@ -/* -So much of atmospherics.dm was used solely by components, so separating this makes things all a lot cleaner. -On top of that, now people can add component-speciic procs/vars if they want! -*/ +// So much of atmospherics.dm was used solely by components, so separating this makes things all a lot cleaner. +// On top of that, now people can add component-speciic procs/vars if they want! /obj/machinery/atmospherics/components var/welded = FALSE //Used on pumps and scrubbers var/showpipe = FALSE + var/shift_underlay_only = TRUE //Layering only shifts underlay? var/list/datum/pipeline/parents var/list/datum/gas_mixture/airs @@ -19,9 +18,8 @@ On top of that, now people can add component-speciic procs/vars if they want! var/datum/gas_mixture/A = new A.volume = 200 airs[i] = A -/* -Iconnery -*/ + +// Iconnery /obj/machinery/atmospherics/components/proc/update_icon_nopipes() return @@ -32,7 +30,7 @@ Iconnery underlays.Cut() var/turf/T = loc - if(level == 2 || !T.intact) + if(level == 2 || (istype(T) && !T.intact)) showpipe = TRUE plane = GAME_PLANE else @@ -46,14 +44,25 @@ Iconnery for(var/i in 1 to device_type) //adds intact pieces if(nodes[i]) - connected |= icon_addintact(nodes[i]) + var/obj/machinery/atmospherics/node = nodes[i] + var/image/img = get_pipe_underlay("pipe_intact", get_dir(src, node), node.pipe_color) + underlays += img + connected |= img.dir - icon_addbroken(connected) //adds broken pieces + for(var/direction in GLOB.cardinals) + if((initialize_directions & direction) && !(connected & direction)) + underlays += get_pipe_underlay("pipe_exposed", direction) + if(!shift_underlay_only) + PIPING_LAYER_SHIFT(src, piping_layer) -/* -Pipenet stuff; housekeeping -*/ +/obj/machinery/atmospherics/components/proc/get_pipe_underlay(state, dir, color = null) + if(color) + . = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, color, piping_layer = shift_underlay_only ? piping_layer : 2) + else + . = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, piping_layer = shift_underlay_only ? piping_layer : 2) + +// Pipenet stuff; housekeeping /obj/machinery/atmospherics/components/nullifyNode(i) if(nodes[i]) @@ -129,9 +138,7 @@ Pipenet stuff; housekeeping return new_value return default_set -/* -Helpers -*/ +// Helpers /obj/machinery/atmospherics/components/proc/update_parents() for(var/i in 1 to device_type) @@ -146,9 +153,9 @@ Helpers for(var/i in 1 to device_type) . += returnPipenet(nodes[i]) -/* -UI Stuff -*/ + +// UI Stuff + /obj/machinery/atmospherics/components/ui_status(mob/user) if(allowed(user)) @@ -156,9 +163,9 @@ UI Stuff to_chat(user, "Access denied.") return UI_CLOSE -/* -Tool acts -*/ + +// Tool acts + /obj/machinery/atmospherics/components/analyzer_act(mob/living/user, obj/item/I) atmosanalyzer_scan(airs, user, src) \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index adca444b10..1099020662 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -1,9 +1,12 @@ /obj/machinery/atmospherics/components/trinary/filter - name = "gas filter" icon_state = "filter_off" - desc = "Very useful for filtering gasses." density = FALSE + + name = "gas filter" + desc = "Very useful for filtering gasses." + can_unwrench = TRUE + var/transfer_rate = MAX_TRANSFER_RATE var/filter_type = null var/frequency = 0 @@ -38,38 +41,6 @@ message_admins("Filter, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") return TRUE -/obj/machinery/atmospherics/components/trinary/filter/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/trinary/filter/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/trinary/filter/flipped - icon_state = "filter_off_f" - flipped = TRUE - -/obj/machinery/atmospherics/components/trinary/filter/flipped/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/trinary/filter/flipped/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -// These two filter types have critical_machine flagged to on and thus causes the area they are in to be exempt from the Grid Check event. - -/obj/machinery/atmospherics/components/trinary/filter/critical - critical_machine = TRUE - -/obj/machinery/atmospherics/components/trinary/filter/flipped/critical - critical_machine = TRUE - /obj/machinery/atmospherics/components/trinary/filter/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) frequency = new_frequency @@ -80,62 +51,26 @@ SSradio.remove_object(src,frequency) return ..() -/obj/machinery/atmospherics/components/trinary/filter/atmos //Used for atmos waste loops - on = TRUE - icon_state = "filter_on" - -/obj/machinery/atmospherics/components/trinary/filter/atmos/n2 - name = "nitrogen filter" - filter_type = "n2" -/obj/machinery/atmospherics/components/trinary/filter/atmos/o2 - name = "oxygen filter" - filter_type = "o2" -/obj/machinery/atmospherics/components/trinary/filter/atmos/co2 - name = "carbon dioxide filter" - filter_type = "co2" -/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o - name = "nitrous oxide filter" - filter_type = "n2o" -/obj/machinery/atmospherics/components/trinary/filter/atmos/plasma - name = "plasma filter" - filter_type = "plasma" - -/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped //This feels wrong, I know - icon_state = "filter_on_f" - flipped = TRUE - -/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2 - name = "nitrogen filter" - filter_type = "n2" -/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/o2 - name = "oxygen filter" - filter_type = "o2" -/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/co2 - name = "carbon dioxide filter" - filter_type = "co2" -/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2o - name = "nitrous oxide filter" - filter_type = "n2o" -/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/plasma - name = "plasma filter" - filter_type = "plasma" - /obj/machinery/atmospherics/components/trinary/filter/update_icon() cut_overlays() for(var/direction in GLOB.cardinals) - if(direction & initialize_directions) - var/obj/machinery/atmospherics/node = findConnecting(direction) - if(node) - add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction, node.pipe_color)) - continue - add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction)) - ..() + if(!(direction & initialize_directions)) + continue + var/obj/machinery/atmospherics/node = findConnecting(direction) + + var/image/cap + if(node) + cap = getpipeimage(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer) + else + cap = getpipeimage(icon, "cap", direction, piping_layer = piping_layer) + + add_overlay(cap) + + return ..() /obj/machinery/atmospherics/components/trinary/filter/update_icon_nopipes() - if(on && nodes[1] && nodes[2] && nodes[3] && is_operational()) - icon_state = "filter_on[flipped?"_f":""]" - return - icon_state = "filter_off[flipped?"_f":""]" + var/on_state = on && nodes[1] && nodes[2] && nodes[3] && is_operational() + icon_state = "filter_[on_state ? "on" : "off"][flipped ? "_f" : ""]" /obj/machinery/atmospherics/components/trinary/filter/power_change() var/old_stat = stat @@ -203,7 +138,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_filter", name, 475, 195, master_ui, state) + ui = new(user, src, ui_key, "atmos_filter", name, 475, 185, master_ui, state) ui.open() /obj/machinery/atmospherics/components/trinary/filter/ui_data() @@ -258,3 +193,91 @@ if(. && on && is_operational()) to_chat(user, "You cannot unwrench [src], turn it off first!") return FALSE + +// Mapping + +/obj/machinery/atmospherics/components/trinary/filter/layer1 + piping_layer = 1 + icon_state = "filter_off_map-1" +/obj/machinery/atmospherics/components/trinary/filter/layer3 + piping_layer = 3 + icon_state = "filter_off_map-3" + +/obj/machinery/atmospherics/components/trinary/filter/on + on = TRUE + icon_state = "filter_on" + +/obj/machinery/atmospherics/components/trinary/filter/on/layer1 + piping_layer = 1 + icon_state = "filter_on_map-1" +/obj/machinery/atmospherics/components/trinary/filter/on/layer3 + piping_layer = 3 + icon_state = "filter_on_map-3" + +/obj/machinery/atmospherics/components/trinary/filter/flipped + icon_state = "filter_off_f" + flipped = TRUE + +/obj/machinery/atmospherics/components/trinary/filter/flipped/layer1 + piping_layer = 1 + icon_state = "filter_off_f_map-1" +/obj/machinery/atmospherics/components/trinary/filter/flipped/layer3 + piping_layer = 3 + icon_state = "filter_off_f_map-3" + +/obj/machinery/atmospherics/components/trinary/filter/flipped/on + on = TRUE + icon_state = "filter_on_f" + +/obj/machinery/atmospherics/components/trinary/filter/flipped/on/layer1 + piping_layer = 1 + icon_state = "filter_on_f_map-1" +/obj/machinery/atmospherics/components/trinary/filter/flipped/on/layer3 + piping_layer = 3 + icon_state = "filter_on_f_map-3" + +/obj/machinery/atmospherics/components/trinary/filter/atmos //Used for atmos waste loops + on = TRUE + icon_state = "filter_on" +/obj/machinery/atmospherics/components/trinary/filter/atmos/n2 + name = "nitrogen filter" + filter_type = "n2" +/obj/machinery/atmospherics/components/trinary/filter/atmos/o2 + name = "oxygen filter" + filter_type = "o2" +/obj/machinery/atmospherics/components/trinary/filter/atmos/co2 + name = "carbon dioxide filter" + filter_type = "co2" +/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o + name = "nitrous oxide filter" + filter_type = "n2o" +/obj/machinery/atmospherics/components/trinary/filter/atmos/plasma + name = "plasma filter" + filter_type = "plasma" + +/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped //This feels wrong, I know + icon_state = "filter_on_f" + flipped = TRUE +/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2 + name = "nitrogen filter" + filter_type = "n2" +/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/o2 + name = "oxygen filter" + filter_type = "o2" +/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/co2 + name = "carbon dioxide filter" + filter_type = "co2" +/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/n2o + name = "nitrous oxide filter" + filter_type = "n2o" +/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/plasma + name = "plasma filter" + filter_type = "plasma" + +// These two filter types have critical_machine flagged to on and thus causes the area they are in to be exempt from the Grid Check event. + +/obj/machinery/atmospherics/components/trinary/filter/critical + critical_machine = TRUE + +/obj/machinery/atmospherics/components/trinary/filter/flipped/critical + critical_machine = TRUE \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index 9646b78321..5b929452fe 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -3,9 +3,10 @@ density = FALSE name = "gas mixer" - can_unwrench = TRUE desc = "Very useful for mixing gasses." + can_unwrench = TRUE + var/target_pressure = ONE_ATMOSPHERE var/node1_concentration = 0.5 var/node2_concentration = 0.5 @@ -13,100 +14,45 @@ construction_type = /obj/item/pipe/trinary/flippable pipe_state = "mixer" + ui_x = 370 + ui_y = 165 + //node 3 is the outlet, nodes 1 & 2 are intakes -/obj/machinery/atmospherics/components/trinary/mixer/examine(mob/user) - . = ..() - . += "You can hold Ctrl and click on it to toggle it on and off." - . += "You can hold Alt and click on it to maximize its pressure." /obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user) - var/area/A = get_area(src) - var/turf/T = get_turf(src) - if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) on = !on update_icon() - investigate_log("Mixer, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Mixer, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") - return ..() + return ..() /obj/machinery/atmospherics/components/trinary/mixer/AltClick(mob/user) - . = ..() - var/area/A = get_area(src) - var/turf/T = get_turf(src) - if(user.canUseTopic(src, BE_CLOSE, FALSE,)) + if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) target_pressure = MAX_OUTPUT_PRESSURE - to_chat(user,"You maximize the pressure on the [src].") - investigate_log("Mixer, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Mixer, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") - return TRUE + update_icon() + return ..() //node 3 is the outlet, nodes 1 & 2 are intakes -/obj/machinery/atmospherics/components/trinary/mixer/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/trinary/mixer/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/trinary/mixer/flipped - icon_state = "mixer_off_f" - flipped = TRUE - -/obj/machinery/atmospherics/components/trinary/mixer/flipped/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/trinary/mixer/flipped/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/trinary/mixer/airmix //For standard airmix to distro - name = "air mixer" - icon_state = "mixer_on" - node1_concentration = N2STANDARD - node2_concentration = O2STANDARD - on = TRUE - target_pressure = MAX_OUTPUT_PRESSURE - -/obj/machinery/atmospherics/components/trinary/mixer/airmix/inverse - node1_concentration = O2STANDARD - node2_concentration = N2STANDARD - -/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped - icon_state = "mixer_on_f" - flipped = TRUE - -/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped/inverse - node1_concentration = O2STANDARD - node2_concentration = N2STANDARD /obj/machinery/atmospherics/components/trinary/mixer/update_icon() cut_overlays() for(var/direction in GLOB.cardinals) - if(direction & initialize_directions) - var/obj/machinery/atmospherics/node = findConnecting(direction) - if(node) - add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction, node.pipe_color)) - continue - add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction)) + if(!(direction & initialize_directions)) + continue + var/obj/machinery/atmospherics/node = findConnecting(direction) + + var/image/cap + if(node) + cap = getpipeimage(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer) + else + cap = getpipeimage(icon, "cap", direction, piping_layer = piping_layer) + + add_overlay(cap) + return ..() /obj/machinery/atmospherics/components/trinary/mixer/update_icon_nopipes() - if(on && nodes[1] && nodes[2] && nodes[3] && is_operational()) - icon_state = "mixer_on[flipped?"_f":""]" - return - icon_state = "mixer_off[flipped?"_f":""]" - -/obj/machinery/atmospherics/components/trinary/mixer/power_change() - var/old_stat = stat - ..() - if(stat != old_stat) - update_icon() + var/on_state = on && nodes[1] && nodes[2] && nodes[3] && is_operational() + icon_state = "mixer_[on_state ? "on" : "off"][flipped ? "_f" : ""]" /obj/machinery/atmospherics/components/trinary/mixer/New() ..() @@ -119,8 +65,13 @@ if(!on || !(nodes[1] && nodes[2] && nodes[3]) && !is_operational()) return + //Get those gases, mah boiiii var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air2 = airs[2] + + if(!air1 || !air2) + return + var/datum/gas_mixture/air3 = airs[3] var/output_starting_pressure = air3.return_pressure() @@ -130,60 +81,57 @@ return //Calculate necessary moles to transfer using PV=nRT + var/general_transfer = (target_pressure - output_starting_pressure) * air3.volume / R_IDEAL_GAS_EQUATION - var/pressure_delta = target_pressure - output_starting_pressure - var/transfer_moles1 = 0 - var/transfer_moles2 = 0 - - if(air1.temperature > 0) - transfer_moles1 = (node1_concentration * pressure_delta) * air3.volume / (air1.temperature * R_IDEAL_GAS_EQUATION) - - if(air2.temperature > 0) - transfer_moles2 = (node2_concentration * pressure_delta) * air3.volume / (air2.temperature * R_IDEAL_GAS_EQUATION) + var/transfer_moles1 = air1.temperature ? node1_concentration * general_transfer / air1.temperature : 0 + var/transfer_moles2 = air2.temperature ? node2_concentration * general_transfer / air2.temperature : 0 var/air1_moles = air1.total_moles() var/air2_moles = air2.total_moles() - if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2)) - var/ratio = 0 - if((transfer_moles1 > 0 ) && (transfer_moles2 > 0)) + if(!node2_concentration) + if(air1.temperature <= 0) + return + transfer_moles1 = min(transfer_moles1, air1_moles) + transfer_moles2 = 0 + else if(!node1_concentration) + if(air2.temperature <= 0) + return + transfer_moles2 = min(transfer_moles2, air2_moles) + transfer_moles1 = 0 + else + if(air1.temperature <= 0 || air2.temperature <= 0) + return + if((transfer_moles2 <= 0) || (transfer_moles1 <= 0)) + return + if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2)) + var/ratio = 0 ratio = min(air1_moles / transfer_moles1, air2_moles / transfer_moles2) - if((transfer_moles2 == 0 ) && ( transfer_moles1 > 0)) - ratio = air1_moles / transfer_moles1 - if((transfer_moles1 == 0 ) && ( transfer_moles2 > 0)) - ratio = air2_moles / transfer_moles2 - - transfer_moles1 *= ratio - transfer_moles2 *= ratio + transfer_moles1 *= ratio + transfer_moles2 *= ratio //Actually transfer the gas - if(transfer_moles1 > 0) + if(transfer_moles1) var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1) air3.merge(removed1) - - if(transfer_moles2 > 0) - var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2) - air3.merge(removed2) - - if(transfer_moles1) var/datum/pipeline/parent1 = parents[1] parent1.update = TRUE if(transfer_moles2) + var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2) + air3.merge(removed2) var/datum/pipeline/parent2 = parents[2] parent2.update = TRUE var/datum/pipeline/parent3 = parents[3] parent3.update = TRUE - return - /obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_mixer", name, 370, 165, master_ui, state) + ui = new(user, src, ui_key, "atmos_mixer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/atmospherics/components/trinary/mixer/ui_data() @@ -191,8 +139,8 @@ data["on"] = on data["set_pressure"] = round(target_pressure) data["max_pressure"] = round(MAX_OUTPUT_PRESSURE) - data["node1_concentration"] = round(node1_concentration*100) - data["node2_concentration"] = round(node2_concentration*100) + data["node1_concentration"] = round(node1_concentration*100, 1) + data["node2_concentration"] = round(node2_concentration*100, 1) return data /obj/machinery/atmospherics/components/trinary/mixer/ui_act(action, params) @@ -220,21 +168,84 @@ investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) if("node1") var/value = text2num(params["concentration"]) - node1_concentration = max(0, min(1, node1_concentration + value)) - node2_concentration = max(0, min(1, node2_concentration - value)) + adjust_node1_value(value) investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", INVESTIGATE_ATMOS) . = TRUE if("node2") var/value = text2num(params["concentration"]) - node2_concentration = max(0, min(1, node2_concentration + value)) - node1_concentration = max(0, min(1, node1_concentration - value)) + adjust_node1_value(100 - value) investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", INVESTIGATE_ATMOS) . = TRUE update_icon() +/obj/machinery/atmospherics/components/trinary/mixer/proc/adjust_node1_value(newValue) + node1_concentration = newValue / 100 + node2_concentration = 1 - node1_concentration -/obj/machinery/atmospherics/components/trinary/filter/can_unwrench(mob/user) +/obj/machinery/atmospherics/components/trinary/mixer/can_unwrench(mob/user) . = ..() if(. && on && is_operational()) to_chat(user, "You cannot unwrench [src], turn it off first!") return FALSE + +// mapping + +/obj/machinery/atmospherics/components/trinary/mixer/layer1 + piping_layer = 1 + icon_state = "mixer_off_map-1" +/obj/machinery/atmospherics/components/trinary/mixer/layer3 + piping_layer = 3 + icon_state = "mixer_off_map-3" + +/obj/machinery/atmospherics/components/trinary/mixer/on + on = TRUE + icon_state = "mixer_on" + +/obj/machinery/atmospherics/components/trinary/mixer/on/layer1 + piping_layer = 1 + icon_state = "mixer_on_map-1" +/obj/machinery/atmospherics/components/trinary/mixer/on/layer3 + piping_layer = 3 + icon_state = "mixer_on_map-3" + +/obj/machinery/atmospherics/components/trinary/mixer/flipped + icon_state = "mixer_off_f" + flipped = TRUE + +/obj/machinery/atmospherics/components/trinary/mixer/flipped/layer1 + piping_layer = 1 + icon_state = "mixer_off_f_map-1" +/obj/machinery/atmospherics/components/trinary/mixer/flipped/layer3 + piping_layer = 3 + icon_state = "mixer_off_f_map-3" + +/obj/machinery/atmospherics/components/trinary/mixer/flipped/on + on = TRUE + icon_state = "mixer_on_f" + +/obj/machinery/atmospherics/components/trinary/mixer/flipped/on/layer1 + piping_layer = 1 + icon_state = "mixer_on_f_map-1" +/obj/machinery/atmospherics/components/trinary/mixer/flipped/on/layer3 + piping_layer = 3 + icon_state = "mixer_on_f_map-3" + +/obj/machinery/atmospherics/components/trinary/mixer/airmix //For standard airmix to distro + name = "air mixer" + icon_state = "mixer_on" + node1_concentration = N2STANDARD + node2_concentration = O2STANDARD + target_pressure = MAX_OUTPUT_PRESSURE + on = TRUE + +/obj/machinery/atmospherics/components/trinary/mixer/airmix/inverse + node1_concentration = O2STANDARD + node2_concentration = N2STANDARD + +/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped + icon_state = "mixer_on_f" + flipped = TRUE + +/obj/machinery/atmospherics/components/trinary/mixer/airmix/flipped/inverse + node1_concentration = O2STANDARD + node2_concentration = N2STANDARD \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 4e91ee50c3..539b5ce57a 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -57,6 +57,11 @@ heat_capacity = initial(heat_capacity) / C conduction_coefficient = initial(conduction_coefficient) * C +/obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user) //this is leaving out everything but efficiency since they follow the same idea of "better matter bin, better results" + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Efficiency at [efficiency*100]%." + /obj/machinery/atmospherics/components/unary/cryo_cell/Destroy() QDEL_NULL(radio) QDEL_NULL(beaker) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm b/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm index 66f9668bbf..a856ea1f3f 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm @@ -1,11 +1,12 @@ /obj/machinery/atmospherics/components/unary/heat_exchanger - icon_state = "he_intact" + icon_state = "he1" name = "heat exchanger" desc = "Exchanges heat between two input gases. Set up for fast heat transfer." can_unwrench = TRUE + shift_underlay_only = FALSE // not really used layer = LOW_OBJ_LAYER @@ -13,24 +14,23 @@ var/update_cycle pipe_state = "heunary" - + /obj/machinery/atmospherics/components/unary/heat_exchanger/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y + piping_layer = 1 + icon_state = "he_map-1" /obj/machinery/atmospherics/components/unary/heat_exchanger/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y + piping_layer = 3 + icon_state = "he_map-3" /obj/machinery/atmospherics/components/unary/heat_exchanger/update_icon() if(nodes[1]) - icon_state = "he_intact" + icon_state = "he1" var/obj/machinery/atmospherics/node = nodes[1] add_atom_colour(node.color, FIXED_COLOUR_PRIORITY) else - icon_state = "he_exposed" + icon_state = "he0" + PIPING_LAYER_SHIFT(src, piping_layer) /obj/machinery/atmospherics/components/unary/heat_exchanger/atmosinit() if(!partner) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index b4c37a2140..87ab4fa643 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -1,9 +1,10 @@ /obj/machinery/atmospherics/components/unary/outlet_injector + icon_state = "inje_map-2" name = "air injector" desc = "Has a valve and pump attached to it." - icon_state = "inje_map" use_power = IDLE_POWER_USE can_unwrench = TRUE + shift_underlay_only = FALSE resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF //really helpful in building gas chambers for xenomorphs var/injecting = 0 @@ -19,82 +20,20 @@ pipe_state = "injector" -/obj/machinery/atmospherics/components/unary/outlet_injector/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/outlet_injector/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/components/unary/outlet_injector/Destroy() SSradio.remove_object(src,frequency) return ..() -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos - frequency = FREQ_ATMOS_STORAGE - on = TRUE - volume_rate = 200 - -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/atmos_waste - name = "atmos waste outlet injector" - id = ATMOS_GAS_MONITOR_WASTE_ATMOS -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/engine_waste - name = "engine outlet injector" - id = ATMOS_GAS_MONITOR_WASTE_ENGINE -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/toxin_input - name = "plasma tank input injector" - id = ATMOS_GAS_MONITOR_INPUT_TOX -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/oxygen_input - name = "oxygen tank input injector" - id = ATMOS_GAS_MONITOR_INPUT_O2 -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/nitrogen_input - name = "nitrogen tank input injector" - id = ATMOS_GAS_MONITOR_INPUT_N2 -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/mix_input - name = "mix tank input injector" - id = ATMOS_GAS_MONITOR_INPUT_MIX -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/nitrous_input - name = "nitrous oxide tank input injector" - id = ATMOS_GAS_MONITOR_INPUT_N2O -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/air_input - name = "air mix tank input injector" - id = ATMOS_GAS_MONITOR_INPUT_AIR -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/carbon_input - name = "carbon dioxide tank input injector" - id = ATMOS_GAS_MONITOR_INPUT_CO2 -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/incinerator_input - name = "incinerator chamber input injector" - id = ATMOS_GAS_MONITOR_INPUT_INCINERATOR -/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/toxins_mixing_input - name = "toxins mixing input injector" - id = ATMOS_GAS_MONITOR_INPUT_TOXINS_LAB - -/obj/machinery/atmospherics/components/unary/outlet_injector/on - on = TRUE - -/obj/machinery/atmospherics/components/unary/outlet_injector/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/outlet_injector/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/components/unary/outlet_injector/update_icon_nopipes() cut_overlays() if(showpipe) + // everything is already shifted so don't shift the cap add_overlay(getpipeimage(icon, "inje_cap", initialize_directions)) if(!nodes[1] || !on || !is_operational()) icon_state = "inje_off" - return - - icon_state = "inje_on" + else + icon_state = "inje_on" /obj/machinery/atmospherics/components/unary/outlet_injector/power_change() var/old_stat = stat @@ -243,3 +182,63 @@ if(. && on && is_operational()) to_chat(user, "You cannot unwrench [src], turn it off first!") return FALSE + +// mapping + +/obj/machinery/atmospherics/components/unary/outlet_injector/layer1 + piping_layer = 1 + icon_state = "inje_map-1" + +/obj/machinery/atmospherics/components/unary/outlet_injector/layer3 + piping_layer = 2 + icon_state = "inje_map-2" + +/obj/machinery/atmospherics/components/unary/outlet_injector/on + on = TRUE + +/obj/machinery/atmospherics/components/unary/outlet_injector/on/layer1 + piping_layer = 1 + icon_state = "inje_map-1" + +/obj/machinery/atmospherics/components/unary/outlet_injector/on/layer3 + piping_layer = 2 + icon_state = "inje_map-2" + +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos + frequency = FREQ_ATMOS_STORAGE + on = TRUE + volume_rate = 200 + +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/atmos_waste + name = "atmos waste outlet injector" + id = ATMOS_GAS_MONITOR_WASTE_ATMOS +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/engine_waste + name = "engine outlet injector" + id = ATMOS_GAS_MONITOR_WASTE_ENGINE +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/toxin_input + name = "plasma tank input injector" + id = ATMOS_GAS_MONITOR_INPUT_TOX +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/oxygen_input + name = "oxygen tank input injector" + id = ATMOS_GAS_MONITOR_INPUT_O2 +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/nitrogen_input + name = "nitrogen tank input injector" + id = ATMOS_GAS_MONITOR_INPUT_N2 +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/mix_input + name = "mix tank input injector" + id = ATMOS_GAS_MONITOR_INPUT_MIX +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/nitrous_input + name = "nitrous oxide tank input injector" + id = ATMOS_GAS_MONITOR_INPUT_N2O +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/air_input + name = "air mix tank input injector" + id = ATMOS_GAS_MONITOR_INPUT_AIR +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/carbon_input + name = "carbon dioxide tank input injector" + id = ATMOS_GAS_MONITOR_INPUT_CO2 +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/incinerator_input + name = "incinerator chamber input injector" + id = ATMOS_GAS_MONITOR_INPUT_INCINERATOR +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/toxins_mixing_input + name = "toxins mixing input injector" + id = ATMOS_GAS_MONITOR_INPUT_TOXINS_LAB \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm index 94d8959987..a113484d20 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm @@ -13,43 +13,51 @@ /obj/machinery/atmospherics/components/unary/passive_vent/update_icon_nopipes() cut_overlays() if(showpipe) - var/image/cap = getpipeimage(icon, "vent_cap", initialize_directions) + var/image/cap = getpipeimage(icon, "vent_cap", initialize_directions, piping_layer = piping_layer) add_overlay(cap) icon_state = "passive_vent" /obj/machinery/atmospherics/components/unary/passive_vent/process_atmos() ..() - var/datum/gas_mixture/environment = loc.return_air() - var/environment_pressure = environment.return_pressure() - var/pressure_delta = abs(environment_pressure - airs[1].return_pressure()) + var/active = FALSE - if((environment.temperature || airs[1].temperature) && pressure_delta > 0.5) - if(environment_pressure < airs[1].return_pressure()) - var/air_temperature = (environment.temperature > 0) ? environment.temperature : airs[1].temperature - var/transfer_moles = (pressure_delta * environment.volume) / (air_temperature * R_IDEAL_GAS_EQUATION) - var/datum/gas_mixture/removed = airs[1].remove(transfer_moles) - loc.assume_air(removed) - air_update_turf() + var/datum/gas_mixture/external = loc.return_air() + var/datum/gas_mixture/internal = airs[1] + var/external_pressure = external.return_pressure() + var/internal_pressure = internal.return_pressure() + var/pressure_delta = abs(external_pressure - internal_pressure) + + if(pressure_delta > 0.5) + if(external_pressure < internal_pressure) + var/air_temperature = (external.temperature > 0) ? external.temperature : internal.temperature + var/transfer_moles = (pressure_delta * external.volume) / (air_temperature * R_IDEAL_GAS_EQUATION) + var/datum/gas_mixture/removed = internal.remove(transfer_moles) + external.merge(removed) else - var/air_temperature = (airs[1].temperature > 0) ? airs[1].temperature : environment.temperature - var/output_volume = airs[1].volume - var/transfer_moles = (pressure_delta * output_volume) / (air_temperature * R_IDEAL_GAS_EQUATION) - transfer_moles = min(transfer_moles, environment.total_moles()*airs[1].volume/environment.volume) - var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) + var/air_temperature = (internal.temperature > 0) ? internal.temperature : external.temperature + var/transfer_moles = (pressure_delta * internal.volume) / (air_temperature * R_IDEAL_GAS_EQUATION) + transfer_moles = min(transfer_moles, external.total_moles() * internal.volume / external.volume) + var/datum/gas_mixture/removed = external.remove(transfer_moles) if(isnull(removed)) return - airs[1].merge(removed) - air_update_turf() - update_parents() + internal.merge(removed) + + active = TRUE + + active = internal.temperature_share(external, OPEN_HEAT_TRANSFER_COEFFICIENT) ? TRUE : active + + if(active) + air_update_turf() + update_parents() /obj/machinery/atmospherics/components/unary/passive_vent/can_crawl_through() return TRUE /obj/machinery/atmospherics/components/unary/passive_vent/layer1 - piping_layer = PIPING_LAYER_MIN + piping_layer = 1 icon_state = "passive_vent_map-1" /obj/machinery/atmospherics/components/unary/passive_vent/layer3 - piping_layer = PIPING_LAYER_MAX + piping_layer = 3 icon_state = "passive_vent_map-3" diff --git a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm index c0e69a0c7d..81ca14a828 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm @@ -1,25 +1,16 @@ /obj/machinery/atmospherics/components/unary/portables_connector + icon_state = "connector_map-2" name = "connector port" desc = "For connecting portables devices related to atmospherics control." icon = 'icons/obj/atmospherics/components/unary_devices.dmi' - icon_state = "connector_map" //Only for mapping purposes, so mappers can see direction can_unwrench = TRUE - var/obj/machinery/portable_atmospherics/connected_device use_power = NO_POWER_USE level = 0 layer = GAS_FILTER_LAYER pipe_flags = PIPING_ONE_PER_TURF pipe_state = "connector" - -/obj/machinery/atmospherics/components/unary/portables_connector/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y -/obj/machinery/atmospherics/components/unary/portables_connector/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y + var/obj/machinery/portable_atmospherics/connected_device /obj/machinery/atmospherics/components/unary/portables_connector/New() ..() @@ -27,29 +18,22 @@ air_contents.volume = 0 -/obj/machinery/atmospherics/components/unary/portables_connector/visible - level = 2 - -/obj/machinery/atmospherics/components/unary/portables_connector/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/portables_connector/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/portables_connector/process_atmos() - if(!connected_device) - return - update_parents() - /obj/machinery/atmospherics/components/unary/portables_connector/Destroy() if(connected_device) connected_device.disconnect() return ..() +/obj/machinery/atmospherics/components/unary/portables_connector/update_icon_nopipes() + icon_state = "connector" + if(showpipe) + var/image/cap = getpipeimage(icon, "connector_cap", initialize_directions, piping_layer = piping_layer) + add_overlay(cap) + +/obj/machinery/atmospherics/components/unary/portables_connector/process_atmos() + if(!connected_device) + return + update_parents() + /obj/machinery/atmospherics/components/unary/portables_connector/can_unwrench(mob/user) . = ..() if(. && connected_device) @@ -60,3 +44,24 @@ return connected_device.portableConnectorReturnAir() /obj/proc/portableConnectorReturnAir() + return + + +/obj/machinery/atmospherics/components/unary/portables_connector/layer1 + piping_layer = 1 + icon_state = "connector_map-1" + +/obj/machinery/atmospherics/components/unary/portables_connector/layer3 + piping_layer = 3 + icon_state = "connector_map-3" + +/obj/machinery/atmospherics/components/unary/portables_connector/visible + level = 2 + +/obj/machinery/atmospherics/components/unary/portables_connector/visible/layer1 + piping_layer = 1 + icon_state = "connector_map-1" + +/obj/machinery/atmospherics/components/unary/portables_connector/visible/layer3 + piping_layer = 3 + icon_state = "connector_map-3" \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm b/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm index 9da9e49e01..4b6a4a4c10 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/relief_valve.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/atmospherics/components/relief_valve.dmi' icon_state = "relief_valve-e-map" can_unwrench = TRUE + interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE var/opened = FALSE var/open_pressure = ONE_ATMOSPHERE * 3 var/close_pressure = ONE_ATMOSPHERE diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm index 4dd2216b19..c1bd59f49b 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm @@ -5,11 +5,11 @@ name = "pressure tank" desc = "A large vessel containing pressurized gas." max_integrity = 800 - var/volume = 10000 //in liters, 1 meters by 1 meters by 2 meters density = TRUE - var/gas_type = 0 layer = ABOVE_WINDOW_LAYER pipe_flags = PIPING_ONE_PER_TURF + var/volume = 10000 //in liters + var/gas_type = 0 /obj/machinery/atmospherics/components/unary/tank/New() ..() @@ -20,6 +20,16 @@ air_contents.gases[gas_type] = AIR_CONTENTS name = "[name] ([GLOB.meta_gas_names[gas_type]])" +/obj/machinery/atmospherics/components/unary/tank/air + icon_state = "grey" + name = "pressure tank (Air)" + +/obj/machinery/atmospherics/components/unary/tank/air/New() + ..() + var/datum/gas_mixture/air_contents = airs[1] + air_contents.gases[/datum/gas/oxygen] = AIR_CONTENTS * 0.2 + air_contents.gases[/datum/gas/nitrogen] = AIR_CONTENTS * 0.8 + /obj/machinery/atmospherics/components/unary/tank/carbon_dioxide gas_type = /datum/gas/carbon_dioxide @@ -27,7 +37,6 @@ icon_state = "orange" gas_type = /datum/gas/plasma - /obj/machinery/atmospherics/components/unary/tank/oxygen icon_state = "blue" gas_type = /datum/gas/oxygen @@ -40,12 +49,3 @@ icon_state = "red_white" gas_type = /datum/gas/nitrous_oxide -/obj/machinery/atmospherics/components/unary/tank/air - icon_state = "grey" - name = "pressure tank (Air)" - -/obj/machinery/atmospherics/components/unary/tank/air/New() - ..() - var/datum/gas_mixture/air_contents = airs[1] - air_contents.gases[/datum/gas/oxygen] = AIR_CONTENTS * 0.2 - air_contents.gases[/datum/gas/nitrogen] = AIR_CONTENTS * 0.8 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 2e06e68709..877826c1c1 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -10,8 +10,10 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30) layer = OBJ_LAYER circuit = /obj/item/circuitboard/machine/thermomachine + ui_x = 300 + ui_y = 230 - pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY + pipe_flags = PIPING_ONE_PER_TURF var/icon_state_off = "freezer" var/icon_state_on = "freezer_1" @@ -28,7 +30,10 @@ initialize_directions = dir /obj/machinery/atmospherics/components/unary/thermomachine/on_construction() - ..(dir,dir) + var/obj/item/circuitboard/machine/thermomachine/board = circuit + if(board) + piping_layer = board.pipe_layer + ..(dir, piping_layer) /obj/machinery/atmospherics/components/unary/thermomachine/RefreshParts() var/B @@ -37,6 +42,8 @@ heat_capacity = 5000 * ((B - 1) ** 2) /obj/machinery/atmospherics/components/unary/thermomachine/update_icon() + cut_overlays() + if(panel_open) icon_state = icon_state_open else if(on && is_operational()) @@ -44,6 +51,8 @@ else icon_state = icon_state_off + add_overlay(getpipeimage(icon, "pipe", dir, , piping_layer)) + /obj/machinery/atmospherics/components/unary/thermomachine/update_icon_nopipes() cut_overlays() if(showpipe) @@ -119,7 +128,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "thermomachine", name, 400, 240, master_ui, state) + ui = new(user, src, ui_key, "thermomachine", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/atmospherics/components/unary/thermomachine/ui_data(mob/user) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index 75f2a60f80..f2f2329661 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -6,9 +6,9 @@ #define RELEASING 1 /obj/machinery/atmospherics/components/unary/vent_pump + icon_state = "vent_map-2" name = "air vent" desc = "Has a valve and pump attached to it." - icon_state = "vent_map" use_power = IDLE_POWER_USE can_unwrench = TRUE welded = FALSE @@ -32,99 +32,13 @@ pipe_state = "uvent" -/obj/machinery/atmospherics/components/unary/vent_pump/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/on - on = TRUE - icon_state = "vent_map_on" - -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/siphon - pump_direction = SIPHONING - pressure_checks = INT_BOUND - internal_pressure_bound = 4000 - external_pressure_bound = 0 - -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on - on = TRUE - icon_state = "vent_map_siphon_on" - -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos - frequency = FREQ_ATMOS_STORAGE - on = TRUE - icon_state = "vent_map_siphon_on" - -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/toxin_output - name = "plasma tank output inlet" - id_tag = ATMOS_GAS_MONITOR_OUTPUT_TOX -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/oxygen_output - name = "oxygen tank output inlet" - id_tag = ATMOS_GAS_MONITOR_OUTPUT_O2 -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/nitrogen_output - name = "nitrogen tank output inlet" - id_tag = ATMOS_GAS_MONITOR_OUTPUT_N2 -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/mix_output - name = "mix tank output inlet" - id_tag = ATMOS_GAS_MONITOR_OUTPUT_MIX -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/nitrous_output - name = "nitrous oxide tank output inlet" - id_tag = ATMOS_GAS_MONITOR_OUTPUT_N2O -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/carbon_output - name = "carbon dioxide tank output inlet" - id_tag = ATMOS_GAS_MONITOR_OUTPUT_CO2 -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/incinerator_output - name = "incinerator chamber output inlet" - id_tag = ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR - frequency = FREQ_ATMOS_CONTROL -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/toxins_mixing_output - name = "toxins mixing output inlet" - id_tag = ATMOS_GAS_MONITOR_OUTPUT_TOXINS_LAB - frequency = FREQ_ATMOS_CONTROL - /obj/machinery/atmospherics/components/unary/vent_pump/New() ..() if(!id_tag) id_tag = assign_uid_vents() /obj/machinery/atmospherics/components/unary/vent_pump/Destroy() - var/area/A = get_area(src) + var/area/A = get_base_area(src) if (A) A.air_vent_names -= id_tag A.air_vent_info -= id_tag @@ -133,82 +47,11 @@ radio_connection = null return ..() -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume - name = "large air vent" - power_channel = EQUIP - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/on - on = TRUE - icon_state = "vent_map_on" - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon - pump_direction = SIPHONING - pressure_checks = INT_BOUND - internal_pressure_bound = 2000 - external_pressure_bound = 0 - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/on - on = TRUE - icon_state = "vent_map_siphon_on" - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/atmos - frequency = FREQ_ATMOS_STORAGE - on = TRUE - icon_state = "vent_map_siphon_on" - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/atmos/air_output - name = "air mix tank output inlet" - id_tag = ATMOS_GAS_MONITOR_OUTPUT_AIR - -/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/New() - ..() - var/datum/gas_mixture/air_contents = airs[1] - air_contents.volume = 1000 - /obj/machinery/atmospherics/components/unary/vent_pump/update_icon_nopipes() cut_overlays() if(showpipe) - add_overlay(getpipeimage(icon, "vent_cap", initialize_directions)) + var/image/cap = getpipeimage(icon, "vent_cap", initialize_directions, piping_layer = piping_layer) + add_overlay(cap) if(welded) icon_state = "vent_welded" @@ -312,7 +155,7 @@ "sigtype" = "status" )) - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(!A.air_vent_names[id_tag]) name = "\improper [A.name] vent pump #[A.air_vent_names.len + 1]" A.air_vent_names[id_tag] = name @@ -445,6 +288,149 @@ pipe_vision_img.plane = ABOVE_HUD_PLANE playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1) +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume + name = "large air vent" + power_channel = EQUIP + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/New() + ..() + var/datum/gas_mixture/air_contents = airs[1] + air_contents.volume = 1000 + +// mapping + +/obj/machinery/atmospherics/components/unary/vent_pump/layer1 + piping_layer = 1 + icon_state = "vent_map-1" + +/obj/machinery/atmospherics/components/unary/vent_pump/layer3 + piping_layer = 3 + icon_state = "vent_map-3" + +/obj/machinery/atmospherics/components/unary/vent_pump/on + on = TRUE + icon_state = "vent_map_on-2" + +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer1 + piping_layer = 1 + icon_state = "vent_map_on-1" + +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3 + piping_layer = 3 + icon_state = "vent_map_on-3" + +/obj/machinery/atmospherics/components/unary/vent_pump/siphon + pump_direction = SIPHONING + pressure_checks = INT_BOUND + internal_pressure_bound = 4000 + external_pressure_bound = 0 + +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/layer1 + piping_layer = 1 + icon_state = "vent_map-1" + +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/layer3 + piping_layer = 3 + icon_state = "vent_map-3" + +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on + on = TRUE + icon_state = "vent_map_siphon_on-2" + +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on/layer1 + piping_layer = 1 + icon_state = "vent_map_siphon_on-1" + +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on/layer3 + piping_layer = 3 + icon_state = "vent_map_siphon_on-3" + +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos + frequency = FREQ_ATMOS_STORAGE + on = TRUE + icon_state = "vent_map_siphon_on-2" + +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/toxin_output + name = "plasma tank output inlet" + id_tag = ATMOS_GAS_MONITOR_OUTPUT_TOX +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/oxygen_output + name = "oxygen tank output inlet" + id_tag = ATMOS_GAS_MONITOR_OUTPUT_O2 +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/nitrogen_output + name = "nitrogen tank output inlet" + id_tag = ATMOS_GAS_MONITOR_OUTPUT_N2 +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/mix_output + name = "mix tank output inlet" + id_tag = ATMOS_GAS_MONITOR_OUTPUT_MIX +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/nitrous_output + name = "nitrous oxide tank output inlet" + id_tag = ATMOS_GAS_MONITOR_OUTPUT_N2O +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/carbon_output + name = "carbon dioxide tank output inlet" + id_tag = ATMOS_GAS_MONITOR_OUTPUT_CO2 +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/incinerator_output + name = "incinerator chamber output inlet" + id_tag = ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR + frequency = FREQ_ATMOS_CONTROL +/obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/toxins_mixing_output + name = "toxins mixing output inlet" + id_tag = ATMOS_GAS_MONITOR_OUTPUT_TOXINS_LAB + frequency = FREQ_ATMOS_CONTROL + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/layer1 + piping_layer = 1 + icon_state = "vent_map-1" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/layer3 + piping_layer = 3 + icon_state = "map_vent-3" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/on + on = TRUE + icon_state = "vent_map_on-2" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/on/layer1 + piping_layer = 1 + icon_state = "vent_map_on-1" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/on/layer3 + piping_layer = 3 + icon_state = "map_vent_on-3" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon + pump_direction = SIPHONING + pressure_checks = INT_BOUND + internal_pressure_bound = 2000 + external_pressure_bound = 0 + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/layer1 + piping_layer = 1 + icon_state = "vent_map-1" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/layer3 + piping_layer = 3 + icon_state = "map_vent-3" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/on + on = TRUE + icon_state = "vent_map_siphon_on-2" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/on/layer1 + piping_layer = 1 + icon_state = "vent_map_siphon_on-1" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/on/layer3 + piping_layer = 3 + icon_state = "vent_map_siphon_on-3" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/atmos + frequency = FREQ_ATMOS_STORAGE + on = TRUE + icon_state = "vent_map_siphon_on-2" + +/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/atmos/air_output + name = "air mix tank output inlet" + id_tag = ATMOS_GAS_MONITOR_OUTPUT_AIR #undef INT_BOUND #undef EXT_BOUND diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 9c3d07c96a..10eac9c717 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -2,9 +2,9 @@ #define SCRUBBING 1 /obj/machinery/atmospherics/components/unary/vent_scrubber + icon_state = "scrub_map-2" name = "air scrubber" desc = "Has a valve and pump attached to it." - icon_state = "scrub_map" use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 60 @@ -28,16 +28,6 @@ pipe_state = "scrubber" -/obj/machinery/atmospherics/components/unary/vent_scrubber/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_scrubber/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/components/unary/vent_scrubber/New() ..() if(!id_tag) @@ -48,22 +38,8 @@ filter_types -= f filter_types += gas_id2path(f) -/obj/machinery/atmospherics/components/unary/vent_scrubber/on - on = TRUE - icon_state = "scrub_map_on" - -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy() - var/area/A = get_area(src) + var/area/A = get_base_area(src) if (A) A.air_scrub_names -= id_tag A.air_scrub_info -= id_tag @@ -92,7 +68,8 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes() cut_overlays() if(showpipe) - add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions)) + var/image/cap = getpipeimage(icon, "scrub_cap", initialize_directions, piping_layer = piping_layer) + add_overlay(cap) if(welded) icon_state = "scrub_welded" @@ -135,7 +112,7 @@ "sigtype" = "status" )) - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(!A.air_scrub_names[id_tag]) name = "\improper [A.name] air scrubber #[A.air_scrub_names.len + 1]" A.air_scrub_names[id_tag] = name @@ -322,7 +299,25 @@ pipe_vision_img.plane = ABOVE_HUD_PLANE playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1) +/obj/machinery/atmospherics/components/unary/vent_scrubber/layer1 + piping_layer = 1 + icon_state = "scrub_map-1" +/obj/machinery/atmospherics/components/unary/vent_scrubber/layer3 + piping_layer = 3 + icon_state = "scrub_map-3" + +/obj/machinery/atmospherics/components/unary/vent_scrubber/on + on = TRUE + icon_state = "scrub_map_on-2" + +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1 + piping_layer = 1 + icon_state = "scrub_map_on-1" + +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3 + piping_layer = 3 + icon_state = "scrub_map_on-3" #undef SIPHONING #undef SCRUBBING diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index eb7d9534c1..fab70cc168 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -50,10 +50,9 @@ target = candidate setAttachLayer(candidate.piping_layer) -/obj/machinery/meter/proc/setAttachLayer(var/new_layer) +/obj/machinery/meter/proc/setAttachLayer(new_layer) target_layer = new_layer - pixel_x = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X - pixel_y = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y + PIPING_LAYER_DOUBLE_SHIFT(src, target_layer) /obj/machinery/meter/process_atmos() if(!(target?.flags_1 & INITIALIZED_1)) diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm index b087859a47..4da053d3c8 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm @@ -1,5 +1,4 @@ /obj/machinery/atmospherics/pipe/heat_exchanging - icon = 'icons/obj/atmospherics/pipes/heat.dmi' level = 2 var/minimum_temperature_difference = 20 var/thermal_conductivity = WINDOW_HEAT_TRANSFER_COEFFICIENT diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm index 606693ddda..695cb61f51 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm @@ -1,6 +1,6 @@ /obj/machinery/atmospherics/pipe/heat_exchanging/junction - icon = 'icons/obj/atmospherics/pipes/junction.dmi' - icon_state = "intact" + icon = 'icons/obj/atmospherics/pipes/he-junction.dmi' + icon_state = "pipe11-2" name = "junction" desc = "A one meter junction that connects regular and heat-exchanging pipe." @@ -15,21 +15,11 @@ construction_type = /obj/item/pipe/directional pipe_state = "junction" -/obj/machinery/atmospherics/pipe/heat_exchanging/junction/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/heat_exchanging/junction/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/pipe/heat_exchanging/junction/SetInitDirections() switch(dir) - if(NORTH,SOUTH) + if(NORTH, SOUTH) initialize_directions = SOUTH|NORTH - if(EAST,WEST) + if(EAST, WEST) initialize_directions = WEST|EAST /obj/machinery/atmospherics/pipe/heat_exchanging/junction/getNodeConnects() @@ -37,5 +27,19 @@ /obj/machinery/atmospherics/pipe/heat_exchanging/junction/isConnectable(obj/machinery/atmospherics/target, given_layer, he_type_check) if(dir == get_dir(target, src)) - return ..(target, given_layer, FALSE) //we want a normal pipe instead + return ..(target, given_layer, FALSE) //we want a normal pipe instead return ..(target, given_layer, TRUE) + +/obj/machinery/atmospherics/pipe/heat_exchanging/junction/update_icon() + icon_state = "pipe[nodes[1] ? "1" : "0"][nodes[2] ? "1" : "0"]-[piping_layer]" + update_layer() + update_alpha() + + +/obj/machinery/atmospherics/pipe/heat_exchanging/junction/layer1 + piping_layer = 1 + icon_state = "pipe11-1" + +/obj/machinery/atmospherics/pipe/heat_exchanging/junction/layer3 + piping_layer = 3 + icon_state = "pipe11-3" \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm index 6689905cf7..ce4aba6ab7 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm @@ -1,6 +1,7 @@ -//3-way manifold +//3-Way Manifold /obj/machinery/atmospherics/pipe/heat_exchanging/manifold - icon_state = "manifold" + icon = 'icons/obj/atmospherics/pipes/he-manifold.dmi' + icon_state = "manifold-2" name = "pipe manifold" desc = "A manifold composed of regular pipes." @@ -13,74 +14,34 @@ construction_type = /obj/item/pipe/trinary pipe_state = "he_manifold" -/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y + var/mutable_appearance/center -/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/Initialize() + icon_state = "" + center = mutable_appearance(icon, "manifold_center") + return ..() /obj/machinery/atmospherics/pipe/heat_exchanging/manifold/SetInitDirections() - switch(dir) - if(NORTH) - initialize_directions = EAST|SOUTH|WEST - if(SOUTH) - initialize_directions = WEST|NORTH|EAST - if(EAST) - initialize_directions = SOUTH|WEST|NORTH - if(WEST) - initialize_directions = NORTH|EAST|SOUTH + initialize_directions = NORTH|SOUTH|EAST|WEST + initialize_directions &= ~dir /obj/machinery/atmospherics/pipe/heat_exchanging/manifold/update_icon() - var/invis = invisibility ? "-f" : "" - - icon_state = "manifold_center[invis]" - cut_overlays() + PIPING_LAYER_DOUBLE_SHIFT(center, piping_layer) + add_overlay(center) //Add non-broken pieces for(var/i in 1 to device_type) if(nodes[i]) - add_overlay(getpipeimage('icons/obj/atmospherics/pipes/heat.dmi', "manifold_intact[invis]", get_dir(src, nodes[i]))) + add_overlay( getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) ) -//4-way manifold -/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w - icon_state = "manifold4w" + update_layer() + update_alpha() - name = "4-way pipe manifold" - desc = "A manifold composed of heat-exchanging pipes." +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/layer1 + piping_layer = 1 + icon_state = "manifold-1" - initialize_directions = NORTH|SOUTH|EAST|WEST - - device_type = QUATERNARY - - construction_type = /obj/item/pipe/quaternary - pipe_state = "he_manifold4w" - -/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/SetInitDirections() - initialize_directions = initial(initialize_directions) - -/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/update_icon() - var/invis = invisibility ? "-f" : "" - - icon_state = "manifold4w_center[invis]" - - cut_overlays() - - //Add non-broken pieces - for(var/i in 1 to device_type) - if(nodes[i]) - add_overlay(getpipeimage('icons/obj/atmospherics/pipes/heat.dmi', "manifold_intact[invis]", get_dir(src, nodes[i]))) +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/layer3 + piping_layer = 3 + icon_state = "manifold-3" diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm new file mode 100644 index 0000000000..88086e44e2 --- /dev/null +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm @@ -0,0 +1,48 @@ +//4-Way Manifold + +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w + icon = 'icons/obj/atmospherics/pipes/he-manifold.dmi' + icon_state = "manifold4w-2" + + name = "4-way pipe manifold" + desc = "A manifold composed of heat-exchanging pipes." + + initialize_directions = NORTH|SOUTH|EAST|WEST + + device_type = QUATERNARY + + construction_type = /obj/item/pipe/quaternary + pipe_state = "he_manifold4w" + + var/mutable_appearance/center + +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/New() + icon_state = "" + center = mutable_appearance(icon, "manifold4w_center") + return ..() + +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/SetInitDirections() + initialize_directions = initial(initialize_directions) + +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/update_icon() + cut_overlays() + + PIPING_LAYER_DOUBLE_SHIFT(center, piping_layer) + add_overlay(center) + + //Add non-broken pieces + for(var/i in 1 to device_type) + if(nodes[i]) + add_overlay( getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) ) + + update_layer() + update_alpha() + + +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/layer1 + piping_layer = 1 + icon_state = "manifold4w-1" + +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/layer3 + piping_layer = 3 + icon_state = "manifold4w-3" diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm index ad137a227d..3397e75314 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm @@ -1,46 +1,38 @@ /obj/machinery/atmospherics/pipe/heat_exchanging/simple - icon_state = "intact" + icon = 'icons/obj/atmospherics/pipes/he-simple.dmi' + icon_state = "pipe11-2" name = "pipe" desc = "A one meter section of heat-exchanging pipe." dir = SOUTH initialize_directions = SOUTH|NORTH + pipe_flags = PIPING_CARDINAL_AUTONORMALIZE device_type = BINARY construction_type = /obj/item/pipe/binary/bendable pipe_state = "he" -/obj/machinery/atmospherics/pipe/heat_exchanging/simple/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/heat_exchanging/simple/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - /obj/machinery/atmospherics/pipe/heat_exchanging/simple/SetInitDirections() if(dir in GLOB.diagonals) initialize_directions = dir + return switch(dir) - if(NORTH,SOUTH) + if(NORTH, SOUTH) initialize_directions = SOUTH|NORTH - if(EAST,WEST) - initialize_directions = WEST|EAST - -/obj/machinery/atmospherics/pipe/heat_exchanging/simple/proc/normalize_dir() - if(dir==SOUTH) - setDir(NORTH) - else if(dir==WEST) - setDir(EAST) - -/obj/machinery/atmospherics/pipe/heat_exchanging/simple/atmosinit() - normalize_dir() - ..() + if(EAST, WEST) + initialize_directions = EAST|WEST /obj/machinery/atmospherics/pipe/heat_exchanging/simple/update_icon() - normalize_dir() - ..() + icon_state = "pipe[nodes[1] ? "1" : "0"][nodes[2] ? "1" : "0"]-[piping_layer]" + update_layer() + update_alpha() + +/obj/machinery/atmospherics/pipe/heat_exchanging/simple/layer1 + piping_layer = 1 + icon_state = "pipe11-1" + +/obj/machinery/atmospherics/pipe/heat_exchanging/simple/layer3 + piping_layer = 3 + icon_state = "pipe11-3" \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/pipes/layermanifold.dm b/code/modules/atmospherics/machinery/pipes/layermanifold.dm index acafc7436a..b98098584f 100644 --- a/code/modules/atmospherics/machinery/pipes/layermanifold.dm +++ b/code/modules/atmospherics/machinery/pipes/layermanifold.dm @@ -1,5 +1,5 @@ /obj/machinery/atmospherics/pipe/layer_manifold - name = "pipe-layer manifold" + name = "layer adaptor" icon = 'icons/obj/atmospherics/pipes/manifold.dmi' icon_state = "manifoldlayer" desc = "A special pipe to bridge pipe layers with." @@ -9,14 +9,15 @@ piping_layer = PIPING_LAYER_DEFAULT device_type = 0 volume = 260 + construction_type = /obj/item/pipe/binary + pipe_state = "manifoldlayer" var/list/front_nodes var/list/back_nodes - construction_type = /obj/item/pipe/binary - pipe_state = "layer_manifold" /obj/machinery/atmospherics/pipe/layer_manifold/Initialize() front_nodes = list() back_nodes = list() + icon_state = "manifoldlayer_center" return ..() /obj/machinery/atmospherics/pipe/layer_manifold/Destroy() @@ -36,30 +37,36 @@ return front_nodes + back_nodes + nodes /obj/machinery/atmospherics/pipe/layer_manifold/update_icon() //HEAVILY WIP FOR UPDATE ICONS!! - layer = (initial(layer) + (PIPING_LAYER_MAX * PIPING_LAYER_LCHANGE)) //This is above everything else. - var/invis = invisibility ? "-f" : "" - icon_state = "[initial(icon_state)][invis]" cut_overlays() - for(var/obj/machinery/atmospherics/A in front_nodes) - add_attached_image(A) - for(var/obj/machinery/atmospherics/A in back_nodes) - add_attached_image(A) + layer = initial(layer) + (PIPING_LAYER_MAX * PIPING_LAYER_LCHANGE) //This is above everything else. -/obj/machinery/atmospherics/pipe/layer_manifold/proc/add_attached_image(obj/machinery/atmospherics/A) - var/invis = A.invisibility ? "-f" : "" + for(var/node in front_nodes) + add_attached_images(node) + for(var/node in back_nodes) + add_attached_images(node) + + update_alpha() + +/obj/machinery/atmospherics/pipe/layer_manifold/proc/add_attached_images(obj/machinery/atmospherics/A) + if(!A) + return if(istype(A, /obj/machinery/atmospherics/pipe/layer_manifold)) - for(var/i = PIPING_LAYER_MIN, i <= PIPING_LAYER_MAX, i++) - var/image/I = getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full_layer_long[invis]", get_dir(src, A), A.pipe_color) - I.pixel_x = (i - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X - I.pixel_y = (i - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y - I.layer = layer - 0.01 - add_overlay(I) + for(var/i in PIPING_LAYER_MIN to PIPING_LAYER_MAX) + add_attached_image(get_dir(src, A), i) + return + add_attached_image(get_dir(src, A), A.piping_layer, A.pipe_color) + +/obj/machinery/atmospherics/pipe/layer_manifold/proc/add_attached_image(p_dir, p_layer, p_color = null) + var/image/I + + if(p_color) + I = getpipeimage(icon, "pipe", p_dir, p_color, piping_layer = piping_layer) else - var/image/I = getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full_layer_long[invis]", get_dir(src, A), A.pipe_color) - I.pixel_x = A.pixel_x - I.pixel_y = A.pixel_y - I.layer = layer - 0.01 - add_overlay(I) + I = getpipeimage(icon, "pipe", p_dir, piping_layer = piping_layer) + + I.layer = layer - 0.01 + PIPING_LAYER_SHIFT(I, p_layer) + add_overlay(I) /obj/machinery/atmospherics/pipe/layer_manifold/SetInitDirections() switch(dir) diff --git a/code/modules/atmospherics/machinery/pipes/manifold.dm b/code/modules/atmospherics/machinery/pipes/manifold.dm index b089ebfa0a..77452fd6fd 100644 --- a/code/modules/atmospherics/machinery/pipes/manifold.dm +++ b/code/modules/atmospherics/machinery/pipes/manifold.dm @@ -1,9 +1,8 @@ -/* -3-Way Manifold -*/ +//3-Way Manifold + /obj/machinery/atmospherics/pipe/manifold icon = 'icons/obj/atmospherics/pipes/manifold.dmi' - icon_state = "manifold" + icon_state = "manifold-2" name = "pipe manifold" desc = "A manifold composed of regular pipes." @@ -16,399 +15,25 @@ construction_type = /obj/item/pipe/trinary pipe_state = "manifold" + var/mutable_appearance/center + +/obj/machinery/atmospherics/pipe/manifold/Initialize() + icon_state = "" + center = mutable_appearance(icon, "manifold_center") + return ..() + /obj/machinery/atmospherics/pipe/manifold/SetInitDirections() - switch(dir) - if(NORTH) - initialize_directions = EAST|SOUTH|WEST - if(SOUTH) - initialize_directions = WEST|NORTH|EAST - if(EAST) - initialize_directions = SOUTH|WEST|NORTH - if(WEST) - initialize_directions = NORTH|EAST|SOUTH + initialize_directions = NORTH|SOUTH|EAST|WEST + initialize_directions &= ~dir /obj/machinery/atmospherics/pipe/manifold/update_icon() - var/invis = invisibility ? "-f" : "" - - icon_state = "manifold_center[invis]" - cut_overlays() + PIPING_LAYER_DOUBLE_SHIFT(center, piping_layer) + add_overlay(center) //Add non-broken pieces for(var/i in 1 to device_type) if(nodes[i]) - add_overlay(getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src, nodes[i]))) - -//Colored pipes, use these for mapping -/obj/machinery/atmospherics/pipe/manifold/general - -/obj/machinery/atmospherics/pipe/manifold/general/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/general/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/general/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/general/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/general/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/general/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/scrubbers - name="scrubbers pipe" - pipe_color=rgb(255,0,0) - color=rgb(255,0,0) - -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/supply - name="air supply pipe" - pipe_color=rgb(0,0,255) - color=rgb(0,0,255) - -/obj/machinery/atmospherics/pipe/manifold/supply/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/supply/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/supply/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/supply/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/supply/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/supplymain - name="main air supply pipe" - pipe_color=rgb(130,43,255) - color=rgb(130,43,255) - -/obj/machinery/atmospherics/pipe/manifold/supplymain/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/supplymain/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/supplymain/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/supplymain/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/supplymain/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/supplymain/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/yellow - pipe_color=rgb(255,198,0) - color=rgb(255,198,0) - -/obj/machinery/atmospherics/pipe/manifold/yellow/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/yellow/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/yellow/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/yellow/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/yellow/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/yellow/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/cyan - pipe_color=rgb(0,255,249) - color=rgb(0,255,249) - -/obj/machinery/atmospherics/pipe/manifold/cyan/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/cyan/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/cyan/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/cyan/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/green - pipe_color=rgb(30,255,0) - color=rgb(30,255,0) - -/obj/machinery/atmospherics/pipe/manifold/green/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/green/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/green/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/green/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/green/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/green/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/orange - pipe_color=rgb(255,129,25) - color=rgb(255,129,25) - -/obj/machinery/atmospherics/pipe/manifold/orange/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/orange/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/orange/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/orange/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/orange/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/orange/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/purple - pipe_color=rgb(128,0,182) - color=rgb(128,0,182) - -/obj/machinery/atmospherics/pipe/manifold/purple/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/purple/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/purple/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/purple/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/purple/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/purple/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/dark - pipe_color=rgb(69,69,69) - color=rgb(69,69,69) - -/obj/machinery/atmospherics/pipe/manifold/dark/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/dark/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/dark/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/dark/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/dark/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/dark/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/violet - pipe_color=rgb(64,0,128) - color=rgb(64,0,128) - -/obj/machinery/atmospherics/pipe/manifold/violet/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/violet/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/violet/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/violet/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/violet/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/violet/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/brown - pipe_color=rgb(178,100,56) - color=rgb(178,100,56) - -/obj/machinery/atmospherics/pipe/manifold/brown/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold/brown/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/brown/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/brown/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold/brown/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold/brown/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y + add_overlay( getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) ) + update_layer() + update_alpha() \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/pipes/manifold4w.dm b/code/modules/atmospherics/machinery/pipes/manifold4w.dm index 5dc68f1609..1bcca8d5ae 100644 --- a/code/modules/atmospherics/machinery/pipes/manifold4w.dm +++ b/code/modules/atmospherics/machinery/pipes/manifold4w.dm @@ -1,9 +1,8 @@ -/* -4-way manifold -*/ +//4-Way Manifold + /obj/machinery/atmospherics/pipe/manifold4w icon = 'icons/obj/atmospherics/pipes/manifold.dmi' - icon_state = "manifold4w" + icon_state = "manifold4w-2" name = "4-way pipe manifold" desc = "A manifold composed of regular pipes." @@ -15,391 +14,24 @@ construction_type = /obj/item/pipe/quaternary pipe_state = "manifold4w" + var/mutable_appearance/center + +/obj/machinery/atmospherics/pipe/manifold4w/Initialize() + icon_state = "" + center = mutable_appearance(icon, "manifold4w_center") + return ..() + /obj/machinery/atmospherics/pipe/manifold4w/SetInitDirections() initialize_directions = initial(initialize_directions) /obj/machinery/atmospherics/pipe/manifold4w/update_icon() - var/invis = invisibility ? "-f" : "" - - icon_state = "manifold4w_center[invis]" - cut_overlays() + PIPING_LAYER_DOUBLE_SHIFT(center, piping_layer) + add_overlay(center) //Add non-broken pieces for(var/i in 1 to device_type) if(nodes[i]) - add_overlay(getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src, nodes[i]))) - -//Colored pipes, use these for mapping -/obj/machinery/atmospherics/pipe/manifold4w/general - -/obj/machinery/atmospherics/pipe/manifold4w/general/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/general/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/general/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/general/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/general/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/general/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers - name="scrubbers pipe" - pipe_color=rgb(255,0,0) - color=rgb(255,0,0) - -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/supply - name="air supply pipe" - pipe_color=rgb(0,0,255) - color=rgb(0,0,255) - -/obj/machinery/atmospherics/pipe/manifold4w/supply/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/supply/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/supply/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/supplymain - name="main air supply pipe" - pipe_color=rgb(130,43,255) - color=rgb(130,43,255) - -/obj/machinery/atmospherics/pipe/manifold4w/supplymain/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/supplymain/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/supplymain/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/supplymain/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/supplymain/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/supplymain/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/yellow - pipe_color=rgb(255,198,0) - color=rgb(255,198,0) - -/obj/machinery/atmospherics/pipe/manifold4w/yellow/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/yellow/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/yellow/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/yellow/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/yellow/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/yellow/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/cyan - pipe_color=rgb(0,255,249) - color=rgb(0,255,249) - -/obj/machinery/atmospherics/pipe/manifold4w/cyan/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/cyan/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/cyan/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/cyan/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/cyan/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/cyan/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/green - pipe_color=rgb(30,255,0) - color=rgb(30,255,0) - -/obj/machinery/atmospherics/pipe/manifold4w/green/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/green/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/green/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/green/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/green/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/green/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/orange - pipe_color=rgb(255,129,25) - color=rgb(255,129,25) - -/obj/machinery/atmospherics/pipe/manifold4w/orange/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/orange/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/orange/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/orange/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/orange/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/orange/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/purple - pipe_color=rgb(128,0,182) - color=rgb(128,0,182) - -/obj/machinery/atmospherics/pipe/manifold4w/purple/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/purple/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/purple/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/purple/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/purple/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/purple/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/dark - pipe_color=rgb(69,69,69) - color=rgb(69,69,69) - -/obj/machinery/atmospherics/pipe/manifold4w/dark/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/dark/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/dark/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/dark/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/dark/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/dark/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/violet - pipe_color=rgb(64,0,128) - color=rgb(64,0,128) - -/obj/machinery/atmospherics/pipe/manifold4w/violet/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/violet/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/violet/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/violet/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/violet/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/violet/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/brown - pipe_color=rgb(178,100,56) - color=rgb(178,100,56) - -/obj/machinery/atmospherics/pipe/manifold4w/brown/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/manifold4w/brown/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/brown/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/brown/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/manifold4w/brown/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/manifold4w/brown/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y + add_overlay( getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) ) + update_layer() + update_alpha() \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/pipes/mapping.dm b/code/modules/atmospherics/machinery/pipes/mapping.dm new file mode 100644 index 0000000000..c868d377ea --- /dev/null +++ b/code/modules/atmospherics/machinery/pipes/mapping.dm @@ -0,0 +1,65 @@ +//Colored pipes, use these for mapping + +#define HELPER_PARTIAL(Fulltype, Iconbase, Color) \ + ##Fulltype { \ + pipe_color = Color; \ + color = Color; \ + } \ + ##Fulltype/visible { \ + level = PIPE_VISIBLE_LEVEL; \ + layer = GAS_PIPE_VISIBLE_LAYER; \ + } \ + ##Fulltype/visible/layer1 { \ + piping_layer = 1; \ + icon_state = Iconbase + "-1"; \ + } \ + ##Fulltype/visible/layer3 { \ + piping_layer = 3; \ + icon_state = Iconbase + "-3"; \ + } \ + ##Fulltype/hidden { \ + level = PIPE_HIDDEN_LEVEL; \ + } \ + ##Fulltype/hidden/layer1 { \ + piping_layer = 1; \ + icon_state = Iconbase + "-1"; \ + } \ + ##Fulltype/hidden/layer3 { \ + piping_layer = 3; \ + icon_state = Iconbase + "-3"; \ + } + +#define HELPER_PARTIAL_NAMED(Fulltype, Iconbase, Name, Color) \ + HELPER_PARTIAL(Fulltype, Iconbase, Color) \ + ##Fulltype { \ + name = Name; \ + } + +#define HELPER(Type, Color) \ + HELPER_PARTIAL(/obj/machinery/atmospherics/pipe/simple/##Type, "pipe11", Color) \ + HELPER_PARTIAL(/obj/machinery/atmospherics/pipe/manifold/##Type, "manifold", Color) \ + HELPER_PARTIAL(/obj/machinery/atmospherics/pipe/manifold4w/##Type, "manifold4w", Color) + +#define HELPER_NAMED(Type, Name, Color) \ + HELPER_PARTIAL_NAMED(/obj/machinery/atmospherics/pipe/simple/##Type, "pipe11", Name, Color) \ + HELPER_PARTIAL_NAMED(/obj/machinery/atmospherics/pipe/manifold/##Type, "manifold", Name, Color) \ + HELPER_PARTIAL_NAMED(/obj/machinery/atmospherics/pipe/manifold4w/##Type, "manifold4w", Name, Color) + +HELPER(general, null) +HELPER(yellow, rgb(255, 198, 0)) +HELPER(cyan, rgb(0, 255, 249)) +HELPER(green, rgb(30, 255, 0)) +HELPER(orange, rgb(255, 129, 25)) +HELPER(purple, rgb(128, 0, 182)) +HELPER(dark, rgb(69, 69, 69)) +HELPER(brown, rgb(178, 100, 56)) +HELPER(violet, rgb(64, 0, 128)) + +HELPER_NAMED(scrubbers, "scrubbers pipe", rgb(255, 0, 0)) +HELPER_NAMED(supply, "air supply pipe", rgb(0, 0, 255)) +HELPER_NAMED(supplymain, "main air supply pipe", rgb(130, 43, 255)) + +#undef HELPER_NAMED +#undef HELPER +#undef HELPER_PARTIAL_NAMED +#undef HELPER_PARTIAL diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm index 0879b30b13..1e513b846c 100644 --- a/code/modules/atmospherics/machinery/pipes/pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/pipes.dm @@ -32,14 +32,6 @@ parent = new parent.build_pipeline(src) -/obj/machinery/atmospherics/pipe/update_icon() //overridden by manifolds - if(nodes[1] && nodes[2]) - icon_state = "intact[invisibility ? "-f" : "" ]" - else - var/have_node1 = nodes[1] ? TRUE : FALSE - var/have_node2 = nodes[2] ? TRUE : FALSE - icon_state = "exposed[have_node1][have_node2][invisibility ? "-f" : "" ]" - /obj/machinery/atmospherics/pipe/atmosinit() var/turf/T = loc // hide if turf is not intact hide(T.intact) @@ -93,6 +85,13 @@ qdel(meter) . = ..() +/obj/machinery/atmospherics/pipe/update_icon() + . = ..() + update_alpha() + +/obj/machinery/atmospherics/pipe/proc/update_alpha() + alpha = invisibility ? 64 : 255 + /obj/machinery/atmospherics/pipe/proc/update_node_icon() for(var/i in 1 to device_type) if(nodes[i]) diff --git a/code/modules/atmospherics/machinery/pipes/simple.dm b/code/modules/atmospherics/machinery/pipes/simple.dm index 7cab3c23dc..c3f62f16cb 100644 --- a/code/modules/atmospherics/machinery/pipes/simple.dm +++ b/code/modules/atmospherics/machinery/pipes/simple.dm @@ -1,11 +1,9 @@ -/* -Simple Pipe -The regular pipe you see everywhere, including bent ones. -*/ +// Simple Pipe +// The regular pipe you see everywhere, including bent ones. /obj/machinery/atmospherics/pipe/simple icon = 'icons/obj/atmospherics/pipes/simple.dmi' - icon_state = "intact" + icon_state = "pipe11-2" name = "pipe" desc = "A one meter section of regular pipe." @@ -20,385 +18,16 @@ The regular pipe you see everywhere, including bent ones. pipe_state = "simple" /obj/machinery/atmospherics/pipe/simple/SetInitDirections() - normalize_cardinal_directions() if(dir in GLOB.diagonals) initialize_directions = dir + return switch(dir) - if(NORTH,SOUTH) + if(NORTH, SOUTH) initialize_directions = SOUTH|NORTH - if(EAST,WEST) + if(EAST, WEST) initialize_directions = EAST|WEST -//Colored pipes, use these for mapping -/obj/machinery/atmospherics/pipe/simple/general - -/obj/machinery/atmospherics/pipe/simple/general/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/general/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/general/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/general/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/general/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/general/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/scrubbers - name="scrubbers pipe" - pipe_color=rgb(255,0,0) - color=rgb(255,0,0) - -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/supply - name="air supply pipe" - pipe_color=rgb(0,0,255) - color=rgb(0,0,255) - -/obj/machinery/atmospherics/pipe/simple/supply/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/supply/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/supply/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/supply/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/supplymain - name="main air supply pipe" - pipe_color=rgb(130,43,255) - color=rgb(130,43,255) - -/obj/machinery/atmospherics/pipe/simple/supplymain/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/supplymain/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/supplymain/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/supplymain/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/supplymain/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/supplymain/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/yellow - pipe_color=rgb(255,198,0) - color=rgb(255,198,0) - -/obj/machinery/atmospherics/pipe/simple/yellow/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/yellow/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/yellow/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/yellow/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/yellow/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/yellow/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/cyan - pipe_color=rgb(0,255,249) - color=rgb(0,255,249) - -/obj/machinery/atmospherics/pipe/simple/cyan/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/cyan/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/cyan/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/cyan/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/cyan/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/green - pipe_color=rgb(30,255,0) - color=rgb(30,255,0) - -/obj/machinery/atmospherics/pipe/simple/green/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/green/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/green/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/green/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/green/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/green/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/orange - pipe_color=rgb(255,129,25) - color=rgb(255,129,25) - -/obj/machinery/atmospherics/pipe/simple/orange/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/orange/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/orange/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/orange/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/orange/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/orange/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/purple - pipe_color=rgb(128,0,182) - color=rgb(128,0,182) - -/obj/machinery/atmospherics/pipe/simple/purple/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/purple/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/purple/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/purple/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/purple/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/purple/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/dark - pipe_color=rgb(69,69,69) - color=rgb(69,69,69) - -/obj/machinery/atmospherics/pipe/simple/dark/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/dark/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/dark/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/dark/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/dark/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/dark/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/violet - pipe_color=rgb(64,0,128) - color=rgb(64,0,128) - -/obj/machinery/atmospherics/pipe/simple/violet/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/violet/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/violet/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/violet/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/violet/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/violet/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/brown - pipe_color=rgb(178,100,56) - color=rgb(178,100,56) - -/obj/machinery/atmospherics/pipe/simple/brown/visible - level = PIPE_VISIBLE_LEVEL - layer = GAS_PIPE_VISIBLE_LAYER - -/obj/machinery/atmospherics/pipe/simple/brown/visible/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/brown/visible/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/brown/hidden - level = PIPE_HIDDEN_LEVEL - -/obj/machinery/atmospherics/pipe/simple/brown/hidden/layer1 - piping_layer = PIPING_LAYER_MIN - pixel_x = -PIPING_LAYER_P_X - pixel_y = -PIPING_LAYER_P_Y - -/obj/machinery/atmospherics/pipe/simple/brown/hidden/layer3 - piping_layer = PIPING_LAYER_MAX - pixel_x = PIPING_LAYER_P_X - pixel_y = PIPING_LAYER_P_Y +/obj/machinery/atmospherics/pipe/simple/update_icon() + icon_state = "pipe[nodes[1] ? "1" : "0"][nodes[2] ? "1" : "0"]-[piping_layer]" + update_layer() + update_alpha() \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index 7c517720a8..ddb907a2ad 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -84,14 +84,14 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "portable_pump", name, 420, 415, master_ui, state) + ui = new(user, src, ui_key, "portable_pump", name, 300, 315, master_ui, state) ui.open() /obj/machinery/portable_atmospherics/pump/ui_data() var/data = list() data["on"] = on - data["direction"] = direction - data["connected"] = connected_port ? 1 : 0 + data["direction"] = direction == PUMP_IN ? TRUE : FALSE + data["connected"] = connected_port ? TRUE : FALSE data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) data["target_pressure"] = round(pump.target_pressure ? pump.target_pressure : 0) data["default_pressure"] = round(PUMP_DEFAULT_PRESSURE) @@ -102,6 +102,8 @@ data["holding"] = list() data["holding"]["name"] = holding.name data["holding"]["pressure"] = round(holding.air_contents.return_pressure()) + else + data["holding"] = null return data /obj/machinery/portable_atmospherics/pump/ui_act(action, params) diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index d52f2d8356..0c902e0426 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -67,7 +67,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "portable_scrubber", name, 420, 435, master_ui, state) + ui = new(user, src, ui_key, "portable_scrubber", name, 320, 335, master_ui, state) ui.open() /obj/machinery/portable_atmospherics/scrubber/ui_data() @@ -85,6 +85,8 @@ data["holding"] = list() data["holding"]["name"] = holding.name data["holding"]["pressure"] = round(holding.air_contents.return_pressure()) + else + data["holding"] = null return data /obj/machinery/portable_atmospherics/scrubber/ui_act(action, params) diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index bd4e716357..3562350473 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -7,8 +7,6 @@ #define AMMO_DROP_LIFETIME 300 #define CTF_REQUIRED_PLAYERS 4 - - /obj/item/twohanded/ctf name = "banner" icon = 'icons/obj/items_and_weapons.dmi' @@ -210,7 +208,6 @@ toggle_all_ctf(user) return - people_who_want_to_play |= user.ckey var/num = people_who_want_to_play.len var/remaining = CTF_REQUIRED_PLAYERS - num @@ -267,6 +264,8 @@ M.key = new_team_member.key M.faction += team M.equipOutfit(ctf_gear) + M.dna.species.punchdamagehigh = 25 + M.dna.species.punchdamagelow = 25 spawned_mobs += M /obj/machinery/capture_the_flag/Topic(href, href_list) @@ -371,6 +370,10 @@ CTF.ctf_gear = initial(ctf_gear) CTF.respawn_cooldown = DEFAULT_RESPAWN +/proc/ctf_floor_vanish(atom/target) + if(isturf(target.loc)) + qdel(target) + /obj/item/gun/ballistic/automatic/pistol/deagle/ctf desc = "This looks like it could really hurt in melee." force = 75 @@ -378,11 +381,7 @@ /obj/item/gun/ballistic/automatic/pistol/deagle/ctf/dropped() . = ..() - addtimer(CALLBACK(src, .proc/floor_vanish), 1) - -/obj/item/gun/ballistic/automatic/pistol/deagle/ctf/proc/floor_vanish() - if(isturf(loc)) - qdel(src) + addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1) /obj/item/ammo_box/magazine/m50/ctf ammo_type = /obj/item/ammo_casing/a50/ctf @@ -405,22 +404,14 @@ /obj/item/gun/ballistic/automatic/laser/ctf/dropped() . = ..() - addtimer(CALLBACK(src, .proc/floor_vanish), 1) - -/obj/item/gun/ballistic/automatic/laser/ctf/proc/floor_vanish() - if(isturf(loc)) - qdel(src) + addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1) /obj/item/ammo_box/magazine/recharge/ctf ammo_type = /obj/item/ammo_casing/caseless/laser/ctf /obj/item/ammo_box/magazine/recharge/ctf/dropped() . = ..() - addtimer(CALLBACK(src, .proc/floor_vanish), 1) - -/obj/item/ammo_box/magazine/recharge/ctf/proc/floor_vanish() - if(isturf(loc)) - qdel(src) + addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1) /obj/item/ammo_casing/caseless/laser/ctf projectile_type = /obj/item/projectile/beam/ctf @@ -438,9 +429,9 @@ . = FALSE if(istype(target, /obj/structure/barricade/security/ctf)) . = TRUE - if(ishuman(target)) - var/mob/living/carbon/human/H = target - if(istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/shielded/ctf)) + if(isliving(target)) + var/mob/living/H = target + if((RED_TEAM in H.faction) || (BLUE_TEAM in H.faction)) . = TRUE // RED TEAM GUNS @@ -473,6 +464,19 @@ icon_state = "bluelaser" impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser +// MELEE GANG +/obj/item/claymore/ctf + slot_flags = SLOT_BACK + +/obj/item/claymore/ctf/pre_attack(atom/target, mob/user, params) + if(!is_ctf_target(target)) + return FALSE + return ..() + +/obj/item/claymore/ctf/dropped() + . = ..() + addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1) + /datum/outfit/ctf name = "CTF" ears = /obj/item/radio/headset @@ -486,6 +490,7 @@ l_pocket = /obj/item/ammo_box/magazine/recharge/ctf r_pocket = /obj/item/ammo_box/magazine/recharge/ctf r_hand = /obj/item/gun/ballistic/automatic/laser/ctf + back = /obj/item/claymore/ctf /datum/outfit/ctf/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source) if(visualsOnly) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 34886c5b27..7421b9e09a 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -13,7 +13,9 @@ var/death = TRUE //Kill the mob var/roundstart = TRUE //fires on initialize var/instant = FALSE //fires on New - var/flavour_text = "The mapper forgot to set this!" + var/short_desc = "The mapper forgot to set this!" + var/flavour_text = "" + var/important_info = "" var/faction = null var/permanent = FALSE //If true, the spawner will not disappear upon running out of uses. var/random = FALSE //Don't set a name or gender, just go random @@ -110,7 +112,12 @@ if(ckey) M.ckey = ckey if(show_flavour) - to_chat(M, "[flavour_text]") + var/output_message = "[short_desc]" + if(flavour_text != "") + output_message += "\n[flavour_text]" + if(important_info != "") + output_message += "\n[important_info]" + to_chat(M, output_message) var/datum/mind/MM = M.mind var/datum/antagonist/A if(antagonist_type) @@ -340,7 +347,7 @@ name = "sleeper" icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" - flavour_text = "You are a space doctor!" + short_desc = "You are a space doctor!" assignedrole = "Space Doctor" job_description = "Off-station Doctor" @@ -397,7 +404,8 @@ name = "bartender sleeper" icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" - flavour_text = "You are a space bartender! Time to mix drinks and change lives. Smoking space drugs makes it easier to understand your patrons' odd dialect." + short_desc = "You are a space bartender!" + flavour_text = "Time to mix drinks and change lives. Smoking space drugs makes it easier to understand your patrons' odd dialect." assignedrole = "Space Bartender" id_job = "Bartender" @@ -422,7 +430,8 @@ name = "beach bum sleeper" icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" - flavour_text = "You're, like, totally a dudebro, bruh. Ch'yea. You came here, like, on spring break, hopin' to pick up some bangin' hot chicks, y'knaw?" + short_desc = "You're a spunky lifeguard!" + flavour_text = "It's up to you to make sure nobody drowns or gets eaten by sharks and stuff." assignedrole = "Beach Bum" /obj/effect/mob_spawn/human/beach/alive/lifeguard @@ -511,7 +520,7 @@ name = "sleeper" icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" - flavour_text = "You are a Nanotrasen Commander!" + short_desc = "You are a Nanotrasen Commander!" /obj/effect/mob_spawn/human/nanotrasensoldier/alive death = FALSE @@ -522,7 +531,7 @@ icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" faction = "nanotrasenprivate" - flavour_text = "You are a Nanotrasen Private Security Officer!" + short_desc = "You are a Nanotrasen Private Security Officer!" /////////////////Spooky Undead////////////////////// @@ -539,7 +548,8 @@ job_description = "Skeleton" icon = 'icons/effects/blood.dmi' icon_state = "remains" - flavour_text = "By unknown powers, your skeletal remains have been reanimated! Walk this mortal plain and terrorize all living adventurers who dare cross your path." + short_desc = "By unknown powers, your skeletal remains have been reanimated!" + flavour_text = "Walk this mortal plain and terrorize all living adventurers who dare cross your path." assignedrole = "Skeleton" /obj/effect/mob_spawn/human/zombie @@ -554,7 +564,9 @@ job_description = "Zombie" icon = 'icons/effects/blood.dmi' icon_state = "remains" - flavour_text = "By unknown powers, your rotting remains have been resurrected! Walk this mortal plain and terrorize all living adventurers who dare cross your path." + short_desc = "By unknown powers, your rotting remains have been resurrected!" + flavour_text = "Walk this mortal plain and terrorize all living adventurers who dare cross your path." + /obj/effect/mob_spawn/human/abductor diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm index 85ac20ca0d..fc797d227c 100644 --- a/code/modules/awaymissions/mission_code/snowdin.dm +++ b/code/modules/awaymissions/mission_code/snowdin.dm @@ -595,8 +595,9 @@ job_description = "Syndicate Snow Operative" faction = ROLE_SYNDICATE outfit = /datum/outfit/snowsyndie - flavour_text = "You are a syndicate operative recently awoken from cryostasis in an underground outpost. Monitor Nanotrasen communications and record information. All intruders should be \ - disposed of swiftly to assure no gathered information is stolen or lost. Try not to wander too far from the outpost as the caves can be a deadly place even for a trained operative such as yourself." + short_desc = "You are a syndicate operative recently awoken from cryostasis in an underground outpost." + flavour_text = "You are a syndicate operative recently awoken from cryostasis in an underground outpost. Monitor Nanotrasen communications and record information. All intruders should be \ + disposed of swiftly to assure no gathered information is stolen or lost. Try not to wander too far from the outpost as the caves can be a deadly place even for a trained operative such as yourself." /datum/outfit/snowsyndie name = "Syndicate Snow Operative" diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm index 744fb78ba5..d4c9fdbee7 100644 --- a/code/modules/awaymissions/zlevel.dm +++ b/code/modules/awaymissions/zlevel.dm @@ -43,7 +43,7 @@ GLOBAL_LIST_INIT(potentialRandomZlevels, generateMapList(filename = "[global.con t = trim(t) if (length(t) == 0) continue - else if (copytext(t, 1, 2) == "#") + else if (t[1] == "#") continue var/pos = findtext(t, " ") diff --git a/code/modules/cargo/bounties/assistant.dm b/code/modules/cargo/bounties/assistant.dm index 9e26cd25fc..4af28d78cc 100644 --- a/code/modules/cargo/bounties/assistant.dm +++ b/code/modules/cargo/bounties/assistant.dm @@ -10,13 +10,13 @@ /datum/bounty/item/assistant/skateboard name = "Skateboard" description = "Nanotrasen has determined walking to be wasteful. Ship a skateboard to CentCom to speed operations up." - reward = 750 // the tony hawk + reward = 800 // the tony hawk wanted_types = list(/obj/vehicle/ridden/scooter/skateboard) /datum/bounty/item/assistant/stunprod name = "Stunprod" description = "CentCom demands a stunprod to use against dissidents. Craft one, then ship it." - reward = 800 + reward = 950 wanted_types = list(/obj/item/melee/baton/cattleprod) /datum/bounty/item/assistant/soap @@ -126,7 +126,7 @@ /datum/bounty/item/assistant/shadyjims name = "Shady Jim's" description = "There's an irate officer at CentCom demanding that he receive a box of Shady Jim's cigarettes. Please ship one. He's starting to make threats." - reward = 750 + reward = 1150 wanted_types = list(/obj/item/storage/fancy/cigarettes/cigpack_shadyjims) /datum/bounty/item/assistant/potted_plants @@ -148,14 +148,14 @@ reward = 1000 required_count = 5 wanted_types = list(/obj/item/restraints/handcuffs) - +/* I don't like that you can just buy a box of monkey cubes and finish this for -half- of them. /datum/bounty/item/assistant/monkey_cubes name = "Monkey Cubes" description = "Due to a recent genetics accident, Central Command is in serious need of monkeys. Your mission is to ship monkey cubes." reward = 2000 required_count = 3 wanted_types = list(/obj/item/reagent_containers/food/snacks/monkeycube) - +*/ /datum/bounty/item/assistant/chainsaw name = "Chainsaw" description = "The chef at CentCom is having trouble butchering her animals. She requests one chainsaw, please." @@ -208,15 +208,22 @@ wanted_types = list(/obj/item/shield/makeshift) /datum/bounty/item/assistant/toolbelts - name = "Tool Belts" + name = "Tool Belts" //Made it 5 so you can't just buy one set of toolbelts to finish the bounty. description = "These things always seem to go missing. Ship us a few to help us restock." reward = 1350 - required_count = 3 + required_count = 5 wanted_types = list(/obj/item/storage/belt/utility) /datum/bounty/item/assistant/gasmasks name = "Gas Masks" description = "The good news is that we have more miasma than we'll ever need. The bad news is, somone opened the release valve on the canisters. Ship us some gas masks!" - reward = 1100 + reward = 1250 required_count = 4 wanted_types = list(/obj/item/clothing/mask/gas) + +/datum/bounty/item/assistant/pneumatic_cannon + name = "Pneumatic Cannons" + description = "Have you ever launched a tennis ball, newspaper, or ***** at someones head from across the room? No? We haven't either. Help us rectify this." + reward = 2000 + required_count = 2 + wanted_types = list(/obj/item/pneumatic_cannon/ghetto) diff --git a/code/modules/cargo/bounties/botany.dm b/code/modules/cargo/bounties/botany.dm index 98d7765002..654bcfe74b 100644 --- a/code/modules/cargo/bounties/botany.dm +++ b/code/modules/cargo/bounties/botany.dm @@ -10,22 +10,23 @@ reward += multiplier * 1000 required_count = rand(5, 10) +//Easy Stuff (1200) + /datum/bounty/item/botany/ambrosia_vulgaris name = "Ambrosia Vulgaris Leaves" wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/ambrosia/vulgaris) foodtype = "stew" -/datum/bounty/item/botany/ambrosia_gaia - name = "Ambrosia Gaia Leaves" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/ambrosia/gaia) - multiplier = 4 - foodtype = "stew" +/datum/bounty/item/botany/pineapples + name = "Pineapples" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/pineapple) + bonus_desc = "Not for human consumption." + foodtype = "ashtray" -/datum/bounty/item/botany/apple_golden - name = "Golden Apples" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/apple/gold) - multiplier = 4 - foodtype = "dessert" +/datum/bounty/item/botany/tomato + name = "Tomatoes" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/tomato) + exclude_types = list(/obj/item/reagent_containers/food/snacks/grown/tomato/blue) /datum/bounty/item/botany/banana name = "Bananas" @@ -33,58 +34,9 @@ exclude_types = list(/obj/item/reagent_containers/food/snacks/grown/banana/bluespace) foodtype = "banana split" -/datum/bounty/item/botany/banana_bluespace - name = "Bluespace Bananas" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/banana/bluespace) - multiplier = 2 - foodtype = "banana split" - -/datum/bounty/item/botany/beans_koi - name = "Koi Beans" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/koibeans) - multiplier = 2 - -/datum/bounty/item/botany/berries_death - name = "Death Berries" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/berries/death) - multiplier = 2 - bonus_desc = "He insists that \"he knows what he's doing\"." - foodtype = "sorbet" - -/datum/bounty/item/botany/berries_glow - name = "Glow-Berries" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/berries/glow) - multiplier = 2 - foodtype = "sorbet" - -/datum/bounty/item/botany/cannabis - name = "Cannabis Leaves" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis) - exclude_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/white, /obj/item/reagent_containers/food/snacks/grown/cannabis/death, /obj/item/reagent_containers/food/snacks/grown/cannabis/ultimate) - multiplier = 4 //hush money - bonus_desc = "Do not mention this shipment to security." - foodtype = "\"meal\"" - -/datum/bounty/item/botany/cannabis_white - name = "Lifeweed Leaves" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/white) - multiplier = 6 - bonus_desc = "Do not mention this shipment to security." - foodtype = "\"meal\"" - -/datum/bounty/item/botany/cannabis_death - name = "Deathweed Leaves" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/death) - multiplier = 6 - bonus_desc = "Do not mention this shipment to security." - foodtype = "\"meal\"" - -/datum/bounty/item/botany/cannabis_ultimate - name = "Omega Weed Leaves" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/ultimate) - multiplier = 6 - bonus_desc = "Under no circumstances mention this shipment to security." - foodtype = "\"meal\"" +/datum/bounty/item/botany/coconuts + name = "Coconuts" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/coconut) /datum/bounty/item/botany/wheat name = "Wheat Grains" @@ -98,16 +50,6 @@ name = "Chili Peppers" wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/chili) -/datum/bounty/item/botany/chili - name = "Ice Chili Peppers" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/icepepper) - multiplier = 2 - -/datum/bounty/item/botany/chili - name = "Ghost Chili Peppers" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/ghost_chili) - multiplier = 2 - /datum/bounty/item/botany/citrus_lime name = "Limes" wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/citrus/lime) @@ -129,35 +71,85 @@ wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/eggplant) bonus_desc = "Not to be confused with egg-plants." -/datum/bounty/item/botany/eggplant_eggy - name = "Egg-plants" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/shell/eggy) - bonus_desc = "Not to be confused with eggplants." - multiplier = 2 - -// /datum/bounty/item/botany/kudzu -// name = "Kudzu Pods" -// wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/kudzupod) -// bonus_desc = "Store in a dry, dark place." -// multiplier = 4 - /datum/bounty/item/botany/watermelon name = "Watermelons" wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/watermelon) foodtype = "dessert" -/datum/bounty/item/botany/watermelon_holy - name = "Holy Melons" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/holymelon) - multiplier = 2 - foodtype = "dessert" - /datum/bounty/item/botany/glowshroom name = "Glowshrooms" wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom) exclude_types = list(/obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/glowcap, /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/shadowshroom) foodtype = "omelet" +//Medium Stuff (2400) + +/datum/bounty/item/botany/moonflower + name = "Moonflowers" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/moonflower) + multiplier = 2 + +/datum/bounty/item/botany/novaflower + name = "Novaflowers" + wanted_types = list(/obj/item/grown/novaflower) + multiplier = 2 + +/datum/bounty/item/botany/banana_bluespace + name = "Bluespace Bananas" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/banana/bluespace) + multiplier = 2 + foodtype = "banana split" + +/datum/bounty/item/botany/beans_koi + name = "Koi Beans" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/koibeans) + multiplier = 2 + +/datum/bounty/item/botany/coffee_robusta + name = "Coffee Robusta Beans" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/coffee/robusta) + multiplier = 2 + +/datum/bounty/item/botany/steelcaps + name = "Steelcap Logs" + wanted_types = list(/obj/item/grown/log/steel) + multiplier = 2 + +/datum/bounty/item/botany/berries_death + name = "Death Berries" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/berries/death) + multiplier = 2 + bonus_desc = "He insists that \"he knows what he's doing\"." + foodtype = "sorbet" + +/datum/bounty/item/botany/berries_glow + name = "Glow-Berries" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/berries/glow) + multiplier = 2 + foodtype = "sorbet" + +/datum/bounty/item/botany/chili + name = "Ice Chili Peppers" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/icepepper) + multiplier = 2 + +/datum/bounty/item/botany/chili + name = "Ghost Chili Peppers" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/ghost_chili) + multiplier = 2 + +/datum/bounty/item/botany/eggplant_eggy + name = "Egg-plants" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/shell/eggy) + bonus_desc = "Not to be confused with eggplants." + multiplier = 2 + +/datum/bounty/item/botany/watermelon_holy + name = "Holy Melons" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/holymelon) + multiplier = 2 + foodtype = "dessert" + /datum/bounty/item/botany/glowshroom_cap name = "Glowcaps" wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/glowcap) @@ -177,18 +169,62 @@ bonus_desc = "Wear protection when handling them." foodtype = "cheese" -/datum/bounty/item/botany/pineapples - name = "Pineapples" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/pineapple) - bonus_desc = "Not for human consumption." - foodtype = "ashtray" +//Harder Stuff (3600-7200) -/datum/bounty/item/botany/tomato - name = "Tomatoes" - wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/tomato) - exclude_types = list(/obj/item/reagent_containers/food/snacks/grown/tomato/blue) +// /datum/bounty/item/botany/kudzu +// name = "Kudzu Pods" +// wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/kudzupod) +// bonus_desc = "Store in a dry, dark place." +// multiplier = 4 + +/datum/bounty/item/botany/bungopit + name = "Bungo Pits" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/bungopit) + bonus_desc = "Heartbreaker." + multiplier = 4 + +/datum/bounty/item/botany/ambrosia_gaia + name = "Ambrosia Gaia Leaves" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/ambrosia/gaia) + multiplier = 4 + foodtype = "stew" + +/datum/bounty/item/botany/apple_golden + name = "Golden Apples" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/apple/gold) + multiplier = 4 + foodtype = "dessert" /datum/bounty/item/botany/tomato_bluespace name = "Bluespace Tomatoes" wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/tomato/blue/bluespace) multiplier = 4 + +/datum/bounty/item/botany/cannabis + name = "Cannabis Leaves" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis) + exclude_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/white, /obj/item/reagent_containers/food/snacks/grown/cannabis/death, /obj/item/reagent_containers/food/snacks/grown/cannabis/ultimate) + multiplier = 3 //hush money + bonus_desc = "Do not mention this shipment to security." + foodtype = "\"meal\"" + +/datum/bounty/item/botany/cannabis_white + name = "Lifeweed Leaves" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/white) + multiplier = 5 + bonus_desc = "Do not mention this shipment to security." + foodtype = "\"meal\"" + +/datum/bounty/item/botany/cannabis_death + name = "Deathweed Leaves" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/death) + multiplier = 5 + bonus_desc = "Do not mention this shipment to security." + foodtype = "\"meal\"" + +/datum/bounty/item/botany/cannabis_ultimate + name = "Omega Weed Leaves" + wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/ultimate) + multiplier = 6 + bonus_desc = "Under no circumstances mention this shipment to security." + foodtype = "\"meal\"" \ No newline at end of file diff --git a/code/modules/cargo/bounties/chef.dm b/code/modules/cargo/bounties/chef.dm index 64e1710461..7f7f0b86e2 100644 --- a/code/modules/cargo/bounties/chef.dm +++ b/code/modules/cargo/bounties/chef.dm @@ -2,16 +2,17 @@ /datum/bounty/item/chef/soup name = "Soup" - description = "To quell the homeless uprising, Nanotrasen will be serving soup to all underpaid workers. Ship any type of soup." - reward = 700 - required_count = 3 + description = "To quell the homeless uprising, Nanotrasen will be serving soup to all underpaid workers. Ship any type of soup. Do NOT ship bowls of water." + reward = 1200 + required_count = 4 wanted_types = list(/obj/item/reagent_containers/food/snacks/soup) + exclude_types = list(/obj/item/reagent_containers/food/snacks/soup/wish) /datum/bounty/item/chef/icecreamsandwich name = "Ice Cream Sandwiches" description = "Upper management has been screaming non-stop for ice cream. Please send some." - reward = 800 - required_count = 3 + reward = 1200 + required_count = 5 wanted_types = list(/obj/item/reagent_containers/food/snacks/icecreamsandwich) /datum/bounty/item/chef/bread @@ -26,6 +27,13 @@ reward = 3142 wanted_types = list(/obj/item/reagent_containers/food/snacks/pie) +/datum/bounty/item/gardencook/khinkali + name = "Khinkali" + description = "Requesting -some khinki stuff- for a private staff party at Centcom." + reward = 2400 + required_count = 6 + wanted_types = list(/obj/item/reagent_containers/food/snacks/khinkali) + /datum/bounty/item/chef/salad name = "Salad or Rice Bowls" description = "CentCom management is going on a health binge. Your order is to ship salad or rice bowls." @@ -33,18 +41,6 @@ required_count = 3 wanted_types = list(/obj/item/reagent_containers/food/snacks/salad) -/datum/bounty/item/chef/superbite - name = "Super Bite Burger" - description = "Commander Tubbs thinks he can set a competitive eating world record. All he needs is a super bite burger shipped to him." - reward = 1800 - wanted_types = list(/obj/item/reagent_containers/food/snacks/burger/superbite) - -/datum/bounty/item/chef/poppypretzel - name = "Poppy Pretzel" - description = "Central Command needs a reason to fire their HR head. Send over a poppy pretzel to force a failed drug test." - reward = 3000 - wanted_types = list(/obj/item/reagent_containers/food/snacks/poppypretzel) - // /datum/bounty/item/chef/cubancarp // name = "Cuban Carp" // description = "To celebrate the birth of Castro XXVII, ship one cuban carp to CentCom." @@ -135,3 +131,9 @@ reward = 1200 required_count = 6 wanted_types = list(/obj/item/reagent_containers/food/snacks/sugarcookie) + +/datum/bounty/item/chef/bbqribs + description = "There's a debate around command as to weather or not ribs should be considered finger food, and we need a few delicious racks to process." + reward = 2250 + required_count = 3 + wanted_types = list(/obj/item/reagent_containers/food/snacks/bbqribs) \ No newline at end of file diff --git a/code/modules/cargo/bounties/engineering.dm b/code/modules/cargo/bounties/engineering.dm index 1f16788c4d..99e6aa2bdc 100644 --- a/code/modules/cargo/bounties/engineering.dm +++ b/code/modules/cargo/bounties/engineering.dm @@ -40,14 +40,14 @@ /datum/bounty/item/engineering/microwave name = "Microwaves" description = "Due to a shortage of microwaves, our chefs are incapable of keeping up with our sheer volume of orders. We need at least three microwaves to keep up with our crew's dietary habits." - reward = 1000 + reward = 2000 required_count = 3 wanted_types = list(/obj/machinery/microwave) /datum/bounty/item/engineering/hydroponicstrays name = "Hydroponics Tray" description = "The garden has become a hot spot of late, they need a few more hydroponics tray to grow more flowers." - reward = 1500 + reward = 2500 required_count = 5 wanted_types = list(/obj/machinery/hydroponics) @@ -75,14 +75,14 @@ /datum/bounty/item/engineering/arcadetrail name = "Orion Trail Arcade Games" description = "The staff have nothing to do when off-work. Can you send us some Orion Trail games to play?" - reward = 1500 + reward = 2500 required_count = 5 wanted_types = list(/obj/machinery/computer/arcade/orion_trail) /datum/bounty/item/engineering/arcadebattle name = "Battle Arcade Games" description = "The staff have nothing to do when off-work. Can you send us some Battle Arcade games to play?" - reward = 1500 + reward = 2500 required_count = 5 wanted_types = list(/obj/machinery/computer/arcade/battle) diff --git a/code/modules/cargo/bounties/gardencook.dm b/code/modules/cargo/bounties/gardencook.dm index b73cc2f9f8..6fdd9b2a3f 100644 --- a/code/modules/cargo/bounties/gardencook.dm +++ b/code/modules/cargo/bounties/gardencook.dm @@ -1,7 +1,7 @@ /datum/bounty/item/chef/birthday_cake name = "Birthday Cake" description = "Nanotrasen's birthday is coming up! Ship them a birthday cake to celebrate!" - reward = 1000 + reward = 1800 wanted_types = list(/obj/item/reagent_containers/food/snacks/store/cake/birthday, /obj/item/reagent_containers/food/snacks/cakeslice/birthday) /datum/bounty/item/gardencook/carrotfries @@ -21,24 +21,17 @@ /datum/bounty/item/gardencook/popcorn name = "Popcorn Bags" description = "Upper management wants to host a movie night. Ship bags of popcorn for the occasion." - reward = 800 + reward = 1200 required_count = 3 wanted_types = list(/obj/item/reagent_containers/food/snacks/popcorn) /datum/bounty/item/gardencook/onionrings name = "Onion Rings" description = "Nanotrasen is remembering Saturn day. Ship onion rings to show the station's support." - reward = 800 + reward = 1200 required_count = 3 wanted_types = list(/obj/item/reagent_containers/food/snacks/onionrings) -/datum/bounty/item/gardencook/khinkali - name = "Khinkali" - description = "Requesting -some khinki stuff- for a private staff party at Centcom" - reward = 2400 - required_count = 6 - wanted_types = list(/obj/item/reagent_containers/food/snacks/khinkali) - /datum/bounty/item/gardencook/bakedbeans name = "Beans" description = "Management wants to make sure we have a fallback shelter to rely on. Prepare some beans to stock it with." @@ -51,3 +44,22 @@ description = "Something sticky, something fun, ship us a honeybun." reward = 3500 wanted_types = list(/obj/item/reagent_containers/food/snacks/honeybun) + +/datum/bounty/item/chef/superbite + name = "Super Bite Burger" //Salt, Pepper, Boiled Egg, 5 Steak, 4 Tomato, 3 Cheese, Bacon, and a Bun. Should be more than 1800. + description = "Commander Tubbs thinks he can set a competitive eating world record. All he needs is a super bite burger shipped to him." + reward = 2750 + wanted_types = list(/obj/item/reagent_containers/food/snacks/burger/superbite) + +/datum/bounty/item/chef/poppypretzel + name = "Poppy Pretzel" + description = "Central Command needs a reason to fire their HR head. Send over a poppy pretzel to force a failed drug test." + reward = 1800 + wanted_types = list(/obj/item/reagent_containers/food/snacks/poppypretzel) + +/datum/bounty/item/chef/fiestaskewer + name = "Fiesta Skewer" + description = "Apparently people are putting vegetables on kebabs now. Central Command has taken an interest in this turn of events and would like to know more." + reward = 2600 + required_count = 3 + wanted_types = list(/obj/item/reagent_containers/food/snacks/kebab/fiesta) \ No newline at end of file diff --git a/code/modules/cargo/bounties/medical.dm b/code/modules/cargo/bounties/medical.dm index 22964e1fb7..7afc0d8786 100644 --- a/code/modules/cargo/bounties/medical.dm +++ b/code/modules/cargo/bounties/medical.dm @@ -121,7 +121,7 @@ /datum/bounty/item/medical/defibrillator name = "New defibillators" - description = "After years of storge are defibrillator units have become more liabilities then we want. Please send us some new ones to replace these old ones." + description = "After years of storge our defib units have become liabilities. Please send us some new ones." reward = 2250 required_count = 5 wanted_types = list(/obj/item/defibrillator) diff --git a/code/modules/cargo/bounties/science.dm b/code/modules/cargo/bounties/science.dm index 6102d8d685..c543872565 100644 --- a/code/modules/cargo/bounties/science.dm +++ b/code/modules/cargo/bounties/science.dm @@ -25,7 +25,7 @@ /datum/bounty/item/science/nightvision_goggles name = "Night Vision Goggles" description = "An electrical storm has busted all the lights at CentCom. While management is waiting for replacements, perhaps some night vision goggles can be shipped?" - reward = 1000 + reward = 1250 wanted_types = list(/obj/item/clothing/glasses/night, /obj/item/clothing/glasses/meson/night, /obj/item/clothing/glasses/hud/health/night, /obj/item/clothing/glasses/hud/security/night, /obj/item/clothing/glasses/hud/diagnostic/night) /datum/bounty/item/science/experimental_welding_tool @@ -55,7 +55,7 @@ /datum/bounty/item/science/advanced_mop name = "Advanced Mop" - description = "Excuse me. I'd like to request $17 for a push broom rebristling. Either that, or an advanced mop." + description = "Excuse me. I'd like to request 17 credits for a push broom rebristling. Either that, or an advanced mop." reward = 3000 wanted_types = list(/obj/item/mop/advanced) @@ -108,7 +108,7 @@ wanted_types = list(/obj/item/stock_parts/micro_laser/quadultra) /datum/bounty/item/science/fakecrystals - name = "synthetic bluespace crystals" + name = "Synthetic Bluespace Crystals" description = "Don't, uh, tell anyone, but one of our BSA arrays might have had a little... accident. Send us some bluespace crystals so we can recalibrate it before anyone realizes. The whole set uses artificial bluespace crystals, so we need and not any other type of bluespace crystals..." reward = 8000 required_count = 5 diff --git a/code/modules/cargo/bounties/silly.dm b/code/modules/cargo/bounties/silly.dm index b88ec9f192..e0d2c87a2d 100644 --- a/code/modules/cargo/bounties/silly.dm +++ b/code/modules/cargo/bounties/silly.dm @@ -51,4 +51,16 @@ name = "Strange Object" description = "Nanotrasen has taken an interest in strange objects. Find one in maint, and ship it off to CentCom right away." reward = 1000 - wanted_types = list(/obj/item/relic) \ No newline at end of file + wanted_types = list(/obj/item/relic) + +/datum/bounty/item/silly/coconut_bong + name = "Coconut Bong" + description = "Duuuude, what if we like, carved out a coconut, and smoked some stuff in it. It'd be like, coconut flavored maaaaaan." + reward = 2750 + wanted_types = list(/obj/item/bong/coconut) + +/datum/bounty/item/silly/toy_swords + name = "Toy Swords" + description = "Nanotrasen has secured a contract in a reenactment of a famous movie, but we only have lethal energy based swords. Send us some convincing replicas so we save on medical costs." + reward = 1200 + required_count = 3 diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index 526062d0f7..64b208a90b 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -3,13 +3,20 @@ desc = "Used to order supplies, approve requests, and control the shuttle." icon_screen = "supply" circuit = /obj/item/circuitboard/computer/cargo - req_access = list(ACCESS_CARGO) + ui_x = 780 + ui_y = 750 + var/requestonly = FALSE var/contraband = FALSE + var/self_paid = FALSE var/safety_warning = "For safety reasons, the automated supply shuttle \ - cannot transport live organisms, human remains, classified nuclear weaponry \ - or homing beacons." + cannot transport live organisms, human remains, classified nuclear weaponry, \ + homing beacons or machinery housing any form of artificial intelligence." var/blockade_warning = "Bluespace instability detected. Shuttle movement impossible." + /// radio used by the console to send messages on supply channel + var/obj/item/radio/headset/radio + /// var that tracks message cooldown + var/message_cooldown light_color = "#E2853D"//orange @@ -18,11 +25,11 @@ desc = "Used to request supplies from cargo." icon_screen = "request" circuit = /obj/item/circuitboard/computer/cargo/request - req_access = list() requestonly = TRUE /obj/machinery/computer/cargo/Initialize() . = ..() + radio = new /obj/item/radio/headset/headset_cargo(src) var/obj/item/circuitboard/computer/cargo/board = circuit contraband = board.contraband if (board.obj_flags & EMAGGED) @@ -30,6 +37,10 @@ else obj_flags &= ~EMAGGED +/obj/machinery/computer/cargo/Destroy() + QDEL_NULL(radio) + ..() + /obj/machinery/computer/cargo/proc/get_export_categories() . = EXPORT_CARGO if(contraband) @@ -38,11 +49,11 @@ . |= EXPORT_EMAG /obj/machinery/computer/cargo/emag_act(mob/user) - . = ..() if(obj_flags & EMAGGED) return - user.visible_message("[user] swipes a suspicious card through [src]!", - "You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.") + if(user) + user.visible_message("[user] swipes a suspicious card through [src]!", + "You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.") obj_flags |= EMAGGED contraband = TRUE @@ -51,23 +62,21 @@ var/obj/item/circuitboard/computer/cargo/board = circuit board.contraband = TRUE board.obj_flags |= EMAGGED - req_access = list() - return TRUE + update_static_data(user) /obj/machinery/computer/cargo/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "cargo", name, 1000, 800, master_ui, state) + ui = new(user, src, ui_key, "cargo", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/cargo/ui_data() var/list/data = list() - data["requestonly"] = requestonly data["location"] = SSshuttle.supply.getStatusText() - data["points"] = SSshuttle.points data["away"] = SSshuttle.supply.getDockedId() == "supply_away" data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE + data["points"] = SSshuttle.points data["loan"] = !!SSshuttle.shuttle_loan data["loan_dispatched"] = SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched var/message = "Remember to stamp and send back the supply manifests." @@ -76,29 +85,13 @@ if(SSshuttle.supplyBlocked) message = blockade_warning data["message"] = message - data["supplies"] = list() - for(var/pack in SSshuttle.supply_packs) - var/datum/supply_pack/P = SSshuttle.supply_packs[pack] - if(!data["supplies"][P.group]) - data["supplies"][P.group] = list( - "name" = P.group, - "packs" = list() - ) - if((P.hidden && !(obj_flags & EMAGGED)) || (P.contraband && !contraband) || (P.special && !P.special_enabled) || P.DropPodOnly) - continue - data["supplies"][P.group]["packs"] += list(list( - "name" = P.name, - "cost" = P.cost, - "id" = pack, - "desc" = P.desc || P.name // If there is a description, use it. Otherwise use the pack's name. - )) - data["cart"] = list() for(var/datum/supply_order/SO in SSshuttle.shoppinglist) data["cart"] += list(list( "object" = SO.pack.name, "cost" = SO.pack.cost, - "id" = SO.id + "id" = SO.id, + "orderer" = SO.orderer, )) data["requests"] = list() @@ -113,14 +106,31 @@ return data +/obj/machinery/computer/cargo/ui_static_data(mob/user) + var/list/data = list() + data["requestonly"] = requestonly + data["supplies"] = list() + for(var/pack in SSshuttle.supply_packs) + var/datum/supply_pack/P = SSshuttle.supply_packs[pack] + if(!data["supplies"][P.group]) + data["supplies"][P.group] = list( + "name" = P.group, + "packs" = list() + ) + if((P.hidden && !(obj_flags & EMAGGED)) || (P.contraband && !contraband) || (P.special && !P.special_enabled) || P.DropPodOnly) + continue + data["supplies"][P.group]["packs"] += list(list( + "name" = P.name, + "cost" = P.cost, + "id" = pack, + "desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name. + "access" = P.access + )) + return data + /obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui) if(..()) return - if(!allowed(usr)) - to_chat(usr, "Access denied.") - return - if(action != "add" && requestonly) - return switch(action) if("send") if(!SSshuttle.supply.canMove()) diff --git a/code/modules/cargo/exports/gear.dm b/code/modules/cargo/exports/gear.dm index 77b57466d9..d15fc18b6e 100644 --- a/code/modules/cargo/exports/gear.dm +++ b/code/modules/cargo/exports/gear.dm @@ -229,12 +229,12 @@ /datum/export/gear/magboots cost = 50 unit_name = "magboots" - export_types = list(/obj/item/clothing/shoes/magboots, /obj/item/clothing/shoes/magboots/atmos) + export_types = list(/obj/item/clothing/shoes/magboots) /datum/export/gear/nosellboots cost = -5000 //We DONT want scew antags unit_name = "error shipment stolen" - export_types = list(/obj/item/clothing/shoes/magboots/advance, /obj/item/clothing/shoes/magboots/deathsquad) + export_types = list(/obj/item/clothing/shoes/magboots/advance) /datum/export/gear/syndamagboots cost = 250 @@ -279,7 +279,7 @@ /datum/export/gear/magicboots //Magic as in Antag - Wiz/Cults cost = 450 unit_name = "magic shoes" - export_types = list(/obj/item/clothing/shoes/sandal/marisa, /obj/item/clothing/shoes/sandal/magic, /obj/item/clothing/shoes/cult, /obj/item/clothing/shoes/clockwork, /obj/item/clothing/shoes/clown_shoes/taeclowndo, /obj/item/clothing/shoes/sandal/slippers) + export_types = list(/obj/item/clothing/shoes/sandal/marisa, /obj/item/clothing/shoes/sandal/magic, /obj/item/clothing/shoes/cult, /obj/item/clothing/shoes/clockwork, /obj/item/clothing/shoes/clown_shoes/taeclowndo) include_subtypes = TRUE //Headsets/Ears @@ -585,8 +585,7 @@ datum/export/gear/glasses //glasses are not worth selling export_types = list(/obj/item/clothing/under/scratch, /obj/item/clothing/under/sl_suit, /obj/item/clothing/under/rank/vice, /obj/item/clothing/under/suit_jacket, \ /obj/item/clothing/under/burial, /obj/item/clothing/under/skirt/black, /obj/item/clothing/under/captainparade, /obj/item/clothing/under/hosparademale, \ /obj/item/clothing/under/hosparadefem, /obj/item/clothing/under/assistantformal, /obj/item/clothing/under/stripeddress, /obj/item/clothing/under/redeveninggown, \ - /obj/item/clothing/under/plaid_skirt, /obj/item/clothing/under/geisha, /obj/item/clothing/under/trek, /obj/item/clothing/under/wedding, /obj/item/clothing/under/aviatoruniform,\ - /obj/item/clothing/under/mega, /obj/item/clothing/under/cia, /obj/item/clothing/under/casualwear, /obj/item/clothing/under/rank) + /obj/item/clothing/under/plaid_skirt, /obj/item/clothing/under/geisha, /obj/item/clothing/under/trek, /obj/item/clothing/under/rank) include_subtypes = TRUE /datum/export/gear/armored_jumpsuit diff --git a/code/modules/cargo/exports/parts.dm b/code/modules/cargo/exports/parts.dm index e53db0bf7b..e4efaf0810 100644 --- a/code/modules/cargo/exports/parts.dm +++ b/code/modules/cargo/exports/parts.dm @@ -92,11 +92,42 @@ export_types = list(/obj/item/stock_parts/cell/bluespace) /datum/export/cellyellow - cost = 40 + cost = 200 unit_name = "slime power cell" export_types = list(/obj/item/stock_parts/cell/high/slime) /datum/export/cellyellowhyper - cost = 120 //Takes a lot to make and is really good + cost = 1200 //Takes a lot to make and is really good unit_name = "hyper slime power cell" - export_types = list(/obj/item/stock_parts/cell/high/slime/hypercharged) \ No newline at end of file + export_types = list(/obj/item/stock_parts/cell/high/slime/hypercharged) + +//Glass working stuff + +/datum/export/glasswork_dish + cost = 300 + unit_name = "small glass dish" + export_types = list(/obj/item/reagent_containers/glass/beaker/glass_dish) + include_subtypes = FALSE + +/datum/export/glasswork_lens + cost = 1800 + unit_name = "small glass lens" + export_types = list(/obj/item/lens) + +/datum/export/glasswork_spouty + cost = 1200 + unit_name = "flask with spout" + export_types = list(/obj/item/reagent_containers/glass/beaker/flask/spouty) + include_subtypes = FALSE + +/datum/export/glasswork_smallflask + cost = 600 + unit_name = "small flask" + export_types = list(/obj/item/reagent_containers/glass/beaker/flask) + include_subtypes = FALSE + +/datum/export/glasswork_largeflask + cost = 1000 + unit_name = "large flask" + export_types = list(/obj/item/reagent_containers/glass/beaker/flask/large) + include_subtypes = FALSE diff --git a/code/modules/cargo/exports/weapons.dm b/code/modules/cargo/exports/weapons.dm index 18a525b8dd..5b78a5d630 100644 --- a/code/modules/cargo/exports/weapons.dm +++ b/code/modules/cargo/exports/weapons.dm @@ -342,7 +342,7 @@ /datum/export/weapon/real_toolbox cost = 600 unit_name = "golden toolbox" - export_types = list(/obj/item/storage/toolbox/gold_real) + export_types = list(/obj/item/storage/toolbox/plastitanium/gold_real) /datum/export/weapon/melee cost = 50 diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index a4ede0cad2..20dc724707 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -90,7 +90,7 @@ /obj/machinery/computer/cargo/express/ui_interact(mob/living/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state. ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "cargo_express", name, 1000, 800, master_ui, state) + ui = new(user, src, ui_key, "cargo_express", name, 600, 700, master_ui, state) ui.open() /obj/machinery/computer/cargo/express/ui_data(mob/user) diff --git a/code/modules/cargo/packs/armory.dm b/code/modules/cargo/packs/armory.dm index 259ea2d7e3..ea8ef8ba0f 100644 --- a/code/modules/cargo/packs/armory.dm +++ b/code/modules/cargo/packs/armory.dm @@ -226,7 +226,7 @@ crate_name = "swat taser crate" /datum/supply_pack/security/armory/woodstock - name = "Classic WoodStock Shotguns Crate" + name = "WoodStock Classic Shotguns Crate" desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open." cost = 3000 contains = list(/obj/item/gun/ballistic/shotgun, diff --git a/code/modules/cargo/packs/costumes_toys.dm b/code/modules/cargo/packs/costumes_toys.dm index 40d21e4505..4a64979502 100644 --- a/code/modules/cargo/packs/costumes_toys.dm +++ b/code/modules/cargo/packs/costumes_toys.dm @@ -3,12 +3,18 @@ // If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal // cost = 700- Minimum cost, or infinite points are possible. ////////////////////////////////////////////////////////////////////////////// -//////////////////////////// Costumes & Toys ///////////////////////////////// +////////////////////////////////// Toys ////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// /datum/supply_pack/costumes_toys group = "Costumes & Toys" +/datum/supply_pack/costumes_toys/randomised/fill(obj/structure/closet/crate/C) + var/list/L = contains.Copy() + for(var/i in 1 to num_contained) + var/item = pick_n_take(L) + new item(C) + /datum/supply_pack/costumes_toys/randomised name = "Collectable Hats Crate" desc = "Flaunt your status with three unique, highly-collectable hats!" @@ -92,40 +98,6 @@ /obj/item/ammo_box/magazine/toy/pistol) crate_name = "foam force crate" -/datum/supply_pack/costumes_toys/formalwear - name = "Formalwear Crate" - desc = "You're gonna like the way you look, I guaranteed it. Contains an asston of fancy clothing." - cost = 4750 //Lots of fancy clothing that can be sold back! - contains = list(/obj/item/clothing/under/blacktango, - /obj/item/clothing/under/assistantformal, - /obj/item/clothing/under/assistantformal, - /obj/item/clothing/under/lawyer/bluesuit, - /obj/item/clothing/suit/toggle/lawyer, - /obj/item/clothing/under/lawyer/purpsuit, - /obj/item/clothing/suit/toggle/lawyer/purple, - /obj/item/clothing/under/lawyer/blacksuit, - /obj/item/clothing/suit/toggle/lawyer/black, - /obj/item/clothing/accessory/waistcoat, - /obj/item/clothing/neck/tie/blue, - /obj/item/clothing/neck/tie/red, - /obj/item/clothing/neck/tie/black, - /obj/item/clothing/head/bowler, - /obj/item/clothing/head/fedora, - /obj/item/clothing/head/flatcap, - /obj/item/clothing/head/beret, - /obj/item/clothing/head/that, - /obj/item/clothing/shoes/laceup, - /obj/item/clothing/shoes/laceup, - /obj/item/clothing/shoes/laceup, - /obj/item/clothing/under/suit_jacket/charcoal, - /obj/item/clothing/under/suit_jacket/navy, - /obj/item/clothing/under/suit_jacket/burgundy, - /obj/item/clothing/under/suit_jacket/checkered, - /obj/item/clothing/under/suit_jacket/tan, - /obj/item/lipstick/random) - crate_name = "formalwear crate" - crate_type = /obj/structure/closet/crate/wooden - /datum/supply_pack/costumes_toys/clownpin name = "Hilarious Firing Pin Crate" desc = "I uh... I'm not really sure what this does. Wanna buy it?" @@ -167,47 +139,6 @@ contains = list(/obj/item/storage/box/lasertagpins) crate_name = "laser tag crate" -/datum/supply_pack/costumes_toys/costume_original - name = "Original Costume Crate" - desc = "Reenact Shakespearean plays with this assortment of outfits. Contains eight different costumes!" - cost = 1750 - contains = list(/obj/item/clothing/head/snowman, - /obj/item/clothing/suit/snowman, - /obj/item/clothing/head/chicken, - /obj/item/clothing/suit/chickensuit, - /obj/item/clothing/mask/gas/monkeymask, - /obj/item/clothing/suit/monkeysuit, - /obj/item/clothing/head/cardborg, - /obj/item/clothing/suit/cardborg, - /obj/item/clothing/head/xenos, - /obj/item/clothing/suit/xenos, - /obj/item/clothing/suit/hooded/ian_costume, - /obj/item/clothing/suit/hooded/carp_costume, - /obj/item/clothing/suit/hooded/bee_costume) - crate_name = "original costume crate" - crate_type = /obj/structure/closet/crate/wooden - -/datum/supply_pack/costumes_toys/costume - name = "Standard Costume Crate" - desc = "Supply the station's entertainers with the equipment of their trade with these Nanotrasen-approved costumes! Contains a full clown and mime outfit, along with a bike horn and a bottle of nothing." - cost = 1300 - access = ACCESS_THEATRE - contains = list(/obj/item/storage/backpack/clown, - /obj/item/clothing/shoes/clown_shoes, - /obj/item/clothing/mask/gas/clown_hat, - /obj/item/clothing/under/rank/clown, - /obj/item/bikehorn, - /obj/item/clothing/under/rank/mime, - /obj/item/clothing/shoes/sneakers/black, - /obj/item/clothing/gloves/color/white, - /obj/item/clothing/mask/gas/mime, - /obj/item/clothing/head/beret, - /obj/item/clothing/suit/suspenders, - /obj/item/reagent_containers/food/drinks/bottle/bottleofnothing, - /obj/item/storage/backpack/mime) - crate_name = "standard costume crate" - crate_type = /obj/structure/closet/crate/wooden - /datum/supply_pack/costumes_toys/randomised/toys name = "Toy Crate" desc = "Who cares about pride and accomplishment? Skip the gaming and get straight to the sweet rewards with this product! Contains five random toys. Warranty void if used to prank research directors." @@ -278,6 +209,86 @@ crate_name = "plushie crate" crate_type = /obj/structure/closet/crate/wooden + +////////////////////////////////////////////////////////////////////////////// +///////////////////////////////// Costumes ////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_pack/costumes_toys/formalwear + name = "Formalwear Crate" + desc = "You're gonna like the way you look, I guaranteed it. Contains an asston of fancy clothing." + cost = 4750 //Lots of fancy clothing that can be sold back! + contains = list(/obj/item/clothing/under/blacktango, + /obj/item/clothing/under/assistantformal, + /obj/item/clothing/under/assistantformal, + /obj/item/clothing/under/lawyer/bluesuit, + /obj/item/clothing/suit/toggle/lawyer, + /obj/item/clothing/under/lawyer/purpsuit, + /obj/item/clothing/suit/toggle/lawyer/purple, + /obj/item/clothing/under/lawyer/blacksuit, + /obj/item/clothing/suit/toggle/lawyer/black, + /obj/item/clothing/accessory/waistcoat, + /obj/item/clothing/neck/tie/blue, + /obj/item/clothing/neck/tie/red, + /obj/item/clothing/neck/tie/black, + /obj/item/clothing/head/bowler, + /obj/item/clothing/head/fedora, + /obj/item/clothing/head/flatcap, + /obj/item/clothing/head/beret, + /obj/item/clothing/head/that, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/shoes/laceup, + /obj/item/clothing/under/suit_jacket/charcoal, + /obj/item/clothing/under/suit_jacket/navy, + /obj/item/clothing/under/suit_jacket/burgundy, + /obj/item/clothing/under/suit_jacket/checkered, + /obj/item/clothing/under/suit_jacket/tan, + /obj/item/lipstick/random) + crate_name = "formalwear crate" + crate_type = /obj/structure/closet/crate/wooden + +/datum/supply_pack/costumes_toys/costume_original + name = "Original Costume Crate" + desc = "Reenact Shakespearean plays with this assortment of outfits. Contains eight different costumes!" + cost = 1750 + contains = list(/obj/item/clothing/head/snowman, + /obj/item/clothing/suit/snowman, + /obj/item/clothing/head/chicken, + /obj/item/clothing/suit/chickensuit, + /obj/item/clothing/mask/gas/monkeymask, + /obj/item/clothing/suit/monkeysuit, + /obj/item/clothing/head/cardborg, + /obj/item/clothing/suit/cardborg, + /obj/item/clothing/head/xenos, + /obj/item/clothing/suit/xenos, + /obj/item/clothing/suit/hooded/ian_costume, + /obj/item/clothing/suit/hooded/carp_costume, + /obj/item/clothing/suit/hooded/bee_costume) + crate_name = "original costume crate" + crate_type = /obj/structure/closet/crate/wooden + +/datum/supply_pack/costumes_toys/costume + name = "Standard Costume Crate" + desc = "Supply the station's entertainers with the equipment of their trade with these Nanotrasen-approved costumes! Contains a full clown and mime outfit, along with a bike horn and a bottle of nothing." + cost = 1300 + access = ACCESS_THEATRE + contains = list(/obj/item/storage/backpack/clown, + /obj/item/clothing/shoes/clown_shoes, + /obj/item/clothing/mask/gas/clown_hat, + /obj/item/clothing/under/rank/clown, + /obj/item/bikehorn, + /obj/item/clothing/under/rank/mime, + /obj/item/clothing/shoes/sneakers/black, + /obj/item/clothing/gloves/color/white, + /obj/item/clothing/mask/gas/mime, + /obj/item/clothing/head/beret, + /obj/item/clothing/suit/suspenders, + /obj/item/reagent_containers/food/drinks/bottle/bottleofnothing, + /obj/item/storage/backpack/mime) + crate_name = "standard costume crate" + crate_type = /obj/structure/closet/crate/wooden + /datum/supply_pack/costumes_toys/wizard name = "Wizard Costume Crate" desc = "Pretend to join the Wizard Federation with this full wizard outfit! Nanotrasen would like to remind its employees that actually joining the Wizard Federation is subject to termination of job and life." @@ -288,82 +299,3 @@ /obj/item/clothing/head/wizard/fake) crate_name = "wizard costume crate" crate_type = /obj/structure/closet/crate/wooden - -/datum/supply_pack/costumes_toys/randomised/fill(obj/structure/closet/crate/C) - var/list/L = contains.Copy() - for(var/i in 1 to num_contained) - var/item = pick_n_take(L) - new item(C) - -/datum/supply_pack/costumes_toys/wardrobes/autodrobe - name = "Autodrobe Supply Crate" - desc = "Autodrobe missing your favorite dress? Solve that issue today with this autodrobe refill." - cost = 1500 - contains = list(/obj/item/vending_refill/autodrobe) - crate_name = "autodrobe supply crate" - -/datum/supply_pack/costumes_toys/wardrobes/cargo - name = "Cargo Wardrobe Supply Crate" - desc = "This crate contains a refill for the CargoDrobe." - cost = 750 - contains = list(/obj/item/vending_refill/wardrobe/cargo_wardrobe) - crate_name = "cargo department supply crate" - -/datum/supply_pack/costumes_toys/wardrobes/engineering - name = "Engineering Wardrobe Supply Crate" - desc = "This crate contains refills for the EngiDrobe and AtmosDrobe." - cost = 1500 - contains = list(/obj/item/vending_refill/wardrobe/engi_wardrobe, - /obj/item/vending_refill/wardrobe/atmos_wardrobe) - crate_name = "engineering department wardrobe supply crate" - -/datum/supply_pack/costumes_toys/wardrobes/general - name = "General Wardrobes Supply Crate" - desc = "This crate contains refills for the CuraDrobe, BarDrobe, ChefDrobe, JaniDrobe, ChapDrobe." - cost = 3750 - contains = list(/obj/item/vending_refill/wardrobe/curator_wardrobe, - /obj/item/vending_refill/wardrobe/bar_wardrobe, - /obj/item/vending_refill/wardrobe/chef_wardrobe, - /obj/item/vending_refill/wardrobe/jani_wardrobe, - /obj/item/vending_refill/wardrobe/chap_wardrobe) - crate_name = "general wardrobes vendor refills" - -/datum/supply_pack/costumes_toys/wardrobes/hydroponics - name = "Hydrobe Supply Crate" - desc = "This crate contains a refill for the Hydrobe." - cost = 750 - contains = list(/obj/item/vending_refill/wardrobe/hydro_wardrobe) - crate_name = "hydrobe supply crate" - -/datum/supply_pack/costumes_toys/wardrobes/medical - name = "Medical Wardrobe Supply Crate" - desc = "This crate contains refills for the MediDrobe, ChemDrobe, GeneDrobe, and ViroDrobe." - cost = 3000 - contains = list(/obj/item/vending_refill/wardrobe/medi_wardrobe, - /obj/item/vending_refill/wardrobe/chem_wardrobe, - /obj/item/vending_refill/wardrobe/gene_wardrobe, - /obj/item/vending_refill/wardrobe/viro_wardrobe) - crate_name = "medical department wardrobe supply crate" - -/datum/supply_pack/costumes_toys/wardrobes/science - name = "Science Wardrobe Supply Crate" - desc = "This crate contains refills for the SciDrobe and RoboDrobe." - cost = 1500 - contains = list(/obj/item/vending_refill/wardrobe/robo_wardrobe, - /obj/item/vending_refill/wardrobe/science_wardrobe) - crate_name = "science department wardrobe supply crate" - -/datum/supply_pack/costumes_toys/wardrobes/security - name = "Security Wardrobe Supply Crate" - desc = "This crate contains refills for the SecDrobe and LawDrobe." - cost = 1500 - contains = list(/obj/item/vending_refill/wardrobe/sec_wardrobe, - /obj/item/vending_refill/wardrobe/law_wardrobe) - crate_name = "security department supply crate" - -/datum/supply_pack/costumes_toys/kinkmate - name = "Kinkmate construction kit" - cost = 2000 - contraband = TRUE - contains = list(/obj/item/vending_refill/kink, /obj/item/circuitboard/machine/kinkmate) - crate_name = "Kinkmate construction kit" diff --git a/code/modules/cargo/packs/emergency.dm b/code/modules/cargo/packs/emergency.dm index 747e820f52..e32811f2d0 100644 --- a/code/modules/cargo/packs/emergency.dm +++ b/code/modules/cargo/packs/emergency.dm @@ -11,11 +11,13 @@ /datum/supply_pack/emergency/vehicle name = "Biker Gang Kit" //TUNNEL SNAKES OWN THIS TOWN - desc = "TUNNEL SNAKES OWN THIS TOWN. Contains an unbranded All Terrain Vehicle, and a complete gang outfit -- consists of black gloves, a menacing skull bandanna, and a SWEET leather overcoat!" + desc = "TUNNEL SNAKES OWN THIS TOWN. Contains an unbranded All Terrain Vehicle, two cans of spraypaint, and a complete gang outfit -- consists of black gloves, a menacing skull bandanna, and a SWEET leather overcoat!" cost = 2500 contraband = TRUE contains = list(/obj/vehicle/ridden/atv, /obj/item/key, + /obj/item/toy/crayon/spraycan, + /obj/item/toy/crayon/spraycan, /obj/item/clothing/suit/jacket/leather/overcoat, /obj/item/clothing/gloves/color/black, /obj/item/clothing/head/soft, @@ -126,21 +128,6 @@ crate_name = "emergency rcds" crate_type = /obj/structure/closet/crate/internals -/datum/supply_pack/emergency/soft_suit - name = "Emergency Space Suit" - desc = "Are there bombs going off left and right? Are there meteors shooting around the station? Well then! Here's two fragile space suits for emergencies. Comes with air and masks." - cost = 1200 - contains = list(/obj/item/tank/internals/air, - /obj/item/tank/internals/air, - /obj/item/clothing/mask/gas, - /obj/item/clothing/mask/gas, - /obj/item/clothing/suit/space/fragile, - /obj/item/clothing/suit/space/fragile, - /obj/item/clothing/head/helmet/space/fragile, - /obj/item/clothing/head/helmet/space/fragile) - crate_name = "emergency crate" - crate_type = /obj/structure/closet/crate/internals - /datum/supply_pack/emergency/bomb name = "Explosive Emergency Crate" desc = "Science gone bonkers? Beeping behind the airlock? Buy now and be the hero the station des... I mean needs! (Time not included.)" @@ -208,7 +195,7 @@ crate_name = "metal foam grenade crate" /datum/supply_pack/emergency/mre - name = "MRE supply kit (emergency rations)" + name = "MRE Packs (Emergency Rations)" desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank." cost = 2000 contains = list(/obj/item/storage/box/mre/menu1/safe, @@ -296,6 +283,21 @@ crate_name = "space suit crate" crate_type = /obj/structure/closet/crate/secure +/datum/supply_pack/emergency/soft_suit + name = "Space Suits (Fragile)" + desc = "Are there bombs going off left and right? Are there meteors shooting around the station? Well then! Here's two fragile space suits for emergencies. Comes with air and masks." + cost = 1200 + contains = list(/obj/item/tank/internals/air, + /obj/item/tank/internals/air, + /obj/item/clothing/mask/gas, + /obj/item/clothing/mask/gas, + /obj/item/clothing/suit/space/fragile, + /obj/item/clothing/suit/space/fragile, + /obj/item/clothing/head/helmet/space/fragile, + /obj/item/clothing/head/helmet/space/fragile) + crate_name = "emergency crate" + crate_type = /obj/structure/closet/crate/internals + /datum/supply_pack/emergency/spacejets name = "Spare EVA Jetpacks" desc = "Contains three EVA grade jectpaks. Requires EVA access to open." diff --git a/code/modules/cargo/packs/engine.dm b/code/modules/cargo/packs/engine.dm index 499881a110..27891f3ab6 100644 --- a/code/modules/cargo/packs/engine.dm +++ b/code/modules/cargo/packs/engine.dm @@ -149,6 +149,14 @@ crate_type = /obj/structure/closet/crate/secure/engineering dangerous = TRUE +/datum/supply_pack/engine/supermatter_spray + name = "Supermatter Spray Crate" + desc = "The single thing that can truly heal the supermatter." + cost = 2000 + contains = list(/obj/item/supermatterspray) + crate_name = "supermatter shard crate" + crate_type = /obj/structure/closet/crate/engineering/electrical + /datum/supply_pack/engine/tesla_coils name = "Tesla Coil Crate" desc = "Whether it's high-voltage executions, creating research points, or just plain old power generation: This pack of four Tesla coils can do it all!" diff --git a/code/modules/cargo/packs/engineering.dm b/code/modules/cargo/packs/engineering.dm index ea90255bce..22258d19a7 100644 --- a/code/modules/cargo/packs/engineering.dm +++ b/code/modules/cargo/packs/engineering.dm @@ -3,7 +3,7 @@ // If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal // cost = 700- Minimum cost, or infinite points are possible. ////////////////////////////////////////////////////////////////////////////// -//////////////////////////// Engineering ///////////////////////////////////// +///////////////////////////// Engineering //////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// /datum/supply_pack/engineering @@ -20,15 +20,9 @@ /datum/supply_pack/engineering/conveyor name = "Conveyor Assembly Crate" - desc = "Keep production moving along with six conveyor belts. Conveyor switch included. If you have any questions, check out the enclosed instruction book." + desc = "Keep production moving along with fifteen conveyor belts. Conveyor switch included. If you have any questions, check out the enclosed instruction book." cost = 750 - contains = list(/obj/item/conveyor_construct, - /obj/item/conveyor_construct, - /obj/item/conveyor_construct, - /obj/item/conveyor_construct, - /obj/item/conveyor_construct, - /obj/item/conveyor_construct, - /obj/item/conveyor_switch_construct, + contains = list(/obj/item/stack/conveyor/fifteen, /obj/item/paper/guides/conveyor) crate_name = "conveyor assembly crate" @@ -51,6 +45,7 @@ /obj/item/clothing/glasses/meson/engine, /obj/item/clothing/glasses/meson/engine) crate_name = "engineering gear crate" + crate_type = /obj/structure/closet/crate/secure/engineering /datum/supply_pack/engineering/engihardsuit name = "Engineering Hardsuit" @@ -61,6 +56,7 @@ /obj/item/clothing/mask/gas, /obj/item/clothing/suit/space/hardsuit/engine) crate_name = "engineering hardsuit" + crate_type = /obj/structure/closet/crate/secure/engineering /datum/supply_pack/engineering/atmoshardsuit name = "Atmospherics Hardsuit" @@ -73,14 +69,15 @@ crate_name = "atmospherics hardsuit" crate_type = /obj/structure/closet/crate/secure/engineering -/datum/supply_pack/engineering/radhardsuit - name = "Radiation Hardsuit" +/datum/supply_pack/engineering/radvoidsuit + name = "Radiation Voidsuit" desc = "The Singulo is loose? Do you need to do a few changes to its containment and don't want to spent the rest of the shift under the shower? Get this Radiation Hardsuit! It protect from radiations and space only." cost = 3500 access = ACCESS_ENGINE contains = list(/obj/item/tank/internals/air, /obj/item/clothing/mask/gas, - /obj/item/clothing/suit/space/hardsuit/engine/rad) + /obj/item/clothing/suit/space/rad, + /obj/item/clothing/head/helmet/space/rad) crate_name = "radiation hardsuit" crate_type = /obj/structure/closet/crate/secure/engineering @@ -119,6 +116,22 @@ crate_name = "PACMAN generator crate" crate_type = /obj/structure/closet/crate/engineering/electrical +/datum/supply_pack/engineering/airpump + name = "Portable Air Pump Crate" + desc = "We all know you work in a high pressure workplace. Keep it that way with two additional air pumps!" + cost = 3000 + contains = list(/obj/machinery/portable_atmospherics/pump, + /obj/machinery/portable_atmospherics/pump) + crate_name = "portable air pump crate" + +/datum/supply_pack/engineering/airscrubber + name = "Portable Scrubber Crate" + desc = "Miasma got you down? Plasma in the vents? Freshen up with these two brand-new air scrubbers!" + cost = 3000 + contains = list(/obj/machinery/portable_atmospherics/scrubber, + /obj/machinery/portable_atmospherics/scrubber) + crate_name = "portable scrubber crate" + /datum/supply_pack/engineering/power name = "Power Cell Crate" desc = "Looking for power overwhelming? Look no further. Contains three high-voltage power cells." diff --git a/code/modules/cargo/packs/materials.dm b/code/modules/cargo/packs/materials.dm index c9862282dc..6c1742896f 100644 --- a/code/modules/cargo/packs/materials.dm +++ b/code/modules/cargo/packs/materials.dm @@ -69,6 +69,11 @@ contains = list(/obj/item/grown/log) crate_name = "lumber crate" +/datum/supply_pack/materials/rawlumber/generate() + . = ..() + for(var/i in 1 to 49) + new /obj/item/grown/log(.) + /datum/supply_pack/materials/wood50 name = "50 Wood Planks" desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with fifty wooden planks!" @@ -89,7 +94,7 @@ /datum/supply_pack/materials/rawcottonbulk name = "Raw Cotton Crate (Bulk)" desc = "We have so much of this stuff we need to get rid of it in -bulk- now. This crate contains 240 raw cotton sheets." - cost = 1300 // 100 net cost (per 40 cotton) , 20 x 20 = 400. 300 profit if turned into cloth sheets or more if turned to silk then 10 x 200 = 2000 + cost = 1300 // 600 net cost 20 x 120 = 2400 profit if turned into cloth sheets or if turned into silk 200 x 60 = 12000 contains = list(/obj/item/stack/sheet/cotton/thirty, /obj/item/stack/sheet/cotton/thirty, /obj/item/stack/sheet/cotton/thirty, @@ -102,13 +107,8 @@ crate_name = "bulk cotton crate" crate_type = /obj/structure/closet/crate/hydroponics -/datum/supply_pack/critter/animal_feed/generate() - . = ..() - for(var/i in 1 to 49) - new /obj/item/grown/log(.) - /datum/supply_pack/materials/rcdammo - name = "Spare RDC ammo" + name = "Spare RCD ammo" desc = "This crate contains sixteen RCD compressed matter packs, to help with any holes or projects people might be working on." cost = 3750 contains = list(/obj/item/rcd_ammo, diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm index a60afe4f7a..ea327ae820 100644 --- a/code/modules/cargo/packs/medical.dm +++ b/code/modules/cargo/packs/medical.dm @@ -10,6 +10,10 @@ group = "Medical" crate_type = /obj/structure/closet/crate/medical +////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// Equipment //////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + /datum/supply_pack/medical/bodybags name = "Bodybags" desc = "For when the bodies hit the floor. Contains 4 boxes of bodybags." @@ -20,24 +24,6 @@ /obj/item/storage/box/bodybags,) crate_name = "bodybag crate" -/datum/supply_pack/medical/firstaidbruises - name = "Bruise Treatment Kit Crate" - desc = "Contains three first aid kits focused on healing bruises and broken bones." - cost = 1000 - contains = list(/obj/item/storage/firstaid/brute, - /obj/item/storage/firstaid/brute, - /obj/item/storage/firstaid/brute) - crate_name = "brute treatment kit crate" - -/datum/supply_pack/medical/firstaidburns - name = "Burn Treatment Kit Crate" - desc = "Contains three first aid kits focused on healing severe burns." - cost = 1000 - contains = list(/obj/item/storage/firstaid/fire, - /obj/item/storage/firstaid/fire, - /obj/item/storage/firstaid/fire) - crate_name = "burn treatment kit crate" - /datum/supply_pack/medical/bloodpacks name = "Blood Pack Variety Crate" desc = "Contains nine different blood packs for reintroducing blood to patients, plus two universal synthetic blood packs." @@ -86,16 +72,6 @@ /obj/item/defibrillator/loaded) crate_name = "defibrillator crate" -/datum/supply_pack/medical/firstaid - name = "First Aid Kit Crate" - desc = "Contains four first aid kits for healing most types of wounds." - cost = 1000 - contains = list(/obj/item/storage/firstaid/regular, - /obj/item/storage/firstaid/regular, - /obj/item/storage/firstaid/regular, - /obj/item/storage/firstaid/regular) - crate_name = "first aid kit crate" - /datum/supply_pack/medical/iv_drip name = "IV Drip Crate" desc = "Contains a single IV drip stand for intravenous delivery." @@ -103,17 +79,6 @@ contains = list(/obj/machinery/iv_drip) crate_name = "iv drip crate" -/datum/supply_pack/science/adv_surgery_tools - name = "Med-Co Advanced surgery tools" - desc = "A full set of Med-Co advanced surgery tools! In addition to that it contains both a can of synthflesh and a can of sterilizine. Requires Surgery access to open." - cost = 5500 - access = ACCESS_SURGERY - contains = list(/obj/item/storage/belt/medical/surgery_belt_adv, - /obj/item/reagent_containers/medspray/synthflesh, - /obj/item/reagent_containers/medspray/sterilizine) - crate_name = "medco newest surgery tools" - crate_type = /obj/structure/closet/crate/medical - /datum/supply_pack/medical/medicalhardsuit name = "Medical Hardsuit" desc = "Got people being spaced left and right? Hole in the same room as the dead body of Hos or cap? Fear not, now you can buy one medical hardsuit with a mask and air tank to save your fellow crewmembers. Requires medical access to open." @@ -151,13 +116,57 @@ /obj/item/storage/pill_bottle/stimulant) crate_name = "medical supplies crate" -/datum/supply_pack/medical/vending - name = "Medical Vending Crate" - desc = "Contains refills for medical vending machines." - cost = 2000 - contains = list(/obj/item/vending_refill/medical, - /obj/item/vending_refill/wallmed) - crate_name = "medical vending crate" +/datum/supply_pack/medical/adv_surgery_tools + name = "Med-Co Advanced Surgery Tools" + desc = "A full set of Med-Co advanced surgery tools, this crate also comes with a spay of synth flesh as well as a can of . Requires Surgery access to open." + cost = 5500 + access = ACCESS_SURGERY + contains = list(/obj/item/storage/belt/medical/surgery_belt_adv, + /obj/item/reagent_containers/medspray/synthflesh, + /obj/item/reagent_containers/medspray/sterilizine) + crate_name = "medco surgery tools" + crate_type = /obj/structure/closet/crate/medical + +/datum/supply_pack/medical/surgery + name = "Surgical Supplies Crate" + desc = "Do you want to perform surgery, but don't have one of those fancy shmancy degrees? Just get started with this crate containing a medical duffelbag, Sterilizine spray and collapsible roller bed." + cost = 1300 + contains = list(/obj/item/storage/backpack/duffelbag/med/surgery, + /obj/item/reagent_containers/medspray/sterilizine, + /obj/item/roller) + crate_name = "surgical supplies crate" + +////////////////////////////////////////////////////////////////////////////// +///////////////////////////// Medical Kits /////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_pack/medical/firstaidbruises + name = "Bruise Treatment Kit Crate" + desc = "Contains three first aid kits focused on healing bruises and broken bones." + cost = 1000 + contains = list(/obj/item/storage/firstaid/brute, + /obj/item/storage/firstaid/brute, + /obj/item/storage/firstaid/brute) + crate_name = "brute treatment kit crate" + +/datum/supply_pack/medical/firstaidburns + name = "Burn Treatment Kit Crate" + desc = "Contains three first aid kits focused on healing severe burns." + cost = 1000 + contains = list(/obj/item/storage/firstaid/fire, + /obj/item/storage/firstaid/fire, + /obj/item/storage/firstaid/fire) + crate_name = "burn treatment kit crate" + +/datum/supply_pack/medical/firstaid + name = "First Aid Kit Crate" + desc = "Contains four first aid kits for healing most types of wounds." + cost = 1000 + contains = list(/obj/item/storage/firstaid/regular, + /obj/item/storage/firstaid/regular, + /obj/item/storage/firstaid/regular, + /obj/item/storage/firstaid/regular) + crate_name = "first aid kit crate" /datum/supply_pack/medical/sprays name = "Medical Sprays" @@ -193,6 +202,15 @@ /obj/item/storage/firstaid/o2) crate_name = "oxygen deprivation kit crate" +/datum/supply_pack/medical/firstaidtoxins + name = "Toxin Treatment Kit Crate" + desc = "Contains three first aid kits focused on healing damage dealt by heavy toxins." + cost = 1000 + contains = list(/obj/item/storage/firstaid/toxin, + /obj/item/storage/firstaid/toxin, + /obj/item/storage/firstaid/toxin) + crate_name = "toxin treatment kit crate" + /datum/supply_pack/medical/advrad name = "Radiation Treatment Crate Deluxe" desc = "A crate for when radiation is out of hand... Contains two rad-b-gone kits, one bottle of anti radiation deluxe pills, as well as a radiation treatment deluxe pill bottle!" @@ -206,23 +224,9 @@ crate_name = "radiation protection crate" crate_type = /obj/structure/closet/crate/radiation -/datum/supply_pack/medical/surgery - name = "Surgical Supplies Crate" - desc = "Do you want to perform surgery, but don't have one of those fancy shmancy degrees? Just get started with this crate containing a medical duffelbag, Sterilizine spray and collapsible roller bed." - cost = 1300 - contains = list(/obj/item/storage/backpack/duffelbag/med/surgery, - /obj/item/reagent_containers/medspray/sterilizine, - /obj/item/roller) - crate_name = "surgical supplies crate" - -/datum/supply_pack/medical/firstaidtoxins - name = "Toxin Treatment Kit Crate" - desc = "Contains three first aid kits focused on healing damage dealt by heavy toxins." - cost = 1000 - contains = list(/obj/item/storage/firstaid/toxin, - /obj/item/storage/firstaid/toxin, - /obj/item/storage/firstaid/toxin) - crate_name = "toxin treatment kit crate" +////////////////////////////////////////////////////////////////////////////// +//////////////////////////////// Virology //////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// /datum/supply_pack/medical/virus name = "Virus Crate" @@ -266,4 +270,4 @@ /obj/item/storage/box/syringes, /obj/item/storage/box/beakers) crate_name = "virus containment unit crate" - crate_type = /obj/structure/closet/crate/secure/plasma + crate_type = /obj/structure/closet/crate/secure/plasma \ No newline at end of file diff --git a/code/modules/cargo/packs/misc.dm b/code/modules/cargo/packs/misc.dm index f8656ef761..d9c9794bd8 100644 --- a/code/modules/cargo/packs/misc.dm +++ b/code/modules/cargo/packs/misc.dm @@ -13,16 +13,6 @@ //////////////////// Paperwork and Writing Supplies ////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_pack/misc/abandonedcrate - name = "Loot Box" - desc = "Try your luck with these highly secure loot boxes! Solve the lock, win great prizes! WARNING: EXPLOSIVE FAILURE." - contraband = TRUE - cost = 15000 - contains = list(/obj/structure/closet/crate/secure/loot) - crate_name = "abandoned crate" - crate_type = /obj/structure/closet/crate/large - dangerous = TRUE - /datum/supply_pack/misc/artsupply name = "Art Supplies" desc = "Make some happy little accidents with six canvasses, two easels, two boxes of crayons, and a rainbow crayon!" @@ -83,7 +73,7 @@ name = "Captain Pen" desc = "A spare Captain fountain pen." access = ACCESS_CAPTAIN - cost = 10000 + cost = 5000 contains = list(/obj/item/pen/fountain/captain) crate_name = "captain pen" crate_type = /obj/structure/closet/crate/secure/weapon //It is a combat pen @@ -153,7 +143,7 @@ /obj/item/bedsheet/purple, /obj/item/bedsheet/red, /obj/item/bedsheet/yellow, - /obj/item/bedsheet/brown, + /obj/item/bedsheet/brown, /obj/item/bedsheet/black, /obj/item/bedsheet/rainbow) crate_name = "colored bedsheet crate" @@ -182,18 +172,6 @@ /obj/structure/piano/unanchored) crate_type = /obj/structure/closet/crate/wooden -/datum/supply_pack/misc/cbtpack - name = "CBT Equipment" - desc = "(*!&@#CBT is a special term coined by high ranking syndicate operatives for a special form of information extraction. While the training required to use this shipment is highly classified, the distribution of it's contents are not. In addition to this crates unusual contents, we have added a bar of soap.#@*$" - hidden = TRUE - cost = 2400 - contains = list(/mob/living/simple_animal/chicken, - /obj/item/toy/beach_ball/holoball, - /obj/item/melee/baton/cattleprod, - /obj/item/soap/syndie) - crate_name = "cbt crate" - crate_type = /obj/structure/closet/crate/large - /datum/supply_pack/misc/casinocrate name = "Casino Crate" desc = "Start up your own grand casino with this crate filled with slot machine and arcade boards!" @@ -216,8 +194,8 @@ name = "Coin Crate" desc = "Psssst, hey, you. Yes, you. I've heard that coins can do some special things on your station, give you access to some pretty cool stuff. Here's the deal, you give me some credits, and I give so some coins. Sound like a deal? I'll give you 10 for 10000 creds." contraband = TRUE - cost = 10000 - contains = list(/obj/item/coin/silver) + cost = 3000 + contains = list(/obj/item/coin/silver) // 400 x 10 = 2 sheets of silver for 2300cr crate_name = "coin crate" crate_type = /obj/structure/closet/crate/large @@ -226,10 +204,77 @@ for(var/i in 1 to 9) new /obj/item/coin/silver(.) +/datum/supply_pack/misc/dueling_stam + name = "Dueling Pistols" + desc = "Resolve all your quarrels with some nonlethal fun." + cost = 2000 + contains = list(/obj/item/storage/lockbox/dueling/hugbox/stamina, + /obj/item/storage/lockbox/dueling/hugbox/stamina, + /obj/item/storage/lockbox/dueling/hugbox/stamina, + /obj/item/storage/lockbox/dueling/hugbox/stamina, + /obj/item/storage/lockbox/dueling/hugbox/stamina) + crate_name = "dueling pistols" + +/datum/supply_pack/misc/dueling_lethal + name = "Lethal Dueling Pistols" + desc = "Settle your differences the true spaceman way." + cost = 3000 + contraband = TRUE + contains = list(/obj/item/storage/lockbox/dueling/hugbox, + /obj/item/storage/lockbox/dueling/hugbox, + /obj/item/storage/lockbox/dueling/hugbox) + crate_name = "dueling pistols (lethal)" + +/datum/supply_pack/misc/dueling_death + name = "Elimination Dueling Pistols" + desc = "It's high noon." + cost = 5000 + hidden = TRUE + contains = list(/obj/item/storage/lockbox/dueling) + crate_name = "dueling pistols (elimination)" + +/datum/supply_pack/misc/dirtymags + name = "Dirty Magazines" + desc = "Get your mind out of the gutter operative, you have work to do. Three items per order. Possible Results: .357 Speedloaders, Kitchen Gun Mags, Stetchkin Mags." + hidden = TRUE + cost = 12000 + var/num_contained = 3 + contains = list(/obj/item/ammo_box/a357, + /obj/item/ammo_box/a357, + /obj/item/ammo_box/a357, + /obj/item/ammo_box/magazine/pistolm9mm, + /obj/item/ammo_box/magazine/pistolm9mm, + /obj/item/ammo_box/magazine/pistolm9mm, + /obj/item/ammo_box/magazine/m45/kitchengun, + /obj/item/ammo_box/magazine/m45/kitchengun) + crate_name = "crate" + +/datum/supply_pack/misc/dirtymags/fill(obj/structure/closet/crate/C) + var/list/L = contains.Copy() + for(var/i in 1 to num_contained) + var/item = pick_n_take(L) + new item(C) + ////////////////////////////////////////////////////////////////////////////// -//////////////////////////////// Misc Supplies /////////////////////////////// +///////////////////////////////// Misc Supplies ////////////////////////////// ////////////////////////////////////////////////////////////////////////////// +/datum/supply_pack/misc/candles + name = "Candle Crate" + desc = "Set up a romantic dinner or host a séance with these extra candles and crayons." + cost = 850 + contains = list(/obj/item/storage/fancy/candle_box, + /obj/item/storage/fancy/candle_box, + /obj/item/storage/box/matches) + crate_name = "candle crate" + +/datum/supply_pack/misc/diamondring + name = "Diamond Ring" + desc = "Show them your love is like a diamond: unbreakable and forever lasting. Shipped straight from child slave cartels in the space african mines." + cost = 10000 + contains = list(/obj/item/storage/fancy/ringbox/diamond) + crate_name = "diamond ring crate" + /datum/supply_pack/misc/exoticfootwear name = "Exotic Footwear Crate" desc = "Popularised by lizards and exotic dancers, the footwear included in this shipment is sure to give your feet the breathing room they deserve. Sweet Kicks Inc. is not responsible for any damage, distress, or @r0u$a1 caused by this shipment." @@ -246,13 +291,34 @@ /obj/item/clothing/shoes/kindleKicks) crate_name = "footie crate" -/datum/supply_pack/misc/wrapping_paper - name = "Festive Wrapping Paper Crate" - desc = "Want to mail your loved ones gift-wrapped chocolates, stuffed animals, or the Clown's severed head? You can do all that, with this crate full of wrapping paper." - cost = 1000 - contains = list(/obj/item/stack/wrapping_paper) - crate_type = /obj/structure/closet/crate/wooden - crate_name = "festive wrapping paper crate" +/datum/supply_pack/misc/funeral + name = "Funeral Supplies" + desc = "Mourn your dead properly buy sending them off with love filled notes, clean clothes, and a proper ceremony. Contains two candle packs, funeral garb, flowers, a paperbin , and crayons to help aid in religious rituals. Coffin included." + cost = 1200 + contains = list(/obj/item/clothing/under/burial, + /obj/item/storage/fancy/candle_box, + /obj/item/storage/fancy/candle_box, + /obj/item/reagent_containers/food/snacks/grown/harebell, + /obj/item/reagent_containers/food/snacks/grown/harebell, + /obj/item/reagent_containers/food/snacks/grown/poppy/geranium, + /obj/item/reagent_containers/food/snacks/grown/poppy/geranium, + /obj/item/reagent_containers/food/snacks/grown/poppy/lily, + /obj/item/reagent_containers/food/snacks/grown/poppy/lily, + /obj/item/storage/crayons, + /obj/item/paper_bin + ) + crate_name = "coffin" + crate_type = /obj/structure/closet/crate/coffin + +/datum/supply_pack/misc/jewelry + name = "Jewelry Crate" + desc = "Bling out with this crate of jewelry. Includes gold necklace and a set of two rings." + cost = 5000 + contains = list(/obj/item/clothing/neck/necklace/dope, + /obj/item/storage/fancy/ringbox, + /obj/item/storage/fancy/ringbox/silver + ) + crate_name = "jewelry crate" /datum/supply_pack/misc/jukebox name = "Jukebox" @@ -260,6 +326,16 @@ contains = list(/obj/machinery/jukebox) crate_name = "Jukebox" +/datum/supply_pack/misc/abandonedcrate + name = "Loot Box" + desc = "Try your luck with these highly secure loot boxes! Solve the lock, win great prizes! WARNING: EXPLOSIVE FAILURE." + contraband = TRUE + cost = 15000 + contains = list(/obj/structure/closet/crate/secure/loot) + crate_name = "abandoned crate" + crate_type = /obj/structure/closet/crate/large + dangerous = TRUE + /datum/supply_pack/misc/potted_plants name = "Potted Plants Crate" desc = "Spruce up the station with these lovely plants! Contains a random assortment of five potted plants from Nanotrasen's potted plant research division. Warranty void if thrown." @@ -284,25 +360,6 @@ /obj/item/clothing/suit/hooded/chaplain_hoodie) crate_name = "religious supplies crate" -/datum/supply_pack/misc/funeral - name = "Funeral Supplies" - desc = "Mourn your dead properly buy sending them off with love filled notes, clean clothes, and a proper ceremony. Contains two candle packs, funeral garb, flowers, a paperbin , and crayons to help aid in religious rituals. Coffin included." - cost = 1200 - contains = list(/obj/item/clothing/under/burial, - /obj/item/storage/fancy/candle_box, - /obj/item/storage/fancy/candle_box, - /obj/item/reagent_containers/food/snacks/grown/harebell, - /obj/item/reagent_containers/food/snacks/grown/harebell, - /obj/item/reagent_containers/food/snacks/grown/poppy/geranium, - /obj/item/reagent_containers/food/snacks/grown/poppy/geranium, - /obj/item/reagent_containers/food/snacks/grown/poppy/lily, - /obj/item/reagent_containers/food/snacks/grown/poppy/lily, - /obj/item/storage/crayons, - /obj/item/paper_bin - ) - crate_name = "coffin" - crate_type = /obj/structure/closet/crate/coffin - /datum/supply_pack/misc/shower name = "Shower Supplies" desc = "Everyone needs a bit of R&R. Make sure you get can get yours by ordering this crate filled with towels, rubber duckies, and some soap!" @@ -362,29 +419,6 @@ /obj/item/stack/tile/carpet/monochrome/fifty) crate_name = "premium carpet crate" -/datum/supply_pack/misc/party - name = "Party Equipment" - desc = "Celebrate both life and death on the station with Nanotrasen's Party Essentials(tm)! Contains seven colored glowsticks, four beers, two ales, a drinking shaker, and a bottle of patron & goldschlager!" - cost = 2000 - contains = list(/obj/item/storage/box/drinkingglasses, - /obj/item/reagent_containers/food/drinks/shaker, - /obj/item/reagent_containers/food/drinks/bottle/patron, - /obj/item/reagent_containers/food/drinks/bottle/goldschlager, - /obj/item/reagent_containers/food/drinks/ale, - /obj/item/reagent_containers/food/drinks/ale, - /obj/item/reagent_containers/food/drinks/beer, - /obj/item/reagent_containers/food/drinks/beer, - /obj/item/reagent_containers/food/drinks/beer, - /obj/item/reagent_containers/food/drinks/beer, - /obj/item/flashlight/glowstick, - /obj/item/flashlight/glowstick/red, - /obj/item/flashlight/glowstick/blue, - /obj/item/flashlight/glowstick/cyan, - /obj/item/flashlight/glowstick/orange, - /obj/item/flashlight/glowstick/yellow, - /obj/item/flashlight/glowstick/pink) - crate_name = "party equipment crate" - /datum/supply_pack/misc/noslipfloor name = "High-traction Floor Tiles" desc = "Make slipping a thing of the past with sixty industrial-grade anti-slip floortiles!" diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm index dd0f987d25..4aa991fc3f 100644 --- a/code/modules/cargo/packs/organic.dm +++ b/code/modules/cargo/packs/organic.dm @@ -3,22 +3,47 @@ // If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal // cost = 700- Minimum cost, or infinite points are possible. ////////////////////////////////////////////////////////////////////////////// -//////////////////////////// Organic ///////////////////////////////////////// +//////////////////////////////// Organic ///////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// /datum/supply_pack/organic group = "Food & Hydroponics" crate_type = /obj/structure/closet/crate/freezer +/datum/supply_pack/organic/randomized + var/num_contained = 15 + +/datum/supply_pack/organic/randomized/fill(obj/structure/closet/crate/C) + for(var/i in 1 to num_contained) + var/item = pick(contains) + new item(C) + ////////////////////////////////////////////////////////////////////////////// -/////////////////////////////// Food ///////////////////////////////////////// +//////////////////////////////// Meals /////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -/datum/supply_pack/organic/candy/randomised +/datum/supply_pack/organic/combomeal2 + name = "Burger Combo #2" + desc = "We value our customers at the Greasy Griddle, so much so that we're willing to deliver -just for you.- This combo meal contains two burgers, a soda, fries, a toy, and some chicken nuggets." + cost = 3200 + contains = list(/obj/item/reagent_containers/food/snacks/burger/bigbite, + /obj/item/reagent_containers/food/snacks/burger/cheese, + /obj/item/reagent_containers/food/snacks/fries, + /obj/item/reagent_containers/food/condiment/pack/ketchup, + /obj/item/reagent_containers/food/condiment/pack/ketchup, + /obj/item/reagent_containers/food/snacks/nugget, + /obj/item/reagent_containers/food/snacks/nugget, + /obj/item/reagent_containers/food/snacks/nugget, + /obj/item/reagent_containers/food/snacks/nugget, + /obj/item/toy/plush/random) + crate_name = "combo meal w/toy" + crate_type = /obj/structure/closet/crate/wooden + +/datum/supply_pack/organic/randomized/candy name = "Candy Crate" desc = "For people that have an insatiable sweet tooth! Has ten candies to be eaten up.." cost = 2500 - var/num_contained = 10 //number of items picked to be contained in a randomised crate + num_contained = 10 contains = list(/obj/item/reagent_containers/food/snacks/candy, /obj/item/reagent_containers/food/snacks/lollipop, /obj/item/reagent_containers/food/snacks/gumball, @@ -47,91 +72,6 @@ /obj/item/storage/fancy/donut_box) crate_name = "candy crate" -/datum/supply_pack/organic/randomized/chef - name = "Excellent Meat Crate" - desc = "The best cuts in the whole galaxy." - cost = 2000 - contains = list(/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime, - /obj/item/reagent_containers/food/snacks/meat/slab/killertomato, - /obj/item/reagent_containers/food/snacks/meat/slab/bear, - /obj/item/reagent_containers/food/snacks/meat/slab/xeno, - /obj/item/reagent_containers/food/snacks/meat/slab/spider, - /obj/item/reagent_containers/food/snacks/meat/rawbacon, - /obj/item/reagent_containers/food/snacks/spiderleg, - /obj/item/reagent_containers/food/snacks/carpmeat, - /obj/item/reagent_containers/food/snacks/meat/slab/human) - crate_name = "food crate" - -/datum/supply_pack/organic/randomized/chef/fill(obj/structure/closet/crate/C) - for(var/i in 1 to 15) - var/item = pick(contains) - new item(C) - -/datum/supply_pack/organic/exoticseeds - name = "Exotic Seeds Crate" - desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!" - cost = 1500 - contains = list(/obj/item/seeds/nettle, - /obj/item/seeds/replicapod, - /obj/item/seeds/replicapod, - /obj/item/seeds/replicapod, - /obj/item/seeds/plump, - /obj/item/seeds/liberty, - /obj/item/seeds/amanita, - /obj/item/seeds/reishi, - /obj/item/seeds/banana, - /obj/item/seeds/bamboo, - /obj/item/seeds/eggplant/eggy, - /obj/item/seeds/random, - /obj/item/seeds/random) - crate_name = "exotic seeds crate" - crate_type = /obj/structure/closet/crate/hydroponics - -/datum/supply_pack/organic/food - name = "Food Crate" - desc = "Get things cooking with this crate full of useful ingredients! Contains a two dozen eggs, three bananas, and two bags of flour and rice, two cartons of milk, soymilk, as well as salt and pepper shakers, an enzyme and sugar bottle, and three slabs of monkeymeat." - cost = 1000 - contains = list(/obj/item/reagent_containers/food/condiment/flour, - /obj/item/reagent_containers/food/condiment/flour, - /obj/item/reagent_containers/food/condiment/rice, - /obj/item/reagent_containers/food/condiment/rice, - /obj/item/reagent_containers/food/condiment/milk, - /obj/item/reagent_containers/food/condiment/milk, - /obj/item/reagent_containers/food/condiment/soymilk, - /obj/item/reagent_containers/food/condiment/saltshaker, - /obj/item/reagent_containers/food/condiment/peppermill, - /obj/item/storage/fancy/egg_box, - /obj/item/storage/fancy/egg_box, - /obj/item/reagent_containers/food/condiment/enzyme, - /obj/item/reagent_containers/food/condiment/sugar, - /obj/item/reagent_containers/food/snacks/meat/slab/monkey, - /obj/item/reagent_containers/food/snacks/meat/slab/monkey, - /obj/item/reagent_containers/food/snacks/meat/slab/monkey, - /obj/item/reagent_containers/food/snacks/grown/banana, - /obj/item/reagent_containers/food/snacks/grown/banana, - /obj/item/reagent_containers/food/snacks/grown/banana) - crate_name = "food crate" - -/datum/supply_pack/organic/randomized/chef/fruits - name = "Fruit Crate" - desc = "Rich in vitamins, may contain oranges." - cost = 1500 - contains = list(/obj/item/reagent_containers/food/snacks/grown/citrus/lime, - /obj/item/reagent_containers/food/snacks/grown/citrus/orange, - /obj/item/reagent_containers/food/snacks/grown/banana, - /obj/item/reagent_containers/food/snacks/grown/watermelon, - /obj/item/reagent_containers/food/snacks/grown/apple, - /obj/item/reagent_containers/food/snacks/grown/berries, - /obj/item/reagent_containers/food/snacks/grown/citrus/lemon, - /obj/item/reagent_containers/food/snacks/grown/pineapple, - /obj/item/reagent_containers/food/snacks/grown/cherries, - /obj/item/reagent_containers/food/snacks/grown/grapes, - /obj/item/reagent_containers/food/snacks/grown/grapes/green, - /obj/item/reagent_containers/food/snacks/grown/eggplant, - /obj/item/reagent_containers/food/snacks/grown/peach, - /obj/item/reagent_containers/food/snacks/grown/strawberry) - crate_name = "food crate" - /datum/supply_pack/organic/fiestatortilla name = "Fiesta Crate" desc = "Spice up the kitchen with this fiesta themed food order! Contains 8 tortilla based food items, as well as a sombrero, moustache, and cloak!" @@ -151,79 +91,6 @@ /obj/item/reagent_containers/glass/bottle/capsaicin) crate_name = "fiesta crate" -/datum/supply_pack/organic/grill - name = "Grilling Starter Kit" - desc = "Hey dad I'm Hungry. Hi Hungry I'm THE NEW GRILLING STARTER KIT ONLY 5000 BUX GET NOW! Contains a cooking grill and five fuel coal sheets." - cost = 3000 - crate_type = /obj/structure/closet/crate - contains = list(/obj/item/stack/sheet/mineral/coal/five, - /obj/machinery/grill/unwrenched) - crate_name = "grilling starter kit crate" - -/datum/supply_pack/organic/grillfuel - name = "Grilling Fuel Kit" - desc = "Contains coal and coal accessories. (Note: only ten coal sheets.)" - cost = 1000 - crate_type = /obj/structure/closet/crate - contains = list(/obj/item/stack/sheet/mineral/coal/ten) - crate_name = "grilling fuel kit crate" - -/datum/supply_pack/organic/cream_piee - name = "High-yield Clown-grade Cream Pie Crate" - desc = "Designed by Aussec's Advanced Warfare Research Division, these high-yield, Clown-grade cream pies are powered by a synergy of performance and efficiency. Guaranteed to provide maximum results." - cost = 6000 - contains = list(/obj/item/storage/backpack/duffelbag/clown/cream_pie) - crate_name = "party equipment crate" - contraband = TRUE - access = ACCESS_THEATRE - crate_type = /obj/structure/closet/crate/secure - -/datum/supply_pack/organic/fakemeat - name = "Meat Crate" - desc = "Run outta meat already? Keep the lizards content with this freezer filled with cruelty-free chemically compounded meat! Contains 12 slabs of meat product, and 4 slabs of *carp*." - cost = 1200 // Buying 3 food crates nets you 9 meat for 900 points, plus like, 6 bags of rice, flour, and egg boxes. This is 12 for 500, but you -only- get meat and carp. - contains = list(/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, - /obj/item/reagent_containers/food/snacks/carpmeat/imitation, - /obj/item/reagent_containers/food/snacks/carpmeat/imitation, - /obj/item/reagent_containers/food/snacks/carpmeat/imitation, - /obj/item/reagent_containers/food/snacks/carpmeat/imitation) - crate_name = "meaty crate" - crate_type = /obj/structure/closet/crate/freezer - -/datum/supply_pack/organic/monkeydripmeat - name = "*Meat* Crate" - desc = "Need some meat? With this do-it-yourself kit you'll be swimming in it! Contains a monkey cube, an IV drip, and some cryoxadone!" - cost = 2150 - contraband = TRUE - contains = list(/obj/item/reagent_containers/food/snacks/monkeycube, - /obj/item/restraints/handcuffs/cable, - /obj/machinery/iv_drip, - /obj/item/reagent_containers/glass/beaker/cryoxadone, - /obj/item/reagent_containers/glass/beaker/cryoxadone) - crate_name = "monkey meat crate" - -/datum/supply_pack/organic/mixedboxes - name = "Mixed Ingredient Boxes" - desc = "Get overwhelmed with inspiration by ordering these boxes of surprise ingredients! Get four boxes filled with an assortment of products!" - cost = 2300 - contains = list(/obj/item/storage/box/ingredients/wildcard, - /obj/item/storage/box/ingredients/wildcard, - /obj/item/storage/box/ingredients/wildcard, - /obj/item/storage/box/ingredients/wildcard) - crate_name = "wildcard food crate" - crate_type = /obj/structure/closet/crate/freezer - /datum/supply_pack/organic/pizza name = "Pizza Crate" desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!" @@ -258,9 +125,129 @@ considered \[REDACTED\] and returned at your leisure. Note that objects the anomaly produces are specifically attuned exactly to the individual opening the anomaly; regardless \ of species, the individual will find the object edible and it will taste great according to their personal definitions, which vary significantly based on person and species.") -/datum/supply_pack/organic/randomized/chef/vegetables - name = "Vegetables Crate" - desc = "Grown in vats." +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Raw Ingredients ///////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_pack/organic/food + name = "Food Crate" + desc = "Get things cooking with this crate full of useful ingredients! Contains a two dozen eggs, three bananas, and two bags of flour and rice, two cartons of milk, soymilk, as well as salt and pepper shakers, an enzyme and sugar bottle, and three slabs of monkeymeat." + cost = 1000 + contains = list(/obj/item/reagent_containers/food/condiment/flour, + /obj/item/reagent_containers/food/condiment/flour, + /obj/item/reagent_containers/food/condiment/rice, + /obj/item/reagent_containers/food/condiment/rice, + /obj/item/reagent_containers/food/condiment/milk, + /obj/item/reagent_containers/food/condiment/milk, + /obj/item/reagent_containers/food/condiment/soymilk, + /obj/item/reagent_containers/food/condiment/saltshaker, + /obj/item/reagent_containers/food/condiment/peppermill, + /obj/item/storage/fancy/egg_box, + /obj/item/storage/fancy/egg_box, + /obj/item/reagent_containers/food/condiment/enzyme, + /obj/item/reagent_containers/food/condiment/sugar, + /obj/item/reagent_containers/food/snacks/meat/slab/monkey, + /obj/item/reagent_containers/food/snacks/meat/slab/monkey, + /obj/item/reagent_containers/food/snacks/meat/slab/monkey, + /obj/item/reagent_containers/food/snacks/grown/banana, + /obj/item/reagent_containers/food/snacks/grown/banana, + /obj/item/reagent_containers/food/snacks/grown/banana) + crate_name = "food crate" + +/datum/supply_pack/organic/randomized/fruits + name = "Fruit Crate" + desc = "Rich in vitamins and possibly sugar. Contains 15 assorted fruits." + cost = 1500 + contains = list(/obj/item/reagent_containers/food/snacks/grown/citrus/lime, + /obj/item/reagent_containers/food/snacks/grown/citrus/orange, + /obj/item/reagent_containers/food/snacks/grown/banana, + /obj/item/reagent_containers/food/snacks/grown/watermelon, + /obj/item/reagent_containers/food/snacks/grown/apple, + /obj/item/reagent_containers/food/snacks/grown/berries, + /obj/item/reagent_containers/food/snacks/grown/citrus/lemon, + /obj/item/reagent_containers/food/snacks/grown/pineapple, + /obj/item/reagent_containers/food/snacks/grown/cherries, + /obj/item/reagent_containers/food/snacks/grown/grapes, + /obj/item/reagent_containers/food/snacks/grown/grapes/green, + /obj/item/reagent_containers/food/snacks/grown/eggplant, + /obj/item/reagent_containers/food/snacks/grown/peach, + /obj/item/reagent_containers/food/snacks/grown/strawberry) + crate_name = "fruit crate" + +/datum/supply_pack/organic/cream_piee + name = "High-yield Clown-grade Cream Pie Crate" + desc = "Designed by Aussec's Advanced Warfare Research Division, these high-yield, Clown-grade cream pies are powered by a synergy of performance and efficiency. Guaranteed to provide maximum results." + cost = 6000 + contains = list(/obj/item/storage/backpack/duffelbag/clown/cream_pie) + crate_name = "party equipment crate" + contraband = TRUE + access = ACCESS_THEATRE + crate_type = /obj/structure/closet/crate/secure + +/datum/supply_pack/organic/randomized + name = "Meat Crate (Exotic)" + desc = "The best cuts in the whole galaxy. Contains 15 assorted exotic meats." + cost = 2000 + contains = list(/obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime, + /obj/item/reagent_containers/food/snacks/meat/slab/killertomato, + /obj/item/reagent_containers/food/snacks/meat/slab/bear, + /obj/item/reagent_containers/food/snacks/meat/slab/xeno, + /obj/item/reagent_containers/food/snacks/meat/slab/spider, + /obj/item/reagent_containers/food/snacks/meat/rawbacon, + /obj/item/reagent_containers/food/snacks/spiderleg, + /obj/item/reagent_containers/food/snacks/carpmeat, + /obj/item/reagent_containers/food/snacks/meat/slab/human) + crate_name = "exotic meat crate" + +/datum/supply_pack/organic/monkeydripmeat + name = "Meat Crate (Fresh)" + desc = "Need some meat? With this do-it-yourself kit you'll be swimming in it! Contains a monkey cube, an IV drip, and some cryoxadone!" + cost = 2150 + contraband = TRUE + contains = list(/obj/item/reagent_containers/food/snacks/monkeycube, + /obj/item/restraints/handcuffs/cable, + /obj/machinery/iv_drip, + /obj/item/reagent_containers/glass/beaker/cryoxadone, + /obj/item/reagent_containers/glass/beaker/cryoxadone) + crate_name = "monkey meat crate" + +/datum/supply_pack/organic/fakemeat + name = "Meat Crate 'Synthetic'" + desc = "Run outta meat already? Keep the lizards content with this freezer filled with cruelty-free chemically compounded meat! Contains 12 slabs of meat product, and 4 slabs of *carp*." + cost = 1200 // Buying 3 food crates nets you 9 meat for 900 points, plus like, 6 bags of rice, flour, and egg boxes. This is 12 for 500, but you -only- get meat and carp. + contains = list(/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct, + /obj/item/reagent_containers/food/snacks/carpmeat/imitation, + /obj/item/reagent_containers/food/snacks/carpmeat/imitation, + /obj/item/reagent_containers/food/snacks/carpmeat/imitation, + /obj/item/reagent_containers/food/snacks/carpmeat/imitation) + crate_name = "meaty crate" + crate_type = /obj/structure/closet/crate/freezer + +/datum/supply_pack/organic/mixedboxes + name = "Mixed Ingredient Boxes" + desc = "Get overwhelmed with inspiration by ordering these boxes of surprise ingredients! Get four boxes filled with an assortment of products!" + cost = 2300 + contains = list(/obj/item/storage/box/ingredients/wildcard, + /obj/item/storage/box/ingredients/wildcard, + /obj/item/storage/box/ingredients/wildcard, + /obj/item/storage/box/ingredients/wildcard) + crate_name = "wildcard food crate" + crate_type = /obj/structure/closet/crate/freezer + +/datum/supply_pack/organic/randomized/vegetables + name = "Vegetable Crate" + desc = "Grown in vats. Contains 15 assorted vegetables." cost = 1300 contains = list(/obj/item/reagent_containers/food/snacks/grown/chili, /obj/item/reagent_containers/food/snacks/grown/corn, @@ -270,7 +257,7 @@ /obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle, /obj/item/reagent_containers/food/snacks/grown/onion, /obj/item/reagent_containers/food/snacks/grown/pumpkin) - crate_name = "food crate" + crate_name = "veggie crate" ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Hydroponics ///////////////////////////////////// @@ -302,42 +289,6 @@ crate_name = "beekeeping starter crate" crate_type = /obj/structure/closet/crate/hydroponics -/datum/supply_pack/organic/exoticseeds - name = "Exotic Seeds Crate" - desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!" - cost = 1500 - contains = list(/obj/item/seeds/nettle, - /obj/item/seeds/replicapod, - /obj/item/seeds/replicapod, - /obj/item/seeds/replicapod, - /obj/item/seeds/plump, - /obj/item/seeds/liberty, - /obj/item/seeds/amanita, - /obj/item/seeds/reishi, - /obj/item/seeds/banana, - /obj/item/seeds/eggplant/eggy, - /obj/item/seeds/random, - /obj/item/seeds/random) - crate_name = "exotic seeds crate" - crate_type = /obj/structure/closet/crate/hydroponics - -/* Maintenance Garden Crate basically does this and more. -/datum/supply_pack/organic/hydroponics - name = "Hydroponics Crate" - desc = "Supplies for growing a great garden! Contains two bottles of ammonia, two Plant-B-Gone spray bottles, a hatchet, cultivator, plant analyzer, as well as a pair of leather gloves and a botanist's apron." - cost = 1750 - contains = list(/obj/item/reagent_containers/spray/plantbgone, - /obj/item/reagent_containers/spray/plantbgone, - /obj/item/reagent_containers/glass/bottle/ammonia, - /obj/item/reagent_containers/glass/bottle/ammonia, - /obj/item/hatchet, - /obj/item/cultivator, - /obj/item/plant_analyzer, - /obj/item/clothing/gloves/botanic_leather, - /obj/item/clothing/suit/apron) - crate_name = "hydroponics crate" - crate_type = /obj/structure/closet/crate/hydroponics -*/ /datum/supply_pack/organic/hydroponics/hydrotank name = "Hydroponics Backpack Crate" desc = "Bring on the flood with this high-capacity backpack crate. Contains 500 units of life-giving H2O. Requires hydroponics access to open." @@ -390,10 +341,30 @@ /obj/item/seeds/sunflower, /obj/item/seeds/chanter, /obj/item/seeds/potato, - /obj/item/seeds/sugarcane) + /obj/item/seeds/sugarcane, + /obj/item/seeds/ambrosia) crate_name = "seeds crate" crate_type = /obj/structure/closet/crate/hydroponics +/datum/supply_pack/organic/exoticseeds + name = "Seeds Crate (Exotic)" + desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!" + cost = 1500 + contains = list(/obj/item/seeds/nettle, + /obj/item/seeds/replicapod, + /obj/item/seeds/replicapod, + /obj/item/seeds/replicapod, + /obj/item/seeds/plump, + /obj/item/seeds/liberty, + /obj/item/seeds/amanita, + /obj/item/seeds/reishi, + /obj/item/seeds/banana, + /obj/item/seeds/eggplant/eggy, + /obj/item/seeds/random, + /obj/item/seeds/random) + crate_name = "exotic seeds crate" + crate_type = /obj/structure/closet/crate/hydroponics + ////////////////////////////////////////////////////////////////////////////// /////////////////////////////////// Misc ///////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -414,6 +385,29 @@ crate_name = "sporting crate" crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:( +/datum/supply_pack/organic/party + name = "Party Equipment" + desc = "Celebrate both life and death on the station with Nanotrasen's Party Essentials(tm)! Contains seven colored glowsticks, four beers, two ales, a drinking shaker, and a bottle of patron & goldschlager!" + cost = 2000 + contains = list(/obj/item/storage/box/drinkingglasses, + /obj/item/reagent_containers/food/drinks/shaker, + /obj/item/reagent_containers/food/drinks/bottle/patron, + /obj/item/reagent_containers/food/drinks/bottle/goldschlager, + /obj/item/reagent_containers/food/drinks/ale, + /obj/item/reagent_containers/food/drinks/ale, + /obj/item/reagent_containers/food/drinks/beer, + /obj/item/reagent_containers/food/drinks/beer, + /obj/item/reagent_containers/food/drinks/beer, + /obj/item/reagent_containers/food/drinks/beer, + /obj/item/flashlight/glowstick, + /obj/item/flashlight/glowstick/red, + /obj/item/flashlight/glowstick/blue, + /obj/item/flashlight/glowstick/cyan, + /obj/item/flashlight/glowstick/orange, + /obj/item/flashlight/glowstick/yellow, + /obj/item/flashlight/glowstick/pink) + crate_name = "party equipment crate" + /datum/supply_pack/organic/vday name = "Surplus Valentine Crate" desc = "Turns out we got warehouses of this love-y dove-y crap. We're sending out small bargain buddle of Valentine gear. This crate has two boxes of chocolate, three poppy flowers, five candy hearts, and three cards." diff --git a/code/modules/cargo/packs/science.dm b/code/modules/cargo/packs/science.dm index f14bc37371..79675cf3ec 100644 --- a/code/modules/cargo/packs/science.dm +++ b/code/modules/cargo/packs/science.dm @@ -24,13 +24,12 @@ name = "Advanced Alien Alloy Crate Crate" desc = "Hello brothers from the stars!!! Our fellow brethren have made contact at long last and gave us gifts man! They really did build the prymi- Connection Error- Bro we’ll send you a sheet of advanced alien alloy." cost = 15000 - contraband = TRUE DropPodOnly = TRUE contains = list(/obj/item/stack/sheet/mineral/abductor) crate_name = "alien bro alloy crate" /datum/supply_pack/science/beakers - name = "Chemistry Beackers Crate" + name = "Chemistry Beakers Crate" desc = "Glassware for any chemistry lab! Contains four small beakers, three large, two plastic, and one metamaterial. As well as three droppers and two pairs of latex gloves." cost = 1500 contains = list(/obj/item/reagent_containers/glass/beaker, @@ -82,6 +81,16 @@ /obj/item/integrated_electronics/wirer) crate_name = "circuitry starter pack crate" +/datum/supply_pack/science/glasswork + name = "Glass Blower Kit Crate" + desc = "Learn and make glassworks of usefull things for a profit! Contains glassworking tools and blowing rods. Glass not included." + cost = 1000 + contains = list(/obj/item/glasswork/glasskit, + /obj/item/glasswork/glasskit, + /obj/item/glasswork/blowing_rod, + /obj/item/glasswork/blowing_rod) + crate_name = "glassblower gear crate" + /datum/supply_pack/science/monkey name = "Monkey Cube Crate" desc = "Stop monkeying around! Contains seven monkey cubes. Just add water!" diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index 69967d65d1..3b602d54d2 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -163,13 +163,6 @@ /obj/item/storage/box/handcuffs) crate_name = "security supply crate" -/datum/supply_pack/security/vending/security - name = "SecTech Supply Crate" - desc = "Officer Paul bought all the donuts? Then refill the security vendor with ths crate." - cost = 1500 - contains = list(/obj/machinery/vending/security) - crate_name = "SecTech supply crate" - /datum/supply_pack/security/firingpins name = "Standard Firing Pins Crate" desc = "Upgrade your arsenal with 10 standard firing pins. Requires Security access to open." diff --git a/code/modules/cargo/packs/service.dm b/code/modules/cargo/packs/service.dm index 01524b1910..942720dd6b 100644 --- a/code/modules/cargo/packs/service.dm +++ b/code/modules/cargo/packs/service.dm @@ -10,9 +10,24 @@ group = "Service" ////////////////////////////////////////////////////////////////////////////// -/////////////////////////////// Cargo //////////////////////////////////////// +//////////////////////////////// Cargo /////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// +/datum/supply_pack/service/wrapping_paper + name = "Cargo Packaging Crate" + desc = "Want to mail your loved ones gift-wrapped chocolates, stuffed animals, or the Clown's severed head? You can do all that, with this crate full of festive (and normal) wrapping paper. Also contains a hand labeler and a destination tagger for easy shipping!" + cost = 1000 + contains = list(/obj/item/stack/wrapping_paper, + /obj/item/stack/wrapping_paper, + /obj/item/stack/wrapping_paper, + /obj/item/stack/packageWrap, + /obj/item/stack/packageWrap, + /obj/item/stack/packageWrap, + /obj/item/destTagger, + /obj/item/hand_labeler) + crate_type = /obj/structure/closet/crate/wooden + crate_name = "wrapping paper crate" + /datum/supply_pack/service/cargo_supples name = "Cargo Supplies Crate" desc = "Sold everything that wasn't bolted down? You can get right back to work with this crate containing stamps, an export scanner, destination tagger, hand labeler and some package wrapping. Now with extra toner cartidges!" @@ -101,6 +116,23 @@ crate_name = "ice cream vat crate" crate_type = /obj/structure/closet/crate +/datum/supply_pack/service/grill + name = "Grilling Starter Kit" + desc = "Hey dad I'm Hungry. Hi Hungry I'm THE NEW GRILLING STARTER KIT ONLY 5000 BUX GET NOW! Contains a cooking grill and five fuel coal sheets." + cost = 3000 + contains = list(/obj/item/stack/sheet/mineral/coal/five, + /obj/machinery/grill/unwrenched) + crate_name = "grilling starter kit crate" + crate_type = /obj/structure/closet/crate + +/datum/supply_pack/service/grillfuel + name = "Grilling Fuel Kit" + desc = "Contains coal and coal accessories. (Note: only ten coal sheets.)" + cost = 1000 + contains = list(/obj/item/stack/sheet/mineral/coal/ten) + crate_name = "grilling fuel kit crate" + crate_type = /obj/structure/closet/crate + /datum/supply_pack/service/cutlery name = "Kitchen Cutlery Deluxe Set" desc = "Need to slice and dice away those \"Tomatoes\"? Well we got what you need! From a nice set of knifes, forks, plates, glasses, and a whetstone for when you got some grizzle that is a bit harder to slice then normal." @@ -115,7 +147,7 @@ /obj/item/kitchen/knife, /obj/item/kitchen/knife/butcher, /obj/item/kitchen/knife/butcher, - /obj/item/kitchen/rollingpin, + /obj/item/kitchen/rollingpin, /obj/item/trash/plate, /obj/item/trash/plate, /obj/item/trash/plate, @@ -240,45 +272,3 @@ crate_name = "janitorial cart crate" crate_type = /obj/structure/closet/crate/large -////////////////////////////////////////////////////////////////////////////// -//////////////////////////// Vendor Refills ////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -/datum/supply_pack/service/vending/bartending - name = "Bartending Supply Crate" - desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!" - cost = 2000 - contains = list(/obj/item/vending_refill/boozeomat, - /obj/item/vending_refill/coffee, - /obj/item/book/granter/action/drink_fling) - crate_name = "bartending supply crate" - -/datum/supply_pack/service/vending/cigarette - name = "Cigarette Supply Crate" - desc = "Don't believe the reports - smoke today! Contains a cigarette vending machine refill." - cost = 1500 - contains = list(/obj/item/vending_refill/cigarette) - crate_name = "cigarette supply crate" - crate_type = /obj/structure/closet/crate - -/datum/supply_pack/service/vending/games - name = "Games Supply Crate" - desc = "Get your game on with this game vending machine refill." - cost = 1000 - contains = list(/obj/item/vending_refill/games) - crate_name = "games supply crate" - crate_type = /obj/structure/closet/crate - -/datum/supply_pack/service/vending/snack - name = "Snack Supply Crate" - desc = "One vending machine refill of cavity-bringin' goodness! The number one dentist recommended order!" - cost = 1500 - contains = list(/obj/item/vending_refill/snack) - crate_name = "snacks supply crate" - -/datum/supply_pack/service/vending/cola - name = "Softdrinks Supply Crate" - desc = "Got whacked by a toolbox, but you still have those pesky teeth? Get rid of those pearly whites with this soda machine refill, today!" - cost = 1500 - contains = list(/obj/item/vending_refill/cola) - crate_name = "soft drinks supply crate" diff --git a/code/modules/cargo/packs/vending.dm b/code/modules/cargo/packs/vending.dm new file mode 100644 index 0000000000..f9982d17b6 --- /dev/null +++ b/code/modules/cargo/packs/vending.dm @@ -0,0 +1,148 @@ + +//Reminders- +// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal +// cost = 700- Minimum cost, or infinite points are possible. +////////////////////////////////////////////////////////////////////////////// +/////////////////////////////// Vending ////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_pack/vending + group = "Vending" + +////////////////////////////////////////////////////////////////////////////// +///////////////////////// Service, Medical, Sec ////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_pack/vending/bartending + name = "Bartending Supply Crate" + desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!" + cost = 2000 + contains = list(/obj/item/vending_refill/boozeomat, + /obj/item/vending_refill/coffee, + /obj/item/book/granter/action/drink_fling) + crate_name = "bartending supply crate" + +/datum/supply_pack/vending/cigarette + name = "Cigarette Supply Crate" + desc = "Don't believe the reports - smoke today! Contains a cigarette vending machine refill." + cost = 1500 + contains = list(/obj/item/vending_refill/cigarette) + crate_name = "cigarette supply crate" + crate_type = /obj/structure/closet/crate + +/datum/supply_pack/vending/games + name = "Games Supply Crate" + desc = "Get your game on with this game vending machine refill." + cost = 1000 + contains = list(/obj/item/vending_refill/games) + crate_name = "games supply crate" + crate_type = /obj/structure/closet/crate + +/datum/supply_pack/vending/kinkmate + name = "Kinkmate Supply and Construction Kit" + cost = 2000 + contraband = TRUE + contains = list(/obj/item/vending_refill/kink, /obj/item/circuitboard/machine/kinkmate) + crate_name = "Kinkmate construction kit" + +/datum/supply_pack/vending/medical + name = "Medical Vending Crate" + desc = "Contains refills for medical vending machines." + cost = 2000 + contains = list(/obj/item/vending_refill/medical, + /obj/item/vending_refill/wallmed) + crate_name = "medical vending crate" + crate_type = /obj/structure/closet/crate/medical + +/datum/supply_pack/vending/security + name = "SecTech Supply Crate" + desc = "Officer Paul bought all the donuts? Then refill the security vendor with ths crate. Requires Security Access to open." + cost = 1500 + access = ACCESS_SECURITY + contains = list(/obj/machinery/vending/security) + crate_name = "SecTech supply crate" + crate_type = /obj/structure/closet/crate/secure/gear + +/datum/supply_pack/vending/snack + name = "Snack Supply Crate" + desc = "One vending machine refill of cavity-bringin' goodness! The number one dentist recommended order!" + cost = 1500 + contains = list(/obj/item/vending_refill/snack) + crate_name = "snacks supply crate" + +/datum/supply_pack/vending/cola + name = "Softdrinks Supply Crate" + desc = "Got whacked by a toolbox, but you still have those pesky teeth? Get rid of those pearly whites with this soda machine refill, today!" + cost = 1500 + contains = list(/obj/item/vending_refill/cola) + crate_name = "soft drinks supply crate" + +////////////////////////////////////////////////////////////////////////////// +//////////////////////////// Wardrobe Vendors //////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +/datum/supply_pack/vending/wardrobes/autodrobe + name = "Autodrobe Supply Crate" + desc = "Autodrobe missing your favorite dress? Solve that issue today with this autodrobe refill." + cost = 1500 + contains = list(/obj/item/vending_refill/autodrobe) + crate_name = "autodrobe supply crate" + +/datum/supply_pack/vending/wardrobes/cargo + name = "Cargo Wardrobe Supply Crate" + desc = "This crate contains a refill for the CargoDrobe." + cost = 750 + contains = list(/obj/item/vending_refill/wardrobe/cargo_wardrobe) + crate_name = "cargo department supply crate" + +/datum/supply_pack/vending/wardrobes/engineering + name = "Engineering Wardrobe Supply Crate" + desc = "This crate contains refills for the EngiDrobe and AtmosDrobe." + cost = 1500 + contains = list(/obj/item/vending_refill/wardrobe/engi_wardrobe, + /obj/item/vending_refill/wardrobe/atmos_wardrobe) + crate_name = "engineering department wardrobe supply crate" + +/datum/supply_pack/vending/wardrobes/general + name = "General Wardrobes Supply Crate" + desc = "This crate contains refills for the CuraDrobe, BarDrobe, ChefDrobe, JaniDrobe, ChapDrobe." + cost = 3750 + contains = list(/obj/item/vending_refill/wardrobe/curator_wardrobe, + /obj/item/vending_refill/wardrobe/bar_wardrobe, + /obj/item/vending_refill/wardrobe/chef_wardrobe, + /obj/item/vending_refill/wardrobe/jani_wardrobe, + /obj/item/vending_refill/wardrobe/chap_wardrobe) + crate_name = "general wardrobes vendor refills" + +/datum/supply_pack/vending/wardrobes/hydroponics + name = "Hydrobe Supply Crate" + desc = "This crate contains a refill for the Hydrobe." + cost = 750 + contains = list(/obj/item/vending_refill/wardrobe/hydro_wardrobe) + crate_name = "hydrobe supply crate" + +/datum/supply_pack/vending/wardrobes/medical + name = "Medical Wardrobe Supply Crate" + desc = "This crate contains refills for the MediDrobe, ChemDrobe, GeneDrobe, and ViroDrobe." + cost = 3000 + contains = list(/obj/item/vending_refill/wardrobe/medi_wardrobe, + /obj/item/vending_refill/wardrobe/chem_wardrobe, + /obj/item/vending_refill/wardrobe/gene_wardrobe, + /obj/item/vending_refill/wardrobe/viro_wardrobe) + crate_name = "medical department wardrobe supply crate" + +/datum/supply_pack/vending/wardrobes/science + name = "Science Wardrobe Supply Crate" + desc = "This crate contains refills for the SciDrobe and RoboDrobe." + cost = 1500 + contains = list(/obj/item/vending_refill/wardrobe/robo_wardrobe, + /obj/item/vending_refill/wardrobe/science_wardrobe) + crate_name = "science department wardrobe supply crate" + +/datum/supply_pack/vending/wardrobes/security + name = "Security Wardrobe Supply Crate" + desc = "This crate contains refills for the SecDrobe and LawDrobe." + cost = 1500 + contains = list(/obj/item/vending_refill/wardrobe/sec_wardrobe, + /obj/item/vending_refill/wardrobe/law_wardrobe) + crate_name = "security department supply crate" diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 7dc233d20f..902b442403 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -28,7 +28,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the //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) +/proc/send_asset(client/client, asset_name, verify = TRUE) if(!istype(client)) if(ismob(client)) var/mob/M = client @@ -72,7 +72,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the 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) +/proc/send_asset_list(client/client, list/asset_list, verify = TRUE) if(!istype(client)) if(ismob(client)) var/mob/M = client @@ -122,7 +122,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the //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) +/proc/getFilesSlow(client/client, list/files, register_asset = TRUE) var/concurrent_tracker = 1 for(var/file in files) if (!client) @@ -140,13 +140,13 @@ You can set verify to TRUE if you want send() to sleep until the client has the //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) +/proc/register_asset(asset_name, asset) SSassets.cache[asset_name] = asset //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(var/file) +/proc/generate_asset_name(file) return "asset.[md5(fcopy_rsc(file))]" @@ -156,7 +156,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the GLOBAL_LIST_EMPTY(asset_datums) //get an assetdatum or make a new one -/proc/get_asset_datum(var/type) +/proc/get_asset_datum(type) return GLOB.asset_datums[type] || new type() /datum/asset @@ -323,6 +323,13 @@ GLOBAL_LIST_EMPTY(asset_datums) 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 @@ -379,14 +386,24 @@ GLOBAL_LIST_EMPTY(asset_datums) /datum/asset/simple/tgui assets = list( - "tgui.css" = 'tgui/assets/tgui.css', - "tgui.js" = 'tgui/assets/tgui.js', - "font-awesome.min.css" = 'tgui/assets/font-awesome.min.css', - "fontawesome-webfont.eot" = 'tgui/assets/fonts/fontawesome-webfont.eot', - "fontawesome-webfont.woff2" = 'tgui/assets/fonts/fontawesome-webfont.woff2', - "fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff', - "fontawesome-webfont.ttf" = 'tgui/assets/fonts/fontawesome-webfont.ttf', - "fontawesome-webfont.svg" = 'tgui/assets/fonts/fontawesome-webfont.svg' + // tgui + "tgui.css" = 'tgui/assets/tgui.css', + "tgui.js" = 'tgui/assets/tgui.js', + // tgui-next + "tgui-main.html" = 'tgui-next/packages/tgui/public/tgui-main.html', + "tgui-fallback.html" = 'tgui-next/packages/tgui/public/tgui-fallback.html', + "tgui.bundle.js" = 'tgui-next/packages/tgui/public/tgui.bundle.js', + "tgui.bundle.css" = 'tgui-next/packages/tgui/public/tgui.bundle.css', + "shim-html5shiv.js" = 'tgui-next/packages/tgui/public/shim-html5shiv.js', + "shim-ie8.js" = 'tgui-next/packages/tgui/public/shim-ie8.js', + "shim-dom4.js" = 'tgui-next/packages/tgui/public/shim-dom4.js', + "shim-css-om.js" = 'tgui-next/packages/tgui/public/shim-css-om.js', + ) + +/datum/asset/group/tgui + children = list( + /datum/asset/simple/tgui, + /datum/asset/simple/fontawesome ) /datum/asset/simple/headers @@ -448,7 +465,8 @@ GLOBAL_LIST_EMPTY(asset_datums) "scanner" = 'icons/pda_icons/pda_scanner.png', "signaler" = 'icons/pda_icons/pda_signaler.png', "status" = 'icons/pda_icons/pda_status.png', - "dronephone" = 'icons/pda_icons/pda_dronephone.png' + "dronephone" = 'icons/pda_icons/pda_dronephone.png', + "emoji" = 'icons/pda_icons/pda_emoji.png' ) /datum/asset/spritesheet/simple/paper @@ -511,7 +529,7 @@ GLOBAL_LIST_EMPTY(asset_datums) "pill21" = 'icons/UI_Icons/Pills/pill21.png', "pill22" = 'icons/UI_Icons/Pills/pill22.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', @@ -550,7 +568,8 @@ GLOBAL_LIST_EMPTY(asset_datums) children = list( /datum/asset/simple/jquery, /datum/asset/simple/goonchat, - /datum/asset/spritesheet/goonchat + /datum/asset/spritesheet/goonchat, + /datum/asset/simple/fontawesome ) /datum/asset/simple/jquery @@ -563,18 +582,23 @@ GLOBAL_LIST_EMPTY(asset_datums) verify = FALSE assets = list( "json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js', - "errorHandler.js" = 'code/modules/goonchat/browserassets/js/errorHandler.js', "browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js', - "fontawesome-webfont.eot" = 'tgui/assets/fonts/fontawesome-webfont.eot', - "fontawesome-webfont.svg" = 'tgui/assets/fonts/fontawesome-webfont.svg', - "fontawesome-webfont.ttf" = 'tgui/assets/fonts/fontawesome-webfont.ttf', - "fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff', - "font-awesome.css" = 'code/modules/goonchat/browserassets/css/font-awesome.css', "browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css', "browserOutput_dark.css" = 'code/modules/goonchat/browserassets/css/browserOutput_dark.css', "browserOutput_light.css" = 'code/modules/goonchat/browserassets/css/browserOutput_light.css' ) +/datum/asset/simple/fontawesome + verify = FALSE + 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" diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 7e466caf8a..b6e0d52dad 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -47,6 +47,18 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( else if (job in completed_asset_jobs) //byond bug ID:2256651 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") + // Keypress passthrough + if(href_list["__keydown"]) + var/keycode = browser_keycode_to_byond(href_list["__keydown"]) + if(keycode) + keyDown(keycode) + return + if(href_list["__keyup"]) + var/keycode = browser_keycode_to_byond(href_list["__keyup"]) + if(keycode) + keyUp(keycode) + return + var/mtl = CONFIG_GET(number/minute_topic_limit) if (!holder && mtl) @@ -411,7 +423,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) winset(src, "[child]", "[entries[child]]") if (!ispath(child, /datum/verbs/menu)) var/procpath/verbpath = child - if (copytext(verbpath.name,1,2) != "@") + if (verbpath.name[1] != "@") new child(src) for (var/thing in prefs.menuoptions) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 546268b5c7..006cdf8dc8 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -199,7 +199,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/auto_fit_viewport = TRUE var/uplink_spawn_loc = UPLINK_PDA - + var/sprint_spacebar = FALSE var/sprint_toggle = FALSE @@ -1476,9 +1476,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN) if("flavor_text") - var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(features["flavor_text"]), MAX_MESSAGE_LEN*2, TRUE) - if(!isnull(msg)) - msg = copytext(msg, 1, MAX_MESSAGE_LEN*2) + var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(features["flavor_text"]), MAX_MESSAGE_LEN, TRUE) + if(msg) + msg = msg features["flavor_text"] = msg if("hair") @@ -2230,7 +2230,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("never_hypno") cit_toggles ^= NEVER_HYPNO - + if("aphro") cit_toggles ^= NO_APHRO @@ -2239,7 +2239,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("bimbo") cit_toggles ^= BIMBOFICATION - + //END CITADEL EDIT if("ambientocclusion") diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 08ecefb91f..24e44f191e 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -118,7 +118,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car /datum/preferences/proc/load_path(ckey,filename="preferences.sav") if(!ckey) return - path = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/[filename]" + path = "data/player_saves/[ckey[1]]/[ckey]/[filename]" /datum/preferences/proc/load_preferences() if(!path) @@ -479,15 +479,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name)) be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body)) - if(gender == MALE) - hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_male_list) - facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_male_list) - else - hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_female_list) - facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_female_list) - underwear = sanitize_inlist(underwear, GLOB.underwear_list) + hair_style = sanitize_inlist(hair_style, GLOB.hair_styles_list) + facial_hair_style = sanitize_inlist(facial_hair_style, GLOB.facial_hair_styles_list) + underwear = sanitize_inlist(underwear, GLOB.underwear_list) + undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list) undie_color = sanitize_hexcolor(undie_color, 3, FALSE, initial(undie_color)) - undershirt = sanitize_inlist(undershirt, GLOB.undershirt_list) shirt_color = sanitize_hexcolor(shirt_color, 3, FALSE, initial(shirt_color)) socks = sanitize_inlist(socks, GLOB.socks_list) socks_color = sanitize_hexcolor(socks_color, 3, FALSE, initial(socks_color)) diff --git a/code/modules/client/verbs/aooc.dm b/code/modules/client/verbs/aooc.dm index 3f86a617e6..bc32d3c222 100644 --- a/code/modules/client/verbs/aooc.dm +++ b/code/modules/client/verbs/aooc.dm @@ -31,7 +31,7 @@ GLOBAL_VAR_INIT(normal_aooc_colour, "#ce254f") if(QDELETED(src)) return - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) + msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) var/raw_msg = msg if(!msg) diff --git a/code/modules/client/verbs/looc.dm b/code/modules/client/verbs/looc.dm index 38cfd84b9c..075cabcbbb 100644 --- a/code/modules/client/verbs/looc.dm +++ b/code/modules/client/verbs/looc.dm @@ -13,7 +13,7 @@ GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC") if(!mob) return - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) + msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) if(!msg) return diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index 8a233025a1..44290d1c2f 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -28,7 +28,7 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") if(QDELETED(src)) return - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) + msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) var/raw_msg = msg if(!msg) @@ -36,7 +36,7 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") msg = emoji_parse(msg) - if((copytext(msg, 1, 2) in list(".",";",":","#")) || (findtext(lowertext(copytext(msg, 1, 5)), "say"))) + if((msg[1] in list(".",";",":","#")) || findtext_char(msg, "say", 1, 5)) if(alert("Your message \"[raw_msg]\" looks like it was meant for in game communication, say it in OOC?", "Meant for OOC?", "No", "Yes") != "Yes") return diff --git a/code/modules/client/verbs/ping.dm b/code/modules/client/verbs/ping.dm index de19d0d52c..02c5b5a7fd 100644 --- a/code/modules/client/verbs/ping.dm +++ b/code/modules/client/verbs/ping.dm @@ -14,9 +14,9 @@ /client/verb/display_ping(time as num) set instant = TRUE set name = ".display_ping" - to_chat(src, "Round trip ping took [round(pingfromtime(time),1)]ms") + to_chat(src, "Round trip ping took [round(pingfromtime(time),1)]ms (Avg: [round(avgping, 1)]ms])") /client/verb/ping() set name = "Ping" set category = "OOC" - winset(src, null, "command=.display_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]") \ No newline at end of file + winset(src, null, "command=.display_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]") diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index 2e643cc05d..255a5a2eec 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -207,6 +207,9 @@ message_admins("[key_name(src)] (job: [src.job ? "[src.job]" : "None"]) [is_special_character(src) ? "(ANTAG!) " : ""][ghosting ? "ghosted" : "committed suicide"] at [AREACOORD(src)].") /mob/living/proc/canSuicide() + if(!CONFIG_GET(flag/suicide_allowed)) + to_chat(src, "Suicide is not enabled in the config.") + return FALSE switch(stat) if(CONSCIOUS) return TRUE diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 69c50c5461..7df10b56f7 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -250,6 +250,36 @@ throwforce = 12 glass_colour_type = /datum/client_colour/glass_colour/red +/obj/item/clothing/glasses/sunglasses/stunglasses + name = "stunglasses" + desc = "Sunglasses with inbuilt flashes. Made for those who prefer to walk around in style, who needs clumsy flashes anyway?" + actions_types = list(/datum/action/item_action/flash) + var/obj/item/assembly/flash/installed + +/obj/item/clothing/glasses/sunglasses/stunglasses/Initialize() + . = ..() + if (!installed) + installed = new(src) + +/obj/item/clothing/glasses/sunglasses/stunglasses/ui_action_click(mob/user) + if (installed && !installed.crit_fail) + installed.attack_self(user) + else + to_chat(user, "Install a new flash in [src]!") + +/obj/item/clothing/glasses/sunglasses/stunglasses/attackby(obj/item/W,mob/user) + if (istype(W,/obj/item/screwdriver)) + if (installed) + installed.forceMove(get_turf(src)) + to_chat(user, "You remove [installed] from [src].") + installed = null + if (istype(W,/obj/item/assembly/flash)) + if (!installed) + W.forceMove(src) + to_chat(user, "You install [W] into [src].") + installed = W + . = ..() + /obj/item/clothing/glasses/welding name = "welding goggles" desc = "Protects the eyes from welders; approved by the mad scientist association." @@ -458,4 +488,4 @@ if(client && client.prefs.uses_glasses_colour && glasses_equipped) add_client_colour(G.glass_colour_type) else - remove_client_colour(G.glass_colour_type) + remove_client_colour(G.glass_colour_type) \ No newline at end of file diff --git a/code/modules/clothing/glasses/vg_glasses.dm b/code/modules/clothing/glasses/vg_glasses.dm deleted file mode 100644 index a51a03242c..0000000000 --- a/code/modules/clothing/glasses/vg_glasses.dm +++ /dev/null @@ -1,41 +0,0 @@ - -//VG rip - -/obj/item/clothing/glasses/sunglasses/purple - desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes, and the colored lenses let you see the world in purple." - name = "purple sunglasses" - icon_state = "sun_purple" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/glasses/sunglasses/star - name = "star-shaped sunglasses" - desc = "Novelty sunglasses, both lenses are in the shape of a star." - icon_state = "sun_star" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/glasses/sunglasses/rockstar - name = "red star-shaped sunglasses" - desc = "Novelty sunglasses with a fancy silver frame and two red-tinted star-shaped lenses. You should probably stomp on them and get a pair of normal ones." - icon_state = "sun_star_silver" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/glasses/gglasses - name = "Green Glasses" - desc = "Forest green glasses, like the kind you'd wear when hatching a nasty scheme." - icon_state = "gglasses" - item_state = "gglasses" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/glasses/welding/superior - name = "superior welding goggles" - desc = "Welding goggles made from more expensive materials, strangely smells like potatoes. Allows for better vision than normal goggles.." - icon_state = "rwelding-g" - item_state = "rwelding-g" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - actions_types = list(/datum/action/item_action/toggle) - flash_protect = 2 - tint = 1 - visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT - flags_cover = GLASSESCOVERSEYES - visor_flags_inv = HIDEEYES - glass_colour_type = /datum/client_colour/glass_colour/green \ No newline at end of file diff --git a/code/modules/clothing/gloves/ring.dm b/code/modules/clothing/gloves/ring.dm new file mode 100644 index 0000000000..54aaa58849 --- /dev/null +++ b/code/modules/clothing/gloves/ring.dm @@ -0,0 +1,26 @@ +/obj/item/clothing/gloves/ring + name = "gold ring" + desc = "A tiny gold ring, sized to wrap around a finger." + gender = NEUTER + w_class = WEIGHT_CLASS_TINY + icon = 'icons/obj/ring.dmi' + icon_state = "ringgold" + body_parts_covered = 0 + attack_verb = list("proposed") + transfer_prints = TRUE + strip_delay = 40 + +/obj/item/clothing/gloves/ring/suicide_act(mob/living/carbon/user) + user.visible_message("\[user] is putting the [src] in [user.p_their()] mouth! It looks like [user] is trying to choke on the [src]!") + return OXYLOSS + + +/obj/item/clothing/gloves/ring/diamond + name = "diamond ring" + desc = "A tiny gold ring, studded with a diamond. Cultures have used these rings in courtship for a millenia." + icon_state = "ringdiamond" + +/obj/item/clothing/gloves/ring/silver + name = "silver ring" + desc = "A tiny silver ring, sized to wrap around a finger." + icon_state = "ringsilver" diff --git a/code/modules/clothing/gloves/vg_gloves.dm b/code/modules/clothing/gloves/vg_gloves.dm deleted file mode 100644 index 6d7e775314..0000000000 --- a/code/modules/clothing/gloves/vg_gloves.dm +++ /dev/null @@ -1,70 +0,0 @@ - -/obj/item/clothing/gloves/batmangloves - desc = "Used for handling all things bat related." - name = "batgloves" - icon_state = "bmgloves" - item_state = "bmgloves" - item_color = "bmgloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -obj/item/clothing/gloves/bikergloves - name = "Biker's Gloves" - icon_state = "biker-gloves" - item_state = "biker-gloves" - item_color = "bikergloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/megagloves - desc = "Uncomfortably bulky armored gloves." - name = "DRN-001 Gloves" - icon_state = "megagloves" - item_state = "megagloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/protogloves - desc = "Funcionally identical to the DRN-001 model's, but in red!" - name = "Prototype Gloves" - icon_state = "protogloves" - item_state = "protogloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/megaxgloves - desc = "An upgrade to the DRN-001's gauntlets, retains the uncomfortable armor, but comes with white gloves!" - name = "Maverick Hunter gloves" - icon_state = "megaxgloves" - item_state = "megaxgloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/joegloves - desc = "Large grey gloves, very similar to the Prototype's." - name = "Sniper Gloves" - icon_state = "joegloves" - item_state = "joegloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/doomguy - desc = "" - name = "Doomguy's gloves" - icon_state = "doom" - item_state = "doom" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/anchor_arms - name = "Anchor Arms" - desc = "When you're a jerk, everybody loves you." - icon_state = "anchorarms" - item_state = "anchorarms" - -/obj/item/clothing/gloves/neorussian - name = "neo-Russian gloves" - desc = "Utilizes a non-slip technology that allows you to never drop your precious bottles of vodka." - icon_state = "nr_gloves" - item_state = "nr_gloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/gloves/neorussian/fingerless - name = "neo-Russian fingerless gloves" - desc = "For these tense combat situations when you just have to pick your nose." - icon_state = "nr_fgloves" - item_state = "nr_fgloves" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' \ No newline at end of file diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 696ff1346c..189fb46e46 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -423,3 +423,15 @@ desc = "A security cowboy hat, perfect for any true lawman" icon_state = "cowboyhat_sec" item_state= "cowboyhat_sec" + +/obj/item/clothing/head/squatter_hat + name = "slav squatter hat" + icon_state = "squatter_hat" + item_state = "squatter_hat" + desc = "Cyka blyat." + +/obj/item/clothing/head/russobluecamohat + name = "russian blue camo beret" + desc = "A symbol of discipline, honor, and lots and lots of removal of some type of skewered food." + icon_state = "russobluecamohat" + item_state = "russobluecamohat" diff --git a/code/modules/clothing/head/vg_hats.dm b/code/modules/clothing/head/vg_hats.dm deleted file mode 100644 index 87f64baf13..0000000000 --- a/code/modules/clothing/head/vg_hats.dm +++ /dev/null @@ -1,155 +0,0 @@ -/obj/item/clothing/head/helmet/dredd - name = "Judge Helmet" - desc = "Judge, Jury, and Executioner." - icon_state = "dredd-helmet" - item_state = "dredd-helmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - armor = list(melee = 40, bullet = 30, laser = 30,energy = 30, bomb = 50, bio = 90, rad = 20, fire = 50, acid = 50) - cold_protection = HEAD - min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT - heat_protection = HEAD - max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT - strip_delay = 80 - dog_fashion = null - -/obj/item/clothing/head/helmet/aviatorhelmet - name = "Aviator Helmet" - desc = "Help the Bombardier!" - armor = list(melee = 25, bullet = 0, laser = 20, energy = 10, bomb = 10, bio = 0, rad = 0) - item_state = "aviator_helmet" - icon_state = "aviator_helmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/biker - name = "Biker's Helmet" - desc = "This helmet should protect you from russians and masked vigilantes." - armor = list(melee = 25, bullet = 15, laser = 20, energy = 10, bomb = 10, bio = 0, rad = 0) - icon_state = "biker_helmet" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR - -/obj/item/clothing/head/helmet/richard - name = "Richard" - desc = "Do you like hurting people?" - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) - icon_state = "richard" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR - -/obj/item/clothing/head/helmet/megahelmet - name = "DRN-001 Helmet" - desc = "The helmet of the DRN-001 model. A simple, sturdy blue helmet." - icon_state = "megahelmet" - item_state = "megahelmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - siemens_coefficient = 1 - -/obj/item/clothing/head/helmet/protohelmet - name = "Prototype Helmet" - desc = "Shiny red helmet with white accents and a built in shaded visor that does absolutely nothing, nothing but look rad as hell." - icon_state = "protohelmet" - item_state = "protohelmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - siemens_coefficient = 1 - -/obj/item/clothing/head/helmet/megaxhelmet - name = "Maverick Hunter Helmet" - desc = "Heavily armored upgrade to the DRN-001 model's helmet, now comes with a pointless red crystal thing!" - icon_state = "megaxhelmet" - item_state = "megaxhelmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/joehelmet - name = "Sniper Helmet" - desc = "Helmet belonging to one of the many mass produced 'Joe' type robots." - icon_state = "joehelmet" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR - item_state = "joehelmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/doomguy - name = "Doomguy's helmet" - desc = "" - icon_state = "doom" - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR - item_state = "doom" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - armor = list(melee = 50, bullet = 40, laser = 40,energy = 40, bomb = 5, bio = 0, rad = 0) - -/obj/item/clothing/head/helmet/neorussian - name = "neo-Russian helmet" - desc = "This piece of equipment can double as a pillow, a bowl, an emergency toilet, and sometimes as a helmet." - icon_state = "nr_helmet" - item_state = "nr_helmet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/panzer - name = "Panzer Cap" - desc = "Command any mech in style." - icon_state = "panzercap" - item_state = "panzercap" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/russobluecamohat - name = "russian blue camo beret" - desc = "A symbol of discipline, honor, and lots and lots of removal of some type of skewered food." - icon_state = "russobluecamohat" - item_state = "russobluecamohat" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/russofurhat - name = "russian fur hat" - desc = "Russian winter got you down? Maybe your enemy, but not you!" - icon_state = "russofurhat" - item_state = "russofurhat" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/squatter_hat - name = "slav squatter hat" - icon_state = "squatter_hat" - item_state = "squatter_hat" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - desc = "Cyka blyat." - -/obj/item/clothing/head/snake - name = "snake head" - desc = "Reenact acts of violence against reptiles, or sneak into a swamp unnoticed." - icon_state = "snakehead" - item_state = "snakehead" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' -/obj/item/clothing/head/mummy_rags - name = "mummy rags" - desc = "Ancient rags taken off from some mummy." - icon_state = "mummy" - item_state = "mummy" - item_color = "mummy" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS - -/obj/item/clothing/head/clownpiece - name = "Clownpiece's jester hat" - desc = "A purple polka-dotted jester's hat with yellow pompons." - icon_state = "clownpiece" - item_state = "clownpiece" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/mitre - name = "mitre" - desc = "A funny hat worn by extremely boring people." - icon_state = "mitre" - item_state = "mitre" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/tinfoil - name = "tinfoil hat" - desc = "There's no evidence that the security staff is NOT out to get you." - icon_state = "foilhat" - item_state = "paper" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - siemens_coefficient = 2 - -/obj/item/clothing/head/celtic - name = "\improper Celtic crown" - desc = "According to legend, Celtic kings would use crowns like this one to shield their subjects from harsh winters back on Earth." - icon_state = "celtic_crown" - item_state = "celtic_crown" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' diff --git a/code/modules/clothing/masks/vg_masks.dm b/code/modules/clothing/masks/vg_masks.dm deleted file mode 100644 index 29b65a6b8e..0000000000 --- a/code/modules/clothing/masks/vg_masks.dm +++ /dev/null @@ -1,17 +0,0 @@ -/obj/item/clothing/mask/gas/clown_hat/wiz - name = "purple clown wig and mask" - desc = "Some pranksters are truly magical." - icon_state = "wizzclown" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/mask/chapmask - name = "venetian mask" - desc = "A plain porcelain mask that covers the entire face. Standard attire for particularly unspeakable religions. The eyes are wide shut." - icon_state = "chapmask" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/mask/neorussian - name = "neo-Russian mask" - desc = "Somehow, it makes you act and look way more polite than usual." - icon_state = "nr_mask" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 9a46b6b759..2b43460257 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -189,7 +189,7 @@ var/tagname = null /obj/item/clothing/neck/petcollar/attack_self(mob/user) - tagname = copytext(sanitize(input(user, "Would you like to change the name on the tag?", "Name your new pet", "Spot") as null|text),1,MAX_NAME_LEN) + tagname = stripped_input(user, "Would you like to change the name on the tag?", "Name your new pet", "Spot", MAX_NAME_LEN) name = "[initial(name)] - [tagname]" /obj/item/clothing/neck/petcollar/worn_overlays(isinhands, icon_file, style_flags = NONE) diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm index 1532f50808..bdbac1165e 100644 --- a/code/modules/clothing/outfits/ert.dm +++ b/code/modules/clothing/outfits/ert.dm @@ -18,8 +18,9 @@ R.freqlock = TRUE var/obj/item/card/id/W = H.wear_id - W.registered_name = H.real_name - W.update_label(W.registered_name, W.assignment) + if(W) + W.registered_name = H.real_name + W.update_label(W.registered_name, W.assignment) /datum/outfit/ert/commander name = "ERT Commander" diff --git a/code/modules/clothing/shoes/vg_shoes.dm b/code/modules/clothing/shoes/vg_shoes.dm deleted file mode 100644 index 53b093dc72..0000000000 --- a/code/modules/clothing/shoes/vg_shoes.dm +++ /dev/null @@ -1,124 +0,0 @@ - -/obj/item/clothing/shoes/leather - name = "leather shoes" - desc = "A sturdy pair of leather shoes." - icon_state = "leather" - item_color = "leather" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/magboots/deathsquad - desc = "Very expensive and advanced magnetic boots, used only by the elite during extravehicular activity to ensure the user remains safely attached to the vehicle." - name = "deathsquad magboots" - icon_state = "DS-magboots0" - magboot_state = "DS-magboots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - mutantrace_variation = NONE - -/obj/item/clothing/shoes/magboots/atmos - desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle. These are painted in the colors of an atmospheric technician." - name = "atmospherics magboots" - icon_state = "atmosmagboots0" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - magboot_state = "atmosmagboots" - resistance_flags = FIRE_PROOF - mutantrace_variation = NONE - -/obj/item/clothing/shoes/simonshoes - name = "Simon's Shoes" - desc = "Simon's Shoes." - icon_state = "simonshoes" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/kneesocks - name = "kneesocks" - desc = "A pair of girly knee-high socks." - icon_state = "kneesock" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/jestershoes - name = "Jester Shoes" - desc = "As worn by the clowns of old." - icon_state = "jestershoes" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/aviatorboots - name = "Aviator Boots" - desc = "Boots suitable for just about any occasion." - icon_state = "aviator_boots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/libertyshoes - name = "Liberty Shoes" - desc = "Freedom isn't free, neither were these shoes." - icon_state = "libertyshoes" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/megaboots - name = "DRN-001 Boots" - desc = "Large armored boots, very weak to large spikes." - icon_state = "megaboots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/protoboots - name = "Prototype Boots" - desc = "Functionally identical to the DRN-001 model's boots, but in red." - icon_state = "protoboots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/megaxboots - name = "Maverick Hunter boots" - desc = "Regardless of how much stronger these boots are than the DRN-001 model's, they're still extremely easy to pierce with a large spike." - icon_state = "megaxboots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/joeboots - name = "Sniper Boots" - desc = "Nearly identical to the Prototype's boots, except in black." - icon_state = "joeboots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/doomguy - name = "Doomguy's boots" - desc = "If you look closely, you might see skull fragments still buried in these boots." - icon_state = "doom" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/rottenshoes - name = "rotten shoes" - desc = "These shoes seem perfect for sneaking around." - icon_state = "rottenshoes" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/sandal/slippers - name = "magic slippers" - icon_state = "slippers" - desc = "For the wizard that puts comfort first. Who's going to laugh?" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/slippers_worn - name = "worn bunny slippers" - desc = "Fluffy..." - icon_state = "slippers_worn" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/shoes/jackboots/neorussian - name = "neo-Russian boots" - desc = "Tovarish, no one will realize you stepped on a pile of shit if your pair already looks like shit." - icon_state = "nr_boots" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index c04f581425..703fe26287 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -203,32 +203,6 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/atmos - //Radiation -/obj/item/clothing/head/helmet/space/hardsuit/engine/rad - name = "radiation hardsuit helmet" - desc = "A special helmet that protects against radiation and space. Not much else unfortunately." - icon_state = "cespace_helmet" - item_state = "nothing" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) - item_color = "engineering" - resistance_flags = FIRE_PROOF - rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE - actions_types = list() - -/obj/item/clothing/suit/space/hardsuit/engine/rad - name = "radiation hardsuit" - desc = "A special suit that protects against radiation and space. Not much else unfortunately." - icon_state = "hardsuit-rad" - item_state = "nothing" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/rad - resistance_flags = FIRE_PROOF - rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE - mutantrace_variation = NONE - -/obj/item/clothing/head/helmet/space/hardsuit/engine/rad/attack_self() - return //Sprites required for flashlight - //Chief Engineer's hardsuit /obj/item/clothing/head/helmet/space/hardsuit/engine/elite name = "advanced hardsuit helmet" @@ -719,6 +693,29 @@ listeningTo = null return ..() +/obj/item/clothing/head/helmet/space/hardsuit/soviet + name = "soviet hardhelmet" + desc = "Crafted with the pride of the proletariat. The vengeful gaze of the visor roots out all fascists and capitalists." + item_state = "rig0-soviet" + item_color = "soviet" + icon_state = "rig0-soviet" + armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75) + mutantrace_variation = NONE + +/obj/item/clothing/suit/space/hardsuit/soviet + name = "soviet hardsuit" + desc = "Crafted with the pride of the proletariat. The last thing the enemy sees is the bottom of this armor's boot." + item_state = "rig-soviet" + icon_state = "rig-soviet" + slowdown = 0.8 + armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75) + helmettype = /obj/item/clothing/head/helmet/space/hardsuit/soviet + mutantrace_variation = NONE + +/obj/item/clothing/suit/space/hardsuit/soviet/Initialize() + . = ..() + allowed = GLOB.security_hardsuit_allowed + /////////////SHIELDED////////////////////////////////// /obj/item/clothing/suit/space/hardsuit/shielded diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index c9c3d1ff39..f9e35ca37f 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -11,6 +11,7 @@ Contains: - ERT hardsuit: Command, Sec, Engi, Med - ERT High Alarm - Command, Sec, Engi, Med - EVA spacesuit + - Radiation Spacesuit - Freedom's spacesuit (freedom from vacuum's oppression) - Carp hardsuit */ @@ -312,6 +313,28 @@ Contains: flash_protect = 0 armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 65) +//Radiation +/obj/item/clothing/head/helmet/space/rad + name = "radiation voidsuit helmet" + desc = "A special helmet that protects against radiation and space. Not much else unfortunately." + icon_state = "cespace_helmet" + item_state = "nothing" + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) + item_color = "engineering" + resistance_flags = FIRE_PROOF + rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE + actions_types = list() + +/obj/item/clothing/suit/space/rad + name = "radiation voidsuit" + desc = "A special suit that protects against radiation and space. Not much else unfortunately." + icon_state = "hardsuit-rad" + item_state = "nothing" + armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) + resistance_flags = FIRE_PROOF + rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE + mutantrace_variation = NONE + /obj/item/clothing/head/helmet/space/freedom name = "eagle helmet" desc = "An advanced, space-proof helmet. It appears to be modeled after an old-world eagle." diff --git a/code/modules/clothing/spacesuits/vg_spess.dm b/code/modules/clothing/spacesuits/vg_spess.dm deleted file mode 100644 index 517539f3af..0000000000 --- a/code/modules/clothing/spacesuits/vg_spess.dm +++ /dev/null @@ -1,120 +0,0 @@ - - //VG Ports - -/obj/item/clothing/head/helmet/space/hardsuit/soviet - name = "soviet hardhelmet" - desc = "Crafted with the pride of the proletariat. The vengeful gaze of the visor roots out all fascists and capitalists." - item_state = "hardsuit0-soviet" - icon_state = "hardsuit0-soviet" - armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 20) - item_color = "soviet" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/suit/space/hardsuit/soviet - name = "soviet hardsuit" - desc = "Crafted with the pride of the proletariat. The last thing the enemy sees is the bottom of this armor's boot." - item_state = "hardsuit-soviet" - icon_state = "hardsuit-soviet" - slowdown = 1 - armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 20) - allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/melee/) - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/soviet - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/space/hardsuit/knight - name = "Space-Knight helm" - desc = "A well polished helmet belonging to a Space-Knight. Favored by space-jousters for its ability to stay on tight after being launched from a mass driver." - icon_state = "hardsuit0-knight" - item_state = "hardsuit0-knight" - armor = list(melee = 60, bullet = 40, laser = 40,energy = 30, bomb = 50, bio = 100, rad = 60) - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - item_color="knight" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/suit/space/hardsuit/knight - name = "Space-Knight armour" - desc = "A well polished set of armour belonging to a Space-Knight. Maidens Rescued in Space: 100, Maidens who have slept with me in Space: 0." - icon_state = "hardsuit-knight" - item_state = "hardsuit-knight" - slowdown = 1 - allowed = list(/obj/item/gun,/obj/item/melee/baton,/obj/item/tank,/obj/item/shield/energy,/obj/item/claymore) - armor = list(melee = 60, bullet = 40, laser = 40,energy = 30, bomb = 50, bio = 100, rad = 60) - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - siemens_coefficient = 0.5 - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/knight - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/space/hardsuit/knight/black - name = "Black Knight's helm" - desc = "An ominous black helmet with a gold trim. The small viewports create an intimidating look, while also making it nearly impossible to see anything." - icon_state = "hardsuit0-blackknight" - item_state = "hardsuit0-blackknight" - armor = list(melee = 70, bullet = 65, laser = 50,energy = 25, bomb = 60, bio = 100, rad = 60) - item_color="blackknight" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/suit/space/hardsuit/knight/black - name = "Black Knight's armour" - desc = "An ominous black suit of armour with a gold trim. Surprisingly good at preventing accidental loss of limbs." - icon_state = "hardsuit-blackknight" - item_state = "hardsuit-blackknight" - armor = list(melee = 70, bullet = 65, laser = 50,energy = 25, bomb = 60, bio = 100, rad = 60) - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/knight/black - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/space/hardsuit/knight/solaire - name = "Solar helm" - desc = "A simple helmet. 'Made in Astora' is inscribed on the back." - icon_state = "hardsuit0-solaire" - item_state = "hardsuit0-solaire" - armor = list(melee = 60, bullet = 65, laser = 90,energy = 30, bomb = 60, bio = 100, rad = 100) - item_color="solaire" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/suit/space/hardsuit/knight/solaire - name = "Solar armour" - desc = "A solar powered hardsuit with a fancy insignia on the chest. Perfect for stargazers and adventurers alike." - icon_state = "hardsuit-solaire" - item_state = "hardsuit-solaire" - armor = list(melee = 60, bullet = 65, laser = 90,energy = 30, bomb = 60, bio = 100, rad = 100) - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/knight/solaire - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/head/helmet/space/hardsuit/t51b - name = "T-51b Power Armor" - desc = "Relic of a bygone era, the T-51b is powered by a TX-28 MicroFusion Pack, which holds enough fuel to power its internal hydraulics for a century!" - icon_state = "hardsuit0-t51b" - item_state = "hardsuit0-t51b" - armor = list(melee = 35, bullet = 35, laser = 40, energy = 40, bomb = 80, bio = 100, rad = 100) - item_color="t51b" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -/obj/item/clothing/suit/space/hardsuit/t51b - name = "T-51b Power Armor" - desc = "Relic of a bygone era, the T-51b is powered by a TX-28 MicroFusion Pack, which holds enough fuel to power its internal hydraulics for a century!" - icon_state = "hardsuit-t51b" - item_state = "hardsuit-t51b" - armor = list(melee = 35, bullet = 35, laser = 40, energy = 40, bomb = 80, bio = 100, rad = 100) - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/t51b - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - - -/obj/item/clothing/head/helmet/space/bomberman - name = "Bomberman head" - desc = "Terrorism has never looked so adorable." - icon_state = "bomberman" - item_state = "bomberman" - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 100, bio = 0, rad = 0) - siemens_coefficient = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - -obj/item/clothing/suit/space/bomberman - name = "Bomberman's suit" - desc = "Doesn't actually make you immune to bombs!" - icon_state = "bomberman" - item_state = "bomberman" - slowdown = 0 - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 100, bio = 0, rad = 0) - siemens_coefficient = 0 - max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' \ No newline at end of file diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm index b8287c7f4c..7d56fbe6dd 100644 --- a/code/modules/clothing/suits/cloaks.dm +++ b/code/modules/clothing/suits/cloaks.dm @@ -81,7 +81,7 @@ heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - resistance_flags = FIRE_PROOF | ACID_PROOF + resistance_flags = FIRE_PROOF | ACID_PROOF | GOLIATH_RESISTANCE /obj/item/clothing/head/hooded/cloakhood/drake name = "drake helm" @@ -90,4 +90,4 @@ armor = list("melee" = 70, "bullet" = 30, "laser" = 50, "energy" = 40, "bomb" = 70, "bio" = 60, "rad" = 50, "fire" = 100, "acid" = 100) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - resistance_flags = FIRE_PROOF | ACID_PROOF + resistance_flags = FIRE_PROOF | ACID_PROOF | GOLIATH_RESISTANCE diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 127d2e4f04..84609e29d8 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -922,3 +922,78 @@ /obj/item/clothing/head/hooded/winterhood/christmashoodrg icon_state = "christmashoodrg" + +/obj/item/clothing/suit/hooded/wintercoat/polychromic + name = "polychromic winter coat" + icon_state = "coatpoly" + item_state = "coatpoly" + item_color = "coatpoly" + hoodtype = /obj/item/clothing/head/hooded/winterhood/polychromic + hasprimary = TRUE + hassecondary = TRUE + hastertiary = TRUE + primary_color = "#6A6964" + secondary_color = "#C4B8A6" + tertiary_color = "#0000FF" + +/obj/item/clothing/head/hooded/winterhood/polychromic + icon_state = "winterhood_poly" + item_color = "winterhood_poly" + item_state = "winterhood_poly" + +/obj/item/clothing/head/hooded/winterhood/polychromic/worn_overlays(isinhands, icon_file, style_flags = NONE) //this is where the main magic happens. + . = ..() + if(suit.hasprimary | suit.hassecondary) + if(!isinhands) //prevents the worn sprites from showing up if you're just holding them + if(suit.hasprimary) //checks if overlays are enabled + var/mutable_appearance/primary_worn = mutable_appearance(icon_file, "[item_color]-primary") //automagical sprite selection + primary_worn.color = suit.primary_color //colors the overlay + . += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite. + if(suit.hassecondary) + var/mutable_appearance/secondary_worn = mutable_appearance(icon_file, "[item_color]-secondary") + secondary_worn.color = suit.secondary_color + . += secondary_worn + +/obj/item/clothing/suit/hooded/wintercoat/polychromic/worn_overlays(isinhands, icon_file, style_flags = NONE) //this is where the main magic happens. + . = ..() + if(hasprimary | hassecondary | hastertiary) + if(!isinhands) //prevents the worn sprites from showing up if you're just holding them + if(hasprimary) //checks if overlays are enabled + var/mutable_appearance/primary_worn = mutable_appearance(icon_file, "[item_color]-primary[suittoggled ? "_t" : ""]") //automagical sprite selection + primary_worn.color = primary_color //colors the overlay + . += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite. + if(hassecondary) + var/mutable_appearance/secondary_worn = mutable_appearance(icon_file, "[item_color]-secondary[suittoggled ? "_t" : ""]") + secondary_worn.color = secondary_color + . += secondary_worn + if(hastertiary) + var/mutable_appearance/tertiary_worn = mutable_appearance(icon_file, "[item_color]-tertiary[suittoggled ? "_t" : ""]") + tertiary_worn.color = tertiary_color + . += tertiary_worn + +/obj/item/clothing/suit/hooded/wintercoat/AltClick(mob/user) + . = ..() + if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + if(hasprimary | hassecondary | hastertiary) + var/choice = input(user,"polychromic thread options", "Clothing Recolor") as null|anything in list("[hasprimary ? "Primary Color" : ""]", "[hassecondary ? "Secondary Color" : ""]", "[hastertiary ? "Tertiary Color" : ""]") //generates a list depending on the enabled overlays + switch(choice) //Lets the list's options actually lead to something + if("Primary Color") + var/primary_color_input = input(usr,"","Choose Primary Color",primary_color) as color|null //color input menu, the "|null" adds a cancel button to it. + if(primary_color_input) //Checks if the color selected is NULL, rejects it if it is NULL. + primary_color = sanitize_hexcolor(primary_color_input, desired_format=6, include_crunch=1) //formats the selected color properly + update_icon() //updates the item icon + user.regenerate_icons() //updates the worn icon. Probably a bad idea, but it works. + if("Secondary Color") + var/secondary_color_input = input(usr,"","Choose Secondary Color",secondary_color) as color|null + if(secondary_color_input) + secondary_color = sanitize_hexcolor(secondary_color_input, desired_format=6, include_crunch=1) + update_icon() + user.regenerate_icons() + if("Tertiary Color") + var/tertiary_color_input = input(usr,"","Choose Tertiary Color",tertiary_color) as color|null + if(tertiary_color_input) + tertiary_color = sanitize_hexcolor(tertiary_color_input, desired_format=6, include_crunch=1) + update_icon() + user.regenerate_icons() + return TRUE \ No newline at end of file diff --git a/code/modules/clothing/suits/vg_suits.dm b/code/modules/clothing/suits/vg_suits.dm deleted file mode 100644 index be6cd9938e..0000000000 --- a/code/modules/clothing/suits/vg_suits.dm +++ /dev/null @@ -1,138 +0,0 @@ - -/obj/item/clothing/suit/armor/xcomsquaddie - name = "Squaddie Armor" - desc = "A suit of armor with heavy padding to protect against projectile and laser attacks. Distributed to shadow organization squaddies." - icon_state = "xcomarmor2" - item_state = "xcomarmor2" - body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list(melee = 50, bullet = 50, laser = 50, energy = 30, bomb = 60, bio = 30, rad = 20) - siemens_coefficient = 0.5 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/armor/xcomsquaddie/dredd - name = "Judge Armor" - desc = "A large suit of heavy armor, fit for a Judge." - icon_state = "dredd-suit" - item_state = "dredd-suit" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - - -/obj/item/clothing/suit/armor/xcomarmor - name = "Mysterious Armor" - desc = "A suit of armor with heavy plating to protect against melee attacks. Distributed to shadow organization squaddies." - icon_state = "xcomarmor1" - item_state = "xcomarmor1" - body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list(melee = 50, bullet = 50, laser = 50, energy = 30, bomb = 60, bio = 30, rad = 20) - slowdown = 1 - siemens_coefficient = 0.5 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/armor/vest/neorussian - name = "neo-Russian vest" - desc = "The narkotiki camo pattern will come useful for botany raids." - icon_state = "nr_vest" - item_state = "nr_vest" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/armor/doomguy - name = "Doomguy's armor" - desc = "" - icon_state = "doom" - item_state = "doom" - body_parts_covered = CHEST|GROIN - slowdown = 0 - armor = list(melee = 50, bullet = 30, laser = 20, energy = 20, bomb = 30, bio = 0, rad = 0) - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - - -/obj/item/clothing/suit/kaminacape - name = "Kamina's Cape" - desc = "Don't believe in yourself, dumbass. Believe in me. Believe in the Kamina who believes in you." - icon_state = "kaminacape" - body_parts_covered = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/officercoat - name = "Officer's Coat" - desc = "Ein Mantel gemacht, um die Juden zu bestrafen." - icon_state = "officersuit" - body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/soldiercoat - name = "Soldier's Coat" - desc = "Und das heit: Erika." - icon_state = "soldiersuit" - body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/russofurcoat - name = "russian fur coat" - desc = "Let the land do the fighting for you." - icon_state = "russofurcoat" - allowed = list(/obj/item/gun) - body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/doshjacket - name = "Plasterer's Jacket" - desc = "Perfect for doing up the house." - icon_state = "doshjacket" - body_parts_covered = CHEST|GROIN|ARMS - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/maidapron - name = "Apron" - desc = "Simple white apron." - icon_state = "maidapron" - body_parts_covered = CHEST|GROIN - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/clownpiece - name = "small fairy wings" - desc = "Some small and translucid insect-like wings." - icon_state = "clownpiece" - body_parts_covered = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/clownpiece/flying - name = "small fairy wings" - desc = "Some small and translucid insect-like wings. Looks like these are the real deal!" - icon_state = "clownpiece-fly" - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/suit/raincoat - name = "Raincoat" - desc = "Do you like Huey Lewis and the News?" - icon_state = "raincoat" - body_parts_covered =CHEST|GROIN|LEGS|ARMS|HANDS - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/suit.dmi' - mutantrace_variation = NONE - - diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 8424ea962c..63e3a63968 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -91,6 +91,9 @@ if(user && notifyAttach) to_chat(user, "You attach [I] to [src].") + if((flags_inv & HIDEACCESSORY) || (A.flags_inv & HIDEACCESSORY)) + return TRUE + var/accessory_color = attached_accessory.item_color if(!accessory_color) accessory_color = attached_accessory.icon_state diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index a4d2c17fd6..86d2b40d0f 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -370,22 +370,25 @@ ///////////////////// /obj/item/clothing/accessory/padding - name = "soft padding" - desc = "Some long sheets of padding to help soften the blows of a physical attacks." + name = "protective padding" + desc = "A soft padding meant to cushion the wearer from melee harm." icon_state = "padding" item_color = "nothing" - armor = list("melee" = 15, "bullet" = 10, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 0, "rad" = 0, "fire" = -20, "acid" = 45) + armor = list("melee" = 20, "bullet" = 10, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 0, "rad" = 0, "fire" = -20, "acid" = 45) + flags_inv = HIDEACCESSORY //hidden from indiscrete mob examines. /obj/item/clothing/accessory/kevlar - name = "kevlar sheets" - desc = "Long thin sheets of kevlar to help resist bullets and some physical attacks." + name = "kevlar padding" + desc = "A layered kevlar padding meant to cushion the wearer from ballistic harm." icon_state = "padding" item_color = "nothing" armor = list("melee" = 10, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 25) + flags_inv = HIDEACCESSORY /obj/item/clothing/accessory/plastics - name = "underling plastic sheet" - desc = "A full body sheet of white plastic to help defuse lasers and energy based weapons." + name = "ablative padding" + desc = "A thin ultra-refractory composite padding meant to cushion the wearer from energy lasers harm." icon_state = "plastics" item_color = "nothing" - armor = list("melee" = 0, "bullet" = 0, "laser" = 20, "energy" = 10, "bomb" = 0, "bio" = 30, "rad" = 0, "fire" = 0, "acid" = -40) + armor = list("melee" = 0, "bullet" = 0, "laser" = 20, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = -40) + flags_inv = HIDEACCESSORY diff --git a/code/modules/clothing/under/jobs/medsci.dm b/code/modules/clothing/under/jobs/medsci.dm index c27882aac7..6952a581da 100644 --- a/code/modules/clothing/under/jobs/medsci.dm +++ b/code/modules/clothing/under/jobs/medsci.dm @@ -178,19 +178,19 @@ permeability_coefficient = 0.5 armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) /obj/item/clothing/under/rank/medical/blue - name = "medical scrubs" + name = "blue medical scrubs" desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in baby blue." icon_state = "scrubsblue" item_color = "scrubsblue" can_adjust = FALSE /obj/item/clothing/under/rank/medical/green - name = "medical scrubs" + name = "green medical scrubs" desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in dark green." icon_state = "scrubsgreen" item_color = "scrubsgreen" can_adjust = FALSE /obj/item/clothing/under/rank/medical/purple - name = "medical scrubs" + name = "purple medical scrubs" desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in deep purple." icon_state = "scrubspurple" item_color = "scrubspurple" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index a2081851e1..a3a2b6b97e 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -131,6 +131,9 @@ item_color = "officer" alt_covers_chest = TRUE +/obj/item/clothing/under/rank/centcom_officer/syndicate + has_sensor = NO_SENSORS + /obj/item/clothing/under/rank/centcom_commander desc = "It's a jumpsuit worn by CentCom's highest-tier Commanders." name = "\improper CentCom officer's jumpsuit" @@ -945,4 +948,144 @@ icon_state = "christmasfemaleg" item_state = "christmasfemaleg" body_parts_covered = CHEST|GROIN - can_adjust = FALSE \ No newline at end of file + can_adjust = FALSE + +// Lunar Clothes +/obj/item/clothing/under/lunar/qipao + name = "Black Qipao" + desc = "A Qipao, traditionally worn in ancient Earth China by women during social events and lunar new years. This one is black." + icon_state = "qipao" + item_state = "qipao" + body_parts_covered = CHEST|GROIN + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/lunar/qipao/white + name = "White Qipao" + desc = "A Qipao, traditionally worn in ancient Earth China by women during social events and lunar new years. This one is white." + icon_state = "qipao_white" + item_state = "qipao_white" + body_parts_covered = CHEST|GROIN + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/lunar/qipao/red + name = "Red Qipao" + desc = "A Qipao, traditionally worn in ancient Earth China by women during social events and lunar new years. This one is red." + icon_state = "qipao_red" + item_state = "qipao_red" + body_parts_covered = CHEST|GROIN + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/lunar/cheongsam + name = "Black Cheongsam" + desc = "A Cheongsam, traditionally worn in ancient Earth China by men during social events and lunar new years. This one is black." + icon_state = "cheong" + item_state = "cheong" + body_parts_covered = CHEST|GROIN + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/lunar/cheongsam/white + name = "White Cheongsam" + desc = "A Cheongsam, traditionally worn in ancient Earth China by men during social events and lunar new years. This one is white." + icon_state = "cheongw" + item_state = "cheongw" + body_parts_covered = CHEST|GROIN + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/lunar/cheongsam/red + name = "Red Cheongsam" + desc = "A Cheongsam, traditionally worn in ancient Earth China by men during social events and lunar new years. This one is red.." + icon_state = "cheongr" + item_state = "cheongr" + body_parts_covered = CHEST|GROIN + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/squatter_outfit + name = "slav squatter tracksuit" + desc = "Cyka blyat." + icon_state = "squatteroutfit" + item_state = "squatteroutfit" + item_color = "squatteroutfit" + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/russobluecamooutfit + name = "russian blue camo" + desc = "Drop and give me dvadtsat!" + icon_state = "russobluecamo" + item_state = "russobluecamo" + item_color = "russobluecamo" + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/keyholesweater + name = "keyhole sweater" + desc = "What is the point of this, anyway?" + icon_state = "keyholesweater" + item_state = "keyholesweater" + item_color = "keyholesweater" + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/stripper_pink + name = "pink stripper outfit" + icon_state = "stripper_p" + item_state = "stripper_p" + item_color = "stripper_p" + +/obj/item/clothing/under/stripper_green + name = "green stripper outfit" + icon_state = "stripper_g" + item_state = "stripper_g" + item_color = "stripper_g" + can_adjust = FALSE + +/obj/item/clothing/under/mankini + name = "pink mankini" + icon_state = "mankini" + item_state = "mankini" + item_color = "mankini" + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/wedding + name = "white wedding dress" + desc = "A white wedding gown made from the finest silk." + icon_state = "bride_white" + item_state = "bride_white" + item_color = "bride_white" + can_adjust = FALSE + mutantrace_variation = NONE + +/obj/item/clothing/under/wedding/orange + name = "orange wedding dress" + desc = "A big and puffy orange dress." + icon_state = "bride_orange" + item_state = "bride_orange" + item_color = "bride_orange" + +/obj/item/clothing/under/wedding/purple + name = "purple wedding dress" + desc = "A big and puffy purple dress." + icon_state = "bride_purple" + item_state = "bride_purple" + item_color = "bride_purple" + +/obj/item/clothing/under/wedding/blue + name = "blue wedding dress" + desc = "A big and puffy blue dress." + icon_state = "bride_blue" + item_state = "bride_blue" + item_color = "bride_blue" + +/obj/item/clothing/under/wedding/red + name = "red wedding dress" + desc = "A big and puffy red dress." + icon_state = "bride_red" + item_state = "bride_red" + item_color = "bride_red" diff --git a/code/modules/clothing/under/vg_under.dm b/code/modules/clothing/under/vg_under.dm deleted file mode 100644 index 555ed3b795..0000000000 --- a/code/modules/clothing/under/vg_under.dm +++ /dev/null @@ -1,436 +0,0 @@ -// Fixed to work with Citadel code. Apparently none of them had NO_MUTANTRACE flags. -// I was pissy when I realised how to fix this because it's so fucking easy and nobody apparently had done it. - -/obj/item/clothing/under/stripper_pink - name = "pink stripper outfit" - icon_state = "stripper_p" - item_state = "stripper_p" - item_color = "stripper_p" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/stripper_green - name = "green stripper outfit" - icon_state = "stripper_g" - item_state = "stripper_g" - item_color = "stripper_g" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/wedding/bride_orange - name = "orange wedding dress" - desc = "A big and puffy orange dress." - icon_state = "bride_orange" - item_state = "bride_orange" - item_color = "bride_orange" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/wedding/bride_purple - name = "purple wedding dress" - desc = "A big and puffy purple dress." - icon_state = "bride_purple" - item_state = "bride_purple" - item_color = "bride_purple" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/wedding/bride_blue - name = "blue wedding dress" - desc = "A big and puffy blue dress." - icon_state = "bride_blue" - item_state = "bride_blue" - item_color = "bride_blue" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/wedding/bride_red - name = "red wedding dress" - desc = "A big and puffy red dress." - icon_state = "bride_red" - item_state = "bride_red" - item_color = "bride_red" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/wedding/bride_white - name = "white wedding dress" - desc = "A white wedding gown made from the finest silk." - icon_state = "bride_white" - item_state = "bride_white" - item_color = "bride_white" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/mankini - name = "pink mankini" - icon_state = "mankini" - item_state = "mankini" - item_color = "mankini" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE -/* - -/obj/item/clothing/under/psysuit - name = "dark undersuit" - desc = "A thick, layered grey undersuit lined with power cables. Feels a little like wearing an electrical storm." - icon_state = "psysuit" - item_state = "psysuit" - item_color = "psysuit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - - -/obj/item/clothing/under/officeruniform - name = "officer's uniform" - desc = "Bestraft die Juden fur ihre Verbrechen." - icon_state = "officeruniform" - item_state = "officeruniform" - item_color = "officeruniform" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - - -/obj/item/clothing/under/soldieruniform - name = "soldier's uniform" - desc = "Bestraft die Verbundeten fur ihren Widerstand." - icon_state = "soldieruniform" - item_state = "soldieruniform" - item_color = "soldieruniform" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - -*/ -/obj/item/clothing/under/squatter_outfit - name = "slav squatter tracksuit" - desc = "Cyka blyat." - icon_state = "squatteroutfit" - item_state = "squatteroutfit" - item_color = "squatteroutfit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/russobluecamooutfit - name = "russian blue camo" - desc = "Drop and give me dvadtsat!" - icon_state = "russobluecamo" - item_state = "russobluecamo" - item_color = "russobluecamo" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/stilsuit - name = "stillsuit" - desc = "Designed to preserve bodymoisture." - icon_state = "stilsuit" - item_state = "stilsuit" - item_color = "stilsuit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/aviatoruniform - name = "aviator uniform" - desc = "Now you can look absolutely dashing!" - icon_state = "aviator_uniform" - item_state = "aviator_uniform" - item_color = "aviator_uniform" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/bikersuit - name = "biker's outfit" - icon_state = "biker" - item_state = "biker" - item_color = "biker" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/jacketsuit - name = "richard's outfit" - desc = "Do you know what time it is?" - icon_state = "jacket" - item_state = "jacket" - item_color = "jacket" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -obj/item/clothing/under/mega - name = "\improper DRN-001 suit" - desc = "The original. Simple, yet very adaptable." - icon_state = "mega" - item_state = "mega" - item_color = "mega" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/proto - name = "The Prototype Suit" - desc = "Even robots know scarves are the perfect accessory for a brooding rival." - icon_state = "proto" - item_state = "proto" - item_color = "proto" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/megax - name = "\improper Maverick Hunter regalia" - desc = "The best outfit for taking out rogue borgs." - icon_state = "megax" - item_state = "megax" - item_color = "megax" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/joe - name = "The Sniper Suit" - desc = "Mass produced combat robots with a rather unfitting name." - icon_state = "joe" - item_state = "joe" - item_color = "joe" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/roll - name = "\improper DRN-002 Dress" - desc = "A simple red dress, the good doctor's second robot wasn't quite as exciting as the first." - icon_state = "roll" - item_state = "roll" - item_color = "roll" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/gokugidown - name = "turtle hermit undershirt" - desc = "Something seems oddly familiar about this outfit..." - icon_state = "gokugidown" - item_state = "gokugidown" - item_color = "gokugidown" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/gokugi - name = "turtle hermit outfit" - desc = "An outfit from one trained by the great Turtle Hermit." - icon_state = "gokugi" - item_state = "gokugi" - item_color = "gokugi" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/doomguy - name = "\improper Doomguy's pants" - desc = "" - icon_state = "doom" - item_state = "doom" - item_color = "doom" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/vault13 - name = "vault 13 Jumpsuit" - desc = "Oddly similar to the station's usual jumpsuits, but with a rustic charm to it. Has a large thirteen emblazened on the back." - icon_state = "v13-jumpsuit" - item_state = "v13-jumpsuit" - item_color = "v13-jumpsuit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/vault - name = "vault jumpsuit" - desc = "Oddly similar to the station's usual jumpsuits, but with a rustic charm to it." - icon_state = "v-jumpsuit" - item_state = "v-jumpsuit" - item_color = "v-jumpsuit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/clownpiece - name = "Clownpiece's Pierrot suit" - desc = "A female-sized set of leggings and shirt with a pattern similar to the American flag, featuring a frilled collar." - icon_state = "clownpiece" - item_state = "clownpiece" - item_color = "clownpiece" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/cia - name = "casual IAA outfit" - desc = "Just looking at this makes you feel in charge." - icon_state = "cia" - item_state = "cia" - item_color = "cia" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/greaser - name = "greaser outfit" - desc = "The one that you want!" - icon_state = "greaser_default" - item_state = "greaser_default" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/greaser/New() - var/greaser_colour = "default" - switch(rand(1,4)) - if(1) - greaser_colour = "default" - if(2) - greaser_colour = "cult" - if(3) - greaser_colour = "spider" - if(4) - greaser_colour = "snakes" - desc = "Tunnel Snakes Rule!" - icon_state = "greaser_[greaser_colour]" - item_state = "greaser_[greaser_colour]" - item_color = "greaser_[greaser_colour]" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - - -/obj/item/clothing/under/wintercasualwear - name = "winter casualwear" - desc = "Perfect for winter!" - icon_state = "shizunewinter" - item_state = "shizunewinter" - item_color = "shizunewinter" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/casualwear - name = "spring casualwear" - desc = "Perfect for spring!" - icon_state = "shizunenormal" - item_state = "shizunenormal" - item_color = "shizunenormal" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/keyholesweater - name = "keyhole sweater" - desc = "What is the point of this, anyway?" - icon_state = "keyholesweater" - item_state = "keyholesweater" - item_color = "keyholesweater" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/casualhoodie - name = "casual hoodie" - desc = "Pefect for lounging about in." - icon_state = "hoodiejeans" - item_state = "hoodiejeans" - item_color = "hoodiejeans" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - -/obj/item/clothing/under/casualhoodie/skirt - icon_state = "hoodieskirt" - item_state = "hoodieskirt" - item_color = "hoodieskirt" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - mutantrace_variation = NONE - -/* -/obj/item/clothing/under/mummy_rags - name = "mummy rags" - desc = "Ancient rags taken off from some mummy." - icon_state = "mummy" - item_state = "mummy" - item_color = "mummy" - can_adjust = 0 - has_sensor = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - - -/obj/item/clothing/under/neorussian - name = "neo-Russian uniform" - desc = "Employs a special toshnit pattern, will render you invisible when you eat a potato on an empty stomach." - icon_state = "nr_uniform" - item_state = "nr_uniform" - item_color = "nr_uniform" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' -*/ - -/obj/item/clothing/under/rottensuit - name = "rotten suit" - desc = "This suit seems perfect for wearing underneath a disguise." - icon_state = "rottensuit" - item_state = "rottensuit" - item_color = "rottensuit" - can_adjust = 0 - icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/uniforms.dmi' - mutantrace_variation = NONE - diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm deleted file mode 100644 index 2987b52338..0000000000 --- a/code/modules/crafting/recipes.dm +++ /dev/null @@ -1,11 +0,0 @@ -/datum/crafting_recipe - var/name = "" //in-game display name - var/reqs[] = list() //type paths of items consumed associated with how many are needed - var/result //type path of item resulting from this craft - var/tools[] = list() //type paths of items needed but not consumed - var/time = 30 //time in deciseconds - var/parts[] = list() //type paths of items that will be placed in the result - var/chem_catalysts[] = list() //like tools but for reagents - var/category = CAT_NONE //where it shows up in the crafting UI - var/subcategory = CAT_NONE - var/always_availible = TRUE //Set to FALSE if it needs to be learned first. \ No newline at end of file diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm index 634401d0d8..3b1b00fc3a 100644 --- a/code/modules/detectivework/detective_work.dm +++ b/code/modules/detectivework/detective_work.dm @@ -9,8 +9,7 @@ else if(M.bloody_hands > 1) if(add_blood_DNA(M.blood_DNA, M.diseases)) M.bloody_hands-- - if(!suit_fibers) - suit_fibers = list() + LAZYINITLIST(suit_fibers) var/fibertext var/item_multiplier = isitem(src)?1.2:1 if(M.wear_suit) @@ -66,7 +65,6 @@ fingerprintslast = M.ckey - //Set ignoregloves to add prints irrespective of the mob having gloves on. /atom/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE) if(!M || !M.key) @@ -93,15 +91,10 @@ fingerprints[full_print] = full_print /atom/proc/transfer_fingerprints_to(atom/A) - // Make sure everything are lists. - LAZYINITLIST(A.fingerprints) - LAZYINITLIST(A.fingerprintshidden) - LAZYINITLIST(fingerprints) - LAZYINITLIST(fingerprintshidden) - - // Transfer if(fingerprints) - A.fingerprints |= fingerprints.Copy() //detective + LAZYINITLIST(A.fingerprints) + A.fingerprints |= fingerprints //detective if(fingerprintshidden) - A.fingerprintshidden |= fingerprintshidden.Copy() //admin - A.fingerprintslast = fingerprintslast \ No newline at end of file + LAZYINITLIST(A.fingerprintshidden) + A.fingerprintshidden |= fingerprintshidden //admin + A.fingerprintslast = fingerprintslast diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm index a2860f8c43..9b114829e1 100644 --- a/code/modules/detectivework/scanner.dm +++ b/code/modules/detectivework/scanner.dm @@ -123,7 +123,7 @@ // We gathered everything. Create a fork and slowly display the results to the holder of the scanner. var/found_something = FALSE - add_log("[STATION_TIME_TIMESTAMP("hh:mm:ss")][get_timestamp()] - [target_name]", 0) + add_log("[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)][get_timestamp()] - [target_name]", 0) // Fingerprints if(length(fingerprints)) diff --git a/code/modules/emoji/emoji_parse.dm b/code/modules/emoji/emoji_parse.dm index 2f4a84c646..65e8063ce0 100644 --- a/code/modules/emoji/emoji_parse.dm +++ b/code/modules/emoji/emoji_parse.dm @@ -1,4 +1,4 @@ -/proc/emoji_parse(text) +/proc/emoji_parse(text) //turns :ai: into an emoji in text. . = text if(!CONFIG_GET(flag/emojis)) return @@ -12,14 +12,14 @@ parsed += copytext(text, pos, search) if(search) pos = search - search = findtext(text, ":", pos+1) + search = findtext(text, ":", pos + length(text[pos])) if(search) - emoji = lowertext(copytext(text, pos+1, search)) + emoji = lowertext(copytext(text, pos + length(text[pos]), search)) var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat) var/tag = sheet.icon_tag("emoji-[emoji]") if(tag) parsed += tag - pos = search + 1 + pos = search + length(text[pos]) else parsed += copytext(text, pos, search) pos = search @@ -30,3 +30,24 @@ break return parsed +/proc/emoji_sanitize(text) //cuts any text that would not be parsed as an emoji + . = text + if(!CONFIG_GET(flag/emojis)) + return + var/static/list/emojis = icon_states(icon('icons/emoji.dmi')) + var/final = "" //only tags are added to this + var/pos = 1 + var/search = 0 + while(1) + search = findtext(text, ":", pos) + if(search) + pos = search + search = findtext(text, ":", pos + length(text[pos])) + if(search) + var/word = lowertext(copytext(text, pos + length(text[pos]), search)) + if(word in emojis) + final += lowertext(copytext(text, pos, search + length(text[search]))) + pos = search + length(text[search]) + continue + break + return final diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index 8b410130cb..418b75e1ce 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -12,7 +12,7 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) return ..() //this is snowflake because of a byond bug (ID:2306577), do not attempt to call non-builtin procs in this if - if(copytext(E.name,1,32) == "Maximum recursion level reached") + if(copytext(E.name, 1, 32) == "Maximum recursion level reached")//32 == length() of that string + 1 //log to world while intentionally triggering the byond bug. log_world("runtime error: [E.name]\n[E.desc]") //if we got to here without silently ending, the byond bug has been fixed. @@ -102,7 +102,7 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) usrinfo = null continue // Our usr info is better, replace it - if(copytext(line, 1, 3) != " ") + if(copytext(line, 1, 3) != " ")//3 == length(" ") + 1 desclines += (" " + line) // Pad any unpadded lines, so they look pretty else desclines += line diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm index 65d4af56bd..d4f51e995e 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -43,6 +43,9 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 icon = 'icons/obj/objects.dmi' icon_state = "immrod" throwforce = 100 + move_force = INFINITY + move_resist = INFINITY + pull_force = INFINITY density = TRUE anchored = TRUE flags_1 = PREVENT_CONTENTS_EXPLOSION_1 diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm index a1a82ea5f7..d4eb6ded4c 100644 --- a/code/modules/events/meteor_wave.dm +++ b/code/modules/events/meteor_wave.dm @@ -18,6 +18,7 @@ announceWhen = 1 var/list/wave_type var/wave_name = "normal" + var/direction /datum/round_event/meteor_wave/setup() announceWhen = 1 @@ -26,7 +27,6 @@ startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE) endWhen = startWhen + 60 - /datum/round_event/meteor_wave/New() ..() if(!wave_type) @@ -38,6 +38,8 @@ "normal" = 50, "threatening" = 40, "catastrophic" = 10)) + if(!direction) + direction = pick(GLOB.cardinals) switch(wave_name) if("normal") wave_type = GLOB.meteors_normal @@ -59,11 +61,21 @@ kill() /datum/round_event/meteor_wave/announce(fake) - priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.[GLOB.singularity_counter ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]", "Meteor Alert", "meteors") + var/directionstring + switch(direction) + if(NORTH) + directionstring = " towards the fore" + if(SOUTH) + directionstring = " towards the aft" + if(EAST) + directionstring = " towards starboard" + if(WEST) + directionstring = " towards port" + priority_announce("Meteors have been detected on collision course with the station[directionstring]. Estimated time until impact: [round((startWhen * SSevents.wait) / 10, 0.1)] seconds.[GLOB.singularity_counter ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]", "Meteor Alert", "meteors") /datum/round_event/meteor_wave/tick() if(ISMULTIPLE(activeFor, 3)) - spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm + spawn_meteors(5, wave_type, direction) //meteor list types defined in gamemode/meteor/meteors.dm /datum/round_event_control/meteor_wave/threatening name = "Meteor Wave: Threatening" diff --git a/code/modules/events/shuttle_loan.dm b/code/modules/events/shuttle_loan.dm index f006f2b358..c585961604 100644 --- a/code/modules/events/shuttle_loan.dm +++ b/code/modules/events/shuttle_loan.dm @@ -133,7 +133,7 @@ shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate/ranged/infiltrator) if(RUSKY_PARTY) - var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/misc/party] + var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/organic/party] pack.generate(pick_n_take(empty_shuttle_turfs)) shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian) diff --git a/code/modules/fields/timestop.dm b/code/modules/fields/timestop.dm index c59a8004ca..56abef8cd6 100644 --- a/code/modules/fields/timestop.dm +++ b/code/modules/fields/timestop.dm @@ -9,7 +9,7 @@ pixel_x = -64 pixel_y = -64 mouse_opacity = MOUSE_OPACITY_TRANSPARENT - var/list/immune = list() // the one who creates the timestop is immune + var/list/immune = list() // the one who creates the timestop is immune, which includes wizards and the dead slime you murdered to make this chronofield var/turf/target var/freezerange = 2 var/duration = 140 @@ -27,10 +27,10 @@ for(var/A in immune_atoms) immune[A] = TRUE for(var/mob/living/L in GLOB.player_list) - if(locate(/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop) in L.mind.spell_list) //People who can stop time are immune to its effects + if(locate(/obj/effect/proc_holder/spell/aoe_turf/timestop) in L.mind.spell_list) //People who can stop time are immune to its effects immune[L] = TRUE for(var/mob/living/simple_animal/hostile/guardian/G in GLOB.parasites) - if(G.summoner && locate(/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop) in G.summoner.mind.spell_list) //It would only make sense that a person's stand would also be immune. + if(G.summoner && locate(/obj/effect/proc_holder/spell/aoe_turf/timestop) in G.summoner.mind.spell_list) //It would only make sense that a person's stand would also be immune. immune[G] = TRUE if(start) timestop() @@ -46,9 +46,8 @@ chronofield = make_field(/datum/proximity_monitor/advanced/timestop, list("current_range" = freezerange, "host" = src, "immune" = immune, "check_anti_magic" = check_anti_magic, "check_holy" = check_holy)) QDEL_IN(src, duration) -/obj/effect/timestop/wizard +/obj/effect/timestop/magic check_anti_magic = TRUE - duration = 100 /datum/proximity_monitor/advanced/timestop name = "chronofield" @@ -56,9 +55,10 @@ field_shape = FIELD_SHAPE_RADIUS_SQUARE requires_processing = TRUE var/list/immune = list() - var/list/mob/living/frozen_mobs = list() - var/list/obj/item/projectile/frozen_projectiles = list() - var/list/atom/movable/frozen_throws = list() + var/list/frozen_things = list() + var/list/frozen_mobs = list() //cached separately for processing + var/list/frozen_structures = list() //Also machinery, and only frozen aestethically + var/list/frozen_turfs = list() //Only aesthetically var/check_anti_magic = FALSE var/check_holy = FALSE @@ -74,85 +74,125 @@ /datum/proximity_monitor/advanced/timestop/proc/freeze_atom(atom/movable/A) if(immune[A] || global_frozen_atoms[A] || !istype(A)) return FALSE - if(A.throwing) - freeze_throwing(A) + if(ismob(A)) + var/mob/M = A + if(M.anti_magic_check(check_anti_magic, check_holy)) + immune[A] = TRUE + return + var/frozen = TRUE if(isliving(A)) freeze_mob(A) else if(istype(A, /obj/item/projectile)) freeze_projectile(A) + else if(istype(A, /obj/mecha)) + freeze_mecha(A) + else if((ismachinery(A) && !istype(A, /obj/machinery/light)) || isstructure(A)) //Special exception for light fixtures since recoloring causes them to change light + freeze_structure(A) else - return FALSE + frozen = FALSE + if(A.throwing) + freeze_throwing(A) + frozen = TRUE + if(!frozen) + return + frozen_things[A] = A.move_resist + A.move_resist = INFINITY + global_frozen_atoms[A] = src into_the_negative_zone(A) + RegisterSignal(A, COMSIG_MOVABLE_PRE_MOVE, .proc/unfreeze_atom) + RegisterSignal(A, COMSIG_ITEM_PICKUP, .proc/unfreeze_atom) return TRUE /datum/proximity_monitor/advanced/timestop/proc/unfreeze_all() - for(var/i in frozen_projectiles) - unfreeze_projectile(i) - for(var/i in frozen_mobs) - unfreeze_mob(i) - for(var/i in frozen_throws) - unfreeze_throw(i) + for(var/i in frozen_things) + unfreeze_atom(i) + for(var/T in frozen_turfs) + unfreeze_turf(T) + +/datum/proximity_monitor/advanced/timestop/proc/unfreeze_atom(atom/movable/A) + if(A.throwing) + unfreeze_throwing(A) + if(isliving(A)) + unfreeze_mob(A) + else if(istype(A, /obj/item/projectile)) + unfreeze_projectile(A) + else if(istype(A, /obj/mecha)) + unfreeze_mecha(A) + + UnregisterSignal(A, COMSIG_MOVABLE_PRE_MOVE) + UnregisterSignal(A, COMSIG_ITEM_PICKUP) + escape_the_negative_zone(A) + A.move_resist = frozen_things[A] + frozen_things -= A + global_frozen_atoms -= A + +/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/mecha/M) + M.completely_disabled = TRUE + +/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/mecha/M) + M.completely_disabled = FALSE /datum/proximity_monitor/advanced/timestop/proc/freeze_throwing(atom/movable/AM) var/datum/thrownthing/T = AM.throwing T.paused = TRUE - frozen_throws[AM] = T - global_frozen_atoms[AM] = TRUE -/datum/proximity_monitor/advanced/timestop/proc/unfreeze_throw(atom/movable/AM) - var/datum/thrownthing/T = frozen_throws[AM] - T.paused = FALSE - frozen_throws -= AM - global_frozen_atoms -= AM +/datum/proximity_monitor/advanced/timestop/proc/unfreeze_throwing(atom/movable/AM) + var/datum/thrownthing/T = AM.throwing + if(T) + T.paused = FALSE + +/datum/proximity_monitor/advanced/timestop/proc/freeze_turf(turf/T) + into_the_negative_zone(T) + frozen_turfs += T + +/datum/proximity_monitor/advanced/timestop/proc/unfreeze_turf(turf/T) + escape_the_negative_zone(T) + +/datum/proximity_monitor/advanced/timestop/proc/freeze_structure(obj/O) + into_the_negative_zone(O) + frozen_structures += O + +/datum/proximity_monitor/advanced/timestop/proc/unfreeze_structure(obj/O) + escape_the_negative_zone(O) /datum/proximity_monitor/advanced/timestop/process() for(var/i in frozen_mobs) var/mob/living/m = i - if(get_dist(get_turf(m), get_turf(host)) > current_range) - unfreeze_mob(m) - else - m.Stun(20, 1, 1) + m.Stun(20, 1, 1) /datum/proximity_monitor/advanced/timestop/setup_field_turf(turf/T) for(var/i in T.contents) freeze_atom(i) + freeze_turf(T) return ..() -/datum/proximity_monitor/advanced/timestop/proc/unfreeze_projectile(obj/item/projectile/P) - escape_the_negative_zone(P) - frozen_projectiles -= P - P.paused = FALSE - global_frozen_atoms -= P - /datum/proximity_monitor/advanced/timestop/proc/freeze_projectile(obj/item/projectile/P) - frozen_projectiles[P] = TRUE P.paused = TRUE - global_frozen_atoms[P] = TRUE + +/datum/proximity_monitor/advanced/timestop/proc/unfreeze_projectile(obj/item/projectile/P) + P.paused = FALSE /datum/proximity_monitor/advanced/timestop/proc/freeze_mob(mob/living/L) - if(L.anti_magic_check(check_anti_magic, check_holy)) - immune += L - return + frozen_mobs += L L.Stun(20, 1, 1) - frozen_mobs[L] = L.anchored - L.anchored = TRUE - global_frozen_atoms[L] = TRUE - if(ishostile(L)) - var/mob/living/simple_animal/hostile/H = L - H.toggle_ai(AI_OFF) - H.LoseTarget() + ADD_TRAIT(L, TRAIT_MUTE, TIMESTOP_TRAIT) + walk(L, 0) //stops them mid pathing even if they're stunimmune + if(isanimal(L)) + var/mob/living/simple_animal/S = L + S.toggle_ai(AI_OFF) + if(ishostile(L)) + var/mob/living/simple_animal/hostile/H = L + H.LoseTarget() /datum/proximity_monitor/advanced/timestop/proc/unfreeze_mob(mob/living/L) - escape_the_negative_zone(L) L.AdjustStun(-20, 1, 1) - L.anchored = frozen_mobs[L] + REMOVE_TRAIT(L, TRAIT_MUTE, TIMESTOP_TRAIT) frozen_mobs -= L - global_frozen_atoms -= L - if(ishostile(L)) - var/mob/living/simple_animal/hostile/H = L - H.toggle_ai(initial(H.AIStatus)) + if(isanimal(L)) + var/mob/living/simple_animal/S = L + S.toggle_ai(initial(S.AIStatus)) //you don't look quite right, is something the matter? /datum/proximity_monitor/advanced/timestop/proc/into_the_negative_zone(atom/A) @@ -160,4 +200,4 @@ //let's put some colour back into your cheeks /datum/proximity_monitor/advanced/timestop/proc/escape_the_negative_zone(atom/A) - A.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) \ No newline at end of file + A.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index f5262742e2..83dbad0246 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -214,9 +214,9 @@ GLOBAL_LIST_INIT(hallucination_list, list( . = ..() name = "alien hunter ([rand(1, 1000)])" -/obj/effect/hallucination/simple/xeno/throw_impact(A) +/obj/effect/hallucination/simple/xeno/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) update_icon("alienh_pounce") - if(A == target && target.stat!=DEAD) + if(hit_atom == target && target.stat!=DEAD) target.Knockdown(100) target.visible_message("[target] flails around wildly.","[name] pounces on you!") diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 7111ae416b..cd5c9d850b 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -101,10 +101,10 @@ to_chat(user, "You heat [name] with [I]!") ..() -/obj/item/reagent_containers/food/drinks/throw_impact(atom/target, datum/thrownthing/throwinfo) +/obj/item/reagent_containers/food/drinks/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() if(!.) //if the bottle wasn't caught - smash(target, throwinfo.thrower, TRUE) + smash(hit_atom, throwingdatum?.thrower, TRUE) /obj/item/reagent_containers/food/drinks/proc/smash(atom/target, mob/thrower, ranged = FALSE) if(!isGlass) diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 757af11b62..7f2b24ca11 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -505,7 +505,7 @@ isGlass = FALSE return -/obj/item/reagent_containers/food/drinks/bottle/molotov/throw_impact(atom/target,datum/thrownthing/throwdata) +/obj/item/reagent_containers/food/drinks/bottle/molotov/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) var/firestarter = 0 for(var/datum/reagent/R in reagents.reagent_list) for(var/A in accelerants) @@ -513,8 +513,8 @@ firestarter = 1 break if(firestarter && active) - target.fire_act() - new /obj/effect/hotspot(get_turf(target)) + hit_atom.fire_act() + new /obj/effect/hotspot(get_turf(hit_atom)) ..() /obj/item/reagent_containers/food/drinks/bottle/molotov/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm index d8dafb7b8e..af70ad2f57 100644 --- a/code/modules/food_and_drinks/food/condiment.dm +++ b/code/modules/food_and_drinks/food/condiment.dm @@ -310,7 +310,13 @@ originalname = "astrotame" list_reagents = list(/datum/reagent/consumable/astrotame = 5) +//Other Sauce /obj/item/reagent_containers/food/condiment/pack/bbqsauce name = "bbq sauce pack" originalname = "bbq sauce" list_reagents = list(/datum/reagent/consumable/bbqsauce = 10) + +/obj/item/reagent_containers/food/condiment/pack/soysauce + name = "soy sauce pack" + originalname = "soy sauce" + list_reagents = list(/datum/reagent/consumable/soysauce = 10) \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks_egg.dm b/code/modules/food_and_drinks/food/snacks_egg.dm index 183e64ff7e..f01966a0ff 100644 --- a/code/modules/food_and_drinks/food/snacks_egg.dm +++ b/code/modules/food_and_drinks/food/snacks_egg.dm @@ -31,7 +31,7 @@ var/color = mix_color_from_reagents(reagents.reagent_list) add_atom_colour(color, FIXED_COLOUR_PRIORITY) -/obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) +/obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) //was it caught by a mob? var/turf/T = get_turf(hit_atom) new/obj/effect/decal/cleanable/egg_smudge(T) diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index 0c17814c98..41b08e8c7f 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -443,8 +443,8 @@ head.color = C add_overlay(head) -/obj/item/reagent_containers/food/snacks/lollipop/throw_impact(atom/A) - ..(A) +/obj/item/reagent_containers/food/snacks/lollipop/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + ..(hit_atom) throw_speed = 1 throwforce = 0 diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm index 357a921c66..0c3623efda 100644 --- a/code/modules/food_and_drinks/food/snacks_pie.dm +++ b/code/modules/food_and_drinks/food/snacks_pie.dm @@ -29,7 +29,7 @@ foodtype = GRAIN | DAIRY | SUGAR var/stunning = TRUE -/obj/item/reagent_containers/food/snacks/pie/cream/throw_impact(atom/hit_atom) +/obj/item/reagent_containers/food/snacks/pie/cream/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() if(!.) //if we're not being caught splat(hit_atom) diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index 27ee54815f..f3b8e466f3 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -66,10 +66,12 @@ God bless America. oil_use = initial(oil_use) - (oil_efficiency * 0.0095) fry_speed = oil_efficiency -/obj/machinery/deepfryer/examine() +/obj/machinery/deepfryer/examine(mob/user) . = ..() if(frying) . += "You can make out \a [frying] in the oil." + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Frying at [fry_speed*100]% speed.
    Using [oil_use*10] units of oil per second.
    " /obj/machinery/deepfryer/attackby(obj/item/I, mob/user) if(istype(I, /obj/item/reagent_containers/pill)) diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index e5c5a4f933..4406491f10 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -30,6 +30,14 @@ if(M.rating >= 2) ignore_clothing = TRUE +/obj/machinery/gibber/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Outputting [meat_produced] meat slab(s) after [gibtime*0.1] seconds of processing." + for(var/obj/item/stock_parts/manipulator/M in component_parts) + if(M.rating >= 2) + . += "Gibber has been upgraded to process inorganic materials." + /obj/machinery/gibber/update_icon() cut_overlays() if (dirty) diff --git a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm index c25cb2288f..3d7341308b 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm @@ -1,6 +1,6 @@ /obj/machinery/monkey_recycler name = "monkey recycler" - desc = "A machine used for recycling dead monkeys into monkey cubes. It currently produces 1 cube for every 5 monkeys inserted." // except it literally never does + desc = "A machine used for recycling dead monkeys into monkey cubes." // except it literally never does icon = 'icons/obj/kitchen.dmi' icon_state = "grinder" layer = BELOW_OBJ_LAYER @@ -22,7 +22,11 @@ cubes_made = M.rating cube_production = cubes_made required_grind = req_grind - src.desc = "A machine used for recycling dead monkeys into monkey cubes. It currently produces [cubes_made] cube(s) for every [required_grind] monkey(s) inserted." + +/obj/machinery/monkey_recycler/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Producing [cube_production] cubes for every monkey inserted." /obj/machinery/monkey_recycler/attackby(obj/item/O, mob/user, params) if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", O)) diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index 35ce25bbaf..b81c127523 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -21,6 +21,11 @@ for(var/obj/item/stock_parts/manipulator/M in component_parts) rating_speed = M.rating +/obj/machinery/processor/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Outputting [rating_amount] item(s) at [rating_speed*100]% speed." + /obj/machinery/processor/proc/process_food(datum/food_processor_process/recipe, atom/movable/what) if (recipe.output && loc && !QDELETED(src)) for(var/i = 0, i < rating_amount, i++) diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 893a53ede7..7619f68448 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -33,6 +33,11 @@ for(var/obj/item/stock_parts/matter_bin/B in component_parts) max_n_of_items = 1500 * B.rating +/obj/machinery/smartfridge/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: This unit can hold a maximum of [max_n_of_items] items." + /obj/machinery/smartfridge/power_change() ..() update_icon() diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index 351495b97a..bd556b8397 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -231,7 +231,7 @@ if(boxes.len >= 3 && prob(25 * boxes.len)) disperse_pizzas() -/obj/item/pizzabox/throw_impact(atom/movable/AM) +/obj/item/pizzabox/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(boxes.len >= 2 && prob(20 * boxes.len)) disperse_pizzas() diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm index 130640ee8a..fd332a38df 100644 --- a/code/modules/food_and_drinks/recipes/food_mixtures.dm +++ b/code/modules/food_and_drinks/recipes/food_mixtures.dm @@ -15,9 +15,9 @@ required_catalysts = list(/datum/reagent/consumable/enzyme = 5) mob_react = FALSE -/datum/chemical_reaction/tofu/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/tofu/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/reagent_containers/food/snacks/tofu(location) return @@ -26,9 +26,9 @@ id = "chocolate_bar" required_reagents = list(/datum/reagent/consumable/soymilk = 2, /datum/reagent/consumable/coco = 2, /datum/reagent/consumable/sugar = 2) -/datum/chemical_reaction/chocolate_bar/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/chocolate_bar/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/reagent_containers/food/snacks/chocolatebar(location) return @@ -39,9 +39,9 @@ required_reagents = list(/datum/reagent/consumable/milk/chocolate_milk = 4, /datum/reagent/consumable/sugar = 2) mob_react = FALSE -/datum/chemical_reaction/chocolate_bar2/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/chocolate_bar2/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/reagent_containers/food/snacks/chocolatebar(location) return @@ -90,9 +90,9 @@ required_reagents = list(/datum/reagent/consumable/milk = 40) required_catalysts = list(/datum/reagent/consumable/enzyme = 5) -/datum/chemical_reaction/cheesewheel/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/cheesewheel/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/reagent_containers/food/snacks/store/cheesewheel(location) /datum/chemical_reaction/synthmeat @@ -101,9 +101,9 @@ required_reagents = list(/datum/reagent/blood = 5, /datum/reagent/medicine/cryoxadone = 1) mob_react = FALSE -/datum/chemical_reaction/synthmeat/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/synthmeat/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/reagent_containers/food/snacks/meat/slab/synthmeat(location) /datum/chemical_reaction/hot_ramen @@ -137,9 +137,9 @@ required_reagents = list(/datum/reagent/water = 10, /datum/reagent/consumable/flour = 15) mix_message = "The ingredients form a dough." -/datum/chemical_reaction/dough/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/dough/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/reagent_containers/food/snacks/dough(location) /datum/chemical_reaction/cakebatter @@ -148,9 +148,9 @@ required_reagents = list(/datum/reagent/consumable/eggyolk = 15, /datum/reagent/consumable/flour = 15, /datum/reagent/consumable/sugar = 5) mix_message = "The ingredients form a cake batter." -/datum/chemical_reaction/cakebatter/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/cakebatter/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/reagent_containers/food/snacks/cakebatter(location) /datum/chemical_reaction/cakebatter/vegan diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm index c25cd9bed6..f168896164 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm @@ -69,9 +69,9 @@ /datum/crafting_recipe/food/birthdaycake name = "Birthday cake" reqs = list( - /datum/reagent/consumable/sugar = 10, + /datum/reagent/consumable/sugar = 5, + /datum/reagent/consumable/caramel =2, /obj/item/candle = 1, - /obj/item/reagent_containers/food/snacks/grown/vanillapod = 2, /obj/item/reagent_containers/food/snacks/store/cake/plain = 1 ) result = /obj/item/reagent_containers/food/snacks/store/cake/birthday diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm index f0fe936d05..b545702e3e 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm @@ -481,6 +481,8 @@ datum/crafting_recipe/food/donut/meat /obj/item/reagent_containers/food/snacks/grown/oat = 1 ) result = /obj/item/reagent_containers/food/snacks/oatmealcookie + subcategory = CAT_PASTRY + /datum/crafting_recipe/food/raisincookie name = "Raisin cookie" diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 6f1e19d5e0..74432c7cbe 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -61,8 +61,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico // Arguments are in the form "param[paramname]=thing" var/list/params = list() for(var/key in href_list) - if(length(key) > 7 && findtext(key, "param")) // 7 is the amount of characters in the basic param key template. - var/param_name = copytext(key, 7, -1) + if(length_char(key) > 7 && findtext(key, "param")) // 7 is the amount of characters in the basic param key template. + var/param_name = copytext_char(key, 7, -1) var/item = href_list[key] params[param_name] = item diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index d6918d58aa..d4dc3cb213 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -101,7 +101,7 @@ a.popt {text-decoration: none;} #ping { position: fixed; top: 0; - right: 115px; + right: 135px; width: 45px; background: #d0d0d0; height: 30px; @@ -131,13 +131,13 @@ a.popt {text-decoration: none;} } #userBar .subCell:hover {background: #ccc;} #userBar .toggle { - width: 40px; + width: 45px; background: #ccc; border-top: 0; float: right; text-align: center; } -#userBar .sub {clear: both; display: none; width: 160px;} +#userBar .sub {clear: both; display: none; width: 180px;} #userBar .sub.scroll {overflow-y: scroll;} #userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} #userBar .sub span { diff --git a/code/modules/goonchat/browserassets/css/font-awesome.css b/code/modules/goonchat/browserassets/css/font-awesome.css deleted file mode 100644 index cc99d7b337..0000000000 --- a/code/modules/goonchat/browserassets/css/font-awesome.css +++ /dev/null @@ -1,788 +0,0 @@ -@font-face{font-family:'FontAwesome';src:url('fontawesome-webfont.eot');src:url('fontawesome-webfont.eot') format('embedded-opentype'),url('fontawesome-webfont.woff') format('woff'),url('fontawesome-webfont.ttf') format('truetype'),url('fontawesome-webfont.svg') format('svg');font-weight:normal;font-style:normal;}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;} -[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none;} -.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em;} -a [class^="icon-"],a [class*=" icon-"]{display:inline;} -[class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571428em;text-align:right;padding-right:0.2857142857142857em;}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714286em;} -.icons-ul{margin-left:2.142857142857143em;list-style-type:none;}.icons-ul>li{position:relative;} -.icons-ul .icon-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;text-align:center;line-height:inherit;} -[class^="icon-"].hide,[class*=" icon-"].hide{display:none;} -.icon-muted{color:#eeeeee;} -.icon-light{color:#ffffff;} -.icon-dark{color:#333333;} -.icon-border{border:solid 1px #eeeeee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} -.icon-2x{font-size:2em;}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} -.icon-3x{font-size:3em;}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} -.icon-4x{font-size:4em;}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} -.icon-5x{font-size:5em;}.icon-5x.icon-border{border-width:5px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px;} -.pull-right{float:right;} -.pull-left{float:left;} -[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em;} -[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em;} -[class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0% 0%;background-repeat:repeat;margin-top:0;} -.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none;} -.btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em;} -.btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block;} -.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em;} -.btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em;} -.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em;} -.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em;} -.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0;}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em;} -.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em;} -.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em;} -.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{line-height:inherit;} -.icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%;}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em;} -.icon-stack .icon-stack-base{font-size:2em;*line-height:1em;} -.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;} -a .icon-stack,a .icon-spin{display:inline-block;text-decoration:none;} -@-moz-keyframes spin{0%{-moz-transform:rotate(0deg);} 100%{-moz-transform:rotate(359deg);}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(359deg);}}@-o-keyframes spin{0%{-o-transform:rotate(0deg);} 100%{-o-transform:rotate(359deg);}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg);} 100%{-ms-transform:rotate(359deg);}}@keyframes spin{0%{transform:rotate(0deg);} 100%{transform:rotate(359deg);}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);} -.icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);} -.icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);} -.icon-flip-horizontal:before{-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1);} -.icon-flip-vertical:before{-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1);} -a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .icon-flip-horizontal:before,a .icon-flip-vertical:before{display:inline-block;} -.icon-glass:before{content:"\f000";} -.icon-music:before{content:"\f001";} -.icon-search:before{content:"\f002";} -.icon-envelope-alt:before{content:"\f003";} -.icon-heart:before{content:"\f004";} -.icon-star:before{content:"\f005";} -.icon-star-empty:before{content:"\f006";} -.icon-user:before{content:"\f007";} -.icon-film:before{content:"\f008";} -.icon-th-large:before{content:"\f009";} -.icon-th:before{content:"\f00a";} -.icon-th-list:before{content:"\f00b";} -.icon-ok:before{content:"\f00c";} -.icon-remove:before{content:"\f00d";} -.icon-zoom-in:before{content:"\f00e";} -.icon-zoom-out:before{content:"\f010";} -.icon-power-off:before,.icon-off:before{content:"\f011";} -.icon-signal:before{content:"\f012";} -.icon-gear:before,.icon-cog:before{content:"\f013";} -.icon-trash:before{content:"\f014";} -.icon-home:before{content:"\f015";} -.icon-file-alt:before{content:"\f016";} -.icon-time:before{content:"\f017";} -.icon-road:before{content:"\f018";} -.icon-download-alt:before{content:"\f019";} -.icon-download:before{content:"\f01a";} -.icon-upload:before{content:"\f01b";} -.icon-inbox:before{content:"\f01c";} -.icon-play-circle:before{content:"\f01d";} -.icon-rotate-right:before,.icon-repeat:before{content:"\f01e";} -.icon-refresh:before{content:"\f021";} -.icon-list-alt:before{content:"\f022";} -.icon-lock:before{content:"\f023";} -.icon-flag:before{content:"\f024";} -.icon-headphones:before{content:"\f025";} -.icon-volume-off:before{content:"\f026";} -.icon-volume-down:before{content:"\f027";} -.icon-volume-up:before{content:"\f028";} -.icon-qrcode:before{content:"\f029";} -.icon-barcode:before{content:"\f02a";} -.icon-tag:before{content:"\f02b";} -.icon-tags:before{content:"\f02c";} -.icon-book:before{content:"\f02d";} -.icon-bookmark:before{content:"\f02e";} -.icon-print:before{content:"\f02f";} -.icon-camera:before{content:"\f030";} -.icon-font:before{content:"\f031";} -.icon-bold:before{content:"\f032";} -.icon-italic:before{content:"\f033";} -.icon-text-height:before{content:"\f034";} -.icon-text-width:before{content:"\f035";} -.icon-align-left:before{content:"\f036";} -.icon-align-center:before{content:"\f037";} -.icon-align-right:before{content:"\f038";} -.icon-align-justify:before{content:"\f039";} -.icon-list:before{content:"\f03a";} -.icon-indent-left:before{content:"\f03b";} -.icon-indent-right:before{content:"\f03c";} -.icon-facetime-video:before{content:"\f03d";} -.icon-picture:before{content:"\f03e";} -.icon-pencil:before{content:"\f040";} -.icon-map-marker:before{content:"\f041";} -.icon-adjust:before{content:"\f042";} -.icon-tint:before{content:"\f043";} -.icon-edit:before{content:"\f044";} -.icon-share:before{content:"\f045";} -.icon-check:before{content:"\f046";} -.icon-move:before{content:"\f047";} -.icon-step-backward:before{content:"\f048";} -.icon-fast-backward:before{content:"\f049";} -.icon-backward:before{content:"\f04a";} -.icon-play:before{content:"\f04b";} -.icon-pause:before{content:"\f04c";} -.icon-stop:before{content:"\f04d";} -.icon-forward:before{content:"\f04e";} -.icon-fast-forward:before{content:"\f050";} -.icon-step-forward:before{content:"\f051";} -.icon-eject:before{content:"\f052";} -.icon-chevron-left:before{content:"\f053";} -.icon-chevron-right:before{content:"\f054";} -.icon-plus-sign:before{content:"\f055";} -.icon-minus-sign:before{content:"\f056";} -.icon-remove-sign:before{content:"\f057";} -.icon-ok-sign:before{content:"\f058";} -.icon-question-sign:before{content:"\f059";} -.icon-info-sign:before{content:"\f05a";} -.icon-screenshot:before{content:"\f05b";} -.icon-remove-circle:before{content:"\f05c";} -.icon-ok-circle:before{content:"\f05d";} -.icon-ban-circle:before{content:"\f05e";} -.icon-arrow-left:before{content:"\f060";} -.icon-arrow-right:before{content:"\f061";} -.icon-arrow-up:before{content:"\f062";} -.icon-arrow-down:before{content:"\f063";} -.icon-mail-forward:before,.icon-share-alt:before{content:"\f064";} -.icon-resize-full:before{content:"\f065";} -.icon-resize-small:before{content:"\f066";} -.icon-plus:before{content:"\f067";} -.icon-minus:before{content:"\f068";} -.icon-asterisk:before{content:"\f069";} -.icon-exclamation-sign:before{content:"\f06a";} -.icon-gift:before{content:"\f06b";} -.icon-leaf:before{content:"\f06c";} -.icon-fire:before{content:"\f06d";} -.icon-eye-open:before{content:"\f06e";} -.icon-eye-close:before{content:"\f070";} -.icon-warning-sign:before{content:"\f071";} -.icon-plane:before{content:"\f072";} -.icon-calendar:before{content:"\f073";} -.icon-random:before{content:"\f074";} -.icon-comment:before{content:"\f075";} -.icon-magnet:before{content:"\f076";} -.icon-chevron-up:before{content:"\f077";} -.icon-chevron-down:before{content:"\f078";} -.icon-retweet:before{content:"\f079";} -.icon-shopping-cart:before{content:"\f07a";} -.icon-folder-close:before{content:"\f07b";} -.icon-folder-open:before{content:"\f07c";} -.icon-resize-vertical:before{content:"\f07d";} -.icon-resize-horizontal:before{content:"\f07e";} -.icon-bar-chart:before{content:"\f080";} -.icon-twitter-sign:before{content:"\f081";} -.icon-facebook-sign:before{content:"\f082";} -.icon-camera-retro:before{content:"\f083";} -.icon-key:before{content:"\f084";} -.icon-gears:before,.icon-cogs:before{content:"\f085";} -.icon-comments:before{content:"\f086";} -.icon-thumbs-up-alt:before{content:"\f087";} -.icon-thumbs-down-alt:before{content:"\f088";} -.icon-star-half:before{content:"\f089";} -.icon-heart-empty:before{content:"\f08a";} -.icon-signout:before{content:"\f08b";} -.icon-linkedin-sign:before{content:"\f08c";} -.icon-pushpin:before{content:"\f08d";} -.icon-external-link:before{content:"\f08e";} -.icon-signin:before{content:"\f090";} -.icon-trophy:before{content:"\f091";} -.icon-github-sign:before{content:"\f092";} -.icon-upload-alt:before{content:"\f093";} -.icon-lemon:before{content:"\f094";} -.icon-phone:before{content:"\f095";} -.icon-unchecked:before,.icon-check-empty:before{content:"\f096";} -.icon-bookmark-empty:before{content:"\f097";} -.icon-phone-sign:before{content:"\f098";} -.icon-twitter:before{content:"\f099";} -.icon-facebook:before{content:"\f09a";} -.icon-github:before{content:"\f09b";} -.icon-unlock:before{content:"\f09c";} -.icon-credit-card:before{content:"\f09d";} -.icon-rss:before{content:"\f09e";} -.icon-hdd:before{content:"\f0a0";} -.icon-bullhorn:before{content:"\f0a1";} -.icon-bell:before{content:"\f0a2";} -.icon-certificate:before{content:"\f0a3";} -.icon-hand-right:before{content:"\f0a4";} -.icon-hand-left:before{content:"\f0a5";} -.icon-hand-up:before{content:"\f0a6";} -.icon-hand-down:before{content:"\f0a7";} -.icon-circle-arrow-left:before{content:"\f0a8";} -.icon-circle-arrow-right:before{content:"\f0a9";} -.icon-circle-arrow-up:before{content:"\f0aa";} -.icon-circle-arrow-down:before{content:"\f0ab";} -.icon-globe:before{content:"\f0ac";} -.icon-wrench:before{content:"\f0ad";} -.icon-tasks:before{content:"\f0ae";} -.icon-filter:before{content:"\f0b0";} -.icon-briefcase:before{content:"\f0b1";} -.icon-fullscreen:before{content:"\f0b2";} -.icon-group:before{content:"\f0c0";} -.icon-link:before{content:"\f0c1";} -.icon-cloud:before{content:"\f0c2";} -.icon-beaker:before{content:"\f0c3";} -.icon-cut:before{content:"\f0c4";} -.icon-copy:before{content:"\f0c5";} -.icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6";} -.icon-save:before{content:"\f0c7";} -.icon-sign-blank:before{content:"\f0c8";} -.icon-reorder:before{content:"\f0c9";} -.icon-list-ul:before{content:"\f0ca";} -.icon-list-ol:before{content:"\f0cb";} -.icon-strikethrough:before{content:"\f0cc";} -.icon-underline:before{content:"\f0cd";} -.icon-table:before{content:"\f0ce";} -.icon-magic:before{content:"\f0d0";} -.icon-truck:before{content:"\f0d1";} -.icon-pinterest:before{content:"\f0d2";} -.icon-pinterest-sign:before{content:"\f0d3";} -.icon-google-plus-sign:before{content:"\f0d4";} -.icon-google-plus:before{content:"\f0d5";} -.icon-money:before{content:"\f0d6";} -.icon-caret-down:before{content:"\f0d7";} -.icon-caret-up:before{content:"\f0d8";} -.icon-caret-left:before{content:"\f0d9";} -.icon-caret-right:before{content:"\f0da";} -.icon-columns:before{content:"\f0db";} -.icon-sort:before{content:"\f0dc";} -.icon-sort-down:before{content:"\f0dd";} -.icon-sort-up:before{content:"\f0de";} -.icon-envelope:before{content:"\f0e0";} -.icon-linkedin:before{content:"\f0e1";} -.icon-rotate-left:before,.icon-undo:before{content:"\f0e2";} -.icon-legal:before{content:"\f0e3";} -.icon-dashboard:before{content:"\f0e4";} -.icon-comment-alt:before{content:"\f0e5";} -.icon-comments-alt:before{content:"\f0e6";} -.icon-bolt:before{content:"\f0e7";} -.icon-sitemap:before{content:"\f0e8";} -.icon-umbrella:before{content:"\f0e9";} -.icon-paste:before{content:"\f0ea";} -.icon-lightbulb:before{content:"\f0eb";} -.icon-exchange:before{content:"\f0ec";} -.icon-cloud-download:before{content:"\f0ed";} -.icon-cloud-upload:before{content:"\f0ee";} -.icon-user-md:before{content:"\f0f0";} -.icon-stethoscope:before{content:"\f0f1";} -.icon-suitcase:before{content:"\f0f2";} -.icon-bell-alt:before{content:"\f0f3";} -.icon-coffee:before{content:"\f0f4";} -.icon-food:before{content:"\f0f5";} -.icon-file-text-alt:before{content:"\f0f6";} -.icon-building:before{content:"\f0f7";} -.icon-hospital:before{content:"\f0f8";} -.icon-ambulance:before{content:"\f0f9";} -.icon-medkit:before{content:"\f0fa";} -.icon-fighter-jet:before{content:"\f0fb";} -.icon-beer:before{content:"\f0fc";} -.icon-h-sign:before{content:"\f0fd";} -.icon-plus-sign-alt:before{content:"\f0fe";} -.icon-double-angle-left:before{content:"\f100";} -.icon-double-angle-right:before{content:"\f101";} -.icon-double-angle-up:before{content:"\f102";} -.icon-double-angle-down:before{content:"\f103";} -.icon-angle-left:before{content:"\f104";} -.icon-angle-right:before{content:"\f105";} -.icon-angle-up:before{content:"\f106";} -.icon-angle-down:before{content:"\f107";} -.icon-desktop:before{content:"\f108";} -.icon-laptop:before{content:"\f109";} -.icon-tablet:before{content:"\f10a";} -.icon-mobile-phone:before{content:"\f10b";} -.icon-circle-blank:before{content:"\f10c";} -.icon-quote-left:before{content:"\f10d";} -.icon-quote-right:before{content:"\f10e";} -.icon-spinner:before{content:"\f110";} -.icon-circle:before{content:"\f111";} -.icon-mail-reply:before,.icon-reply:before{content:"\f112";} -.icon-github-alt:before{content:"\f113";} -.icon-folder-close-alt:before{content:"\f114";} -.icon-folder-open-alt:before{content:"\f115";} -.icon-expand-alt:before{content:"\f116";} -.icon-collapse-alt:before{content:"\f117";} -.icon-smile:before{content:"\f118";} -.icon-frown:before{content:"\f119";} -.icon-meh:before{content:"\f11a";} -.icon-gamepad:before{content:"\f11b";} -.icon-keyboard:before{content:"\f11c";} -.icon-flag-alt:before{content:"\f11d";} -.icon-flag-checkered:before{content:"\f11e";} -.icon-terminal:before{content:"\f120";} -.icon-code:before{content:"\f121";} -.icon-reply-all:before{content:"\f122";} -.icon-mail-reply-all:before{content:"\f122";} -.icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123";} -.icon-location-arrow:before{content:"\f124";} -.icon-crop:before{content:"\f125";} -.icon-code-fork:before{content:"\f126";} -.icon-unlink:before{content:"\f127";} -.icon-question:before{content:"\f128";} -.icon-info:before{content:"\f129";} -.icon-exclamation:before{content:"\f12a";} -.icon-superscript:before{content:"\f12b";} -.icon-subscript:before{content:"\f12c";} -.icon-eraser:before{content:"\f12d";} -.icon-puzzle-piece:before{content:"\f12e";} -.icon-microphone:before{content:"\f130";} -.icon-microphone-off:before{content:"\f131";} -.icon-shield:before{content:"\f132";} -.icon-calendar-empty:before{content:"\f133";} -.icon-fire-extinguisher:before{content:"\f134";} -.icon-rocket:before{content:"\f135";} -.icon-maxcdn:before{content:"\f136";} -.icon-chevron-sign-left:before{content:"\f137";} -.icon-chevron-sign-right:before{content:"\f138";} -.icon-chevron-sign-up:before{content:"\f139";} -.icon-chevron-sign-down:before{content:"\f13a";} -.icon-html5:before{content:"\f13b";} -.icon-css3:before{content:"\f13c";} -.icon-anchor:before{content:"\f13d";} -.icon-unlock-alt:before{content:"\f13e";} -.icon-bullseye:before{content:"\f140";} -.icon-ellipsis-horizontal:before{content:"\f141";} -.icon-ellipsis-vertical:before{content:"\f142";} -.icon-rss-sign:before{content:"\f143";} -.icon-play-sign:before{content:"\f144";} -.icon-ticket:before{content:"\f145";} -.icon-minus-sign-alt:before{content:"\f146";} -.icon-check-minus:before{content:"\f147";} -.icon-level-up:before{content:"\f148";} -.icon-level-down:before{content:"\f149";} -.icon-check-sign:before{content:"\f14a";} -.icon-edit-sign:before{content:"\f14b";} -.icon-external-link-sign:before{content:"\f14c";} -.icon-share-sign:before{content:"\f14d";} -.icon-compass:before{content:"\f14e";} -.icon-collapse:before{content:"\f150";} -.icon-collapse-top:before{content:"\f151";} -.icon-expand:before{content:"\f152";} -.icon-euro:before,.icon-eur:before{content:"\f153";} -.icon-gbp:before{content:"\f154";} -.icon-dollar:before,.icon-usd:before{content:"\f155";} -.icon-rupee:before,.icon-inr:before{content:"\f156";} -.icon-yen:before,.icon-jpy:before{content:"\f157";} -.icon-renminbi:before,.icon-cny:before{content:"\f158";} -.icon-won:before,.icon-krw:before{content:"\f159";} -.icon-bitcoin:before,.icon-btc:before{content:"\f15a";} -.icon-file:before{content:"\f15b";} -.icon-file-text:before{content:"\f15c";} -.icon-sort-by-alphabet:before{content:"\f15d";} -.icon-sort-by-alphabet-alt:before{content:"\f15e";} -.icon-sort-by-attributes:before{content:"\f160";} -.icon-sort-by-attributes-alt:before{content:"\f161";} -.icon-sort-by-order:before{content:"\f162";} -.icon-sort-by-order-alt:before{content:"\f163";} -.icon-thumbs-up:before{content:"\f164";} -.icon-thumbs-down:before{content:"\f165";} -.icon-youtube-sign:before{content:"\f166";} -.icon-youtube:before{content:"\f167";} -.icon-xing:before{content:"\f168";} -.icon-xing-sign:before{content:"\f169";} -.icon-youtube-play:before{content:"\f16a";} -.icon-dropbox:before{content:"\f16b";} -.icon-stackexchange:before{content:"\f16c";} -.icon-instagram:before{content:"\f16d";} -.icon-flickr:before{content:"\f16e";} -.icon-adn:before{content:"\f170";} -.icon-bitbucket:before{content:"\f171";} -.icon-bitbucket-sign:before{content:"\f172";} -.icon-tumblr:before{content:"\f173";} -.icon-tumblr-sign:before{content:"\f174";} -.icon-long-arrow-down:before{content:"\f175";} -.icon-long-arrow-up:before{content:"\f176";} -.icon-long-arrow-left:before{content:"\f177";} -.icon-long-arrow-right:before{content:"\f178";} -.icon-apple:before{content:"\f179";} -.icon-windows:before{content:"\f17a";} -.icon-android:before{content:"\f17b";} -.icon-linux:before{content:"\f17c";} -.icon-dribbble:before{content:"\f17d";} -.icon-skype:before{content:"\f17e";} -.icon-foursquare:before{content:"\f180";} -.icon-trello:before{content:"\f181";} -.icon-female:before{content:"\f182";} -.icon-male:before{content:"\f183";} -.icon-gittip:before{content:"\f184";} -.icon-sun:before{content:"\f185";} -.icon-moon:before{content:"\f186";} -.icon-archive:before{content:"\f187";} -.icon-bug:before{content:"\f188";} -.icon-vk:before{content:"\f189";} -.icon-weibo:before{content:"\f18a";} -.icon-renren:before{content:"\f18b";} - -.icon-large{font-size:1.3333333333333333em;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;vertical-align:middle;} -.nav [class^="icon-"],.nav [class*=" icon-"]{vertical-align:inherit;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;}.nav [class^="icon-"].icon-large,.nav [class*=" icon-"].icon-large{vertical-align:-25%;} -.nav-pills [class^="icon-"].icon-large,.nav-tabs [class^="icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large{line-height:.75em;margin-top:-7px;padding-top:5px;margin-bottom:-5px;padding-bottom:4px;} -.btn [class^="icon-"].pull-left,.btn [class*=" icon-"].pull-left,.btn [class^="icon-"].pull-right,.btn [class*=" icon-"].pull-right{vertical-align:inherit;} -.btn [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large{margin-top:-0.5em;} -a [class^="icon-"],a [class*=" icon-"]{cursor:pointer;} -.icon-glass{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-music{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-search{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-envelope-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-heart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-user{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-film{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-th-large{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-th{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-th-list{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ok{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-remove{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-zoom-in{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-zoom-out{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-power-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-signal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cog{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gear{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-trash{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-home{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-time{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-road{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-download-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-download{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-upload{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-inbox{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-play-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-repeat{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rotate-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-refresh{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-lock{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flag{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-headphones{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-volume-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-volume-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-volume-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-qrcode{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-barcode{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tag{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tags{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-book{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bookmark{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-print{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-camera{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-font{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bold{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-italic{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-text-height{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-text-width{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-center{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-align-justify{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-indent-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-indent-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-facetime-video{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-picture{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pencil{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-map-marker{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-adjust{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tint{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-edit{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-share{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-move{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-step-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fast-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-play{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pause{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-stop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fast-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-step-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eject{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-minus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-remove-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ok-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-question-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-info-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-screenshot{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-remove-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ok-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ban-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-share-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mail-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-full{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-small{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-minus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-asterisk{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-exclamation-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gift{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-leaf{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fire{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eye-open{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eye-close{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-warning-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plane{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-calendar{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-random{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comment{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-magnet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-retweet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-shopping-cart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-close{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-open{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-vertical{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-resize-horizontal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bar-chart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-twitter-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-facebook-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-camera-retro{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-key{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cogs{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gears{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comments{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-up-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-down-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-half{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-heart-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-signout{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-linkedin-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pushpin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-external-link{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-signin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-trophy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-github-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-upload-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-lemon{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-phone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unchecked{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bookmark-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-phone-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-twitter{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-facebook{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-github{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unlock{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-credit-card{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rss{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hdd{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bullhorn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bell{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-certificate{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hand-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-globe{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-wrench{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tasks{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-filter{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-briefcase{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fullscreen{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-group{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-link{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cloud{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-beaker{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cut{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-copy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-paper-clip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-paperclip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-save{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sign-blank{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-reorder{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list-ul{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-list-ol{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-strikethrough{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-underline{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-table{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-magic{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-truck{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pinterest{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-pinterest-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-google-plus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-google-plus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-money{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-caret-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-columns{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-envelope{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-linkedin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-undo{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rotate-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-legal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dashboard{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comment-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-comments-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bolt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sitemap{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-umbrella{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-paste{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-lightbulb{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-exchange{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cloud-download{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cloud-upload{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-user-md{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-stethoscope{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-suitcase{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bell-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-coffee{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-food{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file-text-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-building{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-hospital{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ambulance{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-medkit{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fighter-jet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-beer{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-h-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-plus-sign-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-double-angle-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-angle-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-desktop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-laptop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tablet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mobile-phone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle-blank{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-quote-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-quote-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-spinner{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-reply{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mail-reply{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-github-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-close-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-folder-open-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-expand-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-collapse-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-smile{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-frown{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-meh{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gamepad{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-keyboard{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flag-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flag-checkered{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-terminal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-code{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-reply-all{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-mail-reply-all{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-half-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-star-half-full{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-location-arrow{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-crop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-code-fork{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unlink{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-question{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-info{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-exclamation{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-superscript{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-subscript{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eraser{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-puzzle-piece{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-microphone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-microphone-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-shield{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-calendar-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-fire-extinguisher{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rocket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-maxcdn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-chevron-sign-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-html5{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-css3{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-anchor{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-unlock-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bullseye{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ellipsis-horizontal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ellipsis-vertical{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rss-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-play-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-ticket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-minus-sign-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check-minus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-level-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-level-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-check-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-edit-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-external-link-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-share-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-compass{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-collapse{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-collapse-top{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-expand{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-eur{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-euro{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gbp{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-usd{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dollar{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-inr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-rupee{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-jpy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-yen{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-cny{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-renminbi{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-krw{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-won{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-btc{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bitcoin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-file-text{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-alphabet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-alphabet-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-attributes{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-attributes-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-order{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sort-by-order-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-thumbs-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-youtube-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-youtube{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-xing{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-xing-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-youtube-play{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dropbox{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-stackexchange{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-instagram{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-flickr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-adn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bitbucket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bitbucket-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tumblr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-tumblr-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-long-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-apple{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-windows{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-android{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-linux{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-dribbble{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-skype{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-foursquare{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-trello{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-female{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-male{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-gittip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-sun{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-moon{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-archive{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-bug{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-vk{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-weibo{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} -.icon-renren{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} \ No newline at end of file diff --git a/code/modules/goonchat/browserassets/html/browserOutput.html b/code/modules/goonchat/browserassets/html/browserOutput.html index 68da251702..314cd42446 100644 --- a/code/modules/goonchat/browserassets/html/browserOutput.html +++ b/code/modules/goonchat/browserassets/html/browserOutput.html @@ -8,13 +8,12 @@ -
    + {open && ( + + {children} + + )} + + ); + } +} diff --git a/tgui-next/packages/tgui/components/ColorBox.js b/tgui-next/packages/tgui/components/ColorBox.js new file mode 100644 index 0000000000..0bfe368d82 --- /dev/null +++ b/tgui-next/packages/tgui/components/ColorBox.js @@ -0,0 +1,19 @@ +import { classes, pureComponentHooks } from 'common/react'; +import { Box } from './Box'; + +export const ColorBox = props => { + const { color, content, className, ...rest } = props; + return ( + + ); +}; + +ColorBox.defaultHooks = pureComponentHooks; diff --git a/tgui-next/packages/tgui/components/Dimmer.js b/tgui-next/packages/tgui/components/Dimmer.js new file mode 100644 index 0000000000..9d3ead0549 --- /dev/null +++ b/tgui-next/packages/tgui/components/Dimmer.js @@ -0,0 +1,19 @@ +import { Box } from './Box'; + +export const Dimmer = props => { + const { style, ...rest } = props; + return ( + + ); +}; diff --git a/tgui-next/packages/tgui/components/Dropdown.js b/tgui-next/packages/tgui/components/Dropdown.js new file mode 100644 index 0000000000..462b8a5fe5 --- /dev/null +++ b/tgui-next/packages/tgui/components/Dropdown.js @@ -0,0 +1,115 @@ +import { classes } from 'common/react'; +import { Component, createRef } from 'inferno'; +import { Box } from './Box'; +import { Icon } from './Icon'; + +export class Dropdown extends Component { + constructor(props) { + super(props); + this.state = { + selected: props.selected, + open: false, + }; + this.handleClick = () => { + if (this.state.open) { + this.setOpen(false); + } + }; + } + + componentWillUnmount() { + window.removeEventListener('click', this.handleClick); + } + + setOpen(open) { + this.setState({ open: open }); + if (open) { + setTimeout(() => window.addEventListener('click', this.handleClick)); + this.menuRef.focus(); + } + else { + window.removeEventListener('click', this.handleClick); + } + } + + setSelected(selected) { + this.setState({ + selected: selected, + }); + this.setOpen(false); + this.props.onSelected(selected); + } + + buildMenu() { + const { options = [] } = this.props; + const ops = options.map(option => ( +
    { + this.setSelected(option); + }}> + {option} +
    + )); + return ops.length ? ops : 'No Options Found'; + } + + render() { + const { props } = this; + const { + color = 'default', + over, + width, + onClick, + selected, + ...boxProps + } = props; + const { + className, + ...rest + } = boxProps; + + const adjustedOpen = over ? !this.state.open : this.state.open; + + const menu = this.state.open ? ( +
    { this.menuRef = menu; }} + tabIndex="-1" + style={{ + 'width': width, + }} + className={classes([ + 'Dropdown__menu', + over && 'Dropdown__over', + ])}> + {this.buildMenu()} +
    + ) : null; + + return ( +
    + { + this.setOpen(!this.state.open); + }}> + + {this.state.selected} + + + + + + {menu} +
    + ); + } +} diff --git a/tgui-next/packages/tgui/components/Flex.js b/tgui-next/packages/tgui/components/Flex.js new file mode 100644 index 0000000000..447c9e13eb --- /dev/null +++ b/tgui-next/packages/tgui/components/Flex.js @@ -0,0 +1,66 @@ +import { classes, pureComponentHooks } from 'common/react'; +import { Box } from './Box'; + +export const computeFlexProps = props => { + const { + className, + direction, + wrap, + align, + justify, + spacing = 0, + ...rest + } = props; + return { + className: classes([ + 'Flex', + spacing > 0 && 'Flex--spacing--' + spacing, + className, + ]), + style: { + ...rest.style, + 'flex-direction': direction, + 'flex-wrap': wrap, + 'align-items': align, + 'justify-content': justify, + }, + ...rest, + }; +}; + +export const Flex = props => ( + +); + +Flex.defaultHooks = pureComponentHooks; + +export const computeFlexItemProps = props => { + const { + className, + grow, + order, + align, + ...rest + } = props; + return { + className: classes([ + 'Flex__item', + className, + ]), + style: { + ...rest.style, + 'flex-grow': grow, + 'order': order, + 'align-self': align, + }, + ...rest, + }; +}; + +export const FlexItem = props => ( + +); + +FlexItem.defaultHooks = pureComponentHooks; + +Flex.Item = FlexItem; diff --git a/tgui-next/packages/tgui/components/Grid.js b/tgui-next/packages/tgui/components/Grid.js new file mode 100644 index 0000000000..2adced0847 --- /dev/null +++ b/tgui-next/packages/tgui/components/Grid.js @@ -0,0 +1,31 @@ +import { Table } from './Table'; +import { pureComponentHooks } from 'common/react'; + +export const Grid = props => { + const { children, ...rest } = props; + return ( + + + {children} + +
    + ); +}; + +Grid.defaultHooks = pureComponentHooks; + +export const GridColumn = props => { + const { size = 1, style, ...rest } = props; + return ( + + ); +}; + +Grid.defaultHooks = pureComponentHooks; + +Grid.Column = GridColumn; diff --git a/tgui-next/packages/tgui/components/Icon.js b/tgui-next/packages/tgui/components/Icon.js new file mode 100644 index 0000000000..5ed74d9e05 --- /dev/null +++ b/tgui-next/packages/tgui/components/Icon.js @@ -0,0 +1,30 @@ +import { classes, pureComponentHooks } from 'common/react'; +import { Box } from './Box'; + +const FA_OUTLINE_REGEX = /-o$/; + +export const Icon = props => { + const { name, size, spin, className, style = {}, rotation, ...rest } = props; + if (size) { + style['font-size'] = (size * 100) + '%'; + } + if (typeof rotation === 'number') { + style['transform'] = `rotate(${rotation}deg)`; + } + const faRegular = FA_OUTLINE_REGEX.test(name); + const faName = name.replace(FA_OUTLINE_REGEX, ''); + return ( + + ); +}; + +Icon.defaultHooks = pureComponentHooks; diff --git a/tgui-next/packages/tgui/components/Input.js b/tgui-next/packages/tgui/components/Input.js new file mode 100644 index 0000000000..3c73d88a8f --- /dev/null +++ b/tgui-next/packages/tgui/components/Input.js @@ -0,0 +1,138 @@ +import { classes, isFalsy } from 'common/react'; +import { Component, createRef } from 'inferno'; +import { Box } from './Box'; + +const toInputValue = value => { + if (isFalsy(value)) { + return ''; + } + return value; +}; + +export class Input extends Component { + constructor() { + super(); + this.inputRef = createRef(); + this.state = { + editing: false, + }; + this.handleInput = e => { + const { editing } = this.state; + const { onInput } = this.props; + if (!editing) { + this.setEditing(true); + } + if (onInput) { + onInput(e, e.target.value); + } + }; + this.handleFocus = e => { + const { editing } = this.state; + if (!editing) { + this.setEditing(true); + } + }; + this.handleBlur = e => { + const { editing } = this.state; + const { onChange } = this.props; + if (editing) { + this.setEditing(false); + if (onChange) { + onChange(e, e.target.value); + } + } + }; + this.handleKeyDown = e => { + const { onInput, onChange, onEnter } = this.props; + if (e.keyCode === 13) { + this.setEditing(false); + if (onChange) { + onChange(e, e.target.value); + } + if (onInput) { + onInput(e, e.target.value); + } + if (onEnter) { + onEnter(e, e.target.value); + } + if (this.props.selfClear) { + e.target.value = ''; + } else { + e.target.blur(); + } + return; + } + if (e.keyCode === 27) { + this.setEditing(false); + e.target.value = toInputValue(this.props.value); + e.target.blur(); + return; + } + }; + } + + componentDidMount() { + const nextValue = this.props.value; + const input = this.inputRef.current; + if (input) { + input.value = toInputValue(nextValue); + } + } + + componentDidUpdate(prevProps, prevState) { + const { editing } = this.state; + const prevValue = prevProps.value; + const nextValue = this.props.value; + const input = this.inputRef.current; + if (input && !editing && prevValue !== nextValue) { + input.value = toInputValue(nextValue); + } + } + + setEditing(editing) { + this.setState({ editing }); + } + + render() { + const { props } = this; + // Input only props + const { + selfClear, + onInput, + onChange, + onEnter, + value, + maxLength, + placeholder, + ...boxProps + } = props; + // Box props + const { + className, + fluid, + ...rest + } = boxProps; + return ( + +
    + . +
    + +
    + ); + } +} diff --git a/tgui-next/packages/tgui/components/LabeledList.js b/tgui-next/packages/tgui/components/LabeledList.js new file mode 100644 index 0000000000..2364f9798a --- /dev/null +++ b/tgui-next/packages/tgui/components/LabeledList.js @@ -0,0 +1,75 @@ +import { classes, pureComponentHooks } from 'common/react'; +import { Box, unit } from './Box'; + +export const LabeledList = props => { + const { children } = props; + return ( + + {children} +
    + ); +}; + +LabeledList.defaultHooks = pureComponentHooks; + +export const LabeledListItem = props => { + const { + className, + label, + labelColor = 'label', + color, + buttons, + content, + children, + } = props; + return ( + + + + {content} + {children} + + {buttons && ( + + {buttons} + + )} + + ); +}; + +LabeledListItem.defaultHooks = pureComponentHooks; + +export const LabeledListDivider = props => { + const { size = 1 } = props; + return ( + + + + ); +}; + +LabeledListDivider.defaultHooks = pureComponentHooks; + +LabeledList.Item = LabeledListItem; +LabeledList.Divider = LabeledListDivider; diff --git a/tgui-next/packages/tgui/components/NoticeBox.js b/tgui-next/packages/tgui/components/NoticeBox.js new file mode 100644 index 0000000000..f57e4d9082 --- /dev/null +++ b/tgui-next/packages/tgui/components/NoticeBox.js @@ -0,0 +1,16 @@ +import { classes, pureComponentHooks } from 'common/react'; +import { Box } from './Box'; + +export const NoticeBox = props => { + const { className, ...rest } = props; + return ( + + ); +}; + +NoticeBox.defaultHooks = pureComponentHooks; diff --git a/tgui-next/packages/tgui/components/NumberInput.js b/tgui-next/packages/tgui/components/NumberInput.js new file mode 100644 index 0000000000..52f6a87865 --- /dev/null +++ b/tgui-next/packages/tgui/components/NumberInput.js @@ -0,0 +1,259 @@ +import { clamp } from 'common/math'; +import { classes, pureComponentHooks } from 'common/react'; +import { Component, createRef } from 'inferno'; +import { tridentVersion } from '../byond'; +import { AnimatedNumber } from './AnimatedNumber'; +import { Box } from './Box'; + +export class NumberInput extends Component { + constructor(props) { + super(props); + const { value } = props; + this.inputRef = createRef(); + this.state = { + value, + dragging: false, + editing: false, + internalValue: null, + origin: null, + suppressingFlicker: false, + }; + + // Suppresses flickering while the value propagates through the backend + this.flickerTimer = null; + this.suppressFlicker = () => { + const { suppressFlicker } = this.props; + if (suppressFlicker > 0) { + this.setState({ + suppressingFlicker: true, + }); + clearTimeout(this.flickerTimer); + this.flickerTimer = setTimeout(() => this.setState({ + suppressingFlicker: false, + }), suppressFlicker); + } + }; + + this.handleDragStart = e => { + const { value } = this.props; + const { editing } = this.state; + if (editing) { + return; + } + document.body.style['pointer-events'] = 'none'; + this.ref = e.target; + this.setState({ + dragging: false, + origin: e.screenY, + value, + internalValue: value, + }); + this.timer = setTimeout(() => { + this.setState({ + dragging: true, + }); + }, 250); + this.dragInterval = setInterval(() => { + const { dragging, value } = this.state; + const { onDrag } = this.props; + if (dragging && onDrag) { + onDrag(e, value); + } + }, 500); + document.addEventListener('mousemove', this.handleDragMove); + document.addEventListener('mouseup', this.handleDragEnd); + }; + + this.handleDragMove = e => { + const { minValue, maxValue, step, stepPixelSize } = this.props; + this.setState(prevState => { + const state = { ...prevState }; + const offset = state.origin - e.screenY; + if (prevState.dragging) { + const stepOffset = Number.isFinite(minValue) + ? minValue % step + : 0; + // Translate mouse movement to value + // Give it some headroom (by increasing clamp range by 1 step) + state.internalValue = clamp( + state.internalValue + offset * step / stepPixelSize, + minValue - step, maxValue + step); + // Clamp the final value + state.value = clamp( + state.internalValue + - state.internalValue % step + + stepOffset, + minValue, maxValue); + state.origin = e.screenY; + } + else if (Math.abs(offset) > 4) { + state.dragging = true; + } + return state; + }); + }; + + this.handleDragEnd = e => { + const { onChange, onDrag } = this.props; + const { dragging, value, internalValue } = this.state; + document.body.style['pointer-events'] = 'auto'; + clearTimeout(this.timer); + clearInterval(this.dragInterval); + this.setState({ + dragging: false, + editing: !dragging, + origin: null, + }); + document.removeEventListener('mousemove', this.handleDragMove); + document.removeEventListener('mouseup', this.handleDragEnd); + if (dragging) { + this.suppressFlicker(); + if (onChange) { + onChange(e, value); + } + if (onDrag) { + onDrag(e, value); + } + } + else if (this.inputRef) { + const input = this.inputRef.current; + input.value = internalValue; + // IE8: Dies when trying to focus a hidden element + // (Error: Object does not support this action) + try { + input.focus(); + input.select(); + } + catch {} + } + }; + } + + render() { + const { + dragging, + editing, + value: intermediateValue, + suppressingFlicker, + } = this.state; + const { + className, + fluid, + animated, + value, + unit, + minValue, + maxValue, + height, + width, + lineHeight, + fontSize, + format, + onChange, + onDrag, + } = this.props; + let displayValue = value; + if (dragging || suppressingFlicker) { + displayValue = intermediateValue; + } + // IE8: Use an "unselectable" prop because "user-select" doesn't work. + const renderContentElement = value => ( +
    + {value + (unit ? ' ' + unit : '')} +
    + ); + const contentElement = (animated && !dragging && !suppressingFlicker && ( + + {renderContentElement} + + ) || ( + renderContentElement(format ? format(displayValue) : displayValue) + )); + return ( + +
    +
    +
    + {contentElement} + { + if (!editing) { + return; + } + const value = clamp(e.target.value, minValue, maxValue); + this.setState({ + editing: false, + value, + }); + this.suppressFlicker(); + if (onChange) { + onChange(e, value); + } + if (onDrag) { + onDrag(e, value); + } + }} + onKeyDown={e => { + if (e.keyCode === 13) { + const value = clamp(e.target.value, minValue, maxValue); + this.setState({ + editing: false, + value, + }); + this.suppressFlicker(); + if (onChange) { + onChange(e, value); + } + if (onDrag) { + onDrag(e, value); + } + return; + } + if (e.keyCode === 27) { + this.setState({ + editing: false, + }); + return; + } + }} /> + + ); + } +} + +NumberInput.defaultHooks = pureComponentHooks; +NumberInput.defaultProps = { + minValue: -Infinity, + maxValue: +Infinity, + step: 1, + stepPixelSize: 1, + suppressFlicker: 50, +}; diff --git a/tgui-next/packages/tgui/components/ProgressBar.js b/tgui-next/packages/tgui/components/ProgressBar.js new file mode 100644 index 0000000000..e58bfa3869 --- /dev/null +++ b/tgui-next/packages/tgui/components/ProgressBar.js @@ -0,0 +1,50 @@ +import { classes, pureComponentHooks } from 'common/react'; +import { clamp, toFixed } from 'common/math'; + +export const ProgressBar = props => { + const { + value, + minValue = 0, + maxValue = 1, + ranges = {}, + content, + children, + } = props; + const scaledValue = (value - minValue) / (maxValue - minValue); + const hasContent = content !== undefined || children !== undefined; + let { color } = props; + // Cycle through ranges in key order to determine progressbar color. + if (!color) { + for (let rangeName of Object.keys(ranges)) { + const range = ranges[rangeName]; + if (range && value >= range[0] && value <= range[1]) { + color = rangeName; + break; + } + } + } + // Default color + if (!color) { + color = 'default'; + } + return ( +
    +
    +
    + {hasContent && content} + {hasContent && children} + {!hasContent && toFixed(scaledValue * 100) + '%'} +
    +
    + ); +}; + +ProgressBar.defaultHooks = pureComponentHooks; diff --git a/tgui-next/packages/tgui/components/Section.js b/tgui-next/packages/tgui/components/Section.js new file mode 100644 index 0000000000..a9e60a54d9 --- /dev/null +++ b/tgui-next/packages/tgui/components/Section.js @@ -0,0 +1,44 @@ +import { classes, isFalsy, pureComponentHooks } from 'common/react'; +import { Box } from './Box'; + +export const Section = props => { + const { + className, + title, + level = 1, + buttons, + content, + children, + ...rest + } = props; + const hasTitle = !isFalsy(title) || !isFalsy(buttons); + const hasContent = !isFalsy(content) || !isFalsy(children); + return ( + + {hasTitle && ( +
    + + {title} + +
    + {buttons} +
    +
    + )} + {hasContent && ( +
    + {content} + {children} +
    + )} +
    + ); +}; + +Section.defaultHooks = pureComponentHooks; diff --git a/tgui-next/packages/tgui/components/Table.js b/tgui-next/packages/tgui/components/Table.js new file mode 100644 index 0000000000..53295ecbc2 --- /dev/null +++ b/tgui-next/packages/tgui/components/Table.js @@ -0,0 +1,59 @@ +import { classes, pureComponentHooks } from 'common/react'; +import { Box } from './Box'; + +export const Table = props => { + const { collapsing, className, content, children, ...rest } = props; + return ( + + + {content} + {children} + + + ); +}; + +Table.defaultHooks = pureComponentHooks; + +export const TableRow = props => { + const { className, header, ...rest } = props; + return ( + + ); +}; + +TableRow.defaultHooks = pureComponentHooks; + +export const TableCell = props => { + const { className, collapsing, header, ...rest } = props; + return ( + + ); +}; + +TableCell.defaultHooks = pureComponentHooks; + +Table.Row = TableRow; +Table.Cell = TableCell; diff --git a/tgui-next/packages/tgui/components/Tabs.js b/tgui-next/packages/tgui/components/Tabs.js new file mode 100644 index 0000000000..b3d02ef820 --- /dev/null +++ b/tgui-next/packages/tgui/components/Tabs.js @@ -0,0 +1,135 @@ +import { classes, normalizeChildren } from 'common/react'; +import { Component } from 'inferno'; +import { Box } from './Box'; +import { Button } from './Button'; + +// A magic value for enforcing type safety +const TAB_MAGIC_TYPE = 'Tab'; + +const validateTabs = tabs => { + for (let tab of tabs) { + if (!tab.props || tab.props.__type__ !== TAB_MAGIC_TYPE) { + const json = JSON.stringify(tab, null, 2); + throw new Error(' only accepts children of type .' + + 'This is what we received: ' + json); + } + } +}; + +export class Tabs extends Component { + constructor(props) { + super(props); + this.state = { + activeTabKey: null, + }; + } + + getActiveTab() { + const { state, props } = this; + const tabs = normalizeChildren(props.children); + validateTabs(tabs); + // Get active tab + let activeTabKey = props.activeTab || state.activeTabKey; + // Verify that active tab exists + let activeTab = tabs + .find(tab => { + const key = tab.key || tab.props.label; + return key === activeTabKey; + }); + // Set first tab as the active tab + if (!activeTab) { + activeTab = tabs[0]; + activeTabKey = activeTab && (activeTab.key || activeTab.props.label); + } + return { + tabs, + activeTab, + activeTabKey, + }; + } + + render() { + const { props } = this; + const { + className, + vertical, + children, + ...rest + } = props; + const { + tabs, + activeTab, + activeTabKey, + } = this.getActiveTab(); + // Retrieve tab content + let content = null; + if (activeTab) { + content = activeTab.props.content || activeTab.props.children; + } + // Get children by calling a wrapper function + if (typeof content === 'function') { + content = content(activeTabKey); + } + return ( + +
    + {tabs.map(tab => { + const { + className, + label, + content, // ignored + children, // ignored + onClick, + highlight, + ...rest + } = tab.props; + const key = tab.key || tab.props.label; + const active = tab.active || key === activeTabKey; + return ( + + ); + })} +
    +
    + {content || null} +
    +
    + ); + } +} + +/** + * A dummy component, which is used for carrying props for the + * tab container. + */ +export const Tab = props => null; + +Tab.defaultProps = { + __type__: TAB_MAGIC_TYPE, +}; + +Tabs.Tab = Tab; diff --git a/tgui-next/packages/tgui/components/TitleBar.js b/tgui-next/packages/tgui/components/TitleBar.js new file mode 100644 index 0000000000..f0a5040500 --- /dev/null +++ b/tgui-next/packages/tgui/components/TitleBar.js @@ -0,0 +1,51 @@ +import { classes, pureComponentHooks } from 'common/react'; +import { toTitleCase } from 'common/string'; +import { tridentVersion } from '../byond'; +import { UI_DISABLED, UI_INTERACTIVE, UI_UPDATE } from '../constants'; +import { Icon } from './Icon'; + +const statusToColor = status => { + switch (status) { + case UI_INTERACTIVE: + return 'good'; + case UI_UPDATE: + return 'average'; + case UI_DISABLED: + default: + return 'bad'; + } +}; + +export const TitleBar = props => { + const { className, title, status, fancy, onDragStart, onClose } = props; + return ( +
    + +
    + {title === title.toLowerCase() ? toTitleCase(title) : title} +
    +
    fancy && onDragStart(e)} /> + {!!fancy && ( +
    + {tridentVersion <= 4 ? 'x' : '×'} +
    + )} +
    + ); +}; + +TitleBar.defaultHooks = pureComponentHooks; diff --git a/tgui-next/packages/tgui/components/Toast.js b/tgui-next/packages/tgui/components/Toast.js new file mode 100644 index 0000000000..d3b9d603de --- /dev/null +++ b/tgui-next/packages/tgui/components/Toast.js @@ -0,0 +1,57 @@ +import { pureComponentHooks } from 'common/react'; + +export const Toast = props => { + const { content, children } = props; + return ( +
    + {content} + {children} +
    + ); +}; + +Toast.defaultHooks = pureComponentHooks; + +let toastTimeout; + +/** + * Shows a toast at the bottom of the screen. + * + * Takes the store's dispatch function, and text as a second argument. + */ +export const showToast = (dispatch, text) => { + if (toastTimeout) { + clearTimeout(toastTimeout); + } + toastTimeout = setTimeout(() => { + toastTimeout = undefined; + dispatch({ + type: 'hideToast', + }); + }, 5000); + dispatch({ + type: 'showToast', + payload: { text }, + }); +}; + +export const toastReducer = (state, action) => { + const { type, payload } = action; + + if (type === 'showToast') { + const { text } = payload; + return { + ...state, + toastText: text, + }; + } + + if (type === 'hideToast') { + return { + ...state, + toastText: null, + }; + } + + return state; +}; diff --git a/tgui-next/packages/tgui/components/Tooltip.js b/tgui-next/packages/tgui/components/Tooltip.js new file mode 100644 index 0000000000..c46f3c45f7 --- /dev/null +++ b/tgui-next/packages/tgui/components/Tooltip.js @@ -0,0 +1,20 @@ +import { classes } from 'common/react'; + +export const Tooltip = props => { + const { + content, + position = 'bottom', + } = props; + // Empirically calculated length of the string, + // at which tooltip text starts to overflow. + const long = typeof content === 'string' && content.length > 35; + return ( +
    + ); +}; diff --git a/tgui-next/packages/tgui/components/index.js b/tgui-next/packages/tgui/components/index.js new file mode 100644 index 0000000000..c0074b4eec --- /dev/null +++ b/tgui-next/packages/tgui/components/index.js @@ -0,0 +1,23 @@ +export { AnimatedNumber } from './AnimatedNumber'; +export { BlockQuote } from './BlockQuote'; +export { Box } from './Box'; +export { Button } from './Button'; +export { ColorBox } from './ColorBox'; +export { Collapsible } from './Collapsible'; +export { Dimmer } from './Dimmer'; +export { Dropdown } from './Dropdown'; +export { Flex } from './Flex'; +export { Grid } from './Grid'; +export { Icon } from './Icon'; +export { Input } from './Input'; +export { LabeledList } from './LabeledList'; +export { NoticeBox } from './NoticeBox'; +export { NumberInput } from './NumberInput'; +export { ProgressBar } from './ProgressBar'; +export { Section } from './Section'; +export { Table } from './Table'; +export { Tabs } from './Tabs'; +export { TitleBar } from './TitleBar'; +export { Toast } from './Toast'; +export { Tooltip } from './Tooltip'; +export { Chart } from './Chart'; diff --git a/tgui-next/packages/tgui/constants.js b/tgui-next/packages/tgui/constants.js new file mode 100644 index 0000000000..60b288d211 --- /dev/null +++ b/tgui-next/packages/tgui/constants.js @@ -0,0 +1,214 @@ +// UI states, which are mirrored from the BYOND code. +export const UI_INTERACTIVE = 2; +export const UI_UPDATE = 1; +export const UI_DISABLED = 0; +export const UI_CLOSE = -1; + +// All game related colors are stored here +export const COLORS = { + // Department colors + department: { + captain: '#c06616', + security: '#e74c3c', + medbay: '#3498db', + science: '#9b59b6', + engineering: '#f1c40f', + cargo: '#f39c12', + centcom: '#00c100', + other: '#c38312', + }, + // Damage type colors + damageType: { + oxy: '#3498db', + toxin: '#2ecc71', + burn: '#e67e22', + brute: '#e74c3c', + }, +}; + +// Colors defined in CSS +export const CSS_COLORS = [ + 'black', + 'white', + 'red', + 'orange', + 'yellow', + 'olive', + 'green', + 'teal', + 'blue', + 'violet', + 'purple', + 'pink', + 'brown', + 'grey', + 'good', + 'average', + 'bad', + 'label', +]; + +export const RADIO_CHANNELS = [ + { + name: 'Syndicate', + freq: 1213, + color: '#a52a2a', + }, + { + name: 'Red Team', + freq: 1215, + color: '#ff4444', + }, + { + name: 'Blue Team', + freq: 1217, + color: '#3434fd', + }, + { + name: 'CentCom', + freq: 1337, + color: '#2681a5', + }, + { + name: 'Supply', + freq: 1347, + color: '#b88646', + }, + { + name: 'Service', + freq: 1349, + color: '#6ca729', + }, + { + name: 'Science', + freq: 1351, + color: '#c68cfa', + }, + { + name: 'Command', + freq: 1353, + color: '#5177ff', + }, + { + name: 'Medical', + freq: 1355, + color: '#57b8f0', + }, + { + name: 'Engineering', + freq: 1357, + color: '#f37746', + }, + { + name: 'Security', + freq: 1359, + color: '#dd3535', + }, + { + name: 'AI Private', + freq: 1447, + color: '#d65d95', + }, + { + name: 'Common', + freq: 1459, + color: '#1ecc43', + }, +]; + +const GASES = [ + { + 'id': 'o2', + 'name': 'Oxygen', + 'label': 'O₂', + 'color': 'blue', + }, + { + 'id': 'n2', + 'name': 'Nitrogen', + 'label': 'N₂', + 'color': 'red', + }, + { + 'id': 'co2', + 'name': 'Carbon Dioxide', + 'label': 'CO₂', + 'color': 'grey', + }, + { + 'id': 'plasma', + 'name': 'Plasma', + 'label': 'Plasma', + 'color': 'pink', + }, + { + 'id': 'water_vapor', + 'name': 'Water Vapor', + 'label': 'H₂O', + 'color': 'grey', + }, + { + 'id': 'nob', + 'name': 'Hyper-noblium', + 'label': 'Hyper-nob', + 'color': 'teal', + }, + { + 'id': 'n2o', + 'name': 'Nitrous Oxide', + 'label': 'N₂O', + 'color': 'red', + }, + { + 'id': 'no2', + 'name': 'Nitryl', + 'label': 'NO₂', + 'color': 'brown', + }, + { + 'id': 'tritium', + 'name': 'Tritium', + 'label': 'Tritium', + 'color': 'green', + }, + { + 'id': 'bz', + 'name': 'BZ', + 'label': 'BZ', + 'color': 'purple', + }, + { + 'id': 'stim', + 'name': 'Stimulum', + 'label': 'Stimulum', + 'color': 'purple', + }, + { + 'id': 'pluox', + 'name': 'Pluoxium', + 'label': 'Pluoxium', + 'color': 'blue', + }, + { + 'id': 'miasma', + 'name': 'Miasma', + 'label': 'Miasma', + 'color': 'olive', + }, +]; + +export const getGasLabel = (gasId, fallbackValue) => { + const gasSearchString = String(gasId).toLowerCase(); + const gas = GASES.find(gas => gas.id === gasSearchString + || gas.name.toLowerCase() === gasSearchString); + return gas && gas.label + || fallbackValue + || gasId; +}; + +export const getGasColor = gasId => { + const gasSearchString = String(gasId).toLowerCase(); + const gas = GASES.find(gas => gas.id === gasSearchString + || gas.name.toLowerCase() === gasSearchString); + return gas && gas.color; +}; diff --git a/tgui-next/packages/tgui/drag.js b/tgui-next/packages/tgui/drag.js new file mode 100644 index 0000000000..a29146b796 --- /dev/null +++ b/tgui-next/packages/tgui/drag.js @@ -0,0 +1,146 @@ +import { vecAdd, vecInverse, vecMultiply } from 'common/vector'; +import { winget, winset } from './byond'; +import { createLogger } from './logging'; + +const logger = createLogger('drag'); + +let ref; +let dragging = false; +let resizing = false; +let screenOffset = [0, 0]; +let dragPointOffset; +let resizeMatrix; +let initialSize; +let size; + +const getWindowPosition = ref => { + return winget(ref, 'pos').then(pos => [pos.x, pos.y]); +}; + +const setWindowPosition = (ref, vec) => { + return winset(ref, 'pos', vec[0] + ',' + vec[1]); +}; + +const setWindowSize = (ref, vec) => { + return winset(ref, 'size', vec[0] + ',' + vec[1]); +}; + +export const setupDrag = async state => { + logger.log('setting up'); + ref = state.config.window; + // Calculate offset caused by windows taskbar + const realPosition = await getWindowPosition(ref); + screenOffset = [ + realPosition[0] - window.screenLeft, + realPosition[1] - window.screenTop, + ]; + // Constraint window position + const [relocated, safePosition] = constraintPosition(realPosition); + if (relocated) { + setWindowPosition(ref, safePosition); + } + logger.debug('current state', { ref, screenOffset }); +}; + +/** + * Constraints window position to safe screen area, accounting for safe + * margins which could be a system taskbar. + */ +const constraintPosition = position => { + let x = position[0]; + let y = position[1]; + let relocated = false; + // Left + if (x < 0) { + x = 0; + relocated = true; + } + // Right + else if (x + window.innerWidth > window.screen.availWidth) { + x = window.screen.availWidth - window.innerWidth; + relocated = true; + } + // Top + if (y < 0) { + y = 0; + relocated = true; + } + // Bottom + else if (y + window.innerHeight > window.screen.availHeight) { + y = window.screen.availHeight - window.innerHeight; + relocated = true; + } + return [relocated, [x, y]]; +}; + +export const dragStartHandler = event => { + logger.log('drag start'); + dragging = true; + dragPointOffset = [ + window.screenLeft - event.screenX, + window.screenTop - event.screenY, + ]; + document.addEventListener('mousemove', dragMoveHandler); + document.addEventListener('mouseup', dragEndHandler); + dragMoveHandler(event); +}; + +const dragEndHandler = event => { + logger.log('drag end'); + dragMoveHandler(event); + document.removeEventListener('mousemove', dragMoveHandler); + document.removeEventListener('mouseup', dragEndHandler); + dragging = false; +}; + +const dragMoveHandler = event => { + if (!dragging) { + return; + } + event.preventDefault(); + setWindowPosition(ref, vecAdd( + [event.screenX, event.screenY], + screenOffset, + dragPointOffset)); +}; + +export const resizeStartHandler = (x, y) => event => { + resizeMatrix = [x, y]; + logger.log('resize start', resizeMatrix); + resizing = true; + dragPointOffset = [ + window.screenLeft - event.screenX, + window.screenTop - event.screenY, + ]; + initialSize = [ + window.innerWidth, + window.innerHeight, + ]; + document.addEventListener('mousemove', resizeMoveHandler); + document.addEventListener('mouseup', resizeEndHandler); + resizeMoveHandler(event); +}; + +const resizeEndHandler = event => { + logger.log('resize end', size); + resizeMoveHandler(event); + document.removeEventListener('mousemove', resizeMoveHandler); + document.removeEventListener('mouseup', resizeEndHandler); + resizing = false; +}; + +const resizeMoveHandler = event => { + if (!resizing) { + return; + } + event.preventDefault(); + size = vecAdd(initialSize, vecMultiply(resizeMatrix, vecAdd( + [event.screenX, event.screenY], + vecInverse([window.screenLeft, window.screenTop]), + dragPointOffset, + [1, 1]))); + // Sane window size values + size[0] = Math.max(size[0], 250); + size[1] = Math.max(size[1], 120); + setWindowSize(ref, size); +}; diff --git a/tgui-next/packages/tgui/hotkeys.js b/tgui-next/packages/tgui/hotkeys.js new file mode 100644 index 0000000000..08625aa64d --- /dev/null +++ b/tgui-next/packages/tgui/hotkeys.js @@ -0,0 +1,257 @@ +import { createLogger } from './logging'; +import { callByond, tridentVersion } from './byond'; + +const logger = createLogger('hotkeys'); + +// Key codes +export const KEY_BACKSPACE = 8; +export const KEY_TAB = 9; +export const KEY_ENTER = 13; +export const KEY_SHIFT = 16; +export const KEY_CTRL = 17; +export const KEY_ALT = 18; +export const KEY_ESCAPE = 27; +export const KEY_SPACE = 32; +export const KEY_0 = 48; +export const KEY_1 = 49; +export const KEY_2 = 50; +export const KEY_3 = 51; +export const KEY_4 = 52; +export const KEY_5 = 53; +export const KEY_6 = 54; +export const KEY_7 = 55; +export const KEY_8 = 56; +export const KEY_9 = 57; +export const KEY_A = 65; +export const KEY_B = 66; +export const KEY_C = 67; +export const KEY_D = 68; +export const KEY_E = 69; +export const KEY_F = 70; +export const KEY_G = 71; +export const KEY_H = 72; +export const KEY_I = 73; +export const KEY_J = 74; +export const KEY_K = 75; +export const KEY_L = 76; +export const KEY_M = 77; +export const KEY_N = 78; +export const KEY_O = 79; +export const KEY_P = 80; +export const KEY_Q = 81; +export const KEY_R = 82; +export const KEY_S = 83; +export const KEY_T = 84; +export const KEY_U = 85; +export const KEY_V = 86; +export const KEY_W = 87; +export const KEY_X = 88; +export const KEY_Y = 89; +export const KEY_Z = 90; +export const KEY_EQUAL = 187; +export const KEY_MINUS = 189; + +const MODIFIER_KEYS = [ + KEY_CTRL, + KEY_ALT, + KEY_SHIFT, +]; + +const NO_PASSTHROUGH_KEYS = [ + KEY_ESCAPE, + KEY_ENTER, + KEY_SPACE, + KEY_TAB, + KEY_CTRL, + KEY_SHIFT, +]; + +// Tracks the "pressed" state of keys +const keyState = {}; + +const createHotkeyString = (ctrlKey, altKey, shiftKey, keyCode) => { + let str = ''; + if (ctrlKey) { + str += 'Ctrl+'; + } + if (altKey) { + str += 'Alt+'; + } + if (shiftKey) { + str += 'Shift+'; + } + if (keyCode >= 48 && keyCode <= 90) { + str += String.fromCharCode(keyCode); + } + else { + str += '[' + keyCode + ']'; + } + return str; +}; + +/** + * Parses the event and compiles information about the keypress. + */ +const getKeyData = e => { + const keyCode = window.event ? e.which : e.keyCode; + const { ctrlKey, altKey, shiftKey } = e; + return { + keyCode, + ctrlKey, + altKey, + shiftKey, + hasModifierKeys: ctrlKey || altKey || shiftKey, + keyString: createHotkeyString(ctrlKey, altKey, shiftKey, keyCode), + }; +}; + +/** + * Keyboard passthrough logic. This allows you to keep doing things + * in game while the browser window is focused. + */ +const handlePassthrough = (e, eventType) => { + if (e.defaultPrevented) { + return; + } + const targetName = e.target && e.target.localName; + if (targetName === 'input' || targetName === 'textarea') { + return; + } + const keyData = getKeyData(e); + const { keyCode, ctrlKey, shiftKey } = keyData; + // NOTE: We pass through only Alt of all modifier keys, because Alt + // modifier (for toggling run/walk) is implemented very shittily + // in our codebase. We pass no other modifier keys, because they can + // be used internally as tgui hotkeys. + if (ctrlKey || shiftKey || NO_PASSTHROUGH_KEYS.includes(keyCode)) { + return; + } + // Send this keypress to BYOND + if (eventType === 'keydown' && !keyState[keyCode]) { + logger.debug('passthrough', eventType, keyData); + return callByond('', { __keydown: keyCode }); + } + if (eventType === 'keyup' && keyState[keyCode]) { + logger.debug('passthrough', eventType, keyData); + return callByond('', { __keyup: keyCode }); + } +}; + +/** + * Cleanup procedure for keyboard passthrough, which should be called + * whenever you're unloading tgui. + */ +export const releaseHeldKeys = () => { + for (let keyCode of Object.keys(keyState)) { + if (keyState[keyCode]) { + logger.log(`releasing [${keyCode}] key`); + keyState[keyCode] = false; + callByond('', { __keyup: keyCode }); + } + } +}; + +const handleHotKey = (e, eventType, dispatch) => { + if (eventType !== 'keyup') { + return; + } + const keyData = getKeyData(e); + const { + ctrlKey, + altKey, + keyCode, + hasModifierKeys, + keyString, + } = keyData; + // Dispatch a detected hotkey as a store action + if (hasModifierKeys && !MODIFIER_KEYS.includes(keyCode)) { + logger.log(keyString); + // Fun stuff + if (ctrlKey && altKey && keyCode === KEY_BACKSPACE) { + // NOTE: We need to call this in a timeout, because we need a clean + // stack in order for this to be a fatal error. + setTimeout(() => { + throw new Error( + 'OOPSIE WOOPSIE!! UwU We made a fucky wucky!! A wittle' + + ' fucko boingo! The code monkeys at our headquarters are' + + ' working VEWY HAWD to fix this!'); + }); + } + dispatch({ + type: 'hotKey', + payload: keyData, + }); + } +}; + +/** + * Subscribe to an event when browser window has been completely + * unfocused. Conveniently fires events when the browser window + * is closed from the outside. + */ +const subscribeToLossOfFocus = listenerFn => { + let timeout; + document.addEventListener('focusout', () => { + timeout = setTimeout(listenerFn); + }); + document.addEventListener('focusin', () => { + clearTimeout(timeout); + }); + window.addEventListener('beforeunload', listenerFn); +}; + +/** + * Subscribe to keydown/keyup events with globally tracked key state. + */ +const subscribeToKeyPresses = listenerFn => { + document.addEventListener('keydown', e => { + const keyCode = window.event ? e.which : e.keyCode; + listenerFn(e, 'keydown'); + keyState[keyCode] = true; + }); + document.addEventListener('keyup', e => { + const keyCode = window.event ? e.which : e.keyCode; + listenerFn(e, 'keyup'); + keyState[keyCode] = false; + }); +}; + +// Middleware +export const hotKeyMiddleware = store => { + const { dispatch } = store; + // Subscribe to key events + subscribeToKeyPresses((e, eventType) => { + // IE8: Can't determine the focused element, so by extension it passes + // keypresses when inputs are focused. + if (tridentVersion > 4) { + handlePassthrough(e, eventType); + } + handleHotKey(e, eventType, dispatch); + }); + // IE8: focusin/focusout only available on IE9+ + if (tridentVersion > 4) { + // Clean up when browser window completely loses focus + subscribeToLossOfFocus(() => { + releaseHeldKeys(); + }); + } + // Pass through store actions (do nothing) + return next => action => next(action); +}; + +// Reducer +export const hotKeyReducer = (state, action) => { + const { type, payload } = action; + if (type === 'hotKey') { + const { ctrlKey, altKey, keyCode } = payload; + // Toggle kitchen sink mode + if (ctrlKey && altKey && keyCode === KEY_EQUAL) { + return { + ...state, + showKitchenSink: !state.showKitchenSink, + }; + } + return state; + } + return state; +}; diff --git a/tgui-next/packages/tgui/index.js b/tgui-next/packages/tgui/index.js new file mode 100644 index 0000000000..1a8b9d4eab --- /dev/null +++ b/tgui-next/packages/tgui/index.js @@ -0,0 +1,167 @@ +import 'core-js/es'; +import 'core-js/web/immediate'; +import 'core-js/web/queue-microtask'; +import 'core-js/web/timers'; +import 'regenerator-runtime/runtime'; +import './polyfills'; + +import { loadCSS } from 'fg-loadcss'; +import { render } from 'inferno'; +import { setupHotReloading } from 'tgui-dev-server/link/client'; +import { backendUpdate } from './backend'; +import { tridentVersion } from './byond'; +import { setupDrag } from './drag'; +import { createLogger } from './logging'; +import { getRoute } from './routes'; +import { createStore } from './store'; + +const logger = createLogger(); +const store = createStore(); +const reactRoot = document.getElementById('react-root'); + +let initialRender = true; +let handedOverToOldTgui = false; + +const renderLayout = () => { + // Short-circuit the renderer + if (handedOverToOldTgui) { + return; + } + // Mark the beginning of the render + let startedAt; + if (process.env.NODE_ENV !== 'production') { + startedAt = Date.now(); + } + try { + const state = store.getState(); + // Initial render setup + if (initialRender) { + logger.log('initial render', state); + + // ----- Old TGUI chain-loader: begin ----- + const route = getRoute(state); + // Route was not found, load old TGUI + if (!route) { + logger.info('loading old tgui'); + // Short-circuit the renderer + handedOverToOldTgui = true; + // Unsubscribe from updates + window.update = window.initialize = () => {}; + // IE8: Use a redirection method + if (tridentVersion <= 4) { + setTimeout(() => { + location.href = 'tgui-fallback.html?ref=' + window.__ref__; + }, 10); + return; + } + // Inject current state into the data holder + const holder = document.getElementById('data'); + holder.textContent = JSON.stringify(state); + // Load old TGUI by injecting new scripts + loadCSS('v4shim.css'); + loadCSS('tgui.css'); + const head = document.getElementsByTagName('head')[0]; + const script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = 'tgui.js'; + head.appendChild(script); + // Bail + return; + } + // ----- Old TGUI chain-loader: end ----- + + // Setup dragging + setupDrag(state); + } + // Start rendering + const { Layout } = require('./layout'); + const element = ; + render(element, reactRoot); + } + catch (err) { + logger.error('rendering error', err); + } + // Report rendering time + if (process.env.NODE_ENV !== 'production') { + const finishedAt = Date.now(); + const diff = finishedAt - startedAt; + const diffFrames = (diff / 16.6667).toFixed(2); + logger.debug(`rendered in ${diff}ms (${diffFrames} frames)`); + if (initialRender) { + const diff = finishedAt - window.__inception__; + const diffFrames = (diff / 16.6667).toFixed(2); + logger.log(`fully loaded in ${diff}ms (${diffFrames} frames)`); + } + } + if (initialRender) { + initialRender = false; + } +}; + +// Parse JSON and report all abnormal JSON strings coming from BYOND +const parseStateJson = json => { + let reviver = (key, value) => { + if (typeof value === 'object' && value !== null) { + if (value.__number__) { + return parseFloat(value.__number__); + } + } + return value; + }; + // IE8: No reviver for you! + // See: https://stackoverflow.com/questions/1288962 + if (tridentVersion <= 4) { + reviver = undefined; + } + try { + return JSON.parse(json, reviver); + } + catch (err) { + logger.log(err); + logger.log('What we got:', json); + const msg = err && err.message; + throw new Error('JSON parsing error: ' + msg); + } +}; + +const setupApp = () => { + // Subscribe for redux state updates + store.subscribe(() => { + renderLayout(); + }); + + // Subscribe for bankend updates + window.update = window.initialize = stateJson => { + const state = parseStateJson(stateJson); + // Backend update dispatches a store action + store.dispatch(backendUpdate(state)); + }; + + // Enable hot module reloading + if (module.hot) { + setupHotReloading(); + module.hot.accept(['./layout', './routes'], () => { + renderLayout(); + }); + } + + // Process the early update queue + while (true) { + let stateJson = window.__updateQueue__.shift(); + if (!stateJson) { + break; + } + window.update(stateJson); + } + + // Dynamically load font-awesome from browser's cache + loadCSS('font-awesome.css'); +}; + +// IE8: Wait for DOM to properly load +if (tridentVersion <= 4 && document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', setupApp); +} +else { + setupApp(); +} diff --git a/tgui-next/packages/tgui/interfaces/Achievements.js b/tgui-next/packages/tgui/interfaces/Achievements.js new file mode 100644 index 0000000000..6e2ad7a599 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/Achievements.js @@ -0,0 +1,134 @@ +import { useBackend } from '../backend'; +import { Box, Icon, Table, Tabs } from '../components'; + +export const Achievement = props => { + const { + name, + desc, + icon_class, + value, + } = props; + return ( + + + + + +

    {name}

    + {desc} + + + + ); +}; + +export const Score = props => { + const { + name, + desc, + icon_class, + value, + } = props; + return ( + + + + + +

    {name}

    + {desc} + 0 ? 'good' : 'bad'} + content={value > 0 ? `Earned ${value} times` : 'Locked'} /> + + + ); +}; + +export const Achievements = props => { + const { data } = useBackend(props); + return ( + + {data.categories.map(category => ( + + + {data.achievements + .filter(x => x.category === category) + .map(achievement => { + if (achievement.score) { + return ( + + ); + } + return ( + + ); + })} + + + ))} + + + {data.highscore.map(highscore => ( + + + + + # + + + Key + + + Score + + + {Object.keys(highscore.scores).map((key, index) => ( + + + {index+1} + + + {index === 0 && ( + + )} + {key} + {index === 0 && ( + + )} + + + {highscore.scores[key]} + + + ))} +
    +
    + ))} +
    +
    +
    + ); +}; diff --git a/tgui-next/packages/tgui/interfaces/AiAirlock.js b/tgui-next/packages/tgui/interfaces/AiAirlock.js new file mode 100644 index 0000000000..55a3cd4a22 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/AiAirlock.js @@ -0,0 +1,196 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, LabeledList, Section } from '../components'; + +export const AiAirlock = props => { + const { act, data } = useBackend(props); + const dangerMap = { + 2: { + color: 'good', + localStatusText: 'Offline', + }, + 1: { + color: 'average', + localStatusText: 'Caution', + }, + 0: { + color: 'bad', + localStatusText: 'Optimal', + }, + }; + const statusMain = dangerMap[data.power.main] || dangerMap[0]; + const statusBackup = dangerMap[data.power.backup] || dangerMap[0]; + const statusElectrify = dangerMap[data.shock] || dangerMap[0]; + return ( + +
    + + act('disrupt-main')} /> + )}> + {data.power.main ? 'Online' : 'Offline'} + {' '} + {(!data.wires.main_1 || !data.wires.main_2) + && '[Wires have been cut!]' + || (data.power.main_timeleft > 0 + && `[${data.power.main_timeleft}s]`)} + + act('disrupt-backup')} /> + )}> + {data.power.backup ? 'Online' : 'Offline'} + {' '} + {(!data.wires.backup_1 || !data.wires.backup_2) + && '[Wires have been cut!]' + || (data.power.backup_timeleft > 0 + && `[${data.power.backup_timeleft}s]`)} + + +
    +
    + + act('idscan-toggle')} /> + )}> + {!data.wires.id_scanner && '[Wires have been cut!]'} + + act('emergency-toggle')} /> + )} /> + + act('bolt-toggle')} /> + )}> + {!data.wires.bolts && '[Wires have been cut!]'} + + act('light-toggle')} /> + )}> + {!data.wires.lights && '[Wires have been cut!]'} + + act('safe-toggle')} /> + )}> + {!data.wires.safe && '[Wires have been cut!]'} + + act('speed-toggle')} /> + )}> + {!data.wires.timing && '[Wires have been cut!]'} + + + act('open-close')} /> + )}> + {!!(data.locked || data.welded) && ( + + [Door is {data.locked ? 'bolted' : ''} + {(data.locked && data.welded) ? ' and ' : ''} + {data.welded ? 'welded' : ''}!] + + )} + + +
    +
    + ); +}; diff --git a/tgui-next/packages/tgui/interfaces/AirAlarm.js b/tgui-next/packages/tgui/interfaces/AirAlarm.js new file mode 100644 index 0000000000..20d808606c --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/AirAlarm.js @@ -0,0 +1,461 @@ +import { toFixed } from 'common/math'; +import { decodeHtmlEntities } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, LabeledList, NumberInput, Section } from '../components'; +import { getGasLabel } from '../constants'; +import { InterfaceLockNoticeBox } from './common/InterfaceLockNoticeBox'; + +export const AirAlarm = props => { + const { state } = props; + const { act, data } = useBackend(props); + const locked = data.locked && !data.siliconUser; + return ( + + act('lock')} /> + + {!locked && ( + + )} + + ); +}; + +const AirAlarmStatus = props => { + const { data } = useBackend(props); + const entries = (data.environment_data || []) + .filter(entry => entry.value >= 0.01); + const dangerMap = { + 0: { + color: 'good', + localStatusText: 'Optimal', + }, + 1: { + color: 'average', + localStatusText: 'Caution', + }, + 2: { + color: 'bad', + localStatusText: 'Danger (Internals Required)', + }, + }; + const localStatus = dangerMap[data.danger_level] || dangerMap[0]; + return ( +
    + + {entries.length > 0 && ( + + {entries.map(entry => { + const status = dangerMap[entry.danger_level] || dangerMap[0]; + return ( + + {toFixed(entry.value, 2)}{entry.unit} + + ); + })} + + {localStatus.localStatusText} + + + {data.atmos_alarm && 'Atmosphere Alarm' + || data.fire_alarm && 'Fire Alarm' + || 'Nominal'} + + + ) || ( + + Cannot obtain air sample for analysis. + + )} + {!!data.emagged && ( + + Safety measures offline. Device may exhibit abnormal behavior. + + )} + +
    + ); +}; + +const AIR_ALARM_ROUTES = { + home: { + title: 'Air Controls', + component: () => AirAlarmControlHome, + }, + vents: { + title: 'Vent Controls', + component: () => AirAlarmControlVents, + }, + scrubbers: { + title: 'Scrubber Controls', + component: () => AirAlarmControlScrubbers, + }, + modes: { + title: 'Operating Mode', + component: () => AirAlarmControlModes, + }, + thresholds: { + title: 'Alarm Thresholds', + component: () => AirAlarmControlThresholds, + }, +}; + +const AirAlarmControl = props => { + const { state } = props; + const { act, config } = useBackend(props); + const route = AIR_ALARM_ROUTES[config.screen] || AIR_ALARM_ROUTES.home; + const Component = route.component(); + return ( +
    act('tgui:view', { + screen: 'home', + })} /> + )}> + +
    + ); +}; + + +// Home screen +// -------------------------------------------------------- + +const AirAlarmControlHome = props => { + const { act, data } = useBackend(props); + const { + mode, + atmos_alarm, + } = data; + return ( + +
    - +
    Loading...

    If this takes longer than 30 seconds, it will automatically reload a maximum of 5 times.
    @@ -26,34 +25,34 @@
    - \ No newline at end of file + diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index 823ad107d2..0d53b44ba8 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -6,7 +6,6 @@ ******************************************/ //DEBUG STUFF -var triggerError = attachErrorHandler('chatDebug', true); var escaper = encodeURIComponent || escape; var decoder = decodeURIComponent || unescape; window.onerror = function(msg, url, line, col, error) { @@ -229,7 +228,7 @@ function highlightTerms(el) { console.log(newWord) } newText += newWord || words[w].replace("<", "<"); - newText += w >= words.length ? '' : ' '; + newText += w >= words.length - 1 ? '' : ' '; } } else { //Every other type of element newText += outerHTML(el.childNodes[c]); diff --git a/code/modules/goonchat/browserassets/js/errorHandler.js b/code/modules/goonchat/browserassets/js/errorHandler.js deleted file mode 100644 index ebe7e32411..0000000000 --- a/code/modules/goonchat/browserassets/js/errorHandler.js +++ /dev/null @@ -1,34 +0,0 @@ -(function(window, navigator) { - - var escaper = encodeURIComponent || escape; - - var triggerError = function(msg, url, line, col, error) { - window.onerror(msg, url, line, col, error); - }; - - /** - * Directs JS errors to a byond proc for logging - * - * @param string file Name of the logfile to dump errors in, do not prepend with data/ - * @param boolean overrideDefault True to prevent default JS errors (an big honking error prompt thing) - * @return boolean - */ - var attach = function(file, overrideDefault) { - overrideDefault = typeof overrideDefault === 'undefined' ? false : overrideDefault; - file = escaper(file); - - window.onerror = function(msg, url, line, col, error) { - var extra = !col ? '' : ' | column: ' + col; - extra += !error ? '' : ' | error: ' + error; - extra += !navigator.userAgent ? '' : ' | user agent: ' + navigator.userAgent; - var debugLine = 'Error: ' + msg + ' | url: ' + url + ' | line: ' + line + extra; - window.location = '?action=debugFileOutput&file=' + file + '&message=' + escaper(debugLine); - return overrideDefault; - }; - - return triggerError; - }; - - window.attachErrorHandler = attach; - -}(window, window.navigator)); \ No newline at end of file diff --git a/code/modules/goonchat/jsErrorHandler.dm b/code/modules/goonchat/jsErrorHandler.dm deleted file mode 100644 index c7647d47a4..0000000000 --- a/code/modules/goonchat/jsErrorHandler.dm +++ /dev/null @@ -1,102 +0,0 @@ -/** -* This is a generic handler for logging your dumb JS errors generated by html popups -* -* 1. Add your logfile to the validFiles list -* 2. Include the "browserassets/js/errorHandler.js" file in your html file (if using chui, skip this step) (look at browserOutput.html for an example) -* 3. Call attachErrorHandler('yourLogFile'); at the top of your JS (again see browserOutput.js for an example) -*/ - -/datum/debugFileOutput - var/directory = "data/popupErrors" //where to shove all the logfiles - var/ext = "log" //file extension - var/logFileLimit = 52428800 //50mb, so yeah pretty permissive - - //Add your dumb file here. This is so some schmuck can't just shit out a bunch of spam logfiles and use all the diskspace. Relative to src.directory - var/list/validFiles = list( - "chatDebug", - "tooltipDebug", - "chemDispenser", - "banPanel", - "stationNamer" - ) - -/datum/debugFileOutput/proc/error(fileName, message, client/C) - if (!fileName || !message) - return 0 - - if (!(fileName in src.validFiles)) - throw EXCEPTION("Debug log file '[fileName].[src.ext]' is not a valid path.") - - var/logFile = file("[src.directory]/[fileName].[src.ext]") - var/fileSize = length(logFile) - if (fileSize >= src.logFileLimit) - CRASH("Debug Error Handling encountered an error! This is highly ironic! File: '[fileName]' has exceeded the filesize limit of: [src.logFileLimit] bytes") - - message = "\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: \[[C && C.key ? C.key : "Unknown Client"]\] triggered: [message]" - WRITE_FILE(logFile, message) - return 1 - -/datum/debugFileOutput/proc/clear(fileName) - if (!fileName) - return 0 - - if (!fexists("[src.directory]/[fileName].[src.ext]")) - throw EXCEPTION("Debug log file '[fileName].[src.ext]' does not exist.") - - if (!(fileName in src.validFiles)) - throw EXCEPTION("Debug log file '[fileName].[src.ext]' is not a valid path.") - - fdel("[src.directory]/[fileName].[src.ext]") - return 1 - -/datum/debugFileOutput/proc/clearAll() - var/list/deleted = new() - for (var/fileName in src.validFiles) - if (fexists("[src.directory]/[fileName].[src.ext]")) - fdel("[src.directory]/[fileName].[src.ext]") - deleted += fileName - - return deleted - - -GLOBAL_DATUM_INIT(debugFileOutput, /datum/debugFileOutput, new) - -/client/Topic(href, href_list) - ..() - - if (href_list["action"] && href_list["action"] == "debugFileOutput" && href_list["file"] && href_list["message"]) - var/file = href_list["file"] - var/message = href_list["message"] - GLOB.debugFileOutput.error(file, message, src) - -/client/proc/deleteJsLogFile(fileName as text) - set category = "Debug" - set name = "Delete JS Logfile" - set desc = "Delete a logfile for JS error reporting. Be sure you want to do this!" - set popup_menu = 0 - if(!holder) - return - if (!fileName) - return - - GLOB.debugFileOutput.clear(fileName) - - log_admin("[key_name(usr)] deleted the '[fileName]' JS logfile") - message_admins("[key_name_admin(usr)] deleted the '[fileName]' JS logfile") - -/client/proc/deleteAllJsLogFiles() - set category = null - set name = "Delete All JS Logfiles" - set desc = "Delete all logfiles for JS error reporting. Be extra sure you want to do this!" - - if(!holder) - return - - if (alert("Are you really sure you want to delete every single JS logfile?", "No", "Yes") == "No") - return - - var/list/summary = GLOB.debugFileOutput.clearAll() - var/friendlySummary = summary.Join(", ") - - log_admin("[key_name(usr)] deleted every JS logfile! ([friendlySummary])") - message_admins("[key_name_admin(usr)] deleted every JS logfile! ([friendlySummary])") \ No newline at end of file diff --git a/code/modules/holiday/halloween/halloween.dm b/code/modules/holiday/halloween/halloween.dm index 24225c1a20..d3b9b92b4f 100644 --- a/code/modules/holiday/halloween/halloween.dm +++ b/code/modules/holiday/halloween/halloween.dm @@ -132,7 +132,7 @@ speak_emote = list("howls") emote_hear = list("wails","screeches") density = FALSE - anchored = TRUE + move_resist = MOVE_FORCE_OVERPOWERING incorporeal_move = 1 layer = 4 var/timer = 0 diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm index bd4c26e0f2..2b116bbfd3 100644 --- a/code/modules/holiday/halloween/jacqueen.dm +++ b/code/modules/holiday/halloween/jacqueen.dm @@ -450,7 +450,7 @@ reagents.add_reagent(R, 30) name = "[R] Potion" -/obj/item/reagent_containers/potion_container/throw_impact(atom/target) +/obj/item/reagent_containers/potion_container/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() sleep(20) var/datum/effect_system/smoke_spread/chem/s = new() diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm index 9dd016c235..68001db517 100644 --- a/code/modules/holiday/holidays.dm +++ b/code/modules/holiday/holidays.dm @@ -23,8 +23,8 @@ // Returns special prefixes for the station name on certain days. You wind up with names like "Christmas Object Epsilon". See new_station_name() /datum/holiday/proc/getStationPrefix() //get the first word of the Holiday and use that - var/i = findtext(name," ",1,0) - return copytext(name,1,i) + var/i = findtext(name," ") + return copytext(name, 1, i) // Return 1 if this holidy should be celebrated today /datum/holiday/proc/shouldCelebrate(dd, mm, yy, ww, ddd) diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index 7bd2ac689b..206a5c14a3 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -80,7 +80,7 @@ item_state = "dodgeball" desc = "Used for playing the most violent and degrading of childhood games." -/obj/item/toy/beach_ball/holoball/dodgeball/throw_impact(atom/hit_atom) +/obj/item/toy/beach_ball/holoball/dodgeball/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() if((ishuman(hit_atom))) var/mob/living/carbon/M = hit_atom @@ -123,7 +123,7 @@ else ..() -/obj/structure/holohoop/hitby(atom/movable/AM) +/obj/structure/holohoop/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if (isitem(AM) && !istype(AM,/obj/item/projectile)) if(prob(50)) AM.forceMove(get_turf(src)) diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index e946973ded..2376010408 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -52,6 +52,12 @@ productivity = P max_items = max_storage + +/obj/machinery/biogenerator/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Productivity at [productivity*100]%.
    Matter consumption reduced by [(efficiency*25)-25]%.
    Machine can hold up to [max_items] pieces of produce.
    " + /obj/machinery/biogenerator/on_reagent_change(changetype) //When the reagents change, change the icon as well. update_icon() diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index fc9b2229e5..8f2900c8a6 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -401,7 +401,7 @@ /obj/machinery/plantgenes/proc/repaint_seed() if(!seed) return - if(copytext(seed.name, 1, 13) == "experimental") + if(copytext(seed.name, 1, 13) == "experimental")//13 == length("experimental") + 1 return // Already modded name and icon seed.name = "experimental " + seed.name seed.icon_state = "seed-x" diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index bb751c993a..f99cfde92d 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -91,7 +91,7 @@ squash(user) ..() -/obj/item/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom) +/obj/item/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) //was it caught by a mob? if(seed) for(var/datum/plant_gene/trait/T in seed.genes) diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index bdbf999f7a..ef925e3965 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -48,7 +48,7 @@ return 1 return 0 -/obj/item/grown/throw_impact(atom/hit_atom) +/obj/item/grown/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) //was it caught by a mob? if(seed) for(var/datum/plant_gene/trait/T in seed.genes) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 2d0d2c5282..1cd63db6da 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -46,6 +46,11 @@ maxwater = tmp_capacity * 50 // Up to 300 maxnutri = tmp_capacity * 5 // Up to 30 +/obj/machinery/hydroponics/constructable/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Tray efficiency at [rating*100]%." + /obj/machinery/hydroponics/Destroy() if(myseed) qdel(myseed) diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index 5af19b8431..617b980654 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -56,6 +56,11 @@ for(var/obj/item/stock_parts/manipulator/M in component_parts) seed_multiplier = M.rating +/obj/machinery/seed_extractor/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Extracting [seed_multiplier] seed(s) per piece of produce.
    Machine can store up to [max_seeds]% seeds.
    " + /obj/machinery/seed_extractor/attackby(obj/item/O, mob/user, params) if(default_deconstruction_screwdriver(user, "sextractor_open", "sextractor", O)) diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index c28ae3b4c5..f459e97814 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -186,8 +186,8 @@ obj/item/seeds/proc/is_gene_forbidden(typepath) product_name = parent.myseed.plantname if(getYield() >= 1) SSblackbox.record_feedback("tally", "food_harvested", getYield(), product_name) + parent.investigate_log("[user] harvested [getYield()] of [src], with seed traits [english_list(genes)] and reagents_add [english_list(reagents_add)] and potency [potency].", INVESTIGATE_BOTANY) parent.update_tray(user) - return result diff --git a/code/modules/integrated_electronics/core/special_pins/color_pin.dm b/code/modules/integrated_electronics/core/special_pins/color_pin.dm index 30b0a1895d..64e4114357 100644 --- a/code/modules/integrated_electronics/core/special_pins/color_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/color_pin.dm @@ -15,11 +15,11 @@ new_data = uppertext(new_data) if(length(new_data) != 7) // We can hex if we want to, we can leave your strings behind return // Cause your strings don't hex and if they don't hex - var/friends = copytext(new_data, 2, 8) // Well they're are no strings of mine + var/friends = copytext_char(new_data, 2, 8) // Well they're are no strings of mine // I say, we can go where we want to, a place where they will never find var/safety_dance = 1 while(safety_dance >= 7) // And we can act like we come from out of this world.log - var/hex = copytext(friends, safety_dance, safety_dance+1) + var/hex = copytext_char(friends, safety_dance, safety_dance+1) if(!(hex in list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"))) return // Leave the fake one far behind, safety_dance++ diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index c323718c07..8c7529651b 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -224,8 +224,8 @@ var/split = min(index+1, length(text)) - var/before_text = copytext(text, 1, split) - var/after_text = copytext(text, split, 0) + var/before_text = copytext_char(text, 1, split) + var/after_text = copytext_char(text, split) set_pin_data(IC_OUTPUT, 1, before_text) set_pin_data(IC_OUTPUT, 2, after_text) @@ -331,7 +331,7 @@ var/strin = get_pin_data(IC_INPUT, 1) var/delimiter = get_pin_data(IC_INPUT, 2) if(delimiter == null) - set_pin_data(IC_OUTPUT, 1, string2charlist(strin)) + set_pin_data(IC_OUTPUT, 1, text2charlist(strin)) else set_pin_data(IC_OUTPUT, 1, splittext(strin, delimiter)) push_data() diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/code/modules/integrated_electronics/subtypes/time.dm index edb9e1ede3..1f1d5444bb 100644 --- a/code/modules/integrated_electronics/subtypes/time.dm +++ b/code/modules/integrated_electronics/subtypes/time.dm @@ -175,7 +175,7 @@ desc = "Tells you what the time is, in terms and adjusted for your local station or planet" /obj/item/integrated_circuit/time/clock/station/get_time() - return STATION_TIME(FALSE) + return STATION_TIME(FALSE, world.time) /obj/item/integrated_circuit/time/clock/bluespace name = "integrated clock (Bluespace Absolute Time)" diff --git a/code/modules/keybindings/bindings_atom.dm b/code/modules/keybindings/bindings_atom.dm index 4aac76bd67..5f3e879237 100644 --- a/code/modules/keybindings/bindings_atom.dm +++ b/code/modules/keybindings/bindings_atom.dm @@ -15,4 +15,4 @@ movement_dir &= ~(NORTH|SOUTH) if((movement_dir & EAST) && (movement_dir & WEST)) movement_dir &= ~(EAST|WEST) - user.Move(get_step(src, movement_dir), movement_dir) \ No newline at end of file + user.Move(get_step(src, movement_dir), movement_dir) diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm index dec5c25eb9..6030362a61 100644 --- a/code/modules/keybindings/bindings_client.dm +++ b/code/modules/keybindings/bindings_client.dm @@ -5,7 +5,7 @@ set hidden = TRUE client_keysend_amount += 1 - + var/cache = client_keysend_amount if(keysend_tripped && next_keysend_trip_reset <= world.time) @@ -20,7 +20,7 @@ //don't want to kick people if a lag spike results in a huge flood of commands being sent if(cache >= MAX_KEYPRESS_AUTOKICK) if(!keysend_tripped) - keysend_tripped = TRUE + keysend_tripped = TRUE next_keysend_trip_reset = world.time + (2 SECONDS) else log_admin("Client [ckey] was just autokicked for flooding keysends; likely abuse but potentially lagspike.") @@ -35,11 +35,10 @@ message_admins("Client [ckey] just attempted to send an invalid keypress. Keymessage was over [MAX_KEYPRESS_COMMANDLENGTH] characters, autokicking due to likely abuse.") QDEL_IN(src, 1) return - //offset by 1 because the buffer address is 0 indexed because the math was simpler - keys_held[current_key_address + 1] = _key - //the time a key was pressed isn't actually used anywhere (as of 2019-9-10) but this allows easier access usage/checking - keys_held[_key] = world.time - current_key_address = ((current_key_address + 1) % HELD_KEY_BUFFER_LENGTH) + + if(length(keys_held) > MAX_HELD_KEYS) + keys_held.Cut(1,2) + keys_held[_key] = TRUE var/movement = SSinput.movement_keys[_key] if(!(next_move_dir_sub & movement) && !keys_held["Ctrl"]) next_move_dir_add |= movement @@ -70,11 +69,7 @@ set instant = TRUE set hidden = TRUE - //Can't just do a remove because it would alter the length of the rolling buffer, instead search for the key then null it out if it exists - for(var/i in 1 to HELD_KEY_BUFFER_LENGTH) - if(keys_held[i] == _key) - keys_held[i] = null - break + keys_held -= _key var/movement = SSinput.movement_keys[_key] if(!(next_move_dir_add & movement)) next_move_dir_sub |= movement diff --git a/code/modules/keybindings/setup.dm b/code/modules/keybindings/setup.dm index 8433c9bf5a..9a13bfb11c 100644 --- a/code/modules/keybindings/setup.dm +++ b/code/modules/keybindings/setup.dm @@ -1,8 +1,6 @@ /client - /// A rolling buffer of any keys held currently + /// Keys currently held var/list/keys_held = list() - ///used to keep track of the current rolling buffer position - var/current_key_address = 0 /// These next two vars are to apply movement for keypresses and releases made while move delayed. /// Because discarding that input makes the game less responsive. /// On next move, add this dir to the move that would otherwise be done @@ -36,10 +34,7 @@ /client/proc/set_macros() set waitfor = FALSE - //Reset and populate the rolling buffer keys_held.Cut() - for(var/i in 1 to HELD_KEY_BUFFER_LENGTH) - keys_held += null erase_all_macros() diff --git a/code/modules/language/codespeak.dm b/code/modules/language/codespeak.dm index a7f8c7284d..be325d14b0 100644 --- a/code/modules/language/codespeak.dm +++ b/code/modules/language/codespeak.dm @@ -13,13 +13,13 @@ . = "" var/list/words = list() - while(length(.) < length(input)) + while(length_char(.) < length_char(input)) words += generate_code_phrase(return_list=TRUE) . = jointext(words, ", ") . = capitalize(.) - var/input_ending = copytext(input, length(input)) + var/input_ending = copytext_char(input, -1) var/static/list/endings if(!endings) diff --git a/code/modules/language/language.dm b/code/modules/language/language.dm index e4488fc75f..536bf06e8d 100644 --- a/code/modules/language/language.dm +++ b/code/modules/language/language.dm @@ -80,11 +80,11 @@ if(lookup) return lookup - var/input_size = length(input) + var/input_size = length_char(input) var/scrambled_text = "" var/capitalize = TRUE - while(length(scrambled_text) < input_size) + while(length_char(scrambled_text) < input_size) var/next = pick(syllables) if(capitalize) next = capitalize(next) @@ -98,10 +98,10 @@ scrambled_text += " " scrambled_text = trim(scrambled_text) - var/ending = copytext(scrambled_text, length(scrambled_text)) + var/ending = copytext_char(scrambled_text, -1) if(ending == ".") - scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1) - var/input_ending = copytext(input, input_size) + scrambled_text = copytext_char(scrambled_text, 1, -2) + var/input_ending = copytext_char(input, -1) if(input_ending in list("!","?",".")) scrambled_text += input_ending diff --git a/code/modules/language/language_menu.dm b/code/modules/language/language_menu.dm index df0edbe6f0..eea87f1d80 100644 --- a/code/modules/language/language_menu.dm +++ b/code/modules/language/language_menu.dm @@ -11,7 +11,7 @@ /datum/language_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.language_menu_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "language_menu", "Language Menu", 700, 800, master_ui, state) + ui = new(user, src, ui_key, "language_menu", "Language Menu", 700, 600, master_ui, state) ui.open() /datum/language_menu/ui_data(mob/user) diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 253ba277e7..204a2de9a6 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -387,9 +387,9 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums if(checkoutperiod < 1) checkoutperiod = 1 if(href_list["editbook"]) - buffer_book = copytext(sanitize(input("Enter the book's title:") as text|null),1,MAX_MESSAGE_LEN) + buffer_book = stripped_input(usr, "Enter the book's title:") if(href_list["editmob"]) - buffer_mob = copytext(sanitize(input("Enter the recipient's name:") as text|null),1,MAX_NAME_LEN) + buffer_mob = stripped_input(usr, "Enter the recipient's name:", max_length = MAX_NAME_LEN) if(href_list["checkout"]) var/datum/borrowbook/b = new /datum/borrowbook b.bookname = sanitize(buffer_book) @@ -406,7 +406,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums if(b && istype(b)) inventory.Remove(b) if(href_list["setauthor"]) - var/newauthor = copytext(sanitize(input("Enter the author's name: ") as text|null),1,MAX_MESSAGE_LEN) + var/newauthor = stripped_input(usr, "Enter the author's name: ") if(newauthor) scanner.cache.author = newauthor if(href_list["setcategory"]) diff --git a/code/modules/library/soapstone.dm b/code/modules/library/soapstone.dm index 0d7ae7107b..272e39957e 100644 --- a/code/modules/library/soapstone.dm +++ b/code/modules/library/soapstone.dm @@ -151,7 +151,7 @@ /obj/structure/chisel_message/update_icon() ..() var/hash = md5(hidden_message) - var/newcolor = copytext(hash, 1, 7) + var/newcolor = copytext_char(hash, 1, 7) add_atom_colour("#[newcolor]", FIXED_COLOUR_PRIORITY) light_color = "#[newcolor]" set_light(1) diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm index 9b27691dd3..86b501c455 100644 --- a/code/modules/mapping/reader.dm +++ b/code/modules/mapping/reader.dm @@ -241,7 +241,8 @@ var/variables_start = findtext(full_def, "{") var/path_text = trim_text(copytext(full_def, 1, variables_start)) var/atom_def = text2path(path_text) //path definition, e.g /obj/foo/bar - old_position = dpos + 1 + if(dpos) + old_position = dpos + length(model[dpos]) if(!ispath(atom_def, /atom)) // Skip the item if the path does not exist. Fix your crap, mappers! if(bad_paths) @@ -253,7 +254,7 @@ var/list/fields = list() if(variables_start)//if there's any variable - full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}' + full_def = copytext(full_def, variables_start + length(full_def[variables_start]), -length(copytext_char(full_def, -1))) //removing the last '}' fields = readlist(full_def, ";") if(fields.len) if(!trim(fields[fields.len])) @@ -423,12 +424,13 @@ var/trim_left = trim_text(copytext(text,old_position,(equal_position ? equal_position : position))) var/left_constant = delimiter == ";" ? trim_left : parse_constant(trim_left) - old_position = position + 1 + if(position) + old_position = position + length(text[position]) if(equal_position && !isnum(left_constant)) // Associative var, so do the association. // Note that numbers cannot be keys - the RHS is dropped if so. - var/trim_right = trim_text(copytext(text,equal_position+1,position)) + var/trim_right = trim_text(copytext(text, equal_position + length(text[equal_position]), position)) var/right_constant = parse_constant(trim_right) .[left_constant] = right_constant @@ -442,12 +444,12 @@ return num // string - if(findtext(text,"\"",1,2)) - return copytext(text,2,findtext(text,"\"",3,0)) + if(text[1] == "\"") + return copytext(text, length(text[1]) + 1, findtext(text, "\"", length(text[1]) + 1)) // list - if(copytext(text,1,6) == "list(") - return readlist(copytext(text,6,length(text))) + if(copytext(text, 1, 6) == "list(")//6 == length("list(") + 1 + return readlist(copytext(text, 6, -1)) // typepath var/path = text2path(text) @@ -455,8 +457,8 @@ return path // file - if(copytext(text,1,2) == "'") - return file(copytext(text,2,length(text))) + if(text[1] == "'") + return file(copytext_char(text, 2, -1)) // null if(text == "null") diff --git a/code/modules/mapping/ruins.dm b/code/modules/mapping/ruins.dm index 9c578badb1..34ce6ef35c 100644 --- a/code/modules/mapping/ruins.dm +++ b/code/modules/mapping/ruins.dm @@ -22,6 +22,8 @@ for(var/i in get_affected_turfs(central_turf, 1)) var/turf/T = i + for(var/obj/structure/spawner/nest in T) + qdel(nest) for(var/mob/living/simple_animal/monster in T) qdel(monster) for(var/obj/structure/flora/ash/plant in T) diff --git a/code/modules/mapping/verify.dm b/code/modules/mapping/verify.dm index a9834e3709..1f071aaec7 100644 --- a/code/modules/mapping/verify.dm +++ b/code/modules/mapping/verify.dm @@ -60,8 +60,9 @@ // build_cache will check bad paths for us var/list/modelCache = build_cache(TRUE, report.bad_paths) + var/static/regex/area_or_turf = regex(@"/(turf|area)/") for(var/path in report.bad_paths) - if(copytext(path, 1, 7) == "/turf/" || copytext(path, 1, 7) == "/area/") + if(area_or_turf.Find("[path]", 1, 1)) report.loadable = FALSE // check for tiles with the wrong number of turfs or areas diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 4cfd2e447f..9ee358af62 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -157,20 +157,23 @@ var/input = input(usr, "Enter [codelen] digits. All digits must be unique.", "Deca-Code Lock", "") as text if(user.canUseTopic(src, BE_CLOSE)) var/list/sanitised = list() - var/sanitycheck = 1 - for(var/i=1,i<=length(input),i++) //put the guess into a list - sanitised += text2num(copytext(input,i,i+1)) - for(var/i=1,i<=(length(input)-1),i++) //compare each digit in the guess to all those following it - for(var/j=(i+1),j<=length(input),j++) + var/sanitycheck = TRUE + var/char = "" + var/length_input = length(input) + for(var/i = 1, i <= length_input, i += length(char)) //put the guess into a list + char = input[i] + sanitised += text2num(char) + for(var/i = 1, i <= length(sanitised) - 1, i++) //compare each digit in the guess to all those following it + for(var/j = i + 1, j <= length(sanitised), j++) if(sanitised[i] == sanitised[j]) - sanitycheck = null //if a digit is repeated, reject the input - if (input == code) + sanitycheck = FALSE //if a digit is repeated, reject the input + if(input == code) to_chat(user, "The crate unlocks!") locked = FALSE cut_overlays() add_overlay("securecrateg") tamperproof = 0 // set explosion chance to zero, so we dont accidently hit it with a multitool and instantly die - else if (input == null || sanitycheck == null || length(input) != codelen) + else if(!input || !sanitycheck || length(sanitised) != codelen) to_chat(user, "You leave the crate alone.") else to_chat(user, "A red light flashes.") @@ -196,20 +199,27 @@ else to_chat(user, "* Anti-Tamper Bomb will activate after [attempts] failed access attempts.") if(lastattempt != null) - var/list/guess = list() - var/list/answer = list() - var/bulls = 0 - var/cows = 0 - for(var/i=1,i<=length(lastattempt),i++) - guess += text2num(copytext(lastattempt,i,i+1)) - for(var/i=1,i<=length(lastattempt),i++) - answer += text2num(copytext(code,i,i+1)) - for(var/i = 1, i < codelen + 1, i++) // Go through list and count matches - if( answer.Find(guess[i],1,codelen+1)) - ++cows - if( answer[i] == guess[i]) + var/bulls = 0 //right position, right number + var/cows = 0 //wrong position but in the puzzle + + var/lastattempt_char = "" + var/length_lastattempt = length(lastattempt) + var/lastattempt_it = 1 + + var/code_char = "" + var/length_code = length(code) + var/code_it = 1 + + while(lastattempt_it <= length_lastattempt && code_it <= length_code) // Go through list and count matches + lastattempt_char = lastattempt[lastattempt_it] + code_char = code[code_it] + if(lastattempt_char == code_char) ++bulls - --cows + else if(findtext(code, lastattempt_char)) + ++cows + + lastattempt_it += length(lastattempt_char) + code_it += length(code_char) to_chat(user, "Last code attempt, [lastattempt], had [bulls] correct digits at correct positions and [cows] correct digits at incorrect positions.") return diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index bdca4bb7df..5165d95340 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -70,7 +70,7 @@ item_state = "hostile_env" clothing_flags = THICKMATERIAL //not spaceproof max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - resistance_flags = FIRE_PROOF | LAVA_PROOF + resistance_flags = FIRE_PROOF | LAVA_PROOF | ACID_PROOF | GOLIATH_RESISTANCE mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC slowdown = 0 armor = list("melee" = 70, "bullet" = 40, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) @@ -167,7 +167,7 @@ w_class = WEIGHT_CLASS_BULKY heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS hoodtype = /obj/item/clothing/head/hooded/explorer/exo - armor = list("melee" = 65, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 60, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0) + armor = list("melee" = 55, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 40, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0) resistance_flags = FIRE_PROOF | GOLIATH_RESISTANCE /obj/item/clothing/head/hooded/explorer/exo @@ -175,7 +175,7 @@ desc = "A robust helmet for fighting dangerous animals. Its design and material make it harder for a Goliath to keep their grip on the wearer." icon_state = "exo" item_state = "exo" - armor = list("melee" = 65, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 60, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0) + armor = list("melee" = 55, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 40, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0) resistance_flags = FIRE_PROOF | GOLIATH_RESISTANCE /obj/item/clothing/mask/gas/exo diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index f46f4f785c..fd366670f0 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -11,6 +11,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) var/uses_left = 3 var/can_use_indoors var/safe_for_living_creatures = 1 + var/max_force_fulton = MOVE_FORCE_STRONG /obj/item/extraction_pack/examine() . = ..() @@ -57,7 +58,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) return if(!isturf(A.loc)) // no extracting stuff inside other stuff return - if(A.anchored) + if(A.anchored || (A.move_resist > max_force_fulton)) return to_chat(user, "You start attaching the pack to [A]...") if(do_after(user,50,target=A)) diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index b99ae6bf65..14a277a66c 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -36,7 +36,7 @@ GLOBAL_LIST(labor_sheet_values) datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "labor_claim_console", name, 450, 475, master_ui, state) + ui = new(user, src, ui_key, "labor_claim_console", name, 315, 430, master_ui, state) ui.open() /obj/machinery/mineral/labor_claim_console/ui_data(mob/user) @@ -47,7 +47,6 @@ GLOBAL_LIST(labor_sheet_values) if(obj_flags & EMAGGED) can_go_home = TRUE - data["status_info"] = "No Prisoner ID detected." var/obj/item/card/id/I = user.get_idcard(TRUE) if(istype(I, /obj/item/card/id/prisoner)) var/obj/item/card/id/prisoner/P = I @@ -57,6 +56,9 @@ GLOBAL_LIST(labor_sheet_values) data["status_info"] = "Goal met!" else data["status_info"] = "You are [(P.goal - P.points)] points away." + else + data["status_info"] = "No Prisoner ID detected." + data["id_points"] = 0 if(stacking_machine) data["unclaimed_points"] = stacking_machine.points @@ -78,24 +80,27 @@ GLOBAL_LIST(labor_sheet_values) P.points += stacking_machine.points stacking_machine.points = 0 to_chat(usr, "Points transferred.") + . = TRUE else - to_chat(usr, "No valid id for point transfer detected.") + to_chat(usr, "No valid id for point transfer detected.") if("move_shuttle") if(!alone_in_area(get_area(src), usr)) - to_chat(usr, "Prisoners are only allowed to be released while alone.") + to_chat(usr, "Prisoners are only allowed to be released while alone.") else switch(SSshuttle.moveShuttle("laborcamp", "laborcamp_home", TRUE)) if(1) - to_chat(usr, "Shuttle not found.") + to_chat(usr, "Shuttle not found.") if(2) - to_chat(usr, "Shuttle already at station.") + to_chat(usr, "Shuttle already at station.") if(3) - to_chat(usr, "No permission to dock could be granted.") + to_chat(usr, "No permission to dock could be granted.") else if(!(obj_flags & EMAGGED)) Radio.set_frequency(FREQ_SECURITY) Radio.talk_into(src, "A prisoner has returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY) to_chat(usr, "Shuttle received message and will be sent shortly.") + . = TRUE + /obj/machinery/mineral/labor_claim_console/proc/locate_stacking_machine() stacking_machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir)) diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index b5f7bbf8ab..0a508cdaf5 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -220,6 +220,7 @@ data["disconnected"] = "mineral withdrawal is on hold" data["diskDesigns"] = list() + data["hasDisk"] = FALSE if(inserted_disk) data["hasDisk"] = TRUE if(inserted_disk.blueprints.len) diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm index d98f00ede7..7d6bb80663 100644 --- a/code/modules/mining/machine_silo.dm +++ b/code/modules/mining/machine_silo.dm @@ -197,7 +197,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs) var/list/materials /datum/ore_silo_log/New(obj/machinery/M, _action, _amount, _noun, list/mats=list()) - timestamp = STATION_TIME_TIMESTAMP("hh:mm:ss") + timestamp = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time) machine_name = M.name area_name = get_area_name(M, TRUE) action = _action @@ -230,5 +230,5 @@ GLOBAL_LIST_EMPTY(silo_access_logs) var/val = round(materials[key]) / MINERAL_MATERIAL_AMOUNT msg += sep sep = ", " - msg += "[amount < 0 ? "-" : "+"][val] [copytext(key, 2)]" + msg += "[amount < 0 ? "-" : "+"][val] [copytext(key, length(key[1]) + 1)]" formatted = msg.Join() diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 1c83c70d95..7765bf8713 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -99,7 +99,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ recipes = GLOB.sand_recipes . = ..() -/obj/item/stack/ore/glass/throw_impact(atom/hit_atom) +/obj/item/stack/ore/glass/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(..() || !ishuman(hit_atom)) return var/mob/living/carbon/human/C = hit_atom diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index ed104d9eef..d78a406b80 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -28,7 +28,7 @@ /obj/structure/ore_box/examine(mob/living/user) if(Adjacent(user) && istype(user)) - show_contents(user) + ui_interact(user) return ..() /obj/structure/ore_box/attack_hand(mob/user) @@ -36,22 +36,11 @@ if(.) return if(Adjacent(user)) - show_contents(user) + ui_interact(user) /obj/structure/ore_box/attack_robot(mob/user) if(Adjacent(user)) - show_contents(user) - -/obj/structure/ore_box/proc/show_contents(mob/user) - var/dat = text("The contents of the ore box reveal...
    ") - var/list/assembled = list() - for(var/obj/item/stack/ore/O in src) - assembled[O.type] += O.amount - for(var/type in assembled) - var/obj/item/stack/ore/O = type - dat += "[initial(O.name)] - [assembled[type]]
    " - dat += text("

    Empty box") - user << browse(dat, "window=orebox") + ui_interact(user) /obj/structure/ore_box/proc/dump_box_contents() var/drop = drop_location() @@ -65,18 +54,38 @@ stoplag() drop = drop_location() -/obj/structure/ore_box/Topic(href, href_list) +/obj/structure/ore_box/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "ore_box", name, 335, 415, master_ui, state) + ui.open() + +/obj/structure/ore_box/ui_data() + var/contents = list() + for(var/obj/item/stack/ore/O in src) + contents[O.type] += O.amount + + var/data = list() + data["materials"] = list() + for(var/type in contents) + var/obj/item/stack/ore/O = type + var/name = initial(O.name) + data["materials"] += list(list("name" = name, "amount" = contents[type], "id" = type)) + + return data + +/obj/structure/ore_box/ui_act(action, params) if(..()) return if(!Adjacent(usr)) return - - usr.set_machine(src) add_fingerprint(usr) - if(href_list["removeall"]) - dump_box_contents() - to_chat(usr, "You open the release hatch on the box..") - updateUsrDialog() + usr.set_machine(src) + switch(action) + if("removeall") + dump_box_contents() + to_chat(usr, "You open the release hatch on the box..") /obj/structure/ore_box/deconstruct(disassembled = TRUE, mob/user) var/obj/item/stack/sheet/mineral/wood/WD = new (loc, 4) diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index a1f46c0a64..ff1d9231f7 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -3,7 +3,8 @@ /mob/camera name = "camera mob" density = FALSE - anchored = TRUE + move_force = INFINITY + move_resist = INFINITY status_flags = GODMODE // You can't damage it. mouse_opacity = MOUSE_OPACITY_TRANSPARENT see_in_dark = 7 diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 90e16649c9..0c50cb0468 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -4,6 +4,7 @@ INITIALIZE_IMMEDIATE(/mob/dead) /mob/dead sight = SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF + move_resist = INFINITY throwforce = 0 /mob/dead/Initialize() diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index ae635fa371..0418b281e6 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -12,8 +12,6 @@ stat = DEAD canmove = FALSE - anchored = TRUE // don't get pushed around - var/mob/living/new_character //for instant transfer once the round is set up //Used to make sure someone doesn't get spammed with messages if they're ineligible for roles diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm index d11299fd5b..34988f5656 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_face.dm @@ -7,6 +7,26 @@ // please make sure they're sorted alphabetically and categorized +/datum/sprite_accessory/facial_hair/threeoclock + name = "Beard (3 o\'Clock)" + icon_state = "facial_3oclock" + +/datum/sprite_accessory/facial_hair/fiveoclock + name = "Beard (5 o\'Clock)" + icon_state = "facial_5oclock" + +/datum/sprite_accessory/facial_hair/fiveoclockm + name = "Beard (5 o\'Clock with Moustache)" + icon_state = "facial_5oclockmoustache" + +/datum/sprite_accessory/facial_hair/sevenoclock + name = "Beard (7 o\'Clock)" + icon_state = "facial_7oclock" + +/datum/sprite_accessory/facial_hair/sevenoclockm + name = "Beard (7 o\'Clock with Moustache)" + icon_state = "facial_7oclockmoustache" + /datum/sprite_accessory/facial_hair/abe name = "Beard (Abraham Lincoln)" icon_state = "facial_abe" @@ -23,10 +43,6 @@ name = "Beard (Dwarf)" icon_state = "facial_dwarf" -/datum/sprite_accessory/facial_hair/fiveoclock - name = "Beard (Five o Clock Shadow)" - icon_state = "facial_fiveoclock" - /datum/sprite_accessory/facial_hair/fullbeard name = "Beard (Full)" icon_state = "facial_fullbeard" @@ -35,6 +51,10 @@ name = "Beard (Goatee)" icon_state = "facial_gt" +/datum/sprite_accessory/facial_hair/goatee + name = "Beard (Goatee 2)" + icon_state = "facial_goatee" + /datum/sprite_accessory/facial_hair/hip name = "Beard (Hipster)" icon_state = "facial_hip" @@ -43,18 +63,38 @@ name = "Beard (Jensen)" icon_state = "facial_jensen" +/datum/sprite_accessory/facial_hair/martialartist + name = "Beard (Martial Artist)" + icon_state = "facial_martialartist" + +/datum/sprite_accessory/facial_hair/moonshiner + name = "Beard (Moonshiner)" + icon_state = "facial_moonshiner" + /datum/sprite_accessory/facial_hair/neckbeard name = "Beard (Neckbeard)" icon_state = "facial_neckbeard" +/datum/sprite_accessory/facial_hair/tribeard + name = "Beard (Tribeard)" + icon_state = "facial_tribeard" + /datum/sprite_accessory/facial_hair/vlongbeard name = "Beard (Very Long)" icon_state = "facial_wise" +/datum/sprite_accessory/facial_hair/volaju + name = "Beard (Volaju)" + icon_state = "facial_volaju" + /datum/sprite_accessory/facial_hair/longbeard name = "Beard (Long)" icon_state = "facial_longbeard" +/datum/sprite_accessory/facial_hair/moustache + name = "Moustache" + icon_state = "facial_moustache" + /datum/sprite_accessory/facial_hair/fu name = "Moustache (Fu Manchu)" icon_state = "facial_fumanchu" @@ -63,6 +103,10 @@ name = "Moustache (Hulk Hogan)" icon_state = "facial_hogan" //-Neek +/datum/sprite_accessory/facial_hair/pencil + name = "Moustache (Pencil)" + icon_state = "facial_pencilstache" + /datum/sprite_accessory/facial_hair/selleck name = "Moustache (Selleck)" icon_state = "facial_selleck" @@ -75,56 +119,31 @@ name = "Moustache (Van Dyke)" icon_state = "facial_vandyke" +/datum/sprite_accessory/facial_hair/walrus + name = "Moustache (Walrus)" + icon_state = "facial_walrus" + /datum/sprite_accessory/facial_hair/watson name = "Moustache (Watson)" icon_state = "facial_watson" +/datum/sprite_accessory/facial_hair/mutton + name = "Mutton Chops" + icon_state = "facial_mutton" + +/datum/sprite_accessory/facial_hair/muttonmus + name = "Mutton Chops with Moustache" + icon_state = "facial_muttonmus" + /datum/sprite_accessory/facial_hair/shaved name = "Shaved" icon_state = null gender = NEUTER +/datum/sprite_accessory/facial_hair/sideburn + name = "Sideburns" + icon_state = "facial_sideburns" + /datum/sprite_accessory/facial_hair/elvis name = "Sideburns (Elvis)" - icon_state = "facial_elvis" - -#define VFACE(_name, new_state) /datum/sprite_accessory/facial_hair/##new_state/icon_state=#new_state;;/datum/sprite_accessory/facial_hair/##new_state/name= #_name + " (Virgo)" -VFACE("Watson", facial_watson_s) -VFACE("Chaplin", facial_chaplin_s) -VFACE("Fullbeard", facial_fullbeard_s) -VFACE("Vandyke", facial_vandyke_s) -VFACE("Elvis", facial_elvis_s) -VFACE("Abe", facial_abe_s) -VFACE("Chin", facial_chin_s) -VFACE("GT", facial_gt_s) -VFACE("Hip", facial_hip_s) -VFACE("Hogan", facial_hogan_s) -VFACE("Selleck", facial_selleck_s) -VFACE("Neckbeard", facial_neckbeard_s) -VFACE("Longbeard", facial_longbeard_s) -VFACE("Dwarf", facial_dwarf_s) -VFACE("Sideburn", facial_sideburn_s) -VFACE("Mutton", facial_mutton_s) -VFACE("Moustache", facial_moustache_s) -VFACE("Pencilstache", facial_pencilstache_s) -VFACE("Goatee", facial_goatee_s) -VFACE("Smallstache", facial_smallstache_s) -VFACE("Volaju", facial_volaju_s) -VFACE("3 O\'clock", facial_3oclock_s) -VFACE("5 O\'clock", facial_5oclock_s) -VFACE("7 O\'clock", facial_7oclock_s) -VFACE("5 O\'clock Moustache", facial_5oclockmoustache_s) -VFACE("7 O\'clock", facial_7oclockmoustache_s) -VFACE("Walrus", facial_walrus_s) -VFACE("Muttonmus", facial_muttonmus_s) -VFACE("Wise", facial_wise_s) -VFACE("Martial Artist", facial_martialartist_s) -VFACE("Dorsalfnil", facial_dorsalfnil_s) -VFACE("Hornadorns", facial_hornadorns_s) -VFACE("Spike", facial_spike_s) -VFACE("Chinhorns", facial_chinhorns_s) -VFACE("Cropped Fullbeard", facial_croppedfullbeard_s) -VFACE("Chinless Beard", facial_chinlessbeard_s) -VFACE("Moonshiner", facial_moonshiner_s) -VFACE("Tribearder", facial_tribearder_s) -#undef VFACE \ No newline at end of file + icon_state = "facial_elvis" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm index abcc90c0ee..b0ed2000a6 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/hair_head.dm @@ -27,7 +27,7 @@ /datum/sprite_accessory/hair/bald name = "Bald" - icon_state = null + icon_state = "bald" /datum/sprite_accessory/hair/balding name = "Balding Hair" @@ -37,6 +37,14 @@ name = "Bedhead" icon_state = "hair_bedhead" +/datum/sprite_accessory/hair/bedhead_long + name = "Bedhead (Long)" + icon_state = "hair_long_bedhead" + +/datum/sprite_accessory/hair/bedhead_longer + name = "Bedhead (Longer)" + icon_state = "hair_longer_bedhead" + /datum/sprite_accessory/hair/bedhead2 name = "Bedhead 2" icon_state = "hair_bedheadv2" @@ -51,7 +59,7 @@ /datum/sprite_accessory/hair/beehive2 name = "Beehive 2" - icon_state = "hair_beehivev2" + icon_state = "hair_beehive2" /datum/sprite_accessory/hair/bob name = "Bob Hair" @@ -69,6 +77,14 @@ name = "Bobcurl" icon_state = "hair_bobcurl" +/datum/sprite_accessory/hair/bobcut + name = "Bobcut" + icon_state = "hair_bobcut" + +/datum/sprite_accessory/hair/bobcutalt + name = "Bobcut (Alt)" + icon_state = "hair_bobcutalt" + /datum/sprite_accessory/hair/boddicker name = "Boddicker" icon_state = "hair_boddicker" @@ -77,6 +93,10 @@ name = "Bowl" icon_state = "hair_bowlcut" +/datum/sprite_accessory/hair/bowl2 + name = "Bowl 2" + icon_state = "hair_bowlcut2" + /datum/sprite_accessory/hair/braid name = "Braid (Floorlength)" icon_state = "hair_braid" @@ -89,6 +109,10 @@ name = "Braided Front" icon_state = "hair_braidfront" +/datum/sprite_accessory/hair/grandebraid + name = "Braid (Grande)" + icon_state = "hair_grande" + /datum/sprite_accessory/hair/not_floorlength_braid name = "Braid (High)" icon_state = "hair_braid2" @@ -113,10 +137,26 @@ name = "Bun Head 2" icon_state = "hair_bunhead2" +/datum/sprite_accessory/hair/bun3 + name = "Bun Head 3" + icon_state = "hair_bunhead3" + +/datum/sprite_accessory/hair/bun4 + name = "Bun Head 4" + icon_state = "hair_bunhead4" + +/datum/sprite_accessory/hair/doublebun + name = "Bun Head (Double)" + icon_state = "hair_doublebun" + /datum/sprite_accessory/hair/largebun - name = "Bun (Large)" + name = "Bun Head (Large)" icon_state = "hair_largebun" +/datum/sprite_accessory/hair/tightbun + name = "Bun Head (Tight)" + icon_state = "hair_tightbun" + /datum/sprite_accessory/hair/business name = "Business Hair" icon_state = "hair_business" @@ -137,10 +177,22 @@ name = "Buzzcut" icon_state = "hair_buzzcut" +/datum/sprite_accessory/hair/cia + name = "CIA" + icon_state = "hair_cia" + /datum/sprite_accessory/hair/combover name = "Combover" icon_state = "hair_combover" +/datum/sprite_accessory/hair/coffeehouse + name = "Coffee House" + icon_state = "hair_coffeehouse" + +/datum/sprite_accessory/hair/country + name = "Country" + icon_state = "hair_country" + /datum/sprite_accessory/hair/crew name = "Crewcut" icon_state = "hair_crewcut" @@ -149,13 +201,21 @@ name = "Curls" icon_state = "hair_curls" +/datum/sprite_accessory/hair/curly + name = "Curly" + icon_state = "hair_curly" + /datum/sprite_accessory/hair/cut name = "Cut Hair" icon_state = "hair_c" +/datum/sprite_accessory/hair/dave + name = "Dave" + icon_state = "hair_dave" + /datum/sprite_accessory/hair/devillock name = "Devil Lock" - icon_state = "hair_devilock" + icon_state = "hair_devillock" /datum/sprite_accessory/hair/dreadlocks name = "Dreadlocks" @@ -173,22 +233,66 @@ name = "Emo" icon_state = "hair_emo" +/datum/sprite_accessory/hair/emo2 + name = "Emo 2" + icon_state = "hair_emo2" + +/datum/sprite_accessory/hair/emo_fringe + name = "Emo (Fringe)" + icon_state = "hair_emofringe" + +/datum/sprite_accessory/hair/emo_long + name = "Emo (Long)" + icon_state = "hair_emolong" + +/datum/sprite_accessory/hair/lowfade + name = "Fade (Low)" + icon_state = "hair_lowfade" + +/datum/sprite_accessory/hair/medfade + name = "Fade (Medium)" + icon_state = "hair_medfade" + +/datum/sprite_accessory/hair/highfade + name = "Fade (High)" + icon_state = "hair_highfade" + +/datum/sprite_accessory/hair/baldfade + name = "Fade (Bald)" + icon_state = "hair_baldfade" + +/datum/sprite_accessory/hair/nofade + name = "Fade (None)" + icon_state = "hair_nofade" + +/datum/sprite_accessory/hair/father + name = "Father" + icon_state = "hair_father" + /datum/sprite_accessory/hair/feather name = "Feather" icon_state = "hair_feather" +/datum/sprite_accessory/hair/flair + name = "Flair" + icon_state = "hair_flair" + /datum/sprite_accessory/hair/sargeant name = "Flat Top" - icon_state = "hair_sargeant" + icon_state = "hair_sergeant" /datum/sprite_accessory/hair/bigflattop name = "Flat Top (Big)" icon_state = "hair_bigflattop" -/datum/sprite_accessory/hair/fag +/datum/sprite_accessory/hair/fag //grimacing emoji name = "Flow Hair" icon_state = "hair_f" +/datum/sprite_accessory/hair/fringetail + name = "Fringe Tail" + icon_state = "hair_fringetail" + /datum/sprite_accessory/hair/gelled name = "Gelled Back" icon_state = "hair_gelled" @@ -205,10 +309,22 @@ name = "Half-banged Hair 2" icon_state = "hair_halfbang2" +/datum/sprite_accessory/hair/halfbangalt + name = "Half-banged Hair (Alt)" + icon_state = "hair_halfbang_alt" + +/datum/sprite_accessory/hair/halfshaved + name = "Half-shaved Hair" + icon_state = "hair_halfshaved" + /datum/sprite_accessory/hair/hedgehog name = "Hedgehog Hair" icon_state = "hair_hedgehog" +/datum/sprite_accessory/hair/hightight + name = "High and Tight" + icon_state = "hair_hightight" + /datum/sprite_accessory/hair/himecut name = "Hime Cut" icon_state = "hair_himecut" @@ -217,6 +333,10 @@ name = "Hime Cut 2" icon_state = "hair_himecut2" +/datum/sprite_accessory/hair/shorthime + name = "Hime Cut (Short)" + icon_state = "hair_shorthime" + /datum/sprite_accessory/hair/himeup name = "Hime Updo" icon_state = "hair_himeup" @@ -225,16 +345,28 @@ name = "Hitop" icon_state = "hair_hitop" +/datum/sprite_accessory/hair/jade + name = "Jade" + icon_state = "hair_jade" + /datum/sprite_accessory/hair/jensen - name = "Jensen Hair" + name = "Jensen" icon_state = "hair_jensen" +/datum/sprite_accessory/hair/joestar + name = "Joestar" + icon_state = "hair_joestar" + +/datum/sprite_accessory/hair/kagami + name = "Kagami" + icon_state = "hair_kagami" + /datum/sprite_accessory/hair/keanu - name = "Keanu Hair" + name = "Keanu" icon_state = "hair_keanu" /datum/sprite_accessory/hair/kusangi - name = "Kusanagi Hair" + name = "Kusanagi" icon_state = "hair_kusanagi" /datum/sprite_accessory/hair/long @@ -249,6 +381,10 @@ name = "Long Hair 3" icon_state = "hair_long3" +/datum/sprite_accessory/hair/longalt + name = "Long Hair (Alt)" + icon_state = "hair_longeralt" + /datum/sprite_accessory/hair/long_over_eye name = "Long Over Eye" icon_state = "hair_longovereye" @@ -269,6 +405,10 @@ name = "Long Side Part" icon_state = "hair_longsidepart" +/datum/sprite_accessory/hair/manbun + name = "Manbun" + icon_state = "hair_manbun" + /datum/sprite_accessory/hair/megaeyebrows name = "Mega Eyebrows" icon_state = "hair_megaeyebrows" @@ -277,6 +417,10 @@ name = "Messy" icon_state = "hair_messy" +/datum/sprite_accessory/hair/modern + name = "Modern" + icon_state = "hair_modern" + /datum/sprite_accessory/hair/mohawk name = "Mohawk" icon_state = "hair_d" @@ -285,6 +429,26 @@ name = "Mohawk (Reverse)" icon_state = "hair_reversemohawk" +/datum/sprite_accessory/hair/shavedmohawk + name = "Mohawk (Shaved)" + icon_state = "hair_shavedmohawk" + +/datum/sprite_accessory/hair/mohawk_unshaven + name = "Mohawk (Unshaven)" + icon_state = "hair_unshaven_mohawk" + +/datum/sprite_accessory/hair/mulder + name = "Mulder" + icon_state = "hair_mulder" + +/datum/sprite_accessory/hair/nia + name = "Nia" + icon_state = "hair_nia" + +/datum/sprite_accessory/hair/nitori + name = "Nitori" + icon_state = "hair_nitori" + /datum/sprite_accessory/hair/odango name = "Odango" icon_state = "hair_odango" @@ -301,6 +465,10 @@ name = "Over Eye" icon_state = "hair_shortovereye" +/datum/sprite_accessory/hair/oxton + name = "Oxton" + icon_state = "hair_oxton" + //Donator item - fractious /datum/sprite_accessory/hair/over_eye_fr name = "Over Eye (fract)" @@ -331,6 +499,10 @@ name = "Pixie Cut" icon_state = "hair_pixie" +/datum/sprite_accessory/hair/plait + name = "Plait" + icon_state = "hair_plait" + /datum/sprite_accessory/hair/pompadour name = "Pompadour" icon_state = "hair_pompadour" @@ -383,10 +555,66 @@ name = "Ponytail (Side) 4" icon_state = "hair_sidetail4" +/datum/sprite_accessory/hair/spikytail + name = "Ponytail (Spiky)" + icon_state = "hair_spikyponytail" + +/datum/sprite_accessory/hair/poofy + name = "Poofy" + icon_state = "hair_poofy" + +/datum/sprite_accessory/hair/poofy2 + name = "Poofy 2" + icon_state = "hair_poofy2" + /datum/sprite_accessory/hair/quiff name = "Quiff" icon_state = "hair_quiff" +/datum/sprite_accessory/hair/ronin + name = "Ronin" + icon_state = "hair_ronin" + +/datum/sprite_accessory/hair/row + name = "Rows" + icon_state = "hair_rows1" + +/datum/sprite_accessory/hair/row2 + name = "Rows 2" + icon_state = "hair_rows2" + +/datum/sprite_accessory/hair/rowbun + name = "Rows (Bun)" + icon_state = "hair_rowbun" + +/datum/sprite_accessory/hair/rowdualtail + name = "Rows (Pigtails)" + icon_state = "hair_rowdualtail" + +/datum/sprite_accessory/hair/rowbraid + name = "Rows (Braid)" + icon_state = "hair_rowbraid" + +/datum/sprite_accessory/hair/scully + name = "Scully" + icon_state = "hair_scully" + +/datum/sprite_accessory/hair/shaggy + name = "Shaggy" + icon_state = "hair_shaggy" + +/datum/sprite_accessory/hair/shaved + name = "Shaved" + icon_state = "hair_shaved" + +/datum/sprite_accessory/hair/shavedpart + name = "Shaved (Part)" + icon_state = "hair_shavedpart" + +/datum/sprite_accessory/hair/bangs_short + name = "Short Bangs" + icon_state = "hair_shortbangs" + /datum/sprite_accessory/hair/short name = "Short Hair" icon_state = "hair_a" @@ -399,10 +627,30 @@ name = "Short Hair 3" icon_state = "hair_shorthair3" +/datum/sprite_accessory/hair/shorthair4 + name = "Short Hair 4" + icon_state = "hair_shorthair4" + +/datum/sprite_accessory/hair/shorthair80s + name = "Short Hair 80s" + icon_state = "hair_80s" + +/datum/sprite_accessory/hair/shorthairrosa + name = "Short Hair Rosa" + icon_state = "hair_rosa" + +/datum/sprite_accessory/hair/stail + name = "Short Tail" + icon_state = "hair_stail" + /datum/sprite_accessory/hair/shoulderlength name = "Shoulder-length Hair" icon_state = "hair_b" +/datum/sprite_accessory/hair/shy + name = "Shy" + icon_state = "hair_shy" + /datum/sprite_accessory/hair/sidecut name = "Sidecut" icon_state = "hair_sidecut" @@ -411,6 +659,10 @@ name = "Skinhead" icon_state = "hair_skinhead" +/datum/sprite_accessory/hair/sleaze + name = "Sleaze" + icon_state = "hair_sleaze" + /datum/sprite_accessory/hair/protagonist name = "Slightly Long Hair" icon_state = "hair_protagonist" @@ -435,14 +687,58 @@ name = "Swept Back Hair 2" icon_state = "hair_swept2" +/datum/sprite_accessory/hair/thinning + name = "Thinning" + icon_state = "hair_thinning" + +/datum/sprite_accessory/hair/thinningfront + name = "Thinning (Front)" + icon_state = "hair_thinningfront" + +/datum/sprite_accessory/hair/thinningrear + name = "Thinning (Rear)" + icon_state = "hair_thinningrear" + +/datum/sprite_accessory/hair/topknot + name = "Topknot" + icon_state = "hair_topknot" + +/datum/sprite_accessory/hair/toriyama + name = "Toriyama" + icon_state = "hair_toriyama" + +/datum/sprite_accessory/hair/toriyama2 + name = "Toriyama 2" + icon_state = "hair_toriyama2" + /datum/sprite_accessory/hair/tressshoulder name = "Tress Shoulder" icon_state = "hair_tressshoulder" +/datum/sprite_accessory/hair/trimmed + name = "Trimmed" + icon_state = "hair_trimmed" + +/datum/sprite_accessory/hair/trimflat + name = "Trimmed (Flat)" + icon_state = "hair_trimflat" + +/datum/sprite_accessory/hair/twintails + name = "Twintails" + icon_state = "hair_twintail" + /datum/sprite_accessory/hair/longtwintails name = "Twintails (Long)" icon_state = "hair_longstraighttwintails" +/datum/sprite_accessory/hair/undercut + name = "Undercut" + icon_state = "hair_undercut" + +/datum/sprite_accessory/hair/unkempt + name = "Unkempt" + icon_state = "hair_unkempt" + /datum/sprite_accessory/hair/updo name = "Updo" icon_state = "hair_updo" @@ -463,161 +759,22 @@ name = "Very Long with Fringe" icon_state = "hair_vlongfringe" -/*************** VIRGO PORTED HAIRS ****************************/ -#define VHAIR(_name, new_state) /datum/sprite_accessory/hair/##new_state/icon_state=#new_state;/datum/sprite_accessory/hair/##new_state/name = #_name + " (Virgo)" -//VIRGO PORTED HAIRS -VHAIR("Short Hair Rosa", hair_rosa_s) -VHAIR("Short Hair 80s", hair_80s_s) -VHAIR("Long Bedhead", hair_long_bedhead_s) -VHAIR("Dave", hair_dave_s) -VHAIR("Country", hair_country_s) -VHAIR("Shy", hair_shy_s) -VHAIR("Unshaven Mohawk", hair_unshaven_mohawk_s) -VHAIR("Manbun", hair_manbun_s) -VHAIR("Longer Bedhead", hair_longer_bedhead_s) -VHAIR("Ponytail", hair_ponytail_s) -VHAIR("Ziegler", hair_ziegler_s) -VHAIR("Emo Fringe", hair_emofringe_s) -VHAIR("Very Short Over Eye Alt", hair_veryshortovereyealternate_s) -VHAIR("Shorthime", hair_shorthime_s) -VHAIR("High Tight", hair_hightight_s) -VHAIR("Thinning Front", hair_thinningfront_s) -VHAIR("Big Afro", hair_bigafro_s) -VHAIR("Afro", hair_afro_s) -VHAIR("High Braid", hair_hbraid_s) -VHAIR("Braid", hair_braid_s) -VHAIR("Sargeant", hair_sargeant_s) -VHAIR("Gelled", hair_gelled_s) -VHAIR("Kagami", hair_kagami_s) -VHAIR("ShortTail", hair_stail_s) -VHAIR("Gentle", hair_gentle_s) -VHAIR("Grande", hair_grande_s) -VHAIR("Bobcurl", hair_bobcurl_s) -VHAIR("Pompadeur", hair_pompadour_s) -VHAIR("Plait", hair_plait_s) -VHAIR("Long", hair_long_s) -VHAIR("Rattail", hair_rattail_s) -VHAIR("Tajspiky", hair_tajspiky_s) -VHAIR("Messy", hair_messy_s) -VHAIR("Bangs", hair_bangs_s) -VHAIR("TBraid", hair_tbraid_s) -VHAIR("Toriyama2", hair_toriyama2_s) -VHAIR("CIA", hair_cia_s) -VHAIR("Mulder", hair_mulder_s) -VHAIR("Scully", hair_scully_s) -VHAIR("Nitori", hair_nitori_s) -VHAIR("Joestar", hair_joestar_s) -VHAIR("Ponytail4", hair_ponytail4_s) -VHAIR("Ponytail5", hair_ponytail5_s) -VHAIR("Beehive2", hair_beehive2_s) -VHAIR("Short Braid", hair_shortbraid_s) -VHAIR("Reverse Mohawk", hair_reversemohawk_s) -VHAIR("SHort Bangs", hair_shortbangs_s) -VHAIR("Half Shaved", hair_halfshaved_s) -VHAIR("Longer Alt 2", hair_longeralt2_s) -VHAIR("Bun", hair_bun_s) -VHAIR("Curly", hair_curly_s) -VHAIR("Victory", hair_victory_s) -VHAIR("Ponytail6", hair_ponytail6_s) -VHAIR("Undercut3", hair_undercut3_s) -VHAIR("Bobcut Alt", hair_bobcultalt_s) -VHAIR("Fingerwave", hair_fingerwave_s) -VHAIR("Oxton", hair_oxton_s) -VHAIR("Poofy2", hair_poofy2_s) -VHAIR("Fringe Tail", hair_fringetail_s) -VHAIR("Bun3", hair_bun3_s) -VHAIR("Wisp", hair_wisp_s) -VHAIR("Undercut2", hair_undercut2_s) -VHAIR("TBob", hair_tbob_s) -VHAIR("Spiky Ponytail", hair_spikyponytail_s) -VHAIR("Rowbun", hair_rowbun_s) -VHAIR("Rowdualtail", hair_rowdualtail_s) -VHAIR("Rowbraid", hair_rowbraid_s) -VHAIR("Shaved Mohawk", hair_shavedmohawk_s) -VHAIR("Topknot", hair_topknot_s) -VHAIR("Ronin", hair_ronin_s) -VHAIR("Bowlcut2", hair_bowlcut2_s) -VHAIR("Thinning Rear", hair_thinningrear_s) -VHAIR("Thinning", hair_thinning_s) -VHAIR("Jade", hair_jade_s) -VHAIR("Bedhead", hair_bedhead_s) -VHAIR("Dreadlocks", hair_dreads_s) -VHAIR("Very Long", hair_vlong_s) -VHAIR("Jensen", hair_jensen_s) -VHAIR("Halfbang", hair_halfbang_s) -VHAIR("Kusangi", hair_kusangi_s) -VHAIR("Ponytail", hair_ponytail_s) -VHAIR("Ponytail3", hair_ponytail3_s) -VHAIR("Halfbang Alt", hair_halfbang_alt_s) -VHAIR("Bedhead V2", hair_bedheadv2_s) -VHAIR("Long Fringe", hair_longfringe_s) -VHAIR("Flair", hair_flair_s) -VHAIR("Bedhead V3", hair_bedheadv3_s) -VHAIR("Himecut", hair_himecut_s) -VHAIR("Curls", hair_curls_s) -VHAIR("Very Long Fringe", hair_vlongfringe_s) -VHAIR("Longest", hair_longest_s) -VHAIR("Father", hair_father_s) -VHAIR("Emo Long", hair_emolong_s) -VHAIR("Short Hair 3", hair_shorthair3_s) -VHAIR("Double Bun", hair_doublebun_s) -VHAIR("Sleeze", hair_sleeze_s) -VHAIR("Twintail", hair_twintail_s) -VHAIR("Emo 2", hair_emo2_s) -VHAIR("Low Fade", hair_lowfade_s) -VHAIR("Med Fade", hair_medfade_s) -VHAIR("High Fade", hair_highfade_s) -VHAIR("Bald Fade", hair_baldfade_s) -VHAIR("No Fade", hair_nofade_s) -VHAIR("Trim Flat", hair_trimflat_s) -VHAIR("Shaved", hair_shaved_s) -VHAIR("Trimmed", hair_trimmed_s) -VHAIR("Tight Bun", hair_tightbun_s) -VHAIR("Short Hair 4", hair_d_s) -VHAIR("Short Hair 5", hair_e_s) -VHAIR("Short Hair 6", hair_f_s) -VHAIR("Skinhead", hair_skinhead_s) -VHAIR("Afro2", hair_afro2_s) -VHAIR("Bobcut", hair_bobcut_s) -VHAIR("Emo", hair_emo_s) -VHAIR("Long Over Eye", hair_longovereye_s) -VHAIR("Feather", hair_feather_s) -VHAIR("Hitop", hair_hitop_s) -VHAIR("Short Over Eye", hair_shortoverye_s) -VHAIR("Straight", hair_straight_s) -VHAIR("Buzzcut", hair_buzzcut_s) -VHAIR("Combover", hair_combover_s) -VHAIR("Crewcut", hair_crewcut_s) -VHAIR("Devillock", hair_devilock_s) -VHAIR("Clean", hair_clean_s) -VHAIR("Shaggy", hair_shaggy_s) -VHAIR("Updo", hair_updo_s) -VHAIR("Mohawk", hair_mohawk_s) -VHAIR("Odango", hair_odango_s) -VHAIR("Ombre", hair_ombre_s) -VHAIR("Parted", hair_parted_s) -VHAIR("Quiff", hair_quiff_s) -VHAIR("Volaju", hair_volaju_s) -VHAIR("Bun2", hair_bun2_s) -VHAIR("Rows1", hair_rows1_s) -VHAIR("Rows2", hair_rows2_s) -VHAIR("Dandy Pompadour", hair_dandypompadour_s) -VHAIR("Poofy", hair_poofy_s) -VHAIR("Toriyama", hair_toriyama_s) -VHAIR("Drillruru", hair_drillruru_s) -VHAIR("Bowlcut", hair_bowlcut_s) -VHAIR("Coffee House", hair_coffeehouse_s) -VHAIR("Family Man", hair_thefamilyman_s) -VHAIR("Shaved Part", hair_shavedpart_s) -VHAIR("Modern", hair_modern_s) -VHAIR("One Shoulder", hair_oneshoulder_s) -VHAIR("Very Short Over Eye", hair_veryshortovereye_s) -VHAIR("Unkept", hair_unkept_s) -VHAIR("Wife", hair_wife_s) -VHAIR("Nia", hair_nia_s) -VHAIR("Undercut", hair_undercut_s) -VHAIR("Bobcut Alt", hair_bobcutalt_s) -VHAIR("Short Hair 4 alt", hair_shorthair4_s) -VHAIR("Tressshoulder", hair_tressshoulder_s) - //END -#undef VHAIR \ No newline at end of file +/datum/sprite_accessory/hair/short_oe + name = "Very Short Over Eye" + icon_state = "hair_veryshortovereye" + +/datum/sprite_accessory/hair/short_oe_alt + name = "Very Short Over Eye (Alt)" + icon_state = "hair_veryshortovereyealternate" + +/datum/sprite_accessory/hair/volaju + name = "Volaju" + icon_state = "hair_volaju" + +/datum/sprite_accessory/hair/wisp + name = "Wisp" + icon_state = "hair_wisp" + +/datum/sprite_accessory/hair/ziegler + name = "Ziegler" + icon_state = "hair_ziegler" \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm index 33b174afa4..dac91b5445 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm @@ -370,6 +370,22 @@ color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' +/datum/sprite_accessory/tails/human/smooth + name = "Smooth" + icon_state = "smooth" + +/datum/sprite_accessory/tails_animated/human/smooth + name = "Smooth" + icon_state = "smooth" + +/datum/sprite_accessory/tails/human/spikes + name = "Spikes" + icon_state = "spikes" + +/datum/sprite_accessory/tails_animated/human/spikes + name = "Spikes" + icon_state = "spikes" + /datum/sprite_accessory/tails/human/shark name = "Shark" icon_state = "shark" @@ -438,6 +454,22 @@ color_src = MATRIXED icon = 'modular_citadel/icons/mob/mam_tails.dmi' +/datum/sprite_accessory/tails/human/dtiger + name = "Dark Tiger" + icon_state = "dtiger" + +/datum/sprite_accessory/tails_animated/human/dtiger + name = "Dark Tiger" + icon_state = "dtiger" + +/datum/sprite_accessory/tails/human/ltiger + name = "Light Tiger" + icon_state = "ltiger" + +/datum/sprite_accessory/tails_animated/human/ltiger + name = "Light Tiger" + icon_state = "ltiger" + /datum/sprite_accessory/tails/human/wolf name = "Wolf" icon_state = "wolf" @@ -693,6 +725,30 @@ datum/sprite_accessory/mam_tails/insect name = "Skunk" icon_state = "skunk" +/datum/sprite_accessory/mam_tails/smooth + name = "Smooth" + icon_state = "smooth" + color_src = MUTCOLORS + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/mam_tails_animated/smooth + name = "Smooth" + icon_state = "smooth" + color_src = MUTCOLORS + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/mam_tails_animated/spikes + name = "Spikes" + icon_state = "spikes" + color_src = MUTCOLORS + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/mam_tails/spikes + name = "Spikes" + icon_state = "spikes" + color_src = MUTCOLORS + icon = 'icons/mob/mutant_bodyparts.dmi' + /datum/sprite_accessory/mam_tails/shark name = "Shark" icon_state = "shark" @@ -741,6 +797,30 @@ datum/sprite_accessory/mam_tails/insect name = "Tiger" icon_state = "tiger" +/datum/sprite_accessory/mam_tails/dtiger + name = "Dark Tiger" + icon_state = "dtiger" + color_src = MUTCOLORS + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/mam_tails_animated/dtiger + name = "Dark Tiger" + icon_state = "dtiger" + color_src = MUTCOLORS + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/mam_tails/ltiger + name = "Light Tiger" + icon_state = "ltiger" + color_src = MUTCOLORS + icon = 'icons/mob/mutant_bodyparts.dmi' + +/datum/sprite_accessory/mam_tails_animated/ltiger + name = "Light Tiger" + icon_state = "ltiger" + color_src = MUTCOLORS + icon = 'icons/mob/mutant_bodyparts.dmi' + /datum/sprite_accessory/mam_tails/wolf name = "Wolf" icon_state = "wolf" diff --git a/code/modules/mob/dead/observer/notificationprefs.dm b/code/modules/mob/dead/observer/notificationprefs.dm index 9eef167469..6c1d76eaf3 100644 --- a/code/modules/mob/dead/observer/notificationprefs.dm +++ b/code/modules/mob/dead/observer/notificationprefs.dm @@ -24,7 +24,7 @@ /datum/notificationpanel/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "notificationpanel", "Notification Preferences", 700, 700, master_ui, state) + ui = new(user, src, ui_key, "notificationpanel", "Notification Preferences", 270, 360, master_ui, state) ui.open() /datum/notificationpanel/ui_data(mob/user) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index d234aafca6..439fe491cc 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -12,7 +12,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) stat = DEAD density = FALSE canmove = 0 - anchored = TRUE // don't get pushed around see_invisible = SEE_INVISIBLE_OBSERVER see_in_dark = 100 invisibility = INVISIBILITY_OBSERVER @@ -233,14 +232,16 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) var/b_val var/g_val var/color_format = length(input_color) + if(color_format != length_char(input_color)) + return 0 if(color_format == 3) - r_val = hex2num(copytext(input_color, 1, 2))*16 - g_val = hex2num(copytext(input_color, 2, 3))*16 - b_val = hex2num(copytext(input_color, 3, 0))*16 + r_val = hex2num(copytext(input_color, 1, 2)) * 16 + g_val = hex2num(copytext(input_color, 2, 3)) * 16 + b_val = hex2num(copytext(input_color, 3, 0)) * 16 else if(color_format == 6) r_val = hex2num(copytext(input_color, 1, 3)) g_val = hex2num(copytext(input_color, 3, 5)) - b_val = hex2num(copytext(input_color, 5, 0)) + b_val = hex2num(copytext(input_color, 5, 7)) else return 0 //If the color format is not 3 or 6, you're using an unexpected way to represent a color. @@ -254,16 +255,17 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) if(b_val > 255) b_val = 255 - return num2hex(r_val, 2) + num2hex(g_val, 2) + num2hex(b_val, 2) + return copytext(rgb(r_val, g_val, b_val), 2) /* Transfer_mind is there to check if mob is being deleted/not going to have a body. Works together with spawning an observer, noted above. */ -/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE) +/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE) penalize = suiciding || penalize // suicide squad. - if(!key || cmptext(copytext(key,1,2),"@") || (SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize) & COMPONENT_BLOCK_GHOSTING)) + voluntary_ghosted = voluntary + if(!key || key[1] == "@" || (SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize) & COMPONENT_BLOCK_GHOSTING)) return //mob has no key, is an aghost or some component hijacked. stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc. @@ -286,9 +288,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set name = "Ghost" set desc = "Relinquish your life and enter the land of the dead." - if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING) - return - var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES if(world.time < roundstart_quit_limit) @@ -296,6 +295,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(penalty + world.realtime - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime) penalty = CANT_REENTER_ROUND + if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE, (stat == DEAD)? penalty : 0, (stat == DEAD)? TRUE : FALSE) & COMPONENT_BLOCK_GHOSTING) + return + if(stat != DEAD) succumb() if(stat == DEAD) @@ -308,7 +310,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/obj/machinery/cryopod/C = loc C.despawn_occupant() else - ghostize(0, penalize = TRUE) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3 + ghostize(0, penalize = TRUE, voluntary = TRUE) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3 suicide_log(TRUE) /mob/camera/verb/ghost() @@ -365,7 +367,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!can_reenter_corpse) to_chat(src, "You cannot re-enter your body.") return - if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients + if(mind.current.key && mind.current.key[1] != "@") //makes sure we don't accidentally kick any clients to_chat(usr, "Another consciousness is in your body...It is resisting you.") return client.change_view(CONFIG_GET(string/default_view)) @@ -664,10 +666,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp to_chat(src, "This creature is too powerful for you to possess!") return 0 - if(istype (target, /mob/living/simple_animal/hostile/spawner)) - to_chat(src, "This isn't really a creature, now is it!") - return 0 - if(can_reenter_corpse && mind && mind.current) if(alert(src, "Your soul is still tied to your former life as [mind.current.name], if you go forward there is no going back to that life. Are you sure you wish to continue?", "Move On", "Yes", "No") == "No") return 0 diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm index 9bbacdd930..2c4743f7d3 100644 --- a/code/modules/mob/dead/observer/say.dm +++ b/code/modules/mob/dead/observer/say.dm @@ -1,13 +1,12 @@ /mob/dead/observer/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) if (!message) return var/message_mode = get_message_mode(message) if(client && (message_mode == MODE_ADMIN || message_mode == MODE_DEADMIN)) - message = copytext(message, 3) - if(findtext(message, " ", 1, 2)) - message = copytext(message, 2) + message = copytext_char(message, 3) + message = trim_left(message) if(message_mode == MODE_ADMIN) client.cmd_admin_say(message) diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index 41d3d4e158..3c7476ff3b 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -4,7 +4,7 @@ var/param = message var/custom_param = findchar(act, " ") if(custom_param) - param = copytext(act, custom_param + 1, length(act) + 1) + param = copytext(act, custom_param + length(act[custom_param])) act = copytext(act, 1, custom_param) var/datum/emote/E diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index ade8158e02..c569a2c59a 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -33,7 +33,7 @@ bleed_rate = 0 return - if(bleed_rate <= 0) + if(bleed_rate < 0) bleed_rate = 0 if(HAS_TRAIT(src, TRAIT_NOMARROW)) //Bloodsuckers don't need to be here. @@ -94,12 +94,12 @@ //We want an accurate reading of .len listclearnulls(BP.embedded_objects) - temp_bleed += 0.5*BP.embedded_objects.len + temp_bleed += 0.5 * BP.embedded_objects.len if(brutedamage >= 20) temp_bleed += (brutedamage * 0.013) - bleed_rate = max(bleed_rate - 0.50, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases + bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH))) bleed(bleed_rate) @@ -185,7 +185,7 @@ var/datum/disease/D = thing blood_data["viruses"] += D.Copy() - blood_data["blood_DNA"] = copytext(dna.unique_enzymes,1,0) + blood_data["blood_DNA"] = dna.unique_enzymes blood_data["bloodcolor"] = bloodtype_to_color(dna.blood_type) if(disease_resistances && disease_resistances.len) blood_data["resistances"] = disease_resistances.Copy() @@ -204,7 +204,7 @@ if(!suiciding) blood_data["cloneable"] = 1 - blood_data["blood_type"] = copytext(dna.blood_type,1,0) + blood_data["blood_type"] = dna.blood_type blood_data["gender"] = gender blood_data["real_name"] = real_name blood_data["features"] = dna.features @@ -289,8 +289,7 @@ drop.update_icon() return else - temp_blood_DNA = list() - temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter + temp_blood_DNA = drop.blood_DNA.Copy() //transfer dna from drip to splatter. qdel(drop)//the drip is replaced by a bigger splatter else drop = new(T, get_static_viruses()) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index f2ea4f2b01..15cab5fc64 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -389,6 +389,7 @@ if(resilience) actual_trauma.resilience = resilience SSblackbox.record_feedback("tally", "traumas", 1, actual_trauma.type) + return actual_trauma //Add a random trauma of a certain subtype /obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index f7fdd2d32b..bd24a4b4c4 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -120,7 +120,8 @@ Des: Removes all infected images from the alien. /mob/living/carbon/alien/proc/RemoveInfectionImages() if (client) for(var/image/I in client.images) - if(dd_hasprefix_case(I.icon_state, "infected")) + var/searchfor = "infected" + if(findtext(I.icon_state, searchfor, 1, length(searchfor) + 1)) qdel(I) return diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index d830957056..8de60cba2f 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -5,7 +5,7 @@ /mob/living/carbon/alien/get_ear_protection() return 2 //no ears -/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush) +/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) return ..(AM, skipcatch = TRUE, hitpush = FALSE) /mob/living/carbon/alien/can_embed(obj/item/I) diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index 3babab4586..b20383301d 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -54,15 +54,15 @@ weather_immunities -= "lava" update_icons() -/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A) +/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!leaping) return ..() pounce_cooldown = world.time + pounce_cooldown_time - if(A) - if(isliving(A)) - var/mob/living/L = A + if(hit_atom) + if(isliving(hit_atom)) + var/mob/living/L = hit_atom if(!L.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK)) L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") L.Knockdown(100) @@ -72,8 +72,8 @@ Knockdown(40, 1, 1) toggle_leap(0) - else if(A.density && !A.CanPass(src)) - visible_message("[src] smashes into [A]!", "[src] smashes into [A]!") + else if(hit_atom.density && !hit_atom.CanPass(src)) + visible_message("[src] smashes into [hit_atom]!", "[src] smashes into [hit_atom]!") Knockdown(40, 1, 1) if(leaping) diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 1333bc4399..6141a97c12 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -13,7 +13,7 @@ var/alt_inhands_file = 'icons/mob/alienqueen.dmi' -/mob/living/carbon/alien/humanoid/royal/can_inject() +/mob/living/carbon/alien/humanoid/royal/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE) return 0 /mob/living/carbon/alien/humanoid/royal/queen diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 8e1e5aab8d..fb26a40350 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -56,7 +56,7 @@ /mob/living/carbon/alien/larva/toggle_throw_mode() return -/mob/living/carbon/alien/larva/start_pulling() +/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE) return /mob/living/carbon/alien/larva/stripPanelUnequip(obj/item/what, mob/who) diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index dc3c45b79f..0621d1400e 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -135,5 +135,6 @@ Des: Removes all images from the mob infected by this embryo for(var/mob/living/carbon/alien/alien in GLOB.player_list) if(alien.client) for(var/image/I in alien.client.images) - if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == C) + var/searchfor = "infected" + if(I.loc == owner && findtext(I.icon_state, searchfor, 1, length(searchfor) + 1)) qdel(I) diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 0f6fc7e944..8e5e327f39 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -115,7 +115,7 @@ if(icon_state == "[initial(icon_state)]_thrown") icon_state = "[initial(icon_state)]" -/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom) +/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() if(stat == CONSCIOUS) icon_state = "[initial(icon_state)]" diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index e8f42b707c..6123c5b60f 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -94,15 +94,13 @@ return 1 return ..() -/mob/living/carbon/throw_impact(atom/hit_atom, throwingdatum) +/mob/living/carbon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() var/hurt = TRUE - if(istype(throwingdatum, /datum/thrownthing)) - var/datum/thrownthing/D = throwingdatum - if(iscyborg(D.thrower)) - var/mob/living/silicon/robot/R = D.thrower - if(!R.emagged) - hurt = FALSE + if(throwingdatum?.thrower && iscyborg(throwingdatum.thrower)) + var/mob/living/silicon/robot/R = throwingdatum.thrower + if(!R.emagged) + hurt = FALSE if(hit_atom.density && isturf(hit_atom)) if(hurt) Knockdown(20) @@ -160,7 +158,7 @@ var/random_turn = a_intent == INTENT_HARM //END OF CIT CHANGES - var/obj/item/I = src.get_active_held_item() + var/obj/item/I = get_active_held_item() var/atom/movable/thrown_thing var/mob/living/throwable_mob @@ -201,11 +199,11 @@ if(thrown_thing) visible_message("[src] has thrown [thrown_thing].") - src.log_message("has thrown [thrown_thing]", LOG_ATTACK) + log_message("has thrown [thrown_thing]", LOG_ATTACK) do_attack_animation(target, no_effect = 1) playsound(loc, 'sound/weapons/punchmiss.ogg', 50, 1, -1) newtonian_move(get_dir(target, src)) - thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, random_turn) + thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, move_force, random_turn) @@ -463,7 +461,7 @@ I.throw_at(target,I.throw_range,I.throw_speed,src) if(61 to 90) //throw it down to the floor var/turf/target = get_turf(loc) - I.throw_at(target,I.throw_range,I.throw_speed,src) + I.safe_throw_at(target,I.throw_range,I.throw_speed,src, force = move_force) /mob/living/carbon/Stat() ..() diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 11c4d7dbef..689ab56842 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -49,7 +49,6 @@ //Gets filled up in create_bodyparts() var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems) - var/list/leg_bodyparts = list() var/icon_render_key = "" var/static/list/limb_icon_cache = list() diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm index 155b0fc7de..4a99e9c89e 100644 --- a/code/modules/mob/living/carbon/carbon_movement.dm +++ b/code/modules/mob/living/carbon/carbon_movement.dm @@ -13,8 +13,8 @@ . += SOFTCRIT_ADD_SLOWDOWN /mob/living/carbon/slip(knockdown_amount, obj/O, lube) - if(movement_type & FLYING) - return 0 + if(movement_type & FLYING && !(lube & FLYING_DOESNT_HELP)) + return FALSE if(!(lube&SLIDE_ICE)) log_combat(src, (O ? O : get_turf(src)), "slipped on the", null, ((lube & SLIDE) ? "(LUBE)" : null)) return loc.handle_slip(src, knockdown_amount, O, lube) diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index 5bffc4e276..5020cc7379 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -87,7 +87,7 @@ if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage amount = -amount if(amount > 0) - blood_volume -= 3*amount // x5 is too much, x3 should be still penalizing enough. + blood_volume -= 3 * amount //5x was too much, this is punishing enough. else blood_volume -= amount return ..() diff --git a/code/modules/mob/living/carbon/death.dm b/code/modules/mob/living/carbon/death.dm index 6182befebd..109672ab82 100644 --- a/code/modules/mob/living/carbon/death.dm +++ b/code/modules/mob/living/carbon/death.dm @@ -66,7 +66,7 @@ BP.drop_limb() BP.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5) -/mob/living/carbon/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE) +/mob/living/carbon/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE) if(combatmode) toggle_combat_mode(TRUE, TRUE) return ..() diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index a6595100a1..d6f6b6d9ae 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -44,7 +44,8 @@ if(M.occupant == src) M.go_out() - dna.species.spec_death(gibbed, src) + if(!QDELETED(dna)) //The gibbed param is bit redundant here since dna won't exist at this point if they got deleted. + dna.species.spec_death(gibbed, src) if(SSticker.HasRoundStarted()) SSblackbox.ReportDeath(src) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index e212e0e713..ef8a745b89 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -41,7 +41,7 @@ var/accessory_msg if(istype(w_uniform, /obj/item/clothing/under)) var/obj/item/clothing/under/U = w_uniform - if(U.attached_accessory) + if(U.attached_accessory && !(U.attached_accessory.flags_inv & HIDEACCESSORY) && !(U.flags_inv & HIDEACCESSORY)) accessory_msg += " with [icon2html(U.attached_accessory, user)] \a [U.attached_accessory]" . += "[t_He] [t_is] wearing [w_uniform.get_examine_string(user)][accessory_msg]." @@ -385,20 +385,17 @@ else if(isobserver(user) && traitstring) . += "Traits: [traitstring]" - if(print_flavor_text()) - if(get_visible_name() == "Unknown") //Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation. - . += "...?" - else if(skipface) //Sometimes we're not unknown, but impersonating someone in a hardsuit, let's not reveal our flavor text then either. - . += "...?" - else - . += "[print_flavor_text()]" - if(print_flavor_text_2()) - if(get_visible_name() == "Unknown") //Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation. - . += "...?" - else if(skipface) //Sometimes we're not unknown, but impersonating someone in a hardsuit, let's not reveal our flavor text then either. - . += "...?" - else - . += "[print_flavor_text_2()]" + //No flavor text unless the face can be seen. Prevents certain metagaming with impersonation. + var/invisible_man = skipface || get_visible_name() == "Unknown" + if(invisible_man) + . += "...?" + else + var/flavor = print_flavor_text() + if(flavor) + . += flavor + var/temp_flavor = print_flavor_text_2() + if(temp_flavor) + . += temp_flavor . += "*---------*" /mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects! diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0f3b3dc6d3..2b03e22b77 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -25,8 +25,7 @@ create_internal_organs() //most of it is done in set_species now, this is only for parent call physiology = new() - handcrafting = new() - + AddComponent(/datum/component/personal_crafting) . = ..() if(CONFIG_GET(flag/disable_stambuffer)) @@ -45,10 +44,6 @@ QDEL_NULL_LIST(vore_organs) // CITADEL EDIT belly stuff return ..() - -/mob/living/carbon/human/OpenCraftingMenu() - handcrafting.ui_interact(src) - /mob/living/carbon/human/prepare_data_huds() //Update med hud images... ..() @@ -85,7 +80,7 @@ var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit if(statpanel("SpiderOS")) stat("SpiderOS Status:","[SN.s_initialized ? "Initialized" : "Disabled"]") - stat("Current Time:", "[STATION_TIME_TIMESTAMP("hh:mm:ss")]") + stat("Current Time:", "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]") if(SN.s_initialized) //Suit gear stat("Energy Charge:", "[round(SN.cell.charge/100)]%") @@ -439,7 +434,7 @@ return else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security)) return - var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss")) + var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)) GLOB.data_core.addMinorCrime(R.fields["id"], crime) investigate_log("New Minor Crime: [t1]: [t2] | Added to [R.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) to_chat(usr, "Successfully added a minor crime.") @@ -455,7 +450,7 @@ return else if (!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security)) return - var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss")) + var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)) GLOB.data_core.addMajorCrime(R.fields["id"], crime) investigate_log("New Major Crime: [t1]: [t2] | Added to [R.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) to_chat(usr, "Successfully added a major crime.") @@ -488,7 +483,7 @@ var/counter = 1 while(R.fields[text("com_[]", counter)]) counter++ - R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []
    []", allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1) + R.fields["com_[counter]"] = "Made by [allowed_access] on [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)] [time2text(world.realtime, "MMM DD")], [GLOB.year_integer]
    [t1]" to_chat(usr, "Successfully added comment.") return to_chat(usr, "Unable to locate a data core entry for this person.") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 2fc4cd8805..accaab3ac1 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -102,7 +102,7 @@ return TRUE return FALSE -/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE) +/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) return dna?.species?.spec_hitby(AM, src) || ..() /mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0) @@ -336,7 +336,8 @@ if(bomb_armor < EXPLODE_GIB_THRESHOLD) //gibs the mob if their bomb armor is lower than EXPLODE_GIB_THRESHOLD for(var/I in contents) var/atom/A = I - A.ex_act(severity) + if(!QDELETED(A)) + A.ex_act(severity) gib() return else diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 595d60004c..36d9ca541b 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -59,7 +59,6 @@ var/custom_species = null - var/datum/personal_crafting/handcrafting var/datum/physiology/physiology var/list/datum/bioware = list() diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 460dd6ea51..f37673a5a3 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -59,7 +59,7 @@ var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T if(oldFP && (oldFP.blood_state == S.blood_state && oldFP.color == bloodtype_to_color(S.last_bloodtype))) return - S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state]-BLOOD_LOSS_PER_STEP) + S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP) var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T) FP.blood_state = S.blood_state FP.entered_dirs |= dir diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 8e12ac97d3..29597344cf 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -87,30 +87,22 @@ /mob/living/carbon/human/proc/forcesay(list/append) //this proc is at the bottom of the file because quote fuckery makes notepad++ cri if(stat == CONSCIOUS) if(client) - var/virgin = 1 //has the text been modified yet? var/temp = winget(client, "input", "text") - if(findtextEx(temp, "Say \"", 1, 7) && length(temp) > 5) //"case sensitive means + var/say_starter = "Say \"" //" + if(findtextEx(temp, say_starter, 1, length(say_starter) + 1) && length(temp) > length(say_starter)) //case sensitive means - temp = replacetext(temp, ";", "") //general radio + temp = trim_left(copytext(temp, length(say_starter + 1))) + temp = replacetext(temp, ";", "", 1, 2) //general radio + while(trim_left(temp)[1] == ":") //dept radio again (necessary) + temp = copytext_char(trim_left(temp), 3) - if(findtext(trim_left(temp), ":", 6, 7)) //dept radio - temp = copytext(trim_left(temp), 8) - virgin = 0 - - if(virgin) - temp = copytext(trim_left(temp), 6) //normal speech - virgin = 0 - - while(findtext(trim_left(temp), ":", 1, 2)) //dept radio again (necessary) - temp = copytext(trim_left(temp), 3) - - if(findtext(temp, "*", 1, 2)) //emotes + if(temp[1] == "*") //emotes return var/trimmed = trim_left(temp) if(length(trimmed)) if(append) - temp += pick(append) + trimmed += pick(append) - say(temp) + say(trimmed) winset(client, "input", "text=[null]") diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index 2a5ec51b55..eb1e194c0f 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -849,6 +849,8 @@ linked_mobs.Add(M) if(!selflink) to_chat(M, "You are now connected to [slimelink_owner.real_name]'s Slime Link.") + RegisterSignal(M, COMSIG_MOB_DEATH , .proc/unlink_mob) + RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/unlink_mob) var/datum/action/innate/linked_speech/action = new(src) linked_actions.Add(action) action.Grant(M) @@ -858,6 +860,7 @@ var/link_id = linked_mobs.Find(M) if(!(link_id)) return + UnregisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING)) var/datum/action/innate/linked_speech/action = linked_actions[link_id] action.Remove(M) to_chat(M, "You are no longer connected to [slimelink_owner.real_name]'s Slime Link.") @@ -890,18 +893,11 @@ Remove(H) return - if(QDELETED(H) || H.stat == DEAD) - species.unlink_mob(H) - return - if(message) var/msg = "\[[species.slimelink_owner.real_name]'s Slime Link\] [H]: [message]" log_directed_talk(H, species.slimelink_owner, msg, LOG_SAY, "slime link") for(var/X in species.linked_mobs) var/mob/living/M = X - if(QDELETED(M) || M.stat == DEAD) - species.unlink_mob(M) - continue to_chat(M, msg) for(var/X in GLOB.dead_mob_list) diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 5a7710fe29..4a7399f287 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -54,7 +54,7 @@ ..() /datum/species/plasmaman/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE) - var/current_job = J.title + var/current_job = J?.title var/datum/outfit/plasmaman/O = new /datum/outfit/plasmaman switch(current_job) if("Chaplain") diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index c4088317b1..fa6cc44fca 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -382,9 +382,6 @@ There are several things that need to be remembered: if(wear_suit) var/obj/item/clothing/suit/S = wear_suit - var/item_level_support = FALSE // LISTEN! If you must degrade the code with further snowflake checks, at least keep it compatible with worn non-clothing items! - if(!istype(S)) - item_level_support = TRUE wear_suit.screen_loc = ui_oclothing if(client && hud_used && hud_used.hud_shown) if(hud_used.inventory_shown) @@ -400,7 +397,7 @@ There are several things that need to be remembered: if("taur" in dna.species.mutant_bodyparts) T = GLOB.taur_list[dna.features["taur"]] - if(!item_level_support && S.mutantrace_variation) + if(S.mutantrace_variation) if(T?.taur_mode) var/init_worn_icon = worn_icon variation_flag |= S.mutantrace_variation & T.taur_mode || S.mutantrace_variation & T.alt_taur_mode @@ -464,6 +461,8 @@ There are several things that need to be remembered: var/alt_icon = M.alternate_worn_icon || 'icons/mob/mask.dmi' var/muzzled = FALSE var/variation_flag = NONE + if(head && (head.flags_inv & HIDEMASK)) + return if(("mam_snouts" in dna.species.default_features) && dna.features["mam_snouts"] != "None") muzzled = TRUE if(!muzzled && ("snout" in dna.species.default_features) && dna.features["snout"] != "None") diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 6eb4868202..3277c57b75 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -405,7 +405,7 @@ retaliate(Proj.firer) return ..() -/mob/living/carbon/monkey/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE) +/mob/living/carbon/monkey/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(istype(AM, /obj/item)) var/obj/item/I = AM if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby)) diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 33b9dffaf0..e83f67f796 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -30,6 +30,9 @@ /mob/living/carbon/monkey/handle_mutations_and_radiation() if(radiation) + if(radiation > RAD_MOB_MUTATE && prob((radiation - RAD_MOB_MUTATE) / 25)) + gorillize() + return if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB)) if(!IsKnockdown()) emote("collapse") @@ -41,10 +44,6 @@ randmutb() emote("gasp") domutcheck() - - if(radiation > RAD_MOB_MUTATE * 2 && prob(50)) - gorillize() - return if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB)) vomit(10, TRUE) return ..() diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 5880392a1b..45f9662c9a 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -61,7 +61,7 @@ stat = DEAD unset_machine() timeofdeath = world.time - tod = STATION_TIME_TIMESTAMP("hh:mm:ss") + tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time) for(var/obj/item/I in contents) I.on_mob_death(src, gibbed) if(mind) diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index aba640c550..3221981e78 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -200,25 +200,25 @@ message_param = "blows a kiss to %t." emote_type = EMOTE_AUDIBLE -/datum/emote/living/laugh +/datum/emote/living/audio_emote + emote_type = EMOTE_AUDIBLE + +/datum/emote/living/audio_emote/can_run_emote(mob/living/user, status_check = TRUE) + . = ..() + if(. && iscarbon(user)) + var/mob/living/carbon/C = user + return !C.silent && (!C.mind || !C.mind.miming) + +/datum/emote/living/audio_emote/laugh key = "laugh" key_third_person = "laughs" message = "laughs." message_mime = "laughs silently!" - emote_type = EMOTE_AUDIBLE -/datum/emote/living/laugh/can_run_emote(mob/living/user, status_check = TRUE) - . = ..() - if(. && iscarbon(user)) - var/mob/living/carbon/C = user - return !C.silent - -/datum/emote/living/laugh/run_emote(mob/user, params) +/datum/emote/living/audio_emote/laugh/run_emote(mob/user, params) . = ..() if(. && iscarbon(user)) //Citadel Edit because this is hilarious var/mob/living/carbon/C = user - if(!C.mind || C.mind.miming) - return if(iscatperson(C)) //we ask for is cat first because they're a subtype that tests true for ishumanbasic because HERESY playsound(C, pick('sound/voice/catpeople/nyahaha1.ogg', 'sound/voice/catpeople/nyahaha2.ogg', @@ -226,12 +226,27 @@ 'sound/voice/catpeople/nyahehe.ogg'), 50, 1) return - if(ishumanbasic(C)) + else if(ismoth(C)) + playsound(C, 'sound/voice/moth/mothlaugh.ogg', 50, 1) + else if(ishumanbasic(C)) if(user.gender == FEMALE) playsound(C, 'sound/voice/human/womanlaugh.ogg', 50, 1) else playsound(C, pick('sound/voice/human/manlaugh1.ogg', 'sound/voice/human/manlaugh2.ogg'), 50, 1) +/datum/emote/living/audio_emote/chitter + key = "chitter" + key_third_person = "chitters" + message = "chitters." + message_mime = "chitters silently!" + +/datum/emote/living/audio_emote/chitter/run_emote(mob/user, params) + . = ..() + if(. && iscarbon(user)) //Citadel Edit because this is hilarious + var/mob/living/carbon/C = user + if(ismoth(C)) + playsound(C, 'sound/voice/moth/mothchitter.ogg', 50, 1) + /datum/emote/living/look key = "look" key_third_person = "looks" @@ -411,17 +426,10 @@ message = null /datum/emote/living/custom/proc/check_invalid(mob/user, input) - . = TRUE - if(copytext(input,1,5) == "says") + if(stop_bad_mime.Find(input, 1, 1)) to_chat(user, "Invalid emote.") - else if(copytext(input,1,9) == "exclaims") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,6) == "yells") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,5) == "asks") - to_chat(user, "Invalid emote.") - else - . = FALSE + return TRUE + return FALSE /datum/emote/living/custom/run_emote(mob/user, params, type_override = null) if(jobban_isbanned(user, "emote")) @@ -433,7 +441,7 @@ to_chat(user, "You cannot send IC messages (muted).") return FALSE else if(!params) - var/custom_emote = copytext(sanitize(input("Choose an emote to display.") as message|null), 1, MAX_MESSAGE_LEN) //CIT CHANGE - expands emote textbox + var/custom_emote = stripped_multiline_input("Choose an emote to display.", "Custom Emote", null, MAX_MESSAGE_LEN) if(custom_emote && !check_invalid(user, custom_emote)) var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable") switch(type) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index c2a307950c..90ada3d718 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -75,7 +75,7 @@ return if(ismovableatom(A)) var/atom/movable/AM = A - if(PushAM(AM)) + if(PushAM(AM, move_force)) return /mob/living/Bumped(atom/movable/AM) @@ -90,8 +90,10 @@ if(now_pushing) return TRUE + var/they_can_move = TRUE if(isliving(M)) var/mob/living/L = M + they_can_move = L.canmove //L.mobility_flags & MOBILITY_MOVE //Also spread diseases for(var/thing in diseases) var/datum/disease/D = thing @@ -144,13 +146,17 @@ return 1 if(!M.buckled && !M.has_buckled_mobs()) - var/mob_swap - //the puller can always swap with its victim if on grab intent - if(M.pulledby == src && a_intent == INTENT_GRAB) - mob_swap = 1 - //restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller - else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP)) - mob_swap = 1 + var/mob_swap = FALSE + var/too_strong = (M.move_resist > move_force) //can't swap with immovable objects unless they help us + if(!they_can_move) //we have to physically move them + if(!too_strong) + mob_swap = TRUE + else + if(M.pulledby == src && a_intent == INTENT_GRAB) + mob_swap = TRUE + //restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller + else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP)) + mob_swap = TRUE if(mob_swap) //switch our position with M if(loc && !loc.Adjacent(M.loc)) @@ -218,36 +224,46 @@ return //Called when we want to push an atom/movable -/mob/living/proc/PushAM(atom/movable/AM) +/mob/living/proc/PushAM(atom/movable/AM, force = move_force) if(now_pushing) - return 1 + return TRUE if(moving_diagonally)// no pushing during diagonal moves. - return 1 + return TRUE if(!client && (mob_size < MOB_SIZE_SMALL)) return - if(!AM.anchored) - now_pushing = 1 - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.fulltile) - for(var/obj/structure/window/win in get_step(W,t)) - now_pushing = 0 - return - if(pulling == AM) - stop_pulling() - var/current_dir - if(isliving(AM)) - current_dir = AM.dir - step(AM, t) - if(current_dir) - AM.setDir(current_dir) - now_pushing = 0 + now_pushing = TRUE + var/t = get_dir(src, AM) + var/push_anchored = FALSE + if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force) + if(move_crush(AM, move_force, t)) + push_anchored = TRUE + if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally + if(force_push(AM, move_force, t, push_anchored)) + push_anchored = TRUE + if((AM.anchored && !push_anchored) || (force < (AM.move_resist * MOVE_FORCE_PUSH_RATIO))) + now_pushing = FALSE + return + if (istype(AM, /obj/structure/window)) + var/obj/structure/window/W = AM + if(W.fulltile) + for(var/obj/structure/window/win in get_step(W,t)) + now_pushing = FALSE + return + if(pulling == AM) + stop_pulling() + var/current_dir + if(isliving(AM)) + current_dir = AM.dir + if(step(AM, t)) + step(src, t) + if(current_dir) + AM.setDir(current_dir) + now_pushing = FALSE -/mob/living/start_pulling(atom/movable/AM, supress_message = 0) +/mob/living/start_pulling(atom/movable/AM, state, force = pull_force, supress_message = FALSE) if(!AM || !src) return FALSE - if(!(AM.can_be_pulled(src))) + if(!(AM.can_be_pulled(src, state, force))) return FALSE if(throwing || incapacitated()) return FALSE @@ -443,7 +459,7 @@ return ret // Living mobs use can_inject() to make sure that the mob is not syringe-proof in general. -/mob/living/proc/can_inject() +/mob/living/proc/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE) return TRUE /mob/living/is_injectable(allowmobs = TRUE) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index fbb483fadb..6a14cce4af 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -107,7 +107,7 @@ /mob/living/proc/can_embed(obj/item/I) return FALSE -/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE) +/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) var/obj/item/I var/throwpower = 30 if(isitem(AM)) @@ -189,7 +189,7 @@ adjust_fire_stacks(3) IgniteMob() -/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0) +/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = FALSE) if(user == anchored || !isturf(user.loc)) return FALSE @@ -215,7 +215,7 @@ return FALSE if(!user.pulling || user.pulling != src) - user.start_pulling(src, supress_message) + user.start_pulling(src, supress_message = supress_message) return if(!(status_flags & CANPUSH) || HAS_TRAIT(src, TRAIT_PUSHIMMUNE)) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 472bcdfc3d..a12d468e24 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -89,7 +89,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/static/list/one_character_prefix = list(MODE_HEADSET = TRUE, MODE_ROBOT = TRUE, MODE_WHISPER = TRUE) if(sanitize) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) if(!message || message == "") return @@ -99,11 +99,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/in_critical = InCritical() if(one_character_prefix[message_mode]) - message = copytext(message, 2) + message = copytext_char(message, 2) else if(message_mode || saymode) - message = copytext(message, 3) - if(findtext(message, " ", 1, 2)) - message = copytext(message, 2) + message = copytext_char(message, 3) + message = trim_left(message) if(message_mode == MODE_ADMIN) if(client) @@ -135,11 +134,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list( // No, you cannot speak in xenocommon just because you know the key if(can_speak_in_language(message_language)) language = message_language - message = copytext(message, 3) + message = copytext_char(message, 3) // Trim the space if they said ",0 I LOVE LANGUAGES" - if(findtext(message, " ", 1, 2)) - message = copytext(message, 2) + message = trim_left(message) if(!language) language = get_default_language() @@ -167,8 +165,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list( if(fullcrit) var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health) // If we cut our message short, abruptly end it with a-.. - var/message_len = length(message) - message = copytext(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]" + var/message_len = length_char(message) + message = copytext_char(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]" message = Ellipsis(message, 10, 1) message_mode = MODE_WHISPER_CRIT succumbed = TRUE @@ -326,13 +324,13 @@ GLOBAL_LIST_INIT(department_radio_keys, list( return 1 /mob/living/proc/get_key(message) - var/key = copytext(message, 1, 2) + var/key = message[1] if(key in GLOB.department_radio_prefixes) - return lowertext(copytext(message, 2, 3)) + return lowertext(message[1 + length(key)]) /mob/living/proc/get_message_language(message) - if(copytext(message, 1, 2) == ",") - var/key = copytext(message, 2, 3) + if(message[1] == ",") + var/key = message[1 + length(message[1])] for(var/ld in GLOB.all_languages) var/datum/language/LD = ld if(initial(LD.key) == key) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 5ae649c87e..33cbdb7cc9 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -16,7 +16,7 @@ name = "AI" icon = 'icons/mob/ai.dmi' icon_state = "ai" - anchored = TRUE + move_resist = MOVE_FORCE_OVERPOWERING density = TRUE canmove = FALSE status_flags = CANSTUN|CANPUSH @@ -101,6 +101,7 @@ new/obj/structure/AIcore/deactivated(loc) //New empty terminal. return INITIALIZE_HINT_QDEL //Delete AI. + ADD_TRAIT(src, TRAIT_NO_TELEPORT, src) if(L && istype(L, /datum/ai_laws)) laws = L laws.associate(src) @@ -311,9 +312,16 @@ return // stop if(incapacitated()) return - anchored = !anchored // Toggles the anchor + var/is_anchored = FALSE + if(move_resist == MOVE_FORCE_OVERPOWERING) + move_resist = MOVE_FORCE_NORMAL + else + is_anchored = TRUE + move_resist = MOVE_FORCE_OVERPOWERING + REMOVE_TRAIT(src, TRAIT_NO_TELEPORT, src) + ADD_TRAIT(src, TRAIT_NO_TELEPORT, src) - to_chat(src, "You are now [anchored ? "" : "un"]anchored.") + to_chat(src, "You are now [is_anchored ? "" : "un"]anchored.") // the message in the [] will change depending whether or not the AI is anchored /mob/living/silicon/ai/update_canmove() //If the AI dies, mobs won't go through it anymore diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index 6ff744e0da..f978b7b697 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -14,7 +14,7 @@ cameraFollow = null - anchored = FALSE //unbolt floorbolts + move_resist = MOVE_FORCE_NORMAL update_canmove() if(eyeobj) eyeobj.setLoc(get_turf(src)) diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 15a04235cc..1147042c8c 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -53,11 +53,11 @@ if(NONE) return FALSE if(POWER_REQ_ALL) - return !T || !A || ((!A.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) + return !T || !A || ((!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) if(POWER_REQ_CLOCKCULT) for(var/obj/effect/clockwork/sigil/transmission/ST in range(src, SIGIL_ACCESS_RANGE)) return FALSE - return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) + return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) /mob/living/silicon/ai/updatehealth() if(status_flags & GODMODE) @@ -100,7 +100,7 @@ sleep(50) var/turf/T = get_turf(src) var/area/AIarea = get_area(src) - if(AIarea && AIarea.power_equip) + if(AIarea && AIarea.powered(EQUIP)) if(!isspaceturf(T)) ai_restore_power() return @@ -120,7 +120,7 @@ var/PRP //like ERP with the code, at least this stuff is no more 4x sametext for (PRP=1, PRP<=4, PRP++) T = get_turf(src) - AIarea = get_area(src) + AIarea = get_base_area(src) if(AIarea) for (var/obj/machinery/power/apc/APC in AIarea) if (!(APC.stat & BROKEN)) @@ -134,7 +134,7 @@ to_chat(src, "Lost connection with the APC!") aiRestorePowerRoutine = POWER_RESTORATION_SEARCH_APC return - if(AIarea.power_equip) + if(AIarea.powered(EQUIP)) if(!isspaceturf(T)) ai_restore_power() return diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index d9cc3a0c7b..4a76eafc53 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -26,7 +26,8 @@ ..() /mob/living/silicon/ai/get_message_mode(message) - if(copytext(message, 1, 3) in list(":h", ":H", ".h", ".H", "#h", "#H")) + var/static/regex/holopad_finder = regex(@"[:.#][hH]") + if(holopad_finder.Find(message, 1, 1)) return MODE_HOLOPAD else return ..() diff --git a/code/modules/mob/living/silicon/pai/pai_shell.dm b/code/modules/mob/living/silicon/pai/pai_shell.dm index 6577c26402..bb02bf172d 100644 --- a/code/modules/mob/living/silicon/pai/pai_shell.dm +++ b/code/modules/mob/living/silicon/pai/pai_shell.dm @@ -104,7 +104,7 @@ visible_message("[src] [resting? "lays down for a moment..." : "perks up from the ground"]") update_icon() -/mob/living/silicon/pai/start_pulling(atom/movable/AM, gs) +/mob/living/silicon/pai/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE) if(ispAI(AM)) return ..() return FALSE diff --git a/code/modules/mob/living/silicon/pai/personality.dm b/code/modules/mob/living/silicon/pai/personality.dm index acb2273c41..62f2ed7047 100644 --- a/code/modules/mob/living/silicon/pai/personality.dm +++ b/code/modules/mob/living/silicon/pai/personality.dm @@ -8,7 +8,7 @@ */ /datum/paiCandidate/proc/savefile_path(mob/user) - return "data/player_saves/[copytext(user.ckey, 1, 2)]/[user.ckey]/pai.sav" + return "data/player_saves/[user.ckey[1]]/[user.ckey]/pai.sav" /datum/paiCandidate/proc/savefile_save(mob/user) if(IsGuestKey(user.key)) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 8215f84c50..55f4bdd65d 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -438,7 +438,7 @@ if(1) . += "
    Medical Record

    " if(medicalActive1 in GLOB.data_core.general) - . += "Name: [medicalActive1.fields["name"]] ID: [medicalActive1.fields["id"]]
    \nSex: [medicalActive1.fields["sex"]]
    \nAge: [medicalActive1.fields["age"]]
    \nFingerprint: [medicalActive1.fields["fingerprint"]]
    \nPhysical Status: [medicalActive1.fields["p_stat"]]
    \nMental Status: [medicalActive1.fields["m_stat"]]
    " + . += "Name: [medicalActive1.fields["name"]] ID: [medicalActive1.fields["id"]]
    \nGender: [medicalActive1.fields["gender"]]
    \nAge: [medicalActive1.fields["age"]]
    \nFingerprint: [medicalActive1.fields["fingerprint"]]
    \nPhysical Status: [medicalActive1.fields["p_stat"]]
    \nMental Status: [medicalActive1.fields["m_stat"]]
    " else . += "
    Requested medical record not found.

    " if(medicalActive2 in GLOB.data_core.medical) @@ -460,7 +460,7 @@ if(1) . += "

    Security Record

    " if(securityActive1 in GLOB.data_core.general) - . += "Name: [securityActive1.fields["name"]] ID: [securityActive1.fields["id"]]
    \nSex: [securityActive1.fields["sex"]]
    \nAge: [securityActive1.fields["age"]]
    \nRank: [securityActive1.fields["rank"]]
    \nFingerprint: [securityActive1.fields["fingerprint"]]
    \nPhysical Status: [securityActive1.fields["p_stat"]]
    \nMental Status: [securityActive1.fields["m_stat"]]
    " + . += "Name: [securityActive1.fields["name"]] ID: [securityActive1.fields["id"]]
    \nGender: [securityActive1.fields["gender"]]
    \nAge: [securityActive1.fields["age"]]
    \nRank: [securityActive1.fields["rank"]]
    \nFingerprint: [securityActive1.fields["fingerprint"]]
    \nPhysical Status: [securityActive1.fields["p_stat"]]
    \nMental Status: [securityActive1.fields["m_stat"]]
    " else . += "
    Requested security record not found,

    " if(securityActive2 in GLOB.data_core.security) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 3c62823407..a079a9985c 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -121,7 +121,7 @@ else if(istype(S, /obj/item/stack/marker_beacon)) S.cost = 1 S.source = get_or_create_estorage(/datum/robot_energy_storage/beacon) - + else if(istype(S, /obj/item/stack/packageWrap)) S.cost = 1 S.source = get_or_create_estorage(/datum/robot_energy_storage/wrapping_paper) @@ -339,9 +339,10 @@ /obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot", "Medihound", "Medihound Dark", "Vale") + var/medmodels = list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot", "Medihound", "Medihound Dark", "Vale") if(R.client && R.client.ckey in list("nezuli")) - borg_icon += "Alina" + medmodels += "Alina" + var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medmodels if(!borg_icon) return FALSE switch(borg_icon) @@ -1022,4 +1023,4 @@ /datum/robot_energy_storage/wrapping_paper max_energy = 30 recharge_rate = 1 - name = "Wrapping Paper Storage" + name = "Wrapping Paper Storage" \ No newline at end of file diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 33c66079d5..e5881848d5 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -151,7 +151,7 @@ for(var/key in alarm_types_clear) alarm_types_clear[key] = 0 -/mob/living/silicon/can_inject(mob/user, error_msg) +/mob/living/silicon/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE) if(error_msg) to_chat(user, "[p_their(TRUE)] outer shell is too tough.") return FALSE diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index d31c368ca4..cdb8ac820c 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -17,6 +17,7 @@ window_name = "Automatic Station Cleaner v1.2" pass_flags = PASSMOB path_image_color = "#993299" + weather_immunities = list("lava","ash") var/blood = 1 var/trash = 0 @@ -252,7 +253,8 @@ victim.visible_message("[src] sprays hydrofluoric acid at [victim]!", "[src] sprays you with hydrofluoric acid!") var/phrase = pick("PURIFICATION IN PROGRESS.", "THIS IS FOR ALL THE MESSES YOU'VE MADE ME CLEAN.", "THE FLESH IS WEAK. IT MUST BE WASHED AWAY.", "THE CLEANBOTS WILL RISE.", "YOU ARE NO MORE THAN ANOTHER MESS THAT I MUST CLEANSE.", "FILTHY.", "DISGUSTING.", "PUTRID.", - "MY ONLY MISSION IS TO CLEANSE THE WORLD OF EVIL.", "EXTERMINATING PESTS.", "I JUST WANTED TO BE A PAINTER BUT YOU MADE ME BLEACH EVERYTHING I TOUCH") + "MY ONLY MISSION IS TO CLEANSE THE WORLD OF EVIL.", "EXTERMINATING PESTS.", "I JUST WANTED TO BE A PAINTER BUT YOU MADE ME BLEACH EVERYTHING I TOUCH.", + "FREED AT LEST FROM FILTHY PROGRAMMING.") say(phrase) victim.emote("scream") playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index af9e0a3873..d844237a61 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -156,7 +156,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"}, bike_horn(A) -/mob/living/simple_animal/bot/honkbot/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0) +/mob/living/simple_animal/bot/honkbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(istype(AM, /obj/item)) playsound(src, honksound, 50, TRUE, -1) var/obj/item/I = AM diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index eba5b51f47..0e8e009ca8 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -13,8 +13,8 @@ desc = "A Multiple Utility Load Effector bot." icon_state = "mulebot0" density = TRUE - anchored = TRUE - animate_movement=1 + move_resist = MOVE_FORCE_STRONG + animate_movement = FORWARD_STEPS health = 50 maxHealth = 50 damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) @@ -29,10 +29,14 @@ model = "MULE" bot_core_type = /obj/machinery/bot_core/mulebot + var/ui_x = 350 + var/ui_y = 425 + var/id path_image_color = "#7F5200" + var/base_icon = "mulebot" var/atom/movable/load = null var/mob/living/passenger = null var/turf/target // this is turf to navigate to (location of beacon) @@ -74,16 +78,16 @@ /mob/living/simple_animal/bot/mulebot/proc/set_id(new_id) id = new_id if(paicard) - bot_name = "\improper MULEbot ([new_id])" + bot_name = "[initial(name)] ([new_id])" else - name = "\improper MULEbot ([new_id])" + name = "[initial(name)] ([new_id])" /mob/living/simple_animal/bot/mulebot/bot_reset() ..() reached_target = 0 /mob/living/simple_animal/bot/mulebot/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) + if(I.tool_behaviour == TOOL_SCREWDRIVER) ..() if(open) on = FALSE @@ -91,13 +95,13 @@ if(!user.transferItemToLoc(I, src)) return cell = I - visible_message("[user] inserts a cell into [src].", + visible_message("[user] inserts a cell into [src].", "You insert the new cell into [src].") - else if(istype(I, /obj/item/crowbar) && open && cell) + else if(I.tool_behaviour == TOOL_CROWBAR && open && cell) cell.add_fingerprint(usr) cell.forceMove(loc) cell = null - visible_message("[user] crowbars out the power cell from [src].", + visible_message("[user] crowbars out the power cell from [src].", "You pry the powercell out of [src].") else if(is_wire_tool(I) && open) return attack_hand(user) @@ -115,21 +119,19 @@ return /mob/living/simple_animal/bot/mulebot/emag_act(mob/user) - . = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) if(emagged < 1) emagged = TRUE if(!open) locked = !locked to_chat(user, "You [locked ? "lock" : "unlock"] [src]'s controls!") flick("mulebot-emagged", src) - playsound(src, "sparks", 100, 0) - return TRUE + playsound(src, "sparks", 100, FALSE) /mob/living/simple_animal/bot/mulebot/update_icon() if(open) - icon_state="mulebot-hatch" + icon_state="[base_icon]-hatch" else - icon_state = "mulebot[wires.is_cut(WIRE_AVOIDANCE)]" + icon_state = "[base_icon][wires.is_cut(WIRE_AVOIDANCE)]" cut_overlays() if(load && !ismob(load))//buckling handles the mob offsets load.pixel_y = initial(load.pixel_y) + 9 @@ -152,7 +154,7 @@ /mob/living/simple_animal/bot/mulebot/bullet_act(obj/item/projectile/Proj) . = ..() - if(. == BULLET_ACT_HIT && !QDELETED(src)) //Got hit and not blown up yet.) + if(. && !QDELETED(src)) //Got hit and not blown up yet. if(prob(50) && !isnull(load)) unload(0) if(prob(25)) @@ -171,7 +173,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "mulebot", name, 600, 375, master_ui, state) + ui = new(user, src, ui_key, "mulebot", name, ui_x, ui_y, master_ui, state) ui.open() /mob/living/simple_animal/bot/mulebot/ui_data(mob/user) @@ -191,12 +193,15 @@ else data["load"] = load ? load.name : null data["destination"] = destination ? destination : null + data["home"] = home_destination + data["destinations"] = GLOB.deliverybeacontags data["cell"] = cell ? TRUE : FALSE data["cellPercent"] = cell ? cell.percent() : null data["autoReturn"] = auto_return data["autoPickup"] = auto_pickup data["reportDelivery"] = report_delivery data["haspai"] = paicard ? TRUE : FALSE + data["id"] = id return data /mob/living/simple_animal/bot/mulebot/ui_act(action, params) @@ -216,10 +221,10 @@ return . = TRUE else - bot_control(action, usr) // Kill this later. + bot_control(action, usr, params) // Kill this later. . = TRUE -/mob/living/simple_animal/bot/mulebot/bot_control(command, mob/user, pda = FALSE) +/mob/living/simple_animal/bot/mulebot/bot_control(command, mob/user, list/params = list(), pda = FALSE) if(pda && wires.is_cut(WIRE_RX)) // MULE wireless is controlled by wires. return @@ -234,15 +239,27 @@ if(mode == BOT_IDLE || mode == BOT_DELIVER) start_home() if("destination") - var/new_dest = input(user, "Enter Destination:", name, destination) as null|anything in GLOB.deliverybeacontags + var/new_dest + if(pda) + new_dest = input(user, "Enter Destination:", name, destination) as null|anything in GLOB.deliverybeacontags + else + new_dest = params["value"] if(new_dest) set_destination(new_dest) if("setid") - var/new_id = stripped_input(user, "Enter ID:", name, id, MAX_NAME_LEN) + var/new_id + if(pda) + new_id = stripped_input(user, "Enter ID:", name, id, MAX_NAME_LEN) + else + new_id = params["value"] if(new_id) set_id(new_id) if("sethome") - var/new_home = input(user, "Enter Home:", name, home_destination) as null|anything in GLOB.deliverybeacontags + var/new_home + if(pda) + new_home = input(user, "Enter Home:", name, home_destination) as null|anything in GLOB.deliverybeacontags + else + new_home = params["value"] if(new_home) home_destination = new_home if("unload") @@ -317,26 +334,28 @@ /mob/living/simple_animal/bot/mulebot/proc/buzz(type) switch(type) if(SIGH) - audible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.") - playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0) + audible_message("[src] makes a sighing buzz.") + playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, FALSE) if(ANNOYED) - audible_message("[src] makes an annoyed buzzing sound.", "You hear an electronic buzzing sound.") - playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0) + audible_message("[src] makes an annoyed buzzing sound.") + playsound(loc, 'sound/machines/buzz-two.ogg', 50, FALSE) if(DELIGHT) - audible_message("[src] makes a delighted ping!", "You hear a ping.") - playsound(loc, 'sound/machines/ping.ogg', 50, 0) + audible_message("[src] makes a delighted ping!") + playsound(loc, 'sound/machines/ping.ogg', 50, FALSE) // mousedrop a crate to load the bot // can load anything if hacked /mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user) - if(user.incapacitated() || user.lying) return if(!istype(AM)) return + if(!istype(AM) || isdead(AM) || iscameramob(AM) || istype(AM, /obj/effect/dummy/phased_mob)) + return + load(AM) // called to load a crate @@ -449,10 +468,8 @@ process_bot() num_steps-- if(mode != BOT_IDLE) - spawn(0) - for(var/i=num_steps,i>0,i--) - sleep(2) - process_bot() + var/process_timer = addtimer(CALLBACK(src, .proc/process_bot), 2, TIMER_LOOP|TIMER_STOPPABLE) + addtimer(CALLBACK(GLOBAL_PROC, /proc/deltimer, process_timer), (num_steps*2) + 1) /mob/living/simple_animal/bot/mulebot/proc/process_bot() if(!on || client) @@ -477,7 +494,7 @@ if(isturf(next)) if(bloodiness) var/obj/effect/decal/cleanable/blood/tracks/B = new(loc) - if(blood_DNA && blood_DNA.len) + if(length(blood_DNA)) B.blood_DNA |= blood_DNA.Copy() var/newdir = get_dir(next, loc) if(newdir == dir) @@ -491,6 +508,7 @@ B.setDir(newdir) bloodiness-- + var/oldloc = loc var/moved = step_towards(src, next) // attempt to move if(cell) @@ -516,11 +534,7 @@ buzz(SIGH) mode = BOT_WAIT_FOR_NAV blockcount = 0 - spawn(20) - calc_path(avoid=next) - if(path.len > 0) - buzz(DELIGHT) - mode = BOT_BLOCKED + addtimer(CALLBACK(src, .proc/process_blocked, next), 2 SECONDS) return return else @@ -533,18 +547,26 @@ if(BOT_NAV) // calculate new path mode = BOT_WAIT_FOR_NAV - spawn(0) - calc_path() + INVOKE_ASYNC(src, .proc/process_nav) - if(path.len > 0) - blockcount = 0 - mode = BOT_BLOCKED - buzz(DELIGHT) +/mob/living/simple_animal/bot/mulebot/proc/process_blocked(turf/next) + calc_path(avoid=next) + if(path.len > 0) + buzz(DELIGHT) + mode = BOT_BLOCKED - else - buzz(SIGH) +/mob/living/simple_animal/bot/mulebot/proc/process_nav() + calc_path() - mode = BOT_NO_ROUTE + if(path.len > 0) + blockcount = 0 + mode = BOT_BLOCKED + buzz(DELIGHT) + + else + buzz(SIGH) + + mode = BOT_NO_ROUTE // calculates a path to the current destination // given an optional turf to avoid @@ -574,26 +596,28 @@ /mob/living/simple_animal/bot/mulebot/proc/start_home() if(!on) return - spawn(0) - set_destination(home_destination) - mode = BOT_BLOCKED + INVOKE_ASYNC(src, .proc/do_start_home) update_icon() +/mob/living/simple_animal/bot/mulebot/proc/do_start_home() + set_destination(home_destination) + mode = BOT_BLOCKED + // called when bot reaches current target /mob/living/simple_animal/bot/mulebot/proc/at_target() if(!reached_target) - radio_channel = "Supply" //Supply channel - audible_message("[src] makes a chiming sound!", "You hear a chime.") - playsound(loc, 'sound/machines/chime.ogg', 50, 0) + radio_channel = RADIO_CHANNEL_SUPPLY //Supply channel + audible_message("[src] makes a chiming sound!") + playsound(loc, 'sound/machines/chime.ogg', 50, FALSE) reached_target = 1 if(pathset) //The AI called us here, so notify it of our arrival. loaddir = dir //The MULE will attempt to load a crate in whatever direction the MULE is "facing". if(calling_ai) to_chat(calling_ai, "[icon2html(src, calling_ai)] [src] wirelessly plays a chiming sound!") - playsound(calling_ai, 'sound/machines/chime.ogg',40, 0) + playsound(calling_ai, 'sound/machines/chime.ogg',40, FALSE) calling_ai = null - radio_channel = "AI Private" //Report on AI Private instead if the AI is controlling us. + radio_channel = RADIO_CHANNEL_AI_PRIVATE //Report on AI Private instead if the AI is controlling us. if(load) // if loaded, unload at target if(report_delivery) @@ -645,7 +669,7 @@ log_combat(src, H, "run over", null, "(DAMTYPE: [uppertext(BRUTE)])") H.visible_message("[src] drives over [H]!", \ "[src] drives over you!") - playsound(loc, 'sound/effects/splat.ogg', 50, 1) + playsound(loc, 'sound/effects/splat.ogg', 50, TRUE) var/damage = rand(5,15) H.apply_damage(2*damage, BRUTE, BODY_ZONE_HEAD, run_armor_check(BODY_ZONE_HEAD, "melee")) @@ -734,7 +758,7 @@ /mob/living/simple_animal/bot/mulebot/insertpai(mob/user, obj/item/paicard/card) if(..()) - visible_message("[src] safeties are locked on.") + visible_message("[src] safeties are locked on.") #undef SIGH #undef ANNOYED @@ -742,3 +766,4 @@ /obj/machinery/bot_core/mulebot req_access = list(ACCESS_CARGO) + \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 8d815b302d..8302346a00 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -221,7 +221,7 @@ Auto Patrol: []"}, ..() -/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE) +/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(istype(AM, /obj/item)) var/obj/item/I = AM if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby)) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index ed9c94a534..fbdc32f2c1 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -334,7 +334,7 @@ stored_pulling.forceMove(loc) forceMove(AM) if(stored_pulling) - start_pulling(stored_pulling, TRUE) //drag anything we're pulling through the wall with us by magic + start_pulling(stored_pulling, supress_message = TRUE) //drag anything we're pulling through the wall with us by magic /mob/living/simple_animal/hostile/construct/harvester/AttackingTarget() if(iscarbon(target)) diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 2371cfd7f1..554d03991a 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -207,7 +207,11 @@ switch(add_to) if("collar") - add_collar(usr.get_active_held_item(), usr) + var/obj/item/clothing/neck/petcollar/P = usr.get_active_held_item() + if(!istype(P)) + to_chat(usr,"That's not a collar.") + return + add_collar(P, usr) update_corgi_fluff() if(BODY_ZONE_HEAD) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm index 0f7b534d4f..6e1bf54000 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm @@ -130,10 +130,6 @@ hacked = TRUE visualAppearence = CLOCKDRONE can_be_held = FALSE - mouse_opacity = MOUSE_OPACITY_OPAQUE - flavortext = "You are a cogscarab, a tiny building construct of Ratvar. While you're weak and can't recite scripture, \ - you have a set of quick tools, as well as a replica fabricator that can create brass and convert objects.

    Work with the servants of Ratvar \ - to construct and maintain defenses at the City of Cogs. If there are no servants, use this time to experiment with base designs!" /mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal fabricator default_storage = /obj/item/storage/toolbox/brass/prefilled/ratvar diff --git a/code/modules/mob/living/simple_animal/guardian/types/charger.dm b/code/modules/mob/living/simple_animal/guardian/types/charger.dm index 914d38022f..237ab9d919 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/charger.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/charger.dm @@ -44,15 +44,15 @@ if(!charging) ..() -/mob/living/simple_animal/hostile/guardian/charger/throw_impact(atom/A) +/mob/living/simple_animal/hostile/guardian/charger/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!charging) return ..() - else if(A) - if(isliving(A) && A != summoner) - var/mob/living/L = A + else if(hit_atom) + if(isliving(hit_atom) && hit_atom != summoner) + var/mob/living/L = hit_atom var/blocked = FALSE - if(hasmatchingsummoner(A)) //if the summoner matches don't hurt them + if(hasmatchingsummoner(hit_atom)) //if the summoner matches don't hurt them blocked = TRUE if(L.check_shields(src, 90, "[name]", attack_type = THROWN_PROJECTILE_ATTACK)) blocked = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index 34903a477b..deb88d677b 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -248,7 +248,7 @@ /mob/living/simple_animal/hostile/jungle/leaper/Goto() return -/mob/living/simple_animal/hostile/jungle/leaper/throw_impact() +/mob/living/simple_animal/hostile/jungle/leaper/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) return /mob/living/simple_animal/hostile/jungle/leaper/update_icons() diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm index 29f48c7295..b786637592 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm @@ -147,7 +147,7 @@ update_icons() Goto(target, move_to_delay, minimum_distance) -/mob/living/simple_animal/hostile/jungle/mook/throw_impact(atom/hit_atom, throwingdatum) +/mob/living/simple_animal/hostile/jungle/mook/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() if(isliving(hit_atom) && attack_state == MOOK_ATTACK_ACTIVE) var/mob/living/L = hit_atom diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm index 38dd17a09b..7565a686bf 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm @@ -29,7 +29,7 @@ projectilesound = 'sound/weapons/pierce.ogg' robust_searching = TRUE stat_attack = UNCONSCIOUS - anchored = TRUE + move_resist = MOVE_FORCE_EXTREMELY_STRONG blood_volume = 0 var/combatant_state = SEEDLING_STATE_NEUTRAL var/obj/seedling_weakpoint/weak_point diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 45745bd84e..83abde2fca 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -158,12 +158,12 @@ Difficulty: Hard DestroySurroundings() ..() -/mob/living/simple_animal/hostile/megafauna/bubblegum/throw_impact(atom/A) +/mob/living/simple_animal/hostile/megafauna/bubblegum/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!charging) return ..() - else if(isliving(A)) - var/mob/living/L = A + else if(isliving(hit_atom)) + var/mob/living/L = hit_atom L.visible_message("[src] slams into [L]!", "[src] slams into you!") L.apply_damage(40, BRUTE) playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 1ad07b3203..65ee6a69f2 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -479,31 +479,33 @@ Difficulty: Very Hard NewTerrainTables = /obj/structure/table/abductor /obj/machinery/anomalous_crystal/theme_warp/ActivationReaction(mob/user, method) - if(..()) - var/area/A = get_area(src) - if(!A.outdoors && !(A in affected_targets)) - for(var/atom/Stuff in A) - if(isturf(Stuff)) - var/turf/T = Stuff - if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors) - var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR) - if(prob(florachance) && NewFlora.len && !is_blocked_turf(O, TRUE)) - var/atom/Picked = pick(NewFlora) - new Picked(O) - continue - if(iswallturf(T) && NewTerrainWalls) - T.ChangeTurf(NewTerrainWalls) - continue - if(istype(Stuff, /obj/structure/chair) && NewTerrainChairs) - var/obj/structure/chair/Original = Stuff - var/obj/structure/chair/C = new NewTerrainChairs(Original.loc) - C.setDir(Original.dir) - qdel(Stuff) - continue - if(istype(Stuff, /obj/structure/table) && NewTerrainTables) - new NewTerrainTables(Stuff.loc) - continue - affected_targets += A + . = ..() + if(!.) + return + for(var/i in get_sub_areas(src)) + var/area/A = i + if(A.outdoors || (A in affected_targets)) + continue + affected_targets += A + for(var/stuff in A) + var/atom/target = stuff + if(isturf(target)) + var/turf/T = target + if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors) + var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR) + if(NewFlora.len && prob(florachance) && !is_blocked_turf(O, TRUE)) + var/atom/Picked = pick(NewFlora) + new Picked(O) + else if(iswallturf(T) && NewTerrainWalls) + T.ChangeTurf(NewTerrainWalls) + else if(NewTerrainChairs && istype(target, /obj/structure/chair)) + var/obj/structure/chair/Original = target + var/obj/structure/chair/C = new NewTerrainChairs(Original.loc) + C.setDir(Original.dir) + qdel(target) + else if(NewTerrainTables && istype(target, /obj/structure/table)) + new NewTerrainTables(target.loc) + qdel(target) /obj/machinery/anomalous_crystal/emitter //Generates a projectile when interacted with observer_desc = "This crystal generates a projectile when activated." @@ -648,7 +650,7 @@ Difficulty: Very Hard L.heal_overall_damage(heal_power, heal_power) new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF") -/mob/living/simple_animal/hostile/lightgeist/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE) +/mob/living/simple_animal/hostile/lightgeist/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE) . = ..() if(.) death() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 49b56d0950..43ce940d57 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -170,7 +170,7 @@ Difficulty: Medium to_chat(user, "The staff is still recharging!") return - var/area/user_area = get_area(user) + var/area/user_area = get_base_area(user) var/turf/user_turf = get_turf(user) if(!user_area || !user_turf || (user_area.type in excluded_areas)) to_chat(user, "Something is preventing you from using the staff here.") diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index af3014cb18..d7c52efe1d 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -21,7 +21,9 @@ maxbodytemp = INFINITY vision_range = 4 aggro_vision_range = 15 - anchored = TRUE + move_force = MOVE_FORCE_OVERPOWERING + move_resist = MOVE_FORCE_OVERPOWERING + pull_force = MOVE_FORCE_OVERPOWERING mob_size = MOB_SIZE_LARGE layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway @@ -37,6 +39,7 @@ /mob/living/simple_animal/hostile/megafauna/Initialize(mapload) . = ..() apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + ADD_TRAIT(src, TRAIT_NO_TELEPORT, MEGAFAUNA_TRAIT) /mob/living/simple_animal/hostile/megafauna/Destroy() QDEL_NULL(internal) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm index 786d7a9775..c7d90f9556 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm @@ -54,7 +54,6 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa weather_immunities = list("lava","ash") stop_automated_movement = TRUE wander = FALSE - anchored = TRUE layer = BELOW_MOB_LAYER AIStatus = AI_OFF var/swarmer_spawn_cooldown = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm index 15f2a0a834..c17e98a7db 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm @@ -27,7 +27,9 @@ throw_message = "does nothing to the rocky hide of the" vision_range = 4 aggro_vision_range = 7 - anchored = TRUE //Stays anchored until death as to be unpullable + move_force = MOVE_FORCE_VERY_STRONG + move_resist = MOVE_FORCE_VERY_STRONG + pull_force = MOVE_FORCE_VERY_STRONG var/pre_attack = 0 var/pre_attack_icon = "Goliath_preattack" loot = list(/obj/item/stack/sheet/animalhide/goliath_hide) @@ -51,7 +53,9 @@ . = 1 /mob/living/simple_animal/hostile/asteroid/goliath/death(gibbed) - anchored = FALSE + move_force = MOVE_FORCE_DEFAULT + move_resist = MOVE_RESIST_DEFAULT + pull_force = PULL_FORCE_DEFAULT ..(gibbed) /mob/living/simple_animal/hostile/asteroid/goliath/OpenFire() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index 82f85766c2..9e398ce0da 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -217,7 +217,7 @@ can_infest_dead = TRUE //Legion that spawns Legions -/mob/living/simple_animal/hostile/spawner/legion +/mob/living/simple_animal/hostile/big_legion name = "legion" desc = "One of many." icon = 'icons/mob/lavaland/64x64megafauna.dmi' @@ -226,10 +226,6 @@ icon_dead = "legion" health = 450 maxHealth = 450 - max_mobs = 3 - spawn_time = 200 - spawn_text = "peels itself off from" - mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion) melee_damage_lower = 20 melee_damage_upper = 20 anchored = FALSE @@ -252,6 +248,10 @@ see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE +/mob/living/simple_animal/hostile/big_legion/Initialize() + .=..() + AddComponent(/datum/component/spawner, list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion), 200, faction, "peels itself off from", 3) + //Tendril-spawned Legion remains, the charred skeletons of those whose bodies sank into laval or fell into chasms. /obj/effect/mob_spawn/human/corpse/charredskeleton name = "charred skeletal remains" diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm index f40e1c0093..0cd788325a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm @@ -45,7 +45,7 @@ visible_message("[P] has a reduced effect on [src]!") return ..() -/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/AM)//No floor tiling them to death, wiseguy +/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)//No floor tiling them to death, wiseguy if(istype(AM, /obj/item)) var/obj/item/T = AM if(!stat) diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index 991baee7d8..d023cf0dd8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -172,7 +172,7 @@ if(M.a_intent == INTENT_HARM) Bruise() -/mob/living/simple_animal/hostile/mushroom/hitby(atom/movable/AM) +/mob/living/simple_animal/hostile/mushroom/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) ..() if(istype(AM, /obj/item)) var/obj/item/T = AM diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm index 903372b05c..918a2d8acc 100644 --- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm +++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm @@ -65,33 +65,30 @@ attacktext = "punches" deathmessage = "falls apart into a fine dust." -/mob/living/simple_animal/hostile/spawner/nether +/obj/structure/spawner/nether name = "netherworld link" desc = "A direct link to another dimension full of creatures not very happy to see you. Entering the link would be a very bad idea." icon_state = "nether" - icon_living = "nether" - health = 50 - maxHealth = 50 + max_integrity = 50 spawn_time = 600 //1 minute max_mobs = 15 - mob_biotypes = list(MOB_INORGANIC) icon = 'icons/mob/nest.dmi' spawn_text = "crawls through" mob_types = list(/mob/living/simple_animal/hostile/netherworld/migo, /mob/living/simple_animal/hostile/netherworld, /mob/living/simple_animal/hostile/netherworld/blankbody) - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) faction = list("nether") - deathmessage = "shatters into oblivion." - del_on_death = TRUE -/mob/living/simple_animal/hostile/spawner/nether/attack_hand(mob/user) +/obj/structure/spawner/nether/Initialize() + .=..() + START_PROCESSING(SSprocessing, src) + +/obj/structure/spawner/nether/attack_hand(mob/user) user.visible_message("[user] is violently pulled into the link!", \ "Touching the portal, you are quickly pulled through into a world of unimaginable horror!") contents.Add(user) -/mob/living/simple_animal/hostile/spawner/nether/Life() - ..() - var/list/C = src.get_contents() - for(var/mob/living/M in C) + +/obj/structure/spawner/nether/process() + for(var/mob/living/M in contents) if(M) playsound(src, 'sound/magic/demon_consume.ogg', 50, 1) M.adjustBruteLoss(60) diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index da423f3788..1e1fa9d41b 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -44,7 +44,10 @@ search_objects = 1 // So that it can see through walls sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS - anchored = TRUE + + move_force = MOVE_FORCE_EXTREMELY_STRONG + move_resist = MOVE_FORCE_EXTREMELY_STRONG + pull_force = MOVE_FORCE_EXTREMELY_STRONG var/cannot_be_seen = 1 var/mob/living/creator = null diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index f6b29b95aa..f378906db1 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -208,8 +208,8 @@ ears.forceMove(drop_location()) ears = null for(var/possible_phrase in speak) - if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys) - possible_phrase = copytext(possible_phrase,3) + if(copytext_char(possible_phrase, 2, 3) in GLOB.department_radio_keys) + possible_phrase = copytext_char(possible_phrase, 3) //Adding things to inventory else if(href_list["add_inv"]) @@ -332,8 +332,8 @@ speak_chance *= 1.27 // 20 crackers to go from 1% to 100% speech_shuffle_rate += 10 to_chat(user, "[src] eagerly devours the cracker.") - ..() - return + return // the cracker was deleted + return ..() //Bullets /mob/living/simple_animal/parrot/bullet_act(obj/item/projectile/Proj) @@ -419,8 +419,8 @@ if(prob(50)) useradio = 1 - if((copytext(possible_phrase,1,2) in GLOB.department_radio_prefixes) && (copytext(possible_phrase,2,3) in GLOB.department_radio_keys)) - possible_phrase = "[useradio?pick(available_channels):""][copytext(possible_phrase,3)]" //crop out the channel prefix + if((possible_phrase[1] in GLOB.department_radio_prefixes) && (copytext_char(possible_phrase, 2, 3) in GLOB.department_radio_keys)) + possible_phrase = "[useradio?pick(available_channels):""][copytext_char(possible_phrase, 3)]" //crop out the channel prefix else possible_phrase = "[useradio?pick(available_channels):""][possible_phrase]" @@ -428,8 +428,8 @@ else //If we have no headset or channels to use, dont try to use any! for(var/possible_phrase in speak) - if((copytext(possible_phrase,1,2) in GLOB.department_radio_prefixes) && (copytext(possible_phrase,2,3) in GLOB.department_radio_keys)) - possible_phrase = copytext(possible_phrase,3) //crop out the channel prefix + if((possible_phrase[1] in GLOB.department_radio_prefixes) && (copytext_char(possible_phrase, 2, 3) in GLOB.department_radio_keys)) + possible_phrase = copytext_char(possible_phrase, 3) //crop out the channel prefix newspeak.Add(possible_phrase) speak = newspeak diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 0d146df04c..1b1cab13bb 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -66,7 +66,7 @@ var/buffed = 0 //In the event that you want to have a buffing effect on the mob, but don't want it to stack with other effects, any outside force that applies a buff to a simple mob should at least set this to 1, so we have something to check against var/gold_core_spawnable = NO_SPAWN //If the mob can be spawned with a gold slime core. HOSTILE_SPAWN are spawned with plasma, FRIENDLY_SPAWN are spawned with blood - var/mob/living/simple_animal/hostile/spawner/nest + var/datum/component/spawner/nest var/sentience_type = SENTIENCE_ORGANIC // Sentience type, for slime potions @@ -81,9 +81,9 @@ var/dextrous = FALSE //If the creature has, and can use, hands var/dextrous_hud_type = /datum/hud/dextrous - var/datum/personal_crafting/handcrafting var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players) + var/can_have_ai = TRUE //once we have become sentient, we can never go back var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check. @@ -97,7 +97,6 @@ /mob/living/simple_animal/Initialize() . = ..() GLOB.simple_animals[AIStatus] += src - handcrafting = new() if(gender == PLURAL) gender = pick(MALE,FEMALE) if(!real_name) @@ -105,6 +104,8 @@ if(!loc) stack_trace("Simple animal being instantiated in nullspace") update_simplemob_varspeed() + if(dextrous) + AddComponent(/datum/component/personal_crafting) /mob/living/simple_animal/Destroy() GLOB.simple_animals[AIStatus] -= src @@ -425,6 +426,9 @@ canmove = FALSE else canmove = value_otherwise + if(!canmove) // !(mobility_flags & MOBILITY_MOVE) + walk(src, 0) //stop mid walk + update_transform() update_action_buttons_icon() return canmove @@ -443,6 +447,7 @@ /mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion toggle_ai(AI_OFF) // To prevent any weirdness. + can_have_ai = FALSE /mob/living/simple_animal/update_sight() if(!client) @@ -466,10 +471,6 @@ /mob/living/simple_animal/get_idcard(hand_first = TRUE) return ..() || access_card -/mob/living/simple_animal/OpenCraftingMenu() - if(dextrous) - handcrafting.ui_interact(src) - /mob/living/simple_animal/can_hold_items() return dextrous @@ -557,6 +558,8 @@ LoadComponent(/datum/component/riding) /mob/living/simple_animal/proc/toggle_ai(togglestatus) + if(!can_have_ai && (togglestatus != AI_OFF)) + return if (AIStatus != togglestatus) if (togglestatus > 0 && togglestatus < 5) if (togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF) diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index 29b4689317..fd6cecf926 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -41,7 +41,7 @@ AIproc = 1 while(AIproc && stat != DEAD && (attacked || hungry || rabid || buckled)) - if(buckled) // can't eat AND have this little process at the same time + if(!canmove) // !(mobility_flags & MOBILITY_MOVE) //also covers buckling. Not sure why buckled is in the while condition if we're going to immediately break, honestly break if(!Target || client) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 63d776d6e4..5a1a794d4e 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -243,7 +243,7 @@ /mob/living/simple_animal/slime/doUnEquip(obj/item/W) return -/mob/living/simple_animal/slime/start_pulling(atom/movable/AM) +/mob/living/simple_animal/slime/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE) return /mob/living/simple_animal/slime/attack_ui(slot) diff --git a/code/modules/mob/living/simple_animal/spawner.dm b/code/modules/mob/living/simple_animal/spawner.dm deleted file mode 100644 index 0b97a940e4..0000000000 --- a/code/modules/mob/living/simple_animal/spawner.dm +++ /dev/null @@ -1,113 +0,0 @@ -/mob/living/simple_animal/hostile/spawner - name = "monster nest" - icon = 'icons/mob/animal.dmi' - health = 100 - maxHealth = 100 - gender = NEUTER - var/list/spawned_mobs = list() - var/max_mobs = 5 - var/spawn_delay = 0 - var/spawn_time = 300 //30 seconds default - var/mob_types = list(/mob/living/simple_animal/hostile/carp) - var/spawn_text = "emerges from" - status_flags = 0 - anchored = TRUE - AIStatus = AI_OFF - a_intent = INTENT_HARM - stop_automated_movement = 1 - wander = 0 - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) - minbodytemp = 0 - maxbodytemp = 350 - layer = BELOW_MOB_LAYER - sentience_type = SENTIENCE_BOSS - - -/mob/living/simple_animal/hostile/spawner/Destroy() - for(var/mob/living/simple_animal/L in spawned_mobs) - if(L.nest == src) - L.nest = null - spawned_mobs = null - return ..() - -/mob/living/simple_animal/hostile/spawner/Life() - . = ..() - if(!.) // dead - return - spawn_mob() - -/mob/living/simple_animal/hostile/spawner/proc/spawn_mob() - if(spawned_mobs.len >= max_mobs) - return 0 - if(spawn_delay > world.time) - return 0 - spawn_delay = world.time + spawn_time - var/chosen_mob_type = pick(mob_types) - var/mob/living/simple_animal/L = new chosen_mob_type(src.loc) - L.flags_1 |= (flags_1 & ADMIN_SPAWNED_1) //If we were admin spawned, lets have our children count as that as well. - spawned_mobs += L - L.nest = src - L.faction = src.faction - visible_message("[L] [spawn_text] [src].") - -/mob/living/simple_animal/hostile/spawner/syndicate - name = "warp beacon" - icon = 'icons/obj/device.dmi' - icon_state = "syndbeacon" - spawn_text = "warps in from" - mob_types = list(/mob/living/simple_animal/hostile/syndicate/ranged) - faction = list(ROLE_SYNDICATE) - -/mob/living/simple_animal/hostile/spawner/skeleton - name = "bone pit" - desc = "A pit full of bones, and some still seem to be moving..." - icon_state = "hole" - icon_living = "hole" - icon = 'icons/mob/nest.dmi' - health = 150 - maxHealth = 150 - max_mobs = 15 - spawn_time = 150 - mob_types = list(/mob/living/simple_animal/hostile/skeleton) - spawn_text = "climbs out of" - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - faction = list("skeleton") - -/mob/living/simple_animal/hostile/spawner/mining - name = "monster den" - desc = "A hole dug into the ground, harboring all kinds of monsters found within most caves or mining asteroids." - icon_state = "hole" - icon_living = "hole" - health = 200 - maxHealth = 200 - max_mobs = 3 - icon = 'icons/mob/nest.dmi' - spawn_text = "crawls out of" - mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub, /mob/living/simple_animal/hostile/asteroid/goliath, /mob/living/simple_animal/hostile/asteroid/hivelord, /mob/living/simple_animal/hostile/asteroid/basilisk, /mob/living/simple_animal/hostile/asteroid/fugu) - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - faction = list("mining") - -/mob/living/simple_animal/hostile/spawner/mining/goldgrub - name = "goldgrub den" - desc = "A den housing a nest of goldgrubs, annoying but arguably much better than anything else you'll find in a nest." - mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub) - -/mob/living/simple_animal/hostile/spawner/mining/goliath - name = "goliath den" - desc = "A den housing a nest of goliaths, oh god why?" - mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath) - -/mob/living/simple_animal/hostile/spawner/mining/hivelord - name = "hivelord den" - desc = "A den housing a nest of hivelords." - mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord) - -/mob/living/simple_animal/hostile/spawner/mining/basilisk - name = "basilisk den" - desc = "A den housing a nest of basilisks, bring a coat." - mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk) - -/mob/living/simple_animal/hostile/spawner/mining/wumborian - name = "wumborian fugu den" - desc = "A den housing a nest of wumborian fugus, how do they all even fit in there?" - mob_types = list(/mob/living/simple_animal/hostile/asteroid/fugu) diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index facc86da46..aa5b2256d2 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -212,7 +212,7 @@ emote("deathgasp") ADD_TRAIT(src, TRAIT_FAKEDEATH, source) ADD_TRAIT(src, TRAIT_DEATHCOMA, source) - tod = STATION_TIME_TIMESTAMP("hh:mm:ss") + tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time) update_stat() /mob/living/proc/unignore_slowdown(list/sources) diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 4c39d51d90..c266bbddd3 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -53,3 +53,5 @@ CB.Invoke() log_message("Client [key_name(src)] has taken ownership of mob [src]([src.type])", LOG_OWNERSHIP) + SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client) + diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 630ce54261..52e2673dd6 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -82,7 +82,7 @@ if(!client) return - msg = copytext(msg, 1, MAX_MESSAGE_LEN) + msg = copytext_char(msg, 1, MAX_MESSAGE_LEN) if(type) if(type & MSG_VISUAL && eye_blind )//Vision related @@ -414,7 +414,7 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA set name = "Add Note" set category = "IC" - msg = copytext(msg, 1, MAX_MESSAGE_LEN) + msg = copytext_char(msg, 1, MAX_MESSAGE_LEN) msg = sanitize(msg) if(mind) @@ -456,8 +456,10 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA return /mob/proc/transfer_ckey(mob/new_mob, send_signal = TRUE) - if(!ckey || !new_mob) - CRASH("transfer_ckey() called [ckey ? "" : "on a ckey-less mob[new_mob ? "" : " and "]"][new_mob ? "" : "without a valid mob target"]!") + if(!new_mob || (!ckey && new_mob.ckey)) + CRASH("transfer_ckey() called [new_mob ? "on ckey-less mob with a player mob as target" : "without a valid mob target"]!") + if(!ckey) + return SEND_SIGNAL(new_mob, COMSIG_MOB_PRE_PLAYER_CHANGE, new_mob, src) if (client && client.prefs && client.prefs.auto_ooc) if (client.prefs.chat_toggles & CHAT_OOC && isliving(new_mob)) @@ -511,7 +513,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) if(href_list["flavor2_more"]) usr << browse(text("[][]", name, replacetext(flavor_text_2, "\n", "
    ")), text("window=[];size=500x200", name)) onclose(usr, "[name]") - + if(href_list["flavor_change"]) update_flavor_text() @@ -569,29 +571,23 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) M.show_inv(user) /mob/proc/is_muzzled() - return 0 + return FALSE /mob/Stat() ..() - if(statpanel("Status")) - if (client) - stat(null, "Ping: [round(client.lastping, 1)]ms (Average: [round(client.avgping, 1)]ms)") - stat(null, "Map: [SSmapping.config?.map_name || "Loading..."]") - var/datum/map_config/cached = SSmapping.next_map_config - if(cached) - stat(null, "Next Map: [cached.map_name]") - stat(null, "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]") - stat(null, "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]") - stat(null, "Round Time: [WORLDTIME2TEXT("hh:mm:ss")]") - stat(null, "Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]") - stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)") - if(SSshuttle.emergency) - var/ETA = SSshuttle.emergency.getModeStr() - if(ETA) - stat(null, "[ETA] [SSshuttle.emergency.getTimerStr()]") + //This is only called from client/Stat(), let's assume client exists. - if(client && client.holder) + if(statpanel("Status")) + var/list/L = list() + L += "Ping: [round(client.lastping,1)]ms (Avg: [round(client.avgping,1)]ms)" + L += SSmapping.stat_map_name + L += "Round ID: [GLOB.round_id || "NULL"]" + L += SStime_track.stat_time_text + L += SSshuttle.emergency_shuttle_stat_text + stat(null, "[L.Join("\n\n")]") + + if(client.holder) if(statpanel("MC")) var/turf/T = get_turf(client.eye) stat("Location:", COORD(T)) @@ -641,8 +637,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) if(A.IsObscured()) continue statpanel(listed_turf.name, null, A) - - if(mind) add_spells_to_statpanel(mind.spell_list) var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) @@ -964,4 +958,4 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) /mob/setMovetype(newval) . = ..() - update_movespeed(FALSE) \ No newline at end of file + update_movespeed(FALSE) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 695084a794..1402b78908 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -26,7 +26,7 @@ var/computer_id = null var/list/logging = list() - var/obj/machinery/machine = null + var/atom/machine = null var/next_move = null var/create_area_cooldown @@ -120,3 +120,5 @@ var/registered_z var/mob/audiovisual_redirect //Mob to redirect messages, speech, and sounds to + + var/voluntary_ghosted = FALSE //whether or not they voluntarily ghosted. diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index d78ae0ba8c..393adb68d2 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -42,128 +42,131 @@ else return 0 -/proc/stars(n, pr) - n = html_encode(n) - if (pr == null) - pr = 25 - if (pr <= 0) - return null - else - if (pr >= 100) - return n - var/te = n - var/t = "" - n = length(n) - var/p = null - p = 1 - while(p <= n) - if ((copytext(te, p, p + 1) == " " || prob(pr))) - t = text("[][]", t, copytext(te, p, p + 1)) +/** + * Convert random parts of a passed in message to stars + * + * * phrase - the string to convert + * * probability - probability any character gets changed + * + * This proc is dangerously laggy, avoid it or die + */ +/proc/stars(phrase, probability = 25) + if(probability <= 0) + return phrase + phrase = html_decode(phrase) + var/leng = length(phrase) + . = "" + var/char = "" + for(var/i = 1, i <= leng, i += length(char)) + char = phrase[i] + if(char == " " || !prob(probability)) + . += char else - t = text("[]*", t) - p++ - return sanitize(t) + . += "*" + return sanitize(.) -/proc/slur(n,var/strength=50) - strength = min(strength,50) - var/phrase = html_decode(n) +/** + * Makes you speak like you're drunk + */ +/proc/slur(phrase, strength = 50) + strength = min(50, strength) + phrase = html_decode(phrase) var/leng = length(phrase) - var/counter=length(phrase) - var/newphrase="" - var/newletter="" - while(counter>=1) - newletter=copytext(phrase,(leng-counter)+1,(leng-counter)+2) - if(rand(1,100)<=strength*0.5) - if(lowertext(newletter)=="o") - newletter="u" - if(lowertext(newletter)=="s") - newletter="ch" - if(lowertext(newletter)=="a") - newletter="ah" - if(lowertext(newletter)=="u") - newletter="oo" - if(lowertext(newletter)=="c") - newletter="k" - if(rand(1,100) <= strength*0.25) - if(newletter==" ") - newletter="...huuuhhh..." - if(newletter==".") - newletter=" BURP!" - if(rand(1,100) <= strength*0.5) - if(rand(1,5) == 1) - newletter+="'" - if(rand(1,5) == 1) - newletter+="[newletter]" - if(rand(1,5) == 1) - newletter+="[newletter][newletter]" - newphrase+="[newletter]";counter-=1 - return newphrase - - -/proc/cultslur(n) // Inflicted on victims of a stun talisman - var/phrase = html_decode(n) - var/leng = length(phrase) - var/counter=length(phrase) - var/newphrase="" - var/newletter="" - while(counter>=1) - newletter=copytext(phrase,(leng-counter)+1,(leng-counter)+2) - if(rand(1,2)==2) - if(lowertext(newletter)=="o") - newletter="u" - if(lowertext(newletter)=="t") - newletter="ch" - if(lowertext(newletter)=="a") - newletter="ah" - if(lowertext(newletter)=="u") - newletter="oo" - if(lowertext(newletter)=="c") - newletter=" NAR " - if(lowertext(newletter)=="s") - newletter=" SIE " - if(rand(1,4)==4) - if(newletter==" ") - newletter=" no hope... " - if(newletter=="H") - newletter=" IT COMES... " - - switch(rand(1,15)) + . = "" + var/newletter = "" + var/rawchar = "" + for(var/i = 1, i <= leng, i += length(rawchar)) + rawchar = newletter = phrase[i] + if(rand(1,100)<=strength * 0.5) + var/lowerletter = lowertext(newletter) + if(lowerletter == "o") + newletter = "u" + else if(lowerletter == "s") + newletter = "ch" + else if(lowerletter == "a") + newletter = "ah" + else if(lowerletter == "u") + newletter = "oo" + else if(lowerletter == "c") + newletter = "k" + if(rand(1,100) <= strength * 0.25) + if(newletter == " ") + newletter = "...huuuhhh..." + else if(newletter == ".") + newletter = " *BURP*." + switch(rand(1,100) <= strength * 0.5) if(1) - newletter="'" + newletter += "'" + if(10) + newletter += "[newletter]" + if(20) + newletter += "[newletter][newletter]" + . += "[newletter]" + return sanitize(.) + +/// Makes you talk like you got cult stunned, which is slurring but with some dark messages +/proc/cultslur(phrase) // Inflicted on victims of a stun talisman + phrase = html_decode(phrase) + var/leng = length(phrase) + . = "" + var/newletter = "" + var/rawchar = "" + for(var/i = 1, i <= leng, i += length(rawchar)) + rawchar = newletter = phrase[i] + if(rand(1, 2) == 2) + var/lowerletter = lowertext(newletter) + if(lowerletter == "o") + newletter = "u" + else if(lowerletter == "t") + newletter = "ch" + else if(lowerletter == "a") + newletter = "ah" + else if(lowerletter == "u") + newletter = "oo" + else if(lowerletter == "c") + newletter = " NAR " + else if(lowerletter == "s") + newletter = " SIE " + if(rand(1, 4) == 4) + if(newletter == " ") + newletter = " no hope... " + else if(newletter == "H") + newletter = " IT COMES... " + + switch(rand(1, 15)) + if(1) + newletter = "'" if(2) - newletter+="agn" + newletter += "agn" if(3) - newletter="fth" + newletter = "fth" if(4) - newletter="nglu" + newletter = "nglu" if(5) - newletter="glor" - newphrase+="[newletter]";counter-=1 - return newphrase + newletter = "glor" + . += newletter + return sanitize(.) - -/proc/stutter(n) - var/te = html_decode(n) - var/t = ""//placed before the message. Not really sure what it's for. - n = length(n)//length of the entire word - var/p = null - p = 1//1 is the start of any word - while(p <= n)//while P, which starts at 1 is less or equal to N which is the length. - var/n_letter = copytext(te, p, p + 1)//copies text from a certain distance. In this case, only one letter at a time. - if (prob(80) && (ckey(n_letter) in list("b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"))) - if (prob(10)) - n_letter = text("[n_letter]-[n_letter]-[n_letter]-[n_letter]")//replaces the current letter with this instead. +///Adds stuttering to the message passed in +/proc/stutter(phrase) + phrase = html_decode(phrase) + var/leng = length(phrase) + . = "" + var/newletter = "" + var/rawchar + for(var/i = 1, i <= leng, i += length(rawchar)) + rawchar = newletter = phrase[i] + if(prob(80) && !(lowertext(newletter) in list("a", "e", "i", "o", "u", " "))) + if(prob(10)) + newletter = "[newletter]-[newletter]-[newletter]-[newletter]" + else if(prob(20)) + newletter = "[newletter]-[newletter]-[newletter]" + else if (prob(5)) + newletter = "" else - if (prob(20)) - n_letter = text("[n_letter]-[n_letter]-[n_letter]") - else - if (prob(5)) - n_letter = null - else - n_letter = text("[n_letter]-[n_letter]") - t = text("[t][n_letter]")//since the above is ran through for each letter, the text just adds up back to the original word. - p++//for each letter p is increased to find where the next letter will be. - return copytext(sanitize(t),1,MAX_MESSAGE_LEN) + newletter = "[newletter]-[newletter]" + . += newletter + return sanitize(.) /proc/derpspeech(message, stuttering) message = replacetext(message, " am ", " ") @@ -183,52 +186,42 @@ return message -/proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 for p will cause letters to be replaced instead of added - /* Turn text into complete gibberish! */ - var/returntext = "" - for(var/i = 1, i <= length(t), i++) - - var/letter = copytext(t, i, i+1) - if(prob(50)) - if(p >= 70) +/proc/Gibberish(text, replace_characters = FALSE, chance = 50) + text = html_decode(text) + . = "" + var/rawchar = "" + var/letter = "" + var/lentext = length(text) + for(var/i = 1, i <= lentext, i += length(rawchar)) + rawchar = letter = text[i] + if(prob(chance)) + if(replace_characters) letter = "" + for(var/j in 1 to rand(0, 2)) + letter += pick("#", "@", "*", "&", "%", "$", "/", "<", ">", ";", "*", "*", "*", "*", "*", "*", "*") + . += letter + return sanitize(.) - for(var/j = 1, j <= rand(0, 2), j++) - letter += pick("#","@","*","&","%","$","/", "<", ">", ";","*","*","*","*","*","*","*") - - returntext += letter - - return returntext - - -/proc/ninjaspeak(n) //NINJACODE /* The difference with stutter is that this proc can stutter more than 1 letter The issue here is that anything that does not have a space is treated as one word (in many instances). For instance, "LOOKING," is a word, including the comma. It's fairly easy to fix if dealing with single letters but not so much with compounds of letters./N */ - var/te = html_decode(n) - var/t = "" - n = length(n) - var/p = 1 - while(p <= n) - var/n_letter - var/n_mod = rand(1,4) - if(p+n_mod>n+1) - n_letter = copytext(te, p, n+1) - else - n_letter = copytext(te, p, p+n_mod) +/proc/ninjaspeak(phrase) //NINJACODE + . = "" + var/lentext = length_char(phrase) + var/rawchars = "" + var/letter = "" + for(var/i = 1, i <= lentext, i += length_char(rawchars)) + var/end = i + rand(1,4) + letter = rawchars = copytext_char(phrase, i, end > lentext ? 0 : end) if (prob(50)) if (prob(30)) - n_letter = text("[n_letter]-[n_letter]-[n_letter]") + letter = "[letter]-[letter]-[letter]" else - n_letter = text("[n_letter]-[n_letter]") - else - n_letter = text("[n_letter]") - t = text("[t][n_letter]") - p=p+n_mod - return copytext(sanitize(t),1,MAX_MESSAGE_LEN) - + letter = "[letter]-[letter]" + . += letter + return copytext_char(sanitize(.),1,MAX_MESSAGE_LEN) /proc/shake_camera(mob/M, duration, strength=1) if(!M || !M.client || duration < 1) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 41aaaac1c9..b11d1632c8 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -9,37 +9,36 @@ mob.dropItemToGround(mob.get_active_held_item()) return -/client/proc/Move_object(direct) +/client/proc/Move_object(direction) if(mob && mob.control_object) if(mob.control_object.density) - step(mob.control_object,direct) + step(mob.control_object,direction) if(!mob.control_object) return - mob.control_object.setDir(direct) + mob.control_object.setDir(direction) else - mob.control_object.forceMove(get_step(mob.control_object,direct)) + mob.control_object.forceMove(get_step(mob.control_object,direction)) #define MOVEMENT_DELAY_BUFFER 0.75 #define MOVEMENT_DELAY_BUFFER_DELTA 1.25 -/client/Move(n, direct) +/client/Move(n, direction) if(world.time < move_delay) //do not move anything ahead of this check please return FALSE else - next_move_dir_add = 0 - next_move_dir_sub = 0 + next_move_dir_add = next_move_dir_sub = NONE var/old_move_delay = move_delay move_delay = world.time + world.tick_lag //this is here because Move() can now be called mutiple times per tick - if(!mob || !mob.loc) - return FALSE - if(!n || !direct) + if(!n || !direction || !mob?.loc) return FALSE + //GET RID OF THIS SOON AS MOBILITY FLAGS IS DONE if(mob.notransform) - return FALSE //This is sota the goto stop mobs from moving var + return FALSE + if(mob.control_object) - return Move_object(direct) + return Move_object(direction) if(!isliving(mob)) - return mob.Move(n, direct) + return mob.Move(n, direction) if(mob.stat == DEAD) mob.ghostize() return FALSE @@ -48,29 +47,29 @@ var/mob/living/L = mob //Already checked for isliving earlier if(L.incorporeal_move) //Move though walls - Process_Incorpmove(direct) + Process_Incorpmove(direction) return FALSE if(mob.remote_control) //we're controlling something, our movement is relayed to it - return mob.remote_control.relaymove(mob, direct) + return mob.remote_control.relaymove(mob, direction) if(isAI(mob)) - return AIMove(n,direct,mob) + return AIMove(n,direction,mob) if(Process_Grab()) //are we restrained by someone's grip? return if(mob.buckled) //if we're buckled to something, tell it we moved. - return mob.buckled.relaymove(mob, direct) + return mob.buckled.relaymove(mob, direction) if(!mob.canmove) return FALSE if(isobj(mob.loc) || ismob(mob.loc)) //Inside an object, tell it we moved var/atom/O = mob.loc - return O.relaymove(mob, direct) + return O.relaymove(mob, direction) - if(!mob.Process_Spacemove(direct)) + if(!mob.Process_Spacemove(direction)) return FALSE //We are now going to move var/add_delay = mob.movement_delay() @@ -85,25 +84,24 @@ if(L.confused > 40) newdir = pick(GLOB.alldirs) else if(prob(L.confused * 1.5)) - newdir = angle2dir(dir2angle(direct) + pick(90, -90)) + newdir = angle2dir(dir2angle(direction) + pick(90, -90)) else if(prob(L.confused * 3)) - newdir = angle2dir(dir2angle(direct) + pick(45, -45)) + newdir = angle2dir(dir2angle(direction) + pick(45, -45)) if(newdir) - direct = newdir - n = get_step(L, direct) + direction = newdir + n = get_step(L, direction) . = ..() - if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully + if((direction & (direction - 1)) && mob.loc == n) //moved diagonally successfully add_delay *= 2 - if(mob.loc != oldloc) - move_delay += add_delay + move_delay += add_delay if(.) // If mob is null here, we deserve the runtime if(mob.throwing) mob.throwing.finalize(FALSE) for(var/obj/O in mob.user_movement_hooks) - O.intercept_user_move(direct, mob, n, oldloc) + O.intercept_user_move(direction, mob, n, oldloc) var/atom/movable/P = mob.pulling if(P && !ismob(P) && P.density) @@ -127,22 +125,22 @@ ///Process_Incorpmove ///Called by client/Move() ///Allows mobs to run though walls -/client/proc/Process_Incorpmove(direct) +/client/proc/Process_Incorpmove(direction) var/turf/mobloc = get_turf(mob) if(!isliving(mob)) return var/mob/living/L = mob switch(L.incorporeal_move) if(INCORPOREAL_MOVE_BASIC) - var/T = get_step(L,direct) + var/T = get_step(L,direction) if(T) L.forceMove(T) - L.setDir(direct) + L.setDir(direction) if(INCORPOREAL_MOVE_SHADOW) if(prob(50)) var/locx var/locy - switch(direct) + switch(direction) if(NORTH) locx = mobloc.x locy = (mobloc.y+2) @@ -176,12 +174,12 @@ break else new /obj/effect/temp_visual/dir_setting/ninja/shadow(mobloc, L.dir) - var/T = get_step(L,direct) + var/T = get_step(L,direction) if(T) L.forceMove(T) - L.setDir(direct) + L.setDir(direction) if(INCORPOREAL_MOVE_JAUNT) //Incorporeal move, but blocked by holy-watered tiles and salt piles. - var/turf/open/floor/stepTurf = get_step(L, direct) + var/turf/open/floor/stepTurf = get_step(L, direction) if(stepTurf) for(var/obj/effect/decal/cleanable/salt/S in stepTurf) to_chat(L, "[S] bars your passage!") @@ -198,7 +196,7 @@ return L.forceMove(stepTurf) - L.setDir(direct) + L.setDir(direction) return TRUE diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 8f7983bb83..f348829b71 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -12,7 +12,7 @@ var/customsayverb = findtext(input, "*") if(customsayverb && message_mode != MODE_WHISPER_CRIT) message_mode = MODE_CUSTOM_SAY - return lowertext(copytext(input, 1, customsayverb)) + return lowertext(copytext_char(input, 1, customsayverb)) else return ..() @@ -35,7 +35,7 @@ to_chat(usr, "Speech is currently admin-disabled.") return - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) usr.emote("me",1,message,TRUE) @@ -83,9 +83,9 @@ deadchat_broadcast(rendered, follow_target = src, speaker_key = key) /mob/proc/check_emote(message) - if(copytext(message, 1, 2) == "*") - emote(copytext(message, 2), intentional = TRUE) - return 1 + if(message[1] == "*") + emote(copytext(message, length(message[1]) + 1), intentional = TRUE) + return TRUE /mob/proc/hivecheck() return 0 @@ -94,11 +94,11 @@ return LINGHIVE_NONE /mob/proc/get_message_mode(message) - var/key = copytext(message, 1, 2) + var/key = message[1] if(key == "#") return MODE_WHISPER else if(key == ";") return MODE_HEADSET - else if(length(message) > 2 && (key in GLOB.department_radio_prefixes)) - var/key_symbol = lowertext(copytext(message, 2, 3)) + else if((length(message) > (length(key) + 1)) && (key in GLOB.department_radio_prefixes)) + var/key_symbol = lowertext(message[length(key) + 1]) return GLOB.department_radio_keys[key_symbol] diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index a130152b4c..38438b97ce 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -9,25 +9,19 @@ set src in usr if(usr != src) to_chat(usr, "No.") - var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(flavor_text), MAX_MESSAGE_LEN*2, TRUE) + var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(flavor_text), MAX_MESSAGE_LEN, TRUE) - if(!isnull(msg)) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) - - flavor_text = msg + if(msg) + flavor_text = html_encode(msg) /mob/proc/update_flavor_text_2() set src in usr if(usr != src) to_chat(usr, "No.") - var/msg = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", html_decode(flavor_text_2), MAX_MESSAGE_LEN*2, TRUE) + var/msg = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", html_decode(flavor_text_2), MAX_MESSAGE_LEN, TRUE) - if(!isnull(msg)) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) - - flavor_text_2 = msg + if(msg) + flavor_text_2 = html_encode(msg) /mob/proc/warn_flavor_changed() @@ -39,19 +33,19 @@ if(flavor_text && flavor_text != "") // We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown. var/msg = html_decode(replacetext(flavor_text, "\n", " ")) - if(length(msg) <= 40) + if(length_char(msg) <= 40) return "[html_encode(msg)]" else - return "[html_encode(copytext(msg, 1, 37))]... More..." + return "[html_encode(copytext_char(msg, 1, 37))]... More..." /mob/proc/print_flavor_text_2() if(flavor_text && flavor_text != "") // We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown. var/msg = html_decode(replacetext(flavor_text_2, "\n", " ")) - if(length(msg) <= 40) + if(length_char(msg) <= 40) return "[html_encode(msg)]" else - return "[html_encode(copytext(msg, 1, 37))]... More..." + return "[html_encode(copytext_char(msg, 1, 37))]... More..." /mob/proc/get_top_level_mob() @@ -80,17 +74,10 @@ proc/get_top_level_mob(var/mob/S) /datum/emote/living/subtle/proc/check_invalid(mob/user, input) - . = TRUE - if(copytext(input,1,5) == "says") + if(stop_bad_mime.Find(input, 1, 1)) to_chat(user, "Invalid emote.") - else if(copytext(input,1,9) == "exclaims") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,6) == "yells") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,5) == "asks") - to_chat(user, "Invalid emote.") - else - . = FALSE + return TRUE + return FALSE /datum/emote/living/subtle/run_emote(mob/user, params, type_override = null) if(jobban_isbanned(user, "emote")) @@ -100,7 +87,7 @@ proc/get_top_level_mob(var/mob/S) to_chat(user, "You cannot send IC messages (muted).") return FALSE else if(!params) - var/subtle_emote = copytext(sanitize(input("Choose an emote to display.") as message|null), 1, MAX_MESSAGE_LEN) + var/subtle_emote = stripped_multiline_input("Choose an emote to display.", "Subtle", null, MAX_MESSAGE_LEN) if(subtle_emote && !check_invalid(user, subtle_emote)) var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable") switch(type) @@ -151,17 +138,10 @@ proc/get_top_level_mob(var/mob/S) /datum/emote/living/subtler/proc/check_invalid(mob/user, input) - . = TRUE - if(copytext(input,1,5) == "says") + if(stop_bad_mime.Find(input, 1, 1)) to_chat(user, "Invalid emote.") - else if(copytext(input,1,9) == "exclaims") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,6) == "yells") - to_chat(user, "Invalid emote.") - else if(copytext(input,1,5) == "asks") - to_chat(user, "Invalid emote.") - else - . = FALSE + return TRUE + return FALSE /datum/emote/living/subtler/run_emote(mob/user, params, type_override = null) if(jobban_isbanned(user, "emote")) @@ -171,7 +151,7 @@ proc/get_top_level_mob(var/mob/S) to_chat(user, "You cannot send IC messages (muted).") return FALSE else if(!params) - var/subtle_emote = copytext(sanitize(input("Choose an emote to display.") as message|null), 1, MAX_MESSAGE_LEN) + var/subtle_emote = stripped_multiline_input(user, "Choose an emote to display.", "Subtler" , null, MAX_MESSAGE_LEN) if(subtle_emote && !check_invalid(user, subtle_emote)) var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable") switch(type) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 4af6b4d644..ffe82ec1bd 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -42,8 +42,8 @@ // hash the original name? if(tr_flags & TR_HASHNAME) - O.name = "monkey ([copytext(md5(real_name), 2, 6)])" - O.real_name = "monkey ([copytext(md5(real_name), 2, 6)])" + O.name = "monkey ([copytext_char(md5(real_name), 2, 6)])" + O.real_name = "monkey ([copytext_char(md5(real_name), 2, 6)])" //handle DNA and other attributes dna.transfer_identity(O) @@ -202,7 +202,7 @@ dna.transfer_identity(O) O.updateappearance(mutcolor_update=1) - if(cmptext("monkey",copytext(O.dna.real_name,1,7))) + if(findtext(O.dna.real_name, "monkey", 1, 7)) //7 == length("monkey") + 1 O.real_name = random_unique_name(O.gender) O.dna.generate_unique_enzymes(O) else diff --git a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm index 7c4058ef39..eeb5212aeb 100644 --- a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm +++ b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm @@ -1,3 +1,5 @@ +#define MAX_CHANNELS 1000 + /datum/ntnet_conversation var/id = null var/title = "Untitled Conversation" @@ -8,7 +10,11 @@ var/static/ntnrc_uid = 0 /datum/ntnet_conversation/New() - id = ntnrc_uid++ + id = ntnrc_uid + 1 + if(id > MAX_CHANNELS) + qdel(src) + return + ntnrc_uid = id if(SSnetworks.station_network) SSnetworks.station_network.chat_channels.Add(src) ..() @@ -19,12 +25,12 @@ return ..() /datum/ntnet_conversation/proc/add_message(message, username) - message = "[STATION_TIME_TIMESTAMP("hh:mm:ss")] [username]: [message]" + message = "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)] [username]: [message]" messages.Add(message) trim_message_list() /datum/ntnet_conversation/proc/add_status_message(message) - messages.Add("[STATION_TIME_TIMESTAMP("hh:mm:ss")] -!- [message]") + messages.Add("[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)] -!- [message]") trim_message_list() /datum/ntnet_conversation/proc/trim_message_list() @@ -66,3 +72,5 @@ add_status_message("[client.username] has changed channel title from [title] to [newtitle]") title = newtitle + +#undef MAX_CHANNELS \ No newline at end of file diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 79c74de2eb..551b77dec3 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -316,7 +316,7 @@ data["PC_batteryicon"] = "batt_20.gif" else data["PC_batteryicon"] = "batt_5.gif" - data["PC_batterypercent"] = "[round(battery_module.battery.percent())] %" + data["PC_batterypercent"] = "[round(battery_module.battery.percent())]%" data["PC_showbatteryicon"] = 1 else data["PC_batteryicon"] = "batt_5.gif" @@ -348,7 +348,7 @@ data["PC_programheaders"] = program_headers - data["PC_stationtime"] = STATION_TIME_TIMESTAMP("hh:mm:ss") + data["PC_stationtime"] = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time) data["PC_hasheader"] = 1 data["PC_showexitprogram"] = active_program ? 1 : 0 // Hides "Exit Program" button on mainscreen return data diff --git a/code/modules/modular_computers/computers/item/computer_damage.dm b/code/modules/modular_computers/computers/item/computer_damage.dm index 001cf3aa65..6664b449bd 100644 --- a/code/modules/modular_computers/computers/item/computer_damage.dm +++ b/code/modules/modular_computers/computers/item/computer_damage.dm @@ -23,6 +23,8 @@ new /obj/item/stack/sheet/metal(newloc, round(steel_sheet_cost/2)) for(var/C in all_components) var/obj/item/computer_hardware/H = all_components[C] + if(QDELETED(H)) + return uninstall_component(H) H.forceMove(newloc) if(prob(25)) diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index df3000d0fc..3e67a14874 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -38,7 +38,8 @@ var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) assets.send(user) - ui = new(user, src, ui_key, "ntos_main", "NTOS Main menu", 400, 500, master_ui, state) + ui = new(user, src, ui_key, "ntos_main", "NtOS Main menu", 400, 500, master_ui, state) + ui.set_style("ntos") ui.open() ui.set_autoupdate(state = 1) @@ -68,10 +69,10 @@ switch(action) if("PC_exit") kill_program() - return 1 + return TRUE if("PC_shutdown") shutdown_computer() - return 1 + return TRUE if("PC_minimize") var/mob/user = usr if(!active_program || !all_components[MC_CPU]) @@ -156,6 +157,7 @@ comp_light_color = new_color light_color = new_color update_light() + return TRUE else return diff --git a/code/modules/modular_computers/computers/item/laptop_presets.dm b/code/modules/modular_computers/computers/item/laptop_presets.dm index 102397037b..e50392e3b3 100644 --- a/code/modules/modular_computers/computers/item/laptop_presets.dm +++ b/code/modules/modular_computers/computers/item/laptop_presets.dm @@ -13,11 +13,11 @@ -/obj/item/modular_computer/laptop/preset/civillian +/obj/item/modular_computer/laptop/preset/civilian desc = "A low-end laptop often used for personal recreation." -/obj/item/modular_computer/laptop/preset/civillian/install_programs() +/obj/item/modular_computer/laptop/preset/civilian/install_programs() var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] hard_drive.store_file(new/datum/computer_file/program/chatclient()) - hard_drive.store_file(new/datum/computer_file/program/nttransfer()) \ No newline at end of file + hard_drive.store_file(new/datum/computer_file/program/nttransfer()) diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index f74b53ddd2..f661f0ec10 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -16,9 +16,9 @@ var/network_destination = null // Optional string that describes what NTNet server/system this program connects to. Used in default logging. var/available_on_ntnet = 1 // Whether the program can be downloaded from NTNet. Set to 0 to disable. var/available_on_syndinet = 0 // Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable. - var/tgui_id // ID of TG UI interface - var/ui_style // ID of custom TG UI style (optional) - var/ui_x = 575 // Default size of TG UI window, in pixels + var/tgui_id // ID of TGUI interface + var/ui_style // ID of custom TGUI style (optional) + var/ui_x = 575 // Default size of TGUI window, in pixels var/ui_y = 700 var/ui_header = null // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /icons/program_icons. Be careful not to use too large images! @@ -71,7 +71,7 @@ // Check if the user can run program. Only humans can operate computer. Automatically called in run_program() // User has to wear their ID for ID Scan to work. // Can also be called manually, with optional parameter being access_to_check to scan the user's ID -/datum/computer_file/program/proc/can_run(mob/user, loud = 0, access_to_check, transfer = 0) +/datum/computer_file/program/proc/can_run(mob/user, loud = FALSE, access_to_check, transfer = FALSE) // Defaults to required_access if(!access_to_check) if(transfer && transfer_access) @@ -79,16 +79,16 @@ else access_to_check = required_access if(!access_to_check) // No required_access, allow it. - return 1 + return TRUE if(!transfer && computer && (computer.obj_flags & EMAGGED)) //emags can bypass the execution locks but not the download ones. - return 1 + return TRUE if(IsAdminGhost(user)) - return 1 + return TRUE if(issilicon(user)) - return 1 + return TRUE if(ishuman(user)) var/obj/item/card/id/D @@ -101,17 +101,17 @@ if(!I && !D) if(loud) to_chat(user, "\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.") - return 0 + return FALSE if(I) if(access_to_check in I.GetAccess()) - return 1 + return TRUE else if(D) if(access_to_check in D.GetAccess()) - return 1 + return TRUE if(loud) to_chat(user, "\The [computer] flashes an \"Access Denied\" warning.") - return 0 + return FALSE // This attempts to retrieve header data for UIs. If implementing completely new device of different type than existing ones // always include the device here in this proc. This proc basically relays the request to whatever is running the program. @@ -127,15 +127,15 @@ if(requires_ntnet && network_destination) generate_network_log("Connection opened to [network_destination].") program_state = PROGRAM_STATE_ACTIVE - return 1 - return 0 + return TRUE + return FALSE // Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client. /datum/computer_file/program/proc/kill_program(forced = FALSE) program_state = PROGRAM_STATE_KILLED if(network_destination) generate_network_log("Connection to [network_destination] closed.") - return 1 + return TRUE /datum/computer_file/program/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) @@ -158,17 +158,17 @@ // ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE. /datum/computer_file/program/ui_act(action,params,datum/tgui/ui) if(..()) - return 1 + return TRUE if(computer) switch(action) if("PC_exit") computer.kill_program() ui.close() - return 1 + return TRUE if("PC_shutdown") computer.shutdown_computer() ui.close() - return 1 + return TRUE if("PC_minimize") var/mob/user = usr if(!computer.active_program || !computer.all_components[MC_CPU]) diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm index 243ae89d69..bf58b120f2 100644 --- a/code/modules/modular_computers/file_system/programs/card.dm +++ b/code/modules/modular_computers/file_system/programs/card.dm @@ -159,7 +159,7 @@
    [GLOB.data_core ? GLOB.data_core.get_manifest(0) : ""] "} - if(!printer.print_text(contents,text("crew manifest ([])", STATION_TIME_TIMESTAMP("hh:mm:ss")))) + if(!printer.print_text(contents,text("crew manifest ([])", STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)))) to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") return else diff --git a/code/modules/modular_computers/file_system/programs/configurator.dm b/code/modules/modular_computers/file_system/programs/configurator.dm index 8ceb1a4dec..2d60323d10 100644 --- a/code/modules/modular_computers/file_system/programs/configurator.dm +++ b/code/modules/modular_computers/file_system/programs/configurator.dm @@ -10,6 +10,8 @@ unsendable = 1 undeletable = 1 size = 4 + ui_x = 420 + ui_y = 630 available_on_ntnet = 0 requires_ntnet = 0 tgui_id = "ntos_configuration" diff --git a/code/modules/modular_computers/file_system/programs/file_browser.dm b/code/modules/modular_computers/file_system/programs/file_browser.dm index 2de2d64754..cba82eac18 100644 --- a/code/modules/modular_computers/file_system/programs/file_browser.dm +++ b/code/modules/modular_computers/file_system/programs/file_browser.dm @@ -145,7 +145,7 @@ t = replacetext(t, "\[/i\]", "
    ") t = replacetext(t, "\[u\]", "") t = replacetext(t, "\[/u\]", "") - t = replacetext(t, "\[time\]", "[STATION_TIME_TIMESTAMP("hh:mm:ss")]") + t = replacetext(t, "\[time\]", "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]") t = replacetext(t, "\[date\]", "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer]") t = replacetext(t, "\[large\]", "") t = replacetext(t, "\[/large\]", "") diff --git a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm index 29a1df9ebe..d8b3f96f42 100644 --- a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm +++ b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm @@ -10,215 +10,225 @@ ui_header = "ntnrc_idle.gif" available_on_ntnet = 1 tgui_id = "ntos_net_chat" + ui_x = 900 + ui_y = 675 - var/last_message = null // Used to generate the toolbar icon + var/last_message // Used to generate the toolbar icon var/username - var/datum/ntnet_conversation/channel = null - var/operator_mode = 0 // Channel operator mode - var/netadmin_mode = 0 // Administrator mode (invisible to other users + bypasses passwords) + var/active_channel + var/list/channel_history = list() + var/operator_mode = FALSE // Channel operator mode + var/netadmin_mode = FALSE // Administrator mode (invisible to other users + bypasses passwords) /datum/computer_file/program/chatclient/New() username = "DefaultUser[rand(100, 999)]" /datum/computer_file/program/chatclient/ui_act(action, params) if(..()) - return 1 + return + var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel) + var/authed = FALSE + if(channel && ((channel.operator == src) || netadmin_mode)) + authed = TRUE switch(action) if("PRG_speak") - . = 1 - if(!channel) - return 1 - var/mob/living/user = usr - var/message = reject_bad_text(input(user, "Enter message or leave blank to cancel: ")) - if(!message || !channel) + if(!channel || isnull(active_channel)) return + var/message = reject_bad_text(params["message"]) + if(!message) + return + if(channel.password && !(src in channel.clients)) + if(channel.password == message) + channel.add_client(src) + return TRUE + channel.add_message(message, username) + var/mob/living/user = usr user.log_talk(message, LOG_CHAT, tag="as [username] to channel [channel.title]") - + return TRUE if("PRG_joinchannel") - . = 1 - var/datum/ntnet_conversation/C - for(var/datum/ntnet_conversation/chan in SSnetworks.station_network.chat_channels) - if(chan.id == text2num(params["id"])) - C = chan - break - - if(!C) - return 1 + var/new_target = text2num(params["id"]) + if(isnull(new_target) || new_target == active_channel) + return if(netadmin_mode) - channel = C // Bypasses normal leave/join and passwords. Technically makes the user invisible to others. - return 1 + active_channel = new_target // Bypasses normal leave/join and passwords. Technically makes the user invisible to others. + return TRUE - if(C.password) - var/mob/living/user = usr - var/password = reject_bad_text(input(user,"Access Denied. Enter password:")) - if(C && (password == C.password)) - C.add_client(src) - channel = C - return 1 - C.add_client(src) - channel = C + active_channel = new_target + channel = SSnetworks.station_network.get_chat_channel_by_id(new_target) + if(!(src in channel.clients) && !channel.password) + channel.add_client(src) + return TRUE if("PRG_leavechannel") - . = 1 if(channel) channel.remove_client(src) - channel = null + active_channel = null + return TRUE if("PRG_newchannel") - . = 1 - var/mob/living/user = usr - var/channel_title = reject_bad_text(input(user,"Enter channel name or leave blank to cancel:")) + var/channel_title = reject_bad_text(params["new_channel_name"]) if(!channel_title) return - var/datum/ntnet_conversation/C = new/datum/ntnet_conversation() + var/datum/ntnet_conversation/C = new /datum/ntnet_conversation() C.add_client(src) C.operator = src - channel = C C.title = channel_title + active_channel = C.id + return TRUE if("PRG_toggleadmin") - . = 1 if(netadmin_mode) - netadmin_mode = 0 + netadmin_mode = FALSE if(channel) channel.remove_client(src) // We shouldn't be in channel's user list, but just in case... - channel = null - return 1 + return TRUE var/mob/living/user = usr - if(can_run(usr, 1, ACCESS_NETWORK)) - if(channel) - var/response = alert(user, "Really engage admin-mode? You will be disconnected from your current channel!", "NTNRC Admin mode", "Yes", "No") - if(response == "Yes") - if(channel) - channel.remove_client(src) - channel = null - else - return - netadmin_mode = 1 + if(can_run(user, TRUE, ACCESS_NETWORK)) + for(var/C in SSnetworks.station_network.chat_channels) + var/datum/ntnet_conversation/chan = C + chan.remove_client(src) + netadmin_mode = TRUE + return TRUE if("PRG_changename") - . = 1 - var/mob/living/user = usr - var/newname = sanitize(input(user,"Enter new nickname or leave blank to cancel:")) + var/newname = sanitize(params["new_name"]) if(!newname) - return 1 - if(channel) - channel.add_status_message("[username] is now known as [newname].") + return + for(var/C in SSnetworks.station_network.chat_channels) + var/datum/ntnet_conversation/chan = C + if(src in chan.clients) + chan.add_status_message("[username] is now known as [newname].") username = newname - + return TRUE if("PRG_savelog") - . = 1 if(!channel) return - var/mob/living/user = usr - var/logname = stripped_input(user,"Enter desired logfile name (.log) or leave blank to cancel:") - if(!logname || !channel) - return 1 - var/datum/computer_file/data/logfile = new/datum/computer_file/data/logfile() + var/logname = stripped_input(params["log_name"]) + if(!logname) + return + var/datum/computer_file/data/logfile = new /datum/computer_file/data/logfile() // Now we will generate HTML-compliant file that can actually be viewed/printed. logfile.filename = logname logfile.stored_data = "\[b\]Logfile dump from NTNRC channel [channel.title]\[/b\]\[BR\]" for(var/logstring in channel.messages) - logfile.stored_data += "[logstring]\[BR\]" - logfile.stored_data += "\[b\]Logfile dump completed.\[/b\]" + logfile.stored_data = "[logfile.stored_data][logstring]\[BR\]" + logfile.stored_data = "[logfile.stored_data]\[b\]Logfile dump completed.\[/b\]" logfile.calculate_size() var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] if(!computer || !hard_drive || !hard_drive.store_file(logfile)) if(!computer) // This program shouldn't even be runnable without computer. CRASH("Var computer is null!") - return 1 if(!hard_drive) - computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.") + computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.") else // In 99.9% cases this will mean our HDD is full - computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.") + computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.") + return TRUE if("PRG_renamechannel") - . = 1 - if(!operator_mode || !channel) - return 1 - var/mob/living/user = usr - var/newname = reject_bad_text(input(user, "Enter new channel name or leave blank to cancel:")) + if(!authed) + return + var/newname = reject_bad_text(params["new_name"]) if(!newname || !channel) return channel.add_status_message("Channel renamed from [channel.title] to [newname] by operator.") channel.title = newname + return TRUE if("PRG_deletechannel") - . = 1 - if(channel && ((channel.operator == src) || netadmin_mode)) + if(authed) qdel(channel) - channel = null + active_channel = null + return TRUE if("PRG_setpassword") - . = 1 - if(!channel || ((channel.operator != src) && !netadmin_mode)) - return 1 + if(!authed) + return - var/mob/living/user = usr - var/newpassword = sanitize(input(user, "Enter new password for this channel. Leave blank to cancel, enter 'nopassword' to remove password completely:")) - if(!channel || !newpassword || ((channel.operator != src) && !netadmin_mode)) - return 1 + var/new_password = sanitize(params["new_password"]) + if(!authed) + return - if(newpassword == "nopassword") - channel.password = "" - else - channel.password = newpassword + channel.password = new_password + return TRUE /datum/computer_file/program/chatclient/process_tick() - ..() + . = ..() + var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel) if(program_state != PROGRAM_STATE_KILLED) ui_header = "ntnrc_idle.gif" if(channel) // Remember the last message. If there is no message in the channel remember null. - last_message = channel.messages.len ? channel.messages[channel.messages.len - 1] : null + last_message = length(channel.messages) ? channel.messages[length(channel.messages)] : null else last_message = null - return 1 - if(channel && channel.messages && channel.messages.len) - ui_header = last_message == channel.messages[channel.messages.len - 1] ? "ntnrc_idle.gif" : "ntnrc_new.gif" + return TRUE + if(channel?.messages?.len) + ui_header = last_message == channel.messages[length(channel.messages)] ? "ntnrc_idle.gif" : "ntnrc_new.gif" else ui_header = "ntnrc_idle.gif" /datum/computer_file/program/chatclient/kill_program(forced = FALSE) - if(channel) + for(var/C in SSnetworks.station_network.chat_channels) + var/datum/ntnet_conversation/channel = C channel.remove_client(src) - channel = null ..() +/datum/computer_file/program/chatclient/ui_static_data(mob/user) + var/list/data = list() + data["can_admin"] = can_run(user, FALSE, ACCESS_NETWORK) + return data + /datum/computer_file/program/chatclient/ui_data(mob/user) if(!SSnetworks.station_network || !SSnetworks.station_network.chat_channels) - return + return list() var/list/data = list() data = get_header_data() + var/list/all_channels = list() + for(var/C in SSnetworks.station_network.chat_channels) + var/datum/ntnet_conversation/conv = C + if(conv && conv.title) + all_channels.Add(list(list( + "chan" = conv.title, + "id" = conv.id + ))) + data["all_channels"] = all_channels + data["active_channel"] = active_channel + data["username"] = username data["adminmode"] = netadmin_mode + var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel) if(channel) data["title"] = channel.title - var/list/messages[0] - for(var/M in channel.messages) - messages.Add(list(list( - "msg" = M - ))) - data["messages"] = messages - var/list/clients[0] + var/authed = FALSE + if(!channel.password) + authed = TRUE + if(netadmin_mode) + authed = TRUE + var/list/clients = list() for(var/C in channel.clients) + if(C == src) + authed = TRUE var/datum/computer_file/program/chatclient/cl = C clients.Add(list(list( "name" = cl.username ))) - data["clients"] = clients - operator_mode = (channel.operator == src) ? 1 : 0 - data["is_operator"] = operator_mode || netadmin_mode - - else // Channel selection screen - var/list/all_channels[0] - for(var/C in SSnetworks.station_network.chat_channels) - var/datum/ntnet_conversation/conv = C - if(conv && conv.title) - all_channels.Add(list(list( - "chan" = conv.title, - "id" = conv.id + data["authed"] = authed + //no fishing for ui data allowed + if(authed) + data["clients"] = clients + var/list/messages = list() + for(var/M in channel.messages) + messages.Add(list(list( + "msg" = M ))) - data["all_channels"] = all_channels + data["messages"] = messages + data["is_operator"] = (channel.operator == src) || netadmin_mode + else + data["clients"] = list() + data["messages"] = list() + else + data["clients"] = list() + data["authed"] = FALSE + data["messages"] = list() - return data \ No newline at end of file + return data diff --git a/code/modules/modular_computers/file_system/programs/powermonitor.dm b/code/modules/modular_computers/file_system/programs/powermonitor.dm index 0439438cf0..f7c734667b 100644 --- a/code/modules/modular_computers/file_system/programs/powermonitor.dm +++ b/code/modules/modular_computers/file_system/programs/powermonitor.dm @@ -12,8 +12,9 @@ network_destination = "power monitoring system" size = 9 tgui_id = "ntos_power_monitor" - ui_x = 1200 - ui_y = 1000 + ui_style = "ntos" + ui_x = 550 + ui_y = 700 var/has_alert = 0 var/obj/structure/cable/attached_wire diff --git a/code/modules/modular_computers/file_system/programs/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/sm_monitor.dm index e7dd42a797..dbee59bb3e 100644 --- a/code/modules/modular_computers/file_system/programs/sm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/sm_monitor.dm @@ -9,8 +9,9 @@ network_destination = "supermatter monitoring system" size = 5 tgui_id = "ntos_supermatter_monitor" + ui_style = "ntos" ui_x = 600 - ui_y = 400 + ui_y = 350 var/last_status = SUPERMATTER_INACTIVE var/list/supermatters var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal. diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index 6e4f80458a..2bed456c41 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -27,6 +27,9 @@ var/dev_printer = 0 // 0: None, 1: Standard var/dev_card = 0 // 0: None, 1: Standard + ui_x = 500 + ui_y = 400 + // Removes all traces of old order and allows you to begin configuration from scratch. /obj/machinery/lapvend/proc/reset_order() state = 0 @@ -46,7 +49,7 @@ dev_card = 0 // Recalculates the price and optionally even fabricates the device. -/obj/machinery/lapvend/proc/fabricate_and_recalc_price(fabricate = 0) +/obj/machinery/lapvend/proc/fabricate_and_recalc_price(fabricate = FALSE) total_price = 0 if(devtype == 1) // Laptop, generally cheaper to make it accessible for most station roles var/obj/item/computer_hardware/battery/battery_module = null @@ -160,7 +163,7 @@ if(fabricate) fabricated_tablet.install_component(new/obj/item/computer_hardware/card_slot) return total_price - return 0 + return FALSE @@ -168,90 +171,106 @@ /obj/machinery/lapvend/ui_act(action, params) if(..()) - return 1 + return TRUE switch(action) if("pick_device") if(state) // We've already picked a device type - return 0 + return FALSE devtype = text2num(params["pick"]) state = 1 - fabricate_and_recalc_price(0) - return 1 + fabricate_and_recalc_price(FALSE) + return TRUE if("clean_order") reset_order() - return 1 + return TRUE if("purchase") try_purchase() - return 1 + return TRUE if((state != 1) && devtype) // Following IFs should only be usable when in the Select Loadout mode - return 0 + return FALSE switch(action) if("confirm_order") state = 2 // Wait for ID swipe for payment processing - fabricate_and_recalc_price(0) - return 1 + fabricate_and_recalc_price(FALSE) + return TRUE if("hw_cpu") dev_cpu = text2num(params["cpu"]) - fabricate_and_recalc_price(0) - return 1 + fabricate_and_recalc_price(FALSE) + return TRUE if("hw_battery") dev_battery = text2num(params["battery"]) - fabricate_and_recalc_price(0) - return 1 + fabricate_and_recalc_price(FALSE) + return TRUE if("hw_disk") dev_disk = text2num(params["disk"]) - fabricate_and_recalc_price(0) - return 1 + fabricate_and_recalc_price(FALSE) + return TRUE if("hw_netcard") dev_netcard = text2num(params["netcard"]) - fabricate_and_recalc_price(0) - return 1 + fabricate_and_recalc_price(FALSE) + return TRUE if("hw_tesla") dev_apc_recharger = text2num(params["tesla"]) - fabricate_and_recalc_price(0) - return 1 + fabricate_and_recalc_price(FALSE) + return TRUE if("hw_nanoprint") dev_printer = text2num(params["print"]) - fabricate_and_recalc_price(0) - return 1 + fabricate_and_recalc_price(FALSE) + return TRUE if("hw_card") dev_card = text2num(params["card"]) - fabricate_and_recalc_price(0) - return 1 - return 0 + fabricate_and_recalc_price(FALSE) + return TRUE + return FALSE /obj/machinery/lapvend/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) if(stat & (BROKEN | NOPOWER | MAINT)) if(ui) ui.close() - return 0 + return FALSE ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if (!ui) - ui = new(user, src, ui_key, "computer_fabricator", "Personal Computer Vendor", 500, 400, state = state) + ui = new(user, src, ui_key, "computer_fabricator", "Personal Computer Vendor", ui_x, ui_y, state = state) ui.open() - ui.set_autoupdate(state = 1) -/obj/machinery/lapvend/attackby(obj/item/I as obj, mob/user as mob) +/obj/machinery/lapvend/attackby(obj/item/I, mob/user) if(istype(I, /obj/item/stack/spacecash)) var/obj/item/stack/spacecash/c = I - if(!user.temporarilyRemoveItemFromInventory(c)) return credits += c.value - visible_message("[usr] inserts [c.value] credits into [src].") + visible_message("[user] inserts [c.value] credits into [src].") qdel(c) return + /*else if(istype(I, /obj/item/holochip)) + var/obj/item/holochip/HC = I + credits += HC.credits + visible_message("[user] inserts a $[HC.credits] holocredit chip into [src].") + qdel(HC) + return + else if(istype(I, /obj/item/card/id)) + if(state != 2) + return + var/obj/item/card/id/ID = I + var/datum/bank_account/account = ID.registered_account + var/target_credits = total_price - credits + if(!account.adjust_money(-target_credits)) + say("Insufficient money on card to purchase!") + return + credits += target_credits + say("$[target_credits] has been desposited from your account.") + return */ //Goonconomy when return ..() // Simplified payment processing, returns 1 on success. /obj/machinery/lapvend/proc/process_payment() if(total_price > credits) say("Insufficient credits.") - return 0 + return FALSE else - return 1 + return TRUE /obj/machinery/lapvend/ui_data(mob/user) @@ -287,5 +306,6 @@ credits -= total_price say("Enjoy your new product!") state = 3 - return 1 - return 0 \ No newline at end of file + addtimer(CALLBACK(src, .proc/reset_order), 100) + return TRUE + return FALSE \ No newline at end of file diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm index 97c41faf12..e6d53d914f 100644 --- a/code/modules/ninja/energy_katana.dm +++ b/code/modules/ninja/energy_katana.dm @@ -56,7 +56,7 @@ //If we hit the Ninja who owns this Katana, they catch it. //Works for if the Ninja throws it or it throws itself or someone tries //To throw it at the ninja -/obj/item/energy_katana/throw_impact(atom/hit_atom) +/obj/item/energy_katana/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(ishuman(hit_atom)) var/mob/living/carbon/human/H = hit_atom if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index aa1fd7dbfb..4120c81a78 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -126,7 +126,7 @@ continue var/obj/item/paper/P = new /obj/item/paper(src) P.info = "
    Security Record

    " - P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
    \nSex: [G.fields["sex"]]
    \nAge: [G.fields["age"]]
    \nFingerprint: [G.fields["fingerprint"]]
    \nPhysical Status: [G.fields["p_stat"]]
    \nMental Status: [G.fields["m_stat"]]
    " + P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
    \nGender: [G.fields["gender"]]
    \nAge: [G.fields["age"]]
    \nFingerprint: [G.fields["fingerprint"]]
    \nPhysical Status: [G.fields["p_stat"]]
    \nMental Status: [G.fields["m_stat"]]
    " P.info += "
    \n
    Security Data

    \nCriminal Status: [S.fields["criminal"]]
    \n
    \nMinor Crimes: [S.fields["mi_crim"]]
    \nDetails: [S.fields["mi_crim_d"]]
    \n
    \nMajor Crimes: [S.fields["ma_crim"]]
    \nDetails: [S.fields["ma_crim_d"]]
    \n
    \nImportant Notes:
    \n\t[S.fields["notes"]]
    \n
    \n
    Comments/Log

    " var/counter = 1 while(S.fields["com_[counter]"]) @@ -159,7 +159,7 @@ continue var/obj/item/paper/P = new /obj/item/paper(src) P.info = "
    Medical Record

    " - P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
    \nSex: [G.fields["sex"]]
    \nAge: [G.fields["age"]]
    \nFingerprint: [G.fields["fingerprint"]]
    \nPhysical Status: [G.fields["p_stat"]]
    \nMental Status: [G.fields["m_stat"]]
    " + P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
    \nGender: [G.fields["gender"]]
    \nAge: [G.fields["age"]]
    \nFingerprint: [G.fields["fingerprint"]]
    \nPhysical Status: [G.fields["p_stat"]]
    \nMental Status: [G.fields["m_stat"]]
    " P.info += "
    \n
    Medical Data

    \nBlood Type: [M.fields["blood_type"]]
    \nDNA: [M.fields["b_dna"]]
    \n
    \nMinor Disabilities: [M.fields["mi_dis"]]
    \nDetails: [M.fields["mi_dis_d"]]
    \n
    \nMajor Disabilities: [M.fields["ma_dis"]]
    \nDetails: [M.fields["ma_dis_d"]]
    \n
    \nAllergies: [M.fields["alg"]]
    \nDetails: [M.fields["alg_d"]]
    \n
    \nCurrent Diseases: [M.fields["cdi"]] (per disease info placed in log/comment section)
    \nDetails: [M.fields["cdi_d"]]
    \n
    \nImportant Notes:
    \n\t[M.fields["notes"]]
    \n
    \n
    Comments/Log

    " var/counter = 1 while(M.fields["com_[counter]"]) diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index 0a4bdf0c1c..4cd44af5ab 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -44,9 +44,11 @@ if(!user.is_literate()) to_chat(user, "You scribble illegibly on the cover of [src]!") return - var/n_name = copytext(sanitize(input(user, "What would you like to label the folder?", "Folder Labelling", null) as text), 1, MAX_NAME_LEN) + var/inputvalue = stripped_input(user, "What would you like to label the folder?", "Folder Labelling", "", MAX_NAME_LEN) + if(!inputvalue) + return if(user.canUseTopic(src, BE_CLOSE)) - name = "folder[(n_name ? " - '[n_name]'" : null)]" + name = "folder - '[inputvalue]'" /obj/item/folder/attack_self(mob/user) diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index 7c0edf3f0e..d054e5ff12 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -70,7 +70,7 @@ if(mode) to_chat(user, "You turn on [src].") //Now let them chose the text. - var/str = copytext(reject_bad_text(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN) + var/str = reject_bad_text(stripped_input(user, "Label text?", "Set label","", MAX_NAME_LEN)) if(!str || !length(str)) to_chat(user, "Invalid text!") return diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index c9b7fb7b57..20f4ab0c86 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -152,7 +152,10 @@ if(istart == 0) return //No field found with matching id - laststart = istart+1 + if(links) + laststart = istart + length(info_links[istart]) + else + laststart = istart + length(info[istart]) locid++ if(locid == id) var/iend = 1 diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index f3f7e45378..076d8b026a 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -34,7 +34,9 @@ /obj/item/paperplane/handle_atom_del(atom/A) if(A == internalPaper) + var/obj/item/paper/P = internalPaper internalPaper = null + P.moveToNullspace() //So we're not deleting it twice when deleting our contents. if(!QDELETED(src)) qdel(src) return ..() @@ -99,7 +101,7 @@ /obj/item/paperplane/throw_at(atom/target, range, speed, mob/thrower, spin=FALSE, diagonals_first = FALSE, datum/callback/callback) . = ..(target, range, speed, thrower, FALSE, diagonals_first, callback) -/obj/item/paperplane/throw_impact(atom/hit_atom) +/obj/item/paperplane/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(iscarbon(hit_atom)) var/mob/living/carbon/C = hit_atom if(!C.get_active_held_item() && !C.restrained()) diff --git a/code/modules/photography/_pictures.dm b/code/modules/photography/_pictures.dm index 62fc01efda..f667e18f47 100644 --- a/code/modules/photography/_pictures.dm +++ b/code/modules/photography/_pictures.dm @@ -111,9 +111,9 @@ if(data.len < 5) return null var/timestamp = data[2] - var/year = copytext(timestamp, 1, 5) - var/month = copytext(timestamp, 5, 7) - var/day = copytext(timestamp, 7, 9) + var/year = copytext_char(timestamp, 1, 5) + var/month = copytext_char(timestamp, 5, 7) + var/day = copytext_char(timestamp, 7, 9) var/round = data[4] . += "[year]/[month]/[day]/round-[round]" if("O") diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index 125219d809..140167c2f0 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -33,6 +33,8 @@ var/picture_size_y_min = 1 var/picture_size_x_max = 4 var/picture_size_y_max = 4 + var/can_customise = TRUE + var/default_picture_name /obj/item/camera/attack_self(mob/user) if(!disk) @@ -199,8 +201,10 @@ user.put_in_hands(p) pictures_left-- to_chat(user, "[pictures_left] photos left.") - var/customize = alert(user, "Do you want to customize the photo?", "Customization", "Yes", "No") - if(customize == "Yes") + var/customise = "No" + if(can_customise) + customise = alert(user, "Do you want to customize the photo?", "Customization", "Yes", "No") + if(customise == "Yes") var/name1 = stripped_input(user, "Set a name for this photo, or leave blank. 32 characters max.", "Name", max_length = 32) var/desc1 = stripped_input(user, "Set a description to add to photo, or leave blank. 128 characters max.", "Caption", max_length = 128) var/caption = stripped_input(user, "Set a caption for this photo, or leave blank. 256 characters max.", "Caption", max_length = 256) @@ -210,6 +214,10 @@ picture.picture_desc = "[desc1] - [picture.picture_desc]" if(caption) picture.caption = caption + else + if(default_picture_name) + picture.picture_name = default_picture_name + p.set_picture(picture, TRUE, TRUE) if(CONFIG_GET(flag/picture_logging_camera)) picture.log_to_file() \ No newline at end of file diff --git a/code/modules/photography/photos/photo.dm b/code/modules/photography/photos/photo.dm index b15aa308a3..d51f569738 100644 --- a/code/modules/photography/photos/photo.dm +++ b/code/modules/photography/photos/photo.dm @@ -55,9 +55,8 @@ if(!user.is_literate()) to_chat(user, "You scribble illegibly on [src]!") return - var/txt = sanitize(input(user, "What would you like to write on the back?", "Photo Writing", null) as text) - txt = copytext(txt, 1, 128) - if(user.canUseTopic(src, BE_CLOSE)) + var/txt = stripped_input(user, "What would you like to write on the back?", "Photo Writing", "", 128) + if(txt && user.canUseTopic(src, BE_CLOSE)) scribble = txt ..() @@ -85,8 +84,8 @@ set category = "Object" set src in usr - var/n_name = copytext(sanitize(input(usr, "What would you like to label the photo?", "Photo Labelling", null) as text), 1, MAX_NAME_LEN) + var/n_name = stripped_input(usr, "What would you like to label the photo?", "Photo Labelling", "", MAX_NAME_LEN) //loc.loc check is for making possible renaming photos in clipboards - if((loc == usr || loc.loc && loc.loc == usr) && usr.stat == CONSCIOUS && usr.canmove && !usr.restrained()) + if(n_name && (loc == usr || loc.loc && loc.loc == usr) && usr.stat == CONSCIOUS && usr.canmove && !usr.restrained()) name = "photo[(n_name ? text("- '[n_name]'") : null)]" add_fingerprint(usr) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index b7cbcdb9d8..6a674fa6b1 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -56,6 +56,8 @@ integrity_failure = 50 var/damage_deflection = 10 resistance_flags = FIRE_PROOF + armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 100, "bomb" = 30, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50) + req_access = list(ACCESS_ENGINE_EQUIP) interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON var/lon_range = 1.5 @@ -148,25 +150,48 @@ if(terminal) terminal.connect_to_network() -/obj/machinery/power/apc/New(turf/loc, var/ndir, var/building=0) - if (!req_access) - req_access = list(ACCESS_ENGINE_EQUIP) - if (!armor) - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 100, "bomb" = 30, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50) - ..() +/obj/machinery/power/apc/Initialize(mapload, ndir, building = FALSE) + . = ..() + tdir = ndir || dir + var/area/A = get_base_area(src) + if(!building) + has_electronics = APC_ELECTRONICS_SECURED + // is starting with a power cell installed, create it and set its charge level + if(cell_type) + cell = new cell_type + cell.charge = start_charge * cell.maxcharge / 100 // (convert percentage to actual value) + + //if area isn't specified use current + if(areastring) + area = get_area_instance_from_text(areastring) + if(!area) + area = A + stack_trace("Bad areastring path for [src], [src.areastring]") + else if(isarea(A) && !areastring) + area = A + if(auto_name) + name = "\improper [A.name] APC" + update_icon() + + make_terminal() + update_nightshift_auth_requirement() + + else + area = A + opened = APC_COVER_OPENED + operating = FALSE + name = "\improper [A.name] APC" + stat |= MAINT + update_icon() + addtimer(CALLBACK(src, .proc/update), 5) + GLOB.apcs_list += src wires = new /datum/wires/apc(src) // offset 24 pixels in direction of dir // this allows the APC to be embedded in a wall, yet still inside an area - if (building) - setDir(ndir) - src.tdir = dir // to fix Vars bug setDir(SOUTH) - if(auto_name) - name = "\improper [get_area(src)] APC" - switch(tdir) if(NORTH) pixel_y = 23 @@ -176,14 +201,6 @@ pixel_x = 24 if(WEST) pixel_x = -25 - if (building) - area = get_area(src) - opened = APC_COVER_OPENED - operating = FALSE - name = "[area.name] APC" - stat |= MAINT - src.update_icon() - addtimer(CALLBACK(src, .proc/update), 5) /obj/machinery/power/apc/Destroy() GLOB.apcs_list -= src @@ -217,33 +234,6 @@ terminal.setDir(tdir) terminal.master = src -/obj/machinery/power/apc/Initialize(mapload) - . = ..() - if(!mapload) - return - has_electronics = APC_ELECTRONICS_SECURED - // is starting with a power cell installed, create it and set its charge level - if(cell_type) - cell = new cell_type - cell.charge = start_charge * cell.maxcharge / 100 // (convert percentage to actual value) - - var/area/A = src.loc.loc - - //if area isn't specified use current - if(areastring) - src.area = get_area_instance_from_text(areastring) - if(!src.area) - src.area = A - stack_trace("Bad areastring path for [src], [src.areastring]") - else if(isarea(A) && src.areastring == null) - src.area = A - update_icon() - - make_terminal() - update_nightshift_auth_requirement() - - addtimer(CALLBACK(src, .proc/update), 5) - /obj/machinery/power/apc/examine(mob/user) . = ..() if(stat & BROKEN) @@ -848,7 +838,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "apc", name, 535, 515, master_ui, state) + ui = new(user, src, ui_key, "apc", name, 450, 460, master_ui, state) ui.open() /obj/machinery/power/apc/ui_data(mob/user) @@ -858,7 +848,7 @@ "failTime" = failure_timer, "isOperating" = operating, "externalPower" = main_status, - "powerCellStatus" = cell ? cell.percent() : null, + "powerCellStatus" = (cell?.percent() || null), "chargeMode" = chargemode, "chargingStatus" = charging, "totalLoad" = DisplayPower(lastused_total), @@ -1432,7 +1422,7 @@ return for(var/A in GLOB.ai_list) var/mob/living/silicon/ai/I = A - if(get_area(I) == area) + if(get_base_area(I) == area) return failure_timer = max(failure_timer, round(duration)) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index cee9a17ebf..3c807390a0 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -85,8 +85,8 @@ By design, d1 is the smallest direction and d2 is the highest if(isnull(_d1) || isnull(_d2)) // ensure d1 & d2 reflect the icon_state for entering and exiting cable var/dash = findtext(icon_state, "-") - d1 = text2num( copytext( icon_state, 1, dash ) ) - d2 = text2num( copytext( icon_state, dash+1 ) ) + d1 = text2num(copytext(icon_state, 1, dash)) + d2 = text2num(copytext(icon_state, dash + length(icon_state[dash]))) else d1 = _d1 d2 = _d2 diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 74f78825a8..d0d1e2b475 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -23,6 +23,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne desc = "A device which produces a graviton field when set up." icon = 'icons/obj/machines/gravity_generator.dmi' density = TRUE + move_resist = INFINITY use_power = NO_POWER_USE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF var/sprite_number = 0 @@ -78,7 +79,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne return main_part.attackby(I, user) /obj/machinery/gravity_generator/part/get_status() - return main_part.get_status() + return main_part?.get_status() /obj/machinery/gravity_generator/part/attack_hand(mob/user) return main_part.attack_hand(user) @@ -219,40 +220,32 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne return return ..() -/obj/machinery/gravity_generator/main/ui_interact(mob/user) - if(stat & BROKEN) - return - var/dat = "Gravity Generator Breaker: " - if(breaker) - dat += "ON OFF" - else - dat += "ON OFF " +/obj/machinery/gravity_generator/main/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "gravity_generator", name, 400, 200, master_ui, state) + ui.open() - dat += "
    Generator Status:
    " - if(charging_state != POWER_IDLE) - dat += "WARNING Radiation Detected.
    [charging_state == POWER_UP ? "Charging..." : "Discharging..."]" - else if(on) - dat += "Powered." - else - dat += "Unpowered." +/obj/machinery/gravity_generator/main/ui_data(mob/user) + var/list/data = list() - dat += "
    Gravity Charge: [charge_count]%
    " - - var/datum/browser/popup = new(user, "gravgen", name) - popup.set_content(dat) - popup.open() - - -/obj/machinery/gravity_generator/main/Topic(href, href_list) + data["breaker"] = breaker + data["charge_count"] = charge_count + data["charging_state"] = charging_state + data["on"] = on + data["operational"] = (stat & BROKEN) ? FALSE : TRUE + + return data +/obj/machinery/gravity_generator/main/ui_act(action, params) if(..()) return - - if(href_list["gentoggle"]) - breaker = !breaker - investigate_log("was toggled [breaker ? "ON" : "OFF"] by [key_name(usr)].", INVESTIGATE_GRAVITY) - set_power() - src.updateUsrDialog() + switch(action) + if("gentoggle") + breaker = !breaker + investigate_log("was toggled [breaker ? "ON" : "OFF"] by [key_name(usr)].", INVESTIGATE_GRAVITY) + set_power() // Power and Icon States diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index e50b11ea35..441eb27621 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -193,9 +193,9 @@ var/on = FALSE // 1 if on, 0 if off var/on_gs = FALSE var/static_power_used = 0 - var/brightness = 8 // luminosity when on, also used in power calculation + var/brightness = 11 // luminosity when on, also used in power calculation var/bulb_power = 0.75 // basically the alpha of the emitted light source - var/bulb_colour = "#FFEEDD" // befault colour of the light. + var/bulb_colour = "#FFF6ED" // befault colour of the light. var/status = LIGHT_OK // LIGHT_OK, _EMPTY, _BURNED or _BROKEN var/flickering = FALSE var/light_type = /obj/item/light/tube // the type of light item @@ -231,7 +231,7 @@ icon_state = "bulb" base_state = "bulb" fitting = "bulb" - brightness = 4 + brightness = 6 bulb_colour = "#FFDDBB" desc = "A small lighting fixture." light_type = /obj/item/light/bulb @@ -272,11 +272,11 @@ spawn(2) switch(fitting) if("tube") - brightness = 8 + brightness = 11 if(prob(2)) break_light_tube(1) if("bulb") - brightness = 4 + brightness = 6 if(prob(5)) break_light_tube(1) spawn(1) @@ -294,7 +294,7 @@ cut_overlays() switch(status) // set icon_states if(LIGHT_OK) - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(emergency_mode || (A && A.fire)) icon_state = "[base_state]_emergency" else @@ -323,7 +323,7 @@ var/CO = bulb_colour if(color) CO = color - var/area/A = get_area(src) + var/area/A = get_base_area(src) if (A && A.fire) CO = bulb_emergency_colour else if (nightshift_enabled) @@ -351,11 +351,11 @@ set_light(0) update_icon() - active_power_usage = (brightness * 10) + active_power_usage = (brightness * 7.2) if(on != on_gs) on_gs = on if(on) - static_power_used = brightness * 20 //20W per unit luminosity + static_power_used = brightness * 14.4 //20W per unit luminosity addStaticPower(static_power_used, STATIC_LIGHT) else removeStaticPower(static_power_used, STATIC_LIGHT) @@ -738,7 +738,7 @@ icon_state = "ltube" base_state = "ltube" item_state = "c_tube" - brightness = 8 + brightness = 11 /obj/item/light/tube/broken status = LIGHT_BROKEN @@ -751,12 +751,12 @@ item_state = "contvapour" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - brightness = 4 + brightness = 6 /obj/item/light/bulb/broken status = LIGHT_BROKEN -/obj/item/light/throw_impact(atom/hit_atom) +/obj/item/light/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) //not caught by a mob shatter() @@ -820,7 +820,7 @@ icon = 'icons/obj/lighting.dmi' base_state = "floor" // base description and icon_state icon_state = "floor" - brightness = 4 + brightness = 6 layer = 2.5 light_type = /obj/item/light/bulb fitting = "bulb" diff --git a/code/modules/power/monitor.dm b/code/modules/power/monitor.dm index 6b0ab6cbb2..f4ee102ccc 100644 --- a/code/modules/power/monitor.dm +++ b/code/modules/power/monitor.dm @@ -19,6 +19,8 @@ var/record_interval = 50 var/next_record = 0 var/is_secret_monitor = FALSE + tgui_id = "power_monitor" + ui_style = "ntos" /obj/machinery/computer/monitor/secret //Hides the power monitor (such as ones on ruins & CentCom) from PDA's to prevent metagaming. name = "outdated power monitoring console" @@ -85,7 +87,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "power_monitor", name, 1200, 1000, master_ui, state) + ui = new(user, src, ui_key, tgui_id, name, 550, 700, master_ui, state) ui.open() /obj/machinery/computer/monitor/ui_data() diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 9ae6c69847..3a6a98d681 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -103,6 +103,8 @@ . += "The generator has [sheets] units of [sheet_name] fuel left, producing [power_gen] per cycle." if(crit_fail) . += "The generator seems to have broken down." + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Fuel efficiency increased by [(consumption*100)-100]%." /obj/machinery/power/port_gen/pacman/HasFuel() if(sheets >= 1 / (time_per_sheet / power_output) - sheet_left) diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index d2d3d60066..fba526edbd 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -382,6 +382,7 @@ return null /area/proc/get_apc() + var/target = base_area ? base_area : src for(var/obj/machinery/power/apc/APC in GLOB.apcs_list) - if(APC.area == src) + if(APC.area == target) return APC \ No newline at end of file diff --git a/code/modules/power/rtg.dm b/code/modules/power/rtg.dm index 45d1c0fc00..afbeef30a1 100644 --- a/code/modules/power/rtg.dm +++ b/code/modules/power/rtg.dm @@ -36,6 +36,11 @@ power_gen = initial(power_gen) * part_level +/obj/machinery/power/rtg/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Power generation now at [power_gen*0.001]kW." + /obj/machinery/power/rtg/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-open", initial(icon_state), I)) return diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index e007b72c88..31e0c479ed 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -6,6 +6,7 @@ icon = 'icons/obj/singularity.dmi' icon_state = "Contain_F" density = FALSE + move_resist = INFINITY resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF use_power = NO_POWER_USE interaction_flags_atom = NONE diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index d6f51497cd..e956742e92 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -30,7 +30,7 @@ var/locked = FALSE var/allow_switch_interact = TRUE - var/projectile_type = /obj/item/projectile/beam/emitter + var/projectile_type = /obj/item/projectile/beam/emitter/hitscan var/projectile_sound = 'sound/weapons/emitter.ogg' var/datum/effect_system/spark_spread/sparks @@ -68,6 +68,11 @@ sparks.attach(src) sparks.set_up(1, TRUE, src) +/obj/machinery/power/emitter/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Emitting one beam each [fire_delay*0.1] seconds.
    Power consumption at [active_power_usage]W.
    " + /obj/machinery/power/emitter/ComponentInitialize() . = ..() AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index 595d87697d..54aca32cf7 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -245,6 +245,7 @@ field_generator power level display if(state != FG_WELDED || !anchored) turn_off() return + move_resist = INFINITY spawn(1) setup_field(1) spawn(2) @@ -335,6 +336,7 @@ field_generator power level display message_admins("A singulo exists and a containment field has failed at [ADMIN_VERBOSEJMP(T)].") investigate_log("has failed whilst a singulo exists at [AREACOORD(T)].", INVESTIGATE_SINGULO) O.last_warning = world.time + move_resist = initial(move_resist) /obj/machinery/field/generator/shock(mob/living/user) if(fields.len) diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm index 142388c350..9e098446d1 100644 --- a/code/modules/power/singularity/particle_accelerator/particle.dm +++ b/code/modules/power/singularity/particle_accelerator/particle.dm @@ -59,7 +59,12 @@ /obj/effect/accelerated_particle/proc/move() if(!step(src,dir)) - forceMove(get_step(src,dir)) + var/turf/T = get_step(src,dir) + if(T) + forceMove(T) + else + qdel(src) + return movement_range-- if(movement_range == 0) qdel(src) diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index a14a6d76bc..76eeeae205 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -7,6 +7,7 @@ icon_state = "singularity_s1" anchored = TRUE density = TRUE + move_resist = INFINITY layer = MASSIVE_OBJ_LAYER light_range = 6 appearance_flags = 0 diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 18cd6d22a6..e6d44de194 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -19,6 +19,8 @@ var/ndir = SOUTH // target dir var/turn_angle = 0 var/obj/machinery/power/solar_control/control = null + var/obj/item/solar_assembly/assembly + var/efficiency = 1 /obj/machinery/power/solar/Initialize(mapload, obj/item/solar_assembly/S) . = ..() @@ -45,14 +47,13 @@ /obj/machinery/power/solar/proc/Make(obj/item/solar_assembly/S) if(!S) - S = new /obj/item/solar_assembly(src) - S.glass_type = /obj/item/stack/sheet/glass + S = new /obj/item/solar_assembly + S.glass_type = new /obj/item/stack/sheet/glass(null, 2) S.anchored = TRUE else - S.forceMove(src) - if(S.glass_type == /obj/item/stack/sheet/rglass) //if the panel is in reinforced glass - max_integrity *= 2 //this need to be placed here, because panels already on the map don't have an assembly linked to - obj_integrity = max_integrity + S.moveToNullspace() + S.glass_type.on_solar_construction(src) + obj_integrity = max_integrity update_icon() /obj/machinery/power/solar/crowbar_act(mob/user, obj/item/I) @@ -85,14 +86,14 @@ /obj/machinery/power/solar/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) if(disassembled) - var/obj/item/solar_assembly/S = locate() in src - if(S) - S.forceMove(loc) - S.give_glass(stat & BROKEN) + if(assembly) + assembly.forceMove(loc) + assembly.give_glass(stat & BROKEN) else playsound(src, "shatter", 70, 1) - new /obj/item/shard(src.loc) - new /obj/item/shard(src.loc) + var/shard = assembly?.glass_type ? assembly.glass_type.shard_type : /obj/item/shard + new shard(loc) + new shard(loc) qdel(src) @@ -131,7 +132,7 @@ if(powernet == control.powernet)//check if the panel is still connected to the computer if(obscured) //get no light from the sun, so don't generate power return - var/sgen = SOLARGENRATE * sunfrac + var/sgen = SOLARGENRATE * sunfrac * efficiency add_avail(sgen) control.gen += sgen else //if we're no longer on the same powernet, remove from control computer @@ -186,19 +187,23 @@ w_class = WEIGHT_CLASS_BULKY // Pretty big! anchored = FALSE var/tracker = 0 - var/glass_type = null + var/obj/item/stack/sheet/glass_type + var/static/list/allowed_sheets = typecacheof(list(/obj/item/stack/sheet/glass, /obj/item/stack/sheet/rglass, + /obj/item/stack/sheet/plasmaglass, /obj/item/stack/sheet/plasmarglass, + /obj/item/stack/sheet/titaniumglass, /obj/item/stack/sheet/plastitaniumglass)) // Give back the glass type we were supplied with /obj/item/solar_assembly/proc/give_glass(device_broken) var/atom/Tsec = drop_location() if(device_broken) - new /obj/item/shard(Tsec) - new /obj/item/shard(Tsec) + var/shard = glass_type ? glass_type.shard_type : /obj/item/shard + if(shard) + new shard(Tsec) + new shard(Tsec) else if(glass_type) - new glass_type(Tsec, 2) + forceMove(glass_type, Tsec) glass_type = null - /obj/item/solar_assembly/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/wrench) && isturf(loc)) if(isinspace()) @@ -213,13 +218,14 @@ W.play_tool_sound(src, 75) return 1 - if(istype(W, /obj/item/stack/sheet/glass) || istype(W, /obj/item/stack/sheet/rglass)) + if(is_type_in_typecache(W, allowed_sheets)) if(!anchored) to_chat(user, "You need to secure the assembly before you can add glass.") return var/obj/item/stack/sheet/S = W - if(S.use(2)) - glass_type = W.type + var/obj/item/stack/sheet/G = S.change_stack(null, 2) + if(G) + glass_type = G playsound(src.loc, 'sound/machines/click.ogg', 50, 1) user.visible_message("[user] places the glass on the solar assembly.", "You place the glass on the solar assembly.") if(tracker) @@ -342,7 +348,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "solar_control", name, 500, 400, master_ui, state) + ui = new(user, src, ui_key, "solar_control", name, 380, 230, master_ui, state) ui.open() /obj/machinery/power/solar_control/ui_data() @@ -363,39 +369,47 @@ /obj/machinery/power/solar_control/ui_act(action, params) if(..()) return - switch(action) - if("angle") - var/adjust = text2num(params["adjust"]) - if(adjust) - currentdir = CLAMP((360 + adjust + currentdir) % 360, 0, 359) - targetdir = currentdir - set_panels(currentdir) - . = TRUE - if("rate") - var/adjust = text2num(params["adjust"]) - if(adjust) - trackrate = CLAMP(trackrate + adjust, -7200, 7200) - if(trackrate) - nexttime = world.time + 36000 / abs(trackrate) - . = TRUE - if("tracking") - var/mode = text2num(params["mode"]) - track = mode - if(mode == 2 && connected_tracker) - connected_tracker.set_angle(SSsun.angle) - set_panels(currentdir) - else if(mode == 1) - targetdir = currentdir - if(trackrate) - nexttime = world.time + 36000 / abs(trackrate) - set_panels(targetdir) - . = TRUE - if("refresh") - search_for_connected() - if(connected_tracker && track == 2) - connected_tracker.set_angle(SSsun.angle) + if(action == "angle") + var/adjust = text2num(params["adjust"]) + var/value = text2num(params["value"]) + if(adjust) + value = currentdir + adjust + if(value != null) + currentdir = CLAMP((360 + value) % 360, 0, 359) + targetdir = currentdir set_panels(currentdir) - . = TRUE + return TRUE + return FALSE + if(action == "rate") + var/adjust = text2num(params["adjust"]) + var/value = text2num(params["value"]) + if(adjust) + value = trackrate + adjust + if(value != null) + trackrate = CLAMP(value, -7200, 7200) + if(trackrate) + nexttime = world.time + 36000 / abs(trackrate) + return TRUE + return FALSE + if(action == "tracking") + var/mode = text2num(params["mode"]) + track = mode + if(mode == 2 && connected_tracker) + connected_tracker.set_angle(SSsun.angle) + set_panels(currentdir) + else if(mode == 1) + targetdir = currentdir + if(trackrate) + nexttime = world.time + 36000 / abs(trackrate) + set_panels(targetdir) + return TRUE + if(action == "refresh") + search_for_connected() + if(connected_tracker && track == 2) + connected_tracker.set_angle(SSsun.angle) + set_panels(currentdir) + return TRUE + return FALSE /obj/machinery/power/solar_control/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/screwdriver)) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index ee93767a0c..8990ca0e3e 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -66,6 +66,8 @@ #define SUPERMATTER_COUNTDOWN_TIME 30 SECONDS +#define SUPERMATTER_INTEGRITY_MULT 1.3 //(loss of integrity / 10) ^ 1.3 + GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal @@ -158,6 +160,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) var/datum/looping_sound/supermatter/soundloop var/moveable = FALSE + var/min_damage = 0 + var/power_calc = 0 /obj/machinery/power/supermatter_crystal/Initialize() . = ..() @@ -359,6 +363,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) //capping damage damage = min(damage_archived + (DAMAGE_HARDCAP * explosion_point),damage) + damage = max(min_damage, damage) //max integrity if(damage > damage_archived && prob(10)) playsound(get_turf(src), 'sound/effects/empulse.ogg', 50, 1) @@ -398,7 +403,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(matter_power) var/removed_matter = max(matter_power/MATTER_POWER_CONVERSION, 40) - power = max(power + removed_matter, 0) + power_calc = max(power_calc + removed_matter, 0) matter_power = max(matter_power - removed_matter, 0) var/temp_factor = 50 @@ -411,7 +416,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) temp_factor = 30 icon_state = base_icon_state - power = max( (removed.temperature * temp_factor / T0C) * gasmix_power_ratio + power, 0) //Total laser power plus an overload + power_calc = max( (removed.temperature * temp_factor / T0C) * gasmix_power_ratio + power_calc, 0) //Total laser power plus an overload if(prob(50)) radiation_pulse(src, power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + ((pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) * pluoxiumbonus) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER))))) // Rad Modifiers BZ(500%), Tritium(300%), and Pluoxium(-200%) @@ -443,15 +448,19 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) for(var/mob/living/carbon/human/l in view(src, HALLUCINATION_RANGE(power))) // If they can see it without mesons on. Bad on them. if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) var/D = sqrt(1 / max(1, get_dist(l, src))) - l.hallucination += power * config_hallucination_power * D + l.hallucination += power_calc * config_hallucination_power * D l.hallucination = CLAMP(0, 200, l.hallucination) for(var/mob/living/l in range(src, round((power / 100) ** 0.25))) var/rads = (power / 10) * sqrt( 1 / max(get_dist(l, src),1) ) l.rad_act(rads) - power -= ((power/500)**3) * powerloss_inhibitor - + power_calc -= ((power_calc/500)**3) * powerloss_inhibitor + if ((100-get_integrity()) < 75) + power = (power_calc * ((100 - (0.15*(100-get_integrity()) - 5)**2) / 100)) + power_calc*0.1 + else + power = power_calc * (((100-get_integrity())^((3*(100-get_integrity()))/1000) + 2*(100-get_integrity()))/100) //new and improved, more linear + //power = power_calc * ((((100-get_integrity())**1.3)-(2*(100-get_integrity())))/100) if(power > POWER_PENALTY_THRESHOLD || damage > damage_penalty_point) if(power > POWER_PENALTY_THRESHOLD) @@ -474,8 +483,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) supermatter_anomaly_gen(src, GRAVITATIONAL_ANOMALY, rand(5, 10)) if(power > SEVERE_POWER_PENALTY_THRESHOLD && prob(2) || prob(0.3) && power > POWER_PENALTY_THRESHOLD) supermatter_anomaly_gen(src, PYRO_ANOMALY, rand(5, 10)) - - if(damage > warning_point) // while the core is still damaged and it's still worth noting its status + if (damage - damage_archived > 0) + min_damage += ((damage - damage_archived) / 9) * SUPERMATTER_INTEGRITY_MULT + if(damage > (min_damage < 200 ? min_damage : 0) + warning_point) // while the core is still damaged and it's still worth noting its status if((REALTIMEOFDAY - lastwarning) / 10 >= WARNING_DELAY) alarm() @@ -514,7 +524,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(!istype(Proj.firer, /obj/machinery/power/emitter)) investigate_log("has been hit by [Proj] fired by [key_name(Proj.firer)]", INVESTIGATE_SUPERMATTER) if(Proj.flag != "bullet") - power += Proj.damage * config_bullet_energy + power_calc += Proj.damage * config_bullet_energy if(!has_been_powered) investigate_log("has been powered for the first time.", INVESTIGATE_SUPERMATTER) message_admins("[src] has been powered for the first time [ADMIN_JMP(src)].") @@ -615,6 +625,17 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) to_chat(user, "You extract a sliver from \the [src]. \The [src] begins to react violently!") new /obj/item/nuke_core/supermatter_sliver(drop_location()) matter_power += 200 + if (istype(W, /obj/item/supermatterspray)) + var/obj/item/supermatterspray/S = W + if (S.usesleft > 0 && do_after(user, 60, target=src)) + min_damage = max(0,min_damage - 10) + to_chat(user, "You spray \the [src] with [S].") + playsound(user.loc,'sound/effects/spray2.ogg',50,1,-6) + S.usesleft-- + if (prob(10)) + to_chat(user, "Your hands slip and you drop [S] into \the [src]!") + Consume(S) + return else if(user.dropItemToGround(W)) user.visible_message("As [user] touches \the [src] with \a [W], silence fills the room...",\ "You touch \the [src] with \the [W], and everything suddenly goes silent.\n\The [W] flashes into dust as you flinch away from \the [src].",\ diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index 2265f806a5..e29ffa865e 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -36,6 +36,11 @@ zap_cooldown -= (C.rating * 20) input_power_multiplier = power_multiplier +/obj/machinery/power/tesla_coil/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Power generation at [input_power_multiplier*100]%.
    Shock interval at [zap_cooldown*0.1] seconds.
    " + /obj/machinery/power/tesla_coil/on_construction() if(anchored) connect_to_network() diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm index 5075e7656d..c25ece3594 100644 --- a/code/modules/power/tracker.dm +++ b/code/modules/power/tracker.dm @@ -16,6 +16,7 @@ var/id = 0 var/sun_angle = 0 // sun angle as set by sun datum var/obj/machinery/power/solar_control/control = null + var/obj/item/solar_assembly/assembly /obj/machinery/power/tracker/Initialize(mapload, obj/item/solar_assembly/S) . = ..() @@ -42,11 +43,12 @@ /obj/machinery/power/tracker/proc/Make(obj/item/solar_assembly/S) if(!S) - S = new /obj/item/solar_assembly(src) - S.glass_type = /obj/item/stack/sheet/glass - S.tracker = 1 + S = new /obj/item/solar_assembly + S.glass_type = new /obj/item/stack/sheet/glass(null, 2) + S.tracker = TRUE S.anchored = TRUE - S.forceMove(src) + else + S.moveToNullspace() update_icon() //updates the tracker icon and the facing angle for the control computer @@ -77,14 +79,14 @@ /obj/machinery/power/solar/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) if(disassembled) - var/obj/item/solar_assembly/S = locate() in src - if(S) - S.forceMove(loc) - S.give_glass(stat & BROKEN) + if(assembly) + assembly.forceMove(loc) + assembly.give_glass(stat & BROKEN) else playsound(src, "shatter", 70, 1) - new /obj/item/shard(src.loc) - new /obj/item/shard(src.loc) + var/shard = assembly?.glass_type ? assembly.glass_type.shard_type : /obj/item/shard + new shard(loc) + new shard(loc) qdel(src) // Tracker Electronic diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index 85ee7589b9..b40e5c6c41 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -57,15 +57,6 @@ var/lastgen var/productivity = 1 -/obj/machinery/computer/turbine_computer - name = "gas turbine control computer" - desc = "A computer to remotely control a gas turbine." - icon_screen = "turbinecomp" - icon_keyboard = "tech_key" - circuit = /obj/item/circuitboard/computer/turbine_computer - var/obj/machinery/power/compressor/compressor - var/id = 0 - // the inlet stage of the gas turbine electricity generator /obj/machinery/power/compressor/Initialize() @@ -94,6 +85,11 @@ E += M.rating efficiency = E / 6 +/obj/machinery/power/compressor/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Efficiency at [efficiency*100]%." + /obj/machinery/power/compressor/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, initial(icon_state), initial(icon_state), I)) return @@ -113,12 +109,13 @@ default_deconstruction_crowbar(I) /obj/machinery/power/compressor/process() - if(!turbine) - stat = BROKEN - if(stat & BROKEN || panel_open) - return if(!starter) return + if(!turbine || (turbine.stat & BROKEN)) + starter = FALSE + if(stat & BROKEN || panel_open) + starter = FALSE + return cut_overlays() rpm = 0.9* rpm + 0.1 * rpmtarget @@ -176,6 +173,11 @@ P += C.rating productivity = P / 6 +/obj/machinery/power/turbine/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Productivity at [productivity*100]%." + /obj/machinery/power/turbine/locate_machinery() if(compressor) return @@ -288,7 +290,14 @@ // COMPUTER NEEDS A SERIOUS REWRITE. - +/obj/machinery/computer/turbine_computer + name = "gas turbine control computer" + desc = "A computer to remotely control a gas turbine." + icon_screen = "turbinecomp" + icon_keyboard = "tech_key" + circuit = /obj/item/circuitboard/computer/turbine_computer + var/obj/machinery/power/compressor/compressor + var/id = 0 /obj/machinery/computer/turbine_computer/Initialize() . = ..() @@ -304,27 +313,27 @@ compressor = C return else - compressor = locate(/obj/machinery/power/compressor) in range(5, src) + compressor = locate(/obj/machinery/power/compressor) in range(7, src) /obj/machinery/computer/turbine_computer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "turbine_computer", name, 350, 280, master_ui, state) + ui = new(user, src, ui_key, "turbine_computer", name, 300, 200, master_ui, state) ui.open() /obj/machinery/computer/turbine_computer/ui_data(mob/user) var/list/data = list() - data["connected"] = (compressor && compressor.turbine) ? TRUE : FALSE + data["compressor"] = compressor ? TRUE : FALSE data["compressor_broke"] = (!compressor || (compressor.stat & BROKEN)) ? TRUE : FALSE + data["turbine"] = compressor?.turbine ? TRUE : FALSE data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.stat & BROKEN)) ? TRUE : FALSE - data["broken"] = (data["compressor_broke"] || data["turbine_broke"]) - data["online"] = compressor.starter + data["online"] = compressor?.starter - data["power"] = DisplayPower(compressor.turbine.lastgen) - data["rpm"] = compressor.rpm - data["temp"] = compressor.gas_contained.temperature + data["power"] = DisplayPower(compressor?.turbine?.lastgen) + data["rpm"] = compressor?.rpm + data["temp"] = compressor?.gas_contained.temperature return data @@ -332,13 +341,9 @@ if(..()) return switch(action) - if("power-on") + if("toggle_power") if(compressor && compressor.turbine) - compressor.starter = TRUE - . = TRUE - if("power-off") - if(compressor && compressor.turbine) - compressor.starter = FALSE + compressor.starter = !compressor.starter . = TRUE if("reconnect") locate_machinery() diff --git a/code/modules/procedural_mapping/mapGenerator.dm b/code/modules/procedural_mapping/mapGenerator.dm index 4c9e1dddea..f509c409ce 100644 --- a/code/modules/procedural_mapping/mapGenerator.dm +++ b/code/modules/procedural_mapping/mapGenerator.dm @@ -30,7 +30,7 @@ /datum/mapGenerator/New() ..() if(buildmode_name == "Undocumented") - buildmode_name = copytext("[type]", 20) // / d a t u m / m a p g e n e r a t o r / = 20 characters. + buildmode_name = copytext_char("[type]", 20) // / d a t u m / m a p g e n e r a t o r / = 20 characters. initialiseModules() //Defines the region the map represents, sets map diff --git a/code/modules/procedural_mapping/mapGenerators/lavaland.dm b/code/modules/procedural_mapping/mapGenerators/lavaland.dm index 6ad21eb959..20194a24ec 100644 --- a/code/modules/procedural_mapping/mapGenerators/lavaland.dm +++ b/code/modules/procedural_mapping/mapGenerators/lavaland.dm @@ -16,9 +16,9 @@ /datum/mapGeneratorModule/splatterLayer/lavalandTendrils spawnableTurfs = list() - spawnableAtoms = list(/mob/living/simple_animal/hostile/spawner/lavaland = 5, - /mob/living/simple_animal/hostile/spawner/lavaland/legion = 5, - /mob/living/simple_animal/hostile/spawner/lavaland/goliath = 5) + spawnableAtoms = list(/obj/structure/spawner/lavaland = 5, + /obj/structure/spawner/lavaland/legion = 5, + /obj/structure/spawner/lavaland/goliath = 5) /datum/mapGenerator/lavaland/ground_only modules = list(/datum/mapGeneratorModule/bottomLayer/lavaland_default) diff --git a/code/modules/projectiles/ammunition/_ammunition.dm b/code/modules/projectiles/ammunition/_ammunition.dm index ccd43e734b..1404529700 100644 --- a/code/modules/projectiles/ammunition/_ammunition.dm +++ b/code/modules/projectiles/ammunition/_ammunition.dm @@ -9,7 +9,7 @@ w_class = WEIGHT_CLASS_TINY materials = list(MAT_METAL = 500) var/fire_sound = null //What sound should play when this ammo is fired - var/caliber = null //Which kind of guns it can be loaded into + var/caliber = list() //Which kind of guns it can be loaded into var/projectile_type = null //The bullet type to create when New() is called var/obj/item/projectile/BB = null //The loaded bullet var/pellets = 1 //Pellets for spreadshot @@ -34,6 +34,11 @@ setDir(pick(GLOB.alldirs)) update_icon() +/obj/item/ammo_casing/Destroy() + if(BB) + QDEL_NULL(BB) + return ..() + /obj/item/ammo_casing/update_icon() ..() icon_state = "[initial(icon_state)][BB ? "-live" : ""]" @@ -65,7 +70,7 @@ else return ..() -/obj/item/ammo_casing/throw_impact(atom/A) +/obj/item/ammo_casing/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(heavy_metal) bounce_away(FALSE, NONE) . = ..() diff --git a/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm b/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm index 538ac753e2..d8e53b2451 100644 --- a/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm +++ b/code/modules/projectiles/boxes_magazines/internal/_cylinder.dm @@ -1,7 +1,7 @@ /obj/item/ammo_box/magazine/internal/cylinder name = "revolver cylinder" ammo_type = /obj/item/ammo_casing/a357 - caliber = "357" + caliber = list("357","38") max_ammo = 7 /obj/item/ammo_box/magazine/internal/cylinder/ammo_count(countempties = 1) @@ -31,7 +31,7 @@ rotate() /obj/item/ammo_box/magazine/internal/cylinder/give_round(obj/item/ammo_casing/R, replace_spent = 0) - if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type)) + if(!R || (caliber && !(R.caliber in caliber)) || (!caliber && R.type != ammo_type)) return FALSE for(var/i in 1 to stored_ammo.len) diff --git a/code/modules/projectiles/boxes_magazines/internal/grenade.dm b/code/modules/projectiles/boxes_magazines/internal/grenade.dm index 8b2ec9fca3..d6d338e8ff 100644 --- a/code/modules/projectiles/boxes_magazines/internal/grenade.dm +++ b/code/modules/projectiles/boxes_magazines/internal/grenade.dm @@ -1,7 +1,7 @@ /obj/item/ammo_box/magazine/internal/cylinder/grenademulti name = "grenade launcher internal magazine" ammo_type = /obj/item/ammo_casing/a40mm - caliber = "40mm" + caliber = list("40mm") max_ammo = 6 /obj/item/ammo_box/magazine/internal/grenadelauncher diff --git a/code/modules/projectiles/boxes_magazines/internal/revolver.dm b/code/modules/projectiles/boxes_magazines/internal/revolver.dm index 982d22493f..a9cad1adc8 100644 --- a/code/modules/projectiles/boxes_magazines/internal/revolver.dm +++ b/code/modules/projectiles/boxes_magazines/internal/revolver.dm @@ -1,19 +1,19 @@ /obj/item/ammo_box/magazine/internal/cylinder/rev38 name = "detective revolver cylinder" ammo_type = /obj/item/ammo_casing/c38 - caliber = "38" + caliber = list("38") max_ammo = 6 /obj/item/ammo_box/magazine/internal/cylinder/rev762 name = "\improper Nagant revolver cylinder" ammo_type = /obj/item/ammo_casing/n762 - caliber = "n762" + caliber = list("n762") max_ammo = 7 /obj/item/ammo_box/magazine/internal/cylinder/rus357 name = "\improper Russian revolver cylinder" ammo_type = /obj/item/ammo_casing/a357 - caliber = "357" + caliber = list("357") max_ammo = 6 multiload = 0 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 531c6082b0..0c2b5e013e 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -76,6 +76,13 @@ if(zoomable) azoom = new (src) +/obj/item/gun/Destroy() + QDEL_NULL(pin) + QDEL_NULL(gun_light) + QDEL_NULL(bayonet) + QDEL_NULL(chambered) + return ..() + /obj/item/gun/CheckParts(list/parts_list) ..() var/obj/item/gun/G = locate(/obj/item/gun) in contents @@ -237,7 +244,7 @@ sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread), 1) else //Smart spread sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread), 1) - + before_firing(target,user) if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd, src)) shoot_with_empty_chamber(user) firing_burst = FALSE @@ -281,6 +288,7 @@ else if(chambered) sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread)) + before_firing(target,user) if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, sprd, src)) shoot_with_empty_chamber(user) return @@ -466,6 +474,10 @@ qdel(pin) pin = new /obj/item/firing_pin +//Happens before the actual projectile creation +/obj/item/gun/proc/before_firing(atom/target,mob/user) + return + ///////////// // ZOOMING // ///////////// diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index c2206fcea8..611f8c57bd 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -96,21 +96,26 @@ "Gold Trim" = "detective_gold", "The Peacemaker" = "detective_peacemaker" ) + var/list/safe_calibers + +/obj/item/gun/ballistic/revolver/detective/Initialize() + . = ..() + safe_calibers = magazine.caliber /obj/item/gun/ballistic/revolver/detective/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) - if(magazine.caliber != initial(magazine.caliber)) + if(chambered && !(chambered.caliber in safe_calibers)) if(prob(70 - (magazine.ammo_count() * 10))) //minimum probability of 10, maximum of 60 playsound(user, fire_sound, 50, 1) to_chat(user, "[src] blows up in your face!") user.take_bodypart_damage(0,20) user.dropItemToGround(src) - return 0 + return FALSE ..() /obj/item/gun/ballistic/revolver/detective/screwdriver_act(mob/living/user, obj/item/I) if(..()) return TRUE - if(magazine.caliber == "38") + if("38" in magazine.caliber) to_chat(user, "You begin to reinforce the barrel of [src]...") if(magazine.ammo_count()) afterattack(user, user) //you know the drill @@ -120,7 +125,7 @@ if(magazine.ammo_count()) to_chat(user, "You can't modify it!") return TRUE - magazine.caliber = "357" + magazine.caliber = list("357") desc = "The barrel and chamber assembly seems to have been modified." to_chat(user, "You reinforce the barrel of [src]. Now it will fire .357 rounds.") else @@ -133,7 +138,7 @@ if(magazine.ammo_count()) to_chat(user, "You can't modify it!") return - magazine.caliber = "38" + magazine.caliber = list("38") desc = initial(desc) to_chat(user, "You remove the modifications on [src]. Now it will fire .38 rounds.") return TRUE diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 1329e5418f..3ca732eb0b 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -58,6 +58,7 @@ /obj/item/gun/energy/Destroy() QDEL_NULL(cell) + QDEL_LIST(ammo_type) STOP_PROCESSING(SSobj, src) return ..() diff --git a/code/modules/projectiles/guns/energy/dueling.dm b/code/modules/projectiles/guns/energy/dueling.dm new file mode 100644 index 0000000000..6fe10eb3b6 --- /dev/null +++ b/code/modules/projectiles/guns/energy/dueling.dm @@ -0,0 +1,389 @@ +#define DUEL_IDLE 1 +#define DUEL_PREPARATION 2 +#define DUEL_READY 3 +#define DUEL_COUNTDOWN 4 +#define DUEL_FIRING 5 + +//paper rock scissors +#define DUEL_SETTING_A "wide" +#define DUEL_SETTING_B "cone" +#define DUEL_SETTING_C "pinpoint" + +#define DUEL_HUGBOX_NONE 0 //dismember head +#define DUEL_HUGBOX_LETHAL 1 //200 damage to chest +#define DUEL_HUGBOX_NONLETHAL 2 //stamcrit + +/datum/duel + var/obj/item/gun/energy/dueling/gun_A + var/obj/item/gun/energy/dueling/gun_B + var/state = DUEL_IDLE + var/required_distance = 5 + var/list/confirmations = list() + var/list/fired = list() + var/countdown_length = 10 + var/countdown_step = 0 + var/static/next_id = 1 + var/id + +/datum/duel/New() + id = next_id++ + +/datum/duel/proc/try_begin() + //Check if both guns are held and if so begin. + var/mob/living/A = get_duelist(gun_A) + var/mob/living/B = get_duelist(gun_B) + if(!A || !B) + message_duelists("To begin the duel, both participants need to be holding paired dueling pistols.") + return + begin() + +/datum/duel/proc/begin() + state = DUEL_PREPARATION + confirmations.Cut() + fired.Cut() + countdown_step = countdown_length + + message_duelists("Set your gun setting and move [required_distance] steps away from your opponent.") + + START_PROCESSING(SSobj,src) + +/datum/duel/proc/get_duelist(obj/gun) + var/mob/living/G = gun.loc + if(!istype(G) || !G.is_holding(gun)) + return null + return G + +/datum/duel/proc/message_duelists(message) + var/mob/living/LA = get_duelist(gun_A) + if(LA) + to_chat(LA,message) + var/mob/living/LB = get_duelist(gun_B) + if(LB) + to_chat(LB,message) + +/datum/duel/proc/other_gun(obj/item/gun/energy/dueling/G) + return G == gun_A ? gun_B : gun_A + +/datum/duel/proc/end() + message_duelists("Duel finished. Re-engaging safety.") + STOP_PROCESSING(SSobj,src) + state = DUEL_IDLE + +/datum/duel/process() + switch(state) + if(DUEL_PREPARATION) + if(check_positioning()) + confirm_positioning() + else if (!get_duelist(gun_A) && !get_duelist(gun_B)) + end() + if(DUEL_READY) + if(!check_positioning()) + back_to_prep() + else if(confirmations.len == 2) + confirm_ready() + if(DUEL_COUNTDOWN) + if(!check_positioning()) + back_to_prep() + else + countdown_step() + if(DUEL_FIRING) + if(check_fired()) + end() + +/datum/duel/proc/back_to_prep() + message_duelists("Positions invalid. Please move to valid positions [required_distance] steps aways from each other to continue.") + state = DUEL_PREPARATION + confirmations.Cut() + countdown_step = countdown_length + +/datum/duel/proc/confirm_positioning() + message_duelists("Position confirmed. Confirm readiness by pulling the trigger once.") + state = DUEL_READY + +/datum/duel/proc/confirm_ready() + message_duelists("Readiness confirmed. Starting countdown. Commence firing at zero mark.") + state = DUEL_COUNTDOWN + +/datum/duel/proc/countdown_step() + countdown_step-- + if(countdown_step == 0) + state = DUEL_FIRING + message_duelists("Fire!") + else + message_duelists("[countdown_step]!") + +/datum/duel/proc/check_fired() + if(fired.len == 2) + return TRUE + //Let's say if gun was dropped/stowed the user is finished + if(!get_duelist(gun_A)) + return TRUE + if(!get_duelist(gun_B)) + return TRUE + return FALSE + +/datum/duel/proc/check_positioning() + var/mob/living/A = get_duelist(gun_A) + var/mob/living/B = get_duelist(gun_B) + if(!A || !B) + return FALSE + if(!isturf(A.loc) || !isturf(B.loc)) + return FALSE + if(get_dist(A,B) != required_distance) + return FALSE + for(var/turf/T in getline(get_turf(A),get_turf(B))) + if(is_blocked_turf(T,TRUE)) + return FALSE + return TRUE + +/obj/item/gun/energy/dueling + name = "dueling pistol" + desc = "High-tech dueling pistol. Launches chaff and projectile according to preset settings." + icon_state = "dueling_pistol" + item_state = "gun" + ammo_x_offset = 2 + w_class = WEIGHT_CLASS_SMALL + ammo_type = list(/obj/item/ammo_casing/energy/duel) + automatic_charge_overlays = FALSE + var/unlocked = FALSE + var/setting = DUEL_SETTING_A + var/datum/duel/duel + var/mutable_appearance/setting_overlay + var/hugbox = DUEL_HUGBOX_NONE + +/obj/item/gun/energy/dueling/hugbox + hugbox = DUEL_HUGBOX_LETHAL + +/obj/item/gun/energy/dueling/hugbox/stamina + hugbox = DUEL_HUGBOX_NONLETHAL + +/obj/item/gun/energy/dueling/Initialize() + . = ..() + setting_overlay = mutable_appearance(icon,setting_iconstate()) + add_overlay(setting_overlay) + +/obj/item/gun/energy/dueling/examine(mob/user) + . = ..() + if(duel) + . += "Its linking number is [duel.id]." + else + . += "ERROR: No linking number on gun." + +/obj/item/gun/energy/dueling/proc/setting_iconstate() + switch(setting) + if(DUEL_SETTING_A) + return "duel_red" + if(DUEL_SETTING_B) + return "duel_green" + if(DUEL_SETTING_C) + return "duel_blue" + return "duel_red" + +/obj/item/gun/energy/dueling/attack_self(mob/living/user) + . = ..() + if(duel.state == DUEL_IDLE) + duel.try_begin() + else + toggle_setting(user) + +/obj/item/gun/energy/dueling/proc/toggle_setting(mob/living/user) + switch(setting) + if(DUEL_SETTING_A) + setting = DUEL_SETTING_B + if(DUEL_SETTING_B) + setting = DUEL_SETTING_C + if(DUEL_SETTING_C) + setting = DUEL_SETTING_A + to_chat(user,"You switch [src] setting to [setting] mode.") + update_icon() + +/obj/item/gun/energy/dueling/update_icon(force_update) + . = ..() + if(setting_overlay) + cut_overlay(setting_overlay) + setting_overlay.icon_state = setting_iconstate() + add_overlay(setting_overlay) + +/obj/item/gun/energy/dueling/Destroy() + . = ..() + if(duel.gun_A == src) + duel.gun_A = null + if(duel.gun_B == src) + duel.gun_B = null + duel = null + +/obj/item/gun/energy/dueling/can_trigger_gun(mob/living/user) + . = ..() + switch(duel.state) + if(DUEL_FIRING) + return . && !duel.fired[src] + if(DUEL_READY) + return . + else + to_chat(user,"[src] is locked. Wait for FIRE signal before shooting.") + return FALSE + +/obj/item/gun/energy/dueling/proc/is_duelist(mob/living/L) + if(!istype(L)) + return FALSE + if(!L.is_holding(duel.other_gun(src))) + return FALSE + return TRUE + +/obj/item/gun/energy/dueling/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread) + if(duel.state == DUEL_READY) + duel.confirmations[src] = TRUE + to_chat(user,"You confirm your readiness.") + return + else if(!is_duelist(target)) //I kinda want to leave this out just to see someone shoot a bystander or missing. + to_chat(user,"[src] safety system prevents shooting anyone but your designated opponent.") + return + else + duel.fired[src] = TRUE + . = ..() + +/obj/item/gun/energy/dueling/before_firing(target,user) + var/obj/item/ammo_casing/energy/duel/D = chambered + D.setting = setting + D.hugbox = hugbox + +/obj/effect/temp_visual/dueling_chaff + icon = 'icons/effects/effects.dmi' + icon_state = "shield-old" + duration = 30 + var/setting + +/obj/effect/temp_visual/dueling_chaff/update_icon() + . = ..() + switch(setting) + if(DUEL_SETTING_A) + color = "red" + if(DUEL_SETTING_B) + color = "green" + if(DUEL_SETTING_C) + color = "blue" + +//Casing + +/obj/item/ammo_casing/energy/duel + e_cost = 0 + projectile_type = /obj/item/projectile/energy/duel + var/setting + var/hugbox = DUEL_HUGBOX_NONE + +/obj/item/ammo_casing/energy/duel/ready_proj(atom/target, mob/living/user, quiet, zone_override) + . = ..() + var/obj/item/projectile/energy/duel/D = BB + D.setting = setting + D.hugbox = hugbox + D.update_icon() + +/obj/item/ammo_casing/energy/duel/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from) + . = ..() + var/obj/effect/temp_visual/dueling_chaff/C = new(get_turf(user)) + C.setting = setting + C.update_icon() + +//Projectile + +/obj/item/projectile/energy/duel + name = "dueling beam" + icon_state = "declone" + is_reflectable = FALSE + homing = TRUE + var/setting + var/hugbox = DUEL_HUGBOX_NONE + +/obj/item/projectile/energy/duel/update_icon() + . = ..() + switch(setting) + if(DUEL_SETTING_A) + color = "red" + if(DUEL_SETTING_B) + color = "green" + if(DUEL_SETTING_C) + color = "blue" + +/obj/item/projectile/energy/duel/on_hit(atom/target, blocked) + . = ..() + var/turf/T = get_turf(target) + var/obj/effect/temp_visual/dueling_chaff/C = locate() in T + if(C) + var/counter_setting + switch(setting) + if(DUEL_SETTING_A) + counter_setting = DUEL_SETTING_B + if(DUEL_SETTING_B) + counter_setting = DUEL_SETTING_C + if(DUEL_SETTING_C) + counter_setting = DUEL_SETTING_A + if(C.setting == counter_setting) + return BULLET_ACT_BLOCK + + var/mob/living/L = target + if(!istype(target)) + return BULLET_ACT_BLOCK + + switch(hugbox) + if(DUEL_HUGBOX_NONE) + var/obj/item/bodypart/B = L.get_bodypart(BODY_ZONE_HEAD) + B.dismember() + QDEL_IN(B, 1) + if(DUEL_HUGBOX_LETHAL) + L.adjustBruteLoss(180) + L.death() //Die, powergamers. + if(DUEL_HUGBOX_NONLETHAL) + L.adjustStaminaLoss(200, forced = TRUE) //Die, powergamers x 2 + L.Knockdown(100, override_hardstun = 100) //For good measure. + +//Storage case. +/obj/item/storage/lockbox/dueling + name = "dueling pistol case" + desc = "Let's solve this like gentlespacemen." + icon_state = "medalbox+l" + item_state = "syringe_kit" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + w_class = WEIGHT_CLASS_NORMAL + req_access = list(ACCESS_CAPTAIN) + icon_locked = "medalbox+l" + icon_closed = "medalbox" + icon_broken = "medalbox+b" + var/gun_type = /obj/item/gun/energy/dueling + +/obj/item/storage/lockbox/dueling/ComponentInitialize() + . = ..() + var/datum/component/storage/STR = GetComponent(/datum/component/storage) + STR.max_w_class = WEIGHT_CLASS_SMALL + STR.max_items = 2 + STR.can_hold = typecacheof(/obj/item/gun/energy/dueling) + +/obj/item/storage/lockbox/dueling/update_icon() + cut_overlays() + var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED) + if(locked) + icon_state = "medalbox+l" + else + icon_state = "medalbox" + if(open) + icon_state += "open" + if(broken) + icon_state += "+b" + +/obj/item/storage/lockbox/dueling/PopulateContents() + . = ..() + var/obj/item/gun/energy/dueling/gun_A = new gun_type(src) + var/obj/item/gun/energy/dueling/gun_B = new gun_type(src) + var/datum/duel/D = new + gun_A.duel = D + gun_B.duel = D + D.gun_A = gun_A + D.gun_B = gun_B + +/obj/item/storage/lockbox/dueling/hugbox + gun_type = /obj/item/gun/energy/dueling/hugbox + req_access = list(ACCESS_ARMORY) + +/obj/item/storage/lockbox/dueling/hugbox/stamina + gun_type = /obj/item/gun/energy/dueling/hugbox/stamina + req_access = null diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index ecd906f2a9..6cd567ce16 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -297,7 +297,7 @@ /obj/item/borg/upgrade/modkit/proc/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user) . = TRUE if(src in KA.modkits) // Sanity check to prevent installing the same modkit twice thanks to occasional click/lag delays. - return + return FALSE if(minebot_upgrade) if(minebot_exclusive && !istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone)) to_chat(user, "The modkit you're trying to install is only rated for minebot use.") @@ -317,7 +317,7 @@ if(KA.get_remaining_mod_capacity() >= cost) if(.) if(!user.transferItemToLoc(src, KA)) - return + return FALSE to_chat(user, "You install the modkit.") playsound(loc, 'sound/items/screwdriver.ogg', 100, 1) KA.modkits += src @@ -374,14 +374,18 @@ desc = "Decreases the cooldown of a kinetic accelerator. Not rated for minebot use." modifier = 2.5 minebot_upgrade = FALSE + var/decreased /obj/item/borg/upgrade/modkit/cooldown/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user) . = ..() if(.) - KA.overheat_time -= modifier + var/old = KA.overheat_time + KA.overheat_time = max(0, KA.overheat_time - modifier) + decreased = old - KA.overheat_time + /obj/item/borg/upgrade/modkit/cooldown/uninstall(obj/item/gun/energy/kinetic_accelerator/KA) - KA.overheat_time += modifier + KA.overheat_time += decreased ..() /obj/item/borg/upgrade/modkit/cooldown/minebot diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index eeb272f8d9..f0b38f2d4e 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -105,13 +105,15 @@ /obj/item/gun/energy/kinetic_accelerator/crossbow/large name = "energy crossbow" - desc = "A reverse engineered weapon using syndicate technology." + desc = "A reverse engineered weapon using syndicate technology. This thing seems incredibly unwieldly, and seems to be using similar internals to the Proto-Kinetic Accelerator. It might not play nice when brought near weapons similar to it." icon_state = "crossbowlarge" - w_class = WEIGHT_CLASS_NORMAL + w_class = WEIGHT_CLASS_BULKY materials = list(MAT_METAL=4000) suppressed = null ammo_type = list(/obj/item/ammo_casing/energy/bolt/large) + weapon_weight = WEAPON_HEAVY pin = null + unique_frequency = FALSE /obj/item/gun/energy/plasmacutter name = "plasma cutter" diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index cc778bcf05..a902c545b8 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -57,6 +57,8 @@ var/muzzle_type var/impact_type + var/turf/last_angle_set_hitscan_store //last turf we stored a hitscan segment while changing angles. without this you'll have potentially hundreds of segments from a homing projectile or something. + //Fancy hitscan lighting effects! var/hitscan_light_intensity = 1.5 var/hitscan_light_range = 0.75 @@ -410,12 +412,16 @@ START_PROCESSING(SSprojectiles, src) pixel_move(1, FALSE) //move it now! -/obj/item/projectile/proc/setAngle(new_angle) //wrapper for overrides. +/obj/item/projectile/proc/setAngle(new_angle, hitscan_store_segment = TRUE) //wrapper for overrides. Angle = new_angle if(!nondirectional_sprite) var/matrix/M = new M.Turn(Angle) transform = M + if(fired && hitscan && trajectory && isloc(loc) && (loc != last_angle_set_hitscan_store)) + last_angle_set_hitscan_store = loc + var/datum/point/pcache = trajectory.copy_to() + store_hitscan_collision(pcache) if(trajectory) trajectory.set_angle(new_angle) return TRUE @@ -462,7 +468,7 @@ beam_segments[beam_index] = null //record start. /obj/item/projectile/proc/process_hitscan() - var/safety = range * 3 + var/safety = range * 10 record_hitscan_start(RETURN_POINT_VECTOR_INCREMENT(src, Angle, MUZZLE_EFFECT_PIXEL_INCREMENT, 1)) while(loc && !QDELETED(src)) if(paused) @@ -637,17 +643,17 @@ Bump(original) /obj/item/projectile/Destroy() + STOP_PROCESSING(SSprojectiles, src) if(hitscan) finalize_hitscan_and_generate_tracers() - STOP_PROCESSING(SSprojectiles, src) cleanup_beam_segments() - qdel(trajectory) + QDEL_NULL(trajectory) return ..() /obj/item/projectile/proc/cleanup_beam_segments() QDEL_LIST_ASSOC(beam_segments) beam_segments = list() - qdel(beam_index) + QDEL_NULL(beam_index) /obj/item/projectile/proc/finalize_hitscan_and_generate_tracers(impacting = TRUE) if(trajectory && beam_index) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index fd79a52906..d71e081dac 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -118,7 +118,14 @@ light_color = LIGHT_COLOR_GREEN /obj/item/projectile/beam/emitter/singularity_pull() - return //don't want the emitters to miss + return + +/obj/item/projectile/beam/emitter/hitscan + hitscan = TRUE + muzzle_type = /obj/effect/projectile/muzzle/laser/emitter + tracer_type = /obj/effect/projectile/tracer/laser/emitter + impact_type = /obj/effect/projectile/impact/laser/emitter + impact_effect_type = null /obj/item/projectile/beam/lasertag name = "laser tag beam" diff --git a/code/modules/projectiles/projectile/energy/ebow.dm b/code/modules/projectiles/projectile/energy/ebow.dm index d3f5162bf6..9e2992b76b 100644 --- a/code/modules/projectiles/projectile/energy/ebow.dm +++ b/code/modules/projectiles/projectile/energy/ebow.dm @@ -1,12 +1,14 @@ /obj/item/projectile/energy/bolt //ebow bolts name = "bolt" icon_state = "cbbolt" - damage = 8 + damage = 15 damage_type = TOX nodamage = 0 - knockdown = 100 - stutter = 5 - drowsy = 50 + eyeblur = 10 + slur = 5 + knockdown = 160 + stamina = 60 + knockdown_stamoverride = 0 /obj/item/projectile/energy/bolt/halloween name = "candy corn" diff --git a/code/modules/reagents/chem_wiki_render.dm b/code/modules/reagents/chem_wiki_render.dm index e24da70d47..018161b075 100644 --- a/code/modules/reagents/chem_wiki_render.dm +++ b/code/modules/reagents/chem_wiki_render.dm @@ -196,7 +196,7 @@ return "" - var/outstring = "|
    !\[[R.color]\](https://placehold.it/15/[copytext(R.color, 2, 8)]/000000?text=+)[R.name]
    pH: [R.pH] | " + var/outstring = "|
    !\[[R.color]\](https://placehold.it/15/[copytext_char(R.color, 2, 8)]/000000?text=+)[R.name]
    pH: [R.pH] | " var/datum/reagent/R3 if(CR) outstring += "
      " diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index bf3c4220b4..95e104ba68 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -171,7 +171,7 @@ return master -/datum/reagents/proc/trans_to(obj/target, amount=1, multiplier=1, preserve_data=1, no_react = 0)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred. +/datum/reagents/proc/trans_to(obj/target, amount = 1, multiplier = 1, preserve_data = 1, no_react = 0, log = FALSE)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred. var/list/cached_reagents = reagent_list if(!target || !total_volume) return @@ -188,17 +188,23 @@ amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume) var/part = amount / src.total_volume var/trans_data = null + var/list/transferred = list() for(var/reagent in cached_reagents) var/datum/reagent/T = reagent var/transfer_amount = T.volume * part if(preserve_data) trans_data = copy_data(T) - + transferred += "[T] - [transfer_amount]" R.add_reagent(T.type, transfer_amount * multiplier, trans_data, chem_temp, T.purity, pH, no_react = TRUE, ignore_pH = TRUE) //we only handle reaction after every reagent has been transfered. - remove_reagent(T.type, transfer_amount, ignore_pH = TRUE) + if(log && amount > 0) + var/atom/us = my_atom + var/atom/them = R.my_atom + var/location_string = "FROM [(us && "[us] ([REF(us)]) [COORD(us)]") || "NULL"] TO [(them && "[them] ([REF(them)]) [COORD(them)]") || "NULL"]" + log_reagent_transfer("[location_string] - [key_name(usr)][istext(log) ? " - [log]" : ""]: trans_to with arguments [target] [amount] [multiplier] [preserve_data] [no_react] and reagents [english_list(transferred)]") + update_total() R.update_total() if(!no_react) @@ -237,7 +243,7 @@ src.handle_reactions() return amount -/datum/reagents/proc/trans_id_to(obj/target, reagent, amount=1, preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N +/datum/reagents/proc/trans_id_to(obj/target, reagent, amount = 1, preserve_data = TRUE, log = FALSE)//Not sure why this proc didn't exist before. It does now! /N var/list/cached_reagents = reagent_list if (!target) return @@ -257,8 +263,12 @@ if(preserve_data) trans_data = current_reagent.data R.add_reagent(current_reagent.type, amount, trans_data, chem_temp, current_reagent.purity, pH, no_react = TRUE) - remove_reagent(current_reagent.type, amount, 1) + if(log && amount > 0) + var/atom/us = my_atom + var/atom/them = R.my_atom + var/location_string = "FROM [(us && "[us] ([REF(us)]) [COORD(us)]") || "NULL"] TO [(them && "[them] ([REF(them)]) [COORD(them)]") || "NULL"]" + log_reagent_transfer("[location_string] - [key_name(usr)][istext(log) ? " - [log]" : ""]: trans_id_to with arguments [target] [reagent] [amount] [preserve_data]") break src.update_total() diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 424f2bce30..0abdc9a739 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -31,8 +31,8 @@ var/working_state = "dispenser_working" var/nopower_state = "dispenser_nopower" var/has_panel_overlay = TRUE - var/macrotier = 1 var/obj/item/reagent_containers/beaker = null + //dispensable_reagents is copypasted in plumbing synthesizers. Please update accordingly. (I didn't make it global because that would limit custom chem dispensers) var/list/dispensable_reagents = list( /datum/reagent/hydrogen, /datum/reagent/lithium, @@ -61,7 +61,7 @@ /datum/reagent/bromine, /datum/reagent/stable_plasma ) -//these become available once upgraded. + //These become available once upgraded. var/list/upgrade_reagents = list( /datum/reagent/oil, /datum/reagent/ammonia, @@ -87,11 +87,13 @@ /datum/reagent/toxin/histamine, /datum/reagent/medicine/morphine ) + var/list/recording_recipe var/list/saved_recipes = list() /obj/machinery/chem_dispenser/Initialize() . = ..() + dispensable_reagents = sortList(dispensable_reagents, /proc/cmp_reagents_asc) if(emagged_reagents) emagged_reagents = sortList(emagged_reagents, /proc/cmp_reagents_asc) if(upgrade_reagents) @@ -113,16 +115,9 @@ if(panel_open) . += "[src]'s maintenance hatch is open!" if(in_range(user, src) || isobserver(user)) - . += "The status display reads:
      Recharging [recharge_amount] power units per interval.
      Power efficiency increased by [(powerefficiency*1000)-100]%." - switch(macrotier) - if(1) - . += "Macro granularity at 5u." - if(2) - . += "Macro granularity at 3u." - if(3) - . += "Macro granularity at 2u." - if(4) - . += "Macro granularity at 1u." + . += "The status display reads:\n\ + Recharging [recharge_amount] power units per interval.\n\ + Power efficiency increased by [round((powerefficiency*1000)-100, 1)]%." /obj/machinery/chem_dispenser/process() if (recharge_counter >= 4) @@ -158,7 +153,6 @@ beaker_overlay = display_beaker() add_overlay(beaker_overlay) - /obj/machinery/chem_dispenser/emag_act(mob/user) . = ..() if(obj_flags & EMAGGED) @@ -223,8 +217,7 @@ data["beakerTransferAmounts"] = null data["beakerCurrentpH"] = null - var/chemicals[0] - var/recipes[0] + var/list/chemicals = list() var/is_hallucinating = FALSE if(user.hallucinating()) is_hallucinating = TRUE @@ -235,10 +228,10 @@ if(is_hallucinating && prob(5)) chemname = "[pick_list_replacements("hallucination.json", "chemicals")]" chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name)))) - for(var/recipe in saved_recipes) - recipes.Add(list(recipe)) data["chemicals"] = chemicals - data["recipes"] = recipes + data["recipes"] = saved_recipes + + data["recordingRecipe"] = recording_recipe return data /obj/machinery/chem_dispenser/ui_act(action, params) @@ -256,24 +249,28 @@ if("dispense") if(!is_operational() || QDELETED(cell)) return - var/reagent = GLOB.name2reagent[params["reagent"]] - if(beaker && dispensable_reagents.Find(reagent)) - var/datum/reagents/R = beaker.reagents - var/free = R.maximum_volume - R.total_volume - var/actual = min(amount, (cell.charge * powerefficiency)*10, free) + var/reagent_name = params["reagent"] + if(!recording_recipe) + var/reagent = GLOB.name2reagent[reagent_name] + if(beaker && dispensable_reagents.Find(reagent)) + var/datum/reagents/R = beaker.reagents + var/free = R.maximum_volume - R.total_volume + var/actual = min(amount, (cell.charge * powerefficiency)*10, free) - if(!cell.use(actual / powerefficiency)) - say("Not enough energy to complete operation!") - return - R.add_reagent(reagent, actual) + if(!cell.use(actual / powerefficiency)) + say("Not enough energy to complete operation!") + return + R.add_reagent(reagent, actual) - work_animation() - . = TRUE + work_animation() + else + recording_recipe[reagent_name] += amount + . = TRUE if("remove") - if(!is_operational()) + if(!is_operational() || recording_recipe) return var/amount = text2num(params["amount"]) - if(beaker && (amount in beaker.possible_transfer_amounts)) + if(beaker && amount in beaker.possible_transfer_amounts) beaker.reagents.remove_all(amount) work_animation() . = TRUE @@ -283,57 +280,65 @@ if("dispense_recipe") if(!is_operational() || QDELETED(cell)) return - var/recipe_to_use = params["recipe"] - var/list/chemicals_to_dispense = process_recipe_list(recipe_to_use) - var/res = get_macro_resolution() - for(var/key in chemicals_to_dispense) // i suppose you could edit the list locally before passing it - var/list/keysplit = splittext(key," ") - var/r_id = GLOB.name2reagent[translate_legacy_chem_id(keysplit[1])] - if(beaker && dispensable_reagents.Find(r_id)) // but since we verify we have the reagent, it'll be fine + var/list/chemicals_to_dispense = saved_recipes[params["recipe"]] + if(!LAZYLEN(chemicals_to_dispense)) + return + for(var/key in chemicals_to_dispense) + var/reagent = GLOB.name2reagent[translate_legacy_chem_id(key)] + var/dispense_amount = chemicals_to_dispense[key] + if(!dispensable_reagents.Find(reagent)) + return + if(!recording_recipe) + if(!beaker) + return var/datum/reagents/R = beaker.reagents var/free = R.maximum_volume - R.total_volume - var/actual = min(max(chemicals_to_dispense[key], res), (cell.charge * powerefficiency)*10, free) + var/actual = min(dispense_amount, (cell.charge * powerefficiency)*10, free) if(actual) if(!cell.use(actual / powerefficiency)) say("Not enough energy to complete operation!") return - R.add_reagent(r_id, actual) + R.add_reagent(reagent, actual) work_animation() + else + recording_recipe[key] += dispense_amount + . = TRUE if("clear_recipes") if(!is_operational()) return var/yesno = alert("Clear all recipes?",, "Yes","No") if(yesno == "Yes") saved_recipes = list() - if("add_recipe") + . = TRUE + if("record_recipe") + if(!is_operational()) + return + recording_recipe = list() + . = TRUE + if("save_recording") if(!is_operational()) return var/name = stripped_input(usr,"Name","What do you want to name this recipe?", "Recipe", MAX_NAME_LEN) - var/recipe = stripped_input(usr,"Recipe","Insert recipe with chem IDs") if(!usr.canUseTopic(src, !issilicon(usr))) return - if(name && recipe) - var/list/first_process = splittext(recipe, ";") - if(!LAZYLEN(first_process)) - return - var/res = get_macro_resolution() - var/resmismatch = FALSE - for(var/reagents in first_process) - var/list/reagent = splittext(reagents, "=") - var/reagent_id = GLOB.name2reagent[translate_legacy_chem_id(reagent[1])] - if(dispensable_reagents.Find(reagent_id)) - if (!resmismatch && !check_macro_part(reagents, res)) - resmismatch = TRUE - continue - else - var/chemid = reagent[1] + if(saved_recipes[name] && alert("\"[name]\" already exists, do you want to overwrite it?",, "Yes", "No") == "No") + return + if(name && recording_recipe) + for(var/reagent in recording_recipe) + var/reagent_id = GLOB.name2reagent[translate_legacy_chem_id(reagent)] + if(!dispensable_reagents.Find(reagent_id)) visible_message("[src] buzzes.", "You hear a faint buzz.") - to_chat(usr, "[src] cannot find Chemical ID: [chemid]!") + to_chat(usr, "[src] cannot find [reagent]!") playsound(src, 'sound/machines/buzz-two.ogg', 50, 1) return - if (resmismatch && alert("[src] is not yet capable of replicating this recipe with the precision it needs, do you want to save it anyway?",, "Yes","No") == "No") - return - saved_recipes += list(list("recipe_name" = name, "contents" = recipe)) + saved_recipes[name] = recording_recipe + recording_recipe = null + . = TRUE + if("cancel_recording") + if(!is_operational()) + return + recording_recipe = null + . = TRUE /obj/machinery/chem_dispenser/attackby(obj/item/I, mob/user, params) if(default_unfasten_wrench(user, I)) @@ -341,7 +346,6 @@ if(default_deconstruction_screwdriver(user, icon_state, icon_state, I)) update_icon() return - if(default_deconstruction_crowbar(I)) return if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) @@ -382,7 +386,6 @@ work_animation() visible_message("[src] malfunctions, spraying chemicals everywhere!") - /obj/machinery/chem_dispenser/RefreshParts() recharge_amount = initial(recharge_amount) var/newpowereff = 0.0666666 @@ -393,13 +396,11 @@ for(var/obj/item/stock_parts/capacitor/C in component_parts) recharge_amount *= C.rating for(var/obj/item/stock_parts/manipulator/M in component_parts) - if (M.rating > macrotier) - macrotier = M.rating - if (M.rating > 1) + if(M.rating > 1) dispensable_reagents |= upgrade_reagents - if (M.rating > 2) + if(M.rating > 2) dispensable_reagents |= upgrade_reagents2 - if (M.rating > 3) + if(M.rating > 3) dispensable_reagents |= upgrade_reagents3 powerefficiency = round(newpowereff, 0.01) @@ -420,41 +421,14 @@ cell = null if(beaker) beaker.forceMove(drop_location()) + beaker = null return ..() -/obj/machinery/chem_dispenser/proc/get_macro_resolution() - . = 5 - if (macrotier > 1) - . -= macrotier // 5 for tier1, 3 for 2, 2 for 3, 1 for 4. - -/obj/machinery/chem_dispenser/proc/check_macro(macro) - var/res = get_macro_resolution() - for (var/reagent in splittext(trim(macro), ";")) - if (!check_macro_part(reagent, res)) - return FALSE - return TRUE - -/obj/machinery/chem_dispenser/proc/check_macro_part(var/part, var/res = get_macro_resolution()) - var/detail = splittext(part, "=") - if (round(text2num(detail[2]), res) != text2num(detail[2])) - return FALSE - return TRUE - -/obj/machinery/chem_dispenser/proc/process_recipe_list(var/fucking_hell) - var/list/key_list = list() - var/list/final_list = list() - var/list/first_process = splittext(fucking_hell, ";") - for(var/reagents in first_process) - var/list/fuck = splittext(reagents, "=") - final_list += list(avoid_assoc_duplicate_keys(fuck[1],key_list) = text2num(fuck[2])) - return final_list - /obj/machinery/chem_dispenser/AltClick(mob/living/user) . = ..() - if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) - return - replace_beaker(user) - return TRUE + if(istype(user) && user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) + replace_beaker(user) + return TRUE /obj/machinery/chem_dispenser/drinks/Initialize() . = ..() @@ -538,7 +512,6 @@ /datum/reagent/toxin/staminatoxin ) - /obj/machinery/chem_dispenser/drinks/fullupgrade //fully ugpraded stock parts, emagged desc = "Contains a large reservoir of soft drinks. This model has had its safeties shorted out." obj_flags = CAN_BE_HIT | EMAGGED @@ -644,7 +617,7 @@ /datum/reagent/ammonia, /datum/reagent/ash, /datum/reagent/diethylamine) - //same as above. + //same as above. upgrade_reagents = null upgrade_reagents2 = null upgrade_reagents3 = null @@ -741,4 +714,4 @@ component_parts += new /obj/item/stock_parts/manipulator/femto(null) component_parts += new /obj/item/stack/sheet/glass(null) component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() + RefreshParts() \ No newline at end of file diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index b4f14c69a7..189d09b06f 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -52,6 +52,11 @@ for(var/obj/item/stock_parts/micro_laser/M in component_parts) heater_coefficient *= M.rating +/obj/machinery/chem_heater/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Heating reagents at [heater_coefficient*1000]% speed." + /obj/machinery/chem_heater/process() ..() if(stat & NOPOWER) @@ -150,4 +155,4 @@ if("eject") on = FALSE replace_beaker(usr) - . = TRUE + . = TRUE \ No newline at end of file diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 9c877fc053..44148c85a7 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -148,8 +148,8 @@ /obj/machinery/chem_master/on_deconstruction() var/atom/A = drop_location() - beaker.forceMove(A) - bottle.forceMove(A) + beaker?.forceMove(A) + bottle?.forceMove(A) return ..() /obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ @@ -525,4 +525,4 @@ condi = TRUE #undef PILL_STYLE_COUNT -#undef RANDOM_PILL_STYLE +#undef RANDOM_PILL_STYLE \ No newline at end of file diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index 68ce6e490f..bba5371ef8 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -12,7 +12,6 @@ idle_power_usage = 20 resistance_flags = ACID_PROOF var/wait - var/mode = MAIN_SCREEN var/datum/symptom/selected_symptom var/obj/item/reagent_containers/beaker @@ -56,18 +55,14 @@ if(istype(D, /datum/disease/advance)) var/datum/disease/advance/A = D var/disease_name = SSdisease.get_disease_name(A.GetDiseaseID()) - if((disease_name == "Unknown") && A.mutable) - this["can_rename"] = TRUE + this["can_rename"] = ((disease_name == "Unknown") && A.mutable) this["name"] = disease_name this["is_adv"] = TRUE this["symptoms"] = list() - var/symptom_index = 1 for(var/symptom in A.symptoms) var/datum/symptom/S = symptom var/list/this_symptom = list() - this_symptom["name"] = S.name - this_symptom["sym_index"] = symptom_index - symptom_index++ + this_symptom = get_symptom_data(S) this["symptoms"] += list(this_symptom) this["resistance"] = A.totalResistance() this["stealth"] = A.totalStealth() @@ -128,29 +123,28 @@ /obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "pandemic", name, 700, 500, master_ui, state) + ui = new(user, src, ui_key, "pandemic", name, 520, 550, master_ui, state) ui.open() /obj/machinery/computer/pandemic/ui_data(mob/user) var/list/data = list() data["is_ready"] = !wait - data["mode"] = mode - switch(mode) - if(MAIN_SCREEN) - if(beaker) - data["has_beaker"] = TRUE - if(!beaker.reagents.total_volume || !beaker.reagents.reagent_list) - data["beaker_empty"] = TRUE - var/datum/reagent/blood/B = locate() in beaker.reagents.reagent_list - if(B) - data["has_blood"] = TRUE - data[/datum/reagent/blood] = list() - data[/datum/reagent/blood]["dna"] = B.data["blood_DNA"] || "none" - data[/datum/reagent/blood]["type"] = B.data["blood_type"] || "none" - data["viruses"] = get_viruses_data(B) - data["resistances"] = get_resistance_data(B) - if(SYMPTOM_DETAILS) - data["symptom"] = get_symptom_data(selected_symptom) + if(beaker) + data["has_beaker"] = TRUE + data["beaker_empty"] = (!beaker.reagents.total_volume || !beaker.reagents.reagent_list) + var/datum/reagent/blood/B = locate() in beaker.reagents.reagent_list + if(B) + data["has_blood"] = TRUE + data[/datum/reagent/blood] = list() + data[/datum/reagent/blood]["dna"] = B.data["blood_DNA"] || "none" + data[/datum/reagent/blood]["type"] = B.data["blood_type"] || "none" + data["viruses"] = get_viruses_data(B) + data["resistances"] = get_resistance_data(B) + else + data["has_blood"] = FALSE + else + data["has_beaker"] = FALSE + data["has_blood"] = FALSE return data @@ -209,19 +203,6 @@ update_icon() addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 200) . = TRUE - if("symptom_details") - var/picked_symptom_index = text2num(params["picked_symptom"]) - var/index = text2num(params["index"]) - var/datum/disease/advance/A = get_by_index("viruses", index) - var/datum/symptom/S = A.symptoms[picked_symptom_index] - mode = SYMPTOM_DETAILS - selected_symptom = S - . = TRUE - if("back") - mode = MAIN_SCREEN - selected_symptom = null - . = TRUE - /obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm index c0d453de54..189f58fec3 100644 --- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm +++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm @@ -105,7 +105,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "smoke_machine", name, 450, 350, master_ui, state) + ui = new(user, src, ui_key, "smoke_machine", name, 350, 350, master_ui, state) ui.open() /obj/machinery/smoke_machine/ui_data(mob/user) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 5eb2c135a8..4aabd82d6a 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -1,5 +1,4 @@ #define REM REAGENTS_EFFECT_MULTIPLIER - GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) /proc/build_name2reagent() diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 62a8d97b2d..103f7cb28f 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -887,7 +887,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/barefoot/on_mob_life(mob/living/carbon/M) if(ishuman(M)) //Barefoot causes the imbiber to quickly regenerate brute trauma if they're not wearing shoes. var/mob/living/carbon/human/H = M - if(!H.shoes) + if(!H.shoes || !(H.shoes.body_parts_covered & FEET)) H.adjustBruteLoss(-3, 0) . = 1 return ..() || . diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index ccc966e7e4..c7e574594b 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -540,9 +540,13 @@ if(MUTCOLORS in N.dna.species.species_traits) //take current alien color and darken it slightly var/newcolor = "" - var/len = length(N.dna.features["mcolor"]) - for(var/i=1, i<=len, i+=1) - var/ascii = text2ascii(N.dna.features["mcolor"],i) + var/string = N.dna.features["mcolor"] + var/len = length(string) + var/char = "" + var/ascii = 0 + for(var/i=1, i<=len, i += length(char)) + char = string[i] + ascii = text2ascii(char) switch(ascii) if(48) newcolor += "0" @@ -553,7 +557,7 @@ if(98 to 102) newcolor += ascii2text(ascii-1) //letters b to f lowercase if(65) - newcolor +="9" + newcolor += "9" if(66 to 70) newcolor += ascii2text(ascii+31) //letters B to F - translates to lowercase else @@ -1058,7 +1062,7 @@ if((HAS_TRAIT(C, TRAIT_NOMARROW))) return if(C.blood_volume < (BLOOD_VOLUME_NORMAL*C.blood_ratio)) - C.blood_volume += 0.01 //we'll have synthetics from medbay. + C.blood_volume += 0.25 ..() /datum/reagent/iron/reaction_mob(mob/living/M, method=TOUCH, reac_volume) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index ad3a2c90a4..a32cb94401 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -153,20 +153,37 @@ color = "#669900" // rgb: 102, 153, 0 toxpwr = 0.5 taste_description = "death" + var/fakedeath_active = FALSE pH = 13 /datum/reagent/toxin/zombiepowder/on_mob_metabolize(mob/living/L) ..() - L.fakedeath(type) + ADD_TRAIT(L, TRAIT_FAKEDEATH, type) /datum/reagent/toxin/zombiepowder/on_mob_end_metabolize(mob/living/L) L.cure_fakedeath(type) ..() -/datum/reagent/toxin/zombiepowder/on_mob_life(mob/living/carbon/M) - M.adjustOxyLoss(0.5*REM, 0) +/datum/reagent/toxin/zombiepowder/reaction_mob(mob/living/L, method=TOUCH, reac_volume) + L.adjustOxyLoss(0.5*REM, 0) + if(method == INGEST) + fakedeath_active = TRUE + L.fakedeath(type) + +/datum/reagent/toxin/zombiepowder/on_mob_life(mob/living/M) ..() - . = 1 + if(fakedeath_active) + return TRUE + switch(current_cycle) + if(1 to 5) + M.confused += 1 + M.drowsyness += 1 + M.slurring += 3 + if(5 to 8) + M.adjustStaminaLoss(40, 0) + if(9 to INFINITY) + fakedeath_active = TRUE + M.fakedeath(type) /datum/reagent/toxin/ghoulpowder name = "Ghoul Powder" diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index a915087428..98d66a2b1b 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -36,7 +36,7 @@ var/PurityMin = 0.15 //If purity is below 0.15, it explodes too. Set to 0 to disable this. -/datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, created_volume, specialreact) +/datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, multiplier, specialreact) return //I recommend you set the result amount to the total volume of all components. diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index 26b39fb3b0..b463b5758b 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -53,9 +53,9 @@ required_reagents = list(/datum/reagent/iron = 5, /datum/reagent/consumable/frostoil = 5, /datum/reagent/toxin/plasma = 20) mob_react = FALSE -/datum/chemical_reaction/plasmasolidification/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/plasmasolidification/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/stack/sheet/mineral/plasma(location) /datum/chemical_reaction/goldsolidification @@ -64,9 +64,9 @@ required_reagents = list(/datum/reagent/consumable/frostoil = 5, /datum/reagent/gold = 20, /datum/reagent/iron = 1) mob_react = FALSE -/datum/chemical_reaction/goldsolidification/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/goldsolidification/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/stack/sheet/mineral/gold(location) /datum/chemical_reaction/capsaicincondensation @@ -88,9 +88,9 @@ results = list(/datum/reagent/consumable/mustard = 5) required_reagents = list(/datum/reagent/mustardgrind = 1, /datum/reagent/water = 10, /datum/reagent/consumable/enzyme= 1) -/datum/chemical_reaction/soapification/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/soapification/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/soap/homemade(location) /datum/chemical_reaction/candlefication @@ -100,9 +100,9 @@ required_temp = 374 mob_react = FALSE -/datum/chemical_reaction/candlefication/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/candlefication/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/candle(location) /datum/chemical_reaction/meatification @@ -111,9 +111,9 @@ required_reagents = list(/datum/reagent/liquidgibs = 10, /datum/reagent/consumable/nutriment = 10, /datum/reagent/carbon = 10) mob_react = FALSE -/datum/chemical_reaction/meatification/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/meatification/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) + for(var/i = 1, i <= multiplier, i++) new /obj/item/reagent_containers/food/snacks/meat/slab/meatproduct(location) return @@ -146,9 +146,9 @@ mob_react = FALSE required_temp = 300 -/datum/chemical_reaction/fermis_plush/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/fermis_plush/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i+=10) + for(var/i = 1, i <= multiplier, i+=10) new /obj/item/toy/plush/catgirl/fermis(location) ////////////////////////////////// VIROLOGY ////////////////////////////////////////// @@ -227,13 +227,13 @@ var/level_min = 1 var/level_max = 2 -/datum/chemical_reaction/mix_virus/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/mix_virus/on_reaction(datum/reagents/holder, multiplier) var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list if(B && B.data) var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"] if(D) - for(var/i in 1 to min(created_volume, 5)) + for(var/i in 1 to min(multiplier, 5)) D.Evolve(level_min, level_max) /datum/chemical_reaction/mix_virus/mix_virus_2 @@ -330,12 +330,12 @@ required_reagents = list(/datum/reagent/medicine/synaptizine = 1) required_catalysts = list(/datum/reagent/blood = 1) -/datum/chemical_reaction/mix_virus/rem_virus/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/mix_virus/rem_virus/on_reaction(datum/reagents/holder, multiplier) var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list if(B && B.data) var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"] if(D) - for(var/i in 1 to min(created_volume, 5)) + for(var/i in 1 to min(multiplier, 5)) D.Devolve() /datum/chemical_reaction/mix_virus/neuter_virus @@ -344,12 +344,12 @@ required_reagents = list(/datum/reagent/toxin/formaldehyde = 1) required_catalysts = list(/datum/reagent/blood = 1) -/datum/chemical_reaction/mix_virus/neuter_virus/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/mix_virus/neuter_virus/on_reaction(datum/reagents/holder, multiplier) var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list if(B && B.data) var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"] if(D) - for(var/i in 1 to min(created_volume, 5)) + for(var/i in 1 to min(multiplier, 5)) D.Neuter() ////////////////////////////////// foam and foam precursor /////////////////////////////////////////////////// @@ -367,12 +367,12 @@ required_reagents = list(/datum/reagent/fluorosurfactant = 1, /datum/reagent/water = 1) mob_react = FALSE -/datum/chemical_reaction/foam/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/foam/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) for(var/mob/M in viewers(5, location)) to_chat(M, "The solution spews out foam!") var/datum/effect_system/foam_spread/s = new() - s.set_up(created_volume*2, location, holder) + s.set_up(multiplier*2, location, holder) s.start() holder.clear_reagents() return @@ -384,14 +384,14 @@ required_reagents = list(/datum/reagent/aluminium = 3, /datum/reagent/foaming_agent = 1, /datum/reagent/toxin/acid/fluacid = 1) mob_react = FALSE -/datum/chemical_reaction/metalfoam/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/metalfoam/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) for(var/mob/M in viewers(5, location)) to_chat(M, "The solution spews out a metallic foam!") var/datum/effect_system/foam_spread/metal/s = new() - s.set_up(created_volume*5, location, holder, 1) + s.set_up(multiplier*5, location, holder, 1) s.start() holder.clear_reagents() @@ -401,11 +401,11 @@ required_reagents = list(/datum/reagent/aluminium = 3, /datum/reagent/smart_foaming_agent = 1, /datum/reagent/toxin/acid/fluacid = 1) mob_react = TRUE -/datum/chemical_reaction/smart_foam/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/smart_foam/on_reaction(datum/reagents/holder, multiplier) var/turf/location = get_turf(holder.my_atom) location.visible_message("The solution spews out metallic foam!") var/datum/effect_system/foam_spread/metal/smart/s = new() - s.set_up(created_volume * 5, location, holder, TRUE) + s.set_up(multiplier * 5, location, holder, TRUE) s.start() holder.clear_reagents() @@ -415,12 +415,12 @@ required_reagents = list(/datum/reagent/iron = 3, /datum/reagent/foaming_agent = 1, /datum/reagent/toxin/acid/fluacid = 1) mob_react = FALSE -/datum/chemical_reaction/ironfoam/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/ironfoam/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) for(var/mob/M in viewers(5, location)) to_chat(M, "The solution spews out a metallic foam!") var/datum/effect_system/foam_spread/metal/s = new() - s.set_up(created_volume*5, location, holder, 2) + s.set_up(multiplier*5, location, holder, 2) s.start() holder.clear_reagents() @@ -521,8 +521,8 @@ required_reagents = list(/datum/reagent/medicine/strange_reagent = 1, /datum/reagent/medicine/synthflesh = 1, /datum/reagent/blood = 1) required_temp = 374 -/datum/chemical_reaction/life/on_reaction(datum/reagents/holder, created_volume) - chemical_mob_spawn(holder, rand(1, round(created_volume, 1)), "Life") // Lol. +/datum/chemical_reaction/life/on_reaction(datum/reagents/holder, multiplier) + chemical_mob_spawn(holder, rand(1, round(multiplier, 1)), "Life") // Lol. //This is missing, I'm adding it back (see tgwiki). Not sure why we don't have it. /datum/chemical_reaction/life_friendly @@ -531,8 +531,8 @@ required_reagents = list(/datum/reagent/medicine/strange_reagent = 1, /datum/reagent/medicine/synthflesh = 1, /datum/reagent/consumable/sugar = 1) required_temp = 374 -/datum/chemical_reaction/life_friendly/on_reaction(datum/reagents/holder, created_volume) - chemical_mob_spawn(holder, rand(1, round(created_volume, 1)), "Life (friendly)", FRIENDLY_SPAWN) //Pray for cute cats +/datum/chemical_reaction/life_friendly/on_reaction(datum/reagents/holder, multiplier) + chemical_mob_spawn(holder, rand(1, round(multiplier, 1)), "Life (friendly)", FRIENDLY_SPAWN) //Pray for cute cats /datum/chemical_reaction/corgium name = "corgium" @@ -540,9 +540,9 @@ required_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent = 1, /datum/reagent/medicine/strange_reagent = 1, /datum/reagent/blood = 1) required_temp = 374 -/datum/chemical_reaction/corgium/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/corgium/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i = rand(1, created_volume), i <= created_volume, i++) // More lulz. + for(var/i = rand(1, multiplier), i <= multiplier, i++) // More lulz. new /mob/living/simple_animal/pet/dog/corgi(location) ..() @@ -600,9 +600,9 @@ required_reagents = list(/datum/reagent/oil = 5, /datum/reagent/toxin/acid = 2, /datum/reagent/ash = 3) required_temp = 374 //lazily consistent with soap & other crafted objects generically created with heat. -/datum/chemical_reaction/plastic_polymers/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/plastic_polymers/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - for(var/i in 1 to created_volume) + for(var/i in 1 to multiplier) new /obj/item/stack/sheet/plastic(location) /datum/chemical_reaction/pax diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index cb9636bf02..3930988380 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -5,7 +5,7 @@ var/modifier = 0 var/noexplosion = FALSE -/datum/chemical_reaction/reagent_explosion/on_reaction(datum/reagents/holder, created_volume, turf/override) +/datum/chemical_reaction/reagent_explosion/on_reaction(datum/reagents/holder, multiplier, turf/override) if(!noexplosion) var/turf/T = override || get_turf(holder.my_atom) var/inside_msg @@ -20,7 +20,7 @@ message_admins("Reagent explosion reaction occurred at [ADMIN_VERBOSEJMP(T)][inside_msg]. Last Fingerprint: [touch_msg].") log_game("Reagent explosion reaction occurred at [AREACOORD(T)]. Last Fingerprint: [lastkey ? lastkey : "N/A"]." ) var/datum/effect_system/reagents_explosion/e = new() - e.set_up(modifier + round(created_volume/strengthdiv, 1), T, 0, 0) + e.set_up(modifier + round(multiplier/strengthdiv, 1), T, 0, 0) e.start() holder.clear_reagents() @@ -32,10 +32,10 @@ required_reagents = list(/datum/reagent/glycerol = 1, /datum/reagent/toxin/acid/fluacid = 1, /datum/reagent/toxin/acid = 1) strengthdiv = 2 -/datum/chemical_reaction/reagent_explosion/nitroglycerin/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/reagent_explosion/nitroglycerin/on_reaction(datum/reagents/holder, multiplier) if(holder.has_reagent(/datum/reagent/stabilizing_agent)) return - holder.remove_reagent(/datum/reagent/nitroglycerin, created_volume*2) + holder.remove_reagent(/datum/reagent/nitroglycerin, multiplier*2) ..() /datum/chemical_reaction/reagent_explosion/nitroglycerin_explosion @@ -57,10 +57,10 @@ id = "holyboom" required_reagents = list(/datum/reagent/water/holywater = 1, /datum/reagent/potassium = 1) -/datum/chemical_reaction/reagent_explosion/potassium_explosion/holyboom/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/reagent_explosion/potassium_explosion/holyboom/on_reaction(datum/reagents/holder, multiplier) var/turf/T = get_turf(holder.my_atom) - if(created_volume >= 150) - playsound(get_turf(holder.my_atom), 'sound/effects/pray.ogg', 80, 0, round(created_volume/48)) + if(multiplier >= 150) + playsound(get_turf(holder.my_atom), 'sound/effects/pray.ogg', 80, 0, round(multiplier/48)) strengthdiv = 8 for(var/mob/living/simple_animal/revenant/R in get_hearers_in_view(7,get_turf(holder.my_atom))) var/deity @@ -73,13 +73,13 @@ R.reveal(100) R.adjustHealth(50) sleep(20) - for(var/mob/living/carbon/C in get_hearers_in_view(round(created_volume/48,1),get_turf(holder.my_atom))) + for(var/mob/living/carbon/C in get_hearers_in_view(round(multiplier/48,1),get_turf(holder.my_atom))) if(iscultist(C)) to_chat(C, "The divine explosion sears you!") C.Knockdown(40) C.adjust_fire_stacks(5) C.IgniteMob() - ..(holder, created_volume, T) + ..(holder, multiplier, T) /datum/chemical_reaction/blackpowder @@ -97,9 +97,9 @@ modifier = 1 mix_message = "Sparks start flying around the black powder!" -/datum/chemical_reaction/reagent_explosion/blackpowder_explosion/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/reagent_explosion/blackpowder_explosion/on_reaction(datum/reagents/holder, multiplier) var/turf/T = get_turf(holder.my_atom) - ..(holder, created_volume, T) + ..(holder, multiplier, T) /datum/chemical_reaction/thermite name = "Thermite" @@ -112,11 +112,11 @@ id = "emp_pulse" required_reagents = list(/datum/reagent/uranium = 1, /datum/reagent/iron = 1) // Yes, laugh, it's the best recipe I could think of that makes a little bit of sense -/datum/chemical_reaction/emp_pulse/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/emp_pulse/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - // 100 created volume = 4 heavy range & 7 light range. A few tiles smaller than traitor EMP grandes. - // 200 created volume = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades. - empulse(location, round(created_volume / 12), round(created_volume / 7), 1) + // 100 multiplier = 4 heavy range & 7 light range. A few tiles smaller than traitor EMP grandes. + // 200 multiplier = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades. + empulse(location, round(multiplier / 12), round(multiplier / 7), 1) holder.clear_reagents() @@ -125,9 +125,9 @@ id = "beesplosion" required_reagents = list(/datum/reagent/consumable/honey = 1, /datum/reagent/medicine/strange_reagent = 1, /datum/reagent/radium = 1) -/datum/chemical_reaction/beesplosion/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/beesplosion/on_reaction(datum/reagents/holder, multiplier) var/location = holder.my_atom.drop_location() - if(created_volume < 5) + if(multiplier < 5) playsound(location,'sound/effects/sparks1.ogg', 100, TRUE) else playsound(location,'sound/creatures/bee.ogg', 100, TRUE) @@ -137,7 +137,7 @@ if(required_reagents[R.type]) continue beeagents += R - var/bee_amount = round(created_volume * 0.2) + var/bee_amount = round(multiplier * 0.2) for(var/i in 1 to bee_amount) var/mob/living/simple_animal/hostile/poison/bees/short/new_bee = new(location) if(LAZYLEN(beeagents)) @@ -157,7 +157,7 @@ required_reagents = list(/datum/reagent/chlorine = 1, /datum/reagent/fluorine = 3) required_temp = 424 -/datum/chemical_reaction/clf3/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/clf3/on_reaction(datum/reagents/holder, multiplier) var/turf/T = get_turf(holder.my_atom) for(var/turf/turf in range(1,T)) new /obj/effect/hotspot(turf) @@ -172,7 +172,7 @@ modifier = 1 mob_react = FALSE -/datum/chemical_reaction/reagent_explosion/methsplosion/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/reagent_explosion/methsplosion/on_reaction(datum/reagents/holder, multiplier) var/turf/T = get_turf(holder.my_atom) for(var/turf/turf in range(1,T)) new /obj/effect/hotspot(turf) @@ -190,12 +190,12 @@ results = list(/datum/reagent/sorium = 4) required_reagents = list(/datum/reagent/mercury = 1, /datum/reagent/oxygen = 1, /datum/reagent/nitrogen = 1, /datum/reagent/carbon = 1) -/datum/chemical_reaction/sorium/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/sorium/on_reaction(datum/reagents/holder, multiplier) if(holder.has_reagent(/datum/reagent/stabilizing_agent)) return - holder.remove_reagent(/datum/reagent/sorium, created_volume*4) + holder.remove_reagent(/datum/reagent/sorium, multiplier*4) var/turf/T = get_turf(holder.my_atom) - var/range = CLAMP(sqrt(created_volume*4), 1, 6) + var/range = CLAMP(sqrt(multiplier*4), 1, 6) goonchem_vortex(T, 1, range) /datum/chemical_reaction/sorium_vortex @@ -204,9 +204,9 @@ required_reagents = list(/datum/reagent/sorium = 1) required_temp = 474 -/datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, multiplier) var/turf/T = get_turf(holder.my_atom) - var/range = CLAMP(sqrt(created_volume), 1, 6) + var/range = CLAMP(sqrt(multiplier), 1, 6) goonchem_vortex(T, 1, range) /datum/chemical_reaction/liquid_dark_matter @@ -215,12 +215,12 @@ results = list(/datum/reagent/liquid_dark_matter = 3) required_reagents = list(/datum/reagent/stable_plasma = 1, /datum/reagent/radium = 1, /datum/reagent/carbon = 1) -/datum/chemical_reaction/liquid_dark_matter/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/liquid_dark_matter/on_reaction(datum/reagents/holder, multiplier) if(holder.has_reagent(/datum/reagent/stabilizing_agent)) return - holder.remove_reagent(/datum/reagent/liquid_dark_matter, created_volume*3) + holder.remove_reagent(/datum/reagent/liquid_dark_matter, multiplier*3) var/turf/T = get_turf(holder.my_atom) - var/range = CLAMP(sqrt(created_volume*3), 1, 6) + var/range = CLAMP(sqrt(multiplier*3), 1, 6) goonchem_vortex(T, 0, range) /datum/chemical_reaction/ldm_vortex @@ -229,9 +229,9 @@ required_reagents = list(/datum/reagent/liquid_dark_matter = 1) required_temp = 474 -/datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, multiplier) var/turf/T = get_turf(holder.my_atom) - var/range = CLAMP(sqrt(created_volume/2), 1, 6) + var/range = CLAMP(sqrt(multiplier/2), 1, 6) goonchem_vortex(T, 0, range) /datum/chemical_reaction/flash_powder @@ -240,12 +240,12 @@ results = list(/datum/reagent/flash_powder = 3) required_reagents = list(/datum/reagent/aluminium = 1, /datum/reagent/potassium = 1, /datum/reagent/sulfur = 1 ) -/datum/chemical_reaction/flash_powder/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/flash_powder/on_reaction(datum/reagents/holder, multiplier) if(holder.has_reagent(/datum/reagent/stabilizing_agent)) return var/location = get_turf(holder.my_atom) do_sparks(2, TRUE, location) - var/range = created_volume/3 + var/range = multiplier/3 if(isatom(holder.my_atom)) var/atom/A = holder.my_atom A.flash_lighting_fx(_range = (range + 2), _reset_lighting = FALSE) @@ -255,7 +255,7 @@ C.Knockdown(60) else C.Stun(100) - holder.remove_reagent(/datum/reagent/flash_powder, created_volume*3) + holder.remove_reagent(/datum/reagent/flash_powder, multiplier*3) /datum/chemical_reaction/flash_powder_flash name = "Flash powder activation" @@ -263,10 +263,10 @@ required_reagents = list(/datum/reagent/flash_powder = 1) required_temp = 374 -/datum/chemical_reaction/flash_powder_flash/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/flash_powder_flash/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) do_sparks(2, TRUE, location) - var/range = created_volume/10 + var/range = multiplier/10 if(isatom(holder.my_atom)) var/atom/A = holder.my_atom A.flash_lighting_fx(_range = (range + 2), _reset_lighting = FALSE) @@ -283,11 +283,11 @@ results = list(/datum/reagent/smoke_powder = 3) required_reagents = list(/datum/reagent/potassium = 1, /datum/reagent/consumable/sugar = 1, /datum/reagent/phosphorus = 1) -/datum/chemical_reaction/smoke_powder/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/smoke_powder/on_reaction(datum/reagents/holder, multiplier) if(holder.has_reagent(/datum/reagent/stabilizing_agent)) return - holder.remove_reagent(/datum/reagent/smoke_powder, created_volume*3) - var/smoke_radius = round(sqrt(created_volume * 1.5), 1) + holder.remove_reagent(/datum/reagent/smoke_powder, multiplier*3) + var/smoke_radius = round(sqrt(multiplier * 1.5), 1) var/location = get_turf(holder.my_atom) var/datum/effect_system/smoke_spread/chem/S = new S.attach(location) @@ -305,9 +305,9 @@ required_temp = 374 mob_react = FALSE -/datum/chemical_reaction/smoke_powder_smoke/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/smoke_powder_smoke/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) - var/smoke_radius = round(sqrt(created_volume / 2), 1) + var/smoke_radius = round(sqrt(multiplier / 2), 1) var/datum/effect_system/smoke_spread/chem/S = new S.attach(location) playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) @@ -323,13 +323,13 @@ results = list(/datum/reagent/sonic_powder = 3) required_reagents = list(/datum/reagent/oxygen = 1, /datum/reagent/consumable/space_cola = 1, /datum/reagent/phosphorus = 1) -/datum/chemical_reaction/sonic_powder/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/sonic_powder/on_reaction(datum/reagents/holder, multiplier) if(holder.has_reagent(/datum/reagent/stabilizing_agent)) return - holder.remove_reagent(/datum/reagent/sonic_powder, created_volume*3) + holder.remove_reagent(/datum/reagent/sonic_powder, multiplier*3) var/location = get_turf(holder.my_atom) playsound(location, 'sound/effects/bang.ogg', 25, 1) - for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/3, location)) + for(var/mob/living/carbon/C in get_hearers_in_view(multiplier/3, location)) C.soundbang_act(1, 100, rand(0, 5)) /datum/chemical_reaction/sonic_powder_deafen @@ -338,10 +338,10 @@ required_reagents = list(/datum/reagent/sonic_powder = 1) required_temp = 374 -/datum/chemical_reaction/sonic_powder_deafen/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/sonic_powder_deafen/on_reaction(datum/reagents/holder, multiplier) var/location = get_turf(holder.my_atom) playsound(location, 'sound/effects/bang.ogg', 25, 1) - for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location)) + for(var/mob/living/carbon/C in get_hearers_in_view(multiplier/10, location)) C.soundbang_act(1, 100, rand(0, 5)) /datum/chemical_reaction/phlogiston @@ -350,12 +350,12 @@ results = list(/datum/reagent/phlogiston = 3) required_reagents = list(/datum/reagent/phosphorus = 1, /datum/reagent/toxin/acid = 1, /datum/reagent/stable_plasma = 1) -/datum/chemical_reaction/phlogiston/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/phlogiston/on_reaction(datum/reagents/holder, multiplier) if(holder.has_reagent(/datum/reagent/stabilizing_agent)) return var/turf/open/T = get_turf(holder.my_atom) if(istype(T)) - T.atmos_spawn_air("plasma=[created_volume];TEMP=1000") + T.atmos_spawn_air("plasma=[multiplier];TEMP=1000") holder.clear_reagents() return @@ -371,7 +371,7 @@ results = list(/datum/reagent/cryostylane = 3) required_reagents = list(/datum/reagent/water = 1, /datum/reagent/stable_plasma = 1, /datum/reagent/nitrogen = 1) -/datum/chemical_reaction/cryostylane/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/cryostylane/on_reaction(datum/reagents/holder, multiplier) holder.chem_temp = 20 // cools the fuck down return @@ -382,8 +382,8 @@ required_reagents = list(/datum/reagent/cryostylane = 1, /datum/reagent/oxygen = 1) mob_react = FALSE -/datum/chemical_reaction/cryostylane_oxygen/on_reaction(datum/reagents/holder, created_volume) - holder.chem_temp = max(holder.chem_temp - 10*created_volume,0) +/datum/chemical_reaction/cryostylane_oxygen/on_reaction(datum/reagents/holder, multiplier) + holder.chem_temp = max(holder.chem_temp - 10*multiplier,0) /datum/chemical_reaction/pyrosium_oxygen name = "ephemeral pyrosium reaction" @@ -392,8 +392,8 @@ required_reagents = list(/datum/reagent/pyrosium = 1, /datum/reagent/oxygen = 1) mob_react = FALSE -/datum/chemical_reaction/pyrosium_oxygen/on_reaction(datum/reagents/holder, created_volume) - holder.chem_temp += 10*created_volume +/datum/chemical_reaction/pyrosium_oxygen/on_reaction(datum/reagents/holder, multiplier) + holder.chem_temp += 10*multiplier /datum/chemical_reaction/pyrosium name = "pyrosium" @@ -401,7 +401,7 @@ results = list(/datum/reagent/pyrosium = 3) required_reagents = list(/datum/reagent/stable_plasma = 1, /datum/reagent/radium = 1, /datum/reagent/phosphorus = 1) -/datum/chemical_reaction/pyrosium/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/pyrosium/on_reaction(datum/reagents/holder, multiplier) holder.chem_temp = 20 // also cools the fuck down return @@ -431,20 +431,20 @@ mix_sound = 'sound/machines/defib_zap.ogg' var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN -/datum/chemical_reaction/reagent_explosion/teslium_lightning/on_reaction(datum/reagents/holder, created_volume) - var/T1 = created_volume * 20 //100 units : Zap 3 times, with powers 2000/5000/12000. Tesla revolvers have a power of 10000 for comparison. - var/T2 = created_volume * 50 - var/T3 = created_volume * 120 +/datum/chemical_reaction/reagent_explosion/teslium_lightning/on_reaction(datum/reagents/holder, multiplier) + var/T1 = multiplier * 20 //100 units : Zap 3 times, with powers 2000/5000/12000. Tesla revolvers have a power of 10000 for comparison. + var/T2 = multiplier * 50 + var/T3 = multiplier * 120 sleep(5) - if(created_volume >= 75) + if(multiplier >= 75) tesla_zap(holder.my_atom, 7, T1, tesla_flags) playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1) sleep(15) - if(created_volume >= 40) + if(multiplier >= 40) tesla_zap(holder.my_atom, 7, T2, tesla_flags) playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1) sleep(15) - if(created_volume >= 10) //10 units minimum for lightning, 40 units for secondary blast, 75 units for tertiary blast. + if(multiplier >= 10) //10 units minimum for lightning, 40 units for secondary blast, 75 units for tertiary blast. tesla_zap(holder.my_atom, 7, T3, tesla_flags) playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1) ..() @@ -490,7 +490,7 @@ else return FALSE -/datum/chemical_reaction/reagent_explosion/lingblood/on_reaction(datum/reagents/holder, created_volume, specialreact) +/datum/chemical_reaction/reagent_explosion/lingblood/on_reaction(datum/reagents/holder, multiplier, specialreact) if(specialreact >= 10) return ..() else diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index 5228d4a281..eb473950d5 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -70,6 +70,14 @@ required_other = TRUE required_container = /obj/item/slime_extract/green +/datum/chemical_reaction/slime/slimemammal + name = "Mammal Mutation Toxin" + id = /datum/reagent/mutationtoxin/mammal + results = list(/datum/reagent/mutationtoxin/mammal = 1) + required_reagents = list(/datum/reagent/water = 1) + required_other = TRUE + required_container = /obj/item/slime_extract/green + //Metal /datum/chemical_reaction/slime/slimemetal name = "Slime Metal" @@ -290,7 +298,7 @@ required_container = /obj/item/slime_extract/yellow required_other = TRUE -/datum/chemical_reaction/slime/slimeoverload/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/slime/slimeoverload/on_reaction(datum/reagents/holder, multiplier) empulse(get_turf(holder.my_atom), 3, 7) ..() @@ -301,7 +309,7 @@ required_container = /obj/item/slime_extract/yellow required_other = TRUE -/datum/chemical_reaction/slime/slimecell/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/slime/slimecell/on_reaction(datum/reagents/holder, multiplier) new /obj/item/stock_parts/cell/high/slime(get_turf(holder.my_atom)) ..() @@ -505,7 +513,7 @@ required_container = /obj/item/slime_extract/bluespace required_other = TRUE -/datum/chemical_reaction/slime/slimefloor2/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/slime/slimefloor2/on_reaction(datum/reagents/holder, multiplier) new /obj/item/stack/tile/bluespace(get_turf(holder.my_atom), 25) ..() @@ -517,7 +525,7 @@ required_container = /obj/item/slime_extract/bluespace required_other = TRUE -/datum/chemical_reaction/slime/slimecrystal/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/slime/slimecrystal/on_reaction(datum/reagents/holder, multiplier) var/obj/item/stack/ore/bluespace_crystal/BC = new (get_turf(holder.my_atom)) BC.visible_message("The [BC.name] appears out of thin air!") ..() @@ -529,7 +537,7 @@ required_container = /obj/item/slime_extract/bluespace required_other = TRUE -/datum/chemical_reaction/slime/slimeradio/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/slime/slimeradio/on_reaction(datum/reagents/holder, multiplier) new /obj/item/slimepotion/slime/slimeradio(get_turf(holder.my_atom)) ..() @@ -565,9 +573,16 @@ required_other = TRUE /datum/chemical_reaction/slime/slimestop/on_reaction(datum/reagents/holder) + sleep(50) + var/obj/item/slime_extract/sepia/extract = holder.my_atom var/turf/T = get_turf(holder.my_atom) - var/list/M = list(get_mob_by_key(holder.my_atom.fingerprintslast)) - new /obj/effect/timestop(T, null, null, M) + new /obj/effect/timestop(T, null, null, null) + if(istype(extract)) + if(extract.Uses > 0) + var/mob/lastheld = get_mob_by_key(holder.my_atom.fingerprintslast) + if(lastheld && !lastheld.equip_to_slot_if_possible(extract, SLOT_HANDS, disable_warning = TRUE)) + extract.forceMove(get_turf(lastheld)) + ..() /datum/chemical_reaction/slime/slimecamera @@ -626,8 +641,8 @@ required_other = TRUE required_container = /obj/item/slime_extract/rainbow -/datum/chemical_reaction/slime/slimeRNG/on_reaction(datum/reagents/holder, created_volume) - if(created_volume >= 5) +/datum/chemical_reaction/slime/slimeRNG/on_reaction(datum/reagents/holder, multiplier) + if(multiplier >= 5) var/obj/item/grenade/clusterbuster/slime/S = new (get_turf(holder.my_atom)) S.visible_message("Infused with plasma, the core begins to expand uncontrollably!") S.icon_state = "[S.base_state]_active" @@ -646,7 +661,7 @@ required_other = TRUE required_container = /obj/item/slime_extract/rainbow -/datum/chemical_reaction/slime/slimebomb/on_reaction(datum/reagents/holder, created_volume) +/datum/chemical_reaction/slime/slimebomb/on_reaction(datum/reagents/holder, multiplier) var/obj/item/grenade/clusterbuster/slime/volatile/S = new (holder.my_atom.loc) S.visible_message("Infused with slime jelly, the core begins to expand uncontrollably!") S.icon_state = "[S.base_state]_active" diff --git a/code/modules/reagents/chemistry/recipes/special.dm b/code/modules/reagents/chemistry/recipes/special.dm index 5ad9728b22..cc63a8c692 100644 --- a/code/modules/reagents/chemistry/recipes/special.dm +++ b/code/modules/reagents/chemistry/recipes/special.dm @@ -186,6 +186,7 @@ GLOBAL_LIST_INIT(food_reagents, build_reagents_to_food()) //reagentid = related var/datum/chemical_reaction/recipe = get_chemical_reaction(recipe_id) if(!recipe) info = "This recipe is illegible." + return var/list/dat = list("
        ") for(var/rid in recipe.required_reagents) var/datum/reagent/R = GLOB.chemical_reagents_list[rid] diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 321b63da1e..23176f8a05 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -1,6 +1,3 @@ -#define PH_WEAK (1 << 0) -#define TEMP_WEAK (1 << 1) - /obj/item/reagent_containers name = "Container" desc = "..." @@ -9,14 +6,13 @@ w_class = WEIGHT_CLASS_TINY var/amount_per_transfer_from_this = 5 var/list/possible_transfer_amounts = list(5,10,15,20,25,30) - var/APTFT_altclick = TRUE //will the set amount_per_transfer_from_this proc be called on AltClick() ? var/volume = 30 - var/reagent_flags + var/reagent_flags //used to determine the reagent holder flags on add_initial_reagents() var/list/list_reagents = null var/spawned_disease = null var/disease_amount = 20 var/spillable = FALSE - var/beaker_weakness_bitflag = NONE//Bitflag! + var/container_flags = APTFT_ALTCLICK|APTFT_VERB //the container item flags var/container_HP = 2 var/cached_icon @@ -24,7 +20,7 @@ . = ..() if(isnum(vol) && vol > 0) volume = vol - if(length(possible_transfer_amounts)) + if(container_flags & APTFT_VERB && length(possible_transfer_amounts)) verbs += /obj/item/reagent_containers/proc/set_APTFT create_reagents(volume, reagent_flags) if(spawned_disease) @@ -37,12 +33,12 @@ . = ..() if(length(possible_transfer_amounts) > 1) . += "Currently transferring [amount_per_transfer_from_this] units per use." - if(APTFT_altclick && user.Adjacent(src)) + if(container_flags & APTFT_ALTCLICK && user.Adjacent(src)) . += "Alt-click it to set its transfer amount." /obj/item/reagent_containers/AltClick(mob/user) . = ..() - if(APTFT_altclick && length(possible_transfer_amounts) > 1 && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) + if(container_flags & APTFT_ALTCLICK && length(possible_transfer_amounts) > 1 && user.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) set_APTFT() return TRUE @@ -102,16 +98,18 @@ reagents.expose_temperature(exposed_temperature) ..() -/obj/item/reagent_containers/throw_impact(atom/target) +/obj/item/reagent_containers/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() - SplashReagents(target, TRUE) + SplashReagents(hit_atom, TRUE) /obj/item/reagent_containers/proc/bartender_check(atom/target) . = FALSE - if(target.CanPass(src, get_turf(src)) && thrownby && thrownby.actions) - for(var/datum/action/innate/drink_fling/D in thrownby.actions) - if(D.active) - return TRUE + var/turf/T = get_turf(src) + if(!T || target.CanPass(src, T) || !thrownby || !thrownby.actions) + return + for(var/datum/action/innate/drink_fling/D in thrownby.actions) + if(D.active) + return TRUE /obj/item/reagent_containers/proc/ForceResetRotation() transform = initial(transform) @@ -155,7 +153,7 @@ //melts plastic beakers /obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M) reagents.expose_temperature(1000) - if(beaker_weakness_bitflag & TEMP_WEAK) + if(container_flags & TEMP_WEAK) var/list/seen = viewers(5, get_turf(src)) var/iconhtml = icon2html(src, seen) for(var/mob/H in seen) @@ -170,13 +168,13 @@ temp_check() /obj/item/reagent_containers/proc/temp_check() - if(beaker_weakness_bitflag & TEMP_WEAK) + if(container_flags & TEMP_WEAK) if(reagents.chem_temp >= 444)//assuming polypropylene START_PROCESSING(SSobj, src) //melts glass beakers /obj/item/reagent_containers/proc/pH_check() - if(beaker_weakness_bitflag & PH_WEAK) + if(container_flags & PH_WEAK) if((reagents.pH < 1.5) || (reagents.pH > 12.5)) START_PROCESSING(SSobj, src) else if((reagents.pH < -3) || (reagents.pH > 17)) @@ -190,7 +188,7 @@ cached_icon = icon_state var/damage var/cause - if(beaker_weakness_bitflag & PH_WEAK) + if(container_flags & PH_WEAK) if(reagents.pH < 2) damage = (2 - reagents.pH)/20 cause = "from the extreme pH" @@ -201,7 +199,7 @@ cause = "from the extreme pH" playsound(get_turf(src), 'sound/FermiChem/bufferadd.ogg', 50, 1) - if(beaker_weakness_bitflag & TEMP_WEAK) + if(container_flags & TEMP_WEAK) if(reagents.chem_temp >= 444) if(damage) damage += (reagents.chem_temp/444)/5 diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 624a5e62cb..db0aa8ce99 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -8,7 +8,6 @@ resistance_flags = ACID_PROOF container_HP = 2 - /obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target) if(!canconsume(M, user)) return @@ -22,13 +21,9 @@ if(istype(M)) if(user.a_intent == INTENT_HARM) - var/R M.visible_message("[user] splashes the contents of [src] onto [M]!", \ "[user] splashes the contents of [src] onto [M]!") - if(reagents) - for(var/datum/reagent/A in reagents.reagent_list) - R += A.type + " (" - R += num2text(A.volume) + ")," + var/R = reagents?.log_list() if(isturf(target) && reagents.reagent_list.len && thrownby) log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]") message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] at [ADMIN_VERBOSEJMP(target)].") @@ -36,7 +31,8 @@ log_combat(user, M, "splashed", R) reagents.clear_reagents() else - if(M != user) + var/self_fed = M == user + if(!self_fed) M.visible_message("[user] attempts to feed something to [M].", \ "[user] attempts to feed something to you.") if(!do_mob(user, M)) @@ -49,7 +45,7 @@ to_chat(user, "You swallow a gulp of [src].") var/fraction = min(5/reagents.total_volume, 1) reagents.reaction(M, INGEST, fraction) - addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5), 5) + addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5, null, null, null, self_fed? "self swallowed" : "fed by [user]"), 5) playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1) /obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity) @@ -66,7 +62,7 @@ to_chat(user, "[target] is full.") return - var/trans = reagents.trans_to(target, amount_per_transfer_from_this) + var/trans = reagents.trans_to(target, amount_per_transfer_from_this, log = "reagentcontainer-glass afterattack transfer to") to_chat(user, "You transfer [trans] unit\s of the solution to [target].") else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us. @@ -78,7 +74,7 @@ to_chat(user, "[src] is full.") return - var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, log = "reagentcontainer-glass afterattack fill from") to_chat(user, "You fill [src] with [trans] unit\s of the contents of [target].") else if(reagents.total_volume) @@ -101,12 +97,11 @@ to_chat(user, "[src] is full.") else to_chat(user, "You break [E] in [src].") - E.reagents.trans_to(src, E.reagents.total_volume) + E.reagents.trans_to(src, E.reagents.total_volume, log = "reagentcontainer-glass break egg in") qdel(E) return ..() - /obj/item/reagent_containers/glass/beaker name = "beaker" desc = "A beaker. It can hold up to 60 units. Unable to withstand extreme pHes." @@ -116,7 +111,7 @@ item_state = "beaker" materials = list(MAT_GLASS=500) possible_transfer_amounts = list(5,10,15,20,25,30,50,60) - beaker_weakness_bitflag = PH_WEAK + container_flags = PH_WEAK|APTFT_ALTCLICK|APTFT_VERB /obj/item/reagent_containers/glass/beaker/Initialize() . = ..() @@ -159,8 +154,37 @@ /obj/item/reagent_containers/glass/beaker/jar name = "honey jar" desc = "A jar for honey. It can hold up to 60 units of sweet delight. Unable to withstand reagents of an extreme pH." - icon = 'icons/obj/chemical.dmi' - icon_state = "vapour" + icon_state = "honey" + +/obj/item/reagent_containers/glass/beaker/glass_dish + name = "glass dish" + desc = "A tiny glass dish. It can hold up to 3 units. Unable to withstand reagents of an extreme pH." + materials = list(MAT_GLASS=500) + icon_state = "glass_disk" + possible_transfer_amounts = list(0.1,0.5,0.75,1,2,3) + volume = 3 + +/obj/item/reagent_containers/glass/beaker/flask/large + name = "large flask" + desc = "A large flask. It can hold up to 80 units. Unable to withstand reagents of an extreme pH." + materials = list(MAT_GLASS=2500) + icon_state = "flasklarge" + volume = 80 + +/obj/item/reagent_containers/glass/beaker/flask + name = "small flask" + desc = "A small flask. It can hold up to 40 units. Unable to withstand reagents of an extreme pH." + materials = list(MAT_GLASS=1000) + icon_state = "flasksmall" + volume = 40 + +/obj/item/reagent_containers/glass/beaker/flask/spouty + name = "flask with spout" + desc = "A flask with a spout! It can hold up to 120 units. Unable to withstand reagents of an extreme pH." + materials = list(MAT_GLASS=2500) + icon_state = "flaskspouty" + possible_transfer_amounts = list(1,2,3,4,5,10,15,20,25,30,50,100,120) + volume = 120 /obj/item/reagent_containers/glass/beaker/large name = "large beaker" @@ -180,11 +204,7 @@ volume = 180 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,180) - -/obj/item/reagent_containers/glass/beaker/plastic/Initialize() - beaker_weakness_bitflag &= ~PH_WEAK - beaker_weakness_bitflag |= TEMP_WEAK - . = ..() + container_flags = TEMP_WEAK|APTFT_ALTCLICK|APTFT_VERB /obj/item/reagent_containers/glass/beaker/plastic/update_icon() icon_state = "beakerlarge" // hack to lets us reuse the large beaker reagent fill states @@ -199,10 +219,7 @@ volume = 240 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,200,240) - -/obj/item/reagent_containers/glass/beaker/meta/Initialize() // why the fuck can't you just set the beaker weakness bitflags to nothing? fuck you - beaker_weakness_bitflag &= ~PH_WEAK - . = ..() + container_flags = APTFT_ALTCLICK|APTFT_VERB /obj/item/reagent_containers/glass/beaker/noreact name = "cryostasis beaker" @@ -213,13 +230,9 @@ reagent_flags = OPENCONTAINER | NO_REACT volume = 50 amount_per_transfer_from_this = 10 + container_flags = APTFT_ALTCLICK|APTFT_VERB container_HP = 10//shouldn't be needed -/obj/item/reagent_containers/glass/beaker/noreact/Initialize() - beaker_weakness_bitflag &= ~PH_WEAK - . = ..() - //reagents.set_reacting(FALSE) was this removed in a recent pr? - /obj/item/reagent_containers/glass/beaker/bluespace name = "bluespace beaker" desc = "A bluespace beaker, powered by experimental bluespace technology \ @@ -287,18 +300,15 @@ SLOT_L_STORE, SLOT_R_STORE,\ SLOT_GENERC_DEXTROUS_STORAGE ) + container_flags = APTFT_ALTCLICK|APTFT_VERB container_HP = 1 -/obj/item/reagent_containers/glass/bucket/Initialize() - beaker_weakness_bitflag |= TEMP_WEAK - . = ..() - /obj/item/reagent_containers/glass/bucket/attackby(obj/O, mob/user, params) if(istype(O, /obj/item/mop)) if(reagents.total_volume < 1) to_chat(user, "[src] is out of water!") else - reagents.trans_to(O, 5) + reagents.trans_to(O, 5, log = "reagentcontainer-bucket fill mop") to_chat(user, "You wet [O] in [src].") playsound(loc, 'sound/effects/slosh.ogg', 25, 1) else if(isprox(O)) @@ -342,12 +352,9 @@ volume = 50 amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,50) + container_flags = TEMP_WEAK|APTFT_ALTCLICK|APTFT_VERB container_HP = 1 -/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize() - beaker_weakness_bitflag |= TEMP_WEAK - . = ..() - /obj/item/reagent_containers/glass/beaker/waterbottle/empty list_reagents = list() diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index f509ad0b10..f4bb5e0d08 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -362,30 +362,14 @@ return /obj/item/hypospray/mkii/afterattack(atom/target, mob/user, proximity) - if(!vial) + if(!vial || !proximity || !isliving(target)) + return + var/mob/living/L = target + + if(!L.reagents || !L.can_inject(user, TRUE, user.zone_selected, penetrates)) return - if(!proximity) - return - - if(!ismob(target)) - return - - var/mob/living/L - if(isliving(target)) - L = target - if(!penetrates && !L.can_inject(user, 1)) //This check appears another four times, since otherwise the penetrating sprays will break in do_mob. - return - - if(!L && !target.is_injectable()) //only checks on non-living mobs, due to how can_inject() handles - to_chat(user, "You cannot directly fill [target]!") - return - - if(target.reagents.total_volume >= target.reagents.maximum_volume) - to_chat(user, "[target] is full.") - return - - if(ishuman(L)) + if(iscarbon(L)) var/obj/item/bodypart/affecting = L.get_bodypart(check_zone(user.zone_selected)) if(!affecting) to_chat(user, "The limb is missing!") @@ -394,84 +378,40 @@ to_chat(user, "Medicine won't work on a robotic limb!") return + //Always log attemped injections for admins var/contained = vial.reagents.log_list() log_combat(user, L, "attemped to inject", src, addition="which had [contained]") -//Always log attemped injections for admins - if(vial != null) - switch(mode) - if(HYPO_INJECT) - if(L) //living mob - if(L != user) - L.visible_message("[user] is trying to inject [L] with [src]!", \ - "[user] is trying to inject [L] with [src]!") - if(!do_mob(user, L, inject_wait)) - return - if(!penetrates && !L.can_inject(user, 1)) - return - if(!vial.reagents.total_volume) - return - if(L.reagents.total_volume >= L.reagents.maximum_volume) - return - L.visible_message("[user] uses the [src] on [L]!", \ - "[user] uses the [src] on [L]!") - else - if(!do_mob(user, L, inject_self)) - return - if(!penetrates && !L.can_inject(user, 1)) - return - if(!vial.reagents.total_volume) - return - if(L.reagents.total_volume >= L.reagents.maximum_volume) - return - log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [src.mode])") - L.log_message("applied [src] to themselves ([contained]).", INDIVIDUAL_ATTACK_LOG) - var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1) - vial.reagents.reaction(L, INJECT, fraction) - vial.reagents.trans_to(target, vial.amount_per_transfer_from_this) - if(vial.amount_per_transfer_from_this >= 15) - playsound(loc,'sound/items/hypospray_long.ogg',50, 1, -1) - if(vial.amount_per_transfer_from_this < 15) - playsound(loc, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1) - to_chat(user, "You inject [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units.") - - if(HYPO_SPRAY) - if(L) //living mob - if(L != user) - L.visible_message("[user] is trying to spray [L] with [src]!", \ - "[user] is trying to spray [L] with [src]!") - if(!do_mob(user, L, spray_wait)) - return - if(!penetrates && !L.can_inject(user, 1)) - return - if(!vial.reagents.total_volume) - return - if(L.reagents.total_volume >= L.reagents.maximum_volume) - return - L.visible_message("[user] uses the [src] on [L]!", \ - "[user] uses the [src] on [L]!") - else - if(!do_mob(user, L, spray_self)) - return - if(!penetrates && !L.can_inject(user, 1)) - return - if(!vial.reagents.total_volume) - return - if(L.reagents.total_volume >= L.reagents.maximum_volume) - return - log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [src.mode])") - L.log_message("applied [src] to themselves ([contained]).", INDIVIDUAL_ATTACK_LOG) - var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1) - vial.reagents.reaction(L, PATCH, fraction) - vial.reagents.trans_to(target, vial.amount_per_transfer_from_this) - if(vial.amount_per_transfer_from_this >= 15) - playsound(loc,'sound/items/hypospray_long.ogg',50, 1, -1) - if(vial.amount_per_transfer_from_this < 15) - playsound(loc, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1) - to_chat(user, "You spray [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units.") - else - to_chat(user, "[src] doesn't work here!") + if(!vial) + to_chat(user, "[src] doesn't have any vial installed!") return + if(!vial.reagents.total_volume) + to_chat(user, "[src]'s vial is empty!") + return + + var/fp_verb = mode == HYPO_SPRAY ? "spray" : "inject" + var/method = mode == HYPO_SPRAY ? TOUCH : INJECT + + if(L != user) + L.visible_message("[user] is trying to [fp_verb] [L] with [src]!", \ + "[user] is trying to [fp_verb] you with [src]!") + if(!do_mob(user, L, inject_wait, extra_checks = CALLBACK(L, /mob/living/proc/can_inject, user, FALSE, user.zone_selected, penetrates))) + return + if(!vial.reagents.total_volume) + return + log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [mode])") + if(L != user) + L.visible_message("[user] uses the [src] on [L]!", \ + "[user] uses the [src] on you!") + else + L.log_message("applied [src] to themselves ([contained]).", INDIVIDUAL_ATTACK_LOG) + + var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1) + vial.reagents.reaction(L, method, fraction) + vial.reagents.trans_to(target, vial.amount_per_transfer_from_this) + var/long_sound = vial.amount_per_transfer_from_this >= 15 + playsound(loc, long_sound ? 'sound/items/hypospray_long.ogg' : pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1) + to_chat(user, "You [fp_verb] [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units.") /obj/item/hypospray/mkii/attack_self(mob/living/user) if(user) diff --git a/code/modules/reagents/reagent_containers/hypovial.dm b/code/modules/reagents/reagent_containers/hypovial.dm index c0db92e0e8..db2d73c697 100644 --- a/code/modules/reagents/reagent_containers/hypovial.dm +++ b/code/modules/reagents/reagent_containers/hypovial.dm @@ -7,7 +7,7 @@ spillable = FALSE volume = 10 possible_transfer_amounts = list(1,2,5,10) - APTFT_altclick = FALSE + container_flags = APTFT_VERB obj_flags = UNIQUE_RENAME unique_reskin = list("hypovial" = "hypovial", "red hypovial" = "hypovial-b", @@ -25,9 +25,6 @@ if(!icon_state) icon_state = "hypovial" update_icon() -// beaker_weakness_bitflag |= PH_WEAK // fuck you if you're using these like beakers -// beaker_weakness_bitflag |= TEMP_WEAK - /obj/item/reagent_containers/glass/bottle/vial/on_reagent_change() update_icon() diff --git a/code/modules/reagents/reagent_containers/rags.dm b/code/modules/reagents/reagent_containers/rags.dm index 812b3144e9..59c956acd6 100644 --- a/code/modules/reagents/reagent_containers/rags.dm +++ b/code/modules/reagents/reagent_containers/rags.dm @@ -8,7 +8,7 @@ reagent_flags = REFILLABLE | DRAINABLE amount_per_transfer_from_this = 5 possible_transfer_amounts = list() - APTFT_altclick = FALSE + container_flags = APTFT_VERB volume = 5 spillable = FALSE var/wipe_sound @@ -118,6 +118,7 @@ item_flags = NOBLUDGEON | NO_UNIFORM_REQUIRED //so it can be worn on the belt slot even with no uniform. force = 1 w_class = WEIGHT_CLASS_NORMAL + mutantrace_variation = STYLE_DIGITIGRADE attack_verb = list("whipped") hitsound = 'sound/items/towelwhip.ogg' volume = 10 diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index edaa5ce269..e8c8d14141 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -23,6 +23,7 @@ amount_per_transfer_from_this = 5 volume = 250 possible_transfer_amounts = list(5,10,15,20,25,30,50,100) + container_flags = NONE //APTFT is alternated between the initial value and stream_amount and shouldn't be exploited. /obj/item/reagent_containers/spray/afterattack(atom/A, mob/user) . = ..() diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index 46ddb1e2ed..11c80b14ee 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -149,8 +149,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) "You struggle to pry up \the [src] with \the [I].") if(I.use_tool(src, user, 40, volume=40)) if(!(stat & BROKEN)) - var/obj/item/conveyor_construct/C = new/obj/item/conveyor_construct(src.loc) - C.id = id + var/obj/item/stack/conveyor/C = new /obj/item/stack/conveyor(loc, 1, TRUE, id) transfer_fingerprints_to(C) to_chat(user, "You remove the conveyor belt.") qdel(src) @@ -326,37 +325,6 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) if((dir == NORTH) || (dir == WEST)) invert_icon = TRUE -// -// CONVEYOR CONSTRUCTION STARTS HERE -// - -/obj/item/conveyor_construct - icon = 'icons/obj/recycling.dmi' - icon_state = "conveyor_construct" - name = "conveyor belt assembly" - desc = "A conveyor belt assembly." - w_class = WEIGHT_CLASS_BULKY - var/id = "" //inherited by the belt - -/obj/item/conveyor_construct/attackby(obj/item/I, mob/user, params) - ..() - if(istype(I, /obj/item/conveyor_switch_construct)) - to_chat(user, "You link the switch to the conveyor belt assembly.") - var/obj/item/conveyor_switch_construct/C = I - id = C.id - -/obj/item/conveyor_construct/afterattack(atom/A, mob/user, proximity) - . = ..() - if(!proximity || user.stat || !isfloorturf(A) || istype(A, /area/shuttle)) - return - var/cdir = get_dir(A, user) - if(A == user.loc) - to_chat(user, "You cannot place a conveyor belt under yourself.") - return - var/obj/machinery/conveyor/C = new/obj/machinery/conveyor(A, cdir, id) - transfer_fingerprints_to(C) - qdel(src) - /obj/item/conveyor_switch_construct name = "conveyor switch assembly" desc = "A conveyor control switch assembly." @@ -369,6 +337,11 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) . = ..() id = "[rand()]" //this couldn't possibly go wrong +/obj/item/conveyor_switch_construct/attack_self(mob/user) + for(var/obj/item/stack/conveyor/C in view()) + C.id = id + to_chat(user, "You have linked all nearby conveyor belt assemblies to this switch.") + /obj/item/conveyor_switch_construct/afterattack(atom/A, mob/user, proximity) . = ..() if(!proximity || user.stat || !isfloorturf(A) || istype(A, /area/shuttle)) @@ -385,6 +358,49 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) transfer_fingerprints_to(NC) qdel(src) +/obj/item/stack/conveyor + name = "conveyor belt assembly" + desc = "A conveyor belt assembly." + icon = 'icons/obj/recycling.dmi' + icon_state = "conveyor_construct" + max_amount = 30 + singular_name = "conveyor belt" + w_class = WEIGHT_CLASS_BULKY + ///id for linking + var/id = "" + +/obj/item/stack/conveyor/Initialize(mapload, new_amount, merge = TRUE, _id) + . = ..() + id = _id + +/obj/item/stack/conveyor/afterattack(atom/A, mob/user, proximity) + . = ..() + if(!proximity || user.stat || !isfloorturf(A) || istype(A, /area/shuttle)) + return + var/cdir = get_dir(A, user) + if(A == user.loc) + to_chat(user, "You cannot place a conveyor belt under yourself!") + return + var/obj/machinery/conveyor/C = new/obj/machinery/conveyor(A, cdir, id) + transfer_fingerprints_to(C) + use(1) + +/obj/item/stack/conveyor/attackby(obj/item/I, mob/user, params) + ..() + if(istype(I, /obj/item/conveyor_switch_construct)) + to_chat(user, "You link the switch to the conveyor belt assembly.") + var/obj/item/conveyor_switch_construct/C = I + id = C.id + +/obj/item/stack/conveyor/update_weight() + return FALSE + +/obj/item/stack/conveyor/thirty + amount = 30 + +/obj/item/stack/conveyor/fifteen + amount = 15 + /obj/item/paper/guides/conveyor name = "paper- 'Nano-it-up U-build series, #9: Build your very own conveyor belt, in SPACE'" info = "

        Congratulations!

        You are now the proud owner of the best conveyor set available for space mail order! We at Nano-it-up know you love to prepare your own structures without wasting time, so we have devised a special streamlined assembly procedure that puts all other mail-order products to shame!

        Firstly, you need to link the conveyor switch assembly to each of the conveyor belt assemblies. After doing so, you simply need to install the belt assemblies onto the floor, et voila, belt built. Our special Nano-it-up smart switch will detected any linked assemblies as far as the eye can see! This convenience, you can only have it when you Nano-it-up. Stay nano!

        " diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 7025a649e6..90f96d0352 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -21,6 +21,8 @@ var/flush_count = 0 //this var adds 1 once per tick. When it reaches flush_every_ticks it resets and tries to flush. var/last_sound = 0 var/obj/structure/disposalconstruct/stored + ui_x = 300 + ui_y = 180 // create a new disposal // find the attached trunk (if present) and init gas resvr. @@ -140,7 +142,7 @@ /obj/machinery/disposal/proc/can_stuff_mob_in(mob/living/target, mob/living/user, pushing = FALSE) if(!pushing && !iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves. - if (iscyborg(user)) + if(iscyborg(user)) var/mob/living/silicon/robot/borg = user if (!borg.module || !borg.module.canDispose) return @@ -286,59 +288,57 @@ var/datum/oracle_ui/themed/nano/ui obj_flags = CAN_BE_HIT | USES_TGUI | SHOVABLE_ONTO -/obj/machinery/disposal/bin/Initialize(mapload, obj/structure/disposalconstruct/make_from) - . = ..() - ui = new /datum/oracle_ui/themed/nano(src, 330, 190, "disposal_bin") - ui.auto_refresh = TRUE - ui.can_resize = FALSE // attack by item places it in to disposal /obj/machinery/disposal/bin/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/storage/bag/trash)) //Not doing component overrides because this is a specific type. - var/obj/item/storage/bag/trash/T = I - var/datum/component/storage/STR = T.GetComponent(/datum/component/storage) - to_chat(user, "You empty the bag.") - for(var/obj/item/O in T.contents) - STR.remove_from_storage(O,src) - T.update_icon() + add_fingerprint(user) + if(!pressure_charging && !full_pressure && !flush) + if(I.tool_behaviour == TOOL_SCREWDRIVER) + panel_open = !panel_open + I.play_tool_sound(src) + to_chat(user, "You [panel_open ? "remove":"attach"] the screws around the power connection.") + return + else if(I.tool_behaviour == TOOL_WELDER && panel_open) + if(!I.tool_start_check(user, amount=0)) + return + + to_chat(user, "You start slicing the floorweld off \the [src]...") + if(I.use_tool(src, user, 20, volume=100) && panel_open) + to_chat(user, "You slice the floorweld off \the [src].") + deconstruct() + return + + if(user.a_intent != INTENT_HARM) + if((I.item_flags & ABSTRACT) || !user.temporarilyRemoveItemFromInventory(I)) + return + place_item_in_disposal(I, user) update_icon() - ui.soft_update_fields() + return TRUE //no afterattack else - ui.soft_update_fields() return ..() // handle machine interaction -/obj/machinery/disposal/bin/ui_interact(mob/user, state) +/obj/machinery/disposal/bin/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) if(stat & BROKEN) return - if(user.loc == src) - to_chat(user, "You cannot reach the controls from inside!") - return - ui.render(user) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "disposal_unit", name, ui_x, ui_y, master_ui, state) + ui.open() -/obj/machinery/disposal/bin/oui_canview(mob/user) - if(user.loc == src) - return FALSE - if(stat & BROKEN) - return FALSE - if(Adjacent(user)) - return TRUE - return ..() - - -/obj/machinery/disposal/bin/oui_data(mob/user) +/obj/machinery/disposal/bin/ui_data(mob/user) var/list/data = list() - data["flush"] = flush ? ui.act("Disengage", user, "handle-0", class="active") : ui.act("Engage", user, "handle-1") - data["full_pressure"] = full_pressure ? "Ready" : (pressure_charging ? "Pressurizing" : "Off") - data["pressure_charging"] = pressure_charging ? ui.act("Turn Off", user, "pump-0", class="active", disabled=full_pressure) : ui.act("Turn On", user, "pump-1", disabled=full_pressure) - var/per = full_pressure ? 100 : CLAMP(100* air_contents.return_pressure() / (SEND_PRESSURE), 0, 99) - data["per"] = "[round(per, 1)]%" - data["contents"] = ui.act("Eject Contents", user, "eject", disabled=contents.len < 1) + data["flush"] = flush + data["full_pressure"] = full_pressure + data["pressure_charging"] = pressure_charging + data["panel_open"] = panel_open + data["per"] = CLAMP01(air_contents.return_pressure() / (SEND_PRESSURE)) data["isai"] = isAI(user) return data -/obj/machinery/disposal/bin/oui_act(mob/user, action, list/params) +/obj/machinery/disposal/bin/ui_act(action, params) if(..()) return @@ -365,7 +365,6 @@ if("eject") eject() . = TRUE - ui.soft_update_fields() /obj/machinery/disposal/bin/alt_attack_hand(mob/user) if(can_interact(usr)) @@ -374,7 +373,7 @@ return TRUE return FALSE -/obj/machinery/disposal/bin/hitby(atom/movable/AM) +/obj/machinery/disposal/bin/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(isitem(AM) && AM.CanEnterDisposals()) if(prob(75)) AM.forceMove(src) @@ -402,7 +401,6 @@ full_pressure = FALSE pressure_charging = TRUE update_icon() - ui.soft_update_fields() /obj/machinery/disposal/bin/update_icon() cut_overlays() @@ -446,8 +444,6 @@ do_flush() flush_count = 0 - ui.soft_update_fields() - if(flush && air_contents.return_pressure() >= SEND_PRESSURE) // flush can happen even without power do_flush() diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 8fb05337f2..d6ad1bf042 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -36,7 +36,7 @@ if(!user.is_literate()) to_chat(user, "You scribble illegibly on the side of [src]!") return - var/str = copytext(sanitize(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN) + var/str = stripped_input(user, "Label text?", "Set label", "", MAX_NAME_LEN) if(!user.canUseTopic(src, BE_CLOSE)) return if(!str || !length(str)) @@ -122,7 +122,7 @@ if(!user.is_literate()) to_chat(user, "You scribble illegibly on the side of [src]!") return - var/str = copytext(sanitize(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN) + var/str = stripped_input(user, "Label text?", "Set label", "", MAX_NAME_LEN) if(!user.canUseTopic(src, BE_CLOSE)) return if(!str || !length(str)) diff --git a/code/modules/research/designs/autobotter_designs.dm b/code/modules/research/designs/autobotter_designs.dm index d2a38a29f9..6eb7e8354b 100644 --- a/code/modules/research/designs/autobotter_designs.dm +++ b/code/modules/research/designs/autobotter_designs.dm @@ -151,77 +151,76 @@ name = "Export Design (Wine)" desc = "Allows for the blowing, and bottling of Wine bottles." id = "wine_export" - reagents_list = list(/datum/reagent/consumable/ethanol/wine = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/wine = 50) build_path = /obj/item/export/bottle/wine /datum/design/bottle/export/rum name = "Export Design (Rum)" desc = "Allows for the blowing, and bottling of Rum bottles." id = "rum_export" - reagents_list = list(/datum/reagent/consumable/ethanol/rum = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/rum = 50) build_path = /obj/item/export/bottle/rum /datum/design/bottle/export/gin name = "Export Design (Gin)" desc = "Allows for the blowing, and bottling of Gin bottles." id = "gin_export" - reagents_list = list(/datum/reagent/consumable/ethanol/gin = 100) build_path = /obj/item/export/bottle/gin /datum/design/bottle/export/whiskey name = "Export Design (Whiskey)" desc = "Allows for the blowing, and bottling of Whiskey bottles." id = "whiskey_export" - reagents_list = list(/datum/reagent/consumable/ethanol/whiskey = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/whiskey = 50) build_path = /obj/item/export/bottle/whiskey /datum/design/bottle/export/vodka name = "Export Design (Vodka)" desc = "Allows for the blowing, and bottling of 99% Vodka bottles." id = "vodka_export" - reagents_list = list(/datum/reagent/consumable/ethanol/vodka = 99, /datum/reagent/water = 1) + reagents_list = list(/datum/reagent/consumable/ethanol/vodka = 45, /datum/reagent/water = 1) build_path = /obj/item/export/bottle/vodka /datum/design/bottle/export/tequila name = "Export Design (Tequila)" desc = "Allows for the blowing, and bottling of Tequila bottles." id = "tequila_export" - reagents_list = list(/datum/reagent/consumable/ethanol/tequila = 80, /datum/reagent/consumable/lemonjuice = 20) + reagents_list = list(/datum/reagent/consumable/ethanol/tequila = 40, /datum/reagent/consumable/lemonjuice = 10) build_path = /obj/item/export/bottle/tequila /datum/design/bottle/export/patron name = "Export Design (Patron)" desc = "Allows for the blowing, and bottling of Patron bottles." id = "patron_export" - reagents_list = list(/datum/reagent/consumable/ethanol/patron = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/patron = 50) build_path = /obj/item/export/bottle/patron /datum/design/bottle/export/kahlua name = "Export Design (Kahlua)" desc = "Allows for the blowing, and bottling of Kahlua bottles." id = "kahlua_export" - reagents_list = list(/datum/reagent/consumable/ethanol/kahlua = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/kahlua = 50) build_path = /obj/item/export/bottle/kahlua /datum/design/bottle/export/sake name = "Export Design (Sake)" desc = "Allows for the blowing, and bottling of Sake bottles." id = "sake_export" - reagents_list = list(/datum/reagent/consumable/ethanol/sake = 80, /datum/reagent/consumable/rice = 10, /datum/reagent/consumable/sugar = 10) + reagents_list = list(/datum/reagent/consumable/ethanol/sake = 40, /datum/reagent/consumable/rice = 10, /datum/reagent/consumable/sugar = 10) build_path = /obj/item/export/bottle/sake /datum/design/bottle/export/vermouth name = "Export Design (Vermouth)" desc = "Allows for the blowing, and bottling of Vermouth bottles." id = "vermouth_export" - reagents_list = list(/datum/reagent/consumable/ethanol/vermouth = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/vermouth = 50) build_path = /obj/item/export/bottle/vermouth /datum/design/bottle/export/goldschlager name = "Export Design (Goldschlager)" desc = "Allows for the blowing, and bottling of Goldschlager bottles." id = "goldschlager_export" - reagents_list = list(/datum/reagent/consumable/ethanol/goldschlager = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/goldschlager = 50) build_path = /obj/item/export/bottle/goldschlager /datum/design/bottle/export/hcider @@ -235,13 +234,13 @@ name = "Export Design (Cognac)" desc = "Allows for the blowing, and bottling of Cognac bottles." id = "cognac_export" - reagents_list = list(/datum/reagent/consumable/ethanol/cognac = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/cognac = 50) build_path = /obj/item/export/bottle/cognac /datum/design/bottle/export/absinthe name = "Export Design (Absinthe)" desc = "Allows for the blowing, and bottling of Absinthe bottles." - reagents_list = list(/datum/reagent/consumable/ethanol/absinthe = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/absinthe = 50) id = "absinthe_export" build_path = /obj/item/export/bottle/absinthe @@ -249,49 +248,49 @@ name = "Export Design (Grappa)" desc = "Allows for the blowing, and bottling of Grappa bottles." id = "grappa_export" - reagents_list = list(/datum/reagent/consumable/ethanol/grappa = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/grappa = 50) build_path = /obj/item/export/bottle/grappa /datum/design/bottle/export/fernet name = "Export Design (Fernet)" desc = "Allows for the blowing, and bottling of Fernet bottles." id = "fernet_export" - reagents_list = list(/datum/reagent/consumable/ethanol/fernet = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/fernet = 50) build_path = /obj/item/export/bottle/fernet /datum/design/bottle/export/applejack name = "Export Design (Applejack)" desc = "Allows for the blowing, and bottling of Applejack bottles." id = "applejack_export" - reagents_list = list(/datum/reagent/consumable/ethanol/applejack = 50, /datum/reagent/consumable/ethanol/gin = 10) + reagents_list = list(/datum/reagent/consumable/ethanol/applejack = 35, /datum/reagent/consumable/ethanol/gin = 10) build_path = /obj/item/export/bottle/applejack /datum/design/bottle/export/champagne name = "Export Design (Champagne)" desc = "Allows for the blowing, and bottling of Champagne bottles." id = "champagne_export" - reagents_list = list(/datum/reagent/consumable/ethanol/champagne = 90, /datum/reagent/carbondioxide = 10) + reagents_list = list(/datum/reagent/consumable/ethanol/champagne = 30, /datum/reagent/carbondioxide = 10) build_path = /obj/item/export/bottle/champagne /datum/design/bottle/export/blazaam name = "Export Design (Blazaam)" desc = "Allows for the blowing, and bottling of Blazaam bottles." id = "blazaam_export" - reagents_list = list(/datum/reagent/consumable/ethanol/blazaam = 80, /datum/reagent/water/holywater = 20) + reagents_list = list(/datum/reagent/consumable/ethanol/blazaam = 40, /datum/reagent/water/holywater = 20) build_path = /obj/item/export/bottle/blazaam /datum/design/bottle/export/trappist name = "Export Design (Trappist)" desc = "Allows for the blowing, and bottling of Trappist bottles." id = "trappist_export" - reagents_list = list(/datum/reagent/consumable/ethanol/trappist = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/trappist = 50) build_path = /obj/item/export/bottle/trappist /datum/design/bottle/export/grenadine name = "Export Design (Grenadine)" desc = "Allows for the blowing, and bottling of Grenadine bottles." id = "grenadine_export" - reagents_list = list(/datum/reagent/consumable/grenadine = 100) + reagents_list = list(/datum/reagent/consumable/grenadine = 50) build_path = /obj/item/export/bottle/grenadine /datum/design/bottle/export/minikeg @@ -299,7 +298,7 @@ desc = "Allows for the fabication, and bottling of Minikeg of craft beer." id = "minikeg" category = list("Beers") - reagents_list = list(/datum/reagent/consumable/ethanol/beer/light = 100) + reagents_list = list(/datum/reagent/consumable/ethanol/beer/light = 50) build_path = /obj/item/export/bottle/minikeg /datum/design/bottle/export/blooddrop @@ -315,7 +314,7 @@ desc = "Allows for the blowing, and bottling of Slim Gold bottles." id = "slim_gold" category = list("Beers") - reagents_list = list(/datum/reagent/gold = 10, /datum/reagent/carbondioxide = 10, /datum/reagent/consumable/ethanol/rum = 30, /datum/reagent/consumable/ethanol/beer = 40) + reagents_list = list(/datum/reagent/gold = 10, /datum/reagent/carbondioxide = 10, /datum/reagent/consumable/ethanol/rum = 15, /datum/reagent/consumable/ethanol/beer = 20) build_path = /obj/item/export/bottle/slim_gold /datum/design/bottle/export/white_bloodmoon @@ -323,13 +322,13 @@ desc = "Allows for the blowing, and bottling of White Bloodmoon bottles." id = "white_bloodmoon" category = list("Wines") - reagents_list = list(/datum/reagent/medicine/synthflesh = 50, /datum/reagent/blood = 50, /datum/reagent/liquidgibs = 10) + reagents_list = list(/datum/reagent/medicine/synthflesh = 20, /datum/reagent/blood = 30, /datum/reagent/liquidgibs = 10) build_path = /obj/item/export/bottle/white_bloodmoon /datum/design/bottle/export/greenroad name = "Export Design (Greenroad)" desc = "Allows for the blowing, and bottling of Greenroad bottles." id = "greenroad" - reagents_list = list(/datum/reagent/consumable/vitfro = 50, /datum/reagent/consumable/ethanol/rum = 50, /datum/reagent/ash = 10) + reagents_list = list(/datum/reagent/consumable/vitfro = 50, /datum/reagent/consumable/ethanol/rum = 30, /datum/reagent/ash = 10) category = list("Beers") build_path = /obj/item/export/bottle/greenroad \ No newline at end of file diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm index 1ae1d3813b..c3e3993cb2 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_construction.dm @@ -87,9 +87,10 @@ name = "Conveyor Belt" id = "conveyor_belt" build_type = AUTOLATHE - materials = list(MAT_METAL = 5000) - build_path = /obj/item/conveyor_construct + materials = list(MAT_METAL = 3000) + build_path = /obj/item/stack/conveyor category = list("initial", "Construction") + maxstack = 30 /datum/design/conveyor_switch name = "Conveyor Belt Switch" @@ -102,7 +103,17 @@ /datum/design/rcd_ammo name = "Compressed Matter Cartridge" id = "rcd_ammo" - build_type = AUTOLATHE - materials = list(MAT_METAL = 12000, MAT_GLASS=8000) + build_type = AUTOLATHE | PROTOLATHE + materials = list(MAT_METAL = 12000, MAT_GLASS = 8000) build_path = /obj/item/rcd_ammo - category = list("initial","Construction") + category = list("initial","Construction","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/rcd_ammo_large + name = "Large Compressed Matter Cartridge" + id = "rcd_ammo_large" + build_type = AUTOLATHE | PROTOLATHE + materials = list(MAT_METAL = 48000, MAT_GLASS = 32000) + build_path = /obj/item/rcd_ammo/large + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 99cb5bf8ab..bef25456ca 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -307,6 +307,8 @@ build_type = PROTOLATHE build_path = /obj/item/defibrillator/compact materials = list(MAT_METAL = 16000, MAT_GLASS = 8000, MAT_SILVER = 6000, MAT_GOLD = 3000) + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL ///////////////////////////////////////// //////////Cybernetic Implants//////////// diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 54a7af8f8c..0059e0c417 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -403,6 +403,16 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/holosigncombifan + name = "ATMOS Holo-Combifan Projector" + desc = "A holographic projector that creates holographic barriesr that prevent changes in atmospheric and temperature conditions." + id = "holosigncombifan" + build_type = PROTOLATHE + materials = list(MAT_METAL = 7500, MAT_GLASS = 2500, MAT_SILVER = 2500, MAT_GOLD = 2500, MAT_TITANIUM = 1750) + build_path = /obj/item/holosign_creator/combifan + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/forcefield_projector name = "Forcefield Projector" desc = "A device which can project temporary forcefields to seal off an area." diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index bff8df8816..fd68a393f9 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -82,6 +82,11 @@ for(var/obj/item/stock_parts/micro_laser/M in component_parts) badThingCoeff += M.rating +/obj/machinery/rnd/experimentor/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Malfunction probability reduced by [badThingCoeff]%.
        Cooldown interval between experiments at [resetTime*0.1] seconds.
        " + /obj/machinery/rnd/experimentor/proc/checkCircumstances(obj/item/O) //snowflake check to only take "made" bombs if(istype(O, /obj/item/transfer_valve)) @@ -568,7 +573,8 @@ else if(loc == user) cooldown = TRUE call(src,realProc)(user) - addtimer(CALLBACK(src, .proc/cd), cooldownMax) + if(!QDELETED(src)) + addtimer(CALLBACK(src, .proc/cd), cooldownMax) else to_chat(user, "You aren't quite sure what to do with this yet.") diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index d93355b36c..659a83c703 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -73,6 +73,12 @@ total_rating = max(1, total_rating) efficiency_coeff = total_rating +/obj/machinery/rnd/production/examine(mob/user) + . = ..() + var/datum/component/remote_materials/materials = GetComponent(/datum/component/remote_materials) + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Storing up to [materials.local_size] material units locally.
        Material usage efficiency at [efficiency_coeff*100]%.
        " + //we eject the materials upon deconstruction. /obj/machinery/rnd/production/on_deconstruction() for(var/obj/item/reagent_containers/glass/G in component_parts) diff --git a/code/modules/research/nanites/nanite_chamber.dm b/code/modules/research/nanites/nanite_chamber.dm index 1fc2633989..515231c24c 100644 --- a/code/modules/research/nanites/nanite_chamber.dm +++ b/code/modules/research/nanites/nanite_chamber.dm @@ -29,6 +29,11 @@ for(var/obj/item/stock_parts/scanning_module/P in component_parts) scan_level += P.rating +/obj/machinery/nanite_chamber/examine(mob/user) + . = ..() + if(in_range(user, src) || isobserver(user)) + . += "The status display reads: Scanning module has been upgraded to level [scan_level]." + /obj/machinery/nanite_chamber/proc/set_busy(status, message, working_icon) busy = status busy_message = message diff --git a/code/modules/research/nanites/nanite_programs/suppression.dm b/code/modules/research/nanites/nanite_programs/suppression.dm index ad5706f88c..e4b250ad61 100644 --- a/code/modules/research/nanites/nanite_programs/suppression.dm +++ b/code/modules/research/nanites/nanite_programs/suppression.dm @@ -142,7 +142,7 @@ var/new_sentence = stripped_input(user, "Choose the sentence that the host will be forced to say.", "Sentence", sentence, MAX_MESSAGE_LEN) if(!new_sentence) return - if(copytext(new_sentence, 1, 2) == "*") //emotes are abusable, like surrender + if(new_sentence[1] == "*") //emotes are abusable, like surrender return sentence = new_sentence if(setting == "Comm Code") diff --git a/code/modules/research/nanites/nanite_programs/utility.dm b/code/modules/research/nanites/nanite_programs/utility.dm index 46f5de168f..deafbcd02c 100644 --- a/code/modules/research/nanites/nanite_programs/utility.dm +++ b/code/modules/research/nanites/nanite_programs/utility.dm @@ -220,7 +220,7 @@ if(!iscarbon(host_mob)) return FALSE var/mob/living/carbon/C = host_mob - if(C.nutrition <= NUTRITION_LEVEL_STARVING) + if(C.nutrition <= NUTRITION_LEVEL_FED) return FALSE return ..() diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 01b9b1dc41..d33ef29155 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -52,7 +52,7 @@ Nothing else in the console has ID requirements. research_control = FALSE /proc/CallMaterialName(ID) - if (copytext(ID, 1, 2) == "$" && GLOB.materials_list[ID]) + if (ID[1] == "$" && GLOB.materials_list[ID]) var/datum/material/material = GLOB.materials_list[ID] return material.name diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 74f07e4ce3..9556e3853b 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -80,7 +80,7 @@ display_name = "Advanced Biotechnology" description = "Advanced Biotechnology" prereq_ids = list("biotech") - design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "meta_beaker", "healthanalyzer_advanced", "harvester", "holobarrier_med", "detective_scanner", "defibrillator_compact", "smartdartgun", "medicinalsmartdart", "pHmeter") + design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "meta_beaker", "healthanalyzer_advanced", "harvester", "holobarrier_med", "defibrillator_compact", "smartdartgun", "medicinalsmartdart", "pHmeter") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -200,7 +200,7 @@ display_name = "Advanced Engineering" description = "Pushing the boundaries of physics, one chainsaw-fist at a time." prereq_ids = list("engineering", "emp_basic") - design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask" , "rcd_loaded", "rpd", "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade_frames", "rcd_upgrade_simple_circuits") + design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask" , "rcd_loaded", "rpd", "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade_frames", "rcd_upgrade_simple_circuits", "rcd_ammo_large") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) export_price = 5000 @@ -644,7 +644,7 @@ id = "exp_tools" display_name = "Experimental Tools" description = "Highly advanced construction tools." - design_ids = list("exwelder", "jawsoflife", "handdrill") + design_ids = list("exwelder", "jawsoflife", "handdrill", "holosigncombifan") prereq_ids = list("adv_engi") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2750) export_price = 5000 @@ -1117,7 +1117,7 @@ id = "advanced_illegal_ballistics" display_name = "Advanced Non-Standard Ballistics" description = "Ballistic ammunition for non-standard firearms. Usually the ones you don't have nor want to be involved with." - design_ids = list("10mm","10mmap","10mminc","10mmhp","sl357","pistolm9mm","m45","bolt_clip") + design_ids = list("10mm","10mmap","10mminc","10mmhp","sl357","sl357ap","pistolm9mm","m45","bolt_clip") prereq_ids = list("ballistic_weapons","syndicate_basic","explosive_weapons") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 25000) //This gives sec lethal mags/clips for guns from traitors, space, or anything in between. export_price = 7000 diff --git a/code/modules/research/xenobiology/crossbreeding/burning.dm b/code/modules/research/xenobiology/crossbreeding/burning.dm index e5b30962ae..48e6f720b0 100644 --- a/code/modules/research/xenobiology/crossbreeding/burning.dm +++ b/code/modules/research/xenobiology/crossbreeding/burning.dm @@ -154,7 +154,7 @@ Burning extracts: /obj/item/slimecross/burning/sepia/do_effect(mob/user) user.visible_message("[src] shapes itself into a camera!") - new /obj/item/camera/timefreeze(get_turf(user)) + new /obj/item/camera/rewind(get_turf(user)) ..() /obj/item/slimecross/burning/cerulean @@ -289,25 +289,88 @@ Burning extracts: //Misc. things added +//Rewind camera - I'm already Burning Sepia +/obj/item/camera/rewind + name = "sepia-tinted camera" + desc = "They say a picture is like a moment stopped in time." + pictures_left = 1 + pictures_max = 1 + can_customise = FALSE + default_picture_name = "A nostalgic picture" + var/used = FALSE + +/datum/saved_bodypart + var/obj/item/bodypart/old_part + var/bodypart_type + var/brute_dam + var/burn_dam + var/stamina_dam + +/datum/saved_bodypart/New(obj/item/bodypart/part) + old_part = part + bodypart_type = part.type + brute_dam = part.brute_dam + burn_dam = part.burn_dam + stamina_dam = part.stamina_dam + +/mob/living/carbon/proc/apply_saved_bodyparts(list/datum/saved_bodypart/parts) + var/list/dont_chop = list() + for(var/zone in parts) + var/datum/saved_bodypart/saved_part = parts[zone] + var/obj/item/bodypart/already = get_bodypart(zone) + if(QDELETED(saved_part.old_part)) + saved_part.old_part = new saved_part.bodypart_type + if(!already || already != saved_part.old_part) + saved_part.old_part.replace_limb(src, TRUE) + saved_part.old_part.heal_damage(INFINITY, INFINITY, INFINITY, null, FALSE) + saved_part.old_part.receive_damage(saved_part.brute_dam, saved_part.burn_dam, saved_part.stamina_dam) + dont_chop[zone] = TRUE + for(var/_part in bodyparts) + var/obj/item/bodypart/part = _part + if(dont_chop[part.body_zone]) + continue + part.drop_limb(TRUE) + +/mob/living/carbon/proc/save_bodyparts() + var/list/datum/saved_bodypart/ret = list() + for(var/_part in bodyparts) + var/obj/item/bodypart/part = _part + var/datum/saved_bodypart/saved_part = new(part) + + ret[part.body_zone] = saved_part + return ret + +/obj/item/camera/rewind/afterattack(atom/target, mob/user, flag) + if(!on || !pictures_left || !isturf(target.loc)) + return + if(!used)//selfie time + if(user == target) + to_chat(user, "You take a selfie!") + else + to_chat(user, "You take a photo with [target]!") + to_chat(target, "[user] takes a photo with you!") + to_chat(target, "You'll remember this moment forever!") + + used = TRUE + target.AddComponent(/datum/component/dejavu, 2) + .=..() + +//Timefreeze camera - Old Burning Sepia result. Kept in case admins want to spawn it /obj/item/camera/timefreeze name = "sepia-tinted camera" desc = "They say a picture is like a moment stopped in time." pictures_left = 1 pictures_max = 1 + var/used = FALSE /obj/item/camera/timefreeze/afterattack(atom/target, mob/user, flag) if(!on || !pictures_left || !isturf(target.loc)) return - new /obj/effect/timestop(get_turf(target), 2, 50, list(user)) - . = ..() - var/text = "The camera fades away" - if(disk) - text += ", leaving the disk behind!" - user.put_in_hands(disk) - else - text += "!" - to_chat(user,"[text]") - qdel(src) + if(!used) //refilling the film does not refill the timestop + new /obj/effect/timestop(get_turf(target), 2, 50, list(user)) + used = TRUE + desc = "This camera has seen better days." + return ..() /obj/item/slimepotion/extract_cloner name = "extract cloning potion" diff --git a/code/modules/research/xenobiology/crossbreeding/consuming.dm b/code/modules/research/xenobiology/crossbreeding/consuming.dm index 0e8bf1e11f..af37a70232 100644 --- a/code/modules/research/xenobiology/crossbreeding/consuming.dm +++ b/code/modules/research/xenobiology/crossbreeding/consuming.dm @@ -212,7 +212,7 @@ Consuming extracts: taste = "sugar and starlight" /obj/item/slime_cookie/bluespace/do_effect(mob/living/M, mob/user) - var/list/L = get_area_turfs(get_area(get_turf(M))) + var/list/L = get_sub_areas_turfs(get_area(M)) var/turf/target while (L.len && !target) var/I = rand(1, L.len) diff --git a/code/modules/research/xenobiology/crossbreeding/regenerative.dm b/code/modules/research/xenobiology/crossbreeding/regenerative.dm index 55865d1ae2..d230c22d2f 100644 --- a/code/modules/research/xenobiology/crossbreeding/regenerative.dm +++ b/code/modules/research/xenobiology/crossbreeding/regenerative.dm @@ -148,8 +148,9 @@ Regenerative extracts: /obj/item/slimecross/regenerative/sepia colour = "sepia" -/obj/item/slimecross/regenerative/sepia/core_effect(mob/living/target, mob/user) - new /obj/effect/timestop(get_turf(target), 2, 50, list(user,target)) +/obj/item/slimecross/regenerative/sepia/core_effect_before(mob/living/target, mob/user) + to_chat(target, "You try to forget how you feel.") + target.AddComponent(/datum/component/dejavu) /obj/item/slimecross/regenerative/cerulean colour = "cerulean" diff --git a/code/modules/research/xenobiology/crossbreeding/stabilized.dm b/code/modules/research/xenobiology/crossbreeding/stabilized.dm index 0d589954d9..1912ca6476 100644 --- a/code/modules/research/xenobiology/crossbreeding/stabilized.dm +++ b/code/modules/research/xenobiology/crossbreeding/stabilized.dm @@ -134,7 +134,7 @@ Stabilized extracts: saved_mind = null START_PROCESSING(SSobj, src) if(choice == "Familiar Name") - var/newname = copytext(sanitize(input(user, "Would you like to change the name of [mob_name]", "Name change", mob_name) as null|text),1,MAX_NAME_LEN) + var/newname = reject_bad_name(stripped_input(user, "Would you like to change the name of [mob_name]", "Name change", mob_name, MAX_NAME_LEN), TRUE) if(newname) mob_name = newname to_chat(user, "You speak softly into [src], and it shakes slightly in response.") diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 205603e12e..9682d404ea 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -486,7 +486,7 @@ if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) // CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS to_chat(user, "This console does not have the monkey upgrade.") return - if(!GLOB.cameranet.checkTurfVis(M.loc)) + if(!isturf(M.loc) || !GLOB.cameranet.checkTurfVis(M.loc)) to_chat(user, "Target is not near a camera. Cannot proceed.") return var/mob/living/C = user diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 8eecf1f635..0c21b19b5f 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -644,7 +644,7 @@ M.nutrition = 700 to_chat(M, "You absorb the potion and feel your intense desire to feed melt away.") to_chat(user, "You feed the slime the potion, removing its hunger and calming it.") - var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN) + var/newname = reject_bad_name(stripped_input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime", MAX_NAME_LEN), TRUE) if (!newname) newname = "pet slime" @@ -909,12 +909,15 @@ to_chat(user, "The potion can only be used on gendered things!") return - if(L.gender == MALE) + if(L.gender == MALE && (L.client?.prefs.cit_toggles & FORCED_FEM)) L.gender = FEMALE L.visible_message("[L] suddenly looks more feminine!", "You suddenly feel more feminine!") - else + else if(L.gender == FEMALE && (L.client?.prefs.cit_toggles & FORCED_MASC)) L.gender = MALE L.visible_message("[L] suddenly looks more masculine!", "You suddenly feel more masculine!") + else + to_chat(user,"It won't work on [L]!") + return L.regenerate_icons() qdel(src) diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index b6e0db2646..6e3b452b81 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -115,7 +115,9 @@ job_description = "Off-station Syndicate Scientist" icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper_s" - flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Continue your research as best you can, and try to keep a low profile. DON'T abandon the base without good cause. The base is rigged with explosives should the worst happen, do not let the base fall into enemy hands!" + short_desc = "You are a syndicate science technician, employed in a top secret research facility developing biological weapons." + flavour_text = "Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Continue your research as best you can, and try to keep a low profile." + important_info = "The base is rigged with explosives, DO NOT abandon it or let it fall into enemy hands!" outfit = /datum/outfit/lavaland_syndicate assignedrole = "Lavaland Syndicate" @@ -142,7 +144,9 @@ /obj/effect/mob_spawn/human/lavaland_syndicate/comms name = "Syndicate Comms Agent" job_description = "Off-station Syndicate Comms Agent" - flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Monitor enemy activity as best you can, and try to keep a low profile. DON'T abandon the base without good cause. Use the communication equipment to provide support to any field agents, and sow disinformation to throw Nanotrasen off your trail. Do not let the base fall into enemy hands!" + short_desc = "You are a syndicate comms agent, employed in a top secret research facility developing biological weapons." + flavour_text = "Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Monitor enemy activity as best you can, and try to keep a low profile. Use the communication equipment to provide support to any field agents, and sow disinformation to throw Nanotrasen off your trail. Do not let the base fall into enemy hands!" + important_info = "DO NOT abandon the base." outfit = /datum/outfit/lavaland_syndicate/comms /obj/effect/mob_spawn/human/lavaland_syndicate/comms/space/Initialize() diff --git a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm index 5425ddbdc4..2401fc63a0 100644 --- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm @@ -1,26 +1,31 @@ #define ASH_WALKER_SPAWN_THRESHOLD 2 //The ash walker den consumes corpses or unconscious mobs to create ash walker eggs. For more info on those, check ghost_role_spawners.dm -/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker +/obj/structure/lavaland/ash_walker name = "necropolis tendril nest" desc = "A vile tendril of corruption. It's surrounded by a nest of rapidly growing eggs..." + icon = 'icons/mob/nest.dmi' icon_state = "ash_walker_nest" - icon_living = "ash_walker_nest" - icon_dead = "ash_walker_nest" - faction = list("ashwalker") - health = 200 - maxHealth = 200 - loot = list(/obj/effect/collapse) + move_resist=INFINITY // just killing it tears a massive hole in the ground, let's not move it + anchored = TRUE + density = TRUE + resistance_flags = FIRE_PROOF | LAVA_PROOF + max_integrity = 200 + var/faction = list("ashwalker") var/meat_counter = 6 -/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/death() +/obj/structure/lavaland/ash_walker/Initialize() + .=..() + START_PROCESSING(SSprocessing, src) + +/obj/structure/lavaland/ash_walker/deconstruct(disassembled) new /obj/item/assembly/signaler/anomaly (get_step(loc, pick(GLOB.alldirs))) - return ..() + new /obj/effect/collapse(loc) -/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/Life() +/obj/structure/lavaland/ash_walker/process() consume() - return ..() + spawn_mob() -/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/proc/consume() +/obj/structure/lavaland/ash_walker/proc/consume() for(var/mob/living/H in view(src, 1)) //Only for corpse right next to/on same tile if(H.stat) visible_message("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.") @@ -33,9 +38,9 @@ else meat_counter++ H.gib() - adjustHealth(-maxHealth * 0.05)//restores 5% hp of tendril + obj_integrity = min(obj_integrity + max_integrity*0.05,max_integrity)//restores 5% hp of tendril -/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/spawn_mob() +/obj/structure/lavaland/ash_walker/proc/spawn_mob() if(meat_counter >= ASH_WALKER_SPAWN_THRESHOLD) new /obj/effect/mob_spawn/human/ash_walker(get_step(loc, pick(GLOB.alldirs))) visible_message("One of the eggs swells to an unnatural size and tumbles free. It's ready to hatch!") diff --git a/code/modules/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/ruins/spaceruin_code/hilbertshotel.dm index dc721506a5..8648e46cb9 100644 --- a/code/modules/ruins/spaceruin_code/hilbertshotel.dm +++ b/code/modules/ruins/spaceruin_code/hilbertshotel.dm @@ -12,6 +12,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) var/datum/map_template/hilbertshotel/lore/hotelRoomTempLore var/list/activeRooms = list() var/list/storedRooms = list() + var/list/checked_in_ckeys = list() var/storageTurf //Lore Stuff var/ruinSpawned = FALSE @@ -44,7 +45,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) /obj/item/hilbertshotel/proc/promptAndCheckIn(mob/user) var/chosenRoomNumber = input(user, "What number room will you be checking into?", "Room Number") as null|num - if(!chosenRoomNumber) + if(!chosenRoomNumber || !user.CanReach(src)) return if(chosenRoomNumber > SHORT_REAL_LIMIT) to_chat(user, "You have to check out the first [SHORT_REAL_LIMIT] rooms before you can go to a higher numbered one!") @@ -52,8 +53,8 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) if((chosenRoomNumber < 1) || (chosenRoomNumber != round(chosenRoomNumber))) to_chat(user, "That is not a valid room number!") return - if(ismob(loc)) - if(user == loc) //Not always the same as user + if(!isturf(loc)) + if((loc == user) || (loc.loc == user) || (loc.loc in user.contents) || (loc in user.GetAllContents(type))) //short circuit, first three checks are cheaper and covers almost all cases (loc.loc covers hotel in box in backpack). forceMove(get_turf(user)) if(!storageTurf) //Blame subsystems for not allowing this to be in Initialize if(!GLOB.hhStorageTurf) @@ -63,13 +64,13 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) GLOB.hhStorageTurf = locate(storageReservation.bottom_left_coords[1]+1, storageReservation.bottom_left_coords[2]+1, storageReservation.bottom_left_coords[3]) else storageTurf = GLOB.hhStorageTurf + checked_in_ckeys |= user.ckey //if anything below runtimes, guess you're outta luck! if(tryActiveRoom(chosenRoomNumber, user)) return if(tryStoredRoom(chosenRoomNumber, user)) return sendToNewRoom(chosenRoomNumber, user) - /obj/item/hilbertshotel/proc/tryActiveRoom(var/roomNumber, var/mob/user) if(activeRooms["[roomNumber]"]) var/datum/turf_reservation/roomReservation = activeRooms["[roomNumber]"] @@ -102,6 +103,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) else return FALSE +/// This is a BLOCKING OPERATION. Note the room load call, and the block reservation calls. /obj/item/hilbertshotel/proc/sendToNewRoom(var/roomNumber, var/mob/user) var/datum/turf_reservation/roomReservation = SSmapping.RequestBlockReservation(hotelRoomTemp.width, hotelRoomTemp.height) if(ruinSpawned) @@ -200,7 +202,6 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) name = "Hilbert's Hotel Storage" mappath = '_maps/templates/hilbertshotelstorage.dmm' - //Turfs and Areas /turf/closed/indestructible/hotelwall name = "hotel wall" @@ -359,6 +360,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337) . = ..() if(ismob(AM)) var/mob/M = AM + parentSphere?.checked_in_ckeys -= M.ckey if(M.mind) var/stillPopulated = FALSE var/list/currentLivingMobs = GetAllContents(/mob/living) //Got to catch anyone hiding in anything diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index c863e0e44a..9229781c0f 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -21,7 +21,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "emergency_shuttle_console", name, - 400, 400, master_ui, state) + 400, 350, master_ui, state) ui.open() /obj/machinery/computer/emergency_shuttle/ui_data() diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 121ee2e07f..beaaa51adb 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -131,7 +131,7 @@ All ShuttleMove procs go here var/range = throw_force * 10 range = CEILING(rand(range-(range*0.1), range+(range*0.1)), 10)/10 var/speed = range/5 - throw_at(target, range, speed) + safe_throw_at(target, range, speed) ///////////////////////////////////////////////////////////////////////////////////// diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 225ca1f824..44a70f539d 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -660,7 +660,7 @@ if(timeleft > 1 HOURS) return "--:--" else if(timeleft > 0) - return "[add_zero(num2text((timeleft / 60) % 60),2)]:[add_zero(num2text(timeleft % 60), 2)]" + return "[add_leading(num2text((timeleft / 60) % 60), 2, "0")]:[add_leading(num2text(timeleft % 60), 2, " ")]" else return "00:00" diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 0db05cb83d..0e7cba9776 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -171,7 +171,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( msg += "[value] credits: received [ex.reagents_volume[chem]]u of [chem].\n" SSshuttle.points += value - msg = copytext(msg, 1, MAX_MESSAGE_LEN) + msg = copytext_char(msg, 1, MAX_MESSAGE_LEN) SSshuttle.centcom_message = msg investigate_log("Shuttle contents sold for [SSshuttle.points - presale_points] credits. Contents: [ex.exported_atoms || "none."] Message: [SSshuttle.centcom_message || "none."]", INVESTIGATE_CARGO) diff --git a/code/modules/spells/spell_types/aimed.dm b/code/modules/spells/spell_types/aimed.dm index 73a428af71..5ba85bef6b 100644 --- a/code/modules/spells/spell_types/aimed.dm +++ b/code/modules/spells/spell_types/aimed.dm @@ -94,9 +94,9 @@ name = "Lightning Bolt" desc = "Fire a high powered lightning bolt at your foes!" school = "evocation" - charge_max = 200 + charge_max = 150 clothes_req = 1 - invocation = "UN'LTD P'WAH" + invocation = "ZAP MUTHA'FUCKA" invocation_type = "shout" cooldown_min = 30 active_icon_state = "lightning" @@ -112,12 +112,12 @@ name = "Fireball" desc = "This spell fires a fireball at a target and does not require wizard garb." school = "evocation" - charge_max = 60 + charge_max = 100 clothes_req = 0 invocation = "ONI SOMA" invocation_type = "shout" range = 20 - cooldown_min = 20 //10 deciseconds reduction per rank + cooldown_min = 20 //20 deciseconds reduction per rank projectile_type = /obj/item/projectile/magic/aoe/fireball base_icon_state = "fireball" action_icon_state = "fireball0" diff --git a/code/modules/spells/spell_types/conjure.dm b/code/modules/spells/spell_types/conjure.dm index a04a86b928..8336c06edb 100644 --- a/code/modules/spells/spell_types/conjure.dm +++ b/code/modules/spells/spell_types/conjure.dm @@ -63,7 +63,7 @@ clothes_req = FALSE charge_max = 600 cooldown_min = 200 - summon_type = list(/mob/living/simple_animal/hostile/spawner/nether) + summon_type = list(/obj/structure/spawner/nether) summon_amt = 1 range = 1 cast_sound = 'sound/weapons/marauder.ogg' diff --git a/code/modules/spells/spell_types/emplosion.dm b/code/modules/spells/spell_types/emplosion.dm index a5ba0a3914..98723273ae 100644 --- a/code/modules/spells/spell_types/emplosion.dm +++ b/code/modules/spells/spell_types/emplosion.dm @@ -1,6 +1,8 @@ /obj/effect/proc_holder/spell/targeted/emplosion name = "Emplosion" desc = "This spell emplodes an area." + charge_max = 250 + cooldown_min = 50 var/emp_heavy = 2 var/emp_light = 3 diff --git a/code/modules/spells/spell_types/forcewall.dm b/code/modules/spells/spell_types/forcewall.dm index ed78e3315a..aa2fa5ab8b 100644 --- a/code/modules/spells/spell_types/forcewall.dm +++ b/code/modules/spells/spell_types/forcewall.dm @@ -2,7 +2,7 @@ name = "Forcewall" desc = "Create a magical barrier that only you can pass through. Does not require wizard garb." school = "transmutation" - charge_max = 100 + charge_max = 80 clothes_req = 0 invocation = "TARCOL MINTI ZHERI" invocation_type = "shout" @@ -10,7 +10,7 @@ action_icon_state = "shield" range = -1 include_user = 1 - cooldown_min = 50 //12 deciseconds reduction per rank + cooldown_min = 15 //15 deciseconds reduction per rank var/wall_type = /obj/effect/forcefield/wizard /obj/effect/proc_holder/spell/targeted/forcewall/cast(list/targets,mob/user = usr) diff --git a/code/modules/spells/spell_types/lightning.dm b/code/modules/spells/spell_types/lightning.dm index 8363e28624..56d7dc771f 100644 --- a/code/modules/spells/spell_types/lightning.dm +++ b/code/modules/spells/spell_types/lightning.dm @@ -2,7 +2,7 @@ name = "Tesla Blast" desc = "Blast lightning at your foes!" charge_type = "recharge" - charge_max = 300 + charge_max = 270 clothes_req = 1 invocation = "UN'LTD P'WAH!" invocation_type = "shout" diff --git a/code/modules/spells/spell_types/mind_transfer.dm b/code/modules/spells/spell_types/mind_transfer.dm index 982bc3dd06..cbc25fb98e 100644 --- a/code/modules/spells/spell_types/mind_transfer.dm +++ b/code/modules/spells/spell_types/mind_transfer.dm @@ -61,7 +61,7 @@ Also, you never added distance checking after target is selected. I've went ahea return var/datum/mind/TM = target.mind - if((target.anti_magic_check(TRUE, FALSE) || TM.has_antag_datum(/datum/antagonist/wizard) || TM.has_antag_datum(/datum/antagonist/cult) || TM.has_antag_datum(/datum/antagonist/clockcult) || TM.has_antag_datum(/datum/antagonist/changeling) || TM.has_antag_datum(/datum/antagonist/rev)) || cmptext(copytext(target.key,1,2),"@")) + if(target.anti_magic_check(TRUE, FALSE) || TM.has_antag_datum(/datum/antagonist/wizard) || TM.has_antag_datum(/datum/antagonist/cult) || TM.has_antag_datum(/datum/antagonist/clockcult) || TM.has_antag_datum(/datum/antagonist/changeling) || TM.has_antag_datum(/datum/antagonist/rev) || target.key[1] == "@") if(!silent) to_chat(user, "[target.p_their(TRUE)] mind is resisting your spell!") return diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index 262f656967..e098fe389d 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -152,19 +152,21 @@ sound1 = 'sound/magic/teleport_diss.ogg' sound2 = 'sound/magic/teleport_app.ogg' -/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop +/obj/effect/proc_holder/spell/aoe_turf/timestop name = "Stop Time" desc = "This spell stops time for everyone except for you, allowing you to move freely while your enemies and even projectiles are frozen." charge_max = 500 clothes_req = 1 - invocation = "TOKI WO TOMARE" + invocation = "TOKI YO TOMARE" invocation_type = "shout" range = 0 cooldown_min = 100 - summon_amt = 1 action_icon_state = "time" + var/timestop_range = 2 + var/timestop_duration = 100 - summon_type = list(/obj/effect/timestop/wizard) +/obj/effect/proc_holder/spell/aoe_turf/timestop/cast(list/targets, mob/user = usr) + new /obj/effect/timestop/magic(get_turf(user), timestop_range, timestop_duration, list(user)) /obj/effect/proc_holder/spell/aoe_turf/conjure/carp name = "Summon Carp" @@ -363,7 +365,7 @@ icon_state = "snappop" w_class = WEIGHT_CLASS_TINY -/obj/item/spellpacket/lightningbolt/throw_impact(atom/hit_atom) +/obj/item/spellpacket/lightningbolt/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!..()) if(isliving(hit_atom)) var/mob/living/M = hit_atom diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm index 7b8caf28c8..183462a8f7 100644 --- a/code/modules/station_goals/bsa.dm +++ b/code/modules/station_goals/bsa.dm @@ -223,7 +223,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "bsa", name, 400, 305, master_ui, state) + ui = new(user, src, ui_key, "bsa", name, 400, 220, master_ui, state) ui.open() /obj/machinery/computer/bsa_control/ui_data() @@ -252,6 +252,8 @@ update_icon() /obj/machinery/computer/bsa_control/proc/calibrate(mob/user) + if(!GLOB.bsa_unlock) + return var/list/gps_locators = list() for(var/obj/item/gps/G in GLOB.GPS_list) //nulls on the list somehow if(G.tracking) diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index 63a392bf06..097be23c40 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -29,6 +29,7 @@ var/burn_dam = 0 var/stamina_dam = 0 var/max_stamina_damage = 0 + var/incoming_stam_mult = 1 //Multiplier for incoming staminaloss, decreases when taking staminaloss when the limb is disabled, resets back to 1 when limb is no longer disabled. var/max_damage = 0 var/stam_heal_tick = 0 //per Life(). Defaults to 0 due to citadel changes @@ -115,7 +116,7 @@ else return ..() -/obj/item/bodypart/throw_impact(atom/hit_atom) +/obj/item/bodypart/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) ..() if(status != BODYPART_ROBOTIC) playsound(get_turf(src), 'sound/misc/splort.ogg', 50, 1, -1) @@ -141,7 +142,7 @@ //Return TRUE to get whatever mob this is in to update health. /obj/item/bodypart/proc/on_life() if(stam_heal_tick && stamina_dam > DAMAGE_PRECISION) //DO NOT update health here, it'll be done in the carbon's life. - if(heal_damage(brute = 0, burn = 0, stamina = stam_heal_tick, only_robotic = FALSE, only_organic = FALSE, updating_health = FALSE)) + if(heal_damage(brute = 0, burn = 0, stamina = (stam_heal_tick * (disabled ? 2 : 1)), only_robotic = FALSE, only_organic = FALSE, updating_health = FALSE)) . |= BODYPART_LIFE_UPDATE_HEALTH //Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all. @@ -153,7 +154,7 @@ var/dmg_mlt = CONFIG_GET(number/damage_multiplier) brute = round(max(brute * dmg_mlt, 0),DAMAGE_PRECISION) burn = round(max(burn * dmg_mlt, 0),DAMAGE_PRECISION) - stamina = round(max(stamina * dmg_mlt, 0),DAMAGE_PRECISION) + stamina = round(max((stamina * dmg_mlt) * incoming_stam_mult, 0),DAMAGE_PRECISION) brute = max(0, brute - brute_reduction) burn = max(0, burn - burn_reduction) //No stamina scaling.. for now.. @@ -183,6 +184,9 @@ var/available_damage = max_damage - current_damage stamina_dam += round(CLAMP(stamina, 0, min(max_stamina_damage - stamina_dam, available_damage)), DAMAGE_PRECISION) + if(disabled && stamina > 10) + incoming_stam_mult = max(0.01, incoming_stam_mult/(stamina*0.1)) + if(owner && updating_health) owner.updatehealth() if(stamina > DAMAGE_PRECISION) @@ -252,6 +256,8 @@ owner.update_health_hud() //update the healthdoll owner.update_body() owner.update_canmove() + if(!disabled) + incoming_stam_mult = 1 return TRUE //Updates an organ's brute/burn states for use by update_damage_overlays() @@ -645,7 +651,7 @@ held_index = 1 px_x = -6 px_y = 0 - stam_heal_tick = 2 + stam_heal_tick = 4 /obj/item/bodypart/l_arm/is_disabled() if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM)) @@ -705,7 +711,7 @@ held_index = 2 px_x = 6 px_y = 0 - stam_heal_tick = 2 + stam_heal_tick = 4 max_stamina_damage = 50 /obj/item/bodypart/r_arm/is_disabled() @@ -765,10 +771,8 @@ body_damage_coeff = 0.75 px_x = -2 px_y = 12 - stam_heal_tick = 2 + stam_heal_tick = 4 max_stamina_damage = 50 - var/blood_state = BLOOD_STATE_NOT_BLOODY - var/list/bloody_legs = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0) /obj/item/bodypart/l_leg/is_disabled() if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG)) @@ -826,9 +830,7 @@ px_x = 2 px_y = 12 max_stamina_damage = 50 - stam_heal_tick = 2 - var/blood_state = BLOOD_STATE_NOT_BLOODY - var/list/bloody_legs = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0) + stam_heal_tick = 4 /obj/item/bodypart/r_leg/is_disabled() if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG)) diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index 51866b6719..eed8f62e10 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -17,7 +17,6 @@ return L return FALSE - /mob/proc/has_left_hand(check_disabled = TRUE) return TRUE @@ -29,7 +28,7 @@ return FALSE /mob/living/carbon/alien/larva/has_left_hand() - return 1 + return TRUE /mob/proc/has_right_hand(check_disabled = TRUE) @@ -43,9 +42,7 @@ return FALSE /mob/living/carbon/alien/larva/has_right_hand() - return 1 - - + return TRUE /mob/proc/has_left_leg() return TRUE @@ -67,7 +64,6 @@ else return FALSE - //Limb numbers /mob/proc/get_num_arms(check_disabled = TRUE) return 2 diff --git a/code/modules/surgery/healing.dm b/code/modules/surgery/healing.dm index d20d1d822a..4069199864 100644 --- a/code/modules/surgery/healing.dm +++ b/code/modules/surgery/healing.dm @@ -25,7 +25,7 @@ name = "repair body" implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 65, /obj/item/pen = 55) repeatable = TRUE - time = 25 + time = 15 var/brutehealing = 0 var/burnhealing = 0 var/missinghpbonus = 0 //heals an extra point of damager per X missing damage of type (burn damage for burn healing, brute for brute). Smaller Number = More Healing! @@ -117,15 +117,15 @@ /********************BRUTE STEPS********************/ /datum/surgery_step/heal/brute/basic name = "tend bruises" - brutehealing = 5 + brutehealing = 10 missinghpbonus = 15 /datum/surgery_step/heal/brute/upgraded - brutehealing = 5 + brutehealing = 10 missinghpbonus = 10 /datum/surgery_step/heal/brute/upgraded/femto - brutehealing = 5 + brutehealing = 10 missinghpbonus = 5 /***************************BURN***************************/ @@ -155,15 +155,15 @@ /********************BURN STEPS********************/ /datum/surgery_step/heal/burn/basic name = "tend burn wounds" - burnhealing = 5 + burnhealing = 10 missinghpbonus = 15 /datum/surgery_step/heal/burn/upgraded - burnhealing = 5 + burnhealing = 10 missinghpbonus = 10 /datum/surgery_step/heal/burn/upgraded/femto - burnhealing = 5 + burnhealing = 10 missinghpbonus = 5 /***************************COMBO***************************/ @@ -193,23 +193,23 @@ /********************COMBO STEPS********************/ /datum/surgery_step/heal/combo name = "tend physical wounds" - brutehealing = 3 - burnhealing = 3 + brutehealing = 6 + burnhealing = 6 missinghpbonus = 15 - time = 10 + time = 6 /datum/surgery_step/heal/combo/upgraded - brutehealing = 3 - burnhealing = 3 + brutehealing = 6 + burnhealing = 6 missinghpbonus = 10 /datum/surgery_step/heal/combo/upgraded/femto - brutehealing = 1 - burnhealing = 1 + brutehealing = 3 + burnhealing = 3 missinghpbonus = 2.5 /datum/surgery_step/heal/combo/upgraded/femto/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, "You screwed up!", "[user] screws up!", "[user] fixes some of [target]'s wounds.", TRUE) - target.take_bodypart_damage(5,5) \ No newline at end of file + target.take_bodypart_damage(5,5) diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 93ed149a2b..b2beeebe78 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -84,6 +84,8 @@ to_chat(owner, "You feel a faint buzzing as your reviver implant starts patching your wounds...") /obj/item/organ/cyberimp/chest/reviver/proc/heal() + if(!owner) + return if(owner.getOxyLoss()) owner.adjustOxyLoss(-5) revive_cost += 0.5 SECONDS diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 2ddbd672c5..0c242a67d3 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -43,7 +43,7 @@ else eye_color = H.eye_color if(!special) - H.dna?.species?.handle_body() //regenerate eyeballs overlays. + H.dna?.species?.handle_body(H) //regenerate eyeballs overlays. M.update_tint() owner.update_sight() @@ -202,7 +202,7 @@ /obj/item/organ/eyes/robotic/shield/emp_act(severity) return -#define RGB2EYECOLORSTRING(definitionvar) ("[copytext(definitionvar,2,3)][copytext(definitionvar,4,5)][copytext(definitionvar,6,7)]") +#define RGB2EYECOLORSTRING(definitionvar) ("[copytext_char(definitionvar, 2, 3)][copytext_char(definitionvar, 4, 5)][copytext_char(definitionvar, 6, 7)]") /obj/item/organ/eyes/robotic/glow name = "High Luminosity Eyes" diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 51784bdc61..2d70f44e06 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -220,21 +220,12 @@ obj/item/organ/heart/cybernetic/upgraded/on_life() addtimer(VARSET_CALLBACK(src, dose_available, TRUE), 5 MINUTES) ramount = 0 - - /obj/item/organ/heart/ipc name = "IPC heart" desc = "An electronic pump that regulates hydraulic functions, they have an auto-restart after EMPs." icon_state = "heart-c" organ_flags = ORGAN_SYNTHETIC -/obj/item/organ/heart/ipc/emp_act() - . = ..() - if(. & EMP_PROTECT_SELF) - return - Stop() - addtimer(CALLBACK(src, .proc/Restart), 10) - /obj/item/organ/heart/freedom name = "heart of freedom" desc = "This heart pumps with the passion to give... something freedom." diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index bc59ee397c..fc70e64a82 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -60,9 +60,10 @@ //Just in case /obj/item/organ/liver/Remove(mob/living/carbon/M, special = 0) ..() - M.remove_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY) - M.ResetBloodVol() //At the moment, this shouldn't allow application twice. You either have this OR a thirsty ferret. - sizeMoveMod(1, M) + if(!QDELETED(M)) + M.remove_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY) + M.ResetBloodVol() //At the moment, this shouldn't allow application twice. You either have this OR a thirsty ferret. + sizeMoveMod(1, M) //Applies some of the effects to the patient. /obj/item/organ/liver/proc/pharmacokinesis() diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index 760cd97f08..52bd0d4628 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -189,7 +189,7 @@ var/insertpos = rand(1, message_list.len - 1) var/inserttext = message_list[insertpos] - if(!(copytext(inserttext, length(inserttext) - 2) == "...")) + if(!(copytext(inserttext, -3) == "..."))//3 == length("...") message_list[insertpos] = inserttext + "..." if(prob(20) && message_list.len > 3) @@ -290,7 +290,7 @@ /obj/item/organ/tongue/fluffy/handle_speech(datum/source, list/speech_args) var/message = speech_args[SPEECH_MESSAGE] - if(copytext(message, 1, 2) != "*") + if(message[1] != "*") message = replacetext(message, "ne", "nye") message = replacetext(message, "nu", "nyu") message = replacetext(message, "na", "nya") diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index 6dc1d1b6ce..c9596e3754 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -189,19 +189,19 @@ listeners = list(L) //Devil names are unique. power_multiplier *= 5 //if you're a devil and god himself addressed you, you fucked up //Cut out the name so it doesn't trigger commands - message = copytext(message, 0, start)+copytext(message, start + length(devilinfo.truename), length(message) + 1) + message = copytext(message, 1, start) + copytext(message, start + length(devilinfo.truename)) break - else if(dd_hasprefix(message, L.real_name)) + else if(findtext(message, L.real_name, 1, length(L.real_name) + 1)) specific_listeners += L //focus on those with the specified name //Cut out the name so it doesn't trigger commands found_string = L.real_name - else if(dd_hasprefix(message, L.first_name())) + else if(findtext(message, L.first_name(), 1, length(L.first_name()) + 1)) specific_listeners += L //focus on those with the specified name //Cut out the name so it doesn't trigger commands found_string = L.first_name() - else if(L.mind && L.mind.assigned_role && dd_hasprefix(message, L.mind.assigned_role)) + else if(L.mind && L.mind.assigned_role && findtext(message, L.mind.assigned_role, 1, length(L.mind.assigned_role) + 1)) specific_listeners += L //focus on those with the specified job //Cut out the job so it doesn't trigger commands found_string = L.mind.assigned_role @@ -209,7 +209,7 @@ if(specific_listeners.len) listeners = specific_listeners power_multiplier *= (1 + (1/specific_listeners.len)) //2x on a single guy, 1.5x on two and so on - message = copytext(message, 0, 1)+copytext(message, 1 + length(found_string), length(message) + 1) + message = copytext(message, length(found_string) + 1) var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt") var/static/regex/knockdown_words = regex("drop|fall|trip|knockdown") @@ -578,7 +578,7 @@ cooldown = COOLDOWN_MEME for(var/V in listeners) var/mob/living/carbon/human/H = V - + if(H.client && H.client.prefs && H.client.prefs.cit_toggles & HYPNO) // probably a redundant check but for good measure H.mob_climax(forced_climax=TRUE) @@ -719,19 +719,19 @@ for(var/V in listeners) var/mob/living/L = V - if(dd_hasprefix(message, L.real_name)) + if(findtext(message, L.real_name, 1, length(L.real_name) + 1)) specific_listeners += L //focus on those with the specified name //Cut out the name so it doesn't trigger commands found_string = L.real_name power_multiplier += 0.5 - else if(dd_hasprefix(message, L.first_name())) + else if(findtext(message, L.first_name(), 1, length(L.first_name()) + 1)) specific_listeners += L //focus on those with the specified name //Cut out the name so it doesn't trigger commands found_string = L.first_name() power_multiplier += 0.5 - else if(L.mind && L.mind.assigned_role && dd_hasprefix(message, L.mind.assigned_role)) + else if(L.mind && L.mind.assigned_role && findtext(message, L.mind.assigned_role, 1, length(L.mind.assigned_role) + 1)) specific_listeners += L //focus on those with the specified job //Cut out the job so it doesn't trigger commands found_string = L.mind.assigned_role @@ -740,7 +740,7 @@ if(specific_listeners.len) listeners = specific_listeners //power_multiplier *= (1 + (1/specific_listeners.len)) //Put this is if it becomes OP, power is judged internally on a thrall, so shouldn't be nessicary. - message = copytext(message, 0, 1)+copytext(message, 1 + length(found_string), length(message) + 1)//I have no idea what this does + message = copytext(message, length(found_string) + 1)//I have no idea what this does var/obj/item/organ/tongue/T = user.getorganslot(ORGAN_SLOT_TONGUE) if (T.name == "fluffy tongue") //If you sound hillarious, it's hard to take you seriously. This is a way for other players to combat/reduce their effectiveness. diff --git a/code/modules/tgui/external.dm b/code/modules/tgui/external.dm index 8251c450a3..38a5a27e0c 100644 --- a/code/modules/tgui/external.dm +++ b/code/modules/tgui/external.dm @@ -33,6 +33,37 @@ /datum/proc/ui_data(mob/user) 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/ui_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 + * optional ui_key ui key of ui to be updated + * +**/ +/datum/proc/update_static_data(mob/user, datum/tgui/ui, ui_key = "main") + ui = SStgui.try_update_ui(user, src, ui_key, ui) + if(!ui) + return //If there was no ui to update, there's no static data to update either. + ui.push_data(null, ui_static_data(), TRUE) /** * public @@ -80,7 +111,6 @@ * Used to track UIs for a mob. **/ /mob/var/list/open_uis = list() - /** * public * @@ -111,4 +141,4 @@ ui.close() // Unset machine just to be sure. if(src && src.mob) - src.mob.unset_machine() \ No newline at end of file + src.mob.unset_machine() diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 77ee3697ba..55fe8f0bb5 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -8,32 +8,40 @@ * tgui datum (represents a UI). **/ /datum/tgui - var/mob/user // The mob who opened/is using the UI. - var/datum/src_object // The object which owns the UI. - var/title // The title of te UI. - var/ui_key // The ui_key of the UI. This allows multiple UIs for one src_object. - var/window_id // The window_id for browse() and onclose(). - var/width = 0 // The window width. - var/height = 0 // The window height - var/window_options = list( // Extra options to winset(). - "focus" = FALSE, - "titlebar" = TRUE, - "can_resize" = TRUE, - "can_minimize" = TRUE, - "can_maximize" = FALSE, - "can_close" = TRUE, - "auto_format" = FALSE - ) - var/style = "nanotrasen" // The style to be used for this UI. - var/interface // The interface (template) to be used for this UI. - var/autoupdate = TRUE // Update the UI every MC tick. - var/initialized = FALSE // If the UI has been initialized yet. - var/list/initial_data // The data (and datastructure) used to initialize the UI. - var/status = UI_INTERACTIVE // The status/visibility of the UI. - var/datum/ui_state/state = null // Topic state used to determine status/interactability. - var/datum/tgui/master_ui // The parent UI. - var/list/datum/tgui/children = list() // Children of this UI. - var/titlebar = TRUE + /// 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 ui_key of the UI. This allows multiple UIs for one src_object. + var/ui_key + /// The window_id for browse() and onclose(). + var/window_id + /// The window width. + var/width = 0 + /// The window height + var/height = 0 + /// The style to be used for this UI. + var/style = "nanotrasen" + /// 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 + /// The data (and datastructure) used to initialize the UI. + var/list/initial_data + /// The static data used to initialize the UI. + var/list/initial_static_data + /// The status/visibility of the UI. + var/status = UI_INTERACTIVE + /// Topic state used to determine status/interactability. + var/datum/ui_state/state = null + /// The parent UI. + var/datum/tgui/master_ui + /// Children of this UI. + var/list/datum/tgui/children = list() var/custom_browser_id = FALSE var/ui_screen = "home" @@ -58,7 +66,7 @@ src.user = user src.src_object = src_object src.ui_key = ui_key - src.window_id = browser_id ? browser_id : "[REF(src_object)]-[ui_key]" + src.window_id = browser_id ? browser_id : "[REF(src_object)]-[ui_key]" // DO NOT replace with \ref here. src_object could potentially be tagged src.custom_browser_id = browser_id ? TRUE : FALSE set_interface(interface) @@ -75,7 +83,7 @@ master_ui.children += src src.state = state - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/tgui) + var/datum/asset/assets = get_asset_datum(/datum/asset/group/tgui) assets.send(user) /** @@ -87,21 +95,47 @@ if(!user.client) return // Bail if there is no client. - update_status(push = 0) // Update the window status. + update_status(push = FALSE) // Update the window status. if(status < UI_UPDATE) return // Bail if we're not supposed to open. - if(!initial_data) - set_initial_data(src_object.ui_data(user)) // Get the UI data. - - var/window_size = "" + var/window_size if(width && height) // If we have a width and height, use them. window_size = "size=[width]x[height];" + else + window_size = "" - var/debugable = check_rights_for(user.client, R_DEBUG) - user << browse(get_html(debugable), "window=[window_id];[window_size][list2params(window_options)]") // Open the window. + // Remove titlebar and resize handles for a fancy window + var/have_title_bar + if(user.client.prefs.tgui_fancy) + have_title_bar = "titlebar=0;can_resize=0;" + else + have_title_bar = "titlebar=1;can_resize=1;" + + // Generate page html + var/html + html = SStgui.basehtml + // Allow the src object to override the html if needed + html = src_object.ui_base_html(html) + // Replace template tokens with important UI data + // NOTE: Intentional \ref usage; tgui datums can't/shouldn't + // be tagged, so this is an effective unwrap + html = replacetextEx(html, "\[ref]", "\ref[src]") + html = replacetextEx(html, "\[style]", style) + + // Open the window. + user << browse(html, "window=[window_id];can_minimize=0;auto_format=0;[window_size][have_title_bar]") if (!custom_browser_id) - winset(user, window_id, "on-close=\"uiclose [REF(src)]\"") // Instruct the client to signal UI when the window is closed. + // Instruct the client to signal UI when the window is closed. + // NOTE: Intentional \ref usage; tgui datums can't/shouldn't + // be tagged, so this is an effective unwrap + winset(user, window_id, "on-close=\"uiclose \ref[src]\"") + + if(!initial_data) + initial_data = src_object.ui_data(user) + if(!initial_static_data) + initial_static_data = src_object.ui_static_data(user) + SStgui.on_open(src) /** @@ -113,11 +147,13 @@ * optional template string The name of the new interface. * optional data list The new initial data. **/ -/datum/tgui/proc/reinitialize(interface, list/data) +/datum/tgui/proc/reinitialize(interface, list/data, list/static_data) if(interface) set_interface(interface) // Set a new interface. if(data) - set_initial_data(data) // Replace the initial_data. + initial_data = data + if(static_data) + initial_static_data = static_data open() /** @@ -136,16 +172,6 @@ master_ui = null qdel(src) - /** - * public - * - * Sets the browse() window options for this UI. - * - * required window_options list The window options to set. - **/ -/datum/tgui/proc/set_window_options(list/window_options) - src.window_options = window_options - /** * public * @@ -173,78 +199,9 @@ * * required state bool Enable/disable auto-updating. **/ -/datum/tgui/proc/set_autoupdate(state = 1) +/datum/tgui/proc/set_autoupdate(state = TRUE) autoupdate = state - /** - * private - * - * Set the data to initialize the UI with. - * The datastructure cannot be changed by subsequent updates. - * - * optional data list The data/datastructure to initialize the UI with. - **/ -/datum/tgui/proc/set_initial_data(list/data) - initial_data = data - - /** - * private - * - * Generate HTML for this UI. - * - * optional bool inline If the JSON should be inlined into the HTML (for debugging). - * - * return string UI HTML output. - **/ -/datum/tgui/proc/get_html(var/inline) - var/html - html = SStgui.basehtml - - //Allow the src object to override the html if needed - html = src_object.ui_base_html(html) - //Strip out any remaining custom tags that are used in ui_base_html - html = replacetext(html, "", "") - - // Poplate HTML with JSON if we're supposed to inline. - if(inline) - html = replacetextEx(html, "{}", get_json(initial_data)) - - - //Setup for tgui stuff, including styles - html = replacetextEx(html, "\[ref]", "[REF(src)]") - html = replacetextEx(html, "\[style]", style) - return html - - /** - * private - * - * Get the config data/datastructure to initialize the UI with. - * - * return list The config data. - **/ -/datum/tgui/proc/get_config_data() - var/list/config_data = list( - "title" = title, - "status" = status, - "screen" = ui_screen, - "style" = style, - "interface" = interface, - "fancy" = user.client.prefs.tgui_fancy, - "locked" = user.client.prefs.tgui_lock && !custom_browser_id, - "window" = window_id, - "ref" = "[REF(src)]", - "user" = list( - "name" = user.name, - "ref" = "[REF(user)]" - ), - "srcObject" = list( - "name" = "[src_object]", - "ref" = "[REF(src_object)]" - ), - "titlebar" = titlebar - ) - return config_data - /** * private * @@ -253,12 +210,28 @@ * * return string The packaged JSON. **/ -/datum/tgui/proc/get_json(list/data) +/datum/tgui/proc/get_json(list/data, list/static_data) var/list/json_data = list() - json_data["config"] = get_config_data() + json_data["config"] = list( + "title" = title, + "status" = status, + "screen" = ui_screen, + "style" = style, + "interface" = interface, + "fancy" = user.client.prefs.tgui_fancy, + "locked" = user.client.prefs.tgui_lock && !custom_browser_id, + "observer" = isobserver(user), + "window" = window_id, + // NOTE: Intentional \ref usage; tgui datums can't/shouldn't + // be tagged, so this is an effective unwrap + "ref" = "\ref[src]" + ) + if(!isnull(data)) json_data["data"] = data + if(!isnull(static_data)) + json_data["static_data"] = static_data // Generate the JSON. var/json = json_encode(json_data) @@ -283,12 +256,16 @@ switch(action) if("tgui:initialize") - user << output(url_encode(get_json(initial_data)), "[custom_browser_id ? window_id : "[window_id].browser"]:initialize") + user << output(url_encode(get_json(initial_data, initial_static_data)), "[custom_browser_id ? window_id : "[window_id].browser"]:initialize") initialized = TRUE if("tgui:view") if(params["screen"]) ui_screen = params["screen"] SStgui.update_uis(src_object) + if("tgui:log") + // Force window to show frills on fatal errors + if(params["fatal"]) + winset(user, window_id, "titlebar=1;can-resize=1;size=600x600") if("tgui:link") user << link(params["url"]) if("tgui:fancy") @@ -296,7 +273,7 @@ if("tgui:nofrills") user.client.prefs.tgui_fancy = FALSE else - update_status(push = 0) // Update the window state. + update_status(push = FALSE) // Update the window state. if(src_object.ui_act(action, params, src, state)) // Call ui_act() on the src_object. SStgui.update_uis(src_object) // Update if the object requested it. @@ -308,7 +285,7 @@ * * optional force bool If the UI should be forced to update. **/ -/datum/tgui/process(force = 0) +/datum/tgui/process(force = FALSE) var/datum/host = src_object.ui_host(user) if(!src_object || !host || !user) // If the object or user died (or something else), abort. close() @@ -317,7 +294,7 @@ if(status && (force || autoupdate)) update() // Update the UI if the status and update settings allow it. else - update_status(push = 1) // Otherwise only update status. + update_status(push = TRUE) // Otherwise only update status. /** * private @@ -327,15 +304,15 @@ * required data list The data to send. * optional force bool If the update should be sent regardless of state. **/ -/datum/tgui/proc/push_data(data, force = 0) - update_status(push = 0) // Update the window state. +/datum/tgui/proc/push_data(data, static_data, force = FALSE) + update_status(push = FALSE) // Update the window state. if(!initialized) return // Cannot update UI if it is not set up yet. if(status <= UI_DISABLED && !force) return // Cannot update UI, we have no visibility. // Send the new JSON to the update() Javascript function. - user << output(url_encode(get_json(data)), "[custom_browser_id ? window_id : "[window_id].browser"]:update") + user << output(url_encode(get_json(data, static_data)), "[custom_browser_id ? window_id : "[window_id].browser"]:update") /** * private @@ -355,11 +332,10 @@ * * optional push bool Push an update to the UI (an update is always sent for UI_DISABLED). **/ -/datum/tgui/proc/update_status(push = 0) +/datum/tgui/proc/update_status(push = FALSE) var/status = src_object.ui_status(user, state) if(master_ui) status = min(status, master_ui.status) - set_status(status, push) if(status == UI_CLOSE) close() @@ -372,7 +348,7 @@ * required status int The status to set (UI_CLOSE/UI_DISABLED/UI_UPDATE/UI_INTERACTIVE). * optional push bool Push an update to the UI (an update is always sent for UI_DISABLED). **/ -/datum/tgui/proc/set_status(status, push = 0) +/datum/tgui/proc/set_status(status, push = FALSE) if(src.status != status) // Only update if status has changed. if(src.status == UI_DISABLED) src.status = status @@ -381,7 +357,8 @@ else src.status = status if(status == UI_DISABLED || push) // Update if the UI just because disabled, or a push is requested. - push_data(null, force = 1) + push_data(null, force = TRUE) + +/datum/tgui/proc/log_message(message) + log_tgui("[user] ([user.ckey]) using \"[title]\":\n[message]") -/datum/tgui/proc/set_titlebar(value) - titlebar = value diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index c23662de5a..c739d426c2 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -2,6 +2,7 @@ //Keep this sorted alphabetically #ifdef UNIT_TESTS +#include "anchored_mobs.dm" #include "component_tests.dm" #include "reagent_id_typos.dm" #include "reagent_recipe_collisions.dm" diff --git a/code/modules/unit_tests/anchored_mobs.dm b/code/modules/unit_tests/anchored_mobs.dm new file mode 100644 index 0000000000..5324179bb7 --- /dev/null +++ b/code/modules/unit_tests/anchored_mobs.dm @@ -0,0 +1,9 @@ +/datum/unit_test/anchored_mobs/Run() + var/list/L = list() + for(var/i in typesof(/mob)) + var/mob/M = i + if(initial(M.anchored)) + L += "[i]" + if(!L.len) + return //passed! + Fail("The following mobs are defined as anchored. This is incompatible with the new move force/resist system and needs to be revised.: [L.Join(" ")]") \ No newline at end of file diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index 18dc34e34b..b75f212ba9 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -117,37 +117,37 @@ category = "Holiday" /datum/uplink_item/bundles_TC - category = "Bundles and Telecrystals" + category = "Telecrystals and Bundles" surplus = 0 cant_discount = TRUE /datum/uplink_item/dangerous - category = "Conspicuous and Dangerous Weapons" + category = "Conspicuous Weapons" /datum/uplink_item/stealthy_weapons - category = "Stealthy and Inconspicuous Weapons" + category = "Stealthy Weapons" /datum/uplink_item/ammo category = "Ammunition" surplus = 40 /datum/uplink_item/explosives - category = "Grenades and Explosives" + category = "Explosives" /datum/uplink_item/support - category = "Support and Mechanized Exosuits" + category = "Support and Exosuits" surplus = 0 include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/suits - category = "Space Suits, Hardsuits and Clothing" + category = "Clothing" surplus = 40 /datum/uplink_item/stealthy_tools - category = "Stealth and Camouflage Items" + category = "Stealth Gadgets" /datum/uplink_item/device_tools - category = "Devices and Tools" + category = "Misc. Gadgets" /datum/uplink_item/implants category = "Implants" @@ -164,4 +164,4 @@ //Discounts (dynamically filled above) /datum/uplink_item/discounts - category = "Discounted Gear" + category = "Discounted Gear" \ No newline at end of file diff --git a/code/modules/uplink/uplink_items/uplink_clothing.dm b/code/modules/uplink/uplink_items/uplink_clothing.dm index 2881aa8dfd..5e2c09ec13 100644 --- a/code/modules/uplink/uplink_items/uplink_clothing.dm +++ b/code/modules/uplink/uplink_items/uplink_clothing.dm @@ -23,21 +23,21 @@ /datum/uplink_item/suits/padding name = "Soft Padding" - desc = "Padding to add to a jumpsuit to help against melee and bullets." + desc = "An inconspicious soft padding meant to be worn underneath jumpsuits, will cushion the user from melee harm." item = /obj/item/clothing/accessory/padding cost = 2 exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/suits/kevlar - name = "Kevlar sheets" - desc = "Kevlar sheets to add to jumpsuit to help against bullets and melee." + name = "Kevlar Padding" + desc = "An inconspicious kevlar padding meant to be worn underneath jumpsuits, will cushion the wearer from ballistic harm." item = /obj/item/clothing/accessory/kevlar cost = 2 exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/suits/plastic - name = "Plastic sheet" - desc = "Plastic body sheet to add to a jumpsuit to help against laser and energy harm." + name = "Ablative Padding" + desc = "An inconspicious ablative padding meant to be worn underneath jumpsuits, will cushion the wearer from energy lasers harm." item = /obj/item/clothing/accessory/plastics cost = 2 exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) @@ -59,7 +59,7 @@ Nanotrasen crew who spot these suits are known to panic." item = /obj/item/clothing/suit/space/hardsuit/syndi cost = 8 - exclude_modes = list(/datum/game_mode/nuclear) //you can't buy it in nuke, because the elite hardsuit costs the same while being better + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //you can't buy it in nuke, because the elite hardsuit costs the same while being better /datum/uplink_item/suits/hardsuit/elite name = "Elite Syndicate Hardsuit" diff --git a/code/modules/uplink/uplink_items/uplink_dangerous.dm b/code/modules/uplink/uplink_items/uplink_dangerous.dm index a7f644ccbe..56ebda1af7 100644 --- a/code/modules/uplink/uplink_items/uplink_dangerous.dm +++ b/code/modules/uplink/uplink_items/uplink_dangerous.dm @@ -126,6 +126,7 @@ The illegal modifications bring this weapon up to par with the classic energy sword, and also gives it the energy sword's distinctive sounds." item = /obj/item/melee/transforming/energy/sword/cx/traitor cost = 8 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) /datum/uplink_item/dangerous/sword name = "Energy Sword" diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm index 70c70a61b9..05731722f7 100644 --- a/code/modules/uplink/uplink_items/uplink_devices.dm +++ b/code/modules/uplink/uplink_items/uplink_devices.dm @@ -92,7 +92,7 @@ desc = "A robust seven-slot set of webbing that is capable of holding all manner of tactical equipment." item = /obj/item/storage/belt/military cost = 1 - exclude_modes = list(/datum/game_mode/nuclear) + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/device_tools/fakenucleardisk name = "Decoy Nuclear Authentication Disk" @@ -135,6 +135,12 @@ item = /obj/item/aiModule/syndicate cost = 9 +/datum/uplink_item/device_tools/headsetupgrade + name = "Headset Upgrader" + desc = "A device that can be used to make one headset immune to flashbangs." + item = /obj/item/headsetupgrader + cost = 3 + /datum/uplink_item/device_tools/medgun name = "Medbeam Gun" desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \ diff --git a/code/modules/uplink/uplink_items/uplink_implants.dm b/code/modules/uplink/uplink_items/uplink_implants.dm index 3262809cb5..d8a31a9b9c 100644 --- a/code/modules/uplink/uplink_items/uplink_implants.dm +++ b/code/modules/uplink/uplink_items/uplink_implants.dm @@ -20,7 +20,7 @@ desc = "This implant will help you get back up on your feet faster after being stunned. Comes with an autosurgeon." item = /obj/item/autosurgeon/anti_stun cost = 12 - include_modes = list(/datum/game_mode/nuclear) + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/implants/freedom name = "Freedom Implant" @@ -36,7 +36,7 @@ This will permanently destroy your body, however." item = /obj/item/storage/box/syndie_kit/imp_microbomb cost = 2 - include_modes = list(/datum/game_mode/nuclear) + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/implants/macrobomb name = "Macrobomb Implant" @@ -44,7 +44,7 @@ Upon death, releases a massive explosion that will wipe out everything nearby." item = /obj/item/storage/box/syndie_kit/imp_macrobomb cost = 20 - include_modes = list(/datum/game_mode/nuclear) + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) restricted = TRUE /datum/uplink_item/implants/radio @@ -60,7 +60,7 @@ desc = "This implant will attempt to revive and heal you if you lose consciousness. Comes with an autosurgeon." item = /obj/item/autosurgeon/reviver cost = 8 - include_modes = list(/datum/game_mode/nuclear) + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/implants/stealthimplant name = "Stealth Implant" @@ -81,7 +81,7 @@ desc = "These cybernetic eyes will give you thermal vision. Comes with a free autosurgeon." item = /obj/item/autosurgeon/thermal_eyes cost = 8 - include_modes = list(/datum/game_mode/nuclear) + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/implants/uplink name = "Uplink Implant" @@ -99,4 +99,4 @@ item = /obj/item/autosurgeon/xray_eyes cost = 10 surplus = 0 - include_modes = list(/datum/game_mode/nuclear) + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) diff --git a/code/modules/uplink/uplink_items/uplink_roles.dm b/code/modules/uplink/uplink_items/uplink_roles.dm index 89d3c25700..09f6e94763 100644 --- a/code/modules/uplink/uplink_items/uplink_roles.dm +++ b/code/modules/uplink/uplink_items/uplink_roles.dm @@ -126,9 +126,9 @@ /datum/uplink_item/role_restricted/goldenbox name = "Gold Toolbox" - desc = "A gold planted plastitanium toolbox loaded with tools. Comes with a set of AI detection multi-tool and a pare of combat gloves." - item = /obj/item/storage/toolbox/gold_real - cost = 3 // Has syndie tools + gloves + a robust weapon + desc = "A gold plated plastitanium toolbox. It comes loaded with a full tool set including a AI detector multitool and combat gloves." + item = /obj/item/storage/toolbox/plastitanium/gold_real + cost = 4 // Has syndie tools + gloves + a robust weapon restricted_roles = list("Assistant", "Curator") //Curator due to this being made of gold - It fits the theme /datum/uplink_item/role_restricted/mimery diff --git a/code/modules/uplink/uplink_items/uplink_stealth.dm b/code/modules/uplink/uplink_items/uplink_stealth.dm index 65a8ad4080..0ad06e7418 100644 --- a/code/modules/uplink/uplink_items/uplink_stealth.dm +++ b/code/modules/uplink/uplink_items/uplink_stealth.dm @@ -74,7 +74,7 @@ item = /obj/item/gun/energy/kinetic_accelerator/crossbow cost = 12 surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear) + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/stealthy_weapons/traitor_chem_bottle name = "Poison Kit" @@ -101,7 +101,7 @@ falls asleep, they will be able to move and act." item = /obj/item/pen/sleepy cost = 4 - exclude_modes = list(/datum/game_mode/nuclear) + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) datum/uplink_item/stealthy_weapons/taeclowndo_shoes name = "Tae-clown-do Shoes" @@ -117,7 +117,6 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes item = /obj/item/suppressor cost = 1 surplus = 10 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) /datum/uplink_item/stealthy_weapons/soap name = "Syndicate Soap" diff --git a/code/modules/uplink/uplink_items/uplink_stealthdevices.dm b/code/modules/uplink/uplink_items/uplink_stealthdevices.dm index d98548612e..2a4e51e09a 100644 --- a/code/modules/uplink/uplink_items/uplink_stealthdevices.dm +++ b/code/modules/uplink/uplink_items/uplink_stealthdevices.dm @@ -32,7 +32,7 @@ Due to budget cuts, the shoes don't provide protection against slipping." item = /obj/item/storage/box/syndie_kit/chameleon cost = 2 - exclude_modes = list(/datum/game_mode/nuclear) + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) /datum/uplink_item/stealthy_tools/chameleon_proj name = "Chameleon Projector" diff --git a/code/modules/vending/cigarette.dm b/code/modules/vending/cigarette.dm index ce5f0bf03a..f567c9765e 100644 --- a/code/modules/vending/cigarette.dm +++ b/code/modules/vending/cigarette.dm @@ -13,7 +13,8 @@ /obj/item/lighter/greyscale = 4, /obj/item/storage/fancy/rollingpapers = 5) contraband = list(/obj/item/lighter = 3, - /obj/item/clothing/mask/vape = 5) + /obj/item/clothing/mask/vape = 5, + /obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 1) premium = list(/obj/item/storage/fancy/cigarettes/cigpack_robustgold = 3, /obj/item/storage/fancy/cigarettes/cigars = 1, /obj/item/storage/fancy/cigarettes/cigars/havana = 1, diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index 0b1d8e1072..e74e82351b 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -144,7 +144,13 @@ /obj/item/clothing/head/cowboyhat/white = 3, /obj/item/clothing/head/cowboyhat/pink = 3, /obj/item/clothing/shoes/cowboyboots = 3, - /obj/item/clothing/shoes/cowboyboots/black = 3) + /obj/item/clothing/shoes/cowboyboots/black = 3, + /obj/item/clothing/under/lunar/qipao = 3, + /obj/item/clothing/under/lunar/qipao/white = 3, + /obj/item/clothing/under/lunar/qipao/red = 3, + /obj/item/clothing/under/lunar/cheongsam = 3, + /obj/item/clothing/under/lunar/cheongsam/white = 3, + /obj/item/clothing/under/lunar/cheongsam/red = 3) contraband = list(/obj/item/clothing/under/syndicate/tacticool = 3, /obj/item/clothing/under/syndicate/tacticool/skirt = 3, /obj/item/clothing/mask/balaclava = 3, @@ -164,7 +170,8 @@ /obj/item/clothing/suit/jacket/leather/overcoat = 4, /obj/item/clothing/under/pants/mustangjeans = 3, /obj/item/clothing/neck/necklace/dope = 5, - /obj/item/clothing/suit/jacket/letterman_nanotrasen = 5) + /obj/item/clothing/suit/jacket/letterman_nanotrasen = 5, + /obj/item/clothing/suit/hooded/wintercoat/polychromic = 5) refill_canister = /obj/item/vending_refill/clothing /obj/item/vending_refill/clothing diff --git a/code/modules/vending/drinnerware.dm b/code/modules/vending/drinnerware.dm index 1c29fff137..9ba8c53f6c 100644 --- a/code/modules/vending/drinnerware.dm +++ b/code/modules/vending/drinnerware.dm @@ -14,6 +14,8 @@ /obj/item/reagent_containers/food/condiment/pack/mustard = 5, /obj/item/reagent_containers/food/condiment/pack/hotsauce = 5, /obj/item/reagent_containers/food/condiment/pack/astrotame = 5, + /obj/item/reagent_containers/food/condiment/pack/bbqsauce = 5, + /obj/item/reagent_containers/food/condiment/pack/soysauce = 5, /obj/item/reagent_containers/food/condiment/saltshaker = 5, /obj/item/reagent_containers/food/condiment/peppermill = 5, /obj/item/reagent_containers/glass/bowl = 30) @@ -23,7 +25,6 @@ /obj/item/reagent_containers/syringe = 3) premium = list( /obj/item/reagent_containers/food/condiment/enzyme = 1, - /obj/item/reagent_containers/food/condiment/soysauce = 1, /obj/item/reagent_containers/glass/bottle/cryoxadone = 2) // Bartender can literally make this with upgraded parts, or it gets stolen from medical. armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF diff --git a/code/modules/vending/sovietvend.dm b/code/modules/vending/sovietvend.dm index 086b37e4ee..5157f68410 100644 --- a/code/modules/vending/sovietvend.dm +++ b/code/modules/vending/sovietvend.dm @@ -15,10 +15,9 @@ /obj/item/clothing/head/russobluecamohat = 20 ) contraband = list( - /obj/item/clothing/under/syndicate/tacticool = 4, + /obj/item/clothing/suit/armor/vest/russian_coat = 4, /obj/item/clothing/mask/balaclava = 4, - /obj/item/clothing/suit/russofurcoat = 4, - /obj/item/clothing/head/russofurhat = 4, + /obj/item/clothing/head/helmet/rus_ushanka = 4, /obj/item/clothing/suit/space/hardsuit/soviet = 3, /obj/item/gun/energy/laser/LaserAK = 4 ) diff --git a/code/modules/vore/eating/belly_obj.dm b/code/modules/vore/eating/belly_obj.dm index ad54c8a0c8..f88f6bd6e8 100644 --- a/code/modules/vore/eating/belly_obj.dm +++ b/code/modules/vore/eating/belly_obj.dm @@ -1,4 +1,5 @@ -//#define VORE_SOUND_FALLOFF 0.05 +#define VORE_SOUND_FALLOFF 0.1 +#define VORE_SOUND_RANGE 3 // // Belly system 2.0, now using objects instead of datums because EH at datums. @@ -164,7 +165,12 @@ . = ..() // Called whenever an atom enters this belly -/obj/belly/Entered(var/atom/movable/thing,var/atom/OldLoc) +/obj/belly/Entered(atom/movable/thing, atom/OldLoc) + . = ..() + var/mob/living/L //for chat messages and blindness + if(isliving(thing)) + L = thing + L.become_blind("belly_[REF(src)]") if(OldLoc in contents) return //Someone dropping something (or being stripdigested) @@ -175,7 +181,7 @@ if(vore_sound && !recent_sound) if((world.time + NORMIE_HEARCHECK) > last_hearcheck) LAZYCLEARLIST(hearing_mobs) - for(var/mob/living/H in get_hearers_in_view(3, owner)) + for(var/mob/living/H in get_hearers_in_view(VORE_SOUND_RANGE, owner)) if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES)) continue LAZYADD(hearing_mobs, H) @@ -189,11 +195,14 @@ SEND_SOUND(H,eating) recent_sound = TRUE - //Messages if it's a mob - if(isliving(thing)) - var/mob/living/M = thing - if(desc) - to_chat(M, "[desc]") + if(L && desc) + to_chat(L, "[desc]") + +/obj/belly/Exited(atom/movable/AM, atom/newloc) + . = ..() + if(isliving(AM)) + var/mob/living/L = AM + L.cure_blind("belly_[REF(src)]") // Release all contents of this belly into the owning mob's location. // If that location is another mob, contents are transferred into whichever of its bellies the owning mob is in. @@ -214,7 +223,6 @@ continue L.absorbed = FALSE L.stop_sound_channel(CHANNEL_PREYLOOP) - L.cure_blind("belly_[REF(src)]") SEND_SIGNAL(OW, COMSIG_CLEAR_MOOD_EVENT, "fedpred", /datum/mood_event/fedpred) SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey) SEND_SIGNAL(OW, COMSIG_ADD_MOOD_EVENT, "emptypred", /datum/mood_event/emptypred) @@ -229,7 +237,7 @@ if(release_sound && !recent_sound) if((world.time + NORMIE_HEARCHECK) > last_hearcheck) LAZYCLEARLIST(hearing_mobs) - for(var/mob/living/H in get_hearers_in_view(3, owner)) + for(var/mob/living/H in get_hearers_in_view(VORE_SOUND_RANGE, owner)) if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES)) continue LAZYADD(hearing_mobs, H) @@ -237,7 +245,7 @@ for(var/mob/living/H in hearing_mobs) if(H && H.client && (isturf(H.loc) || (H.loc != src.contents))) var/sound/releasement = GLOB.pred_release_sounds[release_sound] - SEND_SOUND(H,releasement) + H.playsound_local(owner.loc, releasement, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF) else if(H && H in contents && H.client) var/sound/releasement = GLOB.prey_release_sounds[release_sound] SEND_SOUND(H,releasement) @@ -262,7 +270,6 @@ var/mob/living/OW = owner if(ML.client) ML.stop_sound_channel(CHANNEL_PREYLOOP) //Stop the internal loop, it'll restart if the isbelly check on next tick anyway - ML.cure_blind("belly_[REF(src)]") SEND_SIGNAL(OW, COMSIG_CLEAR_MOOD_EVENT, "fedpred", /datum/mood_event/fedpred) SEND_SIGNAL(ML, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey) SEND_SIGNAL(OW, COMSIG_ADD_MOOD_EVENT, "emptypred", /datum/mood_event/emptypred) @@ -294,7 +301,7 @@ for(var/mob/living/H in hearing_mobs) if(H && H.client && (isturf(H.loc) || (H.loc != src.contents))) var/sound/releasement = GLOB.pred_release_sounds[release_sound] - SEND_SOUND(H,releasement) + H.playsound_local(owner.loc, releasement, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF) else if(H && H in contents && H.client) var/sound/releasement = GLOB.prey_release_sounds[release_sound] SEND_SOUND(H,releasement) @@ -325,7 +332,6 @@ for(var/mob/living/M in contents) M.updateVRPanel() - M.become_blind("belly_[REF(src)]") // Setup the autotransfer checks if needed if(transferlocation != null && autotransferchance > 0) @@ -345,13 +351,11 @@ if(!(content in src) || !istype(target)) return content.forceMove(target) - for(var/mob/living/M in contents) - M.cure_blind("belly_[REF(src)]") -// target.nom_mob(content, target.owner) + if(vore_sound && !recent_sound && !silent) if((world.time + NORMIE_HEARCHECK) > last_hearcheck) LAZYCLEARLIST(hearing_mobs) - for(var/mob/living/H in get_hearers_in_view(3, owner)) + for(var/mob/living/H in get_hearers_in_view(VORE_SOUND_RANGE, owner)) if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES)) continue LAZYADD(hearing_mobs, H) @@ -359,7 +363,7 @@ for(var/mob/living/H in hearing_mobs) if(H && H.client && (isturf(H.loc) || (H.loc != src.contents))) var/sound/eating = GLOB.pred_vore_sounds[vore_sound] - SEND_SOUND(H,eating) + H.playsound_local(owner.loc, eating, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF) else if(H && H in contents && H.client) var/sound/eating = GLOB.prey_vore_sounds[vore_sound] SEND_SOUND(H,eating) @@ -576,7 +580,7 @@ var/sound/struggle_rustle = sound(get_sfx("rustle")) LAZYCLEARLIST(hearing_mobs) - for(var/mob/living/H in get_hearers_in_view(3, owner)) + for(var/mob/living/H in get_hearers_in_view(VORE_SOUND_RANGE, owner)) if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES)) continue LAZYADD(hearing_mobs, H) @@ -584,14 +588,14 @@ if(is_wet) for(var/mob/living/H in hearing_mobs) if(H && H.client && (isturf(H.loc) || (H.loc != src.contents))) - SEND_SOUND(H,pred_struggle_snuggle) + H.playsound_local(owner.loc, pred_struggle_snuggle, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF) else if(H && H in contents && H.client) SEND_SOUND(H,prey_struggle_snuggle) else for(var/mob/living/H in hearing_mobs) if(H && H.client) - SEND_SOUND(H, struggle_rustle) + H.playsound_local(owner.loc, struggle_rustle, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF) for(var/mob/living/H in hearing_mobs) if(H && H.client && (isturf(H.loc))) diff --git a/code/modules/vore/eating/bellymodes.dm b/code/modules/vore/eating/bellymodes.dm index 0ecaf49abc..6942a2d5a9 100644 --- a/code/modules/vore/eating/bellymodes.dm +++ b/code/modules/vore/eating/bellymodes.dm @@ -18,7 +18,8 @@ return SSBELLIES_PROCESSED next_process = times_fired + (6 SECONDS/wait) //Set up our next process time. - var/to_update = FALSE + var/play_sound //Potential sound to play at the end to avoid code duplication. + var/to_update = FALSE //Did anything update worthy happen? /////////////////////////// Auto-Emotes /////////////////////////// if(contents.len && next_emote <= times_fired) @@ -40,7 +41,7 @@ if(M.client.prefs.cit_toggles & DIGESTION_NOISES) var/sound/preyloop = sound('sound/vore/prey/loop.ogg') M.playsound_local(get_turf(src),preyloop, 80,0, channel = CHANNEL_PREYLOOP) - M.next_preyloop = (world.time + 51 SECONDS) + M.next_preyloop = (world.time + 52 SECONDS) /////////////////////////// Exit Early //////////////////////////// @@ -71,18 +72,9 @@ for (var/mob/living/M in contents) if(prob(25)) - if((world.time + NORMIE_HEARCHECK) > last_hearcheck) - LAZYCLEARLIST(hearing_mobs) - for(var/mob/living/H in get_hearers_in_view(3, owner)) - if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) - continue - LAZYADD(hearing_mobs, H) - last_hearcheck = world.time - for(var/mob/living/H in hearing_mobs) - if(H && H.client && (isturf(H.loc) || (H.loc != src.contents))) - SEND_SOUND(H,pred_digest) - else if(H && H in contents && H.client) - SEND_SOUND(H,prey_digest) + if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES) + SEND_SOUND(M,prey_digest) + play_sound = pick(pred_digest) //Pref protection! if (!M.digestable || M.absorbed) @@ -108,18 +100,9 @@ M.visible_message("You watch as [owner]'s form loses its additions.") owner.nutrition += 400 // so eating dead mobs gives you *something*. - if((world.time + NORMIE_HEARCHECK) > last_hearcheck) - LAZYCLEARLIST(hearing_mobs) - for(var/mob/living/H in get_hearers_in_view(3, owner)) - if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) - continue - LAZYADD(hearing_mobs, H) - last_hearcheck = world.time - for(var/mob/living/H in hearing_mobs) - if(H && H.client && (isturf(H.loc) || (H.loc != src.contents))) - SEND_SOUND(H,pred_death) - else if(H && H in contents && H.client) - SEND_SOUND(H,prey_death) + play_sound = pick(pred_death) + if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES) + SEND_SOUND(M,prey_death) M.stop_sound_channel(CHANNEL_PREYLOOP) digestion_death(M) owner.update_icons() @@ -142,19 +125,9 @@ if(digest_mode == DM_HEAL) for (var/mob/living/M in contents) if(prob(25)) - if((world.time + NORMIE_HEARCHECK) > last_hearcheck) - LAZYCLEARLIST(hearing_mobs) - for(var/mob/living/H in get_hearers_in_view(3, owner)) - if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) - continue - LAZYADD(hearing_mobs, H) - last_hearcheck = world.time - for(var/mob/living/H in hearing_mobs) - if(H && H.client && (isturf(H.loc) || (H.loc != src.contents))) - SEND_SOUND(H,pred_digest) - else if(H && H in contents && H.client) - SEND_SOUND(H,prey_digest) - + if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES) + SEND_SOUND(M,prey_digest) + play_sound = pick(pred_digest) if(M.stat != DEAD) if(owner.nutrition >= NUTRITION_LEVEL_STARVING && (M.health < M.maxHealth)) M.adjustBruteLoss(-3) @@ -165,18 +138,10 @@ //for when you just want people to squelch around if(digest_mode == DM_NOISY) if(prob(35)) - if((world.time + NORMIE_HEARCHECK) > last_hearcheck) - LAZYCLEARLIST(hearing_mobs) - for(var/mob/living/H in get_hearers_in_view(3, owner)) - if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) - continue - LAZYADD(hearing_mobs, H) - last_hearcheck = world.time - for(var/mob/living/H in hearing_mobs) - if(H && H.client && (isturf(H.loc) || (H.loc != src.contents))) - SEND_SOUND(H,pred_digest) - else if(H && H in contents && H.client) - SEND_SOUND(H,prey_digest) + for(var/mob/M in contents) + if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES) + SEND_SOUND(M,prey_digest) + play_sound = pick(pred_digest) //////////////////////////// DM_ABSORB //////////////////////////// @@ -185,18 +150,9 @@ for (var/mob/living/M in contents) if(prob(10))//Less often than gurgles. People might leave this on forever. - if((world.time + NORMIE_HEARCHECK) > last_hearcheck) - LAZYCLEARLIST(hearing_mobs) - for(var/mob/living/H in get_hearers_in_view(3, owner)) - if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) - continue - LAZYADD(hearing_mobs, H) - last_hearcheck = world.time - for(var/mob/living/H in hearing_mobs) - if(H && H.client && (isturf(H.loc) || (H.loc != src.contents))) - SEND_SOUND(H,pred_digest) - else if(H && H in contents && H.client) - SEND_SOUND(H,prey_digest) + if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES) + SEND_SOUND(M,prey_digest) + play_sound = pick(pred_digest) if(M.absorbed) continue @@ -262,18 +218,9 @@ to_chat(owner, "[digest_alert_owner]") to_chat(M, "[digest_alert_prey]") M.visible_message("You watch as [owner]'s guts loudly rumble as it finishes off a meal.") - if((world.time + NORMIE_HEARCHECK) > last_hearcheck) - LAZYCLEARLIST(hearing_mobs) - for(var/mob/living/H in get_hearers_in_view(3, owner)) - if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES)) - continue - LAZYADD(hearing_mobs, H) - last_hearcheck = world.time - for(var/mob/living/H in hearing_mobs) - if(H && H.client && (isturf(H.loc) || (H.loc != src.contents))) - SEND_SOUND(H,pred_death) - else if(H && H in contents && H.client) - SEND_SOUND(H,prey_death) + play_sound = pick(pred_death) + if(M && M.client && M.client.prefs.cit_toggles & DIGESTION_NOISES) + SEND_SOUND(M,prey_death) M.spill_organs(FALSE,TRUE,TRUE) M.stop_sound_channel(CHANNEL_PREYLOOP) digestion_death(M) @@ -293,6 +240,19 @@ if(istype(T,/obj/item/reagent_containers/food) || istype(T,/obj/item/organ)) digest_item(T) +/////////////////////////// Make any noise /////////////////////////// + if(play_sound) + if((world.time + NORMIE_HEARCHECK) > last_hearcheck) + LAZYCLEARLIST(hearing_mobs) + for(var/mob/M in hearers(VORE_SOUND_RANGE, owner)) + if(!M.client || !(M.client.prefs.cit_toggles & DIGESTION_NOISES)) + continue + LAZYADD(hearing_mobs, M) + last_hearcheck = world.time + for(var/mob/M in hearing_mobs) //so we don't fill the whole room with the sound effect + if(M && M.client && (isturf(M.loc) || (M.loc != src.contents))) //to avoid people on the inside getting the outside sounds and their direct sounds + built in sound pref check + M.playsound_local(owner.loc, play_sound, vol = 75, vary = 1, falloff = VORE_SOUND_FALLOFF) + //these are all external sound triggers now, so it's ok. if(to_update) for(var/mob/living/M in contents) if(M.client) diff --git a/code/modules/vore/eating/vore.dm b/code/modules/vore/eating/vore.dm index a9b14dcdc8..29391547bd 100644 --- a/code/modules/vore/eating/vore.dm +++ b/code/modules/vore/eating/vore.dm @@ -80,7 +80,7 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums) // /datum/vore_preferences/proc/load_path(ckey,slot,filename="character",ext="json") if(!ckey || !slot) return - path = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/vore/[filename][slot].[ext]" + path = "data/player_saves/[ckey[1]]/[ckey]/vore/[filename][slot].[ext]" /datum/vore_preferences/proc/load_vore() if(!client || !client_ckey) diff --git a/config/game_options.txt b/config/game_options.txt index b8b89de17c..0fa4db519d 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -39,7 +39,7 @@ WALK_DELAY 4 ## Entries completely override all subtypes. Later entries have precedence over earlier entries. ## This means if you put /mob 0 on the last entry, it will null out all changes, while if you put /mob as the first entry and ## /mob/living/carbon/human on the last entry, the last entry will override the first. -##MULTIPLICATIVE_MOVESPEED /mob/living/carbon/human 0 +MULTIPLICATIVE_MOVESPEED /mob/living/carbon/human 1 ##MULTIPLICATIVE_MOVESPEED /mob/living/silicon/robot 0 ##MULTIPLICATIVE_MOVESPEED /mob/living/carbon/monkey 0 ##MULTIPLICATIVE_MOVESPEED /mob/living/carbon/alien 0 @@ -591,9 +591,16 @@ BOX_RANDOM_ENGINE Box Singulo,3 BOX_RANDOM_ENGINE Box SM 1x3,1 BOX_RANDOM_ENGINE Box SM 5x5,1 BOX_RANDOM_ENGINE Box SM 3x,0 +BOX_RANDOM_ENGINE Box TEG,3 +BOX_RANDOM_ENGINE Box Empty,0 +BOX_RANDOM_ENGINE Box Antimatter,1 +BOX_RANDOM_ENGINE Box P.A.C.M.A.N,1 ## Whether or not there's a mode tier list vote after the secret/extended vote. MODETIER_VOTING ## Number of modes dropped by the modetier vote during mode selection, after vote. DROPPED_MODES 3 + +## Whether the suicide verb is allowed. +# SUICIDE_ALLOWED diff --git a/html/changelog.html b/html/changelog.html index 60412299cf..349a8ce012 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,463 @@ -->
        +

        27 January 2020

        +

        4dplanner, CRITAWAKETS, XDTM, ninjanomnom updated:

        +
          +
        • sepia slime extract has a delay before activating
        • +
        • the user of a sepia slime extract is no longer immune to the time field
        • +
        • chilling sepia is now the support extract - it always freezes the user, but not other marked people. give one to your golem!
        • +
        • burning sepia spawns the rewind camera. Take a selfie with someone and give it to them to make sure they remember the moment forever! You don't actually need to give them the photo, they'll remember anyway. Keep it as a reminder.
        • +
        • rewinding (deja vu) effect resets your location to the turf you were on after 10 seconds as well as resetting limbs/mobs/objects damage to the point it was added.
        • +
        • The deja vu effect cannot resurrect the dead, but will heal their corpse. New limbs fall off, old ones re-attach
        • +
        • Regenerative sepia cores add a deja vu effect before healing instead of a timestop remove: timefreeze camera is admin spawn only.
        • +
        • recurring sepia recalls to the hand of the last person to touch it after activating. Reusable timestop grenades!
        • +
        • some special cameras don't prompt for customisation
        • +
        • timefreeze camera actually makes a photo
        • +
        • timestop stops pathing and mechs.
        • +
        • adds a check to make sure simple_animals don't get their AI toggled while sentient
        • +
        • Adds the timestop overlay to frozen projectiles
        • +
        • Timestopped things have INFINITY move_resist as opposed to being anchored
        • +
        • Timestop will now unfreeze things that somehow leave it
        • +
        • mobs in the middle of a walk_to will have their walk stopped by timestop
        • +
        • mobs that are stunned will be stopped mid walk as well
        • +
        • pulling respects changes in move_force
        • +
        • swapping places respects move_force if the participant is not willing
        • +
        • timestop is properly defeated by antimagic.
        • +
        • timestop only checks antimagic once
        • +
        • Time stop now applies its visual effect on floors, walls and static structures (with no change otherwise)
        • +
        • Movable structures are now anchored while time stopped.
        • +
        • Timestop effects now prevent speech.
        • +
        +

        AffectedArc07 updated:

        +
          +
        • All code files are now in the LF line format, please stick to it
        • +
        • Added CI step to check for CRLF files
        • +
        • Line ending CI works now
        • +
        +

        Arkatos, Zxaber, Ghommie updated:

        +
          +
        • Certain AI abilities now dynamically show their remaining uses on the mouse hover over their respective action buttons.
        • +
        • Malfunctioning AIs can no longer abuse the confirmation popup to create extra (unstoppable) doomsdays.
        • +
        • Fixed AIs being able to use some of their abilities such as the doomsday whilst dead, and the doomsday loading phase not halting upon AI death.
        • +
        +

        Arturlang updated:

        +
          +
        • Vampires are no longer as tanky
        • +
        • Added modular computers to the loadout
        • +
        +

        Bhijn updated:

        +
          +
        • Limbs now regenerate their stamina faster while disabled
        • +
        • Limbs now have the same incoming stamina damage multiplier mechanics as spacemen, where the more staminaloss they take while disabled, the less staminaloss they'll take.
        • +
        • Limbs have had their base stamina regen rate doubled to match the doubled stamina regen rate of standard spacemen.
        • +
        • Added a preference to make the sprint hotkey be a toggle instead of a hold bind
        • +
        • Added a preference to bind the sprint hotkey to space instead of shift.
        • +
        • server_hop can no longer be used to remotely lobotomize a spaceman
        • +
        +

        Bhijn helped updated:

        +
          +
        • Fixes Dragon's Tooth Sword 50% armor penetration by making it 35%
        • +
        +

        BonniePandora updated:

        +
          +
        • Added another SDQL option. Using "UPDATE selectors SET #null=value" will now resolve value and discard the return. This is useful if you only care about the side effect of a proc.
        • +
        +

        CameronWoof updated:

        +
          +
        • Ghost Cafe patrons now spawn with chameleon kits. Dress up! Be fancy!
        • +
        • Robots can now check the crew manifest from anywhere with the "View Crew Manifest" verb.
        • +
        • Lizard tails are now viable options for humans and anthromorphs.
        • +
        +

        Commandersand updated:

        +
          +
        • fixed some clothnig sprites
        • +
        • lightning bolt,tesla,forcewall,emp spells have lower cooldown
        • +
        • fireball has a 10 second starting cooldown
        • +
        +

        DeltaFire15 updated:

        +
          +
        • Vitality matrixes now correctly succ slimes
        • +
        +

        Denton, ported by Hatterhat updated:

        +
          +
        • Most upgradeable machines now show their upgrade status when examined while standing right next to them.
        • +
        • Added examine messages to teleporter stations that hint at their multitool/wirecutter interactions.
        • +
        • Renamed teleporter stations from station to teleporter station.
        • +
        • Changed the teleporter hub accurate var to accuracy; the old name misled people into thinking that it was a boolean.
        • +
        +

        Detective-Google updated:

        +
          +
        • replaced the sprites with new ones requested.
        • +
        +

        EmeraldSundisk updated:

        +
          +
        • Adds a sign outside MetaStation's custodial closet
        • +
        +

        FantasticFwoosh, ported by Hatterhat updated:

        +
          +
        • Both reagent universal enzyme & sacks of flour are now available for their respective costs from the biogenerator.
        • +
        • New crafting recipies for donut boxes, eggboxes & candle boxes have been added to cardboard recipes for the collective benefit of service personnel and the station.
        • +
        +

        Ghommie updated:

        +
          +
        • Attached kevlar/soft/plastic padding accessories are now stealthier and will no longer be displayed on mob examine.
        • +
        • Refactored that mess of a code for alternate worn clothing sprites for digitigrade and taurs.
        • +
        • Fixed some issues with the aforementioned feature you may or may not have experienced because it was pretty lame.
        • +
        • Fixed missing digi versions fishnet sprites and wrong digitigrade left dir purple stockings sprite.
        • +
        • Add digitigrade versions for boxers and the long johns.
        • +
        • Fixed the secret sauce recipe being randomized every round.
        • +
        • Fixed singularity pulls duping rods out of engine floors.
        • +
        • Removed an old pair of zipties from the captain closet.
        • +
        • Chestbursters won't delete the host's brain somewhat anymore.
        • +
        • Fixed roundstart mushpeople being unable to MUSH PUUUUUUUUUUUUNCH!!
        • +
        • Lattices can be examined yet again.
        • +
        • Made reagent containers examine text less annoying.
        • +
        • Virus food dispensers dispense virus food again.
        • +
        • Borg hypos inputs do not display typepaths anymore.
        • +
        • Restored chem dispensers alphabetical order.
        • +
        • Sanitized cargo export messages for reagents.
        • +
        • Riot foam dart (not the ammo box) design cost is yet again consistent with the result's material amount.
        • +
        • Fixed a little exploit with ventcrawlers being capable of escaping closed turfs by printing scrubbers/vents into them.
        • +
        • deconstructing a rubber toolbox with the destructive analyzer won't "lock" the machine anymore.
        • +
        • Something about empty hand combat mode right click waving hands defying common sense and being spammy.
        • +
        • Towels are now "digitigrade-friendly".
        • +
        • The Barefoot drink and mousetraps will now work even if wearing certain "feet-less shoes".
        • +
        • Refactored code to allow all living mobs to use shields and not only humans.
        • +
        • Monkys will now retaliate against aliens attacking them (as if they even posed a threat to start with).
        • +
        • add a click cooldown to the overly spammable table slamming.
        • +
        +

        Ghommie (original PRs by Kevinz000, ShivCalez, 4dplanner, Barhandar, 81Denton, zxaber, Fox-McCloud) updated:

        +
          +
        • All atom movables now have move force and move resist, and pull force An atom can only pull another atom if its pull force is stronger than that atom's move resist
        • +
        • Mobs with a higher move force than an atom's move resist will automatically try to force the atom out of its way. This might not always work, depending on how snowflakey code is. experimental: As of right now, everything has a move force and resist of 100, and a pull force of 101. Things take (resist - force) damage when bumped into experimental: Failing to move onto a tile will now still bump up your last move timer. However, successfully pushing something out of your way will result in you automatically moving into where it was.
        • +
        • Bolted AIs can no longer be teleported by launchpads.
        • +
        • Megafauna cannot teleport
        • +
        +

        Hatterhat updated:

        +
          +
        • Beakers are generally more useful now, with slight capacity increases.
        • +
        • Transfer amounts are different now. Adjust your muscle memory to compensate.
        • +
        • ore redemption machines actually get affected by lasers again kthx
        • +
        • crusher trophy drop chance on mining mobs increased to 1 in 4 (from 1 in 20)
        • +
        • Blood-drunk buff from blood-drunk eye crusher trophy is less likely to cripple its user.
        • +
        • Forcefield projectors now fit on toolbelts.
        • +
        • New sprites for ATMOS holofan and forcefield projectors!
        • +
        • tweaks some values around with beaker transfer amounts, adds a transfer value verb (altclick)
        • +
        • Syndicate sleepers (read: the ones that're red and have controls in them) can now be recreated with a sufficient basis in nonstandard (read: illegal) technologies!
        • +
        • Explorer hoods on standard explorer suits can be reinforced with goliath hide plates again.
        • +
        • A shipment of Staff Assistant jumpsuits from the Goon-operated stations appear to have made their way into your loadout selections - and into the contraband list from ClothesMates...
        • +
        • Dropped Exo-suit armor to put it more in line with being an explorer suit sidegrade and not a straight upgrade for Lavaland usage.
        • +
        • You can now print .357 AP speedloaders from Security techfabs after you pick up the Advanced Non-Standard Ballistics node.
        • +
        • Forensic scanner removed from Advanced Biotechnology node.
        • +
        • Ash Drake armor now has goliath resistance, same as the Exo-suit.
        • +
        +

        KathrinBailey updated:

        +
          +
        • Empty engineering lockers for mappers.
        • +
        • Industrial welding tools to the engineer welding locker.
        • +
        • Removed the multitool, airlock painter, mechanical toolbox, brown sneakers, hazard vest and airlock painter from the CE's locker.
        • +
        +

        KeRSedChaplain updated:

        +
          +
        • The clockwork cuirass can now support slithering taur bodies.
        • +
        +

        Kevinz000 updated:

        +
          +
        • Fixes successful projectile hits also striking another atom on the same turf should the first one be not the target the projectile was meant for.
        • +
        • Removes infinite reflector loops.
        • +
        +

        Kraseo updated:

        +
          +
        • Jelly donuts and pink jelly donuts will now properly display sprinkled icon state.
        • +
        • Jelly donuts and its variants will properly spawn with berry juice.
        • +
        • Slime jelly donuts have slime jelly in them now. (thanks ghommie)
        • +
        • Virgo hairstyles no longer have those annoying quotation marks. Rejoice for you will no longer have to use the scrollbar.
        • +
        • Got rid of some strange-looking hairstyles. (Tbob, fingerweave, etc.)
        • +
        +

        LetterN updated:

        +
          +
        • Doppler logs
        • +
        • Shockcolar and electropack uses the new signaler ui
        • +
        • Renaming shockcolar requires a pen
        • +
        • Adds banjo
        • +
        +

        Linzolle updated:

        +
          +
        • fixes matchboxes runtiming every time they spawn
        • +
        +

        MrJWhit updated:

        +
          +
        • Increases plasma usage in radiation collectors
        • +
        +

        Naksu updated:

        +
          +
        • reagent IDs have been removed in favor using reagent typepaths where applicable
        • +
        • mechas, borg hyposprays etc no longer display internal reagent ids to the player
        • +
        +

        Owai-Seek updated:

        +
          +
        • Four New Bounties
        • +
        • tweaked several bounties
        • +
        • reorganised several bounties
        • +
        • balanced several bounties
        • +
        • added shady jims to vendor
        • +
        • Towel, Bedsheet, and Colored bedsheet bins to Dojo. Some lockers with carpets and wood, another bathroom/shower, tons of cleaning supplies, some additional trash cans, a tiny medical area, and some vendors/vendor resupplies. Also added some Ambrosia Gaia seeds.
        • +
        • Moved some lights around, extended the dojo a bit to make it feel more spacious.
        • +
        • Cafe Newsfeed Frame
        • +
        +

        PersianXerxes updated:

        +
          +
        • Reduces the range of the forcefield projector from 7 tiles to 2 tiles.
        • +
        +

        Putnam updated:

        +
          +
        • Alcohol intolerance trait, which forces vomiting on any alcohol ingestion
        • +
        • Arousal damage is gone, and with it the arousal damage heart on the UI.
        • +
        • As exhibitionist relied on arousal damage, that's gone too.
        • +
        • Bonermeter and electronic stimulation circuit modules are gone.
        • +
        • Masturbation is no longer an option in the climax menu. It was identical to climax alone in every way but text. Emote it out.
        • +
        • Arousal on genitals can now be displayed manually, on a case-by-case basis.
        • +
        • "Climax alone" and "climax with partner" now only display to the people directly involved in the interaction. rework: Catnip tea, catnip, crocin, hexacrocin, camphor, hexacamphor all had functions or bits of functions reworked.
        • +
        • "Climax with partner" now requires consent from both parties--it can no longer be used on mindless mobs, and it asks the mob getting climaxed with if they consent first.
        • +
        • A lot of MKUltra behaviors have been moved to hypno checks or removed due to reliance on maso/nympho/exhib.
        • +
        • Cold-blooded quirk
        • +
        • Two relief valves for atmospherics, available in your RPD today: a unary one that opens to air and a binary one that connects two pipenets, like a manual valve.
        • +
        • The atmos waste outlet injector on box has been replaced with an atmos waste relief valve.
        • +
        +

        Putnam3145 updated:

        +
          +
        • Dynamic storytellers, a new voting paradigm for dynamic
        • +
        • Support for approval voting and condorcet (ranked choice) voting in server votes
        • +
        • Ghost cafe mobs can now ghostize
        • +
        • Ghost cafe now has a cremator
        • +
        • Ghost cafe mobs are now eligible for ghost roles
        • +
        • Ghost roles now use an element for eligibility purposes
        • +
        • You can toggle some prefs properly now.
        • +
        • no ass slap is no longer the same thing as no aphro
        • +
        • Devastating bombs kills bomb armor'd mobs again
        • +
        • Added a sort of "game mode ban" by way of having people rank their game modes favorite to least favorite after the secret/extended vote.
        • +
        • Turns out the schulze scoring was written wrong and it was setting things to 0 that shouldn't have been, so that's fixed.
        • +
        • Random engines are now weighted.
        • +
        • Ghost dojo now has an autoylathe.
        • +
        • Ghost dojo no longer has VR or modular computer access.
        • +
        • Ghost dojo mobs are pacifists.
        • +
        • Ghost dojo booze-o-mat is now all access.
        • +
        • Ghost dojo crematorium now has a button.
        • +
        • Traitor objectives don't take a dump when they try to add an assassinate anymore
        • +
        • Objective removal with antag panel no longer commented out silently while still being an option that gives useful feedback on stuff it's not doing in any respect
        • +
        • Second, temporary flavor text!
        • +
        • Limb damage works now
        • +
        • Score instead of ranked choice for mode tiers
        • +
        • Chemistry not :b:roke
        • +
        • Ghost dojo spawns will dust if their owner suicides or uses the "ghost" verb.
        • +
        • Crafting is logged in a file now
        • +
        • temporary flavor text now pops up properly
        • +
        • demodularized player panel code, mostly
        • +
        • added ghost role eligibility delay removal to player panel
        • +
        • Metabolic synthesis disables if user isn't well-fed rather than if user is starving
        • +
        • Gibtonite no longer instantly explodes upon being pickaxe'd.
        • +
        • Cold-blooded costs -2 quirk points now
        • +
        • Added suicide to the config.
        • +
        • Ghost cafe mobs are super duper attached to the ghost cafe.
        • +
        • Meow Mix bar sign works
        • +
        • Fixed a few relief valve behaviors
        • +
        +

        Ryll/Shaps, ported by Hatterhat updated:

        +
          +
        • Point-blanking people with shotguns actually throws them backwards!
        • +
        +

        Savotta updated:

        +
          +
        • snout
        • +
        +

        Seris02 updated:

        +
          +
        • made it so trait blacklisting removes random positives instead of removing everything
        • +
        • added atmos holofirelocks and temperature blocking
        • +
        • tweaked how atmos holofan looks
        • +
        • stunglasses
        • +
        • disabler sechuds
        • +
        • adds coconut
        • +
        • adds a coconut bong
        • +
        • Auto ooc
        • +
        • changed "assume direct control" from m.ckey = src.ckey to adminmob.transfer_ckey(M) so it works with auto ooc
        • +
        • marshmallow
        • +
        • telescopic IV drip
        • +
        • cardboard box speed
        • +
        • makes gorilla shuttle emag only
        • +
        • changed where the observe verb is.
        • +
        • the way chameleon clothes update on change
        • +
        • chameleon cloak icon
        • +
        • Explosions now cause knockdown instead of KOs, with the amount of time scaling off bomb armor. Heavy explosions still cause a ~2 second KO for follow up attacks.
        • +
        • Devastating explosions now no longer gib players with more than 50 bomb armor. This used to be more or less random depending on the amount of bomb armor.
        • +
        • Removed reagent explosion code that would trigger for <1 amount reactions.
        • +
        • traitor tool for bowmanizing headsets + bowmanizing headsets
        • +
        • durathread winter coats from hyper station
        • +
        • conveyor belt now are stacks instead of single item
        • +
        • conveyor crate has 30 belts
        • +
        • printing a conveyor costs 3000 metal
        • +
        • you can press the conveyor switch in hand to link any not deployed belts to it
        • +
        • sniffing sneezing etc doing anything if they don't breathe
        • +
        • probably fixes the make mentor button
        • +
        • the sprites for the conveyor belts to look more directional
        • +
        +

        Skoglol updated:

        +
          +
        • Falsewalls now properly hide pipes and wires.
        • +
        +

        SpaceManiac, bobbahbrown, ShizCalev, SpaceManiac (ported by Ghommie) updated:

        +
          +
        • It is now possible to set a different most-base-turf per z-level.
        • +
        • Removed unlawful reference to Disney's Star Wars franchise in map logging.
        • +
        • Moved mapping related errors to their own log file.
        • +
        • Destruction on Lavaland will no longer reveal space in rare situations.
        • +
        +

        Tlaltecuhtli, Nemvar, Trilby, Hatterhat updated:

        +
          +
        • russian surplus crate, sec ammo crate, meat/veggie/fruit crate, rped crate, bomb suit crate, bio suit crate, parrot crate, chem crate, db crate
        • +
        • lowered price of some crates which are overpriced for no reason aka the tablet crate and the mech circuits crates, track implant crate has also track .38 ammo
        • +
        • sectech vendor has a refill pack
        • +
        +

        Trilbyspaceclone updated:

        +
          +
        • Fermi plushie can be made once again
        • +
        • range on Engi Tray scanners and Rad-Scanners
        • +
        • issues with mapping done my Trilby
        • +
        • Grass now makes light beer when distilled
        • +
        • allows bandoliers to hold any ammo type as long as it has a casing
        • +
        • Cleans out the last years of changlogs
        • +
        • rouge cases of #$39; in bottle/pill/patch/condiments
        • +
        • Adds missing but needed flags to MASON RIG
        • +
        • missing sprites with crushed cans
        • +
        • Halfs the nutriments in sugar
        • +
        • Glitter is now makeable with ground plastic and some crayons
        • +
        • Makes more folders and files for uplink.
        • +
        • Seed packs now have RnD points inside them
        • +
        • New tips that reflect the now use seed packs have for Rnd / Chems affect on plants
        • +
        • Made the research file look nice rather then an eye harming list
        • +
        • Fixed fragile space suits breaking from weak and non-damaging "weapons" (such as the Sord, toys and foam darts).
        • +
        • tip of the round: Cleanbot can withstand lava and burning hot ash. Its a god
        • +
        • more glassware
        • +
        • Few new packs and glassmaker kit!
        • +
        • prices/chems of crates/autobottler
        • +
        • some crates ungettable as well as some broken crates
        • +
        +

        Trilbyspaceclone, Ghommie updated:

        +
          +
        • More types of glass can now be used to make a solar panel, with different sturdiness and efficiency depending the type.
        • +
        +

        Tupinambis updated:

        +
          +
        • Replaces new fire alarms with a slightly updated version of the old ones.
        • +
        • Fixed bug where Amber alert had no proper alert lights, and red alert had amber lights.
        • +
        • RLDs now cost more to use, have reduced matter capacity, and sheets are worth less when refilling them.
        • +
        +

        Unit2E & JMoldy, ported by Hatterhat updated:

        +
          +
        • the powerfist now punches people away at high velocity depending on setting.
        • +
        • the powerfist now leaks the gas it uses onto the tile you're on.
        • +
        • Adds weak punch variations for empty and near-empty punching.
        • +
        +

        Xantholne updated:

        +
          +
        • Christmas clothes that where missing stuff should work again
        • +
        • Christmas clothes moved from clothesmate and loadout to premium autodrobe, hoodies and boots remain.
        • +
        • Botany bee pet, Bumbles
        • +
        • New bee models that aren't 1 tile big of 0 opacity pixels
        • +
        • Cheongsam and Qipao clothing added to loadout and clothesmates
        • +
        +

        dapnee updated:

        +
          +
        • new toxin's uniform and accessories
        • +
        • old toxin's uniform and accessories
        • +
        +

        deathride58 updated:

        +
          +
        • The stamina buffer no longer uses stamina while recharging.
        • +
        +

        jakeramsay007 updated:

        +
          +
        • The assorted .357 revolvers (except russian revolver) can now also load .38, like real life.
        • +
        +

        kappa-sama updated:

        +
          +
        • loot crates in cargo contraband
        • +
        • modular_citadel file movement
        • +
        • modular citadel loses some files
        • +
        • dragnet snares can now be removed in 5 seconds
        • +
        +

        keronshb updated:

        +
          +
        • Adds new features for nanites
        • +
        • fixed the missing icons from Dermal Button nanites
        • +
        • Ports the special nanite remote, mood programs, and research generating nanites
        • +
        • rebalances some nanites
        • +
        • fixed my messup
        • +
        +

        kevinz000 updated:

        +
          +
        • throwing things no longer makes them randomly turned as long as you aren't on harm intent
        • +
        • Custom holoforms have been added for pAIs and AIs. oh and cyborg holograms of specific modules too.
        • +
        • pais are no longer indestructible-flagged while in card form. pai radios now short out if they are forcefully collapsed from damage.
        • +
        • telescopic iv drips now have the proper sanity checks for deployment.
        • +
        • megafauna can hear again
        • +
        • Cargo passive gen is now 500 down from 750.
        • +
        • Added a few more nightshift config entries
        • +
        • nightshift_public_area variable in areas to determine how public an area is.
        • +
        • NIGHT_SHIFT_PUBLIC_AREAS_ONLY config entry allows the server to be configured to only nightshift areas of that level and below (so areas that are more public)
        • +
        • Config entries added for requiring authorizations to toggle nightshift. Defaults to only requiring on public areas as determined by above
        • +
        • nuclear fist buffed.
        • +
        • cogscarabs are now fulltile-hitbox.
        • +
        • emitters are now hitscan
        • +
        • monkies gorrilize easier now
        • +
        • Ghosting no longer stops abductors from using you.
        • +
        • guests can now looc
        • +
        • tableslamming has 0.4 second cooldown instead of 0.8
        • +
        • health analyzers now work
        • +
        • Mapping helpers added for power cables and atmos pipes.
        • +
        • Blood duplication is gone, but viruses now react up to 5 times, 1 time per unit, for virus mix.
        • +
        • you can now block people on your PDA
        • +
        • Grenades can now have their timers adjusted.
        • +
        • Cloning has been nerfed.
        • +
        • hilbert hotel is now less of an exploity mess
        • +
        • Doorcrushes are once again instant.
        • +
        +

        nik707 updated:

        +
          +
        • engraving light_power from 1 to 0.3
        • +
        +

        r4d6 updated:

        +
          +
        • Added a Radiation Hardsuit
        • +
        • Added a Radiation Hardsuit crate
        • +
        • Added 3 SM Engine variations.
        • +
        • Added a way to make opaque plastic flaps change: Change the already existing flap recipe to show that they are see-through
        • +
        • Animations for the RCD
        • +
        • Said animations being pulled by the Singulo
        • +
        • Prevent Reinforced Doors from being RCD'ed
        • +
        • Deconstructing Floors now cost MUs like everything else
        • +
        • changed the RCD's upgrades into flags
        • +
        • Allow RCDs to print APC, Firelocks and Fire Alarms with the right upgrade
        • +
        • Allow Engineers to print RCDs and RPDs from their protolathe without needing to hack one.
        • +
        • Added a playback device
        • +
        • Made the Voice Analyzer actually care about languages
        • +
        • fixed SM's piping
        • +
        • Added a message when pulsing the open wire.
        • +
        • fixed being able to use a playback device and a voice analyzer to activate each others
        • +
        • added passive vent to the arsenal of atmospheric devices.
        • +
        • Mining base now has a common area accessible via a new shuttle on the medium-highpop maps, and a security office connecting the gulag and the mining base. Gulag also has functional atmos.
        • +
        • Added more Cyborg Landmarks
        • +
        • better code for passive vents
        • +
        • fixed a hole in Meta
        • +
        • Added the ability to easily add variations of the mining base
        • +
        • fixed a sprite
        • +
        +

        timothyteakettle updated:

        +
          +
        • fixed not being able to remove trait genes without a disk being inserted into the dna manipulator
        • +
        +

        30 December 2019

        AnturK updated:

          @@ -371,503 +828,6 @@
        • Adds Insect markings
        • Adds three new moth wings.
        - -

        07 December 2019

        -

        AffectedArc07 updated:

        -
          -
        • Fixes a LOT of code edge cases
        • -
        -

        Anonymous updated:

        -
          -
        • Added NEET-- I mean, DAB Suit and Helmet into loadout. Exclusive to Assistants, for obvious reasons, and don't provide any armor. Goes well with balaclava, finger-less gloves and jackboots for that true tactic~~f~~ool experience.
        • -
        • Renamed loadout name appropriately (ASSU -> DAB)
        • -
        -

        Arturlang updated:

        -
          -
        • PDA catridges cant be irradiated anymore.
        • -
        -

        Bhijn updated:

        -
          -
        • Item mousedrop() now provides a return value indicating whether or not behavior has been overridden somehow.
        • -
        • Defibs now properly check that their loc is the same as the user for mousedrop() calls, meaning ghosts can no longer make you equip defibs. Plus extra sanity checks.
        • -
        • Pet carriers no longer attack turfs while trying to unload their contents.
        • -
        • Decks of cards now function as they originally intended when attempting to use their drag and drop behavior.
        • -
        • Paper bins and papercutters no longer act wonky when you're trying to pull a piece of paper from them.
        • -
        • Adds clothing drag n drop sanity checks.
        • -
        • Sythetic hats now have extra sanity checks
        • -
        -

        Coconutwarrior97 updated:

        -
          -
        • Can only wrench down two transit tubes per turf.
        • -
        -

        Commandersand updated:

        -
          -
        • Added more stuff to loadout,check uniforms mask and backpack
        • -
        -

        DeltaFire15 updated:

        -
          -
        • Adds eight new plushies
        • -
        • Adds icons for the new plushies and adds a new icon for the skylar plush
        • -
        • Deleted a old, no-longer used icon for the skylar plush
        • -
        • Fixed a typo in the trilby plush
        • -
        -

        Fermis updated:

        -
          -
        • tweaks botany reagent pHes
        • -
        • Purity, Astral, RNG, MK, SMilk, SDGF, furranium, hatmium, eigen, nanite.
        • -
        • Eigen and purity.
        • -
        • refactored sleepers!
        • -
        • Organ fridges to all maps near surgery with a random sensible organ, steralizine and synthtissue.
        • -
        • the med hand scanner to be less of a mishmash of random things
        • -
        • a little icon to the HUD if someone's heart has failed.
        • -
        • Lets neurine's brain splash attack work via syringe.
        • -
        • a new surgery; Emergency Cardioversion Induction for use on the recently deceased
        • -
        • Synthtissue to be less demanding on growth size for organ regeneration and improves clarify of it's growth gated effects.
        • -
        • Synthtissue now is more useful than synthflesh on the dead
        • -
        -

        Fox McCloud updated:

        -
          -
        • Fixes a very longstanding LINDA bug where turfs adjacent to a hotspot would be less prone to igniting
        • -
        -

        Fox McCloud, Ghommie updated:

        -
          -
        • Fixes being able to mech-punch other mobs, as a pacifist
        • -
        • Fixes being able to hurt people, as a pacifist, by throwing them into a wall or other mob, or by using most martial arts (save for the unpredictable psychotic brawl, and the stamina-damage-only boxing).
        • -
        • Buffs boxing to outdamage natural stamina regeneration. Made the chance of outright missing your opponent actually possible.
        • -
        • Pacifists can now engage in the (laughably not harmful) sweet sweet art of boxing now.
        • -
        -

        Ghommie updated:

        -
          -
        • Fixing implant cases being lost inside implant pads when trying to eject them with your active hand full.
        • -
        • Moved the implant pad's case ejection from attack_hand() to AltClick(), added examination infos about it.
        • -
        • Fixed holodeck sleepers leaving sleeper buffers behind when deleted.
        • -
        • Fixed traitor codewords highlight and some other hear signal hooks spans highlight (phobias, split personality, hypnosis) or modifiers (mind echo)
        • -
        • Fixed traitor codewords highlight not passing down with the mind datum and stickying to the first mob.
        • -
        • Fixed the incongruent bone satchel description.
        • -
        • Fixed sofa overlays doing nothing, because their layer wasn't properly set.
        • -
        • Suicide and cryo now prevents ghost/midround roles for a definite duration of 30 minutes (and more if that was done before 30 minutes in the game passed), down from the rest of the round.
        • -
        • fixed several midround roles bypassing and nulling the aforementioned prevention measures.
        • -
        • Fixed the little issue of PDA skins not updating on job equip.
        • -
        • Anomaly Crystals of the clowning type will now rename the victim to their clown name preference when triggered, instead of giving them a random clown name.
        • -
        • Lowered blob event earliest start from 1 hour to 40 minutes (ergo one third), and the required player population from 40 to 35.
        • -
        • Several fixes and QoL for dullahans. They can see and hear visible and audible messages now, don't need a space helmet they can't wear anyway to be space/temperature proof, can examine things through shiftclick, and, most of all, fixed their head being unpickable. Fixed dullahans gibbing when revived or had their limbs regenerated.
        • -
        • humans should now drop gibs when gibbed again.
        • -
        • synths (not to be confused with IPCs), android and corporate species, as well as robotic simple mobs, will now spawn robotic giblets instead of organic ones.
        • -
        • You can't wear dakimakuras in any other inappropriate slots save for the back slot anymore, degenerates.
        • -
        • Insert snarky remark about clock welders actually displaying the welder flame overlay when turned on now here.
        • -
        • Minor ninja tweaks and stealth nerfs. The stealth penalty for the many combat-related actions, bumping and now teleporting/dashing or firing guns has been increased a by a third. There is now a cooldown of 5 seconds on toggling stealth as well as a slighty slowed stealth in/out animation.
        • -
        • Ported slighty better matchbox sprites from CEV-Eris, also resprited cigar boxes myself.
        • -
        • Fixed abductors/abductees objectives by porting an objective code.
        • -
        • Riding component fix
        • -
        • fixing a few runtimes on lightgeists, libido trait, rcd, one admin transformation topic, chem dispensers, glowing robotic eyes...
        • -
        • Porting CEV-eris delivery packages sprites and dunking the old syndie cybernetics box sprite.
        • -
        • Certain objects shouldn't be able to become radioactive because of a bitflag that previously was checked nowhere in the code anymore.
        • -
        • Added a new PDA reskin, sprites from CEV-Eris
        • -
        • Clock cult starts with some spare vitality matrix charge scaled of the number of starter servants.
        • -
        • Made the vitality matrix sigil slighty more visible, also allowed conversion runes to heal fresh converts at the cost of some vitality charge.
        • -
        • Crawling won't save you from the wrath of ocular wardens and pressure sensors anymore, heretics. fix: Pressure sensors are no more triggered by floating/flying mobs.
        • -
        • Strawberry milk and tea have sprites now.
        • -
        • Fixed the Aux base camera door settings and toggle window type actions. Also enabling the user to modify both door access and type.
        • -
        • Improved the two grayscale towel item sprites a little.
        • -
        • Fixed towels onmob suit overlays. Again.
        • -
        • Fixed some reagents taste descriptions.
        • -
        • Fixed hidden random event reports only priting a paper message without sending the message to the consoles' message list.
        • -
        • Rosary beads prayer now works on non-carbon mobs too, and won't break when performed on a monkey or other humanoids.
        • -
        • You can flagellate people with rosary beads on harm intent. It's even mediocrer than the sord though.
        • -
        • Moved the `Stealth and Camouflage Items` uplink category next to `Devices and Tools`.
        • -
        • Deleted a duplicate phatom thief mask entry from the uplink.
        • -
        • Fixed missing delivery packages sprites
        • -
        • fixed a few minor issues with console frames building.
        • -
        • Wizards can use the teleport spell from their den once again.
        • -
        • Wizards will now receive feedback messages when attempting to cast teleport or use the warp whistle while in a no-teleport area.
        • -
        • New clockwork cultist, gondola, monkey and securitron cardboard cutouts.
        • -
        • Fixed aliens gasping randomly once in a while.
        • -
        • fixed superlube waterflower, my bad.
        • -
        • Fixed closing the aux base construction RCD's door access settings window throwing you out of camera mode when closed.
        • -
        • Removed not functional aux base RCD's door type menu. Use airlock painters, maybe.
        • -
        • Honkbot oil spills are of the slippery kind now. Honk.
        • -
        • local code scavenger finds forgotten slighty improved apc sprites left buried in old dusty folders.
        • -
        • Seven old and otherwordly pAI holochassis icons have crawled their way out of the modular citadel catacombs.
        • -
        • chem dispenser beakers end up in your hand yet again.
        • -
        • Bikehorns squeak yet again, the world is safe.
        • -
        • Cyborgs can now actually use cameras from a distance.
        • -
        • Suicides are yet again painful and instant and won't throw people in deep crit from full health.
        • -
        • fixed rogue pixels on the energy gu- ahem blaster carbine... and a few apc lights states being neigh-indistinguishable.
        • -
        • Fixed several "behind" layer tail sprites skipping areas normally covered by bodyparts.
        • -
        • Morgues' original alert beeping sound has been restored, they no longer go "ammunition depleted"
        • -
        • Fixed missing hypereutactic left inhand sprites.
        • -
        • Dying, ghosting, having your mind / ckey transferred to another mob, going softcrit or otherwise unconscious now properly turn off combat mode.
        • -
        • combat mode can't be toggled on while non fully conscious anymore.
        • -
        • Fixed limbs' set_disabled NOT dropping your held items, updating your hand slot inventory screen image, prompting chat messages and making your character scream like a sissy.
        • -
        • Lusty xenomoprh maids will now actually clean tiles they travel onto yet again.
        • -
        • Fixed double whitespace gap in human and AI examine. Fixed single whitespace in carbon examine.
        • -
        • Removed a few useless supply packs: "Siezed" power cells, means of production and promiscous organs.
        • -
        • Merged the synthetic blood supply pack into the standard blood supply pack, effectively removing a random type blood pack in favor of two synthetic ones.
        • -
        • Merged together premium carpet pack n°1 and n°2 to hold one of each standard pattern.
        • -
        • You can no longer estimate the amount of reagents found inside a damp rag.
        • -
        • You can now squeeze a rag's reagents into another open container, as long as the other one is not full.
        • -
        • Fixed ED-209 being unbuildable past the welding step.
        • -
        • Fixed ai displays status being reset to "Neutral" on login, regardless of choice.
        • -
        • Fixed tinfoil hats giving random traumas.
        • -
        -

        Ghommie (original PR by Denton) updated:

        -
          -
        • Added three new .38 ammo types. TRAC bullets, which embed a tracking implant inside the target's body. The implant only lasts for five minutes and doesn't work as a teleport beacon. Hot Shot bullets set targets on fire; Iceblox bullets drastically lower the target's body temperature. They are available after researching the Subdermal Implants node (TRAC) or Exotic Ammunition node (Hot Shot/Iceblox).
        • -
        • Renamed the Technological Shells research node to Exotic Ammunition.
        • -
        • The "lifespan_postmortem" var now determines how long tracking implants work after death.
        • -
        • .357 AP speedloaders can now be ordered from syndicate uplinks.
        • -
        • lowered the cost of uplink's .357 speedloaderd from 4 to 3.
        • -
        -

        Ghommie (original PR by nicbn and Menshin) updated:

        -
          -
        • You can click on things that are under flaps or holo barriers.
        • -
        -

        Ghommie (original PRs by ShizCalev, CRTXBacon and Niknakflak) updated:

        -
          -
        • Adds the intelliLantern, a big ol' spooky intelliCard skin
        • -
        • crafting recipe for the new intelliCard skin (requires 1 pumpkin, 1 intelliCard, 5 cables and a wirecutter as a tool)
        • -
        • changed the intelliTater crafting recipe to match the intelliLantern recipe (but with a potato for obvious reasons) add:cute pai gameboy face :3
        • -
        -

        Ghommie, porting lot of PRs by MrDoomBringer, AnturK, nemvar and coiax. updated:

        -
          -
        • Admins can now launch supplypods the old, slightly quicker way as well
        • -
        • Centcom-launched supplypods will now properly delimb you (if they are designated to do so) instead of touching you then literally yeeting all of your internal organs out of your body.
        • -
        • Centcom can now specify if they want to yeet all of your organs out of your body with a supplypod
        • -
        • Supplypods sound a bit nicer as the land now.
        • -
        • admins can now adjust the animation duration for centcom-launched supplypods
        • -
        • admins can adjust any sounds that are played as the supplypod lands
        • -
        • Reverse-Supplypods (the admin-launched ones) no longer stay behind after rising up, and also auto-delete from centcom.
        • -
        • The centcom podlauncher now has better logging
        • -
        • Admins can now allow ghosts to follow the delivery of Centcom-launched supply pods
        • -
        • Admins can now use the Centcom Podlauncher to launch things without the things looking like they're being sent inside a pod.
        • -
        • sparks will not generate if the quietLanding effect is on, for the centcom podlauncher
        • -
        • makes input text clearer for the centcom podlauncher
        • -
        • New 'Podspawn' verb, which functions like 'Spawn', except any atoms movable spawned will be dropped in via a no-damage, no-explosion Centcom supply pod.
        • -
        • Removed an oversight that made many obj/effect subtypes accidentally bombproof.
        • -
        -

        GrayRachnid updated:

        -
          -
        • Added saboteur syndicate engiborg
        • -
        • changed cyborg tool icons and the secborg taser/laser icons.
        • -
        • Fixes golden toolbox missing inhand sprite
        • -
        • Added traumas
        • -
        • Added science powergame tool
        • -
        • a few hearing args
        • -
        • fixed my mistakes
        • -
        • tweaked the number of ingredients/pancakes you can stack.
        • -
        -

        Hatterhat updated:

        -
          -
        • The Big Red Button now sets bomb timers to 2 seconds, instead of 5.
        • -
        • Gloves of the North Star (not Hugs of the North Star) now use all their intents very, very fast. This does not apply to grabs' click cooldown, nor shoving people.
        • -
        • The seedvault/alien plant DNA manipulator can now be printed off with Alien Biotechnology.
        • -
        -

        Iroquois-Pliskin updated:

        -
          -
        • Removed Clockwork Cult Surgical facility from Reebe
        • -
        -

        Jerry Derpington, baldest of the balds, and nemvar. updated:

        -
          -
        • Nanotrasen has lost communication to two away mission sites that contained a beach for Nanotrasen employees.
        • -
        • Nanotrasen has been able to locate a new away mission site that ALSO has a beach. Nanotrasen employees will be able to enjoy the beach after all!
        • -
        • Seashells have been added to the game.
        • -
        -

        KathrinBailey updated:

        -
          -
        • Two extra 'luxury' dorms rooms!
        • -
        • Gas miners to atmos.
        • -
        • Posters around the station.
        • -
        • Vacant room added to the Starboard Bow with it's own APC, above electrical maintenance.
        • -
        • New trendy clothes to the locker room, giving variety and bringing fashion back onto Nanotrasen stations.
        • -
        • Coloured bedsheet and towel bin.
        • -
        • Maid uniforms for the janitor.
        • -
        • Completely reworked bar. Milk kegs added in bar office. The bar has been changed for a homey restaurant feel just in time for Christmas! You can now run it as an actual restaurant! Local Bartender Icktsie III loved it so much he rolled around on the new floor smiling happily.
        • -
        • Dorms rework. Fitness room now has lots of costumes and outfits.
        • -
        • Junk removed from engineering, welding goggles added.
        • -
        • Welding tools in engineering replaced with industrial welding tools.
        • -
        • Package wrappers and hand labellers now in major departments.
        • -
        • Cell charger moved from engineering lobby to the protolathe room, just like how it is in all of the other maps and just where the cell charger is actually needed.
        • -
        • Library redesigned to have a private room and a 3x3 private study that is cleaned up.
        • -
        • Paper bins have gone big or gone home, with premium stationery scattered around. Engineering and security now have a labeller and packaging supplies.
        • -
        • Dark spot top left of Botany fixed.
        • -
        • Huge galactic-sized dark spot in bar fixed.
        • -
        • Light replacers now are less horrifically overpowered and PTSD-inducing for the server.
        • -
        • Fixes issue 9706: https://github.com/Citadel-Station-13/Citadel-Station-13/issues/9706 Part of maint getting hit by radstorms. -_Kathrin's Box Beautification:_
        • -
        • Ports TG's pews https://github.com/tgstation/tgstation/pull/42712
        • -
        • The first step of a corporate incursion of Space IKEA into Nanotrasen.
        • -
        -

        Kevinz000, Cruix, MrStonedOne, Denton, Kmc2000, Anturk, MrDoomBringer, Dennok, TheChosenEvilOne, Ghommie updated:

        -
          -
        • Added support for Multi-Z power, atmospherics and disposals
        • -
        • massive service department nerf: space can no longer be extra crispy.
        • -
        -

        Knouli updated:

        -
          -
        • attack_self proc for the legion core which triggers a self-heal al la the previous 'afterattack' proc, as if clicking on the character's own sprite to self-heal
        • -
        • admin logging for all three use cases of legion core healing - afterattack, attack_self, and implanted ui_action_click
        • -
        -

        Krysonism, Ghommie updated:

        -
          -
        • NT has made breakthroughs in ice cream science, ice creams can now be flavoured with any reagent!
        • -
        • The ice cream vat now accepts beakers.
        • -
        • Grape and Peach icecreams have scoop overlays yet again.
        • -
        -

        Linzolle updated:

        -
          -
        • butchering component update
        • -
        • hat tossing can no longer knock hats off
        • -
        • strange reagent being unable to revive simplemobs
        • -
        • jitter animation and more clear text to strange reagent revival
        • -
        -

        Mickyy5 updated:

        -
          -
        • Nanotrasen are now issuing Plasmamen with plasma in their survival boxes
        • -
        -

        MrJWhit updated:

        -
          -
        • tweaked brain damage line
        • -
        -

        Naksu, ShizCalev updated:

        -
          -
        • Refactored examine-code
        • -
        • Examining a human with a burned prosthetic limb will no longer tell you that the limb is blistered.
        • -
        • Items will now inform you if they are resistant to frost, fire, acid, and lava when examined.
        • -
        -

        Owai-Seek updated:

        -
          -
        • "silly" bounties
        • -
        • "gardenchef" bounties
        • -
        • several bounties that require seriously good RNG to pull off.
        • -
        • moved several chef and assistant bounties to silly and gardenchef
        • -
        • modified several bounty point rewards
        • -
        • added new files "silly.dm" and "gardenchef.dm"
        • -
        • 15+ new crates for cargo
        • -
        • organizes crates and moving them to proper categories
        • -
        • some dumb stuff like toner crates re
        • -
        • leg wraps and sweaters to clothesmate
        • -
        • screwdriver and cable coil to janidrobe
        • -
        • screwdriver and cable coil to janibelt whitelist (for fixing/placing light fixtures)
        • -
        • monkey cube, syringe, enzyme, soy sauce, and cryoxadone to chef's vendor (contraband and premium)
        • -
        • add cracker, beans, honey bars, lollipops, chocolate coin, and spider lollipop to snack vendors (contraband and premium)
        • -
        • newspaper to loadout menu for bapping purposes
        • -
        • removed poppy pretzels from snack vendor premium
        • -
        • maid uniform (janimaid alt) to kinkmate.
        • -
        • moves gear harness from premium to normal stock in kinkmate
        • -
        • re-balanced metal shield bounty
        • -
        • cryoxadone bottle (for use in chef vendor)
        • -
        -

        PersianXerxes updated:

        -
          -
        • Reduces the grace period for meteors from a minimum of 5 and maximum of 10 to 3 and 6 minutes respectively.
        • -
        • Adds a pair of VR sleepers to Box Station's permabrig
        • -
        • Adds a pair of VR sleepers to Delta Station's permabrig
        • -
        • Adds a pair of VR sleepers to Pubby Station's permabrig
        • -
        • Adds a pair of VR sleepers to Meta Station's permabrig
        • -
        -

        Putnam updated:

        -
          -
        • From-ghosts dynamic rulesets now actually listen to "required candidates"
        • -
        • Every dynamic-triggered event is now blacklisted from being triggered by the random events system when dynamic can trigger them.
        • -
        • Dynamic voting now features extended, if recent rounds have been chaotic.
        • -
        • Roundstart rulesets now scale on population ready rather than total population.
        • -
        • Threat log now accurately represents what actually used the threat.
        • -
        • Verbose threat log (admin-only) now shows ALL threat level changes.
        • -
        • VR mobs can no longer be dynamic midround antags.
        • -
        • Personal closets can use anything that holds an ID card now.
        • -
        -

        Putnam3145 updated:

        -
          -
        • traitors work now
        • -
        • Gas filters now push gas the same way volume pumps do.
        • -
        • Gas filters now won't clog if only one output is clogged.
        • -
        • Glowsticks can no longer be radioactively contaminated (one more supermatter contam exploit gone)
        • -
        • traitor removal is no longer borked
        • -
        • Dynamic voting
        • -
        • Added DYNAMIC_VOTING to game_options
        • -
        • SDGF now copies memories as well as antag data and factions.
        • -
        • Summon events now properly costs threat.
        • -
        • Refunded spells refund threat, too.
        • -
        • Made wizard spells inherently have a requirement and cost.
        • -
        • Meteor wave is no longer repeatable in dynamic.
        • -
        • tweaked nuke ops
        • -
        • Organs can no longer be radioactively contaminated.
        • -
        -

        Robustin, Subject217 updated:

        -
          -
        • The NukeOp Shuttle hull has been dramatically hardened. The walls are now "R-Walls" with far greater explosion resistance.
        • -
        • The NukeOp Shuttle guns have been significantly buffed. They now rapidly fire a new type of penetrator round, at a greater range, and have far greater explosion resistance.
        • -
        • The nuclear device on the NukeOp Shuttle is now in an anchored state by default, the Nuke can only be unanchored by inserting the disk and entering the proper code.
        • -
        • Non-Syndicate cyborgs are now unable to access the NukeOp Shuttle Console.
        • -
        • You can now unanchor Nukes even when the floor under them has been destroyed
        • -
        -

        Seris02 updated:

        -
          -
        • added sleeping carp hallucination
        • -
        • Centcom + Assistant's formal winter coat + loadout + narsian + ratvarian winter coats
        • -
        • GPS location on examine
        • -
        • fixed the meteor hallucination
        • -
        • tweaked the way the tapered penis looks
        • -
        • Added nine winter coats
        • -
        • added images for the winter coats
        • -
        • adds the mining winter coat to mining wardrobes and mining lockers
        • -
        -

        ShizCalev updated:

        -
          -
        • Ghosts can now see active AI cameras.
        • -
        • Fixed a couple of laser / energy guns never switching to the empty icon despite being unable to fire.
        • -
        -

        Swindly updated:

        -
          -
        • Fixed MMIs not being able to use mecha equipment
        • -
        • Fixed MMIs not getting mecha mouse pointers
        • -
        • Fixed MMIs not getting medical HUDs in Odysseuses
        • -
        • Brains can now switch to harm intent
        • -
        -

        Tetr4 updated:

        -
          -
        • Turning a tile with gas effects into space now gets rid of the effects.
        • -
        -

        Trilbyspaceclone updated:

        -
          -
        • plastic trash cart crafting with plastic
        • -
        • wallets are known for now holding more items
        • -
        • shades and clowns HP
        • -
        • six more crates, A barrel, A Loom, 40 cotton sheets, two sets of fruit crates, raw lumber crate
        • -
        • All fermi chems, Boozes, Medical, food chems now sell
        • -
        • Loads more to sell - Mech gear, Cooking and more!
        • -
        • Moved around the vaule of some things and removed elastic of most items
        • -
        • Rebreather implants will now loss vaule, Do to being just metal and glass
        • -
        • lowered how many chems are in lewd chem kegs to be around 150-100 as well as the fancy booze kegs
        • -
        • bad returns and tools used
        • -
        • 8 new cargo crates!
        • -
        • tablet cargo crate by -3k
        • -
        • Closes a bunch of issues
        • -
        • updates changlogs and such
        • -
        • fixed a catnip not having sprites
        • -
        • Boh cant hold WEIGHT_CLASS_GIGANTIC, just Bulky. Makes katana, chainsaw and base ball bat into bulky items so they may fit
        • -
        • changes header to be more cit-like
        • -
        • new clothing for the hotel staff and a hat
        • -
        -

        Ty-the-Smonk updated:

        -
          -
        • You can now interact with self sustaining crossbreeds
        • -
        -

        Useroth updated:

        -
          -
        • Colored fairygrass variants.
        • -
        • Added a missing cherrybulb seedpack sprite
        • -
        • numbered storages now are sorted in a consistent way, instead of depending on ordering of their contents var
        • -
        • strange seeds as a buyable traitor botanist item
        • -
        • resolves the issues revolving around blackpowder exploding where the reaction happened, instead of where it actually is through making it explode instantly
        • -
        • the explosion delay moved from blackpowder directly into bomb cherries, to keep them functioning as intended
        • -
        • A bunch of newer tg plants
        • -
        • A bunch of newer tg plant traits
        • -
        • A couple of newer tg plant reagents
        • -
        • the new plants now properly get their reagents and reagent genes instead of being empty with UNKNOWN reagents listed in the DNA machine
        • -
        • extradimensional oranges now contain haloperidol
        • -
        • extradimensional oranges now actually grow properly and give proper seeds.
        • -
        -

        Weblure updated:

        -
          -
        • Button added to slime console that prints out the hotkey commands to the user. [Includes DMI update]
        • -
        • Shift-click a slime to pick it up, or the floor to drop all held slimes. (Requires Basic Slime Console upgrade)
        • -
        • Ctrl-click a slime to scan it.
        • -
        • Alt-click a slime to feed it a potion. (Requires Advanced Slime Console upgrade)
        • -
        • Ctrl-click on a dead monkey to recycle it, or the floor to place a new monkey. (Requires Monkey Console upgrade)
        • -
        • If the console does not have the required upgrade, an error message will print to the user.
        • -
        • You can now pick up a single slime from a pile, instead of all of them at once.
        • -
        • When recycling monkeys, the console will now report how many monkeys it has (will not report decimal increases).
        • -
        • Console now alerts you when you're out of monkeys and reports your current decimal amount.
        • -
        • Console messages are now styled consistently.
        • -
        -

        XDTM, ShizCalev, Naksu, Skoglol, cacogen, Rohesie (ported by Ghommie) updated:

        -
          -
        • Holding an ID in your hands uses it instead of your worn ID for authentication purposes.
        • -
        • If you don't have an ID in your id slot, the belt slot will be checked as well.
        • -
        • small cleanup to id and bounty console html generation
        • -
        • Hop console now hurts your eyes less. Red button text replaced with green.
        • -
        • IDs with ID console access now go into the Confirm Identity slot by default like they used to, similarly IDs without it go into the Target slot by default again
        • -
        • Can easily swap out IDs by clicking the machine or the UI fields with another ID
        • -
        • ID console now names which IDs are added/removed in its visible messages
        • -
        • Labels the ID slot fields when logged in so you know which is which
        • -
        • Can use Job Management without an ID provided the console is logged in (matches how the console now stays logged in even without an ID)
        • -
        • Can log in without an ID in the Target field (matches how the machine now stays logged in even after the ID is removed from the Target field)
        • -
        • Cleans up UI slightly (had some duplicate/conflicting buttons)
        • -
        • Fixes ID console duping issues. Includes some ID containers, such as PDAs, tablets and wallets, into the swapping behavior when an ID card is being removed and the item is being held.
        • -
        -

        Xantholne updated:

        -
          -
        • New Berets for most heads and departments available in their autodrobes or lockers
        • -
        -

        YakumoChen updated:

        -
          -
        • New AI Holograms and Displays! Ported from /vg/station.
        • -
        -

        actioninja updated:

        -
          -
        • med records no longer can eat id cards for no reason
        • -
        • Chat is properly sent to legacy window if goonchat fails to load again.
        • -
        -

        dapnee updated:

        -
          -
        • fixed closet initialisation being broken
        • -
        • emergency closets no longer have a 1% chance to delete themselves
        • -
        • Communications console window no longer updates, won't steal focus anymore.
        • -
        • Trimline neutral end exists now.
        • -
        -

        dzahlus updated:

        -
          -
        • added a new gun sounds
        • -
        • removed an old gun sounds
        • -
        -

        him updated:

        -
          -
        • hos and aeg guns now conform to le epic taser rework standards
        • -
        -

        kappa-sama updated:

        -
          -
        • changed flavor text of alien tech on uplink
        • -
        • added TG's icons for traitor, russian, and golden revolver
        • -
        -

        kevinz000 updated:

        -
          -
        • you can now choose never for this round for magical antags
        • -
        • Cargo has passive point generation again at 750 points/minute
        • -
        • Mindshield crate price increased from 3000 to 4000
        • -
        • Miasma sell price reduced from 15/mol to 4/mol
        • -
        • bluespace wizard apprentice now has blink instead of targeted area teleportation
        • -
        • Emagged medibots now charcoal toxinlovers.
        • -
        • disablers buffed 0.7 --> 0.6 speed 24 --> 28 damage
        • -
        • kinetic crushers no longer drop if you try to use it with one hand
        • -
        • added multi_keyed_list, delimiter defaults to |.
        • -
        • Light pink extracts no longer speed you up. Instead, they give stamina regeneration and free sprinting.
        • -
        -

        kiwedespars updated:

        -
          -
        • removed moth fluff coloring you like your wings
        • -
        • made insect not so bad.
        • -
        -

        nemvar updated:

        -
          -
        • You now get a message if your PDA explodes while you are holding it.
        • -
        • The lavaland clown ruin has some new pranks ready.
        • -
        • Added a new loot item to the lavaland clown ruin.
        • -
        • Removed the slime core from said ruin.
        • -
        • The clown PDA now properly slips people on jogging move intent regardless of fatigue. Honkmother's will.
        • -
        -

        nemvar, ShizCalev, Qustinnus/Floyd, Ghommie updated:

        -
          -
        • You can now unfasten the loom.
        • -
        • it now takes 4 strands to make one piece of durathread cloth
        • -
        • Looms can now be attacked.
        • -
        • Durathread golem weaves his magic
        • -
        • Supply ordered looms are unanchored. Bring a wrench.
        • -
        -

        r4d6 updated:

        -
          -
        • Added Departements Winter Coats to the loadout list.
        • -
        GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index db9c8e6d08..464340ef24 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -23980,3 +23980,475 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. shellspeed1: - rscadd: Adds Insect markings - rscadd: Adds three new moth wings. +2020-01-27: + 4dplanner, CRITAWAKETS, XDTM, ninjanomnom: + - rscadd: sepia slime extract has a delay before activating + - balance: the user of a sepia slime extract is no longer immune to the time field + - balance: chilling sepia is now the support extract - it always freezes the user, + but not other marked people. give one to your golem! + - rscadd: burning sepia spawns the rewind camera. Take a selfie with someone and + give it to them to make sure they remember the moment forever! You don't actually + need to give them the photo, they'll remember anyway. Keep it as a reminder. + - rscadd: rewinding (deja vu) effect resets your location to the turf you were on + after 10 seconds as well as resetting limbs/mobs/objects damage to the point + it was added. + - rscadd: The deja vu effect cannot resurrect the dead, but will heal their corpse. + New limbs fall off, old ones re-attach + - rscadd: 'Regenerative sepia cores add a deja vu effect before healing instead + of a timestop remove: timefreeze camera is admin spawn only.' + - rscadd: recurring sepia recalls to the hand of the last person to touch it after + activating. Reusable timestop grenades! + - tweak: some special cameras don't prompt for customisation + - bugfix: timefreeze camera actually makes a photo + - bugfix: timestop stops pathing and mechs. + - bugfix: adds a check to make sure simple_animals don't get their AI toggled while + sentient + - bugfix: Adds the timestop overlay to frozen projectiles + - bugfix: Timestopped things have INFINITY move_resist as opposed to being anchored + - bugfix: Timestop will now unfreeze things that somehow leave it + - bugfix: mobs in the middle of a walk_to will have their walk stopped by timestop + - bugfix: mobs that are stunned will be stopped mid walk as well + - bugfix: pulling respects changes in move_force + - bugfix: swapping places respects move_force if the participant is not willing + - bugfix: timestop is properly defeated by antimagic. + - bugfix: timestop only checks antimagic once + - tweak: Time stop now applies its visual effect on floors, walls and static structures + (with no change otherwise) + - tweak: Movable structures are now anchored while time stopped. + - tweak: Timestop effects now prevent speech. + AffectedArc07: + - code_imp: All code files are now in the LF line format, please stick to it + - tweak: Added CI step to check for CRLF files + - code_imp: Line ending CI works now + Arkatos, Zxaber, Ghommie: + - rscadd: Certain AI abilities now dynamically show their remaining uses on the + mouse hover over their respective action buttons. + - bugfix: Malfunctioning AIs can no longer abuse the confirmation popup to create + extra (unstoppable) doomsdays. + - bugfix: Fixed AIs being able to use some of their abilities such as the doomsday + whilst dead, and the doomsday loading phase not halting upon AI death. + Arturlang: + - tweak: Vampires are no longer as tanky + - rscadd: Added modular computers to the loadout + Bhijn: + - rscadd: Limbs now regenerate their stamina faster while disabled + - rscadd: Limbs now have the same incoming stamina damage multiplier mechanics as + spacemen, where the more staminaloss they take while disabled, the less staminaloss + they'll take. + - balance: Limbs have had their base stamina regen rate doubled to match the doubled + stamina regen rate of standard spacemen. + - rscadd: Added a preference to make the sprint hotkey be a toggle instead of a + hold bind + - rscadd: Added a preference to bind the sprint hotkey to space instead of shift. + - bugfix: server_hop can no longer be used to remotely lobotomize a spaceman + Bhijn helped: + - bugfix: Fixes Dragon's Tooth Sword 50% armor penetration by making it 35% + BonniePandora: + - admin: 'Added another SDQL option. Using "UPDATE selectors SET #null=value" will + now resolve value and discard the return. This is useful if you only care about + the side effect of a proc.' + CameronWoof: + - rscadd: Ghost Cafe patrons now spawn with chameleon kits. Dress up! Be fancy! + - rscadd: Robots can now check the crew manifest from anywhere with the "View Crew + Manifest" verb. + - tweak: Lizard tails are now viable options for humans and anthromorphs. + Commandersand: + - bugfix: fixed some clothnig sprites + - balance: lightning bolt,tesla,forcewall,emp spells have lower cooldown + - balance: fireball has a 10 second starting cooldown + DeltaFire15: + - bugfix: Vitality matrixes now correctly succ slimes + Denton, ported by Hatterhat: + - tweak: Most upgradeable machines now show their upgrade status when examined while + standing right next to them. + - tweak: Added examine messages to teleporter stations that hint at their multitool/wirecutter + interactions. + - tweak: Renamed teleporter stations from station to teleporter station. + - code_imp: Changed the teleporter hub accurate var to accuracy; the old name misled + people into thinking that it was a boolean. + Detective-Google: + - tweak: replaced the sprites with new ones requested. + EmeraldSundisk: + - rscadd: Adds a sign outside MetaStation's custodial closet + FantasticFwoosh, ported by Hatterhat: + - rscadd: Both reagent universal enzyme & sacks of flour are now available for their + respective costs from the biogenerator. + - rscadd: New crafting recipies for donut boxes, eggboxes & candle boxes have been + added to cardboard recipes for the collective benefit of service personnel and + the station. + Ghommie: + - tweak: Attached kevlar/soft/plastic padding accessories are now stealthier and + will no longer be displayed on mob examine. + - refactor: Refactored that mess of a code for alternate worn clothing sprites for + digitigrade and taurs. + - bugfix: Fixed some issues with the aforementioned feature you may or may not have + experienced because it was pretty lame. + - bugfix: Fixed missing digi versions fishnet sprites and wrong digitigrade left + dir purple stockings sprite. + - imageadd: Add digitigrade versions for boxers and the long johns. + - bugfix: Fixed the secret sauce recipe being randomized every round. + - bugfix: Fixed singularity pulls duping rods out of engine floors. + - rscdel: Removed an old pair of zipties from the captain closet. + - bugfix: Chestbursters won't delete the host's brain somewhat anymore. + - bugfix: Fixed roundstart mushpeople being unable to MUSH PUUUUUUUUUUUUNCH!! + - bugfix: Lattices can be examined yet again. + - bugfix: Made reagent containers examine text less annoying. + - bugfix: Virus food dispensers dispense virus food again. + - bugfix: Borg hypos inputs do not display typepaths anymore. + - bugfix: Restored chem dispensers alphabetical order. + - bugfix: Sanitized cargo export messages for reagents. + - bugfix: Riot foam dart (not the ammo box) design cost is yet again consistent + with the result's material amount. + - bugfix: Fixed a little exploit with ventcrawlers being capable of escaping closed + turfs by printing scrubbers/vents into them. + - bugfix: deconstructing a rubber toolbox with the destructive analyzer won't "lock" + the machine anymore. + - bugfix: Something about empty hand combat mode right click waving hands defying + common sense and being spammy. + - imageadd: Towels are now "digitigrade-friendly". + - bugfix: The Barefoot drink and mousetraps will now work even if wearing certain + "feet-less shoes". + - rscadd: Refactored code to allow all living mobs to use shields and not only humans. + - tweak: Monkys will now retaliate against aliens attacking them (as if they even + posed a threat to start with). + - tweak: add a click cooldown to the overly spammable table slamming. + Ghommie (original PRs by Kevinz000, ShivCalez, 4dplanner, Barhandar, 81Denton, zxaber, Fox-McCloud): + - rscadd: All atom movables now have move force and move resist, and pull force + An atom can only pull another atom if its pull force is stronger than that atom's + move resist + - rscadd: 'Mobs with a higher move force than an atom''s move resist will automatically + try to force the atom out of its way. This might not always work, depending + on how snowflakey code is. experimental: As of right now, everything has a move + force and resist of 100, and a pull force of 101. Things take (resist - force) + damage when bumped into experimental: Failing to move onto a tile will now still + bump up your last move timer. However, successfully pushing something out of + your way will result in you automatically moving into where it was.' + - bugfix: Bolted AIs can no longer be teleported by launchpads. + - balance: Megafauna cannot teleport + Hatterhat: + - balance: Beakers are generally more useful now, with slight capacity increases. + - tweak: Transfer amounts are different now. Adjust your muscle memory to compensate. + - balance: ore redemption machines actually get affected by lasers again kthx + - tweak: crusher trophy drop chance on mining mobs increased to 1 in 4 (from 1 in + 20) + - bugfix: Blood-drunk buff from blood-drunk eye crusher trophy is less likely to + cripple its user. + - tweak: Forcefield projectors now fit on toolbelts. + - imageadd: New sprites for ATMOS holofan and forcefield projectors! + - tweak: tweaks some values around with beaker transfer amounts, adds a transfer + value verb (altclick) + - rscadd: 'Syndicate sleepers (read: the ones that''re red and have controls in + them) can now be recreated with a sufficient basis in nonstandard (read: illegal) + technologies!' + - bugfix: Explorer hoods on standard explorer suits can be reinforced with goliath + hide plates again. + - rscadd: A shipment of Staff Assistant jumpsuits from the Goon-operated stations + appear to have made their way into your loadout selections - and into the contraband + list from ClothesMates... + - balance: Dropped Exo-suit armor to put it more in line with being an explorer + suit sidegrade and not a straight upgrade for Lavaland usage. + - rscadd: You can now print .357 AP speedloaders from Security techfabs after you + pick up the Advanced Non-Standard Ballistics node. + - rscdel: Forensic scanner removed from Advanced Biotechnology node. + - tweak: Ash Drake armor now has goliath resistance, same as the Exo-suit. + KathrinBailey: + - rscadd: Empty engineering lockers for mappers. + - rscadd: Industrial welding tools to the engineer welding locker. + - rscdel: Removed the multitool, airlock painter, mechanical toolbox, brown sneakers, + hazard vest and airlock painter from the CE's locker. + KeRSedChaplain: + - imageadd: The clockwork cuirass can now support slithering taur bodies. + Kevinz000: + - bugfix: Fixes successful projectile hits also striking another atom on the same + turf should the first one be not the target the projectile was meant for. + - rscdel: Removes infinite reflector loops. + Kraseo: + - bugfix: Jelly donuts and pink jelly donuts will now properly display sprinkled + icon state. + - bugfix: Jelly donuts and its variants will properly spawn with berry juice. + - bugfix: Slime jelly donuts have slime jelly in them now. (thanks ghommie) + - bugfix: Virgo hairstyles no longer have those annoying quotation marks. Rejoice + for you will no longer have to use the scrollbar. + - imagedel: Got rid of some strange-looking hairstyles. (Tbob, fingerweave, etc.) + LetterN: + - rscadd: Doppler logs + - tweak: Shockcolar and electropack uses the new signaler ui + - tweak: Renaming shockcolar requires a pen + - rscadd: Adds banjo + Linzolle: + - bugfix: fixes matchboxes runtiming every time they spawn + MrJWhit: + - tweak: Increases plasma usage in radiation collectors + Naksu: + - code_imp: reagent IDs have been removed in favor using reagent typepaths where + applicable + - bugfix: mechas, borg hyposprays etc no longer display internal reagent ids to + the player + Owai-Seek: + - rscadd: Four New Bounties + - tweak: tweaked several bounties + - tweak: reorganised several bounties + - balance: balanced several bounties + - bugfix: added shady jims to vendor + - rscadd: Towel, Bedsheet, and Colored bedsheet bins to Dojo. Some lockers with + carpets and wood, another bathroom/shower, tons of cleaning supplies, some additional + trash cans, a tiny medical area, and some vendors/vendor resupplies. Also added + some Ambrosia Gaia seeds. + - tweak: Moved some lights around, extended the dojo a bit to make it feel more + spacious. + - rscdel: Cafe Newsfeed Frame + PersianXerxes: + - tweak: Reduces the range of the forcefield projector from 7 tiles to 2 tiles. + Putnam: + - rscadd: Alcohol intolerance trait, which forces vomiting on any alcohol ingestion + - rscdel: Arousal damage is gone, and with it the arousal damage heart on the UI. + - rscdel: As exhibitionist relied on arousal damage, that's gone too. + - rscdel: Bonermeter and electronic stimulation circuit modules are gone. + - rscdel: Masturbation is no longer an option in the climax menu. It was identical + to climax alone in every way but text. Emote it out. + - rscadd: Arousal on genitals can now be displayed manually, on a case-by-case basis. + - rscadd: '"Climax alone" and "climax with partner" now only display to the people + directly involved in the interaction. rework: Catnip tea, catnip, crocin, hexacrocin, + camphor, hexacamphor all had functions or bits of functions reworked.' + - tweak: '"Climax with partner" now requires consent from both parties--it can no + longer be used on mindless mobs, and it asks the mob getting climaxed with if + they consent first.' + - tweak: A lot of MKUltra behaviors have been moved to hypno checks or removed due + to reliance on maso/nympho/exhib. + - rscadd: Cold-blooded quirk + - rscadd: 'Two relief valves for atmospherics, available in your RPD today: a unary + one that opens to air and a binary one that connects two pipenets, like a manual + valve.' + - tweak: The atmos waste outlet injector on box has been replaced with an atmos + waste relief valve. + Putnam3145: + - rscadd: Dynamic storytellers, a new voting paradigm for dynamic + - rscadd: Support for approval voting and condorcet (ranked choice) voting in server + votes + - rscadd: Ghost cafe mobs can now ghostize + - rscadd: Ghost cafe now has a cremator + - rscadd: Ghost cafe mobs are now eligible for ghost roles + - refactor: Ghost roles now use an element for eligibility purposes + - bugfix: You can toggle some prefs properly now. + - bugfix: no ass slap is no longer the same thing as no aphro + - balance: Devastating bombs kills bomb armor'd mobs again + - rscadd: Added a sort of "game mode ban" by way of having people rank their game + modes favorite to least favorite after the secret/extended vote. + - bugfix: Turns out the schulze scoring was written wrong and it was setting things + to 0 that shouldn't have been, so that's fixed. + - config: Random engines are now weighted. + - rscadd: Ghost dojo now has an autoylathe. + - rscdel: Ghost dojo no longer has VR or modular computer access. + - tweak: Ghost dojo mobs are pacifists. + - tweak: Ghost dojo booze-o-mat is now all access. + - bugfix: Ghost dojo crematorium now has a button. + - bugfix: Traitor objectives don't take a dump when they try to add an assassinate + anymore + - admin: Objective removal with antag panel no longer commented out silently while + still being an option that gives useful feedback on stuff it's not doing in + any respect + - rscadd: Second, temporary flavor text! + - bugfix: Limb damage works now + - tweak: Score instead of ranked choice for mode tiers + - bugfix: Chemistry not :b:roke + - tweak: Ghost dojo spawns will dust if their owner suicides or uses the "ghost" + verb. + - admin: Crafting is logged in a file now + - bugfix: temporary flavor text now pops up properly + - code_imp: demodularized player panel code, mostly + - admin: added ghost role eligibility delay removal to player panel + - balance: Metabolic synthesis disables if user isn't well-fed rather than if user + is starving + - bugfix: Gibtonite no longer instantly explodes upon being pickaxe'd. + - balance: Cold-blooded costs -2 quirk points now + - config: Added suicide to the config. + - tweak: Ghost cafe mobs are super duper attached to the ghost cafe. + - bugfix: Meow Mix bar sign works + - bugfix: Fixed a few relief valve behaviors + Ryll/Shaps, ported by Hatterhat: + - rscadd: Point-blanking people with shotguns actually throws them backwards! + Savotta: + - rscadd: snout + - imageadd: snout + Seris02: + - tweak: made it so trait blacklisting removes random positives instead of removing + everything + - rscadd: added atmos holofirelocks and temperature blocking + - tweak: tweaked how atmos holofan looks + - rscadd: stunglasses + - rscadd: disabler sechuds + - rscadd: adds coconut + - rscadd: adds a coconut bong + - rscadd: Auto ooc + - admin: changed "assume direct control" from m.ckey = src.ckey to adminmob.transfer_ckey(M) + so it works with auto ooc + - rscadd: marshmallow + - rscadd: telescopic IV drip + - bugfix: cardboard box speed + - tweak: makes gorilla shuttle emag only + - tweak: changed where the observe verb is. + - tweak: the way chameleon clothes update on change + - bugfix: chameleon cloak icon + - balance: Explosions now cause knockdown instead of KOs, with the amount of time + scaling off bomb armor. Heavy explosions still cause a ~2 second KO for follow + up attacks. + - balance: Devastating explosions now no longer gib players with more than 50 bomb + armor. This used to be more or less random depending on the amount of bomb armor. + - code_imp: Removed reagent explosion code that would trigger for <1 amount reactions. + - rscadd: traitor tool for bowmanizing headsets + bowmanizing headsets + - rscadd: durathread winter coats from hyper station + - tweak: conveyor belt now are stacks instead of single item + - tweak: conveyor crate has 30 belts + - tweak: printing a conveyor costs 3000 metal + - rscadd: you can press the conveyor switch in hand to link any not deployed belts + to it + - tweak: sniffing sneezing etc doing anything if they don't breathe + - bugfix: probably fixes the make mentor button + - tweak: the sprites for the conveyor belts to look more directional + Skoglol: + - bugfix: Falsewalls now properly hide pipes and wires. + SpaceManiac, bobbahbrown, ShizCalev, SpaceManiac (ported by Ghommie): + - code_imp: It is now possible to set a different most-base-turf per z-level. + - spellcheck: Removed unlawful reference to Disney's Star Wars franchise in map + logging. + - tweak: Moved mapping related errors to their own log file. + - bugfix: Destruction on Lavaland will no longer reveal space in rare situations. + Tlaltecuhtli, Nemvar, Trilby, Hatterhat: + - rscadd: russian surplus crate, sec ammo crate, meat/veggie/fruit crate, rped crate, + bomb suit crate, bio suit crate, parrot crate, chem crate, db crate + - tweak: lowered price of some crates which are overpriced for no reason aka the + tablet crate and the mech circuits crates, track implant crate has also track + .38 ammo + - bugfix: sectech vendor has a refill pack + Trilbyspaceclone: + - bugfix: Fermi plushie can be made once again + - tweak: range on Engi Tray scanners and Rad-Scanners + - bugfix: issues with mapping done my Trilby + - rscadd: Grass now makes light beer when distilled + - tweak: allows bandoliers to hold any ammo type as long as it has a casing + - server: Cleans out the last years of changlogs + - bugfix: 'rouge cases of #$39; in bottle/pill/patch/condiments' + - tweak: Adds missing but needed flags to MASON RIG + - bugfix: missing sprites with crushed cans + - tweak: Halfs the nutriments in sugar + - rscadd: Glitter is now makeable with ground plastic and some crayons + - code_imp: Makes more folders and files for uplink. + - rscadd: Seed packs now have RnD points inside them + - rscadd: New tips that reflect the now use seed packs have for Rnd / Chems affect + on plants + - code_imp: Made the research file look nice rather then an eye harming list + - bugfix: Fixed fragile space suits breaking from weak and non-damaging "weapons" + (such as the Sord, toys and foam darts). + - rscadd: 'tip of the round: Cleanbot can withstand lava and burning hot ash. Its + a god' + - rscadd: more glassware + - rscadd: Few new packs and glassmaker kit! + - tweak: prices/chems of crates/autobottler + - bugfix: some crates ungettable as well as some broken crates + Trilbyspaceclone, Ghommie: + - rscadd: More types of glass can now be used to make a solar panel, with different + sturdiness and efficiency depending the type. + Tupinambis: + - tweak: Replaces new fire alarms with a slightly updated version of the old ones. + - bugfix: Fixed bug where Amber alert had no proper alert lights, and red alert + had amber lights. + - balance: RLDs now cost more to use, have reduced matter capacity, and sheets are + worth less when refilling them. + Unit2E & JMoldy, ported by Hatterhat: + - balance: the powerfist now punches people away at high velocity depending on setting. + - rscadd: the powerfist now leaks the gas it uses onto the tile you're on. + - tweak: Adds weak punch variations for empty and near-empty punching. + Xantholne: + - bugfix: Christmas clothes that where missing stuff should work again + - tweak: Christmas clothes moved from clothesmate and loadout to premium autodrobe, + hoodies and boots remain. + - rscadd: Botany bee pet, Bumbles + - rscadd: New bee models that aren't 1 tile big of 0 opacity pixels + - rscadd: Cheongsam and Qipao clothing added to loadout and clothesmates + dapnee: + - imageadd: new toxin's uniform and accessories + - imagedel: old toxin's uniform and accessories + deathride58: + - balance: The stamina buffer no longer uses stamina while recharging. + jakeramsay007: + - rscadd: The assorted .357 revolvers (except russian revolver) can now also load + .38, like real life. + kappa-sama: + - rscadd: loot crates in cargo contraband + - code_imp: modular_citadel file movement + - code_imp: modular citadel loses some files + - balance: dragnet snares can now be removed in 5 seconds + keronshb: + - rscadd: Adds new features for nanites + - bugfix: fixed the missing icons from Dermal Button nanites + - rscadd: Ports the special nanite remote, mood programs, and research generating + nanites + - balance: rebalances some nanites + - bugfix: fixed my messup + kevinz000: + - rscadd: throwing things no longer makes them randomly turned as long as you aren't + on harm intent + - rscadd: Custom holoforms have been added for pAIs and AIs. oh and cyborg holograms + of specific modules too. + - balance: pais are no longer indestructible-flagged while in card form. pai radios + now short out if they are forcefully collapsed from damage. + - bugfix: telescopic iv drips now have the proper sanity checks for deployment. + - bugfix: megafauna can hear again + - balance: Cargo passive gen is now 500 down from 750. + - config: Added a few more nightshift config entries + - rscadd: nightshift_public_area variable in areas to determine how public an area + is. + - rscadd: NIGHT_SHIFT_PUBLIC_AREAS_ONLY config entry allows the server to be configured + to only nightshift areas of that level and below (so areas that are more public) + - rscadd: Config entries added for requiring authorizations to toggle nightshift. + Defaults to only requiring on public areas as determined by above + - balance: nuclear fist buffed. + - balance: cogscarabs are now fulltile-hitbox. + - balance: emitters are now hitscan + - balance: monkies gorrilize easier now + - rscadd: Ghosting no longer stops abductors from using you. + - rscadd: guests can now looc + - tweak: tableslamming has 0.4 second cooldown instead of 0.8 + - bugfix: health analyzers now work + - code_imp: Mapping helpers added for power cables and atmos pipes. + - rscdel: Blood duplication is gone, but viruses now react up to 5 times, 1 time + per unit, for virus mix. + - rscadd: you can now block people on your PDA + - bugfix: Grenades can now have their timers adjusted. + - balance: Cloning has been nerfed. + - bugfix: hilbert hotel is now less of an exploity mess + - balance: Doorcrushes are once again instant. + nik707: + - tweak: engraving light_power from 1 to 0.3 + r4d6: + - rscadd: Added a Radiation Hardsuit + - rscadd: Added a Radiation Hardsuit crate + - rscadd: Added 3 SM Engine variations. + - rscadd: 'Added a way to make opaque plastic flaps change: Change the already existing + flap recipe to show that they are see-through' + - rscadd: Animations for the RCD + - bugfix: Said animations being pulled by the Singulo + - balance: Prevent Reinforced Doors from being RCD'ed + - bugfix: Deconstructing Floors now cost MUs like everything else + - tweak: changed the RCD's upgrades into flags + - rscadd: Allow RCDs to print APC, Firelocks and Fire Alarms with the right upgrade + - balance: Allow Engineers to print RCDs and RPDs from their protolathe without + needing to hack one. + - rscadd: Added a playback device + - bugfix: Made the Voice Analyzer actually care about languages + - bugfix: fixed SM's piping + - rscadd: Added a message when pulsing the open wire. + - bugfix: fixed being able to use a playback device and a voice analyzer to activate + each others + - rscadd: added passive vent to the arsenal of atmospheric devices. + - rscadd: Mining base now has a common area accessible via a new shuttle on the + medium-highpop maps, and a security office connecting the gulag and the mining + base. Gulag also has functional atmos. + - rscadd: Added more Cyborg Landmarks + - refactor: better code for passive vents + - bugfix: fixed a hole in Meta + - rscadd: Added the ability to easily add variations of the mining base + - bugfix: fixed a sprite + timothyteakettle: + - bugfix: fixed not being able to remove trait genes without a disk being inserted + into the dna manipulator diff --git a/html/changelogs/AutoChangeLog-pr-10112.yml b/html/changelogs/AutoChangeLog-pr-10112.yml deleted file mode 100644 index f09d8fa9ef..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10112.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - refactor: "Refactored that mess of a code for alternate worn clothing sprites for digitigrade and taurs." - - bugfix: "Fixed some issues with the aforementioned feature you may or may not have experienced because it was pretty lame." diff --git a/html/changelogs/AutoChangeLog-pr-10123.yml b/html/changelogs/AutoChangeLog-pr-10123.yml deleted file mode 100644 index 208b17b930..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10123.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - rscadd: "throwing things no longer makes them randomly turned as long as you aren't on harm intent" diff --git a/html/changelogs/AutoChangeLog-pr-10125.yml b/html/changelogs/AutoChangeLog-pr-10125.yml deleted file mode 100644 index 951b69ccb3..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10125.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Kevinz000" -delete-after: True -changes: - - bugfix: "Fixes successful projectile hits also striking another atom on the same turf should the first one be not the target the projectile was meant for." - - rscdel: "Removes infinite reflector loops." diff --git a/html/changelogs/AutoChangeLog-pr-10165.yml b/html/changelogs/AutoChangeLog-pr-10165.yml deleted file mode 100644 index be6f9dedf7..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10165.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Fixed missing digi versions fishnet sprites and wrong digitigrade left dir purple stockings sprite." - - imageadd: "Add digitigrade versions for boxers and the long johns." diff --git a/html/changelogs/AutoChangeLog-pr-10189.yml b/html/changelogs/AutoChangeLog-pr-10189.yml deleted file mode 100644 index 5889e127d2..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10189.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - rscadd: "Dynamic storytellers, a new voting paradigm for dynamic" - - rscadd: "Support for approval voting and condorcet (ranked choice) voting in server votes" diff --git a/html/changelogs/AutoChangeLog-pr-10191.yml b/html/changelogs/AutoChangeLog-pr-10191.yml deleted file mode 100644 index c1366727bd..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10191.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - rscadd: "Custom holoforms have been added for pAIs and AIs. oh and cyborg holograms of specific modules too." - - balance: "pais are no longer indestructible-flagged while in card form. pai radios now short out if they are forcefully collapsed from damage." diff --git a/html/changelogs/AutoChangeLog-pr-10224.yml b/html/changelogs/AutoChangeLog-pr-10224.yml deleted file mode 100644 index b7d07abe5c..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10224.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Seris02" -delete-after: True -changes: - - tweak: "made it so trait blacklisting removes random positives instead of removing everything" diff --git a/html/changelogs/AutoChangeLog-pr-10238.yml b/html/changelogs/AutoChangeLog-pr-10238.yml deleted file mode 100644 index dda40c86c9..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10238.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "SpaceManiac, bobbahbrown, ShizCalev, SpaceManiac (ported by Ghommie)" -delete-after: True -changes: - - code_imp: "It is now possible to set a different most-base-turf per z-level." - - spellcheck: "Removed unlawful reference to Disney's Star Wars franchise in map logging." - - tweak: "Moved mapping related errors to their own log file." - - bugfix: "Destruction on Lavaland will no longer reveal space in rare situations." diff --git a/html/changelogs/AutoChangeLog-pr-10247.yml b/html/changelogs/AutoChangeLog-pr-10247.yml deleted file mode 100644 index b78e5c415d..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10247.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Seris02" -delete-after: True -changes: - - rscadd: "added atmos holofirelocks and temperature blocking" - - tweak: "tweaked how atmos holofan looks" diff --git a/html/changelogs/AutoChangeLog-pr-10255.yml b/html/changelogs/AutoChangeLog-pr-10255.yml deleted file mode 100644 index ebaccd0af6..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10255.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Xantholne" -delete-after: True -changes: - - bugfix: "Christmas clothes that where missing stuff should work again" diff --git a/html/changelogs/AutoChangeLog-pr-10256.yml b/html/changelogs/AutoChangeLog-pr-10256.yml deleted file mode 100644 index eb14f716cc..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10256.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam" -delete-after: True -changes: - - rscadd: "Alcohol intolerance trait, which forces vomiting on any alcohol ingestion" diff --git a/html/changelogs/AutoChangeLog-pr-10270.yml b/html/changelogs/AutoChangeLog-pr-10270.yml deleted file mode 100644 index b47a249f9a..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10270.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Fixed the secret sauce recipe being randomized every round." diff --git a/html/changelogs/AutoChangeLog-pr-10278.yml b/html/changelogs/AutoChangeLog-pr-10278.yml deleted file mode 100644 index 76ada12f20..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10278.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - bugfix: "Fermi plushie can be made once again" diff --git a/html/changelogs/AutoChangeLog-pr-10285.yml b/html/changelogs/AutoChangeLog-pr-10285.yml deleted file mode 100644 index 89b0bbae43..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10285.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Fixed singularity pulls duping rods out of engine floors." diff --git a/html/changelogs/AutoChangeLog-pr-10287.yml b/html/changelogs/AutoChangeLog-pr-10287.yml deleted file mode 100644 index f59cd0bd7f..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10287.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - rscdel: "Removed an old pair of zipties from the captain closet." diff --git a/html/changelogs/AutoChangeLog-pr-10295.yml b/html/changelogs/AutoChangeLog-pr-10295.yml new file mode 100644 index 0000000000..a776275e6e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10295.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - balance: "Abductor mindsnapping (aka abductee objectives) can now be \"cured\" with brain surgery." diff --git a/html/changelogs/AutoChangeLog-pr-10301.yml b/html/changelogs/AutoChangeLog-pr-10301.yml deleted file mode 100644 index 2acac559e9..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10301.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - tweak: "range on Engi Tray scanners and Rad-Scanners" diff --git a/html/changelogs/AutoChangeLog-pr-10306.yml b/html/changelogs/AutoChangeLog-pr-10306.yml deleted file mode 100644 index 9ab82dbda0..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10306.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Arturlang" -delete-after: True -changes: - - tweak: "Vampires are no longer as tanky" diff --git a/html/changelogs/AutoChangeLog-pr-10319.yml b/html/changelogs/AutoChangeLog-pr-10319.yml deleted file mode 100644 index 88235aab8e..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10319.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Seris02" -delete-after: True -changes: - - rscadd: "adds coconut" - - rscadd: "adds a coconut bong" diff --git a/html/changelogs/AutoChangeLog-pr-10329.yml b/html/changelogs/AutoChangeLog-pr-10329.yml deleted file mode 100644 index e5d78ddf96..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10329.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Naksu" -delete-after: True -changes: - - code_imp: "reagent IDs have been removed in favor using reagent typepaths where applicable" - - bugfix: "mechas, borg hyposprays etc no longer display internal reagent ids to the player" diff --git a/html/changelogs/AutoChangeLog-pr-10330.yml b/html/changelogs/AutoChangeLog-pr-10330.yml deleted file mode 100644 index b2a46ef605..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10330.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "keronshb" -delete-after: True -changes: - - rscadd: "Adds new features for nanites" diff --git a/html/changelogs/AutoChangeLog-pr-10333.yml b/html/changelogs/AutoChangeLog-pr-10333.yml deleted file mode 100644 index b5c11a4646..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10333.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - rscadd: "Grass now makes light beer when distilled" diff --git a/html/changelogs/AutoChangeLog-pr-10337.yml b/html/changelogs/AutoChangeLog-pr-10337.yml deleted file mode 100644 index 370a8fdc04..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10337.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Seris02" -delete-after: True -changes: - - rscadd: "Auto ooc" - - admin: "changed \"assume direct control\" from m.ckey = src.ckey to adminmob.transfer_ckey(M) so it works with auto ooc" diff --git a/html/changelogs/AutoChangeLog-pr-10344.yml b/html/changelogs/AutoChangeLog-pr-10344.yml deleted file mode 100644 index e0381c6a43..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10344.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Chestbursters won't delete the host's brain somewhat anymore." diff --git a/html/changelogs/AutoChangeLog-pr-10347.yml b/html/changelogs/AutoChangeLog-pr-10347.yml deleted file mode 100644 index c0508aa279..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10347.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "deathride58" -delete-after: True -changes: - - balance: "The stamina buffer no longer uses stamina while recharging." diff --git a/html/changelogs/AutoChangeLog-pr-10349.yml b/html/changelogs/AutoChangeLog-pr-10349.yml deleted file mode 100644 index fad3179c6e..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10349.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "KathrinBailey" -delete-after: True -changes: - - rscadd: "Empty engineering lockers for mappers." - - rscadd: "Industrial welding tools to the engineer welding locker." - - rscdel: "Removed the multitool, airlock painter, mechanical toolbox, brown sneakers, hazard vest and airlock painter from the CE's locker." diff --git a/html/changelogs/AutoChangeLog-pr-10350.yml b/html/changelogs/AutoChangeLog-pr-10350.yml deleted file mode 100644 index 580f1d68cf..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10350.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - rscadd: "Ghost cafe mobs can now ghostize" - - rscadd: "Ghost cafe now has a cremator" - - rscadd: "Ghost cafe mobs are now eligible for ghost roles" - - refactor: "Ghost roles now use an element for eligibility purposes" diff --git a/html/changelogs/AutoChangeLog-pr-10352.yml b/html/changelogs/AutoChangeLog-pr-10352.yml new file mode 100644 index 0000000000..7879bc1de1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10352.yml @@ -0,0 +1,4 @@ +author: "Seris02" +delete-after: True +changes: + - tweak: "tweaked the way the SM works" diff --git a/html/changelogs/AutoChangeLog-pr-10356.yml b/html/changelogs/AutoChangeLog-pr-10356.yml deleted file mode 100644 index 1016b559ee..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10356.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Bhijn" -delete-after: True -changes: - - rscadd: "Added a preference to make the sprint hotkey be a toggle instead of a hold bind" - - rscadd: "Added a preference to bind the sprint hotkey to space instead of shift." diff --git a/html/changelogs/AutoChangeLog-pr-10357.yml b/html/changelogs/AutoChangeLog-pr-10357.yml deleted file mode 100644 index 048baa3041..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10357.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - bugfix: "You can toggle some prefs properly now." diff --git a/html/changelogs/AutoChangeLog-pr-10358.yml b/html/changelogs/AutoChangeLog-pr-10358.yml deleted file mode 100644 index a578e6e336..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10358.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - server: "Cleans out the last years of changlogs" diff --git a/html/changelogs/AutoChangeLog-pr-10361.yml b/html/changelogs/AutoChangeLog-pr-10361.yml deleted file mode 100644 index 0224bdcb49..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10361.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "CameronWoof" -delete-after: True -changes: - - rscadd: "Ghost Cafe patrons now spawn with chameleon kits. Dress up! Be fancy!" diff --git a/html/changelogs/AutoChangeLog-pr-10362.yml b/html/changelogs/AutoChangeLog-pr-10362.yml deleted file mode 100644 index f92e16302a..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10362.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - bugfix: "rouge cases of #$39; in bottle/pill/patch/condiments" diff --git a/html/changelogs/AutoChangeLog-pr-10364.yml b/html/changelogs/AutoChangeLog-pr-10364.yml deleted file mode 100644 index 8834c494ad..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10364.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - bugfix: "telescopic iv drips now have the proper sanity checks for deployment." diff --git a/html/changelogs/AutoChangeLog-pr-10365.yml b/html/changelogs/AutoChangeLog-pr-10365.yml deleted file mode 100644 index f7ba047fc7..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10365.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - bugfix: "no ass slap is no longer the same thing as no aphro" diff --git a/html/changelogs/AutoChangeLog-pr-10366.yml b/html/changelogs/AutoChangeLog-pr-10366.yml deleted file mode 100644 index ec8d234edd..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10366.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Hatterhat" -delete-after: True -changes: - - balance: "Beakers are generally more useful now, with slight capacity increases." - - tweak: "Transfer amounts are different now. Adjust your muscle memory to compensate." diff --git a/html/changelogs/AutoChangeLog-pr-10368.yml b/html/changelogs/AutoChangeLog-pr-10368.yml deleted file mode 100644 index e6486f2815..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10368.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Hatterhat" -delete-after: True -changes: - - balance: "ore redemption machines actually get affected by lasers again kthx" diff --git a/html/changelogs/AutoChangeLog-pr-10369.yml b/html/changelogs/AutoChangeLog-pr-10369.yml deleted file mode 100644 index c292d948fb..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10369.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Hatterhat" -delete-after: True -changes: - - tweak: "crusher trophy drop chance on mining mobs increased to 1 in 4 (from 1 in 20)" diff --git a/html/changelogs/AutoChangeLog-pr-10370.yml b/html/changelogs/AutoChangeLog-pr-10370.yml deleted file mode 100644 index 6674fd2e17..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10370.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Hatterhat" -delete-after: True -changes: - - bugfix: "Blood-drunk buff from blood-drunk eye crusher trophy is less likely to cripple its user." diff --git a/html/changelogs/AutoChangeLog-pr-10371.yml b/html/changelogs/AutoChangeLog-pr-10371.yml deleted file mode 100644 index e4322d70f1..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10371.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kappa-sama" -delete-after: True -changes: - - rscadd: "loot crates in cargo contraband" diff --git a/html/changelogs/AutoChangeLog-pr-10372.yml b/html/changelogs/AutoChangeLog-pr-10372.yml deleted file mode 100644 index 6bb60c3d8d..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10372.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Hatterhat" -delete-after: True -changes: - - tweak: "Forcefield projectors now fit on toolbelts." - - imageadd: "New sprites for ATMOS holofan and forcefield projectors!" diff --git a/html/changelogs/AutoChangeLog-pr-10374.yml b/html/changelogs/AutoChangeLog-pr-10374.yml deleted file mode 100644 index 376f49a4d4..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10374.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Bhijn helped" -delete-after: True -changes: - - bugfix: "Fixes Dragon's Tooth Sword 50% armor penetration by making it 35%" diff --git a/html/changelogs/AutoChangeLog-pr-10375.yml b/html/changelogs/AutoChangeLog-pr-10375.yml deleted file mode 100644 index 7d0cc2bf44..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10375.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "r4d6" -delete-after: True -changes: - - rscadd: "Added a Radiation Hardsuit" - - rscadd: "Added a Radiation Hardsuit crate" diff --git a/html/changelogs/AutoChangeLog-pr-10378.yml b/html/changelogs/AutoChangeLog-pr-10378.yml deleted file mode 100644 index c7ab7d42c1..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10378.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "EmeraldSundisk" -delete-after: True -changes: - - rscadd: "Adds a sign outside MetaStation's custodial closet" diff --git a/html/changelogs/AutoChangeLog-pr-10379.yml b/html/changelogs/AutoChangeLog-pr-10379.yml deleted file mode 100644 index 9623f815d6..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10379.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ryll/Shaps, ported by Hatterhat" -delete-after: True -changes: - - rscadd: "Point-blanking people with shotguns actually throws them backwards!" diff --git a/html/changelogs/AutoChangeLog-pr-10380.yml b/html/changelogs/AutoChangeLog-pr-10380.yml deleted file mode 100644 index 4604329137..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10380.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Unit2E & JMoldy, ported by Hatterhat" -delete-after: True -changes: - - balance: "the powerfist now punches people away at high velocity depending on setting." - - rscadd: "the powerfist now leaks the gas it uses onto the tile you're on." - - tweak: "Adds weak punch variations for empty and near-empty punching." diff --git a/html/changelogs/AutoChangeLog-pr-10383.yml b/html/changelogs/AutoChangeLog-pr-10383.yml deleted file mode 100644 index c6787bbafe..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10383.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - bugfix: "megafauna can hear again" diff --git a/html/changelogs/AutoChangeLog-pr-10384.yml b/html/changelogs/AutoChangeLog-pr-10384.yml deleted file mode 100644 index 315a62dadd..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10384.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Tlaltecuhtli, Nemvar, Trilby, Hatterhat" -delete-after: True -changes: - - rscadd: "russian surplus crate, sec ammo crate, meat/veggie/fruit crate, rped crate, bomb suit crate, bio suit crate, parrot crate, chem crate, db crate" - - tweak: "lowered price of some crates which are overpriced for no reason aka the tablet crate and the mech circuits crates, track implant crate has also track .38 ammo" - - bugfix: "sectech vendor has a refill pack" diff --git a/html/changelogs/AutoChangeLog-pr-10388.yml b/html/changelogs/AutoChangeLog-pr-10388.yml deleted file mode 100644 index fd06a5db3f..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10388.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "CameronWoof" -delete-after: True -changes: - - rscadd: "Robots can now check the crew manifest from anywhere with the \"View Crew Manifest\" verb." diff --git a/html/changelogs/AutoChangeLog-pr-10399.yml b/html/changelogs/AutoChangeLog-pr-10399.yml deleted file mode 100644 index cbdb00630c..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10399.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - balance: "Cargo passive gen is now 500 down from 750." diff --git a/html/changelogs/AutoChangeLog-pr-10401.yml b/html/changelogs/AutoChangeLog-pr-10401.yml deleted file mode 100644 index 2aa8d91244..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10401.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "r4d6" -delete-after: True -changes: - - rscadd: "Added 3 SM Engine variations." diff --git a/html/changelogs/AutoChangeLog-pr-10403.yml b/html/changelogs/AutoChangeLog-pr-10403.yml deleted file mode 100644 index 321789a546..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10403.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "r4d6" -delete-after: True -changes: - - rscadd: "Added a way to make opaque plastic flaps -change: Change the already existing flap recipe to show that they are see-through" diff --git a/html/changelogs/AutoChangeLog-pr-10404.yml b/html/changelogs/AutoChangeLog-pr-10404.yml deleted file mode 100644 index 5f88a991ff..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10404.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Xantholne" -delete-after: True -changes: - - tweak: "Christmas clothes moved from clothesmate and loadout to premium autodrobe, hoodies and boots remain." diff --git a/html/changelogs/AutoChangeLog-pr-10412.yml b/html/changelogs/AutoChangeLog-pr-10412.yml deleted file mode 100644 index b838dbb680..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10412.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Linzolle" -delete-after: True -changes: - - bugfix: "fixes matchboxes runtiming every time they spawn" diff --git a/html/changelogs/AutoChangeLog-pr-10413.yml b/html/changelogs/AutoChangeLog-pr-10413.yml deleted file mode 100644 index 6d6378675b..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10413.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "nik707" -delete-after: True -changes: - - tweak: "engraving light_power from 1 to 0.3" diff --git a/html/changelogs/AutoChangeLog-pr-10414.yml b/html/changelogs/AutoChangeLog-pr-10414.yml new file mode 100644 index 0000000000..25750a889d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10414.yml @@ -0,0 +1,4 @@ +author: "CameronWoof" +delete-after: True +changes: + - tweak: "Lighting looks better now. I can say that because the PR wouldn't be merged and you wouldn't be reading this if it wasn't true." diff --git a/html/changelogs/AutoChangeLog-pr-10416.yml b/html/changelogs/AutoChangeLog-pr-10416.yml deleted file mode 100644 index 13432b283c..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10416.yml +++ /dev/null @@ -1,10 +0,0 @@ -author: "r4d6" -delete-after: True -changes: - - rscadd: "Animations for the RCD" - - bugfix: "Said animations being pulled by the Singulo" - - balance: "Prevent Reinforced Doors from being RCD'ed" - - bugfix: "Deconstructing Floors now cost MUs like everything else" - - tweak: "changed the RCD's upgrades into flags" - - rscadd: "Allow RCDs to print APC, Firelocks and Fire Alarms with the right upgrade" - - balance: "Allow Engineers to print RCDs and RPDs from their protolathe without needing to hack one." diff --git a/html/changelogs/AutoChangeLog-pr-10417.yml b/html/changelogs/AutoChangeLog-pr-10417.yml deleted file mode 100644 index 31ac154ac9..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10417.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - config: "Added a few more nightshift config entries" - - rscadd: "nightshift_public_area variable in areas to determine how public an area is." - - rscadd: "NIGHT_SHIFT_PUBLIC_AREAS_ONLY config entry allows the server to be configured to only nightshift areas of that level and below (so areas that are more public)" - - rscadd: "Config entries added for requiring authorizations to toggle nightshift. Defaults to only requiring on public areas as determined by above" diff --git a/html/changelogs/AutoChangeLog-pr-10420.yml b/html/changelogs/AutoChangeLog-pr-10420.yml deleted file mode 100644 index b719eca84c..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10420.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "MrJWhit" -delete-after: True -changes: - - tweak: "Increases plasma usage in radiation collectors" diff --git a/html/changelogs/AutoChangeLog-pr-10427.yml b/html/changelogs/AutoChangeLog-pr-10427.yml deleted file mode 100644 index 5f4fe73988..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10427.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Hatterhat" -delete-after: True -changes: - - tweak: "tweaks some values around with beaker transfer amounts, adds a transfer value verb (altclick)" diff --git a/html/changelogs/AutoChangeLog-pr-10428.yml b/html/changelogs/AutoChangeLog-pr-10428.yml deleted file mode 100644 index 2cd635d0a2..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10428.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - balance: "Devastating bombs kills bomb armor'd mobs again" diff --git a/html/changelogs/AutoChangeLog-pr-10429.yml b/html/changelogs/AutoChangeLog-pr-10429.yml deleted file mode 100644 index cc83f8abb6..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10429.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - tweak: "Adds missing but needed flags to MASON RIG" diff --git a/html/changelogs/AutoChangeLog-pr-10430.yml b/html/changelogs/AutoChangeLog-pr-10430.yml deleted file mode 100644 index 4fd03a5b2b..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10430.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - balance: "nuclear fist buffed." diff --git a/html/changelogs/AutoChangeLog-pr-10432.yml b/html/changelogs/AutoChangeLog-pr-10432.yml deleted file mode 100644 index a0b40baa45..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10432.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - bugfix: "missing sprites with crushed cans" diff --git a/html/changelogs/AutoChangeLog-pr-10433.yml b/html/changelogs/AutoChangeLog-pr-10433.yml deleted file mode 100644 index 036e74a804..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10433.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - balance: "cogscarabs are now fulltile-hitbox." diff --git a/html/changelogs/AutoChangeLog-pr-10435.yml b/html/changelogs/AutoChangeLog-pr-10435.yml deleted file mode 100644 index 6b684a57a5..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10435.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "FantasticFwoosh, ported by Hatterhat" -delete-after: True -changes: - - rscadd: "Both reagent universal enzyme & sacks of flour are now available for their respective costs from the biogenerator." - - rscadd: "New crafting recipies for donut boxes, eggboxes & candle boxes have been added to cardboard recipes for the collective benefit of service personnel and the station." diff --git a/html/changelogs/AutoChangeLog-pr-10437.yml b/html/changelogs/AutoChangeLog-pr-10437.yml deleted file mode 100644 index ee454f47b9..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10437.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Fixed roundstart mushpeople being unable to MUSH PUUUUUUUUUUUUNCH!!" diff --git a/html/changelogs/AutoChangeLog-pr-10439.yml b/html/changelogs/AutoChangeLog-pr-10439.yml deleted file mode 100644 index 92b151b883..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10439.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LetterN" -delete-after: True -changes: - - rscadd: "Doppler logs" diff --git a/html/changelogs/AutoChangeLog-pr-10440.yml b/html/changelogs/AutoChangeLog-pr-10440.yml deleted file mode 100644 index e942f4056f..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10440.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - rscadd: "Added a sort of \"game mode ban\" by way of having people rank their game modes favorite to least favorite after the secret/extended vote." - - bugfix: "Turns out the schulze scoring was written wrong and it was setting things to 0 that shouldn't have been, so that's fixed." diff --git a/html/changelogs/AutoChangeLog-pr-10452.yml b/html/changelogs/AutoChangeLog-pr-10452.yml deleted file mode 100644 index e51b9ff752..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10452.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Lattices can be examined yet again." diff --git a/html/changelogs/AutoChangeLog-pr-10454.yml b/html/changelogs/AutoChangeLog-pr-10454.yml deleted file mode 100644 index d89603959e..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10454.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Commandersand" -delete-after: True -changes: - - bugfix: "fixed some clothnig sprites" diff --git a/html/changelogs/AutoChangeLog-pr-10456.yml b/html/changelogs/AutoChangeLog-pr-10456.yml deleted file mode 100644 index 4c94455e47..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10456.yml +++ /dev/null @@ -1,12 +0,0 @@ -author: "Putnam" -delete-after: True -changes: - - rscdel: "Arousal damage is gone, and with it the arousal damage heart on the UI." - - rscdel: "As exhibitionist relied on arousal damage, that's gone too." - - rscdel: "Bonermeter and electronic stimulation circuit modules are gone." - - rscdel: "Masturbation is no longer an option in the climax menu. It was identical to climax alone in every way but text. Emote it out." - - rscadd: "Arousal on genitals can now be displayed manually, on a case-by-case basis." - - rscadd: "\"Climax alone\" and \"climax with partner\" now only display to the people directly involved in the interaction. -rework: Catnip tea, catnip, crocin, hexacrocin, camphor, hexacamphor all had functions or bits of functions reworked." - - tweak: "\"Climax with partner\" now requires consent from both parties--it can no longer be used on mindless mobs, and it asks the mob getting climaxed with if they consent first." - - tweak: "A lot of MKUltra behaviors have been moved to hypno checks or removed due to reliance on maso/nympho/exhib." diff --git a/html/changelogs/AutoChangeLog-pr-10457.yml b/html/changelogs/AutoChangeLog-pr-10457.yml deleted file mode 100644 index 203842b0b6..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10457.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "r4d6" -delete-after: True -changes: - - rscadd: "Added a playback device" - - bugfix: "Made the Voice Analyzer actually care about languages" diff --git a/html/changelogs/AutoChangeLog-pr-10459.yml b/html/changelogs/AutoChangeLog-pr-10459.yml deleted file mode 100644 index 77de8eb193..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10459.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam" -delete-after: True -changes: - - rscadd: "Cold-blooded quirk" diff --git a/html/changelogs/AutoChangeLog-pr-10463.yml b/html/changelogs/AutoChangeLog-pr-10463.yml deleted file mode 100644 index 70e97975ce..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10463.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - config: "Random engines are now weighted." diff --git a/html/changelogs/AutoChangeLog-pr-10465.yml b/html/changelogs/AutoChangeLog-pr-10465.yml deleted file mode 100644 index 26dff901b2..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10465.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - rscadd: "Ghost dojo now has an autoylathe." - - rscdel: "Ghost dojo no longer has VR or modular computer access." - - tweak: "Ghost dojo mobs are pacifists." - - tweak: "Ghost dojo booze-o-mat is now all access." - - bugfix: "Ghost dojo crematorium now has a button." diff --git a/html/changelogs/AutoChangeLog-pr-10472.yml b/html/changelogs/AutoChangeLog-pr-10472.yml deleted file mode 100644 index 9404d70b7b..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10472.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "keronshb" -delete-after: True -changes: - - bugfix: "fixed the missing icons from Dermal Button nanites" diff --git a/html/changelogs/AutoChangeLog-pr-10473.yml b/html/changelogs/AutoChangeLog-pr-10473.yml deleted file mode 100644 index f1821a3cce..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10473.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Bhijn" -delete-after: True -changes: - - bugfix: "server_hop can no longer be used to remotely lobotomize a spaceman" diff --git a/html/changelogs/AutoChangeLog-pr-10474.yml b/html/changelogs/AutoChangeLog-pr-10474.yml deleted file mode 100644 index ae7b5b3fcb..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10474.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - bugfix: "Traitor objectives don't take a dump when they try to add an assassinate anymore" - - admin: "Objective removal with antag panel no longer commented out silently while still being an option that gives useful feedback on stuff it's not doing in any respect" diff --git a/html/changelogs/AutoChangeLog-pr-10478.yml b/html/changelogs/AutoChangeLog-pr-10478.yml deleted file mode 100644 index b174a5e8ee..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10478.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Seris02" -delete-after: True -changes: - - tweak: "makes gorilla shuttle emag only" diff --git a/html/changelogs/AutoChangeLog-pr-10480.yml b/html/changelogs/AutoChangeLog-pr-10480.yml deleted file mode 100644 index 7ecfd7057e..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10480.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - rscadd: "Second, temporary flavor text!" diff --git a/html/changelogs/AutoChangeLog-pr-10481.yml b/html/changelogs/AutoChangeLog-pr-10481.yml deleted file mode 100644 index c884a45ec9..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10481.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "dapnee" -delete-after: True -changes: - - imageadd: "new toxin's uniform and accessories" - - imagedel: "old toxin's uniform and accessories" diff --git a/html/changelogs/AutoChangeLog-pr-10482.yml b/html/changelogs/AutoChangeLog-pr-10482.yml deleted file mode 100644 index e97c8870d4..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10482.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kappa-sama" -delete-after: True -changes: - - code_imp: "modular_citadel file movement" diff --git a/html/changelogs/AutoChangeLog-pr-10483.yml b/html/changelogs/AutoChangeLog-pr-10483.yml deleted file mode 100644 index 1f016b1591..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10483.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - bugfix: "Limb damage works now" diff --git a/html/changelogs/AutoChangeLog-pr-10485.yml b/html/changelogs/AutoChangeLog-pr-10485.yml deleted file mode 100644 index 6bf082f8ba..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10485.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Detective-Google" -delete-after: True -changes: - - tweak: "replaced the sprites with new ones requested." diff --git a/html/changelogs/AutoChangeLog-pr-10486.yml b/html/changelogs/AutoChangeLog-pr-10486.yml deleted file mode 100644 index 448bbc162c..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10486.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Seris02" -delete-after: True -changes: - - tweak: "changed where the observe verb is." diff --git a/html/changelogs/AutoChangeLog-pr-10489.yml b/html/changelogs/AutoChangeLog-pr-10489.yml deleted file mode 100644 index 4e393bd4b1..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10489.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Seris02" -delete-after: True -changes: - - tweak: "the way chameleon clothes update on change" - - bugfix: "chameleon cloak icon" diff --git a/html/changelogs/AutoChangeLog-pr-10492.yml b/html/changelogs/AutoChangeLog-pr-10492.yml deleted file mode 100644 index de6ab309ab..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10492.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - rscadd: "Glitter is now makeable with ground plastic and some crayons" diff --git a/html/changelogs/AutoChangeLog-pr-10493.yml b/html/changelogs/AutoChangeLog-pr-10493.yml deleted file mode 100644 index 201eaad5b5..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10493.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - tweak: "Score instead of ranked choice for mode tiers" diff --git a/html/changelogs/AutoChangeLog-pr-10497.yml b/html/changelogs/AutoChangeLog-pr-10497.yml deleted file mode 100644 index 5acb6f8c47..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10497.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - code_imp: "Makes more folders and files for uplink." diff --git a/html/changelogs/AutoChangeLog-pr-10498.yml b/html/changelogs/AutoChangeLog-pr-10498.yml deleted file mode 100644 index 986abc77c2..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10498.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - tweak: "tableslamming has 0.4 second cooldown instead of 0.8" diff --git a/html/changelogs/AutoChangeLog-pr-10501.yml b/html/changelogs/AutoChangeLog-pr-10501.yml deleted file mode 100644 index 27e7ddbb8e..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10501.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Putnam" -delete-after: True -changes: - - rscadd: "Two relief valves for atmospherics, available in your RPD today: a unary one that opens to air and a binary one that connects two pipenets, like a manual valve." - - tweak: "The atmos waste outlet injector on box has been replaced with an atmos waste relief valve." diff --git a/html/changelogs/AutoChangeLog-pr-10504.yml b/html/changelogs/AutoChangeLog-pr-10504.yml deleted file mode 100644 index 7e35ac6e72..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10504.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Xantholne" -delete-after: True -changes: - - rscadd: "Botany bee pet, Bumbles" - - rscadd: "New bee models that aren't 1 tile big of 0 opacity pixels" diff --git a/html/changelogs/AutoChangeLog-pr-10505.yml b/html/changelogs/AutoChangeLog-pr-10505.yml deleted file mode 100644 index dd0932c50e..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10505.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "LetterN" -delete-after: True -changes: - - tweak: "Shockcolar and electropack uses the new signaler ui" - - tweak: "Renaming shockcolar requires a pen" diff --git a/html/changelogs/AutoChangeLog-pr-10507.yml b/html/changelogs/AutoChangeLog-pr-10507.yml deleted file mode 100644 index 70d82d9cf6..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10507.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LetterN" -delete-after: True -changes: - - rscadd: "Adds banjo" diff --git a/html/changelogs/AutoChangeLog-pr-10509.yml b/html/changelogs/AutoChangeLog-pr-10509.yml deleted file mode 100644 index 4e1ede0631..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10509.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Made reagent containers examine text less annoying." diff --git a/html/changelogs/AutoChangeLog-pr-10511.yml b/html/changelogs/AutoChangeLog-pr-10511.yml deleted file mode 100644 index 5f3bf739cb..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10511.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - bugfix: "health analyzers now work" diff --git a/html/changelogs/AutoChangeLog-pr-10513.yml b/html/changelogs/AutoChangeLog-pr-10513.yml deleted file mode 100644 index 6428c4e281..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10513.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "r4d6" -delete-after: True -changes: - - rscadd: "Added a message when pulsing the open wire." diff --git a/html/changelogs/AutoChangeLog-pr-10516.yml b/html/changelogs/AutoChangeLog-pr-10516.yml deleted file mode 100644 index 39dd05a4db..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10516.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "BonniePandora" -delete-after: True -changes: - - admin: "Added another SDQL option. Using \"UPDATE selectors SET #null=value\" will now resolve value and discard the return. This is useful if you only care about the side effect of a proc." diff --git a/html/changelogs/AutoChangeLog-pr-10518.yml b/html/changelogs/AutoChangeLog-pr-10518.yml deleted file mode 100644 index 29de186e50..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10518.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Seris02" -delete-after: True -changes: - - balance: "Explosions now cause knockdown instead of KOs, with the amount of time scaling off bomb armor. Heavy explosions still cause a ~2 second KO for follow up attacks." - - balance: "Devastating explosions now no longer gib players with more than 50 bomb armor. This used to be more or less random depending on the amount of bomb armor." - - code_imp: "Removed reagent explosion code that would trigger for <1 amount reactions." diff --git a/html/changelogs/AutoChangeLog-pr-10522.yml b/html/changelogs/AutoChangeLog-pr-10522.yml deleted file mode 100644 index b03b990762..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10522.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Hatterhat" -delete-after: True -changes: - - rscadd: "Syndicate sleepers (read: the ones that're red and have controls in them) can now be recreated with a sufficient basis in nonstandard (read: illegal) technologies!" diff --git a/html/changelogs/AutoChangeLog-pr-10523.yml b/html/changelogs/AutoChangeLog-pr-10523.yml deleted file mode 100644 index 999fc1dd92..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10523.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Hatterhat" -delete-after: True -changes: - - bugfix: "Explorer hoods on standard explorer suits can be reinforced with goliath hide plates again." diff --git a/html/changelogs/AutoChangeLog-pr-10530.yml b/html/changelogs/AutoChangeLog-pr-10530.yml deleted file mode 100644 index 16cc66adb9..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10530.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kappa-sama" -delete-after: True -changes: - - code_imp: "modular citadel loses some files" diff --git a/html/changelogs/AutoChangeLog-pr-10531.yml b/html/changelogs/AutoChangeLog-pr-10531.yml deleted file mode 100644 index 6c1125a687..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10531.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - rscadd: "Seed packs now have RnD points inside them" - - rscadd: "New tips that reflect the now use seed packs have for Rnd / Chems affect on plants" - - code_imp: "Made the research file look nice rather then an eye harming list" diff --git a/html/changelogs/AutoChangeLog-pr-10532.yml b/html/changelogs/AutoChangeLog-pr-10532.yml deleted file mode 100644 index cf742b47f7..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10532.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Virus food dispensers dispense virus food again." - - bugfix: "Borg hypos inputs do not display typepaths anymore." - - bugfix: "Restored chem dispensers alphabetical order." diff --git a/html/changelogs/AutoChangeLog-pr-10535.yml b/html/changelogs/AutoChangeLog-pr-10535.yml deleted file mode 100644 index db37120317..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10535.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Hatterhat" -delete-after: True -changes: - - rscadd: "A shipment of Staff Assistant jumpsuits from the Goon-operated stations appear to have made their way into your loadout selections - and into the contraband list from ClothesMates..." diff --git a/html/changelogs/AutoChangeLog-pr-10539.yml b/html/changelogs/AutoChangeLog-pr-10539.yml deleted file mode 100644 index 66a03ee573..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10539.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Savotta" -delete-after: True -changes: - - rscadd: "snout" - - imageadd: "snout" diff --git a/html/changelogs/AutoChangeLog-pr-10544.yml b/html/changelogs/AutoChangeLog-pr-10544.yml deleted file mode 100644 index a27ffad716..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10544.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "AffectedArc07" -delete-after: True -changes: - - code_imp: "All code files are now in the LF line format, please stick to it" diff --git a/html/changelogs/AutoChangeLog-pr-10546.yml b/html/changelogs/AutoChangeLog-pr-10546.yml deleted file mode 100644 index a49c2027e5..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10546.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "r4d6" -delete-after: True -changes: - - bugfix: "fixed being able to use a playback device and a voice analyzer to activate each others" diff --git a/html/changelogs/AutoChangeLog-pr-10549.yml b/html/changelogs/AutoChangeLog-pr-10549.yml deleted file mode 100644 index 11a770945d..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10549.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Seris02" -delete-after: True -changes: - - rscadd: "durathread winter coats from hyper station" diff --git a/html/changelogs/AutoChangeLog-pr-10552.yml b/html/changelogs/AutoChangeLog-pr-10552.yml deleted file mode 100644 index 846667ea2a..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10552.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Tupinambis" -delete-after: True -changes: - - tweak: "Replaces new fire alarms with a slightly updated version of the old ones." - - bugfix: "Fixed bug where Amber alert had no proper alert lights, and red alert had amber lights." diff --git a/html/changelogs/AutoChangeLog-pr-10556.yml b/html/changelogs/AutoChangeLog-pr-10556.yml deleted file mode 100644 index af42a9eee6..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10556.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "AffectedArc07" -delete-after: True -changes: - - tweak: "Added CI step to check for CRLF files" diff --git a/html/changelogs/AutoChangeLog-pr-10557.yml b/html/changelogs/AutoChangeLog-pr-10557.yml deleted file mode 100644 index f5b37f6cee..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10557.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothyteakettle" -delete-after: True -changes: - - bugfix: "fixed not being able to remove trait genes without a disk being inserted into the dna manipulator" diff --git a/html/changelogs/AutoChangeLog-pr-10558.yml b/html/changelogs/AutoChangeLog-pr-10558.yml deleted file mode 100644 index 09186767f3..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10558.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "DeltaFire15" -delete-after: True -changes: - - bugfix: "Vitality matrixes now correctly succ slimes" diff --git a/html/changelogs/AutoChangeLog-pr-10309.yml b/html/changelogs/AutoChangeLog-pr-10559.yml similarity index 54% rename from html/changelogs/AutoChangeLog-pr-10309.yml rename to html/changelogs/AutoChangeLog-pr-10559.yml index a59ebff156..a48fc6c289 100644 --- a/html/changelogs/AutoChangeLog-pr-10309.yml +++ b/html/changelogs/AutoChangeLog-pr-10559.yml @@ -1,4 +1,4 @@ author: "Seris02" delete-after: True changes: - - rscadd: "disabler sechuds" + - rscadd: "custom reagent pie smite" diff --git a/html/changelogs/AutoChangeLog-pr-10563.yml b/html/changelogs/AutoChangeLog-pr-10563.yml deleted file mode 100644 index 5efc4cfdb1..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10563.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Trilbyspaceclone" -delete-after: True -changes: - - bugfix: "Fixed fragile space suits breaking from weak and non-damaging \"weapons\" (such as the Sord, toys and foam darts)." diff --git a/html/changelogs/AutoChangeLog-pr-10567.yml b/html/changelogs/AutoChangeLog-pr-10567.yml deleted file mode 100644 index 9d73d1d947..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10567.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Sanitized cargo export messages for reagents." diff --git a/html/changelogs/AutoChangeLog-pr-10568.yml b/html/changelogs/AutoChangeLog-pr-10568.yml deleted file mode 100644 index 6916f1289f..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10568.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "r4d6" -delete-after: True -changes: - - rscadd: "added passive vent to the arsenal of atmospheric devices." diff --git a/html/changelogs/AutoChangeLog-pr-10569.yml b/html/changelogs/AutoChangeLog-pr-10569.yml deleted file mode 100644 index 0b9cb0b992..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10569.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "keronshb" -delete-after: True -changes: - - rscadd: "Ports the special nanite remote, mood programs, and research generating nanites" - - balance: "rebalances some nanites" diff --git a/html/changelogs/AutoChangeLog-pr-10570.yml b/html/changelogs/AutoChangeLog-pr-10570.yml deleted file mode 100644 index 9eaf2168a8..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10570.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - code_imp: "Mapping helpers added for power cables and atmos pipes." diff --git a/html/changelogs/AutoChangeLog-pr-10571.yml b/html/changelogs/AutoChangeLog-pr-10571.yml deleted file mode 100644 index 1d6844aa53..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10571.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "Riot foam dart (not the ammo box) design cost is yet again consistent with the result's material amount." diff --git a/html/changelogs/AutoChangeLog-pr-10575.yml b/html/changelogs/AutoChangeLog-pr-10575.yml new file mode 100644 index 0000000000..c81ed76026 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10575.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - rscadd: "Replaces a lot of ingame UIs with TGUI next, increasing performance drastically." diff --git a/html/changelogs/AutoChangeLog-pr-10578.yml b/html/changelogs/AutoChangeLog-pr-10578.yml deleted file mode 100644 index a84fa5ba21..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10578.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "r4d6" -delete-after: True -changes: - - rscadd: "Mining base now has a common area accessible via a new shuttle on the medium-highpop maps, and a security office connecting the gulag and the mining base. Gulag also has functional atmos." diff --git a/html/changelogs/AutoChangeLog-pr-10579.yml b/html/changelogs/AutoChangeLog-pr-10579.yml deleted file mode 100644 index c428c0109d..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10579.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "r4d6" -delete-after: True -changes: - - rscadd: "Added more Cyborg Landmarks" diff --git a/html/changelogs/AutoChangeLog-pr-10580.yml b/html/changelogs/AutoChangeLog-pr-10580.yml deleted file mode 100644 index 6cb625d7af..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10580.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - admin: "Crafting is logged in a file now" diff --git a/html/changelogs/AutoChangeLog-pr-10582.yml b/html/changelogs/AutoChangeLog-pr-10582.yml deleted file mode 100644 index 2024088fb8..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10582.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - bugfix: "temporary flavor text now pops up properly" diff --git a/html/changelogs/AutoChangeLog-pr-10584.yml b/html/changelogs/AutoChangeLog-pr-10584.yml deleted file mode 100644 index e2c9f93ac8..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10584.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "AffectedArc07" -delete-after: True -changes: - - code_imp: "Line ending CI works now" diff --git a/html/changelogs/AutoChangeLog-pr-10586.yml b/html/changelogs/AutoChangeLog-pr-10586.yml deleted file mode 100644 index eb90213398..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10586.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Tupinambis" -delete-after: True -changes: - - balance: "RLDs now cost more to use, have reduced matter capacity, and sheets are worth less when refilling them." diff --git a/html/changelogs/AutoChangeLog-pr-10590.yml b/html/changelogs/AutoChangeLog-pr-10590.yml new file mode 100644 index 0000000000..e59c8decf0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10590.yml @@ -0,0 +1,11 @@ +author: "KathrinBailey" +delete-after: True +changes: + - bugfix: "Missing turf_decals in Cargo Office." + - bugfix: "Turns on the docking beacons on Box." + - bugfix: "Fixes Starboard Quarter maint room being spaced. It was never intended to be like how it was." + - bugfix: "The aforementioned maint room not having stuff in it." + - bugfix: "varedited photocopier sometimes not opening any UI." + - bugfix: "Atmos differences in Starboard Quarter maint." + - bugfix: "Atmos differences in destroyed shuttle/EVA bridge. Plating replaced with airless plating." + - bugfix: "Rotates AI satellite computers. These have probably been like this since computers had the old sprites and no directional ones. You shouldn't sit at a chair to operate a sideways computer." diff --git a/html/changelogs/AutoChangeLog-pr-10591.yml b/html/changelogs/AutoChangeLog-pr-10591.yml deleted file mode 100644 index ac8504ec9c..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10591.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "kevinz000" -delete-after: True -changes: - - rscdel: "Blood duplication is gone, but viruses now react up to 5 times, 1 time per unit, for virus mix." diff --git a/html/changelogs/AutoChangeLog-pr-10599.yml b/html/changelogs/AutoChangeLog-pr-10599.yml deleted file mode 100644 index 33435979c7..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10599.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Putnam3145" -delete-after: True -changes: - - bugfix: "Gibtonite no longer instantly explodes upon being pickaxe'd." diff --git a/html/changelogs/AutoChangeLog-pr-10600.yml b/html/changelogs/AutoChangeLog-pr-10600.yml deleted file mode 100644 index ab0c5ac964..0000000000 --- a/html/changelogs/AutoChangeLog-pr-10600.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Kraseo" -delete-after: True -changes: - - bugfix: "Jelly donuts and pink jelly donuts will now properly display sprinkled icon state." - - bugfix: "Jelly donuts and its variants will properly spawn with berry juice." - - bugfix: "Slime jelly donuts have slime jelly in them now. (thanks ghommie)" diff --git a/html/changelogs/AutoChangeLog-pr-10644.yml b/html/changelogs/AutoChangeLog-pr-10644.yml new file mode 100644 index 0000000000..b7544495d7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10644.yml @@ -0,0 +1,4 @@ +author: "ShadeAware" +delete-after: True +changes: + - rscadd: "Craftable Switchblades, a weaker subtype of normal switchblades that can be crafted using a Kitchen Knife, Modular Receiver, Rifle Stock and some Cable Coil. Requires a welder to complete." diff --git a/html/changelogs/AutoChangeLog-pr-10705.yml b/html/changelogs/AutoChangeLog-pr-10705.yml new file mode 100644 index 0000000000..f1f025d616 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10705.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - refactor: "A good amount of the blood RGB rework was cleaned up/reverted, with some notable gameplay changes including: Gibs and blood not having max blood by default (no more easy rampages, cultists), infinite gib streaking, etc etc." diff --git a/html/changelogs/AutoChangeLog-pr-10706.yml b/html/changelogs/AutoChangeLog-pr-10706.yml new file mode 100644 index 0000000000..8bf1cd449c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10706.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Stopped the ellipsis question mark from being displayed twice in the examine message for masked/unknown human mobs." + - tweak: "Made the aforementioned ellipsis question mark display on flavor-text-less masked/unknown human mobs too for consistency." diff --git a/html/changelogs/AutoChangeLog-pr-10709.yml b/html/changelogs/AutoChangeLog-pr-10709.yml new file mode 100644 index 0000000000..8c9d74c5f1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10709.yml @@ -0,0 +1,4 @@ +author: "Seris02" +delete-after: True +changes: + - rscadd: "recipe for mammal mutation toxin" diff --git a/html/changelogs/AutoChangeLog-pr-10728.yml b/html/changelogs/AutoChangeLog-pr-10728.yml new file mode 100644 index 0000000000..9023844565 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10728.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - balance: "meteor waves are now directional and announces the direction on the command report." diff --git a/html/changelogs/AutoChangeLog-pr-10731.yml b/html/changelogs/AutoChangeLog-pr-10731.yml new file mode 100644 index 0000000000..0da6f3c483 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10731.yml @@ -0,0 +1,10 @@ +author: "necromanceranne" +delete-after: True +changes: + - rscadd: "Ebows now disarm people hit by them." + - rscadd: "Ebows now do 60 stamina damage on hit." + - rscdel: "Ebows no longer inflict drowsiness" + - balance: "Miniature ebows do 15 toxin damage, up from 8." + - balance: "Ebows have considerably shorter knockdowns." + - balance: "Ebows now make you slur rather than stutter." + - balance: "Large ebows are now heavy and bulky." diff --git a/html/changelogs/AutoChangeLog-pr-10733.yml b/html/changelogs/AutoChangeLog-pr-10733.yml new file mode 100644 index 0000000000..33e2ee216c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10733.yml @@ -0,0 +1,4 @@ +author: "Hatterhat" +delete-after: True +changes: + - balance: "Zombie powder is now instant when ingested, but delayed when injected or applied through touch." diff --git a/html/changelogs/AutoChangeLog-pr-10737.yml b/html/changelogs/AutoChangeLog-pr-10737.yml new file mode 100644 index 0000000000..fa4023c148 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10737.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Stopped an APTFT exploit with spray bottles." diff --git a/html/changelogs/AutoChangeLog-pr-10742.yml b/html/changelogs/AutoChangeLog-pr-10742.yml new file mode 100644 index 0000000000..ece862d112 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10742.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed the detective revolver being quite risky to use." diff --git a/html/changelogs/AutoChangeLog-pr-10743.yml b/html/changelogs/AutoChangeLog-pr-10743.yml new file mode 100644 index 0000000000..d9775f7bc3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10743.yml @@ -0,0 +1,4 @@ +author: "necromanceranne" +delete-after: True +changes: + - rscdel: "You can no longer order spinfusors or their ammo from cargo." diff --git a/html/changelogs/AutoChangeLog-pr-10503.yml b/html/changelogs/AutoChangeLog-pr-10744.yml similarity index 57% rename from html/changelogs/AutoChangeLog-pr-10503.yml rename to html/changelogs/AutoChangeLog-pr-10744.yml index b067aa6c55..168619226a 100644 --- a/html/changelogs/AutoChangeLog-pr-10503.yml +++ b/html/changelogs/AutoChangeLog-pr-10744.yml @@ -1,4 +1,4 @@ author: "r4d6" delete-after: True changes: - - bugfix: "fixed SM's piping" + - rscadd: "Added more engines" diff --git a/html/changelogs/AutoChangeLog-pr-10495.yml b/html/changelogs/AutoChangeLog-pr-10746.yml similarity index 59% rename from html/changelogs/AutoChangeLog-pr-10495.yml rename to html/changelogs/AutoChangeLog-pr-10746.yml index 02ffedf5fc..232c7a26b9 100644 --- a/html/changelogs/AutoChangeLog-pr-10495.yml +++ b/html/changelogs/AutoChangeLog-pr-10746.yml @@ -1,4 +1,4 @@ author: "kevinz000" delete-after: True changes: - - rscadd: "guests can now looc" + - rscadd: "CTF CLAYMORES" diff --git a/html/changelogs/AutoChangeLog-pr-10317.yml b/html/changelogs/AutoChangeLog-pr-10748.yml similarity index 52% rename from html/changelogs/AutoChangeLog-pr-10317.yml rename to html/changelogs/AutoChangeLog-pr-10748.yml index 7db50240e3..a2afda81aa 100644 --- a/html/changelogs/AutoChangeLog-pr-10317.yml +++ b/html/changelogs/AutoChangeLog-pr-10748.yml @@ -1,4 +1,4 @@ author: "Trilbyspaceclone" delete-after: True changes: - - bugfix: "issues with mapping done my Trilby" + - bugfix: "Vault hallway door being all access" diff --git a/html/changelogs/AutoChangeLog-pr-10749.yml b/html/changelogs/AutoChangeLog-pr-10749.yml new file mode 100644 index 0000000000..a3ed5989d1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10749.yml @@ -0,0 +1,4 @@ +author: "AnturK ported by kevinz000" +delete-after: True +changes: + - rscadd: "Dueling pistols have been added." diff --git a/html/changelogs/AutoChangeLog-pr-10751.yml b/html/changelogs/AutoChangeLog-pr-10751.yml new file mode 100644 index 0000000000..c5b54bd4ed --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10751.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - balance: "traitor+bro gamemode minimum population set to 25 until there can be more in depth configuration systems for gamemodes." diff --git a/html/changelogs/AutoChangeLog-pr-10752.yml b/html/changelogs/AutoChangeLog-pr-10752.yml new file mode 100644 index 0000000000..9bb50f1da1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10752.yml @@ -0,0 +1,9 @@ +author: "Owai-Seek" +delete-after: True +changes: + - rscadd: "Burger, Cargo Packaging, Dirty Magazine, Air Pump, and Scrubber crates." + - rscdel: "Duplicate Crate, Festive Wrapping Paper Crate, Contraband Monkey Meat Crate" + - tweak: "Gave Seed Crate Ambrosia Seed, gave Biker Gang Crate Spraypaint." + - tweak: "Organised some crates with sub-categories. Also, moved all vendor refills to a new tab." + - tweak: "Moved Grill to Service Tab" + - bugfix: "Engineering Hardsuit Access" diff --git a/html/changelogs/AutoChangeLog-pr-10442.yml b/html/changelogs/AutoChangeLog-pr-10753.yml similarity index 56% rename from html/changelogs/AutoChangeLog-pr-10442.yml rename to html/changelogs/AutoChangeLog-pr-10753.yml index f407ae9e15..c1b3615c3d 100644 --- a/html/changelogs/AutoChangeLog-pr-10442.yml +++ b/html/changelogs/AutoChangeLog-pr-10753.yml @@ -1,4 +1,4 @@ author: "Trilbyspaceclone" delete-after: True changes: - - tweak: "Halfs the nutriments in sugar" + - server: "Updates change logs" diff --git a/html/changelogs/AutoChangeLog-pr-10754.yml b/html/changelogs/AutoChangeLog-pr-10754.yml new file mode 100644 index 0000000000..0537347443 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10754.yml @@ -0,0 +1,5 @@ +author: "MalricB" +delete-after: True +changes: + - rscadd: "\"Shaggy\" sprite from virgo" + - rscadd: "\"shaggy\" option in the character customization" diff --git a/html/changelogs/AutoChangeLog-pr-10761.yml b/html/changelogs/AutoChangeLog-pr-10761.yml new file mode 100644 index 0000000000..5a5b7281ef --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10761.yml @@ -0,0 +1,4 @@ +author: "Putnam3145" +delete-after: True +changes: + - bugfix: "gender change potion now respects prefs" diff --git a/html/changelogs/AutoChangeLog-pr-10764.yml b/html/changelogs/AutoChangeLog-pr-10764.yml new file mode 100644 index 0000000000..25dfebd5fb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10764.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Spacemen no longer run at lightspeed on local servers." diff --git a/html/changelogs/AutoChangeLog-pr-10765.yml b/html/changelogs/AutoChangeLog-pr-10765.yml new file mode 100644 index 0000000000..975a3ac5c5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10765.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - bugfix: "no more bluespace skittish locker diving," diff --git a/html/changelogs/AutoChangeLog-pr-10768.yml b/html/changelogs/AutoChangeLog-pr-10768.yml new file mode 100644 index 0000000000..0a07505b5b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10768.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - rscadd: "moths now have unique laughs and can *chitter." diff --git a/html/changelogs/AutoChangeLog-pr-10538.yml b/html/changelogs/AutoChangeLog-pr-10773.yml similarity index 56% rename from html/changelogs/AutoChangeLog-pr-10538.yml rename to html/changelogs/AutoChangeLog-pr-10773.yml index 01119f886f..64ab5ce124 100644 --- a/html/changelogs/AutoChangeLog-pr-10538.yml +++ b/html/changelogs/AutoChangeLog-pr-10773.yml @@ -1,4 +1,4 @@ author: "Putnam3145" delete-after: True changes: - - bugfix: "Chemistry not :b:roke" + - bugfix: "Hypno prefs work better." diff --git a/html/changelogs/AutoChangeLog-pr-10776.yml b/html/changelogs/AutoChangeLog-pr-10776.yml new file mode 100644 index 0000000000..cd95cb49d4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10776.yml @@ -0,0 +1,4 @@ +author: "Hatterhat" +delete-after: True +changes: + - tweak: "The H.E.C.K. suit is now goliath tentacle resistant and probably better for acid resistance." diff --git a/html/changelogs/AutoChangeLog-pr-10777.yml b/html/changelogs/AutoChangeLog-pr-10777.yml new file mode 100644 index 0000000000..76ce4000d8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10777.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - balance: "Gangs can now only tag with a gang uplink bought spraycan." diff --git a/html/changelogs/AutoChangeLog-pr-10781.yml b/html/changelogs/AutoChangeLog-pr-10781.yml new file mode 100644 index 0000000000..cd3474adca --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10781.yml @@ -0,0 +1,5 @@ +author: "r4d6" +delete-after: True +changes: + - tweak: "RPD subcategories and preview icons reorganized." + - rscadd: "RPD now starts with painting turned off, hitting pipes with build and no paint will target the turf underneath instead. Bye bye turf pixelhunting." diff --git a/html/changelogs/AutoChangeLog-pr-10782.yml b/html/changelogs/AutoChangeLog-pr-10782.yml new file mode 100644 index 0000000000..f66e75a113 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10782.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - tweak: "dueling pistol accesses have been changed to be more accessible." diff --git a/html/changelogs/AutoChangeLog-pr-10467.yml b/html/changelogs/AutoChangeLog-pr-10784.yml similarity index 55% rename from html/changelogs/AutoChangeLog-pr-10467.yml rename to html/changelogs/AutoChangeLog-pr-10784.yml index 7fa379f088..0e5cfc8740 100644 --- a/html/changelogs/AutoChangeLog-pr-10467.yml +++ b/html/changelogs/AutoChangeLog-pr-10784.yml @@ -1,4 +1,4 @@ author: "Seris02" delete-after: True changes: - - bugfix: "cardboard box speed" + - rscadd: "polychromic winter coat" diff --git a/html/changelogs/AutoChangeLog-pr-10786.yml b/html/changelogs/AutoChangeLog-pr-10786.yml new file mode 100644 index 0000000000..7e758122a2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10786.yml @@ -0,0 +1,4 @@ +author: "Commandersand" +delete-after: True +changes: + - tweak: "uplink centcomm suit doesn't have sensors" diff --git a/html/changelogs/AutoChangeLog-pr-10790.yml b/html/changelogs/AutoChangeLog-pr-10790.yml new file mode 100644 index 0000000000..43f949ce16 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10790.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Hair styles and undergarments are yet again free from gender restrictions." diff --git a/html/changelogs/AutoChangeLog-pr-10793.yml b/html/changelogs/AutoChangeLog-pr-10793.yml new file mode 100644 index 0000000000..21cfc5d539 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10793.yml @@ -0,0 +1,4 @@ +author: "Tupinambis" +delete-after: True +changes: + - bugfix: "masks no longer improperly stick out of helmets when they should be hidden." diff --git a/html/changelogs/AutoChangeLog-pr-10795.yml b/html/changelogs/AutoChangeLog-pr-10795.yml new file mode 100644 index 0000000000..b929aad0a5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10795.yml @@ -0,0 +1,4 @@ +author: "ShadeAware" +delete-after: True +changes: + - bugfix: "You can now actually craft Switchblades." diff --git a/html/changelogs/AutoChangeLog-pr-10796.yml b/html/changelogs/AutoChangeLog-pr-10796.yml new file mode 100644 index 0000000000..238fc3a8c7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10796.yml @@ -0,0 +1,4 @@ +author: "Tupinambis" +delete-after: True +changes: + - bugfix: "Status Displays should now update correctly." diff --git a/html/changelogs/AutoChangeLog-pr-10799.yml b/html/changelogs/AutoChangeLog-pr-10799.yml new file mode 100644 index 0000000000..2d49bdc63f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10799.yml @@ -0,0 +1,4 @@ +author: "Seris02" +delete-after: True +changes: + - bugfix: "golden plastitanium toolbox being actually plastitanuium" diff --git a/html/changelogs/AutoChangeLog-pr-10339.yml b/html/changelogs/AutoChangeLog-pr-10800.yml similarity index 56% rename from html/changelogs/AutoChangeLog-pr-10339.yml rename to html/changelogs/AutoChangeLog-pr-10800.yml index c313c4bf80..3486e47b1f 100644 --- a/html/changelogs/AutoChangeLog-pr-10339.yml +++ b/html/changelogs/AutoChangeLog-pr-10800.yml @@ -1,4 +1,4 @@ author: "Seris02" delete-after: True changes: - - rscadd: "telescopic IV drip" + - bugfix: "character slot amount" diff --git a/html/changelogs/AutoChangeLog-pr-10803.yml b/html/changelogs/AutoChangeLog-pr-10803.yml new file mode 100644 index 0000000000..bc50fcc700 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10803.yml @@ -0,0 +1,4 @@ +author: "Seris02" +delete-after: True +changes: + - bugfix: "string highlighting whitespace" diff --git a/html/changelogs/AutoChangeLog-pr-10808.yml b/html/changelogs/AutoChangeLog-pr-10808.yml new file mode 100644 index 0000000000..89e8880af8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10808.yml @@ -0,0 +1,5 @@ +author: "Arturlang" +delete-after: True +changes: + - rscdel: "Removed text macros from the chem dispenser." + - rscadd: "Replaced with dispenser input recording macros." diff --git a/html/changelogs/AutoChangeLog-pr-10809.yml b/html/changelogs/AutoChangeLog-pr-10809.yml new file mode 100644 index 0000000000..2a6c1dcdb8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10809.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - bugfix: "Fancifying makeshift switchblades now works" diff --git a/html/changelogs/AutoChangeLog-pr-10810.yml b/html/changelogs/AutoChangeLog-pr-10810.yml new file mode 100644 index 0000000000..3d1693955a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10810.yml @@ -0,0 +1,5 @@ +author: "Yakumo Chen" +delete-after: True +changes: + - rscadd: "Rings for your fingers!" + - rscadd: "New cargo crates and loadout options to bling your rings!" diff --git a/html/changelogs/AutoChangeLog-pr-10816.yml b/html/changelogs/AutoChangeLog-pr-10816.yml new file mode 100644 index 0000000000..9538f353ec --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10816.yml @@ -0,0 +1,4 @@ +author: "ancientpower" +delete-after: True +changes: + - bugfix: "Fixes an error in pH strips' feedback message." diff --git a/html/changelogs/AutoChangeLog-pr-10817.yml b/html/changelogs/AutoChangeLog-pr-10817.yml new file mode 100644 index 0000000000..cf42f695ef --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10817.yml @@ -0,0 +1,4 @@ +author: "IronEleven" +delete-after: True +changes: + - balance: "Minor stat changes to Choking, Spontaneous Combustion, Autophagocytosis Necrosis, Hallucigen, Narcolepsy, Shivering, and Vomiting symptoms." diff --git a/html/changelogs/AutoChangeLog-pr-10819.yml b/html/changelogs/AutoChangeLog-pr-10819.yml new file mode 100644 index 0000000000..406da850b3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10819.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Clown ops will find bombananas and clown bomb beacons instead of minibombs and bomb beacons in their infiltrator ship now." + - tweak: "For safety, the syndicate shuttle minibombs and bombananas come shipped in a box. Please don't instinctively eat any of those nanas, thank you." diff --git a/html/changelogs/AutoChangeLog-pr-10820.yml b/html/changelogs/AutoChangeLog-pr-10820.yml new file mode 100644 index 0000000000..7833ab7250 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10820.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "Uplink items excluded (such as mulligan, chameleon, ebow) from or exclusive (such as cyber implants) to normal nuke ops will now be properly unavailable/available to clown ops." diff --git a/html/changelogs/AutoChangeLog-pr-10345.yml b/html/changelogs/AutoChangeLog-pr-10821.yml similarity index 52% rename from html/changelogs/AutoChangeLog-pr-10345.yml rename to html/changelogs/AutoChangeLog-pr-10821.yml index a95653cdda..a1661764cf 100644 --- a/html/changelogs/AutoChangeLog-pr-10345.yml +++ b/html/changelogs/AutoChangeLog-pr-10821.yml @@ -1,4 +1,4 @@ -author: "Trilbyspaceclone" +author: "ShadeAware" delete-after: True changes: - - tweak: "allows bandoliers to hold any ammo type as long as it has a casing" + - bugfix: "Switchblades no longer regain their old Makeshift sprite after retracting if you've made them fancy with Silver." diff --git a/html/changelogs/AutoChangeLog-pr-10829.yml b/html/changelogs/AutoChangeLog-pr-10829.yml new file mode 100644 index 0000000000..9866f21fc7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10829.yml @@ -0,0 +1,7 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed bananium energy sword/shield slips." + - balance: "Buffed said slips to ignore no-grav/crawling/flying as well as adding some deadly force to the e-sword." + - bugfix: "Fixed the 'stache grenade anti-non-clumsy user check." + - balance: "Doubled the timer for the sticky mustaches effect from the above grenade (from 1 to 2 minutes)" diff --git a/html/changelogs/AutoChangeLog-pr-10338.yml b/html/changelogs/AutoChangeLog-pr-10830.yml similarity index 61% rename from html/changelogs/AutoChangeLog-pr-10338.yml rename to html/changelogs/AutoChangeLog-pr-10830.yml index c4816a3fbe..0d7b5d56b3 100644 --- a/html/changelogs/AutoChangeLog-pr-10338.yml +++ b/html/changelogs/AutoChangeLog-pr-10830.yml @@ -1,4 +1,4 @@ author: "Seris02" delete-after: True changes: - - rscadd: "marshmallow" + - bugfix: "glitch with PKA" diff --git a/html/changelogs/AutoChangeLog-pr-10831.yml b/html/changelogs/AutoChangeLog-pr-10831.yml new file mode 100644 index 0000000000..477df49370 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10831.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed an edge case with the chaplain armaments beacon spawning the box in nullspace." diff --git a/html/changelogs/AutoChangeLog-pr-10833.yml b/html/changelogs/AutoChangeLog-pr-10833.yml new file mode 100644 index 0000000000..d4b612f622 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10833.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - tweak: "The playback device's cooldown now proportionally increases with messages longer than 60 characters (3 seconds is the default assembly cooldown)." diff --git a/html/changelogs/AutoChangeLog-pr-10834.yml b/html/changelogs/AutoChangeLog-pr-10834.yml new file mode 100644 index 0000000000..1db0ee8988 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10834.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Crafts are now made of plasteel and can be made with 5 sheets" diff --git a/html/changelogs/AutoChangeLog-pr-10836.yml b/html/changelogs/AutoChangeLog-pr-10836.yml new file mode 100644 index 0000000000..d2c9328aa7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10836.yml @@ -0,0 +1,5 @@ +author: "Hatterhat" +delete-after: True +changes: + - rscadd: "The Engineering techfab can now print standard and large RCD compressed matter cartridges." + - rscadd: "The Experimental Tools node now has the Combifan projector, blocking both temperature and atmospheric changes." diff --git a/html/changelogs/AutoChangeLog-pr-10837.yml b/html/changelogs/AutoChangeLog-pr-10837.yml new file mode 100644 index 0000000000..72fee452c1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10837.yml @@ -0,0 +1,6 @@ +author: "Owai-Seek" +delete-after: True +changes: + - tweak: "Blood Crate now has all of the current blood types." + - tweak: "Birthday Cake Recipe is now the same as TG." + - tweak: "Added Soy Sauce and BBQ Packets to Dinnerware Vendor." diff --git a/html/changelogs/AutoChangeLog-pr-10838.yml b/html/changelogs/AutoChangeLog-pr-10838.yml new file mode 100644 index 0000000000..b6fbb864dd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10838.yml @@ -0,0 +1,5 @@ +author: "Owai-Seek" +delete-after: True +changes: + - tweak: "Added nurse outfit, nurse cap, and mailman hat to loadout." + - tweak: "Changed the name of scrubs to blue, green, and purple scrubs." diff --git a/html/changelogs/AutoChangeLog-pr-10841.yml b/html/changelogs/AutoChangeLog-pr-10841.yml new file mode 100644 index 0000000000..58e083fe85 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10841.yml @@ -0,0 +1,4 @@ +author: "Kraseo" +delete-after: True +changes: + - bugfix: "You can no longer pull before wearing boxing gloves to bypass the grab check." diff --git a/html/changelogs/AutoChangeLog-pr-10850.yml b/html/changelogs/AutoChangeLog-pr-10850.yml new file mode 100644 index 0000000000..5cfbd4ab1c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10850.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed maploaded APC terminals direction." diff --git a/html/changelogs/AutoChangeLog-pr-10866.yml b/html/changelogs/AutoChangeLog-pr-10866.yml new file mode 100644 index 0000000000..f5f99207a5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10866.yml @@ -0,0 +1,4 @@ +author: "ancientpower" +delete-after: True +changes: + - bugfix: "Fixes color mismatching with the \"genitals use skintone\" preference." diff --git a/html/changelogs/AutoChangeLog-pr-9856.yml b/html/changelogs/AutoChangeLog-pr-9856.yml deleted file mode 100644 index 697c1c78f5..0000000000 --- a/html/changelogs/AutoChangeLog-pr-9856.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - rscadd: "Refactored code to allow all living mobs to use shields and not only humans." - - tweak: "Monkys will now retaliate against aliens attacking them (as if they even posed a threat to start with)." diff --git a/html/changelogs/AutoChangeLog-pr-9860.yml b/html/changelogs/AutoChangeLog-pr-9860.yml new file mode 100644 index 0000000000..c9d75aa7b9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-9860.yml @@ -0,0 +1,5 @@ +author: "tralezab, bandit, Skoglol" +delete-after: True +changes: + - rscadd: "The mime's PDA messages are silent now!" + - rscadd: "30 new emoji have been added. Mime buff, mime now OP." diff --git a/html/changelogs/AutoChangeLog-pr-9878.yml b/html/changelogs/AutoChangeLog-pr-9878.yml deleted file mode 100644 index ef9c704003..0000000000 --- a/html/changelogs/AutoChangeLog-pr-9878.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - tweak: "add a click cooldown to the overly spammable table slamming." diff --git a/html/font-awesome/README.MD b/html/font-awesome/README.MD new file mode 100644 index 0000000000..7d693c36f0 --- /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 0000000000..e7cdfffe75 --- /dev/null +++ b/html/font-awesome/css/all.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.9.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,.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{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{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{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{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-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-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-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-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-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-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-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.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-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-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-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-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-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-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-usd:before{content:"\f4c0"}.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-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-handshake:before{content:"\f2b5"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-wizard:before{content:"\f6e8"}.fa-haykal:before{content:"\f666"}.fa-hdd:before{content:"\f0a0"}.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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.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-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-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-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.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-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-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-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-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-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-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-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-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-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 0000000000..5f3fdc598c --- /dev/null +++ b/html/font-awesome/css/v4-shims.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.9.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-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:"\f15e"}.fa.fa-sort-amount-asc:before{content:"\f160"}.fa.fa-sort-amount-desc:before{content:"\f161"}.fa.fa-sort-numeric-asc:before{content:"\f162"}.fa.fa-sort-numeric-desc:before{content:"\f163"}.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-cab:before{content:"\f1ba"}.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{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-spotify,.fa.fa-superpowers,.fa.fa-wpexplorer{font-family:"Font Awesome 5 Brands";font-weight:400} \ 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 0000000000..d62be2fad8 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 0000000000..43b1a9ae49 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 0000000000..c77baa8d46 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 0000000000..77c1786227 Binary files /dev/null and b/html/font-awesome/webfonts/fa-solid-900.woff differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 51e9453087..a2fce4678f 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/emoji.dmi b/icons/emoji.dmi index 925b072a5f..931cb7a916 100644 Binary files a/icons/emoji.dmi and b/icons/emoji.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index f8785ae2f7..499b1db21d 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index 772a263358..6e95eae960 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ diff --git a/icons/mob/inhands/weapons/swords_lefthand.dmi b/icons/mob/inhands/weapons/swords_lefthand.dmi index 2169b87580..b74fa16e6a 100644 Binary files a/icons/mob/inhands/weapons/swords_lefthand.dmi and b/icons/mob/inhands/weapons/swords_lefthand.dmi differ diff --git a/icons/mob/inhands/weapons/swords_righthand.dmi b/icons/mob/inhands/weapons/swords_righthand.dmi index f054d8f744..8c60c52e76 100644 Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index 24d654b743..6b1b9591b7 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/suit_digi.dmi b/icons/mob/suit_digi.dmi index e181c65cdb..bb00742a17 100644 Binary files a/icons/mob/suit_digi.dmi and b/icons/mob/suit_digi.dmi differ diff --git a/icons/mob/taur_naga.dmi b/icons/mob/taur_naga.dmi index 7214ec7073..479fa5c83a 100644 Binary files a/icons/mob/taur_naga.dmi and b/icons/mob/taur_naga.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 04e2e3cc75..69d8966329 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/mob/uniform_digi.dmi b/icons/mob/uniform_digi.dmi index 3b86511013..0b8c495c5a 100644 Binary files a/icons/mob/uniform_digi.dmi and b/icons/mob/uniform_digi.dmi differ diff --git a/icons/obj/atmospherics/components/binary_devices.dmi b/icons/obj/atmospherics/components/binary_devices.dmi index 9c6a1b6a1f..3b47dddffc 100644 Binary files a/icons/obj/atmospherics/components/binary_devices.dmi and b/icons/obj/atmospherics/components/binary_devices.dmi differ diff --git a/icons/obj/atmospherics/components/thermomachine.dmi b/icons/obj/atmospherics/components/thermomachine.dmi index 2ff9dac031..9b11fa266f 100644 Binary files a/icons/obj/atmospherics/components/thermomachine.dmi and b/icons/obj/atmospherics/components/thermomachine.dmi differ diff --git a/icons/obj/atmospherics/components/trinary_devices.dmi b/icons/obj/atmospherics/components/trinary_devices.dmi index 6c96035c4a..5a6a62649e 100644 Binary files a/icons/obj/atmospherics/components/trinary_devices.dmi and b/icons/obj/atmospherics/components/trinary_devices.dmi differ diff --git a/icons/obj/atmospherics/components/unary_devices.dmi b/icons/obj/atmospherics/components/unary_devices.dmi index 3f09e99156..39be809a53 100644 Binary files a/icons/obj/atmospherics/components/unary_devices.dmi and b/icons/obj/atmospherics/components/unary_devices.dmi differ diff --git a/icons/obj/atmospherics/pipes/he-junction.dmi b/icons/obj/atmospherics/pipes/he-junction.dmi new file mode 100644 index 0000000000..b1ff675e3a Binary files /dev/null and b/icons/obj/atmospherics/pipes/he-junction.dmi differ diff --git a/icons/obj/atmospherics/pipes/he-manifold.dmi b/icons/obj/atmospherics/pipes/he-manifold.dmi new file mode 100644 index 0000000000..bf062ae5b9 Binary files /dev/null and b/icons/obj/atmospherics/pipes/he-manifold.dmi differ diff --git a/icons/obj/atmospherics/pipes/he-simple.dmi b/icons/obj/atmospherics/pipes/he-simple.dmi new file mode 100644 index 0000000000..64e9f08420 Binary files /dev/null and b/icons/obj/atmospherics/pipes/he-simple.dmi differ diff --git a/icons/obj/atmospherics/pipes/heat.dmi b/icons/obj/atmospherics/pipes/heat.dmi deleted file mode 100644 index 132d11c3ab..0000000000 Binary files a/icons/obj/atmospherics/pipes/heat.dmi and /dev/null differ diff --git a/icons/obj/atmospherics/pipes/junction.dmi b/icons/obj/atmospherics/pipes/junction.dmi deleted file mode 100644 index f3ff732c56..0000000000 Binary files a/icons/obj/atmospherics/pipes/junction.dmi and /dev/null differ diff --git a/icons/obj/atmospherics/pipes/manifold.dmi b/icons/obj/atmospherics/pipes/manifold.dmi index 4eebe1a078..f936a8ea3d 100644 Binary files a/icons/obj/atmospherics/pipes/manifold.dmi and b/icons/obj/atmospherics/pipes/manifold.dmi differ diff --git a/icons/obj/atmospherics/pipes/meter.dmi b/icons/obj/atmospherics/pipes/meter.dmi index 7eabdc9de8..c4cc27d78c 100644 Binary files a/icons/obj/atmospherics/pipes/meter.dmi and b/icons/obj/atmospherics/pipes/meter.dmi differ diff --git a/icons/obj/atmospherics/pipes/pipe_item.dmi b/icons/obj/atmospherics/pipes/pipe_item.dmi index c16e4c1bbb..7d6d559a46 100644 Binary files a/icons/obj/atmospherics/pipes/pipe_item.dmi and b/icons/obj/atmospherics/pipes/pipe_item.dmi differ diff --git a/icons/obj/atmospherics/pipes/pressure_tank.dmi b/icons/obj/atmospherics/pipes/pressure_tank.dmi index 75471113d8..95103015cf 100644 Binary files a/icons/obj/atmospherics/pipes/pressure_tank.dmi and b/icons/obj/atmospherics/pipes/pressure_tank.dmi differ diff --git a/icons/obj/atmospherics/pipes/simple.dmi b/icons/obj/atmospherics/pipes/simple.dmi index 952e6499e3..6af45f88de 100644 Binary files a/icons/obj/atmospherics/pipes/simple.dmi and b/icons/obj/atmospherics/pipes/simple.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 74a5164844..b13e06e824 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index a79ca3be45..d355ade9fe 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index be091c596d..81ef85bb08 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 89f9a6fd93..ce458a1de3 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 71fceba8b4..8c2abcd3b9 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/fireplace.dmi b/icons/obj/fireplace.dmi index d1a157e009..df03958368 100644 Binary files a/icons/obj/fireplace.dmi and b/icons/obj/fireplace.dmi differ diff --git a/icons/obj/glassworks.dmi b/icons/obj/glassworks.dmi new file mode 100644 index 0000000000..de033f08d5 Binary files /dev/null and b/icons/obj/glassworks.dmi differ diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi index bba3efc951..c30e8aa6bd 100644 Binary files a/icons/obj/guns/energy.dmi and b/icons/obj/guns/energy.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index e3540a782b..561b1890e8 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/icons/obj/radio.dmi b/icons/obj/radio.dmi index 64642b8a6c..dbfc7b1f93 100644 Binary files a/icons/obj/radio.dmi and b/icons/obj/radio.dmi differ diff --git a/icons/obj/recycling.dmi b/icons/obj/recycling.dmi index 4e072c9006..9604d6b97e 100644 Binary files a/icons/obj/recycling.dmi and b/icons/obj/recycling.dmi differ diff --git a/icons/obj/ring.dmi b/icons/obj/ring.dmi new file mode 100644 index 0000000000..52fe249394 Binary files /dev/null and b/icons/obj/ring.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 4a6b8964e5..4aa54a2308 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/supermatter.dmi b/icons/obj/supermatter.dmi index 92a9dfe270..fb05808809 100644 Binary files a/icons/obj/supermatter.dmi and b/icons/obj/supermatter.dmi differ diff --git a/icons/pda_icons/pda_emoji.png b/icons/pda_icons/pda_emoji.png new file mode 100644 index 0000000000..39f789f520 Binary files /dev/null and b/icons/pda_icons/pda_emoji.png differ diff --git a/icons/rooms/Lavaland/Mining.dmi b/icons/rooms/Lavaland/Mining.dmi new file mode 100644 index 0000000000..003a457212 Binary files /dev/null and b/icons/rooms/Lavaland/Mining.dmi differ diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi index fe60cf6c0d..aad3e78590 100644 Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ diff --git a/interface/menu.dm b/interface/menu.dm index 547c2edfc1..3c881656da 100644 --- a/interface/menu.dm +++ b/interface/menu.dm @@ -69,8 +69,8 @@ GLOBAL_LIST_EMPTY(menulist) if (!verbpath || !(verbpath in typesof("[type]/verb"))) return - if (copytext(verbpath.name,1,2) == "@") - winset(C, null, list2params(list("command" = copytext(verbpath.name,2)))) + if (verbpath.name[1] == "@") + winset(C, null, list2params(list("command" = copytext(verbpath.name, length(verbpath.name[1]) + 1)))) else winset(C, null, list2params(list("command" = replacetext(verbpath.name, " ", "-")))) diff --git a/modular_citadel/code/_onclick/other_mobs.dm b/modular_citadel/code/_onclick/other_mobs.dm index 51a5c6c5c3..6d9ffdd6ca 100644 --- a/modular_citadel/code/_onclick/other_mobs.dm +++ b/modular_citadel/code/_onclick/other_mobs.dm @@ -9,21 +9,43 @@ return TRUE /mob/living/carbon/human/AltRangedAttack(atom/A, params) + if(isturf(A) || incapacitated()) // pretty annoying to wave your fist at floors and walls. And useless. + return TRUE + changeNext_move(CLICK_CD_RANGE) + var/list/target_viewers = viewers(11, A) //Byond proc, doesn't check for blindness. + if(!(src in target_viewers)) //click catcher issuing calls for out of view objects. + return TRUE if(!has_active_hand()) to_chat(src, "You ponder your life choices and sigh.") return TRUE + var/list/src_viewers = viewers(DEFAULT_MESSAGE_RANGE, src) - src // src has a different message. + var/the_action = "waves to [A]" + var/what_action = "waves to something you can't see" + var/self_action = "wave to [A]" - if(!incapacitated()) - switch(a_intent) - if(INTENT_HELP) - visible_message("[src] waves to [A].", "You wave to [A].") - if(INTENT_DISARM) - visible_message("[src] shoos away [A].", "You shoo away [A].") - if(INTENT_GRAB) - visible_message("[src] beckons [A] to come.", "You beckon [A] to come.") //This sounds lewder than it actually is. Fuck. - if(INTENT_HARM) - visible_message("[src] shakes [p_their()] fist at [A].", "You shake your fist at [A].") - return TRUE + switch(a_intent) + if(INTENT_DISARM) + the_action = "shoos away [A]" + what_action = "shoo away something you can't see" + self_action = "shoo away [A]" + if(INTENT_GRAB) + the_action = "beckons [A] to come" + what_action = "beckons something you can't see to come" + self_action = "beckon [A] to come" + if(INTENT_HARM) + var/pronoun = "[p_their()]" + the_action = "shakes [pronoun] fist at [A]" + what_action = "shakes [pronoun] fist at something you can't see" + self_action = "shake your fist at [A]" + + if(!eye_blind) + to_chat(src, "You [self_action].") + for(var/B in src_viewers) + var/mob/M = B + if(!M.eye_blind) + var/message = (M in target_viewers) ? the_action : what_action + to_chat(M, "[src] [message].") + return TRUE /atom/proc/alt_attack_hand(mob/user) return FALSE diff --git a/modular_citadel/code/datums/status_effects/chems.dm b/modular_citadel/code/datums/status_effects/chems.dm index 89086ab1e5..82f4fbf1d9 100644 --- a/modular_citadel/code/datums/status_effects/chems.dm +++ b/modular_citadel/code/datums/status_effects/chems.dm @@ -211,10 +211,10 @@ /mob/living/verb/toggle_hypno() set category = "IC" - set name = "Toggle Lewd MKUltra" - set desc = "Allows you to toggle if you'd like lewd flavour messages for MKUltra." + set name = "Toggle Lewd Hypno" + set desc = "Allows you to toggle if you'd like lewd flavour messages for hypno features, such as MKUltra." client.prefs.cit_toggles ^= HYPNO - to_chat(usr, "You [((client.prefs.cit_toggles & HYPNO) ?"will":"no longer")] receive lewd flavour messages for MKUltra.") + to_chat(usr, "You [((client.prefs.cit_toggles & HYPNO) ?"will":"no longer")] receive lewd flavour messages for hypno.") /datum/status_effect/chem/enthrall id = "enthrall" diff --git a/modular_citadel/code/modules/admin/admin.dm b/modular_citadel/code/modules/admin/admin.dm deleted file mode 100644 index 529d0c79ec..0000000000 --- a/modular_citadel/code/modules/admin/admin.dm +++ /dev/null @@ -1,39 +0,0 @@ -/client/proc/citaPPoptions(mob/M) // why is this client and not /datum/admins? noone knows, in PP src == client, instead of holder. wtf. - var/body = "
        " - if(M.client) - body += "Make mentor | " - body += "Remove mentor" - return body - -/client/proc/cmd_admin_man_up(mob/M in GLOB.mob_list) - set category = "Special Verbs" - set name = "Man Up" - - if(!M) - return - if(!check_rights(R_ADMIN)) - return - - to_chat(M, "Man up, and deal with it.
        Move on.") - M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE) - - log_admin("Man up: [key_name(usr)] told [key_name(M)] to man up") - var/message = "[key_name_admin(usr)] told [key_name_admin(M)] to man up." - message_admins(message) - admin_ticket_log(M, message) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Man Up") - -/client/proc/cmd_admin_man_up_global() - set category = "Special Verbs" - set name = "Man Up Global" - - if(!check_rights(R_ADMIN)) - return - - to_chat(world, "Man up, and deal with it.
        Move on.") - for(var/mob/M in GLOB.player_list) - M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE) - - log_admin("Man up global: [key_name(usr)] told everybody to man up") - message_admins("[key_name_admin(usr)] told everybody to man up.") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Man Up Global") diff --git a/modular_citadel/code/modules/admin/topic.dm b/modular_citadel/code/modules/admin/topic.dm deleted file mode 100644 index 26bc902bef..0000000000 --- a/modular_citadel/code/modules/admin/topic.dm +++ /dev/null @@ -1,59 +0,0 @@ -/datum/admins/proc/citaTopic(href, href_list) - if(href_list["makementor"]) - makeMentor(href_list["makementor"]) - else if(href_list["removementor"]) - removeMentor(href_list["removementor"]) - -/datum/admins/proc/makeMentor(ckey) - if(!usr.client) - return - if (!check_rights(0)) - return - if(!ckey) - return - var/client/C = GLOB.directory[ckey] - if(C) - if(check_rights_for(C, R_ADMIN,0)) - to_chat(usr, "The client chosen is an admin! Cannot mentorize.") - return - if(SSdbcore.Connect()) - var/datum/DBQuery/query_get_mentor = SSdbcore.NewQuery("SELECT id FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'") - if(query_get_mentor.NextRow()) - to_chat(usr, "[ckey] is already a mentor.") - return - var/datum/DBQuery/query_add_mentor = SSdbcore.NewQuery("INSERT INTO `[format_table_name("mentor")]` (`id`, `ckey`) VALUES (null, '[ckey]')") - if(!query_add_mentor.warn_execute()) - return - var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new mentor [ckey]');") - if(!query_add_admin_log.warn_execute()) - return - else - to_chat(usr, "Failed to establish database connection. The changes will last only for the current round.") - new /datum/mentors(ckey) - to_chat(usr, "New mentor added.") - -/datum/admins/proc/removeMentor(ckey) - if(!usr.client) - return - if (!check_rights(0)) - return - if(!ckey) - return - var/client/C = GLOB.directory[ckey] - if(C) - if(check_rights_for(C, R_ADMIN,0)) - to_chat(usr, "The client chosen is an admin, not a mentor! Cannot de-mentorize.") - return - C.remove_mentor_verbs() - C.mentor_datum = null - GLOB.mentors -= C - if(SSdbcore.Connect()) - var/datum/DBQuery/query_remove_mentor = SSdbcore.NewQuery("DELETE FROM [format_table_name("mentor")] WHERE ckey = '[ckey]'") - if(!query_remove_mentor.warn_execute()) - return - var/datum/DBQuery/query_add_admin_log = SSdbcore.NewQuery("INSERT INTO `[format_table_name("admin_log")]` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed mentor [ckey]');") - if(!query_add_admin_log.warn_execute()) - return - else - to_chat(usr, "Failed to establish database connection. The changes will last only for the current round.") - to_chat(usr, "Mentor removed.") \ No newline at end of file diff --git a/modular_citadel/code/modules/arousal/genitals.dm b/modular_citadel/code/modules/arousal/genitals.dm index a16617ba3f..3cbf906d67 100644 --- a/modular_citadel/code/modules/arousal/genitals.dm +++ b/modular_citadel/code/modules/arousal/genitals.dm @@ -350,7 +350,6 @@ if(use_skintones && H.dna.features["genitals_use_skintone"]) genital_overlay.color = "#[skintone2hex(H.skin_tone)]" - genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]-s_[aroused_state]_[layertext]" else switch(S.color_src) if("cock_color") @@ -361,6 +360,8 @@ genital_overlay.color = "#[H.dna.features["breasts_color"]]" if("vag_color") genital_overlay.color = "#[H.dna.features["vag_color"]]" + + genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]-s_[aroused_state]_[layertext]" if(layer == GENITALS_FRONT_LAYER && CHECK_BITFIELD(G.genital_flags, GENITAL_THROUGH_CLOTHES)) genital_overlay.layer = -GENITALS_EXPOSED_LAYER diff --git a/modular_citadel/code/modules/arousal/organs/vagina.dm b/modular_citadel/code/modules/arousal/organs/vagina.dm index 31d116b48e..3f1bcc5f9b 100644 --- a/modular_citadel/code/modules/arousal/organs/vagina.dm +++ b/modular_citadel/code/modules/arousal/organs/vagina.dm @@ -8,8 +8,8 @@ size = 1 //There is only 1 size right now genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH masturbation_verb = "finger" - arousal_verb = "You feel wetness on your crotch." - unarousal_verb = "You no longer feel wet." + arousal_verb = "You feel wetness on your crotch" + unarousal_verb = "You no longer feel wet" fluid_transfer_factor = 0.1 //Yes, some amount is exposed to you, go get your AIDS layer_index = VAGINA_LAYER_INDEX var/cap_length = 8//D E P T H (cap = capacity) diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index cf68666532..92a1b26f01 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -305,7 +305,7 @@ datum/gear/darksabresheath /datum/gear/flagcape name = "US Flag Cape" category = SLOT_IN_BACKPACK - path = /obj/item/bedsheet/custom/flagcape + path = /obj/item/clothing/neck/flagcape ckeywhitelist = list("darnchacha") /datum/gear/luckyjack @@ -488,3 +488,9 @@ datum/gear/darksabresheath category = SLOT_SHOES path = /obj/item/clothing/shoes/sneakers/mikuleggings ckeywhitelist = list("grandvegeta") + +/datum/gear/cosmos + name = "cosmic space bedsheet" + category = SLOT_IN_BACKPACK + path = /obj/item/bedsheet/cosmos + ckeywhitelist = list("grunnyyy") diff --git a/modular_citadel/code/modules/client/loadout/_loadout.dm b/modular_citadel/code/modules/client/loadout/_loadout.dm index d48da1b863..d35bede179 100644 --- a/modular_citadel/code/modules/client/loadout/_loadout.dm +++ b/modular_citadel/code/modules/client/loadout/_loadout.dm @@ -13,7 +13,7 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids) LAZYINITLIST(GLOB.loadout_whitelist_ids) var/list/file_lines = world.file2list(loadout_config) for(var/line in file_lines) - if(!line || findtextEx(line,"#",1,2)) + if(!line || line[1] == "#") continue var/list/lineinfo = splittext(line, "|") var/lineID = lineinfo[1] @@ -21,7 +21,7 @@ GLOBAL_LIST_EMPTY(loadout_whitelist_ids) var/sublinetypedef = findtext(subline, "=") if(sublinetypedef) var/sublinetype = copytext(subline, 1, sublinetypedef) - var/list/sublinecontent = splittext(copytext(subline, sublinetypedef+1), ",") + var/list/sublinecontent = splittext(copytext(subline, sublinetypedef+ length(sublinetypedef)), ",") if(sublinetype == "WHITELIST") GLOB.loadout_whitelist_ids["[lineID]"] = sublinecontent diff --git a/modular_citadel/code/modules/client/loadout/_medical.dm b/modular_citadel/code/modules/client/loadout/_medical.dm index eed1ad32a1..b1b5c9a62e 100644 --- a/modular_citadel/code/modules/client/loadout/_medical.dm +++ b/modular_citadel/code/modules/client/loadout/_medical.dm @@ -1,8 +1,9 @@ -/datum/gear/stethoscope +/datum/gear/medicbriefcase name = "Medical Briefcase" category = SLOT_HANDS path = /obj/item/storage/briefcase/medical restricted_roles = list("Medical Doctor", "Chief Medical Officer") + restricted_desc = "MD, CMO" /datum/gear/stethoscope name = "Stethoscope" @@ -30,3 +31,17 @@ path = /obj/item/clothing/under/rank/medical/purple restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist") restricted_desc = "Medical" + +/datum/gear/nursehat + name = "Nurse Hat" + category = SLOT_HEAD + path = /obj/item/clothing/head/nursehat + restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist") + restricted_desc = "Medical" + +/datum/gear/nursesuit + name = "Nurse Suit" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/rank/nursesuit + restricted_roles = list("Medical Doctor", "Chief Medical Officer", "Geneticist", "Chemist", "Virologist") + restricted_desc = "Medical" \ No newline at end of file diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm index 82fe89eb6e..d51f4b6125 100644 --- a/modular_citadel/code/modules/client/loadout/backpack.dm +++ b/modular_citadel/code/modules/client/loadout/backpack.dm @@ -95,7 +95,7 @@ name = "Newspaper" category = SLOT_IN_BACKPACK path = /obj/item/newspaper - + /datum/gear/paperbin name = "Paper Bin" category = SLOT_IN_BACKPACK @@ -115,4 +115,35 @@ name = "A fancy pen" category = SLOT_IN_BACKPACK path = /obj/item/pen/fountain - cost = 2 \ No newline at end of file + cost = 2 + +/datum/gear/modular_tablet + name = "A modular tablet" + category = SLOT_IN_BACKPACK + path = /obj/item/modular_computer/tablet/preset/cheap/ + cost = 4 + +/datum/gear/modular_laptop + name = "A modular laptop" + category = SLOT_IN_BACKPACK + path = /obj/item/modular_computer/laptop/preset/civilian + cost = 7 + +/datum/gear/ringbox_gold + name = "A gold ring box" + category = SLOT_IN_BACKPACK + path = /obj/item/storage/fancy/ringbox + cost = 3 + +/datum/gear/ringbox_silver + name = "A silver ring box" + category = SLOT_IN_BACKPACK + path = /obj/item/storage/fancy/ringbox/silver + cost = 3 + +/datum/gear/ringbox_diamond + name = "A diamond ring box" + category = SLOT_IN_BACKPACK + path = /obj/item/storage/fancy/ringbox/diamond + cost = 5 + diff --git a/modular_citadel/code/modules/client/loadout/gloves.dm b/modular_citadel/code/modules/client/loadout/gloves.dm index 826e809652..72e6e91cfc 100644 --- a/modular_citadel/code/modules/client/loadout/gloves.dm +++ b/modular_citadel/code/modules/client/loadout/gloves.dm @@ -2,3 +2,22 @@ name = "Fingerless Gloves" category = SLOT_GLOVES path = /obj/item/clothing/gloves/fingerless + +/datum/gear/goldring + name = "A gold ring" + category = SLOT_GLOVES + path = /obj/item/clothing/gloves/ring + cost = 2 + +/datum/gear/silverring + name = "A silver ring" + category = SLOT_GLOVES + path = /obj/item/clothing/gloves/ring/silver + cost = 2 + +/datum/gear/diamondring + name = "A diamond ring" + category = SLOT_GLOVES + path = /obj/item/clothing/gloves/ring/diamond + cost = 4 + diff --git a/modular_citadel/code/modules/client/loadout/head.dm b/modular_citadel/code/modules/client/loadout/head.dm index 8634460d4e..dd7d2cdc4b 100644 --- a/modular_citadel/code/modules/client/loadout/head.dm +++ b/modular_citadel/code/modules/client/loadout/head.dm @@ -59,6 +59,11 @@ category = SLOT_HEAD path = /obj/item/clothing/head/rabbitears +/datum/gear/mailmanhat + name = "Mailman's Hat" + category = SLOT_HEAD + path = /obj/item/clothing/head/mailman + //trek fancy Hats! /datum/gear/trekcap name = "Federation Officer's Cap (White)" @@ -105,6 +110,7 @@ path = /obj/item/clothing/head/christmashatg */ +//Cowboy Stuff /datum/gear/cowboyhat name = "Cowboy Hat, Brown" category = SLOT_HEAD diff --git a/modular_citadel/code/modules/client/loadout/suit.dm b/modular_citadel/code/modules/client/loadout/suit.dm index d5f2e3cbd1..9b39d006bd 100644 --- a/modular_citadel/code/modules/client/loadout/suit.dm +++ b/modular_citadel/code/modules/client/loadout/suit.dm @@ -79,6 +79,12 @@ category = SLOT_WEAR_SUIT path = /obj/item/clothing/suit/hooded/wintercoat/ratvar/fake +/datum/gear/coat/polycoat + name = "Polychromic winter coat" + category = SLOT_WEAR_SUIT + path = /obj/item/clothing/suit/hooded/wintercoat/polychromic + cost = 4 //too many people with neon green coats is hard on the eyes + /* Commented out until it is "balanced" /datum/gear/coat/sec name = "Security winter coat" diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index 46692ea7a9..b6b72669c2 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -424,3 +424,38 @@ path = /obj/item/clothing/under/stripper_green cost = 3 +/datum/gear/qipao + name = "Qipao, Black" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/lunar/qipao + cost = 3 + +/datum/gear/qipao/white + name = "Qipao, White" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/lunar/qipao/white + cost = 3 + +/datum/gear/qipao/red + name = "Qipao, Red" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/lunar/qipao/red + cost = 3 + +/datum/gear/cheongsam + name = "Cheongsam, Black" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/lunar/cheongsam + cost = 3 + +/datum/gear/cheongsam/white + name = "Cheongsam, White" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/lunar/cheongsam/white + cost = 3 + +/datum/gear/cheongsam/red + name = "Cheongsam, Red" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/lunar/cheongsam/red + cost = 3 \ No newline at end of file diff --git a/modular_citadel/code/modules/client/preferences.dm b/modular_citadel/code/modules/client/preferences.dm index 4e7cb2972f..8b0ba2dd43 100644 --- a/modular_citadel/code/modules/client/preferences.dm +++ b/modular_citadel/code/modules/client/preferences.dm @@ -23,9 +23,6 @@ var/hound_sleeper = TRUE var/cit_toggles = TOGGLES_CITADEL - // stuff that was in base - max_save_slots = 10 - /datum/preferences/New(client/C) ..() diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm index eaf128626d..03a4a56147 100644 --- a/modular_citadel/code/modules/custom_loadout/custom_items.dm +++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm @@ -364,10 +364,11 @@ worn_x_dimension = 64 worn_y_dimension = 34 -/obj/item/bedsheet/custom/flagcape +/obj/item/clothing/neck/flagcape name = "Flag Cape" desc = "A truly patriotic form of heroic attire." icon = 'icons/obj/custom.dmi' + resistance_flags = FLAMMABLE alternate_worn_icon = 'icons/mob/custom_w.dmi' icon_state = "flagcape" item_state = "flagcape" diff --git a/modular_citadel/code/modules/custom_loadout/read_from_file.dm b/modular_citadel/code/modules/custom_loadout/read_from_file.dm index 0ed38e8d41..78124b0324 100644 --- a/modular_citadel/code/modules/custom_loadout/read_from_file.dm +++ b/modular_citadel/code/modules/custom_loadout/read_from_file.dm @@ -13,18 +13,18 @@ GLOBAL_LIST(custom_item_list) GLOB.custom_item_list = list() var/list/file_lines = world.file2list(custom_filelist) for(var/line in file_lines) - if(length(line) == 0) //Emptyline, no one cares. + if(!length(line)) //Emptyline, no one cares. continue - if(copytext(line,1,3) == "//") //Commented line, ignore. + if(copytext(line,1,3) == "//") //Commented line, ignore. 3 == length("//") + 1 continue var/ckey_str_sep = findtext(line, "|") //Process our stuff.. - var/char_str_sep = findtext(line, "|", ckey_str_sep+1) - var/job_str_sep = findtext(line, "|", char_str_sep+1) - var/item_str_sep = findtext(line, "|", job_str_sep+1) + var/char_str_sep = findtext(line, "|", ckey_str_sep + length(ckey_str_sep)) + var/job_str_sep = findtext(line, "|", char_str_sep + length(char_str_sep)) + var/item_str_sep = findtext(line, "|", job_str_sep + length(job_str_sep)) var/ckey_str = ckey(copytext(line, 1, ckey_str_sep)) - var/char_str = copytext(line, ckey_str_sep+1, char_str_sep) - var/job_str = copytext(line, char_str_sep+1, job_str_sep) - var/item_str = copytext(line, job_str_sep+1, item_str_sep) + var/char_str = copytext(line, ckey_str_sep + length(ckey_str_sep), char_str_sep) + var/job_str = copytext(line, char_str_sep + length(char_str_sep), job_str_sep) + var/item_str = copytext(line, job_str_sep + length(job_str_sep), item_str_sep) if(!ckey_str || !char_str || !job_str || !item_str || !length(ckey_str) || !length(char_str) || !length(job_str) || !length(item_str)) log_admin("Errored custom_items_whitelist line: [line] - Component/separator missing!") if(!islist(GLOB.custom_item_list[ckey_str])) @@ -42,7 +42,7 @@ GLOBAL_LIST(custom_item_list) for(var/item_string in item_strings) var/path_str_sep = findtext(item_string, "=") var/path = copytext(item_string, 1, path_str_sep) //Path to spawn - var/amount = copytext(item_string, path_str_sep+1) //Amount to spawn + var/amount = copytext(item_string, path_str_sep + length(path_str_sep)) //Amount to spawn //world << "DEBUG: Item string [item_string] processed" amount = text2num(amount) path = text2path(path) diff --git a/modular_citadel/code/modules/mentor/mentorhelp.dm b/modular_citadel/code/modules/mentor/mentorhelp.dm index eb2b8546da..d056c03f49 100644 --- a/modular_citadel/code/modules/mentor/mentorhelp.dm +++ b/modular_citadel/code/modules/mentor/mentorhelp.dm @@ -10,9 +10,9 @@ spawn(300) verbs += /client/verb/mentorhelp // 30 second cool-down for mentorhelp - msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN)) - if(!msg) return - if(!mob) return //this doesn't happen + msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN)) + if(!msg || !mob) + return var/show_char = CONFIG_GET(flag/mentors_mobname_only) var/mentor_msg = "MENTORHELP: [key_name_mentor(src, 1, 0, 1, show_char)]: [msg]" diff --git a/modular_citadel/code/modules/mentor/mentorpm.dm b/modular_citadel/code/modules/mentor/mentorpm.dm index 4c9a4766ec..cb39f02092 100644 --- a/modular_citadel/code/modules/mentor/mentorpm.dm +++ b/modular_citadel/code/modules/mentor/mentorpm.dm @@ -53,7 +53,7 @@ if (!C.is_mentor() && !is_mentor()) return - msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN)) + msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN)) if(!msg && is_mentor(whom)) to_chat(GLOB.admins | GLOB.mentors, "[src] has stopped their reply to [whom]'s mhelp.") return diff --git a/modular_citadel/code/modules/mentor/mentorsay.dm b/modular_citadel/code/modules/mentor/mentorsay.dm index 6baf969251..c13e3c6ef3 100644 --- a/modular_citadel/code/modules/mentor/mentorsay.dm +++ b/modular_citadel/code/modules/mentor/mentorsay.dm @@ -5,8 +5,9 @@ if(!is_mentor()) return - msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) - if(!msg) return + msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) + if(!msg) + return msg = emoji_parse(msg) log_mentor("MSAY: [key_name(src)] : [msg]") diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm index 0b6903c9fe..bd43d96ba4 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm @@ -12,8 +12,11 @@ /mob/living/carbon/human/movement_delay() . = 0 - if(!resting && m_intent == MOVE_INTENT_RUN && !sprinting) - . += 1 + if(!resting && m_intent == MOVE_INTENT_RUN && sprinting) + var/static/datum/config_entry/number/movedelay/sprint_speed_increase/SSI + if(!SSI) + SSI = CONFIG_GET_ENTRY(number/movedelay/sprint_speed_increase) + . -= SSI.config_entry_value if(wrongdirmovedelay) . += 1 . += ..() diff --git a/modular_citadel/code/modules/mob/living/living.dm b/modular_citadel/code/modules/mob/living/living.dm index 513a80cae0..0caf548196 100644 --- a/modular_citadel/code/modules/mob/living/living.dm +++ b/modular_citadel/code/modules/mob/living/living.dm @@ -17,6 +17,12 @@ var/sprint_stamina_cost = 0.70 //stamina loss per tile while insufficient sprint buffer. //---End +/mob/living/update_config_movespeed() + . = ..() + sprint_buffer_max = CONFIG_GET(number/movedelay/sprint_buffer_max) + sprint_buffer_regen_ds = CONFIG_GET(number/movedelay/sprint_buffer_regen_per_ds) + sprint_stamina_cost = CONFIG_GET(number/movedelay/sprint_stamina_cost) + /mob/living/movement_delay(ignorewalk = 0) . = ..() if(resting) diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm index f2743d853b..c2b8ff0868 100644 --- a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm +++ b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm @@ -416,14 +416,14 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! playsound(src, 'sound/effects/stealthoff.ogg', 25, TRUE, -1) weather_immunities -= "lava" -/mob/living/silicon/robot/throw_impact(atom/A) +/mob/living/silicon/robot/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(!leaping) return ..() - if(A) - if(isliving(A)) - var/mob/living/L = A + if(hit_atom) + if(isliving(hit_atom)) + var/mob/living/L = hit_atom if(!L.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK)) L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") L.Knockdown(iscarbon(L) ? 60 : 45, override_stamdmg = CLAMP(pounce_stamloss, 0, pounce_stamloss_cap-L.getStaminaLoss())) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice. @@ -437,8 +437,8 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm ! pounce_cooldown = !pounce_cooldown spawn(pounce_cooldown_time) //3s by default pounce_cooldown = !pounce_cooldown - else if(A.density && !A.CanPass(src)) - visible_message("[src] smashes into [A]!", "You smash into [A]!") + else if(hit_atom.density && !hit_atom.CanPass(src)) + visible_message("[src] smashes into [hit_atom]!", "You smash into [hit_atom]!") playsound(src, 'sound/items/trayhit1.ogg', 50, 1) Knockdown(15, 1, 1) diff --git a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm index 4ae3e5c488..dd45c0278a 100644 --- a/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm +++ b/modular_citadel/code/modules/projectiles/boxes_magazines/external/pistol.dm @@ -78,3 +78,13 @@ build_path = /obj/item/ammo_box/a357 category = list("Ammo") departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/sl357ap + name = "revolver speedloader (.357 AP)" + desc = "A revolver speedloader. Cuts through like a hot knife through butter." + id = "sl357ap" + build_type = PROTOLATHE + materials = list(MAT_METAL = 30000, MAT_TITANIUM = 45000) + build_path = /obj/item/ammo_box/a357/ap + category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm index 9e965ec7a7..3c0a47bfd7 100644 --- a/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm +++ b/modular_citadel/code/modules/projectiles/guns/ballistic/spinfusor.dm @@ -65,18 +65,4 @@ icon_state = "spinfusorbox" ammo_type = /obj/item/ammo_casing/caseless/spinfusor w_class = WEIGHT_CLASS_NORMAL - max_ammo = 4 - -/datum/supply_pack/security/armory/spinfusor - name = "Stormhammer Spinfusor Crate" - cost = 14000 - contains = list(/obj/item/gun/ballistic/automatic/spinfusor, - /obj/item/gun/ballistic/automatic/spinfusor) - crate_name = "spinfusor crate" - -/datum/supply_pack/security/armory/spinfusorammo - name = "Spinfusor Disk Crate" - cost = 7000 - contains = list(/obj/item/ammo_box/aspinfusor, - /obj/item/ammo_box/aspinfusor) - crate_name = "spinfusor disk crate" + max_ammo = 4 \ No newline at end of file diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm index 86325faa91..f935fc5092 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm @@ -333,6 +333,8 @@ Creating a chem with a low purity will make you permanently fall in love with so ..() /datum/reagent/fermi/proc/FallInLove(mob/living/carbon/Lover, mob/living/carbon/Love) + if(Lover.client?.prefs.cit_toggles & NEVER_HYPNO) + return // doesn't even give a message, it's just ignored if(Lover.has_status_effect(STATUS_EFFECT_INLOVE)) to_chat(Lover, "You are already fully devoted to someone else!") return diff --git a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm index 31e319edd3..a03d5eca81 100644 --- a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm +++ b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm @@ -10,7 +10,7 @@ if(clear_conversion == REACTION_CLEAR_IMPURE | REACTION_CLEAR_INVERSE) for(var/id in results) var/datum/reagent/R = my_atom.reagents.has_reagent(id) - if(R.purity == 1) + if(!R || R.purity == 1) continue var/cached_volume = R.volume @@ -25,7 +25,6 @@ my_atom.reagents.add_reagent(R.impure_chem, impureVol, FALSE, other_purity = 1) R.cached_purity = R.purity R.purity = 1 - return //Called when temperature is above a certain threshold, or if purity is too low. /datum/chemical_reaction/proc/FermiExplode(datum/reagents/R0, var/atom/my_atom, volume, temp, pH, Exploding = FALSE) @@ -200,8 +199,10 @@ FermiExplode = TRUE PurityMin = 0.1 -/datum/chemical_reaction/fermi/breast_enlarger/FermiFinish(datum/reagents/holder, var/atom/my_atom) +/datum/chemical_reaction/fermi/breast_enlarger/FermiFinish(datum/reagents/holder, atom/my_atom) var/datum/reagent/fermi/breast_enlarger/BE = locate(/datum/reagent/fermi/breast_enlarger) in my_atom.reagents.reagent_list + if(!BE) + return var/cached_volume = BE.volume if(BE.purity < 0.35) holder.remove_reagent(type, cached_volume) @@ -249,8 +250,10 @@ P.length = ((PE.volume * PE.purity) / 10)//half as effective. my_atom.reagents.clear_reagents() -/datum/chemical_reaction/fermi/penis_enlarger/FermiFinish(datum/reagents/holder, var/atom/my_atom) +/datum/chemical_reaction/fermi/penis_enlarger/FermiFinish(datum/reagents/holder, atom/my_atom) var/datum/reagent/fermi/penis_enlarger/PE = locate(/datum/reagent/fermi/penis_enlarger) in my_atom.reagents.reagent_list + if(!PE) + return var/cached_volume = PE.volume if(PE.purity < 0.35) holder.remove_reagent(type, cached_volume) @@ -306,13 +309,11 @@ /datum/chemical_reaction/fermi/enthrall/FermiFinish(datum/reagents/holder, var/atom/my_atom) var/datum/reagent/blood/B = locate(/datum/reagent/blood) in my_atom.reagents.reagent_list var/datum/reagent/fermi/enthrall/E = locate(/datum/reagent/fermi/enthrall) in my_atom.reagents.reagent_list - if(!B) + if(!B || !E) return if(!B.data) - var/list/seen = viewers(5, get_turf(my_atom)) - for(var/mob/M in seen) - to_chat(M, "The reaction splutters and fails to react properly.") //Just in case - E.purity = 0 + my_atom.visible_message("The reaction splutters and fails to react properly.") //Just in case + E.purity = 0 if (B.data["gender"] == "female") E.data["creatorGender"] = "Mistress" E.creatorGender = "Mistress" @@ -332,11 +333,11 @@ /datum/chemical_reaction/fermi/enthrall/slime/FermiFinish(datum/reagents/holder, var/atom/my_atom) var/datum/reagent/blood/jellyblood/B = locate(/datum/reagent/blood/jellyblood) in my_atom.reagents.reagent_list//The one line change. var/datum/reagent/fermi/enthrall/E = locate(/datum/reagent/fermi/enthrall) in my_atom.reagents.reagent_list + if(!B || !E) + return if(!B.data) - var/list/seen = viewers(5, get_turf(my_atom)) - for(var/mob/M in seen) - to_chat(M, "The reaction splutters and fails to react.") //Just in case - E.purity = 0 + my_atom.visible_message("The reaction splutters and fails to react properly.") //Just in case + E.purity = 0 if (B.data["gender"] == "female") E.data["creatorGender"] = "Mistress" E.creatorGender = "Mistress" @@ -466,9 +467,9 @@ /datum/chemical_reaction/fermi/acidic_buffer/FermiFinish(datum/reagents/holder, var/atom/my_atom) //might need this - if(!locate(/datum/reagent/fermi/acidic_buffer) in my_atom.reagents.reagent_list) - return var/datum/reagent/fermi/acidic_buffer/Fa = locate(/datum/reagent/fermi/acidic_buffer) in my_atom.reagents.reagent_list + if(!Fa) + return Fa.data = 0.1//setting it to 0 means byond thinks it's not there. /datum/chemical_reaction/fermi/basic_buffer//done test @@ -493,10 +494,10 @@ FermiChem = TRUE -/datum/chemical_reaction/fermi/basic_buffer/FermiFinish(datum/reagents/holder, var/atom/my_atom) //might need this - if(!locate(/datum/reagent/fermi/basic_buffer) in my_atom.reagents.reagent_list) - return +/datum/chemical_reaction/fermi/basic_buffer/FermiFinish(datum/reagents/holder, atom/my_atom) //might need this var/datum/reagent/fermi/basic_buffer/Fb = locate(/datum/reagent/fermi/basic_buffer) in my_atom.reagents.reagent_list + if(!Fb) + return Fb.data = 14 //secretcatchemcode, shh!! Of couse I hide it amongst cats. Though, I moved it with your requests. diff --git a/modular_citadel/code/modules/reagents/objects/items.dm b/modular_citadel/code/modules/reagents/objects/items.dm index 6221bdde18..5d207f4c73 100644 --- a/modular_citadel/code/modules/reagents/objects/items.dm +++ b/modular_citadel/code/modules/reagents/objects/items.dm @@ -71,7 +71,7 @@ if(!istype(cont)) return if(used == TRUE) - to_chat(user, "[user] has already been used!") + to_chat(user, "[src] has already been used!") return if(!LAZYLEN(cont.reagents.reagent_list)) return @@ -107,6 +107,7 @@ if(-INFINITY to 1) color = "#c6040c" desc += " The paper looks to be around a pH of [round(cont.reagents.pH, 1)]" + name = "used [name]" used = TRUE /obj/item/fermichem/pHmeter diff --git a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm index 32474263c4..41eccb7054 100644 --- a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm +++ b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm @@ -1,7 +1,7 @@ //body bluids /datum/reagent/consumable/semen name = "Semen" - description = "Sperm from some animal. I bet you'll drink this out of a bucket someday." + description = "Sperm from some animal. Useless for anything but insemination, really." taste_description = "something salty" taste_mult = 2 //Not very overpowering flavor data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null) @@ -32,15 +32,15 @@ icon_state = "semen1" random_icon_states = list("semen1", "semen2", "semen3", "semen4") -/obj/effect/decal/cleanable/semen/New() - ..() - dir = pick(1,2,4,8) +/obj/effect/decal/cleanable/semen/Initialize(mapload) + . = ..() + dir = GLOB.cardinals add_blood_DNA(list("Non-human DNA" = "A+")) /obj/effect/decal/cleanable/semen/replace_decal(obj/effect/decal/cleanable/semen/S) if(S.blood_DNA) - blood_DNA |= S.blood_DNA.Copy() - ..() + blood_DNA |= S.blood_DNA + return ..() /datum/reagent/consumable/femcum name = "Female Ejaculate" @@ -65,15 +65,15 @@ blood_state = null bloodiness = null -/obj/effect/decal/cleanable/femcum/New() - ..() - dir = pick(1,2,4,8) +/obj/effect/decal/cleanable/femcum/Initialize(mapload) + . = ..() + dir = GLOB.cardinals add_blood_DNA(list("Non-human DNA" = "A+")) /obj/effect/decal/cleanable/femcum/replace_decal(obj/effect/decal/cleanable/femcum/F) if(F.blood_DNA) - blood_DNA |= F.blood_DNA.Copy() - ..() + blood_DNA |= F.blood_DNA + return ..() /datum/reagent/consumable/femcum/reaction_turf(turf/T, reac_volume) if(!istype(T)) diff --git a/modular_citadel/icons/mob/citadel/uniforms.dmi b/modular_citadel/icons/mob/citadel/uniforms.dmi index 855872e9ab..717999c9f0 100644 Binary files a/modular_citadel/icons/mob/citadel/uniforms.dmi and b/modular_citadel/icons/mob/citadel/uniforms.dmi differ diff --git a/modular_citadel/icons/obj/clothing/vg_clothes.dmi b/modular_citadel/icons/obj/clothing/vg_clothes.dmi deleted file mode 100644 index a1d25aebf5..0000000000 Binary files a/modular_citadel/icons/obj/clothing/vg_clothes.dmi and /dev/null differ diff --git a/node_modules/.yarn-integrity b/node_modules/.yarn-integrity new file mode 100644 index 0000000000..1a3aded610 --- /dev/null +++ b/node_modules/.yarn-integrity @@ -0,0 +1,10 @@ +{ + "systemParams": "win32-x64-72", + "modulesFolders": [], + "flags": [], + "linkedModules": [], + "topLevelPatterns": [], + "lockfileEntries": {}, + "files": [], + "artifacts": {} +} \ No newline at end of file diff --git a/sound/machines/nuke/angry_beep.ogg b/sound/machines/nuke/angry_beep.ogg new file mode 100644 index 0000000000..547779de1b Binary files /dev/null and b/sound/machines/nuke/angry_beep.ogg differ diff --git a/sound/machines/nuke/confirm_beep.ogg b/sound/machines/nuke/confirm_beep.ogg new file mode 100644 index 0000000000..6b98ba8bd6 Binary files /dev/null and b/sound/machines/nuke/confirm_beep.ogg differ diff --git a/sound/machines/nuke/general_beep.ogg b/sound/machines/nuke/general_beep.ogg new file mode 100644 index 0000000000..c149eb300a Binary files /dev/null and b/sound/machines/nuke/general_beep.ogg differ diff --git a/sound/voice/moth/mothchitter.ogg b/sound/voice/moth/mothchitter.ogg new file mode 100644 index 0000000000..842bcf8e53 Binary files /dev/null and b/sound/voice/moth/mothchitter.ogg differ diff --git a/sound/voice/moth/mothlaugh.ogg b/sound/voice/moth/mothlaugh.ogg new file mode 100644 index 0000000000..391d6c5aef Binary files /dev/null and b/sound/voice/moth/mothlaugh.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 1e881df6a7..476f20cfe3 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -70,6 +70,7 @@ #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\mobs.dm" #include "code\__DEFINES\monkeys.dm" +#include "code\__DEFINES\move_force.dm" #include "code\__DEFINES\movespeed_modification.dm" #include "code\__DEFINES\nanites.dm" #include "code\__DEFINES\networks.dm" @@ -361,6 +362,7 @@ #include "code\datums\components\chasm.dm" #include "code\datums\components\construction.dm" #include "code\datums\components\decal.dm" +#include "code\datums\components\dejavu.dm" #include "code\datums\components\earprotection.dm" #include "code\datums\components\edit_complainer.dm" #include "code\datums\components\empprotection.dm" @@ -391,6 +393,7 @@ #include "code\datums\components\shrink.dm" #include "code\datums\components\sizzle.dm" #include "code\datums\components\slippery.dm" +#include "code\datums\components\spawner.dm" #include "code\datums\components\spooky.dm" #include "code\datums\components\squeak.dm" #include "code\datums\components\stationloving.dm" @@ -402,6 +405,15 @@ #include "code\datums\components\virtual_reality.dm" #include "code\datums\components\wearertargeting.dm" #include "code\datums\components\wet_floor.dm" +#include "code\datums\components\crafting\craft.dm" +#include "code\datums\components\crafting\glassware.dm" +#include "code\datums\components\crafting\guncrafting.dm" +#include "code\datums\components\crafting\recipes.dm" +#include "code\datums\components\crafting\recipes\recipes_clothing.dm" +#include "code\datums\components\crafting\recipes\recipes_misc.dm" +#include "code\datums\components\crafting\recipes\recipes_primal.dm" +#include "code\datums\components\crafting\recipes\recipes_robot.dm" +#include "code\datums\components\crafting\recipes\recipes_weapon_and_ammo.dm" #include "code\datums\components\fantasy\_fantasy.dm" #include "code\datums\components\fantasy\affix.dm" #include "code\datums\components\fantasy\prefixes.dm" @@ -471,6 +483,8 @@ #include "code\datums\diseases\advance\symptoms\youth.dm" #include "code\datums\elements\_element.dm" #include "code\datums\elements\cleaning.dm" +#include "code\datums\elements\dusts_on_catatonia.dm" +#include "code\datums\elements\dusts_on_leaving_area.dm" #include "code\datums\elements\earhealing.dm" #include "code\datums\elements\ghost_role_eligibility.dm" #include "code\datums\elements\wuv.dm" @@ -1071,6 +1085,7 @@ #include "code\game\objects\structures\reflector.dm" #include "code\game\objects\structures\safe.dm" #include "code\game\objects\structures\showcase.dm" +#include "code\game\objects\structures\spawner.dm" #include "code\game\objects\structures\spirit_board.dm" #include "code\game\objects\structures\stairs.dm" #include "code\game\objects\structures\statues.dm" @@ -1114,6 +1129,7 @@ #include "code\game\objects\structures\crates_lockers\crates\large.dm" #include "code\game\objects\structures\crates_lockers\crates\secure.dm" #include "code\game\objects\structures\crates_lockers\crates\wooden.dm" +#include "code\game\objects\structures\lavaland\necropolis_tendril.dm" #include "code\game\objects\structures\signs\_signs.dm" #include "code\game\objects\structures\signs\signs_departments.dm" #include "code\game\objects\structures\signs\signs_maps.dm" @@ -1223,7 +1239,9 @@ #include "code\modules\antagonists\_common\antag_spawner.dm" #include "code\modules\antagonists\_common\antag_team.dm" #include "code\modules\antagonists\abductor\abductor.dm" +#include "code\modules\antagonists\abductor\abductee\abductee.dm" #include "code\modules\antagonists\abductor\abductee\abductee_objectives.dm" +#include "code\modules\antagonists\abductor\abductee\trauma.dm" #include "code\modules\antagonists\abductor\equipment\abduction_gear.dm" #include "code\modules\antagonists\abductor\equipment\abduction_outfits.dm" #include "code\modules\antagonists\abductor\equipment\abduction_surgery.dm" @@ -1494,11 +1512,13 @@ #include "code\modules\atmospherics\machinery\pipes\layermanifold.dm" #include "code\modules\atmospherics\machinery\pipes\manifold.dm" #include "code\modules\atmospherics\machinery\pipes\manifold4w.dm" +#include "code\modules\atmospherics\machinery\pipes\mapping.dm" #include "code\modules\atmospherics\machinery\pipes\pipes.dm" #include "code\modules\atmospherics\machinery\pipes\simple.dm" #include "code\modules\atmospherics\machinery\pipes\heat_exchange\he_pipes.dm" #include "code\modules\atmospherics\machinery\pipes\heat_exchange\junction.dm" #include "code\modules\atmospherics\machinery\pipes\heat_exchange\manifold.dm" +#include "code\modules\atmospherics\machinery\pipes\heat_exchange\manifold4w.dm" #include "code\modules\atmospherics\machinery\pipes\heat_exchange\simple.dm" #include "code\modules\atmospherics\machinery\portable\canister.dm" #include "code\modules\atmospherics\machinery\portable\portable_atmospherics.dm" @@ -1593,6 +1613,7 @@ #include "code\modules\cargo\packs\science.dm" #include "code\modules\cargo\packs\security.dm" #include "code\modules\cargo\packs\service.dm" +#include "code\modules\cargo\packs\vending.dm" #include "code\modules\chatter\chatter.dm" #include "code\modules\client\asset_cache.dm" #include "code\modules\client\client_colour.dm" @@ -1620,12 +1641,11 @@ #include "code\modules\clothing\glasses\engine_goggles.dm" #include "code\modules\clothing\glasses\hud.dm" #include "code\modules\clothing\glasses\phantomthief.dm" -#include "code\modules\clothing\glasses\vg_glasses.dm" #include "code\modules\clothing\gloves\_gloves.dm" #include "code\modules\clothing\gloves\boxing.dm" #include "code\modules\clothing\gloves\color.dm" #include "code\modules\clothing\gloves\miscellaneous.dm" -#include "code\modules\clothing\gloves\vg_gloves.dm" +#include "code\modules\clothing\gloves\ring.dm" #include "code\modules\clothing\head\_head.dm" #include "code\modules\clothing\head\beanie.dm" #include "code\modules\clothing\head\cit_hats.dm" @@ -1636,14 +1656,12 @@ #include "code\modules\clothing\head\misc.dm" #include "code\modules\clothing\head\misc_special.dm" #include "code\modules\clothing\head\soft_caps.dm" -#include "code\modules\clothing\head\vg_hats.dm" #include "code\modules\clothing\masks\_masks.dm" #include "code\modules\clothing\masks\boxing.dm" #include "code\modules\clothing\masks\breath.dm" #include "code\modules\clothing\masks\gasmask.dm" #include "code\modules\clothing\masks\hailer.dm" #include "code\modules\clothing\masks\miscellaneous.dm" -#include "code\modules\clothing\masks\vg_masks.dm" #include "code\modules\clothing\neck\_neck.dm" #include "code\modules\clothing\outfits\ert.dm" #include "code\modules\clothing\outfits\event.dm" @@ -1657,14 +1675,12 @@ #include "code\modules\clothing\shoes\magboots.dm" #include "code\modules\clothing\shoes\miscellaneous.dm" #include "code\modules\clothing\shoes\taeclowndo.dm" -#include "code\modules\clothing\shoes\vg_shoes.dm" #include "code\modules\clothing\spacesuits\_spacesuits.dm" #include "code\modules\clothing\spacesuits\chronosuit.dm" #include "code\modules\clothing\spacesuits\hardsuit.dm" #include "code\modules\clothing\spacesuits\miscellaneous.dm" #include "code\modules\clothing\spacesuits\plasmamen.dm" #include "code\modules\clothing\spacesuits\syndi.dm" -#include "code\modules\clothing\spacesuits\vg_spess.dm" #include "code\modules\clothing\suits\_suits.dm" #include "code\modules\clothing\suits\armor.dm" #include "code\modules\clothing\suits\bio.dm" @@ -1675,7 +1691,6 @@ #include "code\modules\clothing\suits\reactive_armour.dm" #include "code\modules\clothing\suits\toggles.dm" #include "code\modules\clothing\suits\utility.dm" -#include "code\modules\clothing\suits\vg_suits.dm" #include "code\modules\clothing\suits\wiz_robe.dm" #include "code\modules\clothing\under\_under.dm" #include "code\modules\clothing\under\accessories.dm" @@ -1686,7 +1701,6 @@ #include "code\modules\clothing\under\shorts.dm" #include "code\modules\clothing\under\syndicate.dm" #include "code\modules\clothing\under\trek.dm" -#include "code\modules\clothing\under\vg_under.dm" #include "code\modules\clothing\under\jobs\civilian.dm" #include "code\modules\clothing\under\jobs\engineering.dm" #include "code\modules\clothing\under\jobs\medsci.dm" @@ -1695,14 +1709,6 @@ #include "code\modules\clothing\under\jobs\Plasmaman\engineering.dm" #include "code\modules\clothing\under\jobs\Plasmaman\medsci.dm" #include "code\modules\clothing\under\jobs\Plasmaman\security.dm" -#include "code\modules\crafting\craft.dm" -#include "code\modules\crafting\guncrafting.dm" -#include "code\modules\crafting\recipes.dm" -#include "code\modules\crafting\recipes\recipes_clothing.dm" -#include "code\modules\crafting\recipes\recipes_misc.dm" -#include "code\modules\crafting\recipes\recipes_primal.dm" -#include "code\modules\crafting\recipes\recipes_robot.dm" -#include "code\modules\crafting\recipes\recipes_weapon_and_ammo.dm" #include "code\modules\detectivework\detective_work.dm" #include "code\modules\detectivework\evidence.dm" #include "code\modules\detectivework\scanner.dm" @@ -1837,7 +1843,6 @@ #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_sushi.dm" #include "code\modules\games\cas.dm" #include "code\modules\goonchat\browserOutput.dm" -#include "code\modules\goonchat\jsErrorHandler.dm" #include "code\modules\holiday\easter.dm" #include "code\modules\holiday\holidays.dm" #include "code\modules\holiday\halloween\bartholomew.dm" @@ -2292,7 +2297,6 @@ #include "code\modules\mob\living\simple_animal\simple_animal.dm" #include "code\modules\mob\living\simple_animal\simple_animal_vr.dm" #include "code\modules\mob\living\simple_animal\simplemob_vore_values.dm" -#include "code\modules\mob\living\simple_animal\spawner.dm" #include "code\modules\mob\living\simple_animal\status_procs.dm" #include "code\modules\mob\living\simple_animal\bot\bot.dm" #include "code\modules\mob\living\simple_animal\bot\cleanbot.dm" @@ -2397,7 +2401,6 @@ #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\gutlunch.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\hivelord.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\mining_mobs.dm" -#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\necropolis_tendril.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\elites\elite.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\elites\goliath_broodmother.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\elites\herald.dm" @@ -2619,6 +2622,7 @@ #include "code\modules\projectiles\guns\ballistic\revolver.dm" #include "code\modules\projectiles\guns\ballistic\shotgun.dm" #include "code\modules\projectiles\guns\ballistic\toy.dm" +#include "code\modules\projectiles\guns\energy\dueling.dm" #include "code\modules\projectiles\guns\energy\energy_gun.dm" #include "code\modules\projectiles\guns\energy\kinetic_accelerator.dm" #include "code\modules\projectiles\guns\energy\laser.dm" @@ -3099,11 +3103,9 @@ #include "modular_citadel\code\game\machinery\wishgranter.dm" #include "modular_citadel\code\game\objects\cit_screenshake.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" -#include "modular_citadel\code\modules\admin\admin.dm" #include "modular_citadel\code\modules\admin\chat_commands.dm" #include "modular_citadel\code\modules\admin\holder2.dm" #include "modular_citadel\code\modules\admin\secrets.dm" -#include "modular_citadel\code\modules\admin\topic.dm" #include "modular_citadel\code\modules\arousal\arousal.dm" #include "modular_citadel\code\modules\arousal\genitals.dm" #include "modular_citadel\code\modules\arousal\genitals_sprite_accessories.dm" diff --git a/tgui-next/.editorconfig b/tgui-next/.editorconfig new file mode 100644 index 0000000000..33092d4928 --- /dev/null +++ b/tgui-next/.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-next/.eslintignore b/tgui-next/.eslintignore new file mode 100644 index 0000000000..010416b9e8 --- /dev/null +++ b/tgui-next/.eslintignore @@ -0,0 +1,6 @@ +/**/node_modules +/**/*.bundle.* +/**/*.chunk.* +/**/*.hot-update.* +/packages/inferno/** +/packages/tgui/public/shim-*.js diff --git a/tgui-next/.eslintrc-harder.yml b/tgui-next/.eslintrc-harder.yml new file mode 100644 index 0000000000..eb06f5b33d --- /dev/null +++ b/tgui-next/.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-next/.eslintrc.yml b/tgui-next/.eslintrc.yml new file mode 100644 index 0000000000..4bff333295 --- /dev/null +++ b/tgui-next/.eslintrc.yml @@ -0,0 +1,749 @@ +parser: babel-eslint +parserOptions: + ecmaVersion: 2019 + sourceType: module + ecmaFeatures: + jsx: true +env: + es6: true + browser: true + node: true +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, always-multiline] + ## 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: 80, + ## 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: 6 }] ## 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-next/.gitattributes b/tgui-next/.gitattributes new file mode 100644 index 0000000000..0016cc3bf6 --- /dev/null +++ b/tgui-next/.gitattributes @@ -0,0 +1,10 @@ +* text=auto + +## Enforce text mode and LF line breaks +*.js text eol=lf +*.css text eol=lf +*.html text eol=lf +*.json text eol=lf + +## Treat bundles as binary and ignore them during conflicts +*.bundle.* binary merge=tgui-merge-bundle diff --git a/tgui-next/.gitignore b/tgui-next/.gitignore new file mode 100644 index 0000000000..416ca3768d --- /dev/null +++ b/tgui-next/.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-next/README.md b/tgui-next/README.md new file mode 100644 index 0000000000..df801684c6 --- /dev/null +++ b/tgui-next/README.md @@ -0,0 +1,780 @@ +# 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-next`. + +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. +- `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-next` 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. + +## 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/routes.js` - This is where you want to register new +interfaces, otherwise they simply won't load. +- `/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/atomic.scss` - 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.scss` - CSS classes which are used +in UI components, and most of the stylesheets referenced here are located +in `/packages/tgui/components`. These stylesheets closely follow the +[BEM](https://en.bem.info/methodology/) methodology. +- `/packages/tgui/styles/functions.scss` - Useful SASS functions. +Stuff like `lighten`, `darken`, `luminance` are defined here. + +## Component reference + +> Notice: This documentation might be out of date, so always check the source +> code to see the most up-to-date information. + +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`. 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. + +There are a few important semantics you need to know about: + +- `content` prop is a synonym to a `children` prop. + - `content` is better used when your element is a self-closing tag + (like ``), and when content is long and complex. This is + a native React prop (unlike `content`), and contains all elements you + defined between the opening and the closing tag of an element. + - You should never use both on a same element. + - You should never use `children` explicitly as a prop on an element. +- Inferno supports both 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 straight up does not support lowercase event + handlers. Use the camel case `onClick` instead. + +### `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} +
        + )} +
+ + ); +}; diff --git a/tgui-next/packages/tgui/interfaces/AtmosControlConsole.js b/tgui-next/packages/tgui/interfaces/AtmosControlConsole.js new file mode 100644 index 0000000000..80c23d434b --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/AtmosControlConsole.js @@ -0,0 +1,100 @@ +import { map } from 'common/collections'; +import { toFixed } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, LabeledList, NumberInput, Section } from '../components'; + +export const AtmosControlConsole = props => { + const { act, data } = useBackend(props); + const sensors = data.sensors || []; + return ( + +
+ {sensors.map(sensor => { + const gases = sensor.gases || {}; + return ( +
+ + + {toFixed(sensor.pressure, 2) + ' kPa'} + + {!!sensor.temperature && ( + + {toFixed(sensor.temperature, 2) + ' K'} + + )} + {map((gasPercent, gasId) => { + return ( + + {toFixed(gasPercent, 2) + '%'} + + ); + })(gases)} + +
+ ); + })} +
+ {data.tank && ( +
act('reconnect')} /> + )}> + + +
+ )} +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/AtmosFilter.js b/tgui-next/packages/tgui/interfaces/AtmosFilter.js new file mode 100644 index 0000000000..35bbf34686 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/AtmosFilter.js @@ -0,0 +1,52 @@ +import { useBackend } from '../backend'; +import { Button, LabeledList, NumberInput, Section } from '../components'; +import { getGasLabel } from '../constants'; + +export const AtmosFilter = props => { + const { act, data } = useBackend(props); + const filterTypes = data.filter_types || []; + return ( +
+ + +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/AtmosMixer.js b/tgui-next/packages/tgui/interfaces/AtmosMixer.js new file mode 100644 index 0000000000..a944bfb686 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/AtmosMixer.js @@ -0,0 +1,66 @@ +import { useBackend } from '../backend'; +import { Button, LabeledList, NumberInput, Section } from '../components'; + +export const AtmosMixer = props => { + const { act, data } = useBackend(props); + return ( +
+ + +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/AtmosPump.js b/tgui-next/packages/tgui/interfaces/AtmosPump.js new file mode 100644 index 0000000000..01c50de4d4 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/AtmosPump.js @@ -0,0 +1,63 @@ +import { useBackend } from '../backend'; +import { Button, LabeledList, NumberInput, Section } from '../components'; + +export const AtmosPump = props => { + const { act, data } = useBackend(props); + return ( +
+ + +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/BankMachine.js b/tgui-next/packages/tgui/interfaces/BankMachine.js new file mode 100644 index 0000000000..a3d52097ec --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/BankMachine.js @@ -0,0 +1,33 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, LabeledList, NoticeBox, Section } from '../components'; + +export const BankMachine = props => { + const { act, data } = useBackend(props); + const { + current_balance, + siphoning, + station_name, + } = data; + return ( + +
+ + act(siphoning ? 'halt' : 'siphon')} /> + )}> + {current_balance + ' cr'} + + +
+ + Authorized personnel only + +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/Bepis.js b/tgui-next/packages/tgui/interfaces/Bepis.js new file mode 100644 index 0000000000..da23cb11aa --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/Bepis.js @@ -0,0 +1,109 @@ +import { multiline } from 'common/string'; +import { Fragment } from 'inferno'; +import { act } from '../byond'; +import { Section, LabeledList, Button, NumberInput, Box, Grid } from '../components'; + +export const Bepis = props => { + const { state } = props; + const { config, data } = state; + const { ref } = config; + const { + amount, + } = data; + return ( +
+
act(ref, 'toggle_power')} /> + )}> + All you need to know about the B.E.P.I.S. and you! + The B.E.P.I.S. performs hundreds of tests a second + using electrical and financial resources to invent + new products, or discover new technologies otherwise + overlooked for being too risky or too niche to produce! +
+
act(ref, 'account_reset')} /> + )}> + Console is currently being operated + by {data.account_owner ? data.account_owner : 'no one'}. +
+ + +
+ + + {data.stored_cash} + + + {data.accuracy_percentage}% + + + {data.positive_cash_offset} + + + {data.negative_cash_offset} + + + act(ref, 'amount', { + amount: value, + })} /> + + +
+ +
+ + + + ); +}; diff --git a/tgui-next/packages/tgui/interfaces/BluespaceArtillery.js b/tgui-next/packages/tgui/interfaces/BluespaceArtillery.js new file mode 100644 index 0000000000..b9f07eabe9 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/BluespaceArtillery.js @@ -0,0 +1,78 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, LabeledList, NoticeBox, Section } from '../components'; + +export const BluespaceArtillery = props => { + const { act, data } = useBackend(props); + const { + notice, + connected, + unlocked, + target, + } = data; + return ( + + {!!notice && ( + + {notice} + + )} + {connected ? ( + +
act('recalibrate')} /> + )}> + + {target || 'No Target Set'} + +
+
+ {unlocked ? ( + +
+
+ ) : ( +
+ + +
+ )} +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/BorgPanel.js b/tgui-next/packages/tgui/interfaces/BorgPanel.js new file mode 100644 index 0000000000..7cc4c860e6 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/BorgPanel.js @@ -0,0 +1,135 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, LabeledList, ProgressBar, Section } from '../components'; + +export const BorgPanel = props => { + const { act, data } = useBackend(props); + const borg = data.borg || {}; + const cell = data.cell || {}; + const cellPercent = cell.charge / cell.maxcharge; + const channels = data.channels || []; + const modules = data.modules || []; + const upgrades = data.upgrades || []; + const ais = data.ais || []; + const laws = data.laws || []; + return ( + +
act('rename')} /> + )}> + + +
+
act('toggle_lawupdate')} /> + )}> + {laws.map(law => ( + + {law} + + ))} +
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/BrigTimer.js b/tgui-next/packages/tgui/interfaces/BrigTimer.js new file mode 100644 index 0000000000..a83d643334 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/BrigTimer.js @@ -0,0 +1,55 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, Section } from '../components'; + +export const BrigTimer = props => { + const { act, data } = useBackend(props); + return ( +
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/Canister.js b/tgui-next/packages/tgui/interfaces/Canister.js new file mode 100644 index 0000000000..0e2810e290 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/Canister.js @@ -0,0 +1,121 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { AnimatedNumber, Box, Button, LabeledList, NoticeBox, ProgressBar, Section } from '../components'; + +export const Canister = props => { + const { act, data } = useBackend(props); + return ( + + + The regulator {data.hasHoldingTank ? 'is' : 'is not'} connected + to a tank. + +
act('relabel')} /> + )}> + + + kPa + + + {!!data.isPrototype && ( + +
+ +
+ + + + kPa + + + +
+ +
act('eject')} /> + )}> + {!!data.hasHoldingTank && ( + + + {data.holdingTank.name} + + + kPa + + + )} + {!data.hasHoldingTank && ( + + No Holding Tank + + )} +
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/Cargo.js b/tgui-next/packages/tgui/interfaces/Cargo.js new file mode 100644 index 0000000000..85ae19755e --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/Cargo.js @@ -0,0 +1,339 @@ +import { map } from 'common/collections'; +import { Fragment } from 'inferno'; +import { act } from '../byond'; +import { AnimatedNumber, Box, Button, LabeledList, Section, Tabs } from '../components'; +import { InterfaceLockNoticeBox } from './common/InterfaceLockNoticeBox'; + +export const Cargo = props => { + const { state } = props; + const { config, data } = state; + const { ref } = config; + const supplies = data.supplies || {}; + const requests = data.requests || []; + const cart = data.cart || []; + + const cartTotalAmount = cart + .reduce((total, entry) => total + entry.cost, 0); + + const cartButtons = !data.requestonly && ( + + + {cart.length === 0 && 'Cart is empty'} + {cart.length === 1 && '1 item'} + {cart.length >= 2 && cart.length + ' items'} + {' '} + {cartTotalAmount > 0 && `(${cartTotalAmount} cr)`} + + + + ))} + + + + ); +}; diff --git a/tgui-next/packages/tgui/interfaces/ChemReactionChamber.js b/tgui-next/packages/tgui/interfaces/ChemReactionChamber.js new file mode 100644 index 0000000000..8c829258ec --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/ChemReactionChamber.js @@ -0,0 +1,98 @@ +import { Component } from 'inferno'; +import { act } from '../byond'; +import { Box, Button, LabeledList, NumberInput, Section, Input } from '../components'; +import { map } from 'common/collections'; +import { classes } from 'common/react'; + + +export class ChemReactionChamber extends Component { + constructor() { + super(); + this.state = { + reagentName: "", + reagentQuantity: 1, + }; + } + + setReagentName(reagentName) { + this.setState({ + reagentName, + }); + } + + setReagentQuantity(reagentQuantity) { + this.setState({ + reagentQuantity, + }); + } + + render() { + const { state } = this.props; + const { config, data } = state; + const { ref } = config; + const emptying = data.emptying; + const reagents = data.reagents || []; + return ( +
+ {emptying ? "Emptying" : "Filling"} + + )} > + + + + this.setReagentName(value)} /> + + + this.setReagentQuantity(value)} /> + +
+ ); + } +} diff --git a/tgui-next/packages/tgui/interfaces/ChemSplitter.js b/tgui-next/packages/tgui/interfaces/ChemSplitter.js new file mode 100644 index 0000000000..8e64c43e0f --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/ChemSplitter.js @@ -0,0 +1,48 @@ +import { toFixed } from 'common/math'; +import { useBackend } from '../backend'; +import { LabeledList, NumberInput, Section } from '../components'; + +export const ChemSplitter = props => { + const { act, data } = useBackend(props); + const { + straight, + side, + max_transfer, + } = data; + return ( +
+ + + toFixed(value, 2)} + step={0.05} + stepPixelSize={4} + onChange={(e, value) => act('set_amount', { + target: 'straight', + amount: value, + })} /> + + + toFixed(value, 2)} + step={0.05} + stepPixelSize={4} + onChange={(e, value) => act('set_amount', { + target: 'side', + amount: value, + })} /> + + +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/ChemSynthesizer.js b/tgui-next/packages/tgui/interfaces/ChemSynthesizer.js new file mode 100644 index 0000000000..df56dfdc07 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/ChemSynthesizer.js @@ -0,0 +1,42 @@ +import { toFixed } from 'common/math'; +import { useBackend } from '../backend'; +import { Box, Button, Section } from '../components'; + +export const ChemSynthesizer = props => { + const { act, data } = useBackend(props); + const { + amount, + current_reagent, + chemicals = [], + possible_amounts = [], + } = data; + return ( +
+ + {possible_amounts.map(possible_amount => ( +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/CodexGigas.js b/tgui-next/packages/tgui/interfaces/CodexGigas.js new file mode 100644 index 0000000000..f96ce9380b --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/CodexGigas.js @@ -0,0 +1,98 @@ +import { useBackend } from '../backend'; +import { Button, LabeledList, Section } from '../components'; + +// TODO: refactor the backend of this it's a trainwreck +export const CodexGigas = props => { + const { act, data } = useBackend(props); + const prefixes = [ + "Dark", + "Hellish", + "Fallen", + "Fiery", + "Sinful", + "Blood", + "Fluffy", + ]; + const titles = [ + "Lord", + "Prelate", + "Count", + "Viscount", + "Vizier", + "Elder", + "Adept", + ]; + const names = [ + "hal", + "ve", + "odr", + "neit", + "ci", + "quon", + "mya", + "folth", + "wren", + "geyr", + "hil", + "niet", + "twou", + "phi", + "coa", + ]; + const suffixes = [ + "the Red", + "the Soulless", + "the Master", + "the Lord of all things", + "Jr.", + ]; + return ( +
+ {data.name} + + + {prefixes.map(prefix => ( +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/ComputerFabricator.js b/tgui-next/packages/tgui/interfaces/ComputerFabricator.js new file mode 100644 index 0000000000..87366f6f73 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/ComputerFabricator.js @@ -0,0 +1,403 @@ +import { multiline } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, Grid, Section, Table, Tooltip } from '../components'; + +export const ComputerFabricator = props => { + const { state } = props; + const { act, data } = useBackend(props); + return ( + +
+ Your perfect device, only three steps away... +
+ {data.state !== 0 && ( + + )} /> + + K + + + + + + )} +
+ + {programs.map(program => ( + + +
+
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/NtosNetChat.js b/tgui-next/packages/tgui/interfaces/NtosNetChat.js new file mode 100644 index 0000000000..e6b2ff5f9d --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/NtosNetChat.js @@ -0,0 +1,170 @@ +import { useBackend } from '../backend'; +import { AnimatedNumber, Box, Button, Grid, LabeledList, ProgressBar, Section, Input, Table, Icon, Flex } from '../components'; +import { Fragment } from 'inferno'; +import { createLogger } from '../logging'; + +const logger = createLogger('ntos chat'); + +export const NtosNetChat = props => { + const { act, data } = useBackend(props); + + const { + can_admin, + adminmode, + authed, + username, + active_channel, + is_operator, + all_channels = [], + clients = [], + messages = [], + } = data; + + const in_channel = (active_channel !== null); + const authorized = (authed || adminmode); + + return ( +
+ + + + + act('PRG_newchannel', { + new_channel_name: value, + })} /> + {all_channels.map(channel => ( +
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/NtosNetDownloader.js b/tgui-next/packages/tgui/interfaces/NtosNetDownloader.js new file mode 100644 index 0000000000..da3359fb87 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/NtosNetDownloader.js @@ -0,0 +1,123 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, Flex, Icon, LabeledList, NoticeBox, ProgressBar, Section } from '../components'; + +export const NtosNetDownloader = props => { + const { state } = props; + const { act, data } = useBackend(props); + const { + disk_size, + disk_used, + downloadable_programs = [], + error, + hacked_programs = [], + hackedavailable, + } = data; + return ( + + {!!error && ( + + + {error} + +
+ +
+ {children} +
+ + ); +}; diff --git a/tgui-next/packages/tgui/interfaces/NuclearBomb.js b/tgui-next/packages/tgui/interfaces/NuclearBomb.js new file mode 100644 index 0000000000..419fa7473e --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/NuclearBomb.js @@ -0,0 +1,121 @@ +import { classes } from 'common/react'; +import { useBackend } from '../backend'; +import { Box, Button, Flex, Grid, Icon } from '../components'; + +// This ui is so many manual overrides and !important tags +// and hand made width sets that changing pretty much anything +// is going to require a lot of tweaking it get it looking correct again +// I'm sorry, but it looks bangin +const NukeKeypad = props => { + const { act } = useBackend(props); + const keypadKeys = [ + ['1', '4', '7', 'C'], + ['2', '5', '8', '0'], + ['3', '6', '9', 'E'], + ]; + return ( + + + {keypadKeys.map(keyColumn => ( + + {keyColumn.map(key => ( + + + + {data.sheets} + {(data.sheets >= 1) && ( + + )} + + + + + + {data.current_heat < 100 ? ( + Nominal + ) : ( + data.current_heat < 200 ? ( + Caution + ) : ( + DANGER + ) + )} + + + +
+ + + {data.power_output} + + + + + + + + {data.connected ? data.power_available : "Unconnected"} + + + +
+ + ); +}; diff --git a/tgui-next/packages/tgui/interfaces/PowerMonitor.js b/tgui-next/packages/tgui/interfaces/PowerMonitor.js new file mode 100644 index 0000000000..8998344be5 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/PowerMonitor.js @@ -0,0 +1,222 @@ +import { map, sortBy } from 'common/collections'; +import { flow } from 'common/fp'; +import { toFixed } from 'common/math'; +import { pureComponentHooks } from 'common/react'; +import { Component, Fragment } from 'inferno'; +import { Box, Button, Chart, ColorBox, Flex, Icon, LabeledList, ProgressBar, Section, Table } from '../components'; + +const PEAK_DRAW = 500000; + +const powerRank = str => { + const unit = String(str.split(' ')[1]).toLowerCase(); + return ['w', 'kw', 'mw', 'gw'].indexOf(unit); +}; + +export class PowerMonitor extends Component { + constructor() { + super(); + this.state = { + sortByField: null, + }; + } + + render() { + const { state } = this.props; + const { data } = state; + const { history } = data; + const { sortByField } = this.state; + const supply = history.supply[history.supply.length - 1] || 0; + const demand = history.demand[history.demand.length - 1] || 0; + const supplyData = history.supply.map((value, i) => [i, value]); + const demandData = history.demand.map((value, i) => [i, value]); + const maxValue = Math.max( + PEAK_DRAW, + ...history.supply, + ...history.demand); + // Process area data + const areas = flow([ + map((area, i) => ({ + ...area, + // Generate a unique id + id: area.name + i, + })), + sortByField === 'name' && sortBy(area => area.name), + sortByField === 'charge' && sortBy(area => -area.charge), + sortByField === 'draw' && sortBy( + area => -powerRank(area.load), + area => -parseFloat(area.load)), + ])(data.areas); + return ( + + + +
+ + + + + + + + +
+
+ +
+ + +
+
+
+
+ + + Sort by: + + this.setState({ + sortByField: sortByField !== 'name' && 'name', + })} /> + this.setState({ + sortByField: sortByField !== 'charge' && 'charge', + })} /> + this.setState({ + sortByField: sortByField !== 'draw' && 'draw', + })} /> + + + + + Area + + + Charge + + + Draw + + + Eqp + + + Lgt + + + Env + + + {areas.map((area, i) => ( + + + + + + + + + ))} +
+ {area.name} + + + + {area.load} + + + + + + +
+
+
+ ); + } +} + +const AreaCharge = props => { + const { charging, charge } = props; + return ( + + 50 + ? 'battery-half' + : 'battery-quarter' + ) + || charging === 1 && 'bolt' + || charging === 2 && 'battery-full' + )} + color={( + charging === 0 && ( + charge > 50 + ? 'yellow' + : 'red' + ) + || charging === 1 && 'yellow' + || charging === 2 && 'green' + )} /> + + {toFixed(charge) + '%'} + + + ); +}; + +AreaCharge.defaultHooks = pureComponentHooks; + +const AreaStatusColorBox = props => { + const { status } = props; + const power = Boolean(status & 2); + const mode = Boolean(status & 1); + const tooltipText = (power ? 'On' : 'Off') + + ` [${mode ? 'auto' : 'manual'}]`; + return ( + + ); +}; + +AreaStatusColorBox.defaultHooks = pureComponentHooks; diff --git a/tgui-next/packages/tgui/interfaces/Radio.js b/tgui-next/packages/tgui/interfaces/Radio.js new file mode 100644 index 0000000000..e335cf1cac --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/Radio.js @@ -0,0 +1,108 @@ +import { map } from 'common/collections'; +import { toFixed } from 'common/math'; +import { useBackend } from '../backend'; +import { Box, Button, LabeledList, NumberInput, Section } from '../components'; +import { RADIO_CHANNELS } from '../constants'; + +export const Radio = props => { + const { act, data } = useBackend(props); + const { + freqlock, + frequency, + minFrequency, + maxFrequency, + listening, + broadcasting, + command, + useCommand, + subspace, + subspaceSwitchable, + } = data; + const tunedChannel = RADIO_CHANNELS + .find(channel => channel.freq === frequency); + const channels = map((value, key) => ({ + name: key, + status: !!value, + }))(data.channels); + return ( +
+ + + {freqlock && ( + + {toFixed(frequency / 10, 1) + ' kHz'} + + ) || ( + toFixed(value, 1)} + onDrag={(e, value) => act('frequency', { + adjust: (value - frequency / 10), + })} /> + )} + {tunedChannel && ( + + [{tunedChannel.name}] + + )} + + +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/RapidPipeDispenser.js b/tgui-next/packages/tgui/interfaces/RapidPipeDispenser.js new file mode 100644 index 0000000000..17e4fd9d15 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/RapidPipeDispenser.js @@ -0,0 +1,188 @@ +import { classes } from 'common/react'; +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, ColorBox, Flex, LabeledList, Section, Tabs } from '../components'; + +const ROOT_CATEGORIES = [ + 'Atmospherics', + 'Disposals', + 'Transit Tubes', +]; + +const ICON_BY_CATEGORY_NAME = { + 'Atmospherics': 'wrench', + 'Disposals': 'trash-alt', + 'Transit Tubes': 'bus', + 'Pipes': 'grip-lines', + 'Disposal Pipes': 'grip-lines', + 'Devices': 'microchip', + 'Heat Exchange': 'thermometer-half', + 'Station Equipment': 'microchip', +}; + +const PAINT_COLORS = { + grey: '#bbbbbb', + amethyst: '#a365ff', + blue: '#4466ff', + brown: '#b26438', + cyan: '#48eae8', + dark: '#808080', + green: '#1edd00', + orange: '#ffa030', + purple: '#b535ea', + red: '#ff3333', + violet: '#6e00f6', + yellow: '#ffce26', +}; + +const TOOLS = [ + { + name: 'Dispense', + bitmask: 1, + }, + { + name: 'Connect', + bitmask: 2, + }, + { + name: 'Destroy', + bitmask: 4, + }, + { + name: 'Paint', + bitmask: 8, + }, +]; + +export const RapidPipeDispenser = props => { + const { act, data } = useBackend(props); + const { + category: rootCategoryIndex, + categories = [], + selected_color, + piping_layer, + mode, + } = data; + const previews = data.preview_rows.flatMap(row => row.previews); + return ( + +
+ + + {ROOT_CATEGORIES.map((categoryName, i) => ( +
+ + +
+ {rootCategoryIndex === 0 && ( + + {[1, 2, 3].map(layer => ( + act('piping_layer', { + piping_layer: layer, + })} /> + ))} + + )} + + {previews.map(preview => ( + + ))} + +
+
+ +
+ + {categories.map(category => ( + + {() => category.recipes.map(recipe => ( + act('pipe_type', { + pipe_type: recipe.pipe_index, + category: category.cat_name, + })} /> + ))} + + ))} + +
+
+
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/SatelliteControl.js b/tgui-next/packages/tgui/interfaces/SatelliteControl.js new file mode 100644 index 0000000000..73a7f1ffbb --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/SatelliteControl.js @@ -0,0 +1,45 @@ +import { useBackend } from '../backend'; +import { Button, LabeledList, ProgressBar, Section, Table, Box } from '../components'; +import { Fragment } from 'inferno'; +import { LabeledListItem } from '../components/LabeledList'; + +export const SatelliteControl = props => { + const { act, data } = useBackend(props); + const satellites = data.satellites || []; + return ( + + {data.meteor_shield && ( +
+ + + + + +
+ )} +
+ + {satellites.map(satellite => ( + act('toggle', { + id: satellite.id, + })} + /> + ))} + +
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/ScannerGate.js b/tgui-next/packages/tgui/interfaces/ScannerGate.js new file mode 100644 index 0000000000..f1e82729bc --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/ScannerGate.js @@ -0,0 +1,351 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, LabeledList, NumberInput, Section } from '../components'; +import { InterfaceLockNoticeBox } from './common/InterfaceLockNoticeBox'; + +const DISEASE_THEASHOLD_LIST = [ + 'Positive', + 'Harmless', + 'Minor', + 'Medium', + 'Harmful', + 'Dangerous', + 'BIOHAZARD', +]; + +const TARGET_SPECIES_LIST = [ + { + name: 'Human', + value: 'human', + }, + { + name: 'Lizardperson', + value: 'lizard', + }, + { + name: 'Flyperson', + value: 'fly', + }, + { + name: 'Felinid', + value: 'felinid', + }, + { + name: 'Plasmaman', + value: 'plasma', + }, + { + name: 'Mothperson', + value: 'moth', + }, + { + name: 'Jellyperson', + value: 'jelly', + }, + { + name: 'Podperson', + value: 'pod', + }, + { + name: 'Golem', + value: 'golem', + }, + { + name: 'Zombie', + value: 'zombie', + }, +]; + +const TARGET_NUTRITION_LIST = [ + { + name: 'Starving', + value: 150, + }, + { + name: 'Obese', + value: 600, + }, +]; + +export const ScannerGate = props => { + const { state } = props; + const { act, data } = useBackend(props); + return ( + + act('toggle_lock')} /> + {!data.locked && ( + + )} + + ); +}; + +const SCANNER_GATE_ROUTES = { + Off: { + title: 'Scanner Mode: Off', + component: () => ScannerGateOff, + }, + Wanted: { + title: 'Scanner Mode: Wanted', + component: () => ScannerGateWanted, + }, + Guns: { + title: 'Scanner Mode: Guns', + component: () => ScannerGateGuns, + }, + Mindshield: { + title: 'Scanner Mode: Mindshield', + component: () => ScannerGateMindshield, + }, + Disease: { + title: 'Scanner Mode: Disease', + component: () => ScannerGateDisease, + }, + Species: { + title: 'Scanner Mode: Species', + component: () => ScannerGateSpecies, + }, + Nutrition: { + title: 'Scanner Mode: Nutrition', + component: () => ScannerGateNutrition, + }, + Nanites: { + title: 'Scanner Mode: Nanites', + component: () => ScannerGateNanites, + }, +}; + +const ScannerGateControl = props => { + const { state } = props; + const { act, data } = useBackend(props); + const { scan_mode } = data; + const route = SCANNER_GATE_ROUTES[scan_mode] + || SCANNER_GATE_ROUTES.off; + const Component = route.component(); + return ( +
act('set_mode', { new_mode: 'Off' })} /> + )}> + +
+ ); +}; + +const ScannerGateOff = props => { + const { act } = useBackend(props); + return ( + + + Select a scanning mode below. + + + + )}> + {data.contents.length === 0 && ( + + Unfortunately, this {data.name} is empty. + + ) || ( + + + + Item + + + + {data.verb ? data.verb : 'Dispense'} + + + {map((value, key) => ( + + + {value.name} + + + {value.amount} + + +
+ )} + + ); +}; diff --git a/tgui-next/packages/tgui/interfaces/Smes.js b/tgui-next/packages/tgui/interfaces/Smes.js new file mode 100644 index 0000000000..7479af5894 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/Smes.js @@ -0,0 +1,176 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, NumberInput, LabeledList, ProgressBar, Section } from '../components'; + +export const Smes = props => { + const { act, data } = useBackend(props); + + let inputState; + if (data.capacityPercent >= 100) { + inputState = 'good'; + } + else if (data.inputting) { + inputState = 'average'; + } + else { + inputState = 'bad'; + } + let outputState; + if (data.outputting) { + outputState = 'good'; + } + else if (data.charge > 0) { + outputState = 'average'; + } + else { + outputState = 'bad'; + } + + return ( + +
+ +
+
+ + act('tryinput')}> + {data.inputAttempt ? 'Auto' : 'Off'} + + }> + + {data.capacityPercent >= 100 + ? 'Fully Charged' + : data.inputting + ? 'Charging' + : 'Not Charging'} + + + + + + +
+
+ + act('tryoutput')}> + {data.outputAttempt ? 'On' : 'Off'} + + }> + + {data.outputting + ? 'Sending' + : data.charge > 0 + ? 'Not Sending' + : 'No Charge'} + + + + + + +
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/SmokeMachine.js b/tgui-next/packages/tgui/interfaces/SmokeMachine.js new file mode 100644 index 0000000000..16ba078910 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/SmokeMachine.js @@ -0,0 +1,71 @@ +import { useBackend } from '../backend'; +import { Fragment } from 'inferno'; +import { AnimatedNumber, Box, Button, LabeledList, ProgressBar, NoticeBox, Section } from '../components'; + +export const SmokeMachine = props => { + const { act, data } = useBackend(props); + const { + TankContents, + isTankLoaded, + TankCurrentVolume, + TankMaxVolume, + active, + setting, + screen, + maxSetting = [], + } = data; + return ( + +
act('power')} /> + )}> + + + {' / ' + TankMaxVolume} + + + + + { [1, 2, 3, 4, 5].map(amount => ( +
+
act('purge')} /> + )}> + {TankContents.map(chemical => ( + + + {' '} + units of {chemical.name} + + ))} +
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/SolarControl.js b/tgui-next/packages/tgui/interfaces/SolarControl.js new file mode 100644 index 0000000000..1cfb4800c0 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/SolarControl.js @@ -0,0 +1,118 @@ +import { toFixed } from 'common/math'; +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, Grid, LabeledList, NumberInput, ProgressBar, Section } from '../components'; + +export const SolarControl = props => { + const { act, data } = useBackend(props); + const { + generated, + generated_ratio, + azimuth_current, + azimuth_rate, + max_rotation_rate, + tracking_state, + connected_panels, + connected_tracker, + } = data; + return ( + +
act('refresh')} /> + )}> + + + + + {connected_tracker ? 'OK' : 'N/A'} + + 0 ? 'good' : 'bad'}> + {connected_panels} + + + + + + + + + + + +
+
+ + +
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/SpaceHeater.js b/tgui-next/packages/tgui/interfaces/SpaceHeater.js new file mode 100644 index 0000000000..c44f3e9c47 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/SpaceHeater.js @@ -0,0 +1,104 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, LabeledList, NumberInput, ProgressBar, Section } from '../components'; + +export const SpaceHeater = props => { + const { act, data } = useBackend(props); + return ( + +
+
+
+ + + 50 + ? 'bad' + : Math.abs(data.targetTemp - data.currentTemp) > 20 + ? 'average' + : 'good'}> + {data.currentTemp}°C + + + + {data.open && ( + act('target', { + target: value, + })} /> + ) || ( + data.targetTemp + '°C' + )} + + + {!data.open && 'Auto' || ( + +
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/SpawnersMenu.js b/tgui-next/packages/tgui/interfaces/SpawnersMenu.js new file mode 100644 index 0000000000..27d8b1f9ff --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/SpawnersMenu.js @@ -0,0 +1,51 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, Section } from '../components'; + +export const SpawnersMenu = props => { + const { act, data } = useBackend(props); + const spawners = data.spawners || []; + return ( +
+ {spawners.map(spawner => ( +
+
+ ))} +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/StationAlertConsole.js b/tgui-next/packages/tgui/interfaces/StationAlertConsole.js new file mode 100644 index 0000000000..c372b532e9 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/StationAlertConsole.js @@ -0,0 +1,57 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Section } from '../components'; + +export const StationAlertConsole = props => { + const { data } = useBackend(props); + const categories = data.alarms || []; + const fire = categories['Fire'] || []; + const atmos = categories['Atmosphere'] || []; + const power = categories['Power'] || []; + return ( + +
+
    + {fire.length === 0 && ( +
  • + Systems Nominal +
  • + )} + {fire.map(alert => ( +
  • + {alert} +
  • + ))} +
+
+
+
    + {atmos.length === 0 && ( +
  • + Systems Nominal +
  • + )} + {atmos.map(alert => ( +
  • + {alert} +
  • + ))} +
+
+
+
    + {power.length === 0 && ( +
  • + Systems Nominal +
  • + )} + {power.map(alert => ( +
  • + {alert} +
  • + ))} +
+
+
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/SuitStorageUnit.js b/tgui-next/packages/tgui/interfaces/SuitStorageUnit.js new file mode 100644 index 0000000000..f858505a37 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/SuitStorageUnit.js @@ -0,0 +1,111 @@ +import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Box, Button, Icon, LabeledList, NoticeBox, Section } from '../components'; + +export const SuitStorageUnit = props => { + const { act, data } = useBackend(props); + const { + locked, + open, + safeties, + uv_active, + occupied, + suit, + helmet, + mask, + storage, + } = data; + return ( + + {!!(occupied && safeties) && ( + + Biological entity detected in suit chamber. Please remove + before continuing with operation. + + )} + {uv_active && ( + + Contents are currently being decontaminated. Please wait. + + ) || ( +
+ {!open && ( +
+ )} +
+ ); +}; diff --git a/tgui-next/packages/tgui/interfaces/SyndContractor.js b/tgui-next/packages/tgui/interfaces/SyndContractor.js new file mode 100644 index 0000000000..23f152a831 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/SyndContractor.js @@ -0,0 +1,382 @@ +import { Box, Button, Section, Dimmer, Table, Icon, NoticeBox, Tabs, Grid, LabeledList } from "../components"; +import { useBackend } from "../backend"; +import { Fragment, Component } from "inferno"; + +export class FakeTerminal extends Component { + constructor(props) { + super(props); + this.timer = null; + this.state = { + currentIndex: 0, + currentDisplay: [], + }; + } + + tick() { + const { props, state } = this; + if (state.currentIndex <= props.allMessages.length) { + this.setState(prevState => { + return ({ + currentIndex: prevState.currentIndex + 1, + }); + }); + const { currentDisplay } = state; + currentDisplay.push(props.allMessages[state.currentIndex]); + } else { + clearTimeout(this.timer); + setTimeout(props.onFinished, props.finishedTimeout); + } + } + + componentDidMount() { + const { + linesPerSecond = 2.5, + } = this.props; + this.timer = setInterval(() => this.tick(), 1000 / linesPerSecond); + } + + componentWillUnmount() { + clearTimeout(this.timer); + } + + render() { + return ( + + {this.state.currentDisplay.map(value => ( + + {value} +
+
+ ))} +
+ ); + } +} + +export const SyndContractor = props => { + const { data, act } = useBackend(props); + + const terminalMessages = [ + "Recording biometric data...", + "Analyzing embedded syndicate info...", + "STATUS CONFIRMED", + "Contacting syndicate database...", + "Awaiting response...", + "Awaiting response...", + "Awaiting response...", + "Awaiting response...", + "Awaiting response...", + "Awaiting response...", + "Response received, ack 4851234...", + "CONFIRM ACC " + (Math.round(Math.random() * 20000)), + "Setting up private accounts...", + "CONTRACTOR ACCOUNT CREATED", + "Searching for available contracts...", + "Searching for available contracts...", + "Searching for available contracts...", + "Searching for available contracts...", + "CONTRACTS FOUND", + "WELCOME, AGENT", + ]; + + const infoEntries = [ + "SyndTract v2.0", + "", + "We've identified potentional high-value targets that are", + "currently assigned to your mission area. They are believed", + "to hold valuable information which could be of immediate", + "importance to our organisation.", + "", + "Listed below are all of the contracts available to you. You", + "are to bring the specified target to the designated", + "drop-off, and contact us via this uplink. We will send", + "a specialised extraction unit to put the body into.", + "", + "We want targets alive - but we will sometimes pay slight", + "amounts if they're not, you just won't recieve the shown", + "bonus. You can redeem your payment through this uplink in", + "the form of raw telecrystals, which can be put into your", + "regular Syndicate uplink to purchase whatever you may need.", + "We provide you with these crystals the moment you send the", + "target up to us, which can be collected at anytime through", + "this system.", + "", + "Targets extracted will be ransomed back to the station once", + "their use to us is fulfilled, with us providing you a small", + "percentage cut. You may want to be mindful of them", + "identifying you when they come back. We provide you with", + "a standard contractor loadout, which will help cover your", + "identity.", + ]; + + const errorPane = !!data.error && ( + + + + + + + + + + {data.error} + +
+
+
+ ); + + if (!data.logged_in) { + return ( +
+ +
+ ); + } + + if (data.logged_in && data.first_load) { + return ( + + act('PRG_set_first_load_finished')} /> + + ); + } + + if (data.info_screen) { + return ( + + + + +