diff --git a/_maps/map_files/Cerestation/cerestation.dmm b/_maps/map_files/Cerestation/cerestation.dmm
index 0bcbf8da32..0df3264dce 100644
--- a/_maps/map_files/Cerestation/cerestation.dmm
+++ b/_maps/map_files/Cerestation/cerestation.dmm
@@ -1,5 +1,4 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
-//Model dictionary trimmed on: 12-05-2017 18:47 (UTC)
"aaa" = (
/turf/open/space,
/area/space)
@@ -46766,6 +46765,7 @@
})
"bCK" = (
/obj/effect/turf_decal/stripes/asteroid/line,
+/obj/machinery/atmospherics/pipe/simple/orange/visible,
/turf/open/floor/plating/astplate{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -46773,7 +46773,6 @@
name = "Central Asteroid Maintenance"
})
"bCL" = (
-/obj/machinery/atmospherics/pipe/simple/orange/hidden,
/obj/structure/rack,
/turf/open/floor/plating/astplate{
baseturf = /turf/open/floor/plating/asteroid/airless
@@ -47412,18 +47411,22 @@
density = 0;
layer = 4
},
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 6
+ },
/turf/closed/wall/r_wall{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bDX" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 6
- },
/obj/machinery/door/airlock/maintenance{
name = "Atmospehrics Maintenance";
req_access_txt = "12;24"
},
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/simple/orange/visible,
/turf/open/floor/plating{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -47977,6 +47980,7 @@
/area/hydroponics)
"bEY" = (
/obj/effect/turf_decal/delivery,
+/obj/machinery/portable_atmospherics/canister/air,
/turf/open/floor/plasteel/vault{
baseturf = /turf/open/floor/plating/asteroid/airless;
dir = 5
@@ -48011,21 +48015,26 @@
icon_state = "tube1";
dir = 8
},
+/obj/item/weapon/twohanded/required/kirbyplants{
+ tag = "icon-plant-21";
+ icon_state = "plant-21"
+ },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bFd" = (
/obj/structure/closet/firecloset/full,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bFe" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,
/obj/effect/turf_decal/stripes/line{
dir = 1
},
+/obj/machinery/atmospherics/pipe/simple/orange/visible,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -48036,7 +48045,6 @@
/obj/item/stack/rods{
amount = 50
},
-/obj/machinery/atmospherics/pipe/simple/orange/visible,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -48063,6 +48071,11 @@
/obj/structure/table,
/obj/item/weapon/grenade/chem_grenade/metalfoam,
/obj/item/weapon/grenade/chem_grenade/metalfoam,
+/obj/machinery/airalarm{
+ frequency = 1439;
+ locked = 0;
+ pixel_y = 23
+ },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -49042,6 +49055,10 @@
icon_state = "1-2";
pixel_y = 0
},
+/obj/machinery/atmospherics/components/unary/vent_pump{
+ dir = 4;
+ on = 1
+ },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -49051,6 +49068,10 @@
dir = 4
},
/obj/effect/landmark/start/atmospheric_technician,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ icon_state = "intact";
+ dir = 8
+ },
/turf/open/floor/plasteel/yellow/side{
tag = "icon-yellow (EAST)";
icon_state = "yellow";
@@ -49065,13 +49086,22 @@
id = "atmodesk"
},
/obj/machinery/door/window/eastright{
+ name = "Atmospherics Desk";
req_access_txt = "24"
},
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ icon_state = "intact";
+ dir = 8
+ },
/turf/open/floor/plasteel/yellow{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bGU" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ icon_state = "intact";
+ dir = 8
+ },
/turf/open/floor/plasteel/yellow/side{
tag = "icon-yellow (WEST)";
icon_state = "yellow";
@@ -49091,13 +49121,11 @@
icon_state = "1-2";
pixel_y = 0
},
-/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
- dir = 8
- },
/obj/structure/disposalpipe/segment{
dir = 4;
icon_state = "pipe-c"
},
+/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -50714,6 +50742,7 @@
icon_state = "camera";
network = list("SS13","CE")
},
+/obj/machinery/portable_atmospherics/scrubber,
/turf/open/floor/plasteel/vault{
baseturf = /turf/open/floor/plating/asteroid/airless;
dir = 5
@@ -50744,16 +50773,19 @@
},
/area/atmos)
"bJM" = (
-/obj/machinery/atmospherics/pipe/simple/orange/visible{
- dir = 5
+/obj/machinery/atmospherics/components/unary/vent_scrubber{
+ dir = 4;
+ on = 1;
+ scrub_N2O = 0;
+ scrub_Toxins = 0
},
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bJN" = (
-/obj/machinery/atmospherics/pipe/simple/orange/visible{
- dir = 10
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
},
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
@@ -51249,31 +51281,30 @@
name = "Lounge"
})
"bKF" = (
-/obj/structure/extinguisher_cabinet{
- pixel_x = -24
- },
-/turf/open/floor/plasteel/yellow/side{
- baseturf = /turf/open/floor/plating/asteroid/airless
+/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/visible,
+/obj/machinery/meter,
+/turf/open/floor/plasteel/yellow/corner{
+ dir = 8
},
/area/atmos)
"bKG" = (
-/obj/structure/window/reinforced,
-/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{
+/obj/machinery/atmospherics/pipe/simple/orange/visible,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{
+ icon_state = "intact";
dir = 8
},
-/turf/open/floor/plasteel/yellow/side{
+/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bKH" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
+/obj/effect/landmark/lightsout,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{
+ dir = 10;
icon_state = "intact";
- dir = 10
+ tag = "icon-intact (SOUTHEAST)"
},
-/turf/open/floor/plasteel/yellow/corner{
- tag = "icon-yellowcorner (WEST)";
- icon_state = "yellowcorner";
- dir = 8;
+/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
@@ -51306,6 +51337,8 @@
icon_state = "camera";
network = list("SS13","CE")
},
+/obj/structure/closet/secure_closet/atmospherics,
+/obj/item/weapon/pickaxe/mini,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -51964,7 +51997,11 @@
},
/area/atmos)
"bLV" = (
-/obj/machinery/pipedispenser/disposal/transit_tube,
+/obj/machinery/door/window/eastright{
+ dir = 1;
+ name = "Interior Pipe Access";
+ req_access_txt = "24"
+ },
/turf/open/floor/plasteel/black{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -51975,16 +52012,14 @@
},
/area/atmos)
"bLX" = (
-/obj/structure/window/reinforced{
- dir = 4
- },
/obj/machinery/atmospherics/components/binary/pump{
- dir = 2;
- name = "Waste To Filter";
- on = 1
+ dir = 1;
+ name = "Mix To Engine";
+ on = 0;
+ target_pressure = 101
},
-/turf/open/floor/plasteel/black{
- baseturf = /turf/open/floor/plating/asteroid/airless
+/turf/open/floor/plasteel/yellow/corner{
+ dir = 8
},
/area/atmos)
"bLY" = (
@@ -52015,6 +52050,8 @@
pixel_x = 30;
pixel_y = 0
},
+/obj/structure/closet/secure_closet/atmospherics,
+/obj/item/weapon/pickaxe/mini,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -53034,6 +53071,8 @@
dir = 4;
icon_state = "tube1"
},
+/obj/machinery/disposal/bin,
+/obj/structure/disposalpipe/trunk,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -53546,23 +53585,8 @@
/turf/open/floor/plating,
/area/atmos)
"bOv" = (
-/obj/machinery/computer/atmos_control/tank{
- frequency = 1441;
- input_tag = "n2_in";
- name = "Nitrogen Supply Control";
- output_tag = "n2_out";
- sensors = list("n2_sensor" = "Tank")
- },
-/obj/machinery/atmospherics/pipe/simple/green/visible,
-/turf/open/floor/plasteel/black{
- baseturf = /turf/open/floor/plating/asteroid/airless
- },
-/area/atmos)
-"bOw" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- icon_state = "intact";
- dir = 5
- },
+/obj/machinery/atmospherics/pipe/simple/yellow/visible,
+/obj/machinery/meter,
/turf/open/floor/plasteel/yellow/side{
tag = "icon-yellow (WEST)";
icon_state = "yellow";
@@ -53570,17 +53594,31 @@
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
+"bOw" = (
+/obj/machinery/atmospherics/pipe/simple/general/visible{
+ dir = 5
+ },
+/obj/machinery/meter,
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
"bOx" = (
-/obj/machinery/atmospherics/pipe/manifold/yellow/visible,
+/obj/machinery/atmospherics/pipe/simple/general/visible{
+ dir = 10;
+ pixel_x = 0;
+ initialize_directions = 10
+ },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bOy" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- dir = 4
- },
-/turf/open/floor/plasteel{
+/obj/machinery/atmospherics/pipe/simple/general/visible,
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (WEST)";
+ icon_state = "yellow";
+ dir = 8;
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
@@ -53590,9 +53628,11 @@
d2 = 4;
icon_state = "1-4"
},
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- dir = 4
+/obj/structure/disposalpipe/segment{
+ dir = 1;
+ icon_state = "pipe-c"
},
+/obj/structure/chair/stool/bar,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -53603,9 +53643,12 @@
d2 = 8;
icon_state = "4-8"
},
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
+/obj/structure/disposalpipe/segment{
dir = 4
},
+/obj/structure/table,
+/obj/item/weapon/storage/fancy/cigarettes,
+/obj/item/weapon/lighter/greyscale,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -53616,14 +53659,15 @@
d2 = 8;
icon_state = "4-8"
},
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- dir = 4
- },
/obj/item/device/radio/intercom{
broadcasting = 0;
name = "Station Intercom (General)";
pixel_y = 20
},
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/chair/stool/bar,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -53634,13 +53678,12 @@
d2 = 8;
icon_state = "4-8"
},
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- icon_state = "intact";
- dir = 10
- },
/obj/structure/sign/atmosplaque{
pixel_y = 32
},
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -53651,11 +53694,11 @@
d2 = 8;
icon_state = "1-8"
},
-/obj/machinery/atmospherics/pipe/simple/supply/visible,
/obj/structure/disposalpipe/segment{
- dir = 1;
+ dir = 8;
icon_state = "pipe-c"
},
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -54301,14 +54344,6 @@
},
/area/atmos)
"bPC" = (
-/obj/machinery/atmospherics/pipe/simple/general/visible{
- dir = 4
- },
-/turf/open/floor/plasteel/black{
- baseturf = /turf/open/floor/plating/asteroid/airless
- },
-/area/atmos)
-"bPD" = (
/obj/machinery/atmospherics/pipe/simple/green/visible,
/obj/machinery/atmospherics/components/binary/pump{
dir = 4;
@@ -54316,9 +54351,19 @@
on = 1
},
/obj/structure/window/reinforced{
+ dir = 8
+ },
+/turf/open/floor/plasteel/red,
+/area/atmos)
+"bPD" = (
+/obj/machinery/atmospherics/pipe/simple/cyan/visible{
dir = 4
},
-/turf/open/floor/plasteel/black{
+/obj/machinery/atmospherics/pipe/simple/yellow/visible,
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (WEST)";
+ icon_state = "yellow";
+ dir = 8;
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
@@ -54382,7 +54427,9 @@
},
/area/atmos)
"bPL" = (
-/obj/structure/disposalpipe/segment,
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 10
+ },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -54973,9 +55020,9 @@
/area/atmos)
"bQG" = (
/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- icon_state = "intact";
- dir = 10
+ dir = 4
},
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel/yellow/side{
tag = "icon-yellow (WEST)";
icon_state = "yellow";
@@ -54990,12 +55037,11 @@
},
/area/atmos)
"bQI" = (
-/obj/structure/closet/secure_closet/atmospherics,
-/obj/item/weapon/pickaxe/mini,
-/turf/open/floor/plasteel/yellow/side{
- tag = "icon-yellow (EAST)";
- icon_state = "yellow";
- dir = 4;
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 8;
+ name = "North Canister to Waste"
+ },
+/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
@@ -55008,13 +55054,11 @@
},
/area/atmos)
"bQK" = (
-/obj/machinery/atmospherics/components/unary/portables_connector/visible{
- tag = "icon-connector_map (EAST)";
- icon_state = "connector_map";
- dir = 4
+/obj/machinery/atmospherics/pipe/manifold/general/visible{
+ dir = 1
},
-/obj/machinery/portable_atmospherics/canister,
-/turf/open/floor/plasteel/delivery{
+/obj/machinery/meter,
+/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
@@ -55042,10 +55086,7 @@
/obj/structure/fireaxecabinet{
pixel_x = 32
},
-/obj/machinery/disposal/bin,
-/obj/structure/disposalpipe/trunk{
- dir = 1
- },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -55530,8 +55571,9 @@
},
/area/atmos)
"bRI" = (
-/obj/machinery/atmospherics/pipe/manifold4w/yellow/visible,
-/obj/machinery/meter,
+/obj/machinery/atmospherics/pipe/manifold/general/visible{
+ dir = 1
+ },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -55548,22 +55590,17 @@
/obj/machinery/light{
dir = 1
},
-/obj/machinery/atmospherics/components/unary/portables_connector/visible{
- tag = "icon-connector_map (EAST)";
- icon_state = "connector_map";
- dir = 4
- },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bRL" = (
-/obj/machinery/meter,
-/obj/machinery/atmospherics/pipe/simple/cyan/visible{
- tag = "icon-intact (WEST)";
- icon_state = "intact";
- dir = 8
+/obj/machinery/atmospherics/components/unary/portables_connector/visible{
+ tag = "icon-connector_map (EAST)";
+ icon_state = "connector_map";
+ dir = 4
},
+/obj/machinery/portable_atmospherics/pump,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -55574,6 +55611,7 @@
icon_state = "intact";
dir = 8
},
+/obj/machinery/meter,
/turf/open/floor/plasteel/yellow/side{
tag = "icon-yellow (EAST)";
icon_state = "yellow";
@@ -55595,6 +55633,7 @@
/area/atmos)
"bRO" = (
/obj/machinery/portable_atmospherics/canister,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel/yellow/side{
tag = "icon-yellow (WEST)";
icon_state = "yellow";
@@ -55603,9 +55642,7 @@
},
/area/atmos)
"bRP" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{
- tag = "icon-intact (SOUTHEAST)";
- icon_state = "intact";
+/obj/machinery/atmospherics/pipe/simple/yellow/visible{
dir = 6
},
/turf/open/floor/plasteel{
@@ -55614,8 +55651,8 @@
/area/atmos)
"bRQ" = (
/obj/machinery/atmospherics/components/binary/pump{
- dir = 8;
- name = "Waste to Filter";
+ dir = 4;
+ name = "Filter to Waste";
on = 1
},
/turf/open/floor/plasteel{
@@ -56039,19 +56076,16 @@
},
/area/atmos)
"bSI" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- dir = 9
+/obj/machinery/atmospherics/components/unary/portables_connector/visible{
+ dir = 1
},
-/turf/open/floor/plasteel{
+/turf/open/floor/plasteel/delivery{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bSJ" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- icon_state = "intact";
- dir = 5
- },
-/turf/open/floor/plasteel{
+/obj/machinery/pipedispenser/disposal,
+/turf/open/floor/plasteel/yellow/corner{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
@@ -56064,19 +56098,18 @@
},
/area/atmos)
"bSL" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- dir = 4
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 8;
+ name = "Pure To Canisters";
+ on = 0
},
-/obj/machinery/meter,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bSM" = (
-/obj/machinery/atmospherics/components/binary/pump{
- dir = 8;
- name = "Mix To Canisters";
- on = 0
+/obj/machinery/atmospherics/pipe/simple/yellow/visible{
+ dir = 4
},
/turf/open/floor/plasteel/yellow/side{
tag = "icon-yellow (EAST)";
@@ -56099,11 +56132,8 @@
},
/area/atmos)
"bSO" = (
-/obj/machinery/atmospherics/components/binary/pump{
- dir = 2;
- name = "Mix to Filter";
- on = 1
- },
+/obj/machinery/atmospherics/pipe/manifold/yellow/visible,
+/obj/machinery/meter,
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -56503,11 +56533,7 @@
},
/area/atmos)
"bTA" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- tag = "icon-intact (NORTHEAST)";
- icon_state = "intact";
- dir = 5
- },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel/yellow/side{
tag = "icon-yellow (WEST)";
icon_state = "yellow";
@@ -56747,13 +56773,20 @@
/area/atmos)
"bTZ" = (
/obj/effect/landmark/event_spawn,
+/obj/machinery/atmospherics/components/unary/vent_scrubber{
+ dir = 4;
+ on = 1;
+ scrub_N2O = 0;
+ scrub_Toxins = 0
+ },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bUa" = (
-/obj/machinery/atmospherics/pipe/manifold/yellow/visible{
- dir = 8
+/obj/machinery/atmospherics/pipe/simple/yellow/visible,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
},
/turf/open/floor/plasteel/yellow/side{
tag = "icon-yellow (EAST)";
@@ -57157,16 +57190,16 @@
},
/area/atmos)
"bUL" = (
-/obj/machinery/atmospherics/pipe/simple/green/visible,
+/obj/machinery/atmospherics/pipe/simple/yellow/visible,
/obj/machinery/atmospherics/pipe/simple/cyan/visible{
tag = "icon-intact (WEST)";
icon_state = "intact";
dir = 8
},
-/obj/structure/window/reinforced{
- dir = 8
- },
-/turf/open/floor/plasteel/yellow{
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (WEST)";
+ icon_state = "yellow";
+ dir = 8;
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
@@ -57185,20 +57218,16 @@
},
/area/atmos)
"bUN" = (
-/obj/machinery/atmospherics/pipe/simple/cyan/visible{
- tag = "icon-intact (NORTHWEST)";
- icon_state = "intact";
- dir = 9
+/obj/machinery/atmospherics/pipe/simple/general/visible{
+ dir = 5
},
-/turf/open/floor/plasteel/yellow/side{
+/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bUO" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- dir = 6
- },
-/turf/open/floor/plasteel/yellow/side{
+/obj/machinery/atmospherics/pipe/manifold/general/visible,
+/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
@@ -57262,6 +57291,10 @@
dir = 4;
icon_state = "tube1"
},
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ icon_state = "intact";
+ dir = 4
+ },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -57451,32 +57484,22 @@
},
/area/atmos)
"bVt" = (
-/obj/machinery/computer/atmos_control/tank{
- frequency = 1441;
- input_tag = "air_in";
- name = "Mixed Air Supply Control";
- output_tag = "air_out";
- sensors = list("air_sensor" = "Tank")
+/obj/machinery/atmospherics/pipe/manifold/yellow/visible{
+ dir = 8
},
-/obj/machinery/atmospherics/pipe/simple/green/visible{
- tag = "icon-intact (NORTHEAST)";
- icon_state = "intact";
- dir = 5
- },
-/turf/open/floor/plasteel/vault{
- baseturf = /turf/open/floor/plating/asteroid/airless;
- dir = 5
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (SOUTHWEST)";
+ icon_state = "yellow";
+ dir = 10;
+ baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bVu" = (
-/obj/machinery/atmospherics/pipe/simple/green/visible{
- tag = "icon-intact (WEST)";
+/obj/machinery/atmospherics/pipe/simple/yellow/visible{
icon_state = "intact";
dir = 8
},
-/obj/machinery/atmospherics/pipe/simple/yellow/visible,
-/obj/structure/window/reinforced,
-/turf/open/floor/plasteel/yellow{
+/turf/open/floor/plasteel/yellow/side{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
@@ -57532,14 +57555,11 @@
},
/area/atmos)
"bVy" = (
-/obj/machinery/atmospherics/pipe/simple/green/visible{
+/obj/machinery/atmospherics/pipe/simple/yellow/visible{
dir = 4
},
-/obj/structure/window/reinforced{
- dir = 1;
- layer = 2.9
- },
-/turf/open/floor/plasteel/black{
+/obj/machinery/atmospherics/pipe/simple/general/visible,
+/turf/open/floor/plasteel/yellow/side{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
@@ -57939,75 +57959,129 @@
},
/area/atmos)
"bWe" = (
-/obj/machinery/atmospherics/pipe/manifold/cyan/visible{
- dir = 1;
- initialize_directions = 11
+/obj/machinery/atmospherics/pipe/simple/cyan/visible{
+ dir = 10;
+ initialize_directions = 10
},
/turf/open/floor/plasteel/black{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bWf" = (
-/obj/machinery/atmospherics/components/binary/pump{
- dir = 4;
- name = "Air to Pure"
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ tag = "icon-intact (NORTHEAST)";
+ icon_state = "intact";
+ dir = 5
},
-/turf/open/floor/plasteel/black{
- baseturf = /turf/open/floor/plating/asteroid/airless
+/obj/structure/window/reinforced{
+ dir = 8
},
+/obj/structure/window/reinforced,
+/obj/structure/table,
+/obj/item/weapon/paper_bin{
+ pixel_x = -3;
+ pixel_y = 7
+ },
+/turf/open/floor/plasteel/barber,
/area/atmos)
"bWg" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
+/obj/machinery/atmospherics/pipe/simple/green/visible{
tag = "icon-intact (WEST)";
icon_state = "intact";
dir = 8
},
-/turf/open/floor/plasteel/black{
- baseturf = /turf/open/floor/plating/asteroid/airless
+/obj/structure/window/reinforced,
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 1;
+ name = "Air to Pure";
+ on = 0
},
+/turf/open/floor/plasteel/barber,
/area/atmos)
"bWh" = (
-/obj/machinery/atmospherics/pipe/manifold/yellow/visible,
-/obj/machinery/meter,
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ dir = 4
+ },
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/obj/structure/window/reinforced{
+ dir = 4
+ },
+/obj/machinery/door/window/eastright{
+ dir = 1;
+ name = "Interior Pipe Access";
+ req_access_txt = "24"
+ },
/turf/open/floor/plasteel/black{
baseturf = /turf/open/floor/plating/asteroid/airless
},
/area/atmos)
"bWi" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- tag = "icon-intact (WEST)";
- icon_state = "intact";
- dir = 8
+/obj/machinery/atmospherics/components/trinary/filter{
+ dir = 4;
+ filter_type = "co2";
+ name = "co2 filter";
+ on = 1
},
-/obj/machinery/atmospherics/pipe/simple/green/visible,
-/turf/open/floor/plasteel/black{
- baseturf = /turf/open/floor/plating/asteroid/airless
+/obj/structure/window/reinforced,
+/turf/open/floor/plasteel/vault{
+ initial_gas_mix = "n2=100;TEMP=80";
+ temperature = 80
},
/area/atmos)
"bWj" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible{
- tag = "icon-intact (NORTHWEST)";
- icon_state = "intact";
- dir = 9
+/obj/machinery/computer/atmos_control/tank{
+ frequency = 1441;
+ input_tag = "co2_in";
+ name = "Carbon Dioxide Supply Control";
+ output_tag = "co2_out";
+ sensors = list("co2_sensor" = "Tank")
},
-/turf/open/floor/plasteel/black{
- baseturf = /turf/open/floor/plating/asteroid/airless
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ dir = 4
+ },
+/obj/structure/window/reinforced,
+/turf/open/floor/plasteel/vault{
+ dir = 5;
+ initial_gas_mix = "n2=500;TEMP=80";
+ temperature = 80
},
/area/atmos)
"bWk" = (
-/obj/machinery/atmospherics/pipe/simple/yellow/visible,
-/turf/open/floor/plasteel/black{
- baseturf = /turf/open/floor/plating/asteroid/airless
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ dir = 4
+ },
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 1;
+ name = "CO2 to Pure";
+ on = 0
+ },
+/obj/structure/window/reinforced,
+/turf/open/floor/plasteel/vault{
+ initial_gas_mix = "n2=100;TEMP=80";
+ temperature = 80
},
/area/atmos)
"bWl" = (
-/obj/machinery/atmospherics/pipe/simple/green/visible,
-/turf/open/floor/plasteel/black{
- baseturf = /turf/open/floor/plating/asteroid/airless
+/obj/machinery/atmospherics/components/trinary/filter{
+ dir = 4;
+ filter_type = "plasma";
+ name = "plasma filter";
+ on = 1
},
+/obj/structure/window/reinforced,
+/turf/open/floor/plasteel/purple,
/area/atmos)
"bWm" = (
-/obj/machinery/atmospherics/pipe/simple/green/visible,
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ dir = 4
+ },
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 2;
+ name = "Unfiltered to Mix";
+ on = 1
+ },
/turf/open/floor/plasteel/yellow/side{
tag = "icon-yellow (WEST)";
icon_state = "yellow";
@@ -58019,6 +58093,11 @@
/obj/structure/extinguisher_cabinet{
pixel_x = 24
},
+/obj/machinery/atmospherics/pipe/simple/cyan/visible{
+ tag = "icon-intact (NORTHWEST)";
+ icon_state = "intact";
+ dir = 9
+ },
/turf/open/floor/plasteel{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -58219,7 +58298,6 @@
/obj/machinery/light{
dir = 8
},
-/obj/machinery/pipedispenser/disposal,
/turf/open/floor/plasteel/black{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -58251,15 +58329,13 @@
},
/area/atmos)
"bWJ" = (
-/obj/machinery/atmospherics/pipe/simple/cyan/visible{
- dir = 4
- },
/obj/machinery/camera{
c_tag = "Atmoshperic Tanks 1";
dir = 1;
icon_state = "camera";
network = list("SS13","CE")
},
+/obj/machinery/atmospherics/pipe/manifold/cyan/visible,
/turf/open/floor/plasteel/black{
baseturf = /turf/open/floor/plating/asteroid/airless
},
@@ -79479,9 +79555,9 @@
},
/area/crew_quarters/fitness)
"cHs" = (
-/obj/effect/landmark/start/atmospheric_technician,
-/turf/open/floor/plasteel{
- baseturf = /turf/open/floor/plating/asteroid/airless
+/obj/machinery/pipedispenser/disposal/transit_tube,
+/turf/open/floor/plasteel/yellow/corner{
+ dir = 4
},
/area/atmos)
"cHt" = (
@@ -91948,6 +92024,754 @@
/area/maintenance/port{
name = "Port Asteroid Maintenance"
})
+"deK" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ icon_state = "intact";
+ dir = 8
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"deL" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ icon_state = "intact";
+ dir = 8
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"deM" = (
+/obj/structure/extinguisher_cabinet{
+ pixel_x = -24
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"deN" = (
+/obj/machinery/atmospherics/pipe/simple/orange/visible,
+/obj/machinery/meter,
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"deO" = (
+/obj/structure/cable{
+ d1 = 1;
+ d2 = 2;
+ icon_state = "1-2";
+ pixel_y = 0
+ },
+/obj/structure/closet/secure_closet/atmospherics,
+/obj/item/weapon/pickaxe/mini,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"deP" = (
+/obj/machinery/atmospherics/components/unary/outlet_injector/on{
+ dir = 4;
+ frequency = 1441;
+ id = "n2_in"
+ },
+/obj/structure/lattice/catwalk,
+/turf/open/space/basic,
+/area/maintenance/maintcentral{
+ name = "Central Asteroid Maintenance"
+ })
+"deQ" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/closed/mineral,
+/area/maintenance/maintcentral{
+ name = "Central Asteroid Maintenance"
+ })
+"deR" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/closed/mineral,
+/area/maintenance/maintcentral{
+ name = "Central Asteroid Maintenance"
+ })
+"deS" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/closed/mineral,
+/area/maintenance/maintcentral{
+ name = "Central Asteroid Maintenance"
+ })
+"deT" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/closed/mineral,
+/area/maintenance/maintcentral{
+ name = "Central Asteroid Maintenance"
+ })
+"deU" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/closed/mineral/random/labormineral,
+/area/maintenance/maintcentral{
+ name = "Central Asteroid Maintenance"
+ })
+"deV" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/closed/wall{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/maintenance/maintcentral{
+ name = "Central Asteroid Maintenance"
+ })
+"deW" = (
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/maintenance/maintcentral{
+ name = "Central Asteroid Maintenance"
+ })
+"deX" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/simple/orange/hidden,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/maintenance/maintcentral{
+ name = "Central Asteroid Maintenance"
+ })
+"deY" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/obj/machinery/portable_atmospherics/scrubber/huge,
+/turf/open/floor/plasteel/vault{
+ baseturf = /turf/open/floor/plating/asteroid/airless;
+ dir = 5
+ },
+/area/atmos)
+"deZ" = (
+/obj/machinery/portable_atmospherics/canister/carbon_dioxide,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plasteel/vault{
+ baseturf = /turf/open/floor/plating/asteroid/airless;
+ dir = 5
+ },
+/area/atmos)
+"dfa" = (
+/obj/machinery/portable_atmospherics/canister/nitrous_oxide,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plasteel/vault{
+ baseturf = /turf/open/floor/plating/asteroid/airless;
+ dir = 5
+ },
+/area/atmos)
+"dfb" = (
+/obj/machinery/portable_atmospherics/canister/nitrogen,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plasteel/vault{
+ baseturf = /turf/open/floor/plating/asteroid/airless;
+ dir = 5
+ },
+/area/atmos)
+"dfc" = (
+/obj/machinery/atmospherics/components/binary/valve/digital{
+ dir = 4;
+ name = "Waste Release"
+ },
+/turf/open/floor/plasteel/yellow/side{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfd" = (
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/visible,
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (SOUTHWEST)";
+ icon_state = "yellow";
+ dir = 10;
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfe" = (
+/obj/machinery/atmospherics/components/trinary/filter{
+ dir = 2;
+ filter_type = "n2";
+ name = "nitogren filter";
+ on = 1
+ },
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/turf/open/floor/plasteel/red,
+/area/atmos)
+"dff" = (
+/obj/machinery/atmospherics/pipe/simple/general/visible,
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfg" = (
+/obj/structure/sign/nosmoking_2,
+/turf/closed/wall/r_wall{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfh" = (
+/obj/machinery/computer/atmos_control/tank{
+ frequency = 1441;
+ input_tag = "n2_in";
+ name = "Nitrogen Supply Control";
+ output_tag = "n2_out";
+ sensors = list("n2_sensor" = "Tank")
+ },
+/obj/machinery/atmospherics/pipe/simple/green/visible,
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/turf/open/floor/plasteel/red,
+/area/atmos)
+"dfi" = (
+/obj/machinery/atmospherics/pipe/simple/general/visible,
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfj" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 5
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfk" = (
+/obj/machinery/atmospherics/pipe/simple/green/visible,
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 4;
+ name = "N2 to Pure"
+ },
+/obj/structure/window/reinforced{
+ dir = 1;
+ layer = 2.9
+ },
+/obj/structure/window/reinforced,
+/obj/machinery/door/window/eastright{
+ name = "Interior Pipe Access";
+ req_access_txt = "24"
+ },
+/turf/open/floor/plasteel/black{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfl" = (
+/obj/machinery/atmospherics/pipe/simple/general/visible,
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfm" = (
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
+ dir = 1
+ },
+/turf/closed/wall{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/crew_quarters/chief)
+"dfn" = (
+/obj/machinery/atmospherics/components/trinary/filter{
+ dir = 2;
+ filter_type = "o2";
+ name = "oxygen filter";
+ on = 1
+ },
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/turf/open/floor/plasteel/blue,
+/area/atmos)
+"dfo" = (
+/obj/machinery/atmospherics/pipe/manifold/general/visible{
+ dir = 8
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfp" = (
+/obj/machinery/atmospherics/pipe/manifold/general/visible{
+ dir = 1
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfq" = (
+/obj/machinery/atmospherics/pipe/simple/general/visible{
+ dir = 10
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfr" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfs" = (
+/obj/machinery/computer/atmos_control/tank{
+ frequency = 1441;
+ input_tag = "o2_in";
+ name = "Oxygen Supply Control";
+ output_tag = "o2_out";
+ sensors = list("o2_sensor" = "Tank")
+ },
+/obj/machinery/atmospherics/pipe/simple/green/visible,
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/turf/open/floor/plasteel/blue,
+/area/atmos)
+"dft" = (
+/obj/machinery/atmospherics/pipe/simple/general/visible,
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (EAST)";
+ icon_state = "yellow";
+ dir = 4
+ },
+/area/atmos)
+"dfu" = (
+/obj/machinery/pipedispenser,
+/obj/machinery/light,
+/turf/open/floor/plasteel/yellow/corner{
+ tag = "icon-yellowcorner (WEST)";
+ icon_state = "yellowcorner";
+ dir = 8
+ },
+/area/atmos)
+"dfv" = (
+/obj/machinery/atmospherics/components/unary/portables_connector/visible{
+ dir = 1
+ },
+/turf/open/floor/plasteel/delivery{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfw" = (
+/obj/machinery/atmospherics/components/unary/portables_connector/visible{
+ dir = 1
+ },
+/turf/open/floor/plasteel/delivery{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfx" = (
+/obj/machinery/atmospherics/pipe/simple/general/visible{
+ icon_state = "intact";
+ dir = 6
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfy" = (
+/obj/machinery/atmospherics/pipe/simple/green/visible,
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 4;
+ name = "O2 to Airmix";
+ on = 1
+ },
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/turf/open/floor/plasteel/blue,
+/area/atmos)
+"dfz" = (
+/obj/machinery/atmospherics/pipe/simple/general/visible,
+/obj/machinery/camera{
+ c_tag = "Atmospherics Distro";
+ dir = 9;
+ icon_state = "camera";
+ network = list("SS13","CE")
+ },
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (EAST)";
+ icon_state = "yellow";
+ dir = 4
+ },
+/area/atmos)
+"dfA" = (
+/obj/structure/sign/poster/official/safety_internals,
+/turf/closed/wall,
+/area/atmos)
+"dfB" = (
+/obj/machinery/camera{
+ c_tag = "Atmospherics South";
+ dir = 4;
+ icon_state = "camera";
+ network = list("SS13","CE")
+ },
+/obj/machinery/atmospherics/pipe/manifold/general/visible{
+ dir = 8
+ },
+/obj/machinery/meter,
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (WEST)";
+ icon_state = "yellow";
+ dir = 8;
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfC" = (
+/obj/machinery/atmospherics/pipe/simple/general/visible{
+ icon_state = "intact";
+ dir = 4
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfD" = (
+/obj/machinery/atmospherics/pipe/manifold/general/visible,
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfE" = (
+/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
+ dir = 4;
+ initialize_directions = 11
+ },
+/turf/closed/wall/r_wall{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfF" = (
+/obj/machinery/atmospherics/pipe/simple/green/visible,
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 4;
+ name = "O2 to Pure"
+ },
+/obj/structure/window/reinforced{
+ dir = 1;
+ layer = 2.9
+ },
+/obj/structure/window/reinforced,
+/obj/machinery/door/window/eastright{
+ name = "Interior Pipe Access";
+ req_access_txt = "24"
+ },
+/turf/open/floor/plasteel/black{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfG" = (
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 1;
+ name = "South Canister To Waste";
+ on = 0;
+ target_pressure = 101
+ },
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (EAST)";
+ icon_state = "yellow";
+ dir = 4
+ },
+/area/atmos)
+"dfH" = (
+/obj/machinery/atmospherics/components/unary/thermomachine/freezer,
+/obj/machinery/light{
+ dir = 1
+ },
+/turf/open/floor/plasteel/yellow/corner{
+ dir = 1
+ },
+/area/atmos)
+"dfI" = (
+/obj/machinery/portable_atmospherics/canister,
+/obj/machinery/atmospherics/components/unary/portables_connector/visible,
+/turf/open/floor/plasteel/delivery{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfJ" = (
+/obj/machinery/portable_atmospherics/canister,
+/obj/machinery/atmospherics/components/unary/portables_connector/visible,
+/turf/open/floor/plasteel/delivery{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfK" = (
+/obj/machinery/portable_atmospherics/canister,
+/obj/machinery/atmospherics/components/unary/portables_connector/visible,
+/turf/open/floor/plasteel/delivery{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfL" = (
+/obj/effect/landmark/start/atmospheric_technician,
+/obj/machinery/atmospherics/pipe/simple/general/visible,
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (WEST)";
+ icon_state = "yellow";
+ dir = 8;
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfM" = (
+/obj/machinery/atmospherics/pipe/simple/cyan/visible,
+/obj/structure/grille,
+/obj/structure/window/reinforced/fulltile,
+/obj/machinery/door/firedoor,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plating{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfN" = (
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (WEST)";
+ icon_state = "yellow";
+ dir = 8;
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfO" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber{
+ dir = 8;
+ on = 1;
+ scrub_Toxins = 0
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfP" = (
+/obj/machinery/status_display{
+ density = 0;
+ layer = 4
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/turf/closed/wall/r_wall{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfQ" = (
+/obj/machinery/atmospherics/pipe/simple/green/visible,
+/obj/machinery/atmospherics/pipe/simple/cyan/visible{
+ tag = "icon-intact (WEST)";
+ icon_state = "intact";
+ dir = 8
+ },
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/turf/open/floor/plasteel/barber,
+/area/atmos)
+"dfR" = (
+/obj/machinery/atmospherics/pipe/manifold4w/general/visible,
+/obj/machinery/meter,
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfS" = (
+/obj/machinery/atmospherics/pipe/simple/general/visible{
+ dir = 9
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfT" = (
+/obj/machinery/atmospherics/pipe/manifold/yellow/visible{
+ dir = 8
+ },
+/obj/machinery/meter,
+/turf/open/floor/plasteel/yellow/side{
+ tag = "icon-yellow (EAST)";
+ icon_state = "yellow";
+ dir = 4;
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfU" = (
+/obj/machinery/atmospherics/components/unary/vent_pump{
+ dir = 4;
+ on = 1
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfV" = (
+/obj/machinery/computer/atmos_control/tank{
+ frequency = 1441;
+ input_tag = "air_in";
+ name = "Mixed Air Supply Control";
+ output_tag = "air_out";
+ sensors = list("air_sensor" = "Tank")
+ },
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/simple/green/visible,
+/turf/open/floor/plasteel/barber,
+/area/atmos)
+"dfW" = (
+/obj/machinery/atmospherics/pipe/simple/cyan/visible,
+/obj/machinery/airalarm{
+ dir = 8;
+ icon_state = "alarm0";
+ pixel_x = 24
+ },
+/turf/open/floor/plasteel{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfX" = (
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ dir = 4
+ },
+/obj/structure/window/reinforced{
+ dir = 8
+ },
+/obj/structure/window/reinforced{
+ dir = 4
+ },
+/obj/machinery/door/window/eastright{
+ dir = 1;
+ name = "Interior Pipe Access";
+ req_access_txt = "24"
+ },
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 1;
+ name = "Air to South Canister";
+ on = 0
+ },
+/turf/open/floor/plasteel/black{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dfY" = (
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ dir = 4
+ },
+/obj/machinery/computer/atmos_control/tank{
+ frequency = 1441;
+ input_tag = "tox_in";
+ name = "Plasma Supply Control";
+ output_tag = "tox_out";
+ sensors = list("tox_sensor" = "Tank")
+ },
+/obj/structure/window/reinforced,
+/turf/open/floor/plasteel/purple,
+/area/atmos)
+"dfZ" = (
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ dir = 4
+ },
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 1;
+ name = "Plasma to Pure";
+ on = 0
+ },
+/obj/structure/window/reinforced,
+/turf/open/floor/plasteel/purple,
+/area/atmos)
+"dga" = (
+/obj/machinery/atmospherics/components/trinary/filter{
+ dir = 4;
+ filter_type = "n2";
+ name = "nitogren filter";
+ on = 1
+ },
+/obj/structure/window/reinforced,
+/turf/open/floor/plasteel/escape{
+ dir = 10
+ },
+/area/atmos)
+"dgb" = (
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ dir = 4
+ },
+/obj/machinery/computer/atmos_control/tank{
+ frequency = 1441;
+ input_tag = "n2o_in";
+ name = "Nitrous Oxide Supply Control";
+ output_tag = "n2o_out";
+ sensors = list("n2o_sensor" = "Tank")
+ },
+/obj/structure/window/reinforced,
+/turf/open/floor/plasteel/escape,
+/area/atmos)
+"dgc" = (
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ dir = 4
+ },
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 1;
+ name = "N2O to Pure";
+ on = 0
+ },
+/obj/structure/window/reinforced,
+/turf/open/floor/plasteel/escape{
+ dir = 6
+ },
+/area/atmos)
+"dgd" = (
+/obj/machinery/atmospherics/pipe/simple/cyan/visible,
+/obj/structure/grille,
+/obj/structure/window/reinforced/fulltile,
+/obj/machinery/door/firedoor,
+/obj/machinery/atmospherics/pipe/simple/green/visible{
+ dir = 4
+ },
+/turf/open/floor/plating{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
+"dge" = (
+/obj/machinery/atmospherics/pipe/manifold/cyan/visible,
+/turf/open/floor/plasteel/black{
+ baseturf = /turf/open/floor/plating/asteroid/airless
+ },
+/area/atmos)
(1,1,1) = {"
aaa
@@ -107243,7 +108067,7 @@ btk
btk
btk
ddI
-cJW
+ddI
btk
btk
btk
@@ -108016,7 +108840,7 @@ bxl
ddJ
ddX
bte
-bBF
+dem
cHi
bDU
bte
@@ -108273,7 +109097,7 @@ bte
byn
bzm
bte
-bBF
+dem
bCC
bDO
bte
@@ -109041,10 +109865,10 @@ bzr
ddn
bwc
ddB
-ddL
+ddv
dea
bAq
-dep
+ddo
dey
deE
bzr
@@ -109297,12 +110121,12 @@ brI
btj
ddo
bwc
-ddC
-ddM
-deb
+ddB
+ddv
+dea
dej
-deq
-dez
+ddo
+dey
cUI
bzr
bGC
@@ -109559,7 +110383,7 @@ ddN
bzn
bAr
buB
-bzo
+ddY
bDP
bzr
bGD
@@ -109809,14 +110633,14 @@ boR
aYW
brI
btj
-ddp
+ddo
ddv
-ddE
-ddO
-dec
+ddB
+ddv
+dea
bwc
-der
-deA
+ddo
+dey
bDQ
bzr
bGE
@@ -110066,14 +110890,14 @@ boR
aYW
brJ
bzr
-ddq
-ddw
-ddF
-ddP
-ded
+ddn
+ddv
+ddB
+ddv
+dea
bwc
-des
-deB
+ddo
+dey
bDR
bzr
bGF
@@ -110327,7 +111151,7 @@ byq
bwd
bxn
ddQ
-bzo
+ddY
byp
det
bzm
@@ -110581,7 +111405,7 @@ bqm
brL
bzr
ddr
-ddx
+ddr
bxo
ddR
dee
@@ -111098,10 +111922,10 @@ buC
ddy
bxq
ddT
-def
+ddV
bAu
-deu
-bCF
+ddG
+ddV
bDT
bzr
bGJ
@@ -111359,7 +112183,7 @@ bzp
dek
bBG
bwg
-deG
+ddG
bzr
bGK
bIk
@@ -111612,11 +112436,11 @@ buE
ddz
ddG
ddV
-deg
+ddG
del
-dev
+ddV
deC
-bCF
+ddV
bzr
bQB
bGL
@@ -111875,7 +112699,7 @@ btk
btk
btk
bEX
-deI
+dei
bTq
aXZ
bCG
@@ -116504,9 +117328,9 @@ aaa
aaa
aaa
aaa
-aaa
-aaa
-aaa
+deP
+abC
+abC
abC
aaa
aaa
@@ -116761,7 +117585,7 @@ aaa
aaa
aaa
aXS
-aXS
+deQ
aXS
aXE
aYh
@@ -117018,7 +117842,7 @@ aaa
aXE
aXE
aXS
-aXS
+deR
aXS
aXS
aXS
@@ -117275,7 +118099,7 @@ aXS
aXS
aXS
aXS
-aXS
+deS
aXS
aXS
aXS
@@ -117532,7 +118356,7 @@ aYg
aYg
aXS
aXS
-aXS
+deT
aXS
aXS
aXS
@@ -117789,7 +118613,7 @@ bzs
bzs
bzs
bzs
-bzs
+deU
bxK
bxK
bwA
@@ -118046,7 +118870,7 @@ cHu
bwA
bzs
bwA
-bwA
+deV
cHu
bwA
bvh
@@ -118303,7 +119127,7 @@ cQI
bwA
cHu
cHu
-bYq
+deW
cQe
cQC
cRq
@@ -118560,7 +119384,7 @@ cUT
cUU
cUV
cUW
-cUX
+deX
cUY
cUY
cUY
@@ -118817,7 +119641,7 @@ bDV
bDV
bDV
bDV
-bDV
+bDZ
bDV
bxK
cHu
@@ -119074,7 +119898,7 @@ bEY
bEY
bIm
bJI
-bEY
+deY
bLU
bLU
bLU
@@ -119331,7 +120155,7 @@ bEZ
bGM
bIn
bJJ
-bJJ
+deZ
bLU
bNt
bOr
@@ -119588,7 +120412,7 @@ bFa
bFa
bIn
bJK
-bJK
+dfa
bLU
bNt
bOs
@@ -119845,7 +120669,7 @@ bFb
bFb
bIn
bJL
-bJL
+dfb
bLU
bNu
bOt
@@ -120102,7 +120926,7 @@ bDV
bDV
bIo
bDV
-bDV
+bDZ
bLU
bNv
bOu
@@ -120352,14 +121176,14 @@ aXS
bxK
bwA
bxM
-bBJ
+cQB
bxK
bDV
bFc
bGN
bGO
-bGO
-bDV
+deM
+dfc
bLV
bNw
bLW
@@ -120609,25 +121433,25 @@ aXS
bxK
cHu
bwy
-cQB
+cUQ
bCJ
bDW
bFd
-bGO
-bGO
-bGO
+bGP
+bGP
+bGP
bKF
-bLW
-bNw
-bLW
+dfd
+dfe
+dfh
bPC
-bPC
-bNw
-bLW
-bPC
-bPC
-bUK
-bLW
+dfk
+dfn
+dfs
+dfy
+dfF
+dfQ
+dfV
bWf
bUK
bDV
@@ -120866,27 +121690,27 @@ aXS
bxK
bxK
cQu
-cUQ
+cUR
bCK
bDX
bFe
-bGP
-bGP
-bGP
+bGQ
+bGQ
+deN
bKG
bLX
-bNx
+bNy
bOv
bPD
-bQF
-bRH
-bSH
-bTt
-bTX
+bTY
+bNy
+bNy
+bTu
+bTY
bUL
bVt
bWg
-bUK
+dge
bDV
cHx
cHz
@@ -121123,24 +121947,24 @@ aYK
aYK
aYK
bAB
-cUR
+bBJ
bCL
-bDY
+bDZ
bFf
-bGQ
-bGQ
+bGO
+bGO
bJM
bKH
-bLY
-bNy
+bQM
+dff
bOw
-bPE
-bQG
-bNy
-bNy
-bTu
-bTY
-bUM
+bPF
+bQH
+bQH
+bQH
+bTv
+bQH
+bVK
bVu
bWh
bUK
@@ -121387,18 +122211,18 @@ bFg
bGR
bIp
bJN
-bKI
-bGQ
-bNz
+bGO
+bGO
+bGO
bOx
-bPF
-bQH
-bQH
-bQH
-bTv
-bQH
+dfi
+dfl
+dfo
+dft
+dfz
+dfG
bUN
-bVv
+bVu
bWi
bWG
bXg
@@ -121641,21 +122465,21 @@ bBJ
bwA
bDZ
bFh
-bGO
+deK
bIq
-bGO
+bJN
bKJ
bGO
-bNA
-bOy
-bPG
-bQI
-bQI
-bQI
-bPG
bGO
+bGO
+bNA
+bGO
+bQI
+dfu
+bPH
+dfH
bUO
-bVw
+bVu
bWj
bWH
bOu
@@ -121898,21 +122722,21 @@ bBK
cHu
bDZ
bFi
-bGO
+deL
bIr
-bGR
+deO
bKK
bLZ
bNB
bOz
-bPH
-bQJ
-bQJ
-bQJ
-bQO
bGO
+bGO
+dfp
+dfv
+bQJ
+dfI
+bUO
bUP
-bVx
bWk
bWI
bXh
@@ -122157,20 +122981,20 @@ bDZ
bFj
bGS
bIs
+bDZ
bDV
bDV
-bDV
-bDV
+dfg
bOA
-bPI
-bQK
-bQK
-bQK
-bTw
bGO
-bUQ
+bGO
+bQK
+dfw
+bQJ
+dfJ
+dfR
bVy
-bLW
+dfX
bWJ
bLU
bLU
@@ -122414,19 +123238,19 @@ bEa
bFk
bGT
bIt
-bJO
+bJP
bKL
bMa
bDV
bOB
bGO
-bQL
+bGO
bRI
bSI
-bGO
-bGO
+bQJ
+dfK
+bUO
bUQ
-bVz
bWl
bWG
bXg
@@ -122676,15 +123500,15 @@ bKM
bMb
bDV
bOC
-bPJ
-bQM
-bRJ
-bSJ
bGO
+bGO
+bQI
+bSJ
+dfA
cHs
+bQI
bUQ
-bVA
-bLW
+dfY
bWH
bOu
bXD
@@ -122933,15 +123757,15 @@ bKN
bMc
bNC
bOD
-bPK
-bGO
+dfj
bGO
+dfq
bOy
-bGO
-bGO
+dfB
+dfL
+dfS
bUP
-bVB
-bWk
+dfZ
bWI
bXh
bXE
@@ -123189,16 +124013,16 @@ bDZ
bKM
bMb
bDV
-bOE
+bGO
bPL
bQN
+dfr
+bPK
+dfC
bGO
-bSK
-bSJ
bGO
bUQ
-bVy
-bLW
+bWh
bWK
bLU
bLU
@@ -123450,12 +124274,12 @@ bOF
bPM
bQO
bRK
-bOy
-bTx
+dfx
+dfD
bTZ
+bGO
bUQ
-bVC
-bWl
+dga
bWG
bXg
bXF
@@ -123707,12 +124531,12 @@ cRb
cRb
bQP
bRL
+bTx
bSL
-bSL
+bJN
bGO
bUQ
-bVD
-bLW
+dgb
bWH
bOu
bXG
@@ -123967,10 +124791,10 @@ bRM
bSM
bTy
bUa
+dfT
bUR
-bVE
-bWk
-bWL
+dgc
+bWI
bXh
bXH
bYl
@@ -124223,10 +125047,10 @@ bQQ
bRN
bSN
bTz
+dfM
bUb
bTz
-bVF
-bTz
+dgd
bWM
bLU
bLU
@@ -124476,13 +125300,13 @@ bMg
cRk
cRs
bPP
-bQQ
+dfm
bRO
bQG
bTA
+dfN
bUc
bUS
-bVG
bWm
bWN
bXg
@@ -124736,11 +125560,11 @@ cRA
cWQ
bRP
bSO
-bOx
+bGO
+dfO
bUd
bUT
bVH
-bGO
bWO
bOu
bXJ
@@ -124992,12 +125816,12 @@ cRu
cRB
cWR
bRQ
-bGO
bQL
+bPJ
bUe
bPJ
-bVI
bPJ
+bVI
bWP
bXh
bXK
@@ -125252,9 +126076,9 @@ bRR
bSP
bTB
bUf
+dfU
bGO
bVJ
-bQH
bWQ
bLU
bLU
@@ -125510,7 +126334,7 @@ bSQ
bTC
bUg
bUU
-bVK
+dfW
bWn
bWR
bDV
@@ -125764,9 +126588,9 @@ cRc
bQS
bRT
bSR
+dfE
+dfP
bTD
-bDW
-bDV
bDV
bDV
bDV
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index c157cdc780..3c7218915c 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -63624,6 +63624,7 @@
dir = 8
},
/obj/effect/turf_decal/bot,
+/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel,
/area/engine/engineering)
"cqt" = (
diff --git a/code/__DEFINES/cult.dm b/code/__DEFINES/cult.dm
new file mode 100644
index 0000000000..71d4ad3af9
--- /dev/null
+++ b/code/__DEFINES/cult.dm
@@ -0,0 +1,9 @@
+//rune colors, for easy reference
+#define RUNE_COLOR_TALISMAN "#0000FF"
+#define RUNE_COLOR_TELEPORT "#551A8B"
+#define RUNE_COLOR_OFFER "#FFFFFF"
+#define RUNE_COLOR_DARKRED "#7D1717"
+#define RUNE_COLOR_MEDIUMRED "#C80000"
+#define RUNE_COLOR_RED "#FF0000"
+#define RUNE_COLOR_EMP "#4D94FF"
+#define RUNE_COLOR_SUMMON "#00FF00"
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index b0742ae3ab..a5e69bdc7b 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -27,6 +27,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define BLOCK_GAS_SMOKE_EFFECT 4096 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
#define THICKMATERIAL 8192 //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body.
#define DROPDEL 16384 // When dropped, it calls qdel on itself
+#define PREVENT_CLICK_UNDER 32768 //Prevent clicking things below it on the same turf eg. doors/ fulltile windows
/* Secondary atom flags, access using the SECONDARY_FLAG macros */
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 321bbf7b67..8b02a61fba 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -407,3 +407,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
//Error handler defines
#define ERROR_USEFUL_LEN 2
+
+#define NO_FIELD 0
+#define FIELD_TURF 1
+#define FIELD_EDGE 2
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index ca4093adf1..43b657dd9c 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -340,6 +340,20 @@ Proc for attack log creation, because really why not
qdel(progbar)
+//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action
+/mob/proc/break_do_after_checks(list/checked_health, check_clicks)
+ if(check_clicks && next_move > world.time)
+ return FALSE
+ return TRUE
+
+//pass a list in the format list("health" = mob's health var) to check health during this
+/mob/living/break_do_after_checks(list/checked_health, check_clicks)
+ if(islist(checked_health))
+ if(health < checked_health["health"])
+ return FALSE
+ checked_health["health"] = health
+ return ..()
+
/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null)
if(!user)
return 0
diff --git a/code/_globalvars/game_modes.dm b/code/_globalvars/game_modes.dm
index 12fb1bae48..806ac576d4 100644
--- a/code/_globalvars/game_modes.dm
+++ b/code/_globalvars/game_modes.dm
@@ -13,4 +13,5 @@ GLOBAL_VAR_INIT(sac_image, null)
GLOBAL_VAR_INIT(cult_vote_called, FALSE)
GLOBAL_VAR_INIT(cult_mastered, FALSE)
GLOBAL_VAR_INIT(reckoning_complete, FALSE)
-GLOBAL_VAR_INIT(sac_complete, FALSE)
\ No newline at end of file
+GLOBAL_VAR_INIT(sac_complete, FALSE)
+GLOBAL_DATUM(cult_narsie, /obj/singularity/narsie/large/cult)
\ No newline at end of file
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 07dcfaee28..ad4a84529b 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -92,6 +92,9 @@
if(next_move > world.time) // in the year 2000...
return
+ if(A.IsObscured())
+ return
+
if(istype(loc,/obj/mecha))
var/obj/mecha/M = loc
return M.click_action(A,src,params)
@@ -141,6 +144,24 @@
else
RangedAttack(A,params)
+//Is the atom obscured by a PREVENT_CLICK_UNDER object above it
+/atom/proc/IsObscured()
+ if(!isturf(loc)) //This only makes sense for things directly on turfs for now
+ return FALSE
+ var/turf/T = get_turf_pixel(src)
+ if(!T)
+ return FALSE
+ for(var/atom/movable/AM in T)
+ if(AM.flags & PREVENT_CLICK_UNDER && AM.density && AM.layer > layer)
+ return TRUE
+ return FALSE
+
+/turf/IsObscured()
+ for(var/atom/movable/AM in src)
+ if(AM.flags & PREVENT_CLICK_UNDER && AM.density)
+ return TRUE
+ return FALSE
+
/atom/movable/proc/CanReach(atom/target,obj/item/tool,view_only = FALSE)
if(isturf(target) || isturf(target.loc) || DirectAccess(target)) //Directly accessible atoms
if(Adjacent(target) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 00e6729a6f..dfabe23025 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -287,9 +287,9 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
GLOB.blood_target = null
else
blood_target = GLOB.blood_target
- if(Cviewer)
- if(Cviewer.seeking && Cviewer.master)
- blood_target = Cviewer.master
+ if(Cviewer && Cviewer.seeking && Cviewer.master)
+ blood_target = Cviewer.master
+ desc = "Your blood sense is leading you to [Cviewer.master]"
if(!blood_target)
if(!GLOB.sac_complete)
if(icon_state == "runed_sense0")
@@ -301,22 +301,21 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
desc = "Nar-Sie demands that [GLOB.sac_mind] be sacrificed before the summoning ritual can begin."
add_overlay(GLOB.sac_image)
else
- if(SSticker.mode.eldergod)
- desc = "The sacrifice is complete, prepare to summon Nar-Sie!"
- else
- desc = "The summoning is complete, glory to Nar-Sie!"
if(icon_state == "runed_sense1")
return
animate(src, transform = null, time = 1, loop = 0)
angle = 0
cut_overlays()
icon_state = "runed_sense1"
+ desc = "The sacrifice is complete, bring the wrath of Nar-Sie upon the crew!"
add_overlay(narnar)
return
var/turf/P = get_turf(blood_target)
var/turf/Q = get_turf(mob_viewer)
var/area/A = get_area(P)
if(P.z != Q.z) //The target is on a different Z level, we cannot sense that far.
+ icon_state = "runed_sense2"
+ desc = "[blood_target] is no longer in your sector, you cannot sense its presence here."
return
desc = "You are currently tracking [blood_target] in [A.name]."
var/target_angle = Get_Angle(Q, P)
diff --git a/code/controllers/subsystem/fields.dm b/code/controllers/subsystem/fields.dm
new file mode 100644
index 0000000000..8e9f387478
--- /dev/null
+++ b/code/controllers/subsystem/fields.dm
@@ -0,0 +1,27 @@
+
+SUBSYSTEM_DEF(fields)
+ name = "Fields"
+ wait = 2
+ priority = 40
+ flags = SS_KEEP_TIMING
+ var/list/datum/proximity_monitor/advanced/running = list()
+ var/list/datum/proximity_monitor/advanced/currentrun = list()
+
+/datum/controller/subsystem/fields/fire(resumed = 0)
+ if(!resumed)
+ src.currentrun = running.Copy()
+ var/list/currentrun = src.currentrun
+ while(currentrun.len)
+ var/datum/proximity_monitor/advanced/F = currentrun[currentrun.len]
+ currentrun.len--
+ if(!F.requires_processing)
+ continue
+ F.process()
+ if(MC_TICK_CHECK)
+ return
+
+/datum/controller/subsystem/fields/proc/register_new_field(datum/proximity_monitor/advanced/F)
+ running += F
+
+/datum/controller/subsystem/fields/proc/unregister_field(datum/proximity_monitor/advanced/F)
+ running -= F
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 7694eb8daf..e8d575a517 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -284,7 +284,7 @@ SUBSYSTEM_DEF(ticker)
//Now animate the cinematic
switch(station_missed)
if(NUKE_NEAR_MISS) //nuke was nearby but (mostly) missed
- if( mode && !override )
+ if(mode && !override )
override = mode.name
switch( override )
if("nuclear emergency") //Nuke wasn't on station when it blew up
@@ -294,6 +294,17 @@ SUBSYSTEM_DEF(ticker)
station_explosion_detonation(bomb)
flick("station_intact_fade_red",cinematic)
cinematic.icon_state = "summary_nukefail"
+ if("cult")
+ cinematic.icon_state = null
+ flick("intro_cult",cinematic)
+ sleep(25)
+ world << sound('sound/magic/enter_blood.ogg')
+ sleep(28)
+ world << sound('sound/machines/terminal_off.ogg')
+ sleep(20)
+ flick("station_corrupted",cinematic)
+ world << sound('sound/effects/ghost.ogg')
+ actually_blew_up = FALSE
if("gang war") //Gang Domination (just show the override screen)
cinematic.icon_state = "intro_malf_still"
flick("intro_malf",cinematic)
@@ -342,6 +353,13 @@ SUBSYSTEM_DEF(ticker)
world << sound('sound/effects/explosionfar.ogg')
station_explosion_detonation(bomb) //TODO: no idea what this case could be
cinematic.icon_state = "summary_selfdes"
+ if("cult") //Station nuked (nuke,explosion,summary)
+ flick("intro_nuke",cinematic)
+ sleep(35)
+ flick("station_explode_fade_red",cinematic)
+ world << sound('sound/effects/explosionfar.ogg')
+ station_explosion_detonation(bomb) //TODO: no idea what this case could be
+ cinematic.icon_state = "summary_cult"
if("no_core") //Nuke failed to detonate as it had no core
flick("intro_nuke",cinematic)
sleep(35)
diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm
index 10599ca25b..8f18f8b1fe 100644
--- a/code/datums/holocall.dm
+++ b/code/datums/holocall.dm
@@ -31,6 +31,7 @@
var/obj/machinery/holopad/H = I
if(!QDELETED(H) && H.is_operational())
dialed_holopads += H
+ H.say("Incoming call.")
LAZYADD(H.holo_calls, src)
if(!dialed_holopads.len)
@@ -42,12 +43,16 @@
//cleans up ALL references :)
/datum/holocall/Destroy()
- QDEL_NULL(eye)
-
user.reset_perspective()
+ if(user.client)
+ for(var/datum/camerachunk/chunk in eye.visibleCameraChunks)
+ user.client.images -= chunk.obscured
+ user.remote_control = null
+ QDEL_NULL(eye)
user = null
- hologram.HC = null
+ if(hologram)
+ hologram.HC = null
hologram = null
calling_holopad.outgoing_call = null
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index c223d3b315..dd7a7ba38a 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -1330,7 +1330,7 @@
obj_count++
/datum/mind/proc/find_syndicate_uplink()
- var/list/L = current.get_contents()
+ var/list/L = current.GetAllContents()
for (var/obj/item/I in L)
if (I.hidden_uplink)
return I.hidden_uplink
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm
index 9637010625..3e7d0f3779 100644
--- a/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm
+++ b/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm
@@ -387,4 +387,4 @@
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.04), "spawn_dir" = SOUTH)
/obj/item/clockwork/alloy_shards/small/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
- return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.02), "spawn_dir" = SOUTH)
+ return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.02), "spawn_dir" = SOUTH)
\ No newline at end of file
diff --git a/code/game/gamemodes/clock_cult/clock_items/clock_components.dm b/code/game/gamemodes/clock_cult/clock_items/clock_components.dm
index 16cfef5d72..f64b361ac1 100644
--- a/code/game/gamemodes/clock_cult/clock_items/clock_components.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/clock_components.dm
@@ -162,14 +162,15 @@
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/randomsinglesprite = FALSE
var/randomspritemax = 2
+ var/sprite_shift = 9
/obj/item/clockwork/alloy_shards/Initialize()
. = ..()
if(randomsinglesprite)
replace_name_desc()
icon_state = "[icon_state][rand(1, randomspritemax)]"
- pixel_x = rand(-9, 9)
- pixel_y = rand(-9, 9)
+ pixel_x = rand(-sprite_shift, sprite_shift)
+ pixel_y = rand(-sprite_shift, sprite_shift)
/obj/item/clockwork/alloy_shards/proc/replace_name_desc()
name = "replicant alloy shard"
@@ -177,16 +178,21 @@
clockwork_desc = "A broken shard of replicant alloy. Can be proselytized for additional power."
/obj/item/clockwork/alloy_shards/large
+ w_class = WEIGHT_CLASS_TINY
randomsinglesprite = TRUE
icon_state = "shard_large"
+ sprite_shift = 9
/obj/item/clockwork/alloy_shards/medium
+ w_class = WEIGHT_CLASS_TINY
randomsinglesprite = TRUE
icon_state = "shard_medium"
+ sprite_shift = 10
/obj/item/clockwork/alloy_shards/medium/gear_bit
randomspritemax = 4
icon_state = "gear_bit"
+ sprite_shift = 12
/obj/item/clockwork/alloy_shards/medium/gear_bit/replace_name_desc()
name = "gear bit"
@@ -200,9 +206,11 @@
name = "complex gear bit"
/obj/item/clockwork/alloy_shards/small
+ w_class = WEIGHT_CLASS_TINY
randomsinglesprite = TRUE
randomspritemax = 3
icon_state = "shard_small"
+ sprite_shift = 12
/obj/item/clockwork/alloy_shards/pinion_lock
name = "pinion lock"
diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm
index 60df56b6ef..aa174adcd8 100644
--- a/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm
@@ -178,21 +178,24 @@
return TRUE
//A note here; return values are for if we CAN BE PUT ON A TABLE, not IF WE ARE SUCCESSFUL, unless no_table_check is TRUE
-/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user, no_table_check)
+/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user, silent, no_table_check)
if(!target || !user)
return FALSE
if(repairing)
- to_chat(user, "You are currently repairing [repairing] with [src]!")
+ if(!silent)
+ to_chat(user, "You are currently repairing [repairing] with [src]!")
return FALSE
if(recharging)
- to_chat(user, "You are currently recharging [src] from the [recharging.sigil_name]!")
+ if(!silent)
+ to_chat(user, "You are currently recharging [src] from the [recharging.sigil_name]!")
return FALSE
- var/list/proselytize_values = target.proselytize_vals(user, src) //relevant values for proselytizing stuff, given as an associated list
+ var/list/proselytize_values = target.proselytize_vals(user, src, silent) //relevant values for proselytizing stuff, given as an associated list
if(!islist(proselytize_values))
if(proselytize_values != TRUE) //if we get true, fail, but don't send a message for whatever reason
if(!isturf(target)) //otherwise, if we didn't get TRUE and the original target wasn't a turf, try to proselytize the turf
return proselytize(get_turf(target), user, no_table_check)
- to_chat(user, "[target] cannot be proselytized!")
+ if(!silent)
+ to_chat(user, "[target] cannot be proselytized!")
if(!no_table_check)
return TRUE
return FALSE
@@ -207,19 +210,22 @@
var/target_type = target.type
- if(!proselytize_checks(proselytize_values, target, target_type, user))
+ if(!proselytize_checks(proselytize_values, target, target_type, user, silent))
return FALSE
proselytize_values["operation_time"] *= speed_multiplier
playsound(target, 'sound/machines/click.ogg', 50, 1)
if(proselytize_values["operation_time"])
- user.visible_message("[user]'s [name] begins tearing apart [target]!", "You begin proselytizing [target]...")
+ if(!silent)
+ user.visible_message("[user]'s [name] begins tearing apart [target]!", "You begin proselytizing [target]...")
if(!do_after(user, proselytize_values["operation_time"], target = target, extra_checks = CALLBACK(src, .proc/proselytize_checks, proselytize_values, target, target_type, user, TRUE)))
return FALSE
- user.visible_message("[user]'s [name] covers [target] in golden energy!", "You proselytize [target].")
+ if(!silent)
+ user.visible_message("[user]'s [name] covers [target] in golden energy!", "You proselytize [target].")
else
- user.visible_message("[user]'s [name] tears apart [target], covering it in golden energy!", "You proselytize [target].")
+ if(!silent)
+ user.visible_message("[user]'s [name] tears apart [target], covering it in golden energy!", "You proselytize [target].")
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
var/new_thing_type = proselytize_values["new_obj_type"]
@@ -227,11 +233,12 @@
var/turf/T = target
T.ChangeTurf(new_thing_type)
else
- if(proselytize_values["dir_in_new"])
- new new_thing_type(get_turf(target), proselytize_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New()
- else
- var/atom/A = new new_thing_type(get_turf(target))
- A.setDir(proselytize_values["spawn_dir"])
+ if(new_thing_type)
+ if(proselytize_values["dir_in_new"])
+ new new_thing_type(get_turf(target), proselytize_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New()
+ else
+ var/atom/A = new new_thing_type(get_turf(target))
+ A.setDir(proselytize_values["spawn_dir"])
if(!proselytize_values["no_target_deletion"]) //for some cases where proselytize_vals() modifies the object but doesn't want it deleted
qdel(target)
modify_stored_power(-proselytize_values["power_cost"])
@@ -239,8 +246,13 @@
return TRUE
return FALSE
+//The following three procs are heavy wizardry.
+//What these procs do is they take an existing list of values, which they then modify.
+//This(modifying an existing object, in this case the list) is the only way to get information OUT of a do_after callback, which this is used as.
+
+//The proselytize check proc.
/obj/item/clockwork/clockwork_proselytizer/proc/proselytize_checks(list/proselytize_values, atom/target, expected_type, mob/user, silent) //checked constantly while proselytizing
- if(!islist(proselytize_values) || !target || QDELETED(target) || !user)
+ if(!islist(proselytize_values) || QDELETED(target) || QDELETED(user))
return FALSE
if(repairing || recharging)
return FALSE
@@ -259,11 +271,8 @@
return TRUE
//The repair check proc.
-//Is dark magic. Can probably kill you.
-//What this proc does is it takes an existing list of values, which it modifies.
-//This(modifying an existing object) is the only way to get information OUT of a do_after callback, which this is used as.
/obj/item/clockwork/clockwork_proselytizer/proc/proselytizer_repair_checks(list/repair_values, atom/target, mob/user, silent) //Exists entirely to avoid an otherwise unreadable series of checks.
- if(!islist(repair_values) || !target || QDELETED(target) || !user)
+ if(!islist(repair_values) || QDELETED(target) || QDELETED(user))
return FALSE
if(isliving(target)) //standard checks for if we can affect the target
var/mob/living/L = target
@@ -302,9 +311,9 @@
return FALSE
return TRUE
-//checked constantly while charging from a sigil
+//The sigil charge check proc.
/obj/item/clockwork/clockwork_proselytizer/proc/sigil_charge_checks(list/charge_values, obj/effect/clockwork/sigil/transmission/sigil, mob/user, silent)
- if(!islist(charge_values) || !sigil || QDELETED(sigil) || !user)
+ if(!islist(charge_values) || QDELETED(sigil) || QDELETED(user))
return FALSE
if(can_use_power(RATVAR_POWER_CHECK))
return FALSE
diff --git a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm
index b82e9a9c85..25f151def5 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm
@@ -28,7 +28,7 @@
var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/clockwork_effects.dmi', "ratvar_alert")
var/area/A = get_area(src)
notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [A.name] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay)
- INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency..proc/request, null, 0, 0)
+ INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency.proc/request, null, 0, null, FALSE, 0)
/obj/structure/destructible/clockwork/massive/ratvar/Destroy()
GLOB.ratvar_awakens--
diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm
index 0fe35322ed..2d2b5d1fa9 100644
--- a/code/game/gamemodes/cult/cult_comms.dm
+++ b/code/game/gamemodes/cult/cult_comms.dm
@@ -152,7 +152,7 @@
return TRUE
/datum/action/innate/cult/master/IsAvailable()
- if(!owner.mind || !owner.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER))
+ if(!owner.mind || !owner.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER) || GLOB.cult_narsie)
return 0
return ..()
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index ecbd033750..ed1a64eede 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -214,7 +214,7 @@
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands)
. = list()
if(!isinhands && current_charges)
- . += mutable_appearance('icons/effects/effects.dmi', "shield-cult", MOB_LAYER + 0.01)
+ . += mutable_appearance('icons/effects/cult_effects.dmi', "shield-cult", MOB_LAYER + 0.01)
/obj/item/clothing/suit/hooded/cultrobes/berserker
name = "flagellant's robes"
diff --git a/code/game/gamemodes/cult/rune_spawn_action.dm b/code/game/gamemodes/cult/rune_spawn_action.dm
new file mode 100644
index 0000000000..beffe924bc
--- /dev/null
+++ b/code/game/gamemodes/cult/rune_spawn_action.dm
@@ -0,0 +1,70 @@
+//after a delay, creates a rune below you. for constructs creating runes.
+/datum/action/innate/cult/create_rune
+ background_icon_state = "bg_cult"
+ var/obj/effect/rune/rune_type
+ var/cooldown = 0
+ var/base_cooldown = 900
+ var/scribe_time = 100
+ var/damage_interrupt = TRUE
+ var/action_interrupt = TRUE
+ var/obj/effect/overlay/temp/cult/rune_spawn/rune_word_type
+ var/obj/effect/overlay/temp/cult/rune_spawn/rune_innerring_type
+ var/obj/effect/overlay/temp/cult/rune_spawn/rune_center_type
+ var/rune_color
+
+/datum/action/innate/cult/create_rune/IsAvailable()
+ if(!rune_type || cooldown > world.time)
+ return FALSE
+ return ..()
+
+/datum/action/innate/cult/create_rune/Activate()
+ var/chosen_keyword
+ if(!isturf(owner.loc))
+ to_chat(owner, "")
+ visible_message("The markings pulse with a small flash of red light, then fall dark.")
var/oldcolor = color
color = rgb(255, 0, 0)
animate(src, color = oldcolor, time = 5)
@@ -192,7 +191,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "transforms paper into powerful magic talismans."
invocation = "H'drak v'loso, mir'kanas verbot!"
icon_state = "3"
- color = "#0000FF"
+ color = RUNE_COLOR_TALISMAN
/obj/effect/rune/imbue/invoke(var/list/invokers)
var/mob/living/user = invokers[1] //the first invoker is always the user
@@ -247,7 +246,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "warps everything above it to another chosen teleport rune."
invocation = "Sas'so c'arta forbici!"
icon_state = "2"
- color = "#551A8B"
+ color = RUNE_COLOR_TELEPORT
req_keyword = TRUE
var/listkey
@@ -307,10 +306,11 @@ structure_check() searches for nearby cultist structures required for the invoca
A.forceMove(target)
if(movedsomething)
..()
- visible_message("There is a sharp crack of inrushing air, and everything above the rune disappears!")
+ visible_message("There is a sharp crack of inrushing air, and everything above the rune disappears!", null, "You hear a sharp crack.")
to_chat(user, "You[moveuserlater ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"].")
if(moveuserlater)
user.forceMove(target)
+ target.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.")
else
fail_invoke()
@@ -322,7 +322,7 @@ structure_check() searches for nearby cultist structures required for the invoca
req_cultists_text = "2 for conversion, 3 for living sacrifices and sacrifice targets."
invocation = "Mah'weyh pleggh at e'ntrath!"
icon_state = "3"
- color = "#FFFFFF"
+ color = RUNE_COLOR_OFFER
req_cultists = 1
allow_excess_invokers = TRUE
rune_in_use = FALSE
@@ -345,7 +345,7 @@ structure_check() searches for nearby cultist structures required for the invoca
rune_in_use = TRUE
visible_message("[src] pulses blood red!")
var/oldcolor = color
- color = "#7D1717"
+ color = RUNE_COLOR_DARKRED
var/mob/living/L = pick(myriad_targets)
var/is_clock = is_servant_of_ratvar(L)
var/is_convertable = is_convertable_to_cult(L)
@@ -442,7 +442,7 @@ structure_check() searches for nearby cultist structures required for the invoca
invocation = "TOK-LYR RQA-NAP G'OLT-ULOFT!!"
req_cultists = 9
icon = 'icons/effects/96x96.dmi'
- color = "#7D1717"
+ color = RUNE_COLOR_DARKRED
icon_state = "rune_large"
pixel_x = -32 //So the big ol' 96x96 sprite shows up right
pixel_y = -32
@@ -479,9 +479,9 @@ structure_check() searches for nearby cultist structures required for the invoca
var/turf/T = get_turf(src)
sleep(40)
if(src)
- color = "#FF0000"
+ color = RUNE_COLOR_RED
SSticker.mode.eldergod = FALSE
- new /obj/singularity/narsie/large(T) //Causes Nar-Sie to spawn even if the rune has been removed
+ new /obj/singularity/narsie/large/cult(T) //Causes Nar-Sie to spawn even if the rune has been removed
/obj/effect/rune/narsie/attackby(obj/I, mob/user, params) //Since the narsie rune takes a long time to make, add logging to removal.
if((istype(I, /obj/item/weapon/tome) && iscultist(user)))
@@ -502,7 +502,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "requires the corpse of a cultist placed upon the rune. Provided there have been sufficient sacrifices, they will be revived."
invocation = "Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!" //Depends on the name of the user - see below
icon_state = "1"
- color = "#C80000"
+ color = RUNE_COLOR_MEDIUMRED
var/static/revives_used = 0
/obj/effect/rune/raise_dead/examine(mob/user)
@@ -593,7 +593,7 @@ structure_check() searches for nearby cultist structures required for the invoca
invocation = "Ta'gh fara'qha fel d'amar det!"
icon_state = "5"
allow_excess_invokers = 1
- color = "#4D94FF"
+ color = RUNE_COLOR_EMP
/obj/effect/rune/emp/invoke(var/list/invokers)
var/turf/E = get_turf(src)
@@ -623,7 +623,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "severs the link between one's spirit and body. This effect is taxing and one's physical body will take damage while this is active."
invocation = "Fwe'sh mah erl nyag r'ya!"
icon_state = "7"
- color = "#7D1717"
+ color = RUNE_COLOR_DARKRED
rune_in_use = 0 //One at a time, please!
construct_invoke = 0
var/mob/living/affecting = null
@@ -649,9 +649,9 @@ structure_check() searches for nearby cultist structures required for the invoca
var/mob/living/user = invokers[1]
..()
var/turf/T = get_turf(src)
- rune_in_use = 1
+ rune_in_use = TRUE
affecting = user
- user.color = "#7D1717"
+ user.add_atom_colour(RUNE_COLOR_DARKRED, ADMIN_COLOUR_PRIORITY)
user.visible_message("[user] freezes statue-still, glowing an unearthly red.", \
"You see what lies beyond. All is revealed. While this is a wondrous experience, your physical form will waste away in this state. Hurry...")
user.ghostize(1)
@@ -659,7 +659,7 @@ structure_check() searches for nearby cultist structures required for the invoca
if(!affecting)
visible_message("[src] pulses gently before falling dark.")
affecting = null //In case it's assigned to a number or something
- rune_in_use = 0
+ rune_in_use = FALSE
return
affecting.apply_damage(0.1, BRUTE)
if(!(user in T))
@@ -669,9 +669,9 @@ structure_check() searches for nearby cultist structures required for the invoca
if(user.key)
user.visible_message("[user] slowly relaxes, the glow around [user.p_them()] dimming.", \
"You are re-united with your physical form. [src] releases its hold over you.")
- user.color = initial(user.color)
+ user.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED)
user.Weaken(3)
- rune_in_use = 0
+ rune_in_use = FALSE
affecting = null
return
if(user.stat == UNCONSCIOUS)
@@ -679,14 +679,14 @@ structure_check() searches for nearby cultist structures required for the invoca
var/mob/dead/observer/G = user.get_ghost()
to_chat(G, "You feel the link between you and your body weakening... you must hurry!")
if(user.stat == DEAD)
- user.color = initial(user.color)
- rune_in_use = 0
+ user.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED)
+ rune_in_use = FALSE
affecting = null
var/mob/dead/observer/G = user.get_ghost()
to_chat(G, "You suddenly feel your physical form pass on. [src]'s exertion has killed you!")
return
sleep(1)
- rune_in_use = 0
+ rune_in_use = FALSE
//Rite of the Corporeal Shield: When invoked, becomes solid and cannot be passed. Invoke again to undo.
/obj/effect/rune/wall
@@ -694,7 +694,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "when invoked, makes a temporary invisible wall to block passage. Can be invoked again to reverse this."
invocation = "Khari'd! Eske'te tannin!"
icon_state = "1"
- color = "#C80000"
+ color = RUNE_COLOR_MEDIUMRED
CanAtmosPass = ATMOS_PASS_DENSITY
var/density_timer
var/recharging = FALSE
@@ -753,7 +753,7 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/wall/proc/recharge()
recharging = FALSE
- add_atom_colour("#C80000", FIXED_COLOUR_PRIORITY)
+ add_atom_colour(RUNE_COLOR_MEDIUMRED, FIXED_COLOUR_PRIORITY)
/obj/effect/rune/wall/proc/update_state()
deltimer(density_timer)
@@ -764,10 +764,10 @@ structure_check() searches for nearby cultist structures required for the invoca
shimmer.alpha = 60
shimmer.color = "#701414"
add_overlay(shimmer)
- add_atom_colour("#FF0000", FIXED_COLOUR_PRIORITY)
+ add_atom_colour(RUNE_COLOR_RED, FIXED_COLOUR_PRIORITY)
else
cut_overlays()
- add_atom_colour("#C80000", FIXED_COLOUR_PRIORITY)
+ add_atom_colour(RUNE_COLOR_MEDIUMRED, FIXED_COLOUR_PRIORITY)
//Rite of Joined Souls: Summons a single cultist.
/obj/effect/rune/summon
@@ -777,7 +777,7 @@ structure_check() searches for nearby cultist structures required for the invoca
req_cultists = 2
allow_excess_invokers = 1
icon_state = "5"
- color = "#00FF00"
+ color = RUNE_COLOR_SUMMON
/obj/effect/rune/summon/invoke(var/list/invokers)
var/mob/living/user = invokers[1]
@@ -822,7 +822,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "boils the blood of non-believers who can see the rune, rapidly dealing extreme amounts of damage. Requires 3 invokers."
invocation = "Dedo ol'btoh!"
icon_state = "4"
- color = "#C80000"
+ color = RUNE_COLOR_MEDIUMRED
light_color = LIGHT_COLOR_LAVA
req_cultists = 3
construct_invoke = 0
@@ -889,7 +889,7 @@ structure_check() searches for nearby cultist structures required for the invoca
invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this
icon_state = "6"
construct_invoke = 0
- color = "#C80000"
+ color = RUNE_COLOR_MEDIUMRED
var/ghost_limit = 5
var/ghosts = 0
@@ -962,4 +962,4 @@ structure_check() searches for nearby cultist structures required for the invoca
"Your link to the world fades. Your form breaks apart.")
for(var/obj/I in new_human)
new_human.dropItemToGround(I, TRUE)
- new_human.dust()
+ new_human.dust()
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm
index 027df31acd..9a9d8c582b 100644
--- a/code/game/gamemodes/cult/talisman.dm
+++ b/code/game/gamemodes/cult/talisman.dm
@@ -49,7 +49,7 @@
/obj/item/weapon/paper/talisman/teleport
cultist_name = "Talisman of Teleportation"
cultist_desc = "A single-use talisman that will teleport a user to a random rune of the same keyword."
- color = "#551A8B" // purple
+ color = RUNE_COLOR_TELEPORT
invocation = "Sas'so c'arta forbici!"
health_cost = 5
creation_time = 80
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index 503fc0f396..c72152668d 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -210,13 +210,16 @@
var/datum/action/innate/seek_master/SM = new()
SM.Grant(newstruct)
newstruct.key = target.key
+ var/obj/screen/alert/bloodsense/BS
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode)
SSticker.mode.add_cultist(newstruct.mind, 0)
+ BS = newstruct.alerts.Find("bloodsense")
if(iscultist(stoner) || cultoverride)
to_chat(newstruct, "You are still bound to serve the cult[stoner ? " and [stoner]":""], follow their orders and help them complete their goals at all costs.")
else if(stoner)
to_chat(newstruct, "You are still bound to serve your creator, [stoner], follow their orders and help them complete their goals at all costs.")
- var/obj/screen/alert/bloodsense/BS = newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
+ BS = newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
+ if(BS)
BS.Cviewer = newstruct
newstruct.cancel_camera()
diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm
index ace9b543d1..0ebae75da6 100644
--- a/code/game/machinery/bank_machine.dm
+++ b/code/game/machinery/bank_machine.dm
@@ -25,9 +25,6 @@
if(istype(I, /obj/item/stack/spacecash))
var/obj/item/stack/spacecash/C = I
value = C.value * C.amount
- if(istype(I, /obj/item/weapon/coin))
- var/obj/item/weapon/coin/C = I
- value = C.value
if(value)
SSshuttle.points += value
to_chat(user, "You deposit [I]. The station now has [SSshuttle.points] credits.")
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 643282ab4a..1fdfd61f07 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -43,7 +43,8 @@
/obj/item/weapon/grenade/chem_grenade/glitter/pink = 1,
/obj/item/weapon/grenade/chem_grenade/glitter/blue = 1,
/obj/item/weapon/grenade/chem_grenade/glitter/white = 1,
- /obj/item/toy/eightball = 2)
+ /obj/item/toy/eightball = 2,
+ /obj/item/toy/windupToolbox = 2)
light_color = LIGHT_COLOR_GREEN
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 4e076e3338..b71aeaca8d 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -12,6 +12,7 @@
max_integrity = 350
armor = list(melee = 30, bullet = 30, laser = 20, energy = 20, bomb = 10, bio = 100, rad = 100, fire = 80, acid = 70)
CanAtmosPass = ATMOS_PASS_DENSITY
+ flags = PREVENT_CLICK_UNDER
var/secondsElectrified = 0
var/shockedby = list()
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 2c2e39c4d7..7cf0b69d7d 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -26,8 +26,6 @@ Possible to do for anyone motivated enough:
#define HOLOPAD_PASSIVE_POWER_USAGE 1
#define HOLOGRAM_POWER_USAGE 2
-
-GLOBAL_LIST_EMPTY(holopads)
#define HOLOPAD_MODE RANGE_BASED
/obj/machinery/holopad
@@ -295,7 +293,7 @@ GLOBAL_LIST_EMPTY(holopads)
Hologram.Impersonation = user
- Hologram.language_holder = user.get_language_holder()
+ Hologram.copy_known_languages_from(user,replace = TRUE)
Hologram.mouse_opacity = 0//So you can't click on it.
Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index bd51e1e651..ebe4c79730 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -48,6 +48,7 @@
var/icon_deny //Icon_state when vending!
var/seconds_electrified = 0 //Shock customers like an airlock.
var/shoot_inventory = 0 //Fire items at customers! We're broken!
+ var/shoot_inventory_chance = 2
var/shut_up = 0 //Stop spouting those godawful pitches!
var/extended_inventory = 0 //can we access the hidden inventory?
var/scan_id = 1
@@ -561,7 +562,7 @@
speak(slogan)
last_slogan = world.time
- if(shoot_inventory && prob(2))
+ if(shoot_inventory && prob(shoot_inventory_chance))
throw_item()
@@ -592,7 +593,7 @@
if(!target)
return 0
- for(var/datum/data/vending_product/R in product_records)
+ for(var/datum/data/vending_product/R in shuffle(product_records))
if(R.amount <= 0) //Try to use a record that actually has something to dump.
continue
var/dump_path = R.product_path
@@ -605,19 +606,22 @@
if(!throw_item)
return 0
+ pre_throw(throw_item)
+
throw_item.throw_at(target, 16, 3)
visible_message("[src] launches [throw_item] at [target]!")
return 1
+/obj/machinery/vending/proc/pre_throw(obj/item/I)
+ return
+
/obj/machinery/vending/proc/shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return FALSE
if(!prob(prb))
return FALSE
- var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
- s.set_up(5, 1, src)
- s.start()
+ do_sparks(5, TRUE, src)
var/tmp/check_range = TRUE
if(electrocute_mob(user, get_area(src), src, 0.7, check_range))
return TRUE
@@ -864,6 +868,11 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/weapon/storage/fancy/cigarettes/cigars = 1, /obj/item/weapon/storage/fancy/cigarettes/cigars/havana = 1, /obj/item/weapon/storage/fancy/cigarettes/cigars/cohiba = 1)
refill_canister = /obj/item/weapon/vending_refill/cigarette
+/obj/machinery/vending/cigarette/pre_throw(obj/item/I)
+ if(istype(I, /obj/item/weapon/lighter))
+ var/obj/item/weapon/lighter/L = I
+ L.set_lit(TRUE)
+
/obj/machinery/vending/medical
name = "\improper NanoMed Plus"
desc = "Medical drug dispenser."
@@ -919,6 +928,15 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
resistance_flags = FIRE_PROOF
+/obj/machinery/vending/security/pre_throw(obj/item/I)
+ if(istype(I, /obj/item/weapon/grenade))
+ var/obj/item/weapon/grenade/G = I
+ G.preprime()
+ else if(istype(I, /obj/item/device/flashlight))
+ var/obj/item/device/flashlight/F = I
+ F.on = TRUE
+ F.update_brightness()
+
/obj/machinery/vending/hydronutrients
name = "\improper NutriMax"
desc = "A plant nutrients vendor."
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index 12225321d7..9d9694b076 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -18,620 +18,6 @@
..()
QDEL_IN(src, 10)
-/obj/effect/overlay/temp
- icon_state = "nothing"
- anchored = 1
- layer = ABOVE_MOB_LAYER
- mouse_opacity = 0
- var/duration = 10 //in deciseconds
- var/randomdir = TRUE
- var/timerid
-
-/obj/effect/overlay/temp/Destroy()
- . = ..()
- deltimer(timerid)
-
-/obj/effect/overlay/temp/Initialize()
- . = ..()
- if(randomdir)
- setDir(pick(GLOB.cardinal))
-
- timerid = QDEL_IN(src, duration)
-
-/obj/effect/overlay/temp/ex_act()
- return
-
-/obj/effect/overlay/temp/dir_setting
- randomdir = FALSE
-
-/obj/effect/overlay/temp/dir_setting/Initialize(mapload, set_dir)
- if(set_dir)
- setDir(set_dir)
- . = ..()
-
-/obj/effect/overlay/temp/dir_setting/bloodsplatter
- icon = 'icons/effects/blood.dmi'
- duration = 5
- randomdir = FALSE
- layer = BELOW_MOB_LAYER
- var/splatter_type = "splatter"
-
-/obj/effect/overlay/temp/dir_setting/bloodsplatter/Initialize(mapload, set_dir)
- if(set_dir in GLOB.diagonals)
- icon_state = "[splatter_type][pick(1, 2, 6)]"
- else
- icon_state = "[splatter_type][pick(3, 4, 5)]"
- . = ..()
- var/target_pixel_x = 0
- var/target_pixel_y = 0
- switch(set_dir)
- if(NORTH)
- target_pixel_y = 16
- if(SOUTH)
- target_pixel_y = -16
- layer = ABOVE_MOB_LAYER
- if(EAST)
- target_pixel_x = 16
- if(WEST)
- target_pixel_x = -16
- if(NORTHEAST)
- target_pixel_x = 16
- target_pixel_y = 16
- if(NORTHWEST)
- target_pixel_x = -16
- target_pixel_y = 16
- if(SOUTHEAST)
- target_pixel_x = 16
- target_pixel_y = -16
- layer = ABOVE_MOB_LAYER
- if(SOUTHWEST)
- target_pixel_x = -16
- target_pixel_y = -16
- layer = ABOVE_MOB_LAYER
- animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
-
-/obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter
- splatter_type = "xsplatter"
-
-/obj/effect/overlay/temp/dir_setting/speedbike_trail
- name = "speedbike trails"
- icon_state = "ion_fade"
- layer = BELOW_MOB_LAYER
- duration = 10
- randomdir = 0
-
-/obj/effect/overlay/temp/dir_setting/firing_effect
- icon = 'icons/effects/effects.dmi'
- icon_state = "firing_effect"
- duration = 2
-
-/obj/effect/overlay/temp/dir_setting/firing_effect/setDir(newdir)
- switch(newdir)
- if(NORTH)
- layer = BELOW_MOB_LAYER
- pixel_x = rand(-3,3)
- pixel_y = rand(4,6)
- if(SOUTH)
- pixel_x = rand(-3,3)
- pixel_y = rand(-1,1)
- else
- pixel_x = rand(-1,1)
- pixel_y = rand(-1,1)
- ..()
-
-/obj/effect/overlay/temp/dir_setting/firing_effect/energy
- icon_state = "firing_effect_energy"
- duration = 3
-
-/obj/effect/overlay/temp/dir_setting/firing_effect/magic
- icon_state = "shieldsparkles"
- duration = 3
-
-/obj/effect/overlay/temp/dir_setting/ninja
- name = "ninja shadow"
- icon = 'icons/mob/mob.dmi'
- icon_state = "uncloak"
- duration = 9
-
-/obj/effect/overlay/temp/dir_setting/ninja/cloak
- icon_state = "cloak"
-
-/obj/effect/overlay/temp/dir_setting/ninja/shadow
- icon_state = "shadow"
-
-/obj/effect/overlay/temp/dir_setting/ninja/phase
- name = "ninja energy"
- icon_state = "phasein"
-
-/obj/effect/overlay/temp/dir_setting/ninja/phase/out
- icon_state = "phaseout"
-
-/obj/effect/overlay/temp/dir_setting/wraith
- name = "blood"
- icon = 'icons/mob/mob.dmi'
- icon_state = "phase_shift2"
- duration = 12
-
-/obj/effect/overlay/temp/dir_setting/wraith/out
- icon_state = "phase_shift"
-
-/obj/effect/overlay/temp/dir_setting/tailsweep
- icon_state = "tailsweep"
- duration = 4
-
-/obj/effect/overlay/temp/wizard
- name = "water"
- icon = 'icons/mob/mob.dmi'
- icon_state = "reappear"
- duration = 5
-
-/obj/effect/overlay/temp/wizard/out
- icon_state = "liquify"
- duration = 12
-
-/obj/effect/overlay/temp/monkeyify
- icon = 'icons/mob/mob.dmi'
- icon_state = "h2monkey"
- duration = 22
-
-/obj/effect/overlay/temp/monkeyify/humanify
- icon_state = "monkey2h"
-
-/obj/effect/overlay/temp/borgflash
- icon = 'icons/mob/mob.dmi'
- icon_state = "blspell"
- duration = 5
-
-/obj/effect/overlay/temp/guardian
- randomdir = 0
-
-/obj/effect/overlay/temp/guardian/phase
- duration = 5
- icon_state = "phasein"
-
-/obj/effect/overlay/temp/guardian/phase/out
- icon_state = "phaseout"
-
-/obj/effect/overlay/temp/decoy
- desc = "It's a decoy!"
- duration = 15
-
-/obj/effect/overlay/temp/decoy/Initialize(mapload, atom/mimiced_atom)
- . = ..()
- alpha = initial(alpha)
- if(mimiced_atom)
- name = mimiced_atom.name
- appearance = mimiced_atom.appearance
- setDir(mimiced_atom.dir)
- mouse_opacity = 0
-
-/obj/effect/overlay/temp/decoy/fading/Initialize(mapload, atom/mimiced_atom)
- . = ..()
- animate(src, alpha = 0, time = duration)
-
-/obj/effect/overlay/temp/decoy/fading/fivesecond
- duration = 50
-
-/obj/effect/overlay/temp/small_smoke
- icon_state = "smoke"
- duration = 50
-
-/obj/effect/overlay/temp/fire
- icon = 'icons/effects/fire.dmi'
- icon_state = "3"
- duration = 20
-
-/obj/effect/overlay/temp/cult
- randomdir = 0
- duration = 10
-
-/obj/effect/overlay/temp/cult/sparks
- randomdir = 1
- name = "blood sparks"
- icon_state = "bloodsparkles"
-
-/obj/effect/overlay/temp/cult/blood // The traditional teleport
- name = "blood jaunt"
- duration = 12
- icon_state = "bloodin"
-
-/obj/effect/overlay/temp/cult/blood/out
- icon_state = "bloodout"
-
-/obj/effect/overlay/temp/dir_setting/cult/phase // The veil shifter teleport
- name = "phase glow"
- duration = 7
- icon_state = "cultin"
-
-/obj/effect/overlay/temp/dir_setting/cult/phase/out
- icon_state = "cultout"
-
-/obj/effect/overlay/temp/cult/sac
- name = "maw of Nar-Sie"
- icon_state = "sacconsume"
-
-/obj/effect/overlay/temp/cult/door
- name = "unholy glow"
- icon_state = "doorglow"
- layer = CLOSED_FIREDOOR_LAYER //above closed doors
-
-/obj/effect/overlay/temp/cult/door/unruned
- icon_state = "unruneddoorglow"
-
-/obj/effect/overlay/temp/cult/turf
- name = "unholy glow"
- icon_state = "wallglow"
- layer = ABOVE_NORMAL_TURF_LAYER
-
-/obj/effect/overlay/temp/cult/turf/floor
- icon_state = "floorglow"
- duration = 5
-
-
-/obj/effect/overlay/temp/ratvar
- name = "ratvar's light"
- icon = 'icons/effects/clockwork_effects.dmi'
- duration = 8
- randomdir = 0
- layer = ABOVE_NORMAL_TURF_LAYER
-
-/obj/effect/overlay/temp/ratvar/door
- icon_state = "ratvardoorglow"
- layer = CLOSED_DOOR_LAYER //above closed doors
-
-/obj/effect/overlay/temp/ratvar/door/window
- icon_state = "ratvarwindoorglow"
- layer = ABOVE_WINDOW_LAYER
-
-/obj/effect/overlay/temp/ratvar/beam
- icon_state = "ratvarbeamglow"
-
-/obj/effect/overlay/temp/ratvar/beam/door
- layer = CLOSED_DOOR_LAYER
-
-/obj/effect/overlay/temp/ratvar/beam/grille
- layer = BELOW_OBJ_LAYER
-
-/obj/effect/overlay/temp/ratvar/beam/itemconsume
- layer = HIGH_OBJ_LAYER
-
-/obj/effect/overlay/temp/ratvar/beam/falsewall
- layer = OBJ_LAYER
-
-/obj/effect/overlay/temp/ratvar/beam/catwalk
- layer = LATTICE_LAYER
-
-/obj/effect/overlay/temp/ratvar/wall
- icon_state = "ratvarwallglow"
-
-/obj/effect/overlay/temp/ratvar/wall/false
- layer = OBJ_LAYER
-
-/obj/effect/overlay/temp/ratvar/floor
- icon_state = "ratvarfloorglow"
-
-/obj/effect/overlay/temp/ratvar/floor/catwalk
- layer = LATTICE_LAYER
-
-/obj/effect/overlay/temp/ratvar/window
- icon_state = "ratvarwindowglow"
- layer = ABOVE_OBJ_LAYER
-
-/obj/effect/overlay/temp/ratvar/window/single
- icon_state = "ratvarwindowglow_s"
-
-/obj/effect/overlay/temp/ratvar/gear
- icon_state = "ratvargearglow"
- layer = BELOW_OBJ_LAYER
-
-/obj/effect/overlay/temp/ratvar/grille
- icon_state = "ratvargrilleglow"
- layer = BELOW_OBJ_LAYER
-
-/obj/effect/overlay/temp/ratvar/grille/broken
- icon_state = "ratvarbrokengrilleglow"
-
-/obj/effect/overlay/temp/ratvar/mending_mantra
- layer = ABOVE_MOB_LAYER
- duration = 20
- alpha = 200
- icon_state = "mending_mantra"
- light_range = 1.5
- light_color = "#1E8CE1"
-
-/obj/effect/overlay/temp/ratvar/mending_mantra/Initialize(mapload)
- . = ..()
- transform = matrix()*2
- var/matrix/M = transform
- M.Turn(90)
- animate(src, alpha = 20, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
- animate(src, transform = M, time = duration, flags = ANIMATION_PARALLEL)
-
-/obj/effect/overlay/temp/ratvar/volt_hit
- name = "volt blast"
- layer = ABOVE_MOB_LAYER
- duration = 5
- icon_state = "volt_hit"
- light_range = 1.5
- light_power = 2
- light_color = LIGHT_COLOR_ORANGE
- var/mob/user
- var/damage = 20
-
-/obj/effect/overlay/temp/ratvar/volt_hit/Initialize(mapload, caster, multiplier)
- if(multiplier)
- damage *= multiplier
- duration = max(round(damage * 0.2), 1)
- . = ..()
-
-/obj/effect/overlay/temp/ratvar/volt_hit/true/Initialize(mapload, caster, multiplier)
- . = ..()
- user = caster
- if(user)
- var/matrix/M = new
- M.Turn(Get_Angle(src, user))
- transform = M
- INVOKE_ASYNC(src, .proc/volthit)
-
-/obj/effect/overlay/temp/ratvar/volt_hit/proc/volthit()
- if(user)
- Beam(get_turf(user), "volt_ray", time=duration, maxdistance=8, beam_type=/obj/effect/ebeam/volt_ray)
- var/hit_amount = 0
- var/turf/T = get_turf(src)
- for(var/mob/living/L in T)
- if(is_servant_of_ratvar(L))
- continue
- var/obj/item/I = L.null_rod_check()
- if(I)
- L.visible_message("Strange energy flows into [L]'s [I.name]!", \
- "Your [I.name] shields you from [src]!")
- continue
- L.visible_message("[L] is struck by a [name]!", "You're struck by a [name]!")
- L.apply_damage(damage, BURN, "chest", L.run_armor_check("chest", "laser", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 0, "Your armor was penetrated by [src]!"))
- add_logs(user, L, "struck with a volt blast")
- hit_amount++
- for(var/obj/mecha/M in T)
- if(M.occupant)
- if(is_servant_of_ratvar(M.occupant))
- continue
- to_chat(M.occupant, "Your [M.name] is struck by a [name]!")
- M.visible_message("[M] is struck by a [name]!")
- M.take_damage(damage, BURN, 0, 0)
- hit_amount++
- if(hit_amount)
- playsound(src, 'sound/machines/defib_zap.ogg', damage*hit_amount, 1, -1)
- else
- playsound(src, "sparks", 50, 1)
-
-/obj/effect/overlay/temp/ratvar/ocular_warden
- name = "warden's gaze"
- layer = ABOVE_MOB_LAYER
- icon_state = "warden_gaze"
- duration = 3
-
-/obj/effect/overlay/temp/ratvar/ocular_warden/Initialize()
- . = ..()
- pixel_x = rand(-8, 8)
- pixel_y = rand(-10, 10)
- animate(src, alpha = 0, time = 3, easing = EASE_OUT)
-
-/obj/effect/overlay/temp/ratvar/spearbreak
- icon = 'icons/effects/64x64.dmi'
- icon_state = "ratvarspearbreak"
- layer = BELOW_MOB_LAYER
- pixel_y = -16
- pixel_x = -16
-
-/obj/effect/overlay/temp/ratvar/geis_binding
- icon_state = "geisbinding"
-
-/obj/effect/overlay/temp/ratvar/geis_binding/top
- icon_state = "geisbinding_top"
-
-/obj/effect/overlay/temp/ratvar/component
- icon = 'icons/obj/clockwork_objects.dmi'
- icon_state = "belligerent_eye"
- layer = ABOVE_MOB_LAYER
- duration = 10
-
-/obj/effect/overlay/temp/ratvar/component/Initialize()
- . = ..()
- transform = matrix()*0.75
- pixel_x = rand(-10, 10)
- pixel_y = rand(-10, -2)
- animate(src, pixel_y = pixel_y + 10, alpha = 50, time = 10, easing = EASE_OUT)
-
-/obj/effect/overlay/temp/ratvar/component/cogwheel
- icon_state = "vanguard_cogwheel"
-
-/obj/effect/overlay/temp/ratvar/component/capacitor
- icon_state = "geis_capacitor"
-
-/obj/effect/overlay/temp/ratvar/component/alloy
- icon_state = "replicant_alloy"
-
-/obj/effect/overlay/temp/ratvar/component/ansible
- icon_state = "hierophant_ansible"
-
-/obj/effect/overlay/temp/ratvar/sigil
- name = "glowing circle"
- icon_state = "sigildull"
-
-/obj/effect/overlay/temp/ratvar/sigil/transgression
- color = "#FAE48C"
- layer = ABOVE_MOB_LAYER
- duration = 70
- light_range = 5
- light_power = 2
- light_color = "#FAE48C"
-
-/obj/effect/overlay/temp/ratvar/sigil/transgression/Initialize()
- . = ..()
- var/oldtransform = transform
- animate(src, transform = matrix()*2, time = 5)
- animate(transform = oldtransform, alpha = 0, time = 65)
-
-/obj/effect/overlay/temp/ratvar/sigil/vitality
- color = "#1E8CE1"
- icon_state = "sigilactivepulse"
- layer = ABOVE_MOB_LAYER
- light_range = 1.4
- light_power = 0.5
- light_color = "#1E8CE1"
-
-/obj/effect/overlay/temp/ratvar/sigil/accession
- color = "#AF0AAF"
- layer = ABOVE_MOB_LAYER
- duration = 70
- icon_state = "sigilactiveoverlay"
- alpha = 0
-
-
-/obj/effect/overlay/temp/revenant
- name = "spooky lights"
- icon_state = "purplesparkles"
-
-/obj/effect/overlay/temp/revenant/cracks
- name = "glowing cracks"
- icon_state = "purplecrack"
- duration = 6
-
-
-/obj/effect/overlay/temp/gravpush
- name = "gravity wave"
- icon_state = "shieldsparkles"
- duration = 5
-
-/obj/effect/overlay/temp/telekinesis
- name = "telekinetic force"
- icon_state = "empdisable"
- duration = 5
-
-/obj/effect/overlay/temp/emp
- name = "emp sparks"
- icon_state = "empdisable"
-
-/obj/effect/overlay/temp/emp/pulse
- name = "emp pulse"
- icon_state = "emppulse"
- duration = 8
- randomdir = 0
-
-/obj/effect/overlay/temp/gib_animation
- icon = 'icons/mob/mob.dmi'
- duration = 15
-
-/obj/effect/overlay/temp/gib_animation/Initialize(mapload, gib_icon)
- icon_state = gib_icon // Needs to be before ..() so icon is correct
- . = ..()
-
-/obj/effect/overlay/temp/gib_animation/ex_act(severity)
- return //so the overlay isn't deleted by the explosion that gibbed the mob.
-
-/obj/effect/overlay/temp/gib_animation/animal
- icon = 'icons/mob/animal.dmi'
-
-/obj/effect/overlay/temp/dust_animation
- icon = 'icons/mob/mob.dmi'
- duration = 15
-
-/obj/effect/overlay/temp/dust_animation/Initialize(mapload, dust_icon)
- icon_state = dust_icon // Before ..() so the correct icon is flick()'d
- . = ..()
-
-/obj/effect/overlay/temp/mummy_animation
- icon = 'icons/mob/mob.dmi'
- icon_state = "mummy_revive"
- duration = 20
-
-/obj/effect/overlay/temp/heal //color is white by default, set to whatever is needed
- name = "healing glow"
- icon_state = "heal"
- duration = 15
-
-/obj/effect/overlay/temp/heal/Initialize(mapload, colour)
- if(colour)
- color = colour
- . = ..()
- pixel_x = rand(-12, 12)
- pixel_y = rand(-9, 0)
-
-/obj/effect/overlay/temp/kinetic_blast
- name = "kinetic explosion"
- icon = 'icons/obj/projectiles.dmi'
- icon_state = "kinetic_blast"
- layer = ABOVE_ALL_MOB_LAYER
- duration = 4
-
-/obj/effect/overlay/temp/explosion
- name = "explosion"
- icon = 'icons/effects/96x96.dmi'
- icon_state = "explosion"
- pixel_x = -32
- pixel_y = -32
- duration = 8
-
-/obj/effect/overlay/temp/explosion/fast
- icon_state = "explosionfast"
- duration = 4
-
-/obj/effect/overlay/temp/blob
- name = "blob"
- icon_state = "blob_attack"
- alpha = 140
- randomdir = 0
- duration = 6
-
-/obj/effect/overlay/temp/impact_effect
- icon_state = "impact_bullet"
- duration = 5
-
-/obj/effect/overlay/temp/impact_effect/Initialize(mapload, atom/target, obj/item/projectile/P)
- if(target == P.original) //the projectile hit the target originally clicked
- pixel_x = P.p_x + target.pixel_x - 16 + rand(-4,4)
- pixel_y = P.p_y + target.pixel_y - 16 + rand(-4,4)
- else
- pixel_x = target.pixel_x + rand(-4,4)
- pixel_y = target.pixel_y + rand(-4,4)
- . = ..()
-
-/obj/effect/overlay/temp/impact_effect/red_laser
- icon_state = "impact_laser"
- duration = 4
-
-/obj/effect/overlay/temp/impact_effect/red_laser/wall
- icon_state = "impact_laser_wall"
- duration = 10
-
-/obj/effect/overlay/temp/impact_effect/blue_laser
- icon_state = "impact_laser_blue"
- duration = 4
-
-/obj/effect/overlay/temp/impact_effect/green_laser
- icon_state = "impact_laser_green"
- duration = 4
-
-/obj/effect/overlay/temp/impact_effect/purple_laser
- icon_state = "impact_laser_purple"
- duration = 4
-
-/obj/effect/overlay/temp/impact_effect/ion
- icon_state = "shieldsparkles"
- duration = 6
-
-/obj/effect/overlay/temp/heart
- name = "heart"
- icon = 'icons/mob/animal.dmi'
- icon_state = "heart"
- duration = 25
-
-/obj/effect/overlay/temp/heart/Initialize(mapload)
- . = ..()
- pixel_x = rand(-4,4)
- pixel_y = rand(-4,4)
-
- animate(src, pixel_y = pixel_y + 32, alpha = 0, time = 25)
-
/obj/effect/overlay/palmtree_r
name = "Palm tree"
icon = 'icons/misc/beach2.dmi'
diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm
new file mode 100644
index 0000000000..65c9d30e47
--- /dev/null
+++ b/code/game/objects/effects/temporary_visuals/clockcult.dm
@@ -0,0 +1,218 @@
+//temporary visual effects(/obj/effect/overlay/temp) used by clockcult stuff
+/obj/effect/overlay/temp/ratvar
+ name = "ratvar's light"
+ icon = 'icons/effects/clockwork_effects.dmi'
+ duration = 8
+ randomdir = 0
+ layer = ABOVE_NORMAL_TURF_LAYER
+
+/obj/effect/overlay/temp/ratvar/door
+ icon_state = "ratvardoorglow"
+ layer = CLOSED_DOOR_LAYER //above closed doors
+
+/obj/effect/overlay/temp/ratvar/door/window
+ icon_state = "ratvarwindoorglow"
+ layer = ABOVE_WINDOW_LAYER
+
+/obj/effect/overlay/temp/ratvar/beam
+ icon_state = "ratvarbeamglow"
+
+/obj/effect/overlay/temp/ratvar/beam/door
+ layer = CLOSED_DOOR_LAYER
+
+/obj/effect/overlay/temp/ratvar/beam/grille
+ layer = BELOW_OBJ_LAYER
+
+/obj/effect/overlay/temp/ratvar/beam/itemconsume
+ layer = HIGH_OBJ_LAYER
+
+/obj/effect/overlay/temp/ratvar/beam/falsewall
+ layer = OBJ_LAYER
+
+/obj/effect/overlay/temp/ratvar/beam/catwalk
+ layer = LATTICE_LAYER
+
+/obj/effect/overlay/temp/ratvar/wall
+ icon_state = "ratvarwallglow"
+
+/obj/effect/overlay/temp/ratvar/wall/false
+ layer = OBJ_LAYER
+
+/obj/effect/overlay/temp/ratvar/floor
+ icon_state = "ratvarfloorglow"
+
+/obj/effect/overlay/temp/ratvar/floor/catwalk
+ layer = LATTICE_LAYER
+
+/obj/effect/overlay/temp/ratvar/window
+ icon_state = "ratvarwindowglow"
+ layer = ABOVE_OBJ_LAYER
+
+/obj/effect/overlay/temp/ratvar/window/single
+ icon_state = "ratvarwindowglow_s"
+
+/obj/effect/overlay/temp/ratvar/gear
+ icon_state = "ratvargearglow"
+ layer = BELOW_OBJ_LAYER
+
+/obj/effect/overlay/temp/ratvar/grille
+ icon_state = "ratvargrilleglow"
+ layer = BELOW_OBJ_LAYER
+
+/obj/effect/overlay/temp/ratvar/grille/broken
+ icon_state = "ratvarbrokengrilleglow"
+
+/obj/effect/overlay/temp/ratvar/mending_mantra
+ layer = ABOVE_MOB_LAYER
+ duration = 20
+ alpha = 200
+ icon_state = "mending_mantra"
+ light_range = 1.5
+ light_color = "#1E8CE1"
+
+/obj/effect/overlay/temp/ratvar/mending_mantra/Initialize(mapload)
+ . = ..()
+ transform = matrix()*2
+ var/matrix/M = transform
+ M.Turn(90)
+ animate(src, alpha = 20, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
+ animate(src, transform = M, time = duration, flags = ANIMATION_PARALLEL)
+
+/obj/effect/overlay/temp/ratvar/volt_hit
+ name = "volt blast"
+ layer = ABOVE_MOB_LAYER
+ duration = 5
+ icon_state = "volt_hit"
+ light_range = 1.5
+ light_power = 2
+ light_color = LIGHT_COLOR_ORANGE
+ var/mob/user
+ var/damage = 20
+
+/obj/effect/overlay/temp/ratvar/volt_hit/Initialize(mapload, caster, multiplier)
+ if(multiplier)
+ damage *= multiplier
+ duration = max(round(damage * 0.2), 1)
+ . = ..()
+
+/obj/effect/overlay/temp/ratvar/volt_hit/true/Initialize(mapload, caster, multiplier)
+ . = ..()
+ user = caster
+ if(user)
+ var/matrix/M = new
+ M.Turn(Get_Angle(src, user))
+ transform = M
+ INVOKE_ASYNC(src, .proc/volthit)
+
+/obj/effect/overlay/temp/ratvar/volt_hit/proc/volthit()
+ if(user)
+ Beam(get_turf(user), "volt_ray", time=duration, maxdistance=8, beam_type=/obj/effect/ebeam/volt_ray)
+ var/hit_amount = 0
+ var/turf/T = get_turf(src)
+ for(var/mob/living/L in T)
+ if(is_servant_of_ratvar(L))
+ continue
+ var/obj/item/I = L.null_rod_check()
+ if(I)
+ L.visible_message("Strange energy flows into [L]'s [I.name]!", \
+ "Your [I.name] shields you from [src]!")
+ continue
+ L.visible_message("[L] is struck by a [name]!", "You're struck by a [name]!")
+ L.apply_damage(damage, BURN, "chest", L.run_armor_check("chest", "laser", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 0, "Your armor was penetrated by [src]!"))
+ add_logs(user, L, "struck with a volt blast")
+ hit_amount++
+ for(var/obj/mecha/M in T)
+ if(M.occupant)
+ if(is_servant_of_ratvar(M.occupant))
+ continue
+ to_chat(M.occupant, "Your [M.name] is struck by a [name]!")
+ M.visible_message("[M] is struck by a [name]!")
+ M.take_damage(damage, BURN, 0, 0)
+ hit_amount++
+ if(hit_amount)
+ playsound(src, 'sound/machines/defib_zap.ogg', damage*hit_amount, 1, -1)
+ else
+ playsound(src, "sparks", 50, 1)
+
+/obj/effect/overlay/temp/ratvar/ocular_warden
+ name = "warden's gaze"
+ layer = ABOVE_MOB_LAYER
+ icon_state = "warden_gaze"
+ duration = 3
+
+/obj/effect/overlay/temp/ratvar/ocular_warden/Initialize()
+ . = ..()
+ pixel_x = rand(-8, 8)
+ pixel_y = rand(-10, 10)
+ animate(src, alpha = 0, time = 3, easing = EASE_OUT)
+
+/obj/effect/overlay/temp/ratvar/spearbreak
+ icon = 'icons/effects/64x64.dmi'
+ icon_state = "ratvarspearbreak"
+ layer = BELOW_MOB_LAYER
+ pixel_y = -16
+ pixel_x = -16
+
+/obj/effect/overlay/temp/ratvar/geis_binding
+ icon_state = "geisbinding"
+
+/obj/effect/overlay/temp/ratvar/geis_binding/top
+ icon_state = "geisbinding_top"
+
+/obj/effect/overlay/temp/ratvar/component
+ icon = 'icons/obj/clockwork_objects.dmi'
+ icon_state = "belligerent_eye"
+ layer = ABOVE_MOB_LAYER
+ duration = 10
+
+/obj/effect/overlay/temp/ratvar/component/Initialize()
+ . = ..()
+ transform = matrix()*0.75
+ pixel_x = rand(-10, 10)
+ pixel_y = rand(-10, -2)
+ animate(src, pixel_y = pixel_y + 10, alpha = 50, time = 10, easing = EASE_OUT)
+
+/obj/effect/overlay/temp/ratvar/component/cogwheel
+ icon_state = "vanguard_cogwheel"
+
+/obj/effect/overlay/temp/ratvar/component/capacitor
+ icon_state = "geis_capacitor"
+
+/obj/effect/overlay/temp/ratvar/component/alloy
+ icon_state = "replicant_alloy"
+
+/obj/effect/overlay/temp/ratvar/component/ansible
+ icon_state = "hierophant_ansible"
+
+/obj/effect/overlay/temp/ratvar/sigil
+ name = "glowing circle"
+ icon_state = "sigildull"
+
+/obj/effect/overlay/temp/ratvar/sigil/transgression
+ color = "#FAE48C"
+ layer = ABOVE_MOB_LAYER
+ duration = 70
+ light_range = 5
+ light_power = 2
+ light_color = "#FAE48C"
+
+/obj/effect/overlay/temp/ratvar/sigil/transgression/Initialize()
+ . = ..()
+ var/oldtransform = transform
+ animate(src, transform = matrix()*2, time = 5)
+ animate(transform = oldtransform, alpha = 0, time = 65)
+
+/obj/effect/overlay/temp/ratvar/sigil/vitality
+ color = "#1E8CE1"
+ icon_state = "sigilactivepulse"
+ layer = ABOVE_MOB_LAYER
+ light_range = 1.4
+ light_power = 0.5
+ light_color = "#1E8CE1"
+
+/obj/effect/overlay/temp/ratvar/sigil/accession
+ color = "#AF0AAF"
+ layer = ABOVE_MOB_LAYER
+ duration = 70
+ icon_state = "sigilactiveoverlay"
+ alpha = 0
diff --git a/code/game/objects/effects/temporary_visuals/cult.dm b/code/game/objects/effects/temporary_visuals/cult.dm
new file mode 100644
index 0000000000..ad3f84fe06
--- /dev/null
+++ b/code/game/objects/effects/temporary_visuals/cult.dm
@@ -0,0 +1,144 @@
+//temporary visual effects(/obj/effect/overlay/temp) used by cult stuff
+/obj/effect/overlay/temp/cult
+ icon = 'icons/effects/cult_effects.dmi'
+ randomdir = 0
+ duration = 10
+
+/obj/effect/overlay/temp/cult/sparks
+ randomdir = 1
+ name = "blood sparks"
+ icon_state = "bloodsparkles"
+
+/obj/effect/overlay/temp/cult/blood // The traditional teleport
+ name = "blood jaunt"
+ duration = 12
+ icon_state = "bloodin"
+
+/obj/effect/overlay/temp/cult/blood/out
+ icon_state = "bloodout"
+
+/obj/effect/overlay/temp/dir_setting/cult/phase // The veil shifter teleport
+ name = "phase glow"
+ duration = 7
+ icon_state = "cultin"
+
+/obj/effect/overlay/temp/dir_setting/cult/phase/out
+ icon_state = "cultout"
+
+/obj/effect/overlay/temp/cult/sac
+ name = "maw of Nar-Sie"
+ icon_state = "sacconsume"
+
+/obj/effect/overlay/temp/cult/door
+ name = "unholy glow"
+ icon_state = "doorglow"
+ layer = CLOSED_FIREDOOR_LAYER //above closed doors
+
+/obj/effect/overlay/temp/cult/door/unruned
+ icon_state = "unruneddoorglow"
+
+/obj/effect/overlay/temp/cult/turf
+ name = "unholy glow"
+ icon_state = "wallglow"
+ layer = ABOVE_NORMAL_TURF_LAYER
+
+/obj/effect/overlay/temp/cult/turf/floor
+ icon_state = "floorglow"
+ duration = 5
+
+//visuals for runes being magically created
+/obj/effect/overlay/temp/cult/rune_spawn
+ icon_state = "runeouter"
+ alpha = 0
+ var/turnedness = 179 //179 turns counterclockwise, 181 turns clockwise
+
+/obj/effect/overlay/temp/cult/rune_spawn/Initialize(mapload, set_duration, set_color)
+ if(isnum(set_duration))
+ duration = set_duration
+ if(set_color)
+ add_atom_colour(set_color, FIXED_COLOUR_PRIORITY)
+ . = ..()
+ var/oldtransform = transform
+ transform = matrix()*2
+ var/matrix/M = transform
+ M.Turn(turnedness)
+ transform = M
+ animate(src, alpha = 255, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
+ animate(src, transform = oldtransform, time = duration, flags = ANIMATION_PARALLEL)
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune1
+ icon_state = "rune1words"
+ turnedness = 181
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune1/inner
+ icon_state = "rune1inner"
+ turnedness = 179
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune1/center
+ icon_state = "rune1center"
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune2
+ icon_state = "rune2words"
+ turnedness = 181
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune2/inner
+ icon_state = "rune2inner"
+ turnedness = 179
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune2/center
+ icon_state = "rune2center"
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune3
+ icon_state = "rune3words"
+ turnedness = 181
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune3/inner
+ icon_state = "rune3inner"
+ turnedness = 179
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune3/center
+ icon_state = "rune3center"
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune4
+ icon_state = "rune4words"
+ turnedness = 181
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune4/inner
+ icon_state = "rune4inner"
+ turnedness = 179
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune4/center
+ icon_state = "rune4center"
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune5
+ icon_state = "rune5words"
+ turnedness = 181
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune5/inner
+ icon_state = "rune5inner"
+ turnedness = 179
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune5/center
+ icon_state = "rune5center"
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune6
+ icon_state = "rune6words"
+ turnedness = 181
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune6/inner
+ icon_state = "rune6inner"
+ turnedness = 179
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune6/center
+ icon_state = "rune6center"
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune7
+ icon_state = "rune7words"
+ turnedness = 181
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune7/inner
+ icon_state = "rune7inner"
+ turnedness = 179
+
+/obj/effect/overlay/temp/cult/rune_spawn/rune7/center
+ icon_state = "rune7center"
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
new file mode 100644
index 0000000000..2ceea0aced
--- /dev/null
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -0,0 +1,312 @@
+//unsorted miscellaneous temporary visuals
+/obj/effect/overlay/temp/dir_setting/bloodsplatter
+ icon = 'icons/effects/blood.dmi'
+ duration = 5
+ randomdir = FALSE
+ layer = BELOW_MOB_LAYER
+ var/splatter_type = "splatter"
+
+/obj/effect/overlay/temp/dir_setting/bloodsplatter/Initialize(mapload, set_dir)
+ if(set_dir in GLOB.diagonals)
+ icon_state = "[splatter_type][pick(1, 2, 6)]"
+ else
+ icon_state = "[splatter_type][pick(3, 4, 5)]"
+ . = ..()
+ var/target_pixel_x = 0
+ var/target_pixel_y = 0
+ switch(set_dir)
+ if(NORTH)
+ target_pixel_y = 16
+ if(SOUTH)
+ target_pixel_y = -16
+ layer = ABOVE_MOB_LAYER
+ if(EAST)
+ target_pixel_x = 16
+ if(WEST)
+ target_pixel_x = -16
+ if(NORTHEAST)
+ target_pixel_x = 16
+ target_pixel_y = 16
+ if(NORTHWEST)
+ target_pixel_x = -16
+ target_pixel_y = 16
+ if(SOUTHEAST)
+ target_pixel_x = 16
+ target_pixel_y = -16
+ layer = ABOVE_MOB_LAYER
+ if(SOUTHWEST)
+ target_pixel_x = -16
+ target_pixel_y = -16
+ layer = ABOVE_MOB_LAYER
+ animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
+
+/obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter
+ splatter_type = "xsplatter"
+
+/obj/effect/overlay/temp/dir_setting/speedbike_trail
+ name = "speedbike trails"
+ icon_state = "ion_fade"
+ layer = BELOW_MOB_LAYER
+ duration = 10
+ randomdir = 0
+
+/obj/effect/overlay/temp/dir_setting/firing_effect
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "firing_effect"
+ duration = 2
+
+/obj/effect/overlay/temp/dir_setting/firing_effect/setDir(newdir)
+ switch(newdir)
+ if(NORTH)
+ layer = BELOW_MOB_LAYER
+ pixel_x = rand(-3,3)
+ pixel_y = rand(4,6)
+ if(SOUTH)
+ pixel_x = rand(-3,3)
+ pixel_y = rand(-1,1)
+ else
+ pixel_x = rand(-1,1)
+ pixel_y = rand(-1,1)
+ ..()
+
+/obj/effect/overlay/temp/dir_setting/firing_effect/energy
+ icon_state = "firing_effect_energy"
+ duration = 3
+
+/obj/effect/overlay/temp/dir_setting/firing_effect/magic
+ icon_state = "shieldsparkles"
+ duration = 3
+
+/obj/effect/overlay/temp/dir_setting/ninja
+ name = "ninja shadow"
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "uncloak"
+ duration = 9
+
+/obj/effect/overlay/temp/dir_setting/ninja/cloak
+ icon_state = "cloak"
+
+/obj/effect/overlay/temp/dir_setting/ninja/shadow
+ icon_state = "shadow"
+
+/obj/effect/overlay/temp/dir_setting/ninja/phase
+ name = "ninja energy"
+ icon_state = "phasein"
+
+/obj/effect/overlay/temp/dir_setting/ninja/phase/out
+ icon_state = "phaseout"
+
+/obj/effect/overlay/temp/dir_setting/wraith
+ name = "blood"
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "phase_shift2"
+ duration = 12
+
+/obj/effect/overlay/temp/dir_setting/wraith/out
+ icon_state = "phase_shift"
+
+/obj/effect/overlay/temp/dir_setting/tailsweep
+ icon_state = "tailsweep"
+ duration = 4
+
+/obj/effect/overlay/temp/wizard
+ name = "water"
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "reappear"
+ duration = 5
+
+/obj/effect/overlay/temp/wizard/out
+ icon_state = "liquify"
+ duration = 12
+
+/obj/effect/overlay/temp/monkeyify
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "h2monkey"
+ duration = 22
+
+/obj/effect/overlay/temp/monkeyify/humanify
+ icon_state = "monkey2h"
+
+/obj/effect/overlay/temp/borgflash
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "blspell"
+ duration = 5
+
+/obj/effect/overlay/temp/guardian
+ randomdir = 0
+
+/obj/effect/overlay/temp/guardian/phase
+ duration = 5
+ icon_state = "phasein"
+
+/obj/effect/overlay/temp/guardian/phase/out
+ icon_state = "phaseout"
+
+/obj/effect/overlay/temp/decoy
+ desc = "It's a decoy!"
+ duration = 15
+
+/obj/effect/overlay/temp/decoy/Initialize(mapload, atom/mimiced_atom)
+ . = ..()
+ alpha = initial(alpha)
+ if(mimiced_atom)
+ name = mimiced_atom.name
+ appearance = mimiced_atom.appearance
+ setDir(mimiced_atom.dir)
+ mouse_opacity = 0
+
+/obj/effect/overlay/temp/decoy/fading/Initialize(mapload, atom/mimiced_atom)
+ . = ..()
+ animate(src, alpha = 0, time = duration)
+
+/obj/effect/overlay/temp/decoy/fading/fivesecond
+ duration = 50
+
+/obj/effect/overlay/temp/small_smoke
+ icon_state = "smoke"
+ duration = 50
+
+/obj/effect/overlay/temp/fire
+ icon = 'icons/effects/fire.dmi'
+ icon_state = "3"
+ duration = 20
+
+/obj/effect/overlay/temp/revenant
+ name = "spooky lights"
+ icon_state = "purplesparkles"
+
+/obj/effect/overlay/temp/revenant/cracks
+ name = "glowing cracks"
+ icon_state = "purplecrack"
+ duration = 6
+
+/obj/effect/overlay/temp/gravpush
+ name = "gravity wave"
+ icon_state = "shieldsparkles"
+ duration = 5
+
+/obj/effect/overlay/temp/telekinesis
+ name = "telekinetic force"
+ icon_state = "empdisable"
+ duration = 5
+
+/obj/effect/overlay/temp/emp
+ name = "emp sparks"
+ icon_state = "empdisable"
+
+/obj/effect/overlay/temp/emp/pulse
+ name = "emp pulse"
+ icon_state = "emppulse"
+ duration = 8
+ randomdir = 0
+
+/obj/effect/overlay/temp/gib_animation
+ icon = 'icons/mob/mob.dmi'
+ duration = 15
+
+/obj/effect/overlay/temp/gib_animation/Initialize(mapload, gib_icon)
+ icon_state = gib_icon // Needs to be before ..() so icon is correct
+ . = ..()
+
+/obj/effect/overlay/temp/gib_animation/animal
+ icon = 'icons/mob/animal.dmi'
+
+/obj/effect/overlay/temp/dust_animation
+ icon = 'icons/mob/mob.dmi'
+ duration = 15
+
+/obj/effect/overlay/temp/dust_animation/Initialize(mapload, dust_icon)
+ icon_state = dust_icon // Before ..() so the correct icon is flick()'d
+ . = ..()
+
+/obj/effect/overlay/temp/mummy_animation
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "mummy_revive"
+ duration = 20
+
+/obj/effect/overlay/temp/heal //color is white by default, set to whatever is needed
+ name = "healing glow"
+ icon_state = "heal"
+ duration = 15
+
+/obj/effect/overlay/temp/heal/Initialize(mapload, set_color)
+ if(set_color)
+ add_atom_colour(set_color, FIXED_COLOUR_PRIORITY)
+ . = ..()
+ pixel_x = rand(-12, 12)
+ pixel_y = rand(-9, 0)
+
+/obj/effect/overlay/temp/kinetic_blast
+ name = "kinetic explosion"
+ icon = 'icons/obj/projectiles.dmi'
+ icon_state = "kinetic_blast"
+ layer = ABOVE_ALL_MOB_LAYER
+ duration = 4
+
+/obj/effect/overlay/temp/explosion
+ name = "explosion"
+ icon = 'icons/effects/96x96.dmi'
+ icon_state = "explosion"
+ pixel_x = -32
+ pixel_y = -32
+ duration = 8
+
+/obj/effect/overlay/temp/explosion/fast
+ icon_state = "explosionfast"
+ duration = 4
+
+/obj/effect/overlay/temp/blob
+ name = "blob"
+ icon_state = "blob_attack"
+ alpha = 140
+ randomdir = 0
+ duration = 6
+
+/obj/effect/overlay/temp/impact_effect
+ icon_state = "impact_bullet"
+ duration = 5
+
+/obj/effect/overlay/temp/impact_effect/Initialize(mapload, atom/target, obj/item/projectile/P)
+ if(target == P.original) //the projectile hit the target originally clicked
+ pixel_x = P.p_x + target.pixel_x - 16 + rand(-4,4)
+ pixel_y = P.p_y + target.pixel_y - 16 + rand(-4,4)
+ else
+ pixel_x = target.pixel_x + rand(-4,4)
+ pixel_y = target.pixel_y + rand(-4,4)
+ . = ..()
+
+/obj/effect/overlay/temp/impact_effect/red_laser
+ icon_state = "impact_laser"
+ duration = 4
+
+/obj/effect/overlay/temp/impact_effect/red_laser/wall
+ icon_state = "impact_laser_wall"
+ duration = 10
+
+/obj/effect/overlay/temp/impact_effect/blue_laser
+ icon_state = "impact_laser_blue"
+ duration = 4
+
+/obj/effect/overlay/temp/impact_effect/green_laser
+ icon_state = "impact_laser_green"
+ duration = 4
+
+/obj/effect/overlay/temp/impact_effect/purple_laser
+ icon_state = "impact_laser_purple"
+ duration = 4
+
+/obj/effect/overlay/temp/impact_effect/ion
+ icon_state = "shieldsparkles"
+ duration = 6
+
+/obj/effect/overlay/temp/heart
+ name = "heart"
+ icon = 'icons/mob/animal.dmi'
+ icon_state = "heart"
+ duration = 25
+
+/obj/effect/overlay/temp/heart/Initialize(mapload)
+ . = ..()
+ pixel_x = rand(-4,4)
+ pixel_y = rand(-4,4)
+ animate(src, pixel_y = pixel_y + 32, alpha = 0, time = 25)
diff --git a/code/game/objects/effects/temporary_visuals/temporary_visual.dm b/code/game/objects/effects/temporary_visuals/temporary_visual.dm
new file mode 100644
index 0000000000..8c7a178bd6
--- /dev/null
+++ b/code/game/objects/effects/temporary_visuals/temporary_visual.dm
@@ -0,0 +1,37 @@
+//temporary visual effects
+/obj/effect/overlay/temp
+ icon_state = "nothing"
+ anchored = 1
+ layer = ABOVE_MOB_LAYER
+ mouse_opacity = 0
+ var/duration = 10 //in deciseconds
+ var/randomdir = TRUE
+ var/timerid
+
+/obj/effect/overlay/temp/Initialize()
+ . = ..()
+ if(randomdir)
+ setDir(pick(GLOB.cardinal))
+
+ timerid = QDEL_IN(src, duration)
+
+/obj/effect/overlay/temp/Destroy()
+ . = ..()
+ deltimer(timerid)
+
+/obj/effect/overlay/temp/singularity_act()
+ return
+
+/obj/effect/overlay/temp/singularity_pull()
+ return
+
+/obj/effect/overlay/temp/ex_act()
+ return
+
+/obj/effect/overlay/temp/dir_setting
+ randomdir = FALSE
+
+/obj/effect/overlay/temp/dir_setting/Initialize(mapload, set_dir)
+ if(set_dir)
+ setDir(set_dir)
+ . = ..()
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 8dc9bd89b2..4a69fdff87 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -528,6 +528,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/throw_impact(atom/A)
if(A && !QDELETED(A))
+ if(is_hot() && isliving(A))
+ var/mob/living/L = A
+ L.IgniteMob()
var/itempush = 1
if(w_class < 4)
itempush = 0 //too light to push anything
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index f38cad82f2..abf7f5b827 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -504,6 +504,113 @@
S.change_head_color(color2)
dropped = TRUE
+//Peacekeeper Cyborg Projectile Dampenening Field
+/obj/item/borg/projectile_dampen
+ name = "Hyperkinetic Dampening projector"
+ desc = "A device that projects a dampening field that weakens kinetic energy above a certain threshold. Projects a field that drains power per second \
+ while active, that will weaken and slow damaging projectiles inside its field. Still being a prototype, it tends to induce a charge on ungrounded metallic surfaces."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "shield"
+ var/maxenergy = 1500
+ var/energy = 1500
+ var/energy_recharge = 7.5
+ var/energy_recharge_cyborg_drain_coefficient = 0.4
+ var/cyborg_cell_critical_percentage = 0.05
+ var/mob/living/silicon/robot/host = null
+ var/datum/proximity_monitor/advanced/dampening_field
+ var/projectile_damage_coefficient = 0.5
+ var/projectile_damage_tick_ecost_coefficient = 2 //Lasers get half their damage chopped off, drains 50 power/tick. Note that fields are processed 5 times per second.
+ var/projectile_speed_coefficient = 1.5 //Higher the coefficient slower the projectile.
+ var/projectile_tick_speed_ecost = 15
+ var/current_damage_dampening = 0
+ var/list/obj/item/projectile/tracked
+ var/image/projectile_effect
+ var/field_radius = 3
+
+/obj/item/borg/projectile_dampen/debug
+ maxenergy = 50000
+ energy = 50000
+ energy_recharge = 5000
+
+/obj/item/borg/projectile_dampen/Initialize()
+ . = ..()
+ projectile_effect = image('icons/effects/fields.dmi', "projectile_dampen_effect")
+ tracked = list()
+ icon_state = "shield0"
+ START_PROCESSING(SSfastprocess, src)
+
+/obj/item/borg/projectile_dampen/Destroy()
+ STOP_PROCESSING(SSfastprocess, src)
+ return ..()
+
+/obj/item/borg/projectile_dampen/attack_self(mob/user)
+ var/active = FALSE
+ if(!istype(dampening_field))
+ activate_field()
+ active = TRUE
+ else
+ deactivate_field()
+ active = FALSE
+ to_chat(user, "You [active? "activate":"deactivate"] the [src].")
+ icon_state = "[initial(icon_state)][active]"
+
+/obj/item/borg/projectile_dampen/proc/activate_field()
+ if(!istype(dampening_field))
+ dampening_field = make_field(/datum/proximity_monitor/advanced/peaceborg_dampener, list("current_range" = field_radius, "host" = src, "projector" = src))
+
+/obj/item/borg/projectile_dampen/proc/deactivate_field()
+ QDEL_NULL(dampening_field)
+ visible_message("The [src] shuts off!")
+ for(var/obj/item/projectile/P in tracked)
+ restore_projectile(P)
+
+/obj/item/borg/projectile_dampen/process()
+ process_recharge()
+ process_usage()
+ update_location()
+
+/obj/item/borg/projectile_dampen/proc/update_location()
+ if(dampening_field)
+ dampening_field.HandleMove()
+
+/obj/item/borg/projectile_dampen/proc/process_usage()
+ var/usage = 0
+ for(var/I in tracked)
+ if(!tracked[I]) //No damage
+ continue
+ usage += projectile_tick_speed_ecost
+ usage += (current_damage_dampening * projectile_damage_tick_ecost_coefficient)
+ energy = Clamp(energy - usage, 0, maxenergy)
+ if(energy <= 0)
+ deactivate_field()
+ visible_message("The [src] blinks \"ENERGY DEPLETED\"")
+
+/obj/item/borg/projectile_dampen/proc/process_recharge()
+ if(!istype(host))
+ energy = Clamp(energy + energy_recharge, 0, maxenergy)
+ return
+ if((host.cell.charge >= (host.cell.maxcharge * cyborg_cell_critical_percentage)) && (energy < maxenergy))
+ host.cell.use(energy_recharge*energy_recharge_cyborg_drain_coefficient)
+ energy += energy_recharge
+
+/obj/item/borg/projectile_dampen/proc/dampen_projectile(obj/item/projectile/P, track_projectile = TRUE)
+ if(tracked[P])
+ return
+ if(track_projectile)
+ tracked[P] = P.damage
+ current_damage_dampening += P.damage
+ P.damage *= projectile_damage_coefficient
+ P.speed *= projectile_speed_coefficient
+ P.add_overlay(projectile_effect)
+
+/obj/item/borg/projectile_dampen/proc/restore_projectile(obj/item/projectile/P)
+ tracked -= P
+ P.damage *= (1/projectile_damage_coefficient)
+ P.speed *= (1/projectile_speed_coefficient)
+ P.cut_overlay(projectile_effect)
+ current_damage_dampening -= P.damage
+
+
/**********************************************************************
HUD/SIGHT things
***********************************************************************/
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 5353341ab6..69e00e057e 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -279,6 +279,28 @@
resistance_flags = FLAMMABLE
+/obj/item/toy/windupToolbox
+ name = "windup toolbox"
+ desc = "A replica toolbox that rumbles when you turn the key"
+ icon_state = "his_grace"
+ item_state = "artistic_toolbox"
+ var/active = FALSE
+ icon = 'icons/obj/weapons.dmi'
+ attack_verb = list("robusted")
+
+/obj/item/toy/windupToolbox/attack_self(mob/user)
+ if(!active)
+ icon_state = "his_grace_awakened"
+ to_chat(user, "You wind up [src], it begins to rumble.")
+ active = TRUE
+ addtimer(CALLBACK(src, .proc/stopRumble), 600)
+ else
+ to_chat(user, "[src] is already active.")
+
+/obj/item/toy/windupToolbox/proc/stopRumble()
+ icon_state = initial(icon_state)
+ active = FALSE
+
/*
* Subtype of Double-Bladed Energy Swords
*/
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index 3cf5305dcb..82229bb7cf 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -472,8 +472,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM
flags = CONDUCT
slot_flags = SLOT_BELT
var/lit = 0
+ var/fancy = TRUE
heat = 1500
resistance_flags = FIRE_PROOF
+ light_color = LIGHT_COLOR_FIRE
/obj/item/weapon/lighter/update_icon()
if(lit)
@@ -484,37 +486,28 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/weapon/lighter/ignition_effect(atom/A, mob/user)
. = "With a single flick of their wrist, [user] smoothly lights [A] with [src]. Damn [user.p_theyre()] cool."
-/obj/item/weapon/lighter/greyscale
- name = "cheap lighter"
- desc = "A cheap-as-free lighter."
- icon_state = "lighter"
-
-/obj/item/weapon/lighter/greyscale/Initialize()
- . = ..()
- add_atom_colour(color2hex(randomColor(1)), FIXED_COLOUR_PRIORITY)
- update_icon()
-
-/obj/item/weapon/lighter/greyscale/update_icon()
- cut_overlays()
- var/mutable_appearance/base_overlay = mutable_appearance(icon,"[initial(icon_state)]_base")
- base_overlay.appearance_flags = RESET_COLOR //the edging doesn't change color
+/obj/item/weapon/lighter/proc/set_lit(new_lit)
+ lit = new_lit
if(lit)
- base_overlay.icon_state = "[initial(icon_state)]_on"
- add_overlay(base_overlay)
-
-/obj/item/weapon/lighter/greyscale/ignition_effect(atom/A, mob/user)
- . = "After some fiddling, [user] manages to light [A] with [src]."
+ force = 5
+ damtype = "fire"
+ hitsound = 'sound/items/welder.ogg'
+ attack_verb = list("burnt", "singed")
+ set_light(1)
+ START_PROCESSING(SSobj, src)
+ else
+ hitsound = "swing_hit"
+ force = 0
+ attack_verb = null //human_defense.dm takes care of it
+ set_light(0)
+ STOP_PROCESSING(SSobj, src)
+ update_icon()
/obj/item/weapon/lighter/attack_self(mob/living/user)
if(user.is_holding(src))
if(!lit)
- lit = 1
- update_icon()
- force = 5
- damtype = "fire"
- hitsound = 'sound/items/welder.ogg'
- attack_verb = list("burnt", "singed")
- if(!istype(src, /obj/item/weapon/lighter/greyscale))
+ set_lit(TRUE)
+ if(fancy)
user.visible_message("Without even breaking stride, [user] flips open and lights [src] in one smooth movement.", "Without even breaking stride, you flip open and lights [src] in one smooth movement.")
else
var/prot = FALSE
@@ -534,20 +527,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM
user.apply_damage(5, BURN, hitzone)
user.visible_message("After a few attempts, [user] manages to light [src] - however, [user.p_they()] burn their finger in the process.", "You burn yourself while lighting the lighter!")
- set_light(1)
- START_PROCESSING(SSobj, src)
else
- lit = 0
- update_icon()
- hitsound = "swing_hit"
- force = 0
- attack_verb = null //human_defense.dm takes care of it
- if(!istype(src, /obj/item/weapon/lighter/greyscale))
+ set_lit(FALSE)
+ if(fancy)
user.visible_message("You hear a quiet click, as [user] shuts off [src] without even looking at what [user.p_theyre()] doing. Wow.", "You quietly shut off [src] without even looking at what you're doing. Wow.")
else
user.visible_message("[user] quietly shuts off [src].", "You quietly shut off [src].")
- set_light(0)
- STOP_PROCESSING(SSobj, src)
else
. = ..()
@@ -562,7 +547,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(M == user)
cig.attackby(src, user)
else
- if(!istype(src, /obj/item/weapon/lighter/greyscale))
+ if(fancy)
cig.light("[user] whips the [name] out and holds it for [M]. [user.p_their(TRUE)] arm is as steady as the unflickering flame they light \the [cig] with.")
else
cig.light("[user] holds the [name] out for [M], and lights the [cig.name].")
@@ -575,6 +560,30 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/weapon/lighter/is_hot()
return lit * heat
+
+/obj/item/weapon/lighter/greyscale
+ name = "cheap lighter"
+ desc = "A cheap-as-free lighter."
+ icon_state = "lighter"
+ fancy = FALSE
+
+/obj/item/weapon/lighter/greyscale/Initialize()
+ . = ..()
+ add_atom_colour(color2hex(randomColor(1)), FIXED_COLOUR_PRIORITY)
+ update_icon()
+
+/obj/item/weapon/lighter/greyscale/update_icon()
+ cut_overlays()
+ var/mutable_appearance/base_overlay = mutable_appearance(icon,"[initial(icon_state)]_base")
+ base_overlay.appearance_flags = RESET_COLOR //the edging doesn't change color
+ if(lit)
+ base_overlay.icon_state = "[initial(icon_state)]_on"
+ add_overlay(base_overlay)
+
+/obj/item/weapon/lighter/greyscale/ignition_effect(atom/A, mob/user)
+ . = "After some fiddling, [user] manages to light [A] with [src]."
+
+
///////////
//ROLLING//
///////////
diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm
index 00d6a55f2e..c50ef26b81 100644
--- a/code/game/objects/items/weapons/dna_injector.dm
+++ b/code/game/objects/items/weapons/dna_injector.dm
@@ -50,9 +50,7 @@
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
M.updateappearance(mutations_overlay_update=1)
log_attack(log_msg)
- else
- to_chat(user, "It appears that [M] does not have compatible DNA.")
- return
+ return TRUE
/obj/item/weapon/dnainjector/attack(mob/target, mob/user)
if(!user.IsAdvancedToolUser())
@@ -79,7 +77,9 @@
add_logs(user, target, "injected", src)
- inject(target, user) //Now we actually do the heavy lifting.
+ if(!inject(target, user)) //Now we actually do the heavy lifting.
+ to_chat(user, "It appears that [target] does not have compatible DNA.")
+
used = 1
icon_state = "dnainjector0"
desc += " This one is used up."
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index e478813558..a5f5eb6133 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -48,23 +48,27 @@
/obj/item/weapon/grenade/attack_self(mob/user)
if(!active)
if(clown_check(user))
- to_chat(user, "You prime the [name]! [det_time/10] seconds!")
- playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
- active = 1
- icon_state = initial(icon_state) + "_active"
- add_fingerprint(user)
- var/turf/bombturf = get_turf(src)
- var/area/A = get_area(bombturf)
- var/message = "[ADMIN_LOOKUPFLW(user)]) has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]"
- GLOB.bombers += message
- message_admins(message)
- log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
+ preprime(user)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
- spawn(det_time)
- prime()
+/obj/item/weapon/grenade/proc/preprime(mob/user)
+ if(user)
+ to_chat(user, "You prime the [name]! [det_time/10] seconds!")
+ playsound(loc, 'sound/weapons/armbomb.ogg', 60, 1)
+ active = TRUE
+ icon_state = initial(icon_state) + "_active"
+ add_fingerprint(user)
+ var/turf/bombturf = get_turf(src)
+ var/area/A = get_area(bombturf)
+ if(user)
+ var/message = "[ADMIN_LOOKUPFLW(user)]) has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]"
+ GLOB.bombers += message
+ message_admins(message)
+ log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
+
+ addtimer(CALLBACK(src, .proc/prime), det_time)
/obj/item/weapon/grenade/proc/prime()
@@ -104,4 +108,4 @@
if(damage && attack_type == PROJECTILE_ATTACK && prob(15))
owner.visible_message("[attack_text] hits [owner]'s [src], setting it off! What a shot!")
prime()
- return 1 //It hit the grenade, not them
\ No newline at end of file
+ return 1 //It hit the grenade, not them
diff --git a/code/game/objects/items/weapons/grenades/plastic.dm b/code/game/objects/items/weapons/grenades/plastic.dm
index 3118d731f2..21a71f371d 100644
--- a/code/game/objects/items/weapons/grenades/plastic.dm
+++ b/code/game/objects/items/weapons/grenades/plastic.dm
@@ -18,6 +18,10 @@
plastic_overlay = mutable_appearance(icon, "[item_state]2")
..()
+/obj/item/weapon/grenade/plastic/Initialize(mapload)
+ . = ..()
+ SET_SECONDARY_FLAG(src, NO_EMP_WIRES)
+
/obj/item/weapon/grenade/plastic/Destroy()
qdel(nadeassembly)
nadeassembly = null
diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm
index 86c517aa99..64fb4c7ecc 100644
--- a/code/game/objects/items/weapons/pneumaticCannon.dm
+++ b/code/game/objects/items/weapons/pneumaticCannon.dm
@@ -244,7 +244,7 @@
range_multiplier = 3
fire_mode = PCANNON_FIFO
throw_amount = 1
- maxWeightClass = 100 //50 pies. :^)
+ maxWeightClass = 150 //50 pies. :^)
clumsyCheck = FALSE
/obj/item/weapon/pneumatic_cannon/pie/can_load_item(obj/item/I, mob/user)
@@ -252,3 +252,22 @@
return ..()
to_chat(user, "[src] only accepts pies!")
return FALSE
+
+/obj/item/weapon/pneumatic_cannon/pie/selfcharge
+ automatic = TRUE
+ var/charge_amount = 1
+ var/charge_ticks = 1
+ var/charge_tick = 0
+ maxWeightClass = 60 //20 pies.
+
+/obj/item/weapon/pneumatic_cannon/pie/selfcharge/Initialize()
+ . = ..()
+ START_PROCESSING(SSobj, src)
+
+/obj/item/weapon/pneumatic_cannon/pie/selfcharge/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/item/weapon/pneumatic_cannon/pie/selfcharge/process()
+ if(++charge_tick >= charge_ticks)
+ fill_with_type(/obj/item/weapon/reagent_containers/food/snacks/pie, charge_amount)
diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm
old mode 100644
new mode 100755
index f1f16a69b7..4ffa4a9b89
--- a/code/game/objects/items/weapons/tanks/tank_types.dm
+++ b/code/game/objects/items/weapons/tanks/tank_types.dm
@@ -140,6 +140,8 @@
item_state = "plasmaman_tank_belt"
slot_flags = SLOT_BELT
force = 5
+ volume = 3
+ w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
/obj/item/weapon/tank/internals/plasmaman/belt/full/New()
..()
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index 82378b094c..05414f0a4d 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -149,8 +149,8 @@
/obj/effect/mob_spawn/human/golem/attack_hand(mob/user)
if(isgolem(user) && can_transfer)
- var/transfer = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No")
- if(!transfer)
+ var/transfer_choice = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No")
+ if(transfer_choice != "Yes")
return
log_game("[user.ckey] golem-swapped into [src]")
user.visible_message("A faint light leaves [user], moving to [src] and animating it!","You leave your old body behind, and transfer into [src]!")
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 09d9507b4e..0c11418003 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -440,7 +440,7 @@
dir = FULLTILE_WINDOW_DIR
max_integrity = 50
fulltile = 1
- flags = NONE
+ flags = PREVENT_CLICK_UNDER
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile,/obj/structure/window/reinforced/highpressure/fulltile, /obj/structure/window/reinforced/tinted/fulltile)
glass_amount = 2
@@ -454,7 +454,7 @@
dir = FULLTILE_WINDOW_DIR
max_integrity = 100
fulltile = 1
- flags = NONE
+ flags = PREVENT_CLICK_UNDER
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile,/obj/structure/window/reinforced/highpressure/fulltile, /obj/structure/window/reinforced/tinted/fulltile)
@@ -467,7 +467,7 @@
dir = FULLTILE_WINDOW_DIR
max_integrity = 1000
fulltile = 1
- flags = NONE
+ flags = PREVENT_CLICK_UNDER
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile,/obj/structure/window/reinforced/highpressure/fulltile, /obj/structure/window/reinforced/tinted/fulltile)
level = 3
@@ -481,7 +481,7 @@
icon_state = "tinted_window"
dir = FULLTILE_WINDOW_DIR
fulltile = 1
- flags = NONE
+ flags = PREVENT_CLICK_UNDER
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile,/obj/structure/window/reinforced/highpressure/fulltile, /obj/structure/window/reinforced/tinted/fulltile/)
level = 3
@@ -504,7 +504,7 @@
max_integrity = 100
wtype = "shuttle"
fulltile = 1
- flags = NONE
+ flags = PREVENT_CLICK_UNDER
reinf = 1
heat_resistance = 1600
armor = list(melee = 50, bullet = 0, laser = 0, energy = 0, bomb = 25, bio = 100, rad = 100, fire = 80, acid = 100)
@@ -583,7 +583,7 @@
smooth = SMOOTH_TRUE
canSmoothWith = null
fulltile = 1
- flags = NONE
+ flags = PREVENT_CLICK_UNDER
dir = FULLTILE_WINDOW_DIR
max_integrity = 120
level = 3
diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm
index a0940eded1..1876d6f782 100644
--- a/code/game/turfs/space/space.dm
+++ b/code/game/turfs/space/space.dm
@@ -42,7 +42,7 @@
if (opacity)
has_opaque_atom = TRUE
-
+
return INITIALIZE_HINT_NORMAL
/turf/open/space/attack_ghost(mob/dead/observer/user)
@@ -177,7 +177,7 @@
ChangeTurf(/turf/open/floor/plating)
return TRUE
return FALSE
-
+
/turf/open/space/ReplaceWithLattice()
var/dest_x = destination_x
var/dest_y = destination_y
@@ -186,4 +186,4 @@
destination_x = dest_x
destination_y = dest_y
destination_z = dest_z
-
+
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 96e3b9c590..c4d35d7bd1 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -92,39 +92,39 @@
LC.attackby(C,user)
return
coil.place_turf(src, user)
- return 1
+ return TRUE
- return 0
+ return FALSE
/turf/CanPass(atom/movable/mover, turf/target, height=1.5)
- if(!target) return 0
+ if(!target) return FALSE
if(istype(mover)) // turf/Enter(...) will perform more advanced checks
return !density
else // Now, doing more detailed checks for air movement and air group formation
if(target.blocks_air||blocks_air)
- return 0
+ return FALSE
for(var/obj/obstacle in src)
if(!obstacle.CanPass(mover, target, height))
- return 0
+ return FALSE
for(var/obj/obstacle in target)
if(!obstacle.CanPass(mover, src, height))
- return 0
+ return FALSE
- return 1
+ return TRUE
/turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area)
if (!mover)
- return 1
+ return TRUE
// First, make sure it can leave its square
if(isturf(mover.loc))
// Nothing but border objects stop you from leaving a tile, only one loop is needed
for(var/obj/obstacle in mover.loc)
if(!obstacle.CheckExit(mover, src) && obstacle != mover && obstacle != forget)
mover.Bump(obstacle, 1)
- return 0
+ return FALSE
var/list/large_dense = list()
//Next, check objects to block entry that are on the border
@@ -132,14 +132,14 @@
if(border_obstacle.flags & ON_BORDER)
if(!border_obstacle.CanPass(mover, mover.loc, 1) && (forget != border_obstacle))
mover.Bump(border_obstacle, 1)
- return 0
+ return FALSE
else
large_dense += border_obstacle
//Then, check the turf itself
if (!src.CanPass(mover, src))
mover.Bump(src, 1)
- return 0
+ return FALSE
//Finally, check objects/mobs to block entry that are not on the border
var/atom/movable/tompost_bump
@@ -151,8 +151,9 @@
top_layer = obstacle.layer
if(tompost_bump)
mover.Bump(tompost_bump,1)
- return 0
- return 1 //Nothing found to block so return success!
+ return FALSE
+
+ return TRUE //Nothing found to block so return success!
/turf/Entered(atom/movable/AM)
if(explosion_level && AM.ex_check(explosion_id))
@@ -185,7 +186,7 @@
O.make_unfrozen()
/turf/proc/is_plasteel_floor()
- return 0
+ return FALSE
/turf/proc/levelupdate()
for(var/obj/O in src)
@@ -303,7 +304,7 @@
if(src_object.contents.len)
to_chat(usr, "You start dumping out the contents...")
if(!do_after(usr,20,target=src_object))
- return 0
+ return FALSE
var/list/things = src_object.contents.Copy()
var/datum/progressbar/progress = new(user, things.len, src)
@@ -311,7 +312,7 @@
sleep(1)
qdel(progress)
- return 1
+ return TRUE
//////////////////////////////
//Distance procs
@@ -325,7 +326,7 @@
// possible. It results in more efficient (CPU-wise) pathing
// for bots and anything else that only moves in cardinal dirs.
/turf/proc/Distance_cardinal(turf/T)
- if(!src || !T) return 0
+ if(!src || !T) return FALSE
return abs(x - T.x) + abs(y - T.y)
////////////////////////////////////////////////////
@@ -341,7 +342,7 @@
return(2)
/turf/proc/can_have_cabling()
- return 1
+ return TRUE
/turf/proc/can_lay_cable()
return can_have_cabling() & !intact
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 949ce63d16..9bed5ad238 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -108,7 +108,11 @@ GLOBAL_PROTECT(AdminProcCallCount)
return call(target, procname)(arglist(arguments))
/proc/IsAdminAdvancedProcCall()
+#ifdef TESTING
+ return FALSE
+#else
return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey
+#endif
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
set category = "Debug"
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index 99db88dfe3..73e0c2042f 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -153,8 +153,8 @@
return
var/datum/gas_mixture/air1 = AIR1
var/turf/T = get_turf(src)
- if(isliving(occupant))
- var/mob/living/mob_occupant
+ if(occupant)
+ var/mob/living/mob_occupant = occupant
if(mob_occupant.health >= 100) // Don't bother with fully healed people.
on = FALSE
update_icon()
@@ -176,8 +176,8 @@
if(beaker)
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
- beaker.reagents.trans_to(mob_occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic.
- beaker.reagents.reaction(mob_occupant, VAPOR)
+ beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic.
+ beaker.reagents.reaction(occupant, VAPOR)
air1.gases["o2"][MOLES] -= 2 / efficiency // Lets use gas for this.
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
@@ -192,7 +192,7 @@
on = FALSE
update_icon()
return
- if(isliving(occupant))
+ if(occupant)
var/mob/living/mob_occupant = occupant
var/cold_protection = 0
var/mob/living/carbon/human/H = occupant
@@ -244,7 +244,7 @@
..()
if(occupant)
if(on)
- to_chat(user, "[occupant] is inside [src]!")
+ to_chat(user, "Someone's inside [src]!")
else
to_chat(user, "You can barely make out a form floating in [src].")
else
@@ -299,7 +299,7 @@
data["autoEject"] = autoeject
var/list/occupantData = list()
- if(isliving(occupant))
+ if(occupant)
var/mob/living/mob_occupant = occupant
occupantData["name"] = mob_occupant.name
occupantData["stat"] = mob_occupant.stat
diff --git a/code/modules/fields/fields.dm b/code/modules/fields/fields.dm
new file mode 100644
index 0000000000..4b083d7e02
--- /dev/null
+++ b/code/modules/fields/fields.dm
@@ -0,0 +1,309 @@
+
+//Movable and easily code-modified fields! Allows for custom AOE effects that affect movement and anything inside of them, and can do custom turf effects!
+//Supports automatic recalculation/reset on movement.
+//If there's any way to make this less CPU intensive than I've managed, gimme a call or do it yourself! - kevinz000
+
+//Field shapes
+#define FIELD_NO_SHAPE 0 //Does not update turfs automatically
+#define FIELD_SHAPE_RADIUS_SQUARE 1 //Uses current_range and square_depth_up/down
+#define FIELD_SHAPE_CUSTOM_SQUARE 2 //Uses square_height and square_width and square_depth_up/down
+
+//Proc to make fields. make_field(field_type, field_params_in_associative_list)
+/proc/make_field(field_type, list/field_params, override_checks = FALSE, start_field = TRUE)
+ var/datum/proximity_monitor/advanced/F = new field_type()
+ if(!F.assume_params(field_params) && !override_checks)
+ QDEL_NULL(F)
+ if(!F.check_variables() && !override_checks)
+ QDEL_NULL(F)
+ if(start_field && (F || override_checks))
+ F.Initialize()
+ return F
+
+/datum/proximity_monitor/advanced
+ var/name = "\improper Energy Field"
+ //Field setup specifications
+ var/field_shape = FIELD_NO_SHAPE
+ var/square_height = 0
+ var/square_width = 0
+ var/square_depth_up = 0
+ var/square_depth_down = 0
+ //Processing
+ var/requires_processing = FALSE
+ var/process_inner_turfs = FALSE //Don't do this unless it's absolutely necessary
+ var/process_edge_turfs = FALSE //Don't do this either unless it's absolutely necessary, you can just track what things are inside manually or on the initial setup.
+ var/setup_edge_turfs = FALSE //Setup edge turfs/all field turfs. Set either or both to ON when you need it, it's defaulting to off unless you do to save CPU.
+ var/setup_field_turfs = FALSE
+
+ var/list/turf/field_turfs = list()
+ var/list/turf/edge_turfs = list()
+ var/list/turf/field_turfs_new = list()
+ var/list/turf/edge_turfs_new = list()
+
+/datum/proximity_monitor/advanced/New()
+ SSfields.register_new_field(src)
+
+/datum/proximity_monitor/advanced/Destroy()
+ SSfields.unregister_field(src)
+ full_cleanup()
+ return ..()
+
+/datum/proximity_monitor/advanced/proc/assume_params(list/field_params)
+ var/pass_check = TRUE
+ for(var/param in field_params)
+ if(vars[param] || isnull(vars[param]) || (param in vars))
+ vars[param] = field_params[param]
+ else
+ pass_check = FALSE
+ return pass_check
+
+/datum/proximity_monitor/advanced/proc/check_variables()
+ var/pass = TRUE
+ if(field_shape == FIELD_NO_SHAPE) //If you're going to make a manually updated field you shouldn't be using automatic checks so don't.
+ pass = FALSE
+ if(current_range < 0 || square_height < 0 || square_width < 0 || square_depth_up < 0 || square_depth_down < 0)
+ pass = FALSE
+ if(!istype(host))
+ pass = FALSE
+ return pass
+
+/datum/proximity_monitor/advanced/process()
+ if(process_inner_turfs)
+ for(var/turf/T in field_turfs)
+ process_inner_turf(T)
+ CHECK_TICK //Really crappy lagchecks, needs improvement once someone starts using processed fields.
+ if(process_edge_turfs)
+ for(var/turf/T in edge_turfs)
+ process_edge_turf(T)
+ CHECK_TICK //Same here.
+
+/datum/proximity_monitor/advanced/proc/process_inner_turf(turf/T)
+
+/datum/proximity_monitor/advanced/proc/process_edge_turf(turf/T)
+
+/datum/proximity_monitor/advanced/proc/Initialize()
+ setup_field()
+ post_setup_field()
+
+/datum/proximity_monitor/advanced/proc/full_cleanup() //Full cleanup for when you change something that would require complete resetting.
+ for(var/turf/T in edge_turfs)
+ cleanup_edge_turf(T)
+ for(var/turf/T in field_turfs)
+ cleanup_field_turf(T)
+
+/datum/proximity_monitor/advanced/proc/recalculate_field(ignore_movement_check = FALSE) //Call every time the field moves (done automatically if you use update_center) or a setup specification is changed.
+ if(!(ignore_movement_check || ((host.loc != last_host_loc) && (field_shape != FIELD_NO_SHAPE))))
+ return
+ update_new_turfs()
+ var/list/turf/needs_setup = field_turfs_new.Copy()
+ if(setup_field_turfs)
+ for(var/turf/T in field_turfs)
+ if(!(T in needs_setup))
+ cleanup_field_turf(T)
+ else
+ needs_setup -= T
+ CHECK_TICK
+ for(var/turf/T in needs_setup)
+ setup_field_turf(T)
+ CHECK_TICK
+ if(setup_edge_turfs)
+ for(var/turf/T in edge_turfs)
+ cleanup_edge_turf(T)
+ CHECK_TICK
+ for(var/turf/T in edge_turfs_new)
+ setup_edge_turf(T)
+ CHECK_TICK
+
+/datum/proximity_monitor/advanced/proc/field_turf_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F, turf/entering)
+ return TRUE
+
+/datum/proximity_monitor/advanced/proc/field_turf_uncross(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F)
+ return TRUE
+
+/datum/proximity_monitor/advanced/proc/field_turf_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F)
+ return TRUE
+
+/datum/proximity_monitor/advanced/proc/field_turf_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F)
+ return TRUE
+
+/datum/proximity_monitor/advanced/proc/field_edge_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F, turf/entering)
+ return TRUE
+
+/datum/proximity_monitor/advanced/proc/field_edge_uncross(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
+ return TRUE
+
+/datum/proximity_monitor/advanced/proc/field_edge_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
+ return TRUE
+
+/datum/proximity_monitor/advanced/proc/field_edge_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
+ return TRUE
+
+/datum/proximity_monitor/advanced/HandleMove()
+ var/atom/_host = host
+ var/atom/new_host_loc = _host.loc
+ if(last_host_loc != new_host_loc)
+ recalculate_field()
+
+/datum/proximity_monitor/advanced/proc/post_setup_field()
+
+/datum/proximity_monitor/advanced/proc/setup_field()
+ update_new_turfs()
+ if(setup_field_turfs)
+ for(var/turf/T in field_turfs_new)
+ setup_field_turf(T)
+ CHECK_TICK
+ if(setup_edge_turfs)
+ for(var/turf/T in edge_turfs_new)
+ setup_edge_turf(T)
+ CHECK_TICK
+
+/datum/proximity_monitor/advanced/proc/cleanup_field_turf(turf/T)
+ qdel(field_turfs[T])
+ field_turfs -= T
+
+/datum/proximity_monitor/advanced/proc/cleanup_edge_turf(turf/T)
+ qdel(edge_turfs[T])
+ edge_turfs -= T
+
+/datum/proximity_monitor/advanced/proc/setup_field_turf(turf/T)
+ field_turfs[T] = new /obj/effect/abstract/proximity_checker/advanced/field_turf(T, src)
+
+/datum/proximity_monitor/advanced/proc/setup_edge_turf(turf/T)
+ edge_turfs[T] = new /obj/effect/abstract/proximity_checker/advanced/field_edge(T, src)
+
+/datum/proximity_monitor/advanced/proc/update_new_turfs()
+ if(!istype(host))
+ return FALSE
+ last_host_loc = host.loc
+ var/turf/center = get_turf(host)
+ field_turfs_new = list()
+ edge_turfs_new = list()
+ switch(field_shape)
+ if(FIELD_NO_SHAPE)
+ return FALSE
+ if(FIELD_SHAPE_RADIUS_SQUARE)
+ for(var/turf/T in block(locate(center.x-current_range,center.y-current_range,center.z-square_depth_down),locate(center.x+current_range, center.y+current_range,center.z+square_depth_up)))
+ field_turfs_new += T
+ edge_turfs_new = field_turfs_new.Copy()
+ if(current_range >= 1)
+ var/list/turf/center_turfs = list()
+ for(var/turf/T in block(locate(center.x-current_range+1,center.y-current_range+1,center.z-square_depth_down),locate(center.x+current_range-1, center.y+current_range-1,center.z+square_depth_up)))
+ center_turfs += T
+ for(var/turf/T in center_turfs)
+ edge_turfs_new -= T
+ if(FIELD_SHAPE_CUSTOM_SQUARE)
+ for(var/turf/T in block(locate(center.x-square_width,center.y-square_height,center.z-square_depth_down),locate(center.x+square_width, center.y+square_height,center.z+square_depth_up)))
+ field_turfs_new += T
+ edge_turfs_new = field_turfs_new.Copy()
+ if(square_height >= 1 && square_width >= 1)
+ var/list/turf/center_turfs = list()
+ for(var/turf/T in block(locate(center.x-square_width+1,center.y-square_height+1,center.z-square_depth_down),locate(center.x+square_width-1, center.y+square_height-1,center.z+square_depth_up)))
+ center_turfs += T
+ for(var/turf/T in center_turfs)
+ edge_turfs_new -= T
+
+//Gets edge direction/corner, only works with square radius/WDH fields!
+/datum/proximity_monitor/advanced/proc/get_edgeturf_direction(turf/T, turf/center_override = null)
+ var/turf/checking_from = get_turf(host)
+ if(istype(center_override))
+ checking_from = center_override
+ if(field_shape != FIELD_SHAPE_RADIUS_SQUARE && field_shape != FIELD_SHAPE_CUSTOM_SQUARE)
+ return
+ if(!(T in edge_turfs))
+ return
+ switch(field_shape)
+ if(FIELD_SHAPE_RADIUS_SQUARE)
+ if(((T.x == (checking_from.x + current_range)) || (T.x == (checking_from.x - current_range))) && ((T.y == (checking_from.y + current_range)) || (T.y == (checking_from.y - current_range))))
+ return get_dir(checking_from, T)
+ if(T.x == (checking_from.x + current_range))
+ return EAST
+ if(T.x == (checking_from.x - current_range))
+ return WEST
+ if(T.y == (checking_from.y - current_range))
+ return SOUTH
+ if(T.y == (checking_from.y + current_range))
+ return NORTH
+ if(FIELD_SHAPE_CUSTOM_SQUARE)
+ if(((T.x == (checking_from.x + square_width)) || (T.x == (checking_from.x - square_width))) && ((T.y == (checking_from.y + square_height)) || (T.y == (checking_from.y - square_height))))
+ return get_dir(checking_from, T)
+ if(T.x == (checking_from.x + square_width))
+ return EAST
+ if(T.x == (checking_from.x - square_width))
+ return WEST
+ if(T.y == (checking_from.y - square_height))
+ return SOUTH
+ if(T.y == (checking_from.y + square_height))
+ return NORTH
+
+//DEBUG FIELDS
+/datum/proximity_monitor/advanced/debug
+ name = "\improper Color Matrix Field"
+ field_shape = FIELD_SHAPE_RADIUS_SQUARE
+ current_range = 5
+ var/set_fieldturf_color = "#aaffff"
+ var/set_edgeturf_color = "#ffaaff"
+ setup_field_turfs = TRUE
+ setup_edge_turfs = TRUE
+
+/datum/proximity_monitor/advanced/debug/recalculate_field()
+ ..()
+
+/datum/proximity_monitor/advanced/debug/post_setup_field()
+ ..()
+
+/datum/proximity_monitor/advanced/debug/setup_edge_turf(turf/T)
+ T.color = set_edgeturf_color
+ ..()
+
+/datum/proximity_monitor/advanced/debug/cleanup_edge_turf(turf/T)
+ T.color = initial(T.color)
+ ..()
+ if(T in field_turfs)
+ T.color = set_fieldturf_color
+
+/datum/proximity_monitor/advanced/debug/setup_field_turf(turf/T)
+ T.color = set_fieldturf_color
+ ..()
+
+/datum/proximity_monitor/advanced/debug/cleanup_field_turf(turf/T)
+ T.color = initial(T.color)
+ ..()
+
+//DEBUG FIELD ITEM
+/obj/item/device/multitool/field_debug
+ name = "strange multitool"
+ desc = "Seems to project a colored field!"
+ var/list/field_params = list("field_shape" = FIELD_SHAPE_RADIUS_SQUARE, "current_range" = 5, "set_fieldturf_color" = "#aaffff", "set_edgeturf_color" = "#ffaaff")
+ var/field_type = /datum/proximity_monitor/advanced/debug
+ var/operating = FALSE
+ var/datum/proximity_monitor/advanced/current = null
+
+/obj/item/device/multitool/field_debug/New()
+ START_PROCESSING(SSobj, src)
+ ..()
+
+/obj/item/device/multitool/field_debug/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ QDEL_NULL(current)
+ ..()
+
+/obj/item/device/multitool/field_debug/proc/setup_debug_field()
+ var/list/new_params = field_params.Copy()
+ new_params["host"] = src
+ current = make_field(field_type, new_params)
+
+/obj/item/device/multitool/field_debug/attack_self(mob/user)
+ operating = !operating
+ to_chat(user, "You turn the [src] [operating? "on":"off"].")
+ if(!istype(current) && operating)
+ setup_debug_field()
+ else if(!operating)
+ QDEL_NULL(current)
+
+/obj/item/device/multitool/field_debug/on_mob_move()
+ check_turf(get_turf(src))
+
+/obj/item/device/multitool/field_debug/process()
+ check_turf(get_turf(src))
+
+/obj/item/device/multitool/field_debug/proc/check_turf(turf/T)
+ current.HandleMove()
diff --git a/code/modules/fields/peaceborg_dampener.dm b/code/modules/fields/peaceborg_dampener.dm
new file mode 100644
index 0000000000..bcf8a88585
--- /dev/null
+++ b/code/modules/fields/peaceborg_dampener.dm
@@ -0,0 +1,106 @@
+
+//Projectile dampening field that slows projectiles and lowers their damage for an energy cost deducted every 1/5 second.
+//Only use square radius for this!
+/datum/proximity_monitor/advanced/peaceborg_dampener
+ name = "\improper Hyperkinetic Dampener Field"
+ requires_processing = TRUE
+ setup_edge_turfs = TRUE
+ setup_field_turfs = TRUE
+ field_shape = FIELD_SHAPE_RADIUS_SQUARE
+ var/static/image/edgeturf_south = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_south")
+ var/static/image/edgeturf_north = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_north")
+ var/static/image/edgeturf_west = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_west")
+ var/static/image/edgeturf_east = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_east")
+ var/static/image/northwest_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_northwest")
+ var/static/image/southwest_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_southwest")
+ var/static/image/northeast_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_northeast")
+ var/static/image/southeast_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_southeast")
+ var/obj/item/borg/projectile_dampen/projector = null
+ var/list/obj/item/projectile/tracked
+ var/list/obj/item/projectile/staging
+
+/datum/proximity_monitor/advanced/peaceborg_dampener/New()
+ tracked = list()
+ staging = list()
+ ..()
+
+/datum/proximity_monitor/advanced/peaceborg_dampener/process()
+ if(!istype(projector))
+ qdel(src)
+ var/list/ranged = list()
+ for(var/obj/item/projectile/P in range(current_range, get_turf(host)))
+ ranged += P
+ for(var/obj/item/projectile/P in tracked)
+ if(!(P in ranged) || !P.loc)
+ release_projectile(P)
+ for(var/mob/living/silicon/robot/R in range(current_range, get_turf(host)))
+ if(R.has_buckled_mobs())
+ for(var/mob/living/L in R.buckled_mobs)
+ L.visible_message("[L] is knocked off of [R] by the charge in [R]'s chassis induced by [name]!") //I know it's bad.
+ L.Weaken(3)
+ R.unbuckle_mob(L)
+ do_sparks(5, 0, L)
+ ..()
+
+/datum/proximity_monitor/advanced/peaceborg_dampener/setup_edge_turf(turf/T)
+ ..()
+ var/image/I = get_edgeturf_overlay(get_edgeturf_direction(T))
+ var/obj/effect/abstract/proximity_checker/advanced/F = edge_turfs[T]
+ F.appearance = I.appearance
+ F.invisibility = 0
+ F.layer = 5
+
+/datum/proximity_monitor/advanced/peaceborg_dampener/cleanup_edge_turf(turf/T)
+ ..()
+
+/datum/proximity_monitor/advanced/peaceborg_dampener/proc/get_edgeturf_overlay(direction)
+ switch(direction)
+ if(NORTH)
+ return edgeturf_north
+ if(SOUTH)
+ return edgeturf_south
+ if(EAST)
+ return edgeturf_east
+ if(WEST)
+ return edgeturf_west
+ if(NORTHEAST)
+ return northeast_corner
+ if(NORTHWEST)
+ return northwest_corner
+ if(SOUTHEAST)
+ return southeast_corner
+ if(SOUTHWEST)
+ return southwest_corner
+
+/datum/proximity_monitor/advanced/peaceborg_dampener/proc/capture_projectile(obj/item/projectile/P, track_projectile = TRUE)
+ if(P in tracked)
+ return
+ projector.dampen_projectile(P, track_projectile)
+ if(track_projectile)
+ tracked += P
+
+/datum/proximity_monitor/advanced/peaceborg_dampener/proc/release_projectile(obj/item/projectile/P)
+ projector.restore_projectile(P)
+ tracked -= P
+
+/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
+ if(!is_turf_in_field(get_turf(AM), src))
+ if(istype(AM, /obj/item/projectile))
+ if(AM in tracked)
+ release_projectile(AM)
+ else
+ capture_projectile(AM, FALSE)
+ return ..()
+
+/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
+ if(istype(AM, /obj/item/projectile) && !(AM in tracked) && staging[AM] && !is_turf_in_field(staging[AM], src))
+ capture_projectile(AM)
+ staging -= AM
+ return ..()
+
+/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F, turf/entering)
+ if(istype(AM, /obj/item/projectile))
+ staging[AM] = get_turf(AM)
+ . = ..()
+ if(!.)
+ staging -= AM //This one ain't goin' through.
diff --git a/code/modules/fields/turf_objects.dm b/code/modules/fields/turf_objects.dm
new file mode 100644
index 0000000000..683fa67c96
--- /dev/null
+++ b/code/modules/fields/turf_objects.dm
@@ -0,0 +1,76 @@
+
+/obj/effect/abstract/proximity_checker/advanced
+ name = "field"
+ desc = "Why can you see energy fields?!"
+ icon = null
+ icon_state = null
+ alpha = 0
+ invisibility = INVISIBILITY_ABSTRACT
+ flags = ABSTRACT|ON_BORDER
+ var/datum/proximity_monitor/advanced/parent = null
+
+/obj/effect/abstract/proximity_checker/advanced/Initialize(mapload, _monitor)
+ if(_monitor)
+ parent = _monitor
+ return ..()
+
+/obj/effect/abstract/proximity_checker/advanced/center
+ name = "field anchor"
+ desc = "No."
+
+/obj/effect/abstract/proximity_checker/advanced/field_turf
+ name = "energy field"
+ desc = "Get off my turf!"
+
+/obj/effect/abstract/proximity_checker/advanced/field_turf/CanPass(atom/movable/AM, turf/target, height)
+ if(parent)
+ return parent.field_turf_canpass(AM, src, target)
+ return TRUE
+
+/obj/effect/abstract/proximity_checker/advanced/field_turf/Crossed(atom/movable/AM)
+ if(parent)
+ return parent.field_turf_crossed(AM, src)
+ return TRUE
+
+/obj/effect/abstract/proximity_checker/advanced/field_turf/Uncross(atom/movable/AM)
+ if(parent)
+ return parent.field_turf_uncross(AM, src)
+ return TRUE
+
+/obj/effect/abstract/proximity_checker/advanced/field_turf/Uncrossed(atom/movable/AM)
+ if(parent)
+ return parent.field_turf_uncrossed(AM, src)
+ return TRUE
+
+/obj/effect/abstract/proximity_checker/advanced/field_edge
+ name = "energy field edge"
+ desc = "Edgy description here."
+
+/obj/effect/abstract/proximity_checker/advanced/field_edge/CanPass(atom/movable/AM, turf/target, height)
+ if(parent)
+ return parent.field_edge_canpass(AM, src, target)
+ return TRUE
+
+/obj/effect/abstract/proximity_checker/advanced/field_edge/Crossed(atom/movable/AM)
+ if(parent)
+ return parent.field_edge_crossed(AM, src)
+ return TRUE
+
+/obj/effect/abstract/proximity_checker/advanced/field_edge/Uncross(atom/movable/AM)
+ if(parent)
+ return parent.field_edge_uncross(AM, src)
+ return TRUE
+
+/obj/effect/abstract/proximity_checker/advanced/field_edge/Uncrossed(atom/movable/AM)
+ if(parent)
+ return parent.field_edge_uncrossed(AM, src)
+ return TRUE
+
+/proc/is_turf_in_field(turf/T, datum/proximity_monitor/advanced/F) //Looking for ways to optimize this!
+ for(var/obj/effect/abstract/proximity_checker/advanced/O in T)
+ if(istype(O, /obj/effect/abstract/proximity_checker/advanced/field_edge))
+ if(O.parent == F)
+ return FIELD_EDGE
+ if(O.parent == F)
+ return FIELD_TURF
+ return NO_FIELD
diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm
index 3a6c2d91f6..7a1682aedd 100644
--- a/code/modules/food_and_drinks/food/customizables.dm
+++ b/code/modules/food_and_drinks/food/customizables.dm
@@ -135,7 +135,6 @@
/obj/item/weapon/reagent_containers/food/snacks/customizable/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/slice, reagents_per_slice)
..()
- slice.name = "[customname] [initial(slice.name)]"
slice.filling_color = filling_color
slice.update_overlays(src)
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index 148541922f..95d3a7993b 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -215,8 +215,9 @@
/obj/item/weapon/reagent_containers/food/snacks/proc/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/slice, reagents_per_slice)
slice.create_reagents(slice.volume)
reagents.trans_to(slice,reagents_per_slice)
- if( name != initial(name) || desc != initial(desc) )
- slice.name = "slice of [src]"
+ if(name != initial(name))
+ slice.name = "slice of [name]"
+ if(desc != initial(desc))
slice.desc = "[desc]"
/obj/item/weapon/reagent_containers/food/snacks/proc/generate_trash(atom/location)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
index 81e3692376..f4ffb4123a 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
@@ -174,7 +174,6 @@
var/mob/living/carbon/human/gibee = occupant
sourcejob = gibee.job
var/sourcenutriment = mob_occupant.nutrition / 15
- var/sourcetotalreagents = mob_occupant.reagents.total_volume
var/gibtype = /obj/effect/decal/cleanable/blood/gibs
var/typeofmeat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human
var/typeofskin = /obj/item/stack/sheet/animalhide/human
@@ -207,7 +206,6 @@
newmeat.reagents.add_reagent ("nutriment", sourcenutriment / meat_produced) // Thehehe. Fat guys go first
if(sourcejob)
newmeat.subjectjob = sourcejob
- src.occupant.reagents.trans_to (newmeat, round (sourcetotalreagents / meat_produced, 1)) // Transfer all the reagents from the
allmeat[i] = newmeat
allskin = newskin
diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm
index 8c2d1ca281..0811c0a8d9 100644
--- a/code/modules/mining/aux_base.dm
+++ b/code/modules/mining/aux_base.dm
@@ -2,7 +2,8 @@
#define BAD_ZLEVEL 1
#define BAD_AREA 2
-#define ZONE_SET 3
+#define BAD_COORDS 3
+#define ZONE_SET 4
/area/shuttle/auxillary_base
name = "Auxillary Base"
@@ -149,6 +150,9 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
if(T.z != ZLEVEL_MINING)
return BAD_ZLEVEL
var/colony_radius = max(base_dock.width, base_dock.height)*0.5
+ if(T.x - colony_radius < 1 || T.x + colony_radius >= world.maxx || T.y - colony_radius < 1 || T.y + colony_radius >= world.maxx)
+ return BAD_COORDS //Avoid dropping the base too close to map boundaries, as it results in parts of it being left in space
+
var/list/area_counter = get_areas_in_range(colony_radius, T)
if(area_counter.len > 1) //Avoid smashing ruins unless you are inside a really big one
return BAD_AREA
@@ -195,6 +199,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
if(!do_after(user, 50, target = user)) //You get a few seconds to cancel if you do not want to drop there.
setting = FALSE
return
+ setting = FALSE
var/turf/T = get_turf(user)
var/obj/machinery/computer/auxillary_base/AB
@@ -212,6 +217,8 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
to_chat(user, "This uplink can only be used in a designed mining zone.")
if(BAD_AREA)
to_chat(user, "Unable to acquire a targeting lock. Find an area clear of stuctures or entirely within one.")
+ if(BAD_COORDS)
+ to_chat(user, "Location is too close to the edge of the station's scanning range. Move several paces away and try again.")
if(ZONE_SET)
qdel(src)
@@ -347,4 +354,5 @@ obj/docking_port/stationary/public_mining_dock/onShuttleMove()
#undef BAD_ZLEVEL
#undef BAD_AREA
+#undef BAD_COORDS
#undef ZONE_SET
\ No newline at end of file
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 780eee9018..ba28e89736 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -1,5 +1,6 @@
//The chests dropped by mob spawner tendrils. Also contains associated loot.
+
/obj/structure/closet/crate/necropolis
name = "necropolis chest"
desc = "It's watching you closely."
@@ -821,6 +822,8 @@
if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one!
chaser_timer = world.time + chaser_cooldown
new /obj/effect/temp_visual/hierophant/chaser(get_turf(user), user, target, chaser_speed, friendly_fire_check)
+ C.damage = 30
+ C.monster_damage_boost = FALSE
add_logs(user, target, "fired a chaser at", src)
else
INVOKE_ASYNC(src, .proc/cardinal_blasts, T, user) //otherwise, just do cardinal blast
@@ -1005,6 +1008,8 @@
if(!J)
return
new /obj/effect/temp_visual/hierophant/blast(J, user, friendly_fire_check)
+ B.damage = 30
+ B.monster_damage_boost = FALSE
previousturf = J
J = get_step(previousturf, dir)
@@ -1016,3 +1021,4 @@
sleep(2)
for(var/t in RANGE_TURFS(1, T))
new /obj/effect/temp_visual/hierophant/blast(t, user, friendly_fire_check)
+ B.damage = 15 //keeps monster damage boost due to lower damage
diff --git a/code/modules/mob/living/carbon/alien/status_procs.dm b/code/modules/mob/living/carbon/alien/status_procs.dm
index 653b05ae5a..b63d233016 100644
--- a/code/modules/mob/living/carbon/alien/status_procs.dm
+++ b/code/modules/mob/living/carbon/alien/status_procs.dm
@@ -17,4 +17,4 @@
/mob/living/carbon/alien/AdjustStunned(amount, updating = 1, ignore_canstun = 0)
. = ..()
if(!.)
- move_delay_add = min(move_delay_add + round(amount / 2), 10)
+ move_delay_add = Clamp(move_delay_add + round(amount/2), 0, 10)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 926e88787e..99c99a44d9 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -823,7 +823,7 @@
/mob/living/proc/has_bane(banetype)
var/datum/antagonist/devil/devilInfo = is_devil(src)
- return (banetype == devilInfo.bane)
+ return devilInfo && banetype == devilInfo.bane
/mob/living/proc/check_weakness(obj/item/weapon, mob/living/attacker)
if(mind && mind.has_antag_datum(ANTAG_DATUM_DEVIL))
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index d15d71c23c..9ed7796f1a 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -1,361 +1,370 @@
-
-/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = null, soften_text = null, armour_penetration, penetrated_text)
- var/armor = getarmor(def_zone, attack_flag)
-
- //the if "armor" check is because this is used for everything on /living, including humans
- if(armor && armour_penetration)
- armor = max(0, armor - armour_penetration)
- if(penetrated_text)
- to_chat(src, "[penetrated_text]")
- else
- to_chat(src, "Your armor was penetrated!")
- else if(armor >= 100)
- if(absorb_text)
- to_chat(src, "[absorb_text]")
- else
- to_chat(src, "Your armor absorbs the blow!")
- else if(armor > 0)
- if(soften_text)
- to_chat(src, "[soften_text]")
- else
- to_chat(src, "Your armor softens the blow!")
- return armor
-
-
-/mob/living/proc/getarmor(def_zone, type)
- return 0
-
-//this returns the mob's protection against eye damage (number between -1 and 2)
-/mob/living/proc/get_eye_protection()
- return 0
-
-//this returns the mob's protection against ear damage (0:no protection; 1: some ear protection; 2: has no ears)
-/mob/living/proc/get_ear_protection()
- return 0
-
-/mob/living/proc/on_hit(obj/item/projectile/P)
- return
-
-/mob/living/bullet_act(obj/item/projectile/P, def_zone)
- var/armor = run_armor_check(def_zone, P.flag, "","",P.armour_penetration)
- if(!P.nodamage)
- apply_damage(P.damage, P.damage_type, def_zone, armor)
- if(P.dismemberment)
- check_projectile_dismemberment(P, def_zone)
- return P.on_hit(src, armor)
-
-/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
- return 0
-
-/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
- if(throwforce && w_class)
- return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
- else if(w_class)
- return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
- else
- return 0
-
-/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
- if(istype(AM, /obj/item))
- var/obj/item/I = AM
- var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
- var/dtype = BRUTE
- var/volume = I.get_volume_by_throwforce_and_or_w_class()
- if(istype(I,/obj/item/weapon)) //If the item is a weapon...
- var/obj/item/weapon/W = I
- dtype = W.damtype
-
- if (W.throwforce > 0) //If the weapon's throwforce is greater than zero...
- if (W.throwhitsound) //...and throwhitsound is defined...
- playsound(loc, W.throwhitsound, volume, 1, -1) //...play the weapon's throwhitsound.
- else if(W.hitsound) //Otherwise, if the weapon's hitsound is defined...
- playsound(loc, W.hitsound, volume, 1, -1) //...play the weapon's hitsound.
- else if(!W.throwhitsound) //Otherwise, if throwhitsound isn't defined...
- playsound(loc, 'sound/weapons/genhit.ogg',volume, 1, -1) //...play genhit.ogg.
-
- else if(!I.throwhitsound && I.throwforce > 0) //Otherwise, if the item doesn't have a throwhitsound and has a throwforce greater than zero...
- playsound(loc, 'sound/weapons/genhit.ogg', volume, 1, -1)//...play genhit.ogg
- if(!I.throwforce)// Otherwise, if the item's throwforce is 0...
- playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg.
- if(!blocked)
- visible_message("[src] has been hit by [I].", \
- "[src] has been hit by [I].")
- var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration)
- apply_damage(I.throwforce, dtype, zone, armor)
- if(I.thrownby)
- add_logs(I.thrownby, src, "hit", I)
- else
- return 1
- else
- playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
- ..()
-
-
-/mob/living/mech_melee_attack(obj/mecha/M)
- if(M.occupant.a_intent == INTENT_HARM)
- M.do_attack_animation(src)
- if(M.damtype == "brute")
- step_away(src,M,15)
- switch(M.damtype)
- if(BRUTE)
- Paralyse(1)
- take_overall_damage(rand(M.force/2, M.force))
- playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
- if(BURN)
- take_overall_damage(0, rand(M.force/2, M.force))
- playsound(src, 'sound/items/Welder.ogg', 50, 1)
- if(TOX)
- M.mech_toxin_damage(src)
- else
- return
- updatehealth()
- visible_message("[M.name] has hit [src]!", \
- "[M.name] has hit [src]!", null, COMBAT_MESSAGE_RANGE)
- add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
- else
- step_away(src,M)
- add_logs(M.occupant, src, "pushed", M)
- visible_message("[M] pushes [src] out of the way.", null, null, 5)
-
-/mob/living/fire_act()
- adjust_fire_stacks(3)
- IgniteMob()
-
-/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
- if(user == src || anchored || !isturf(user.loc))
- return 0
- if(!user.pulling || user.pulling != src)
- user.start_pulling(src, supress_message)
- return
-
- if(!(status_flags & CANPUSH))
- to_chat(user, "[src] can't be grabbed more aggressively!")
- return 0
- grippedby(user)
-
-//proc to upgrade a simple pull into a more aggressive grab.
-/mob/living/proc/grippedby(mob/living/carbon/user)
- if(user.grab_state < GRAB_KILL)
- user.changeNext_move(CLICK_CD_GRABBING)
- playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
-
- if(user.grab_state) //only the first upgrade is instantaneous
- var/old_grab_state = user.grab_state
- var/grab_upgrade_time = 30
- visible_message("[user] starts to tighten [user.p_their()] grip on [src]!", \
- "[user] starts to tighten [user.p_their()] grip on you!")
- if(!do_mob(user, src, grab_upgrade_time))
- return 0
- if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != INTENT_GRAB)
- return 0
- user.grab_state++
- switch(user.grab_state)
- if(GRAB_AGGRESSIVE)
- add_logs(user, src, "grabbed", addition="aggressively")
- visible_message("[user] has grabbed [src] aggressively!", \
- "[user] has grabbed [src] aggressively!")
- drop_all_held_items()
- stop_pulling()
- if(GRAB_NECK)
- visible_message("[user] has grabbed [src] by the neck!",\
- "[user] has grabbed you by the neck!")
- update_canmove() //we fall down
- if(!buckled && !density)
- Move(user.loc)
- if(GRAB_KILL)
- visible_message("[user] is strangling [src]!", \
- "[user] is strangling you!")
- update_canmove() //we fall down
- if(!buckled && !density)
- Move(user.loc)
- return 1
-
-
-/mob/living/attack_slime(mob/living/simple_animal/slime/M)
+
+/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = null, soften_text = null, armour_penetration, penetrated_text)
+ var/armor = getarmor(def_zone, attack_flag)
+
+ //the if "armor" check is because this is used for everything on /living, including humans
+ if(armor && armour_penetration)
+ armor = max(0, armor - armour_penetration)
+ if(penetrated_text)
+ to_chat(src, "[penetrated_text]")
+ else
+ to_chat(src, "Your armor was penetrated!")
+ else if(armor >= 100)
+ if(absorb_text)
+ to_chat(src, "[absorb_text]")
+ else
+ to_chat(src, "Your armor absorbs the blow!")
+ else if(armor > 0)
+ if(soften_text)
+ to_chat(src, "[soften_text]")
+ else
+ to_chat(src, "Your armor softens the blow!")
+ return armor
+
+
+/mob/living/proc/getarmor(def_zone, type)
+ return 0
+
+//this returns the mob's protection against eye damage (number between -1 and 2)
+/mob/living/proc/get_eye_protection()
+ return 0
+
+//this returns the mob's protection against ear damage (0:no protection; 1: some ear protection; 2: has no ears)
+/mob/living/proc/get_ear_protection()
+ return 0
+
+/mob/living/proc/on_hit(obj/item/projectile/P)
+ return
+
+/mob/living/bullet_act(obj/item/projectile/P, def_zone)
+ var/armor = run_armor_check(def_zone, P.flag, "","",P.armour_penetration)
+ if(!P.nodamage)
+ apply_damage(P.damage, P.damage_type, def_zone, armor)
+ if(P.dismemberment)
+ check_projectile_dismemberment(P, def_zone)
+ return P.on_hit(src, armor)
+
+/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
+ return 0
+
+/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
+ if(throwforce && w_class)
+ return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
+ else if(w_class)
+ return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
+ else
+ return 0
+
+/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
+ if(istype(AM, /obj/item))
+ var/obj/item/I = AM
+ var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
+ var/dtype = BRUTE
+ var/volume = I.get_volume_by_throwforce_and_or_w_class()
+ if(istype(I,/obj/item/weapon)) //If the item is a weapon...
+ var/obj/item/weapon/W = I
+ dtype = W.damtype
+
+ if (W.throwforce > 0) //If the weapon's throwforce is greater than zero...
+ if (W.throwhitsound) //...and throwhitsound is defined...
+ playsound(loc, W.throwhitsound, volume, 1, -1) //...play the weapon's throwhitsound.
+ else if(W.hitsound) //Otherwise, if the weapon's hitsound is defined...
+ playsound(loc, W.hitsound, volume, 1, -1) //...play the weapon's hitsound.
+ else if(!W.throwhitsound) //Otherwise, if throwhitsound isn't defined...
+ playsound(loc, 'sound/weapons/genhit.ogg',volume, 1, -1) //...play genhit.ogg.
+
+ else if(!I.throwhitsound && I.throwforce > 0) //Otherwise, if the item doesn't have a throwhitsound and has a throwforce greater than zero...
+ playsound(loc, 'sound/weapons/genhit.ogg', volume, 1, -1)//...play genhit.ogg
+ if(!I.throwforce)// Otherwise, if the item's throwforce is 0...
+ playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg.
+ if(!blocked)
+ visible_message("[src] has been hit by [I].", \
+ "[src] has been hit by [I].")
+ var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration)
+ apply_damage(I.throwforce, dtype, zone, armor)
+ if(I.thrownby)
+ add_logs(I.thrownby, src, "hit", I)
+ else
+ return 1
+ else
+ playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
+ ..()
+
+
+/mob/living/mech_melee_attack(obj/mecha/M)
+ if(M.occupant.a_intent == INTENT_HARM)
+ M.do_attack_animation(src)
+ if(M.damtype == "brute")
+ step_away(src,M,15)
+ switch(M.damtype)
+ if(BRUTE)
+ Paralyse(1)
+ take_overall_damage(rand(M.force/2, M.force))
+ playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
+ if(BURN)
+ take_overall_damage(0, rand(M.force/2, M.force))
+ playsound(src, 'sound/items/Welder.ogg', 50, 1)
+ if(TOX)
+ M.mech_toxin_damage(src)
+ else
+ return
+ updatehealth()
+ visible_message("[M.name] has hit [src]!", \
+ "[M.name] has hit [src]!", null, COMBAT_MESSAGE_RANGE)
+ add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
+ else
+ step_away(src,M)
+ add_logs(M.occupant, src, "pushed", M)
+ visible_message("[M] pushes [src] out of the way.", null, null, 5)
+
+/mob/living/fire_act()
+ adjust_fire_stacks(3)
+ IgniteMob()
+
+/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
+ if(user == src || anchored || !isturf(user.loc))
+ return 0
+ if(!user.pulling || user.pulling != src)
+ user.start_pulling(src, supress_message)
+ return
+
+ if(!(status_flags & CANPUSH))
+ to_chat(user, "[src] can't be grabbed more aggressively!")
+ return 0
+ grippedby(user)
+
+//proc to upgrade a simple pull into a more aggressive grab.
+/mob/living/proc/grippedby(mob/living/carbon/user)
+ if(user.grab_state < GRAB_KILL)
+ user.changeNext_move(CLICK_CD_GRABBING)
+ playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
+
+ if(user.grab_state) //only the first upgrade is instantaneous
+ var/old_grab_state = user.grab_state
+ var/grab_upgrade_time = 30
+ visible_message("[user] starts to tighten [user.p_their()] grip on [src]!", \
+ "[user] starts to tighten [user.p_their()] grip on you!")
+ if(!do_mob(user, src, grab_upgrade_time))
+ return 0
+ if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != INTENT_GRAB)
+ return 0
+ user.grab_state++
+ switch(user.grab_state)
+ if(GRAB_AGGRESSIVE)
+ add_logs(user, src, "grabbed", addition="aggressively")
+ visible_message("[user] has grabbed [src] aggressively!", \
+ "[user] has grabbed [src] aggressively!")
+ drop_all_held_items()
+ stop_pulling()
+ if(GRAB_NECK)
+ visible_message("[user] has grabbed [src] by the neck!",\
+ "[user] has grabbed you by the neck!")
+ update_canmove() //we fall down
+ if(!buckled && !density)
+ Move(user.loc)
+ if(GRAB_KILL)
+ visible_message("[user] is strangling [src]!", \
+ "[user] is strangling you!")
+ update_canmove() //we fall down
+ if(!buckled && !density)
+ Move(user.loc)
+ return 1
+
+
+/mob/living/attack_slime(mob/living/simple_animal/slime/M)
if(!SSticker.HasRoundStarted())
- to_chat(M, "You cannot attack people before the game has started.")
- return
-
- if(M.buckled)
- if(M in buckled_mobs)
- M.Feedstop()
- return // can't attack while eating!
-
- if (stat != DEAD)
- add_logs(M, src, "attacked")
- M.do_attack_animation(src)
- visible_message("The [M.name] glomps [src]!", \
- "The [M.name] glomps [src]!", null, COMBAT_MESSAGE_RANGE)
- return 1
-
-/mob/living/attack_animal(mob/living/simple_animal/M)
- M.face_atom(src)
- if(M.melee_damage_upper == 0)
- M.visible_message("\The [M] [M.friendly] [src]!")
- return 0
- else
- if(M.attack_sound)
- playsound(loc, M.attack_sound, 50, 1, 1)
- M.do_attack_animation(src)
- visible_message("\The [M] [M.attacktext] [src]!", \
- "\The [M] [M.attacktext] [src]!", null, COMBAT_MESSAGE_RANGE)
- add_logs(M, src, "attacked")
- return 1
-
-
-/mob/living/attack_paw(mob/living/carbon/monkey/M)
- if(isturf(loc) && istype(loc.loc, /area/start))
- to_chat(M, "No attacking people at spawn, you jackass.")
- return 0
-
- if (M.a_intent == INTENT_HARM)
- if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
- to_chat(M, "You can't bite with your mouth covered!")
- return 0
- M.do_attack_animation(src, ATTACK_EFFECT_BITE)
- if (prob(75))
- add_logs(M, src, "attacked")
- playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
- visible_message("[M.name] bites [src]!", \
- "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE)
- return 1
- else
- visible_message("[M.name] has attempted to bite [src]!", \
- "[M.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE)
- return 0
-
-/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
- switch(L.a_intent)
- if("help")
- visible_message("[L.name] rubs its head against [src].")
- return 0
-
- else
- L.do_attack_animation(src)
- if(prob(90))
- add_logs(L, src, "attacked")
- visible_message("[L.name] bites [src]!", \
- "[L.name] bites [src]!", null, COMBAT_MESSAGE_RANGE)
- playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
- return 1
- else
- visible_message("[L.name] has attempted to bite [src]!", \
- "[L.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE)
- return 0
-
-/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
- switch(M.a_intent)
- if ("help")
- visible_message("[M] caresses [src] with its scythe like arm.")
- return 0
-
- if ("grab")
- grabbedby(M)
- return 0
- if("harm")
- M.do_attack_animation(src)
- return 1
- if("disarm")
- M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
- return 1
-
-/mob/living/ex_act(severity, target, origin)
- if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
- return
- ..()
-
-//Looking for irradiate()? It's been moved to radiation.dm under the rad_act() for mobs.
-
-/mob/living/acid_act(acidpwr, acid_volume)
- take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
- return 1
-
-/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
+ to_chat(M, "You cannot attack people before the game has started.")
+ return
+
+ if(M.buckled)
+ if(M in buckled_mobs)
+ M.Feedstop()
+ return // can't attack while eating!
+
+ if (stat != DEAD)
+ add_logs(M, src, "attacked")
+ M.do_attack_animation(src)
+ visible_message("The [M.name] glomps [src]!", \
+ "The [M.name] glomps [src]!", null, COMBAT_MESSAGE_RANGE)
+ return 1
+
+/mob/living/attack_animal(mob/living/simple_animal/M)
+ M.face_atom(src)
+ if(M.melee_damage_upper == 0)
+ M.visible_message("\The [M] [M.friendly] [src]!")
+ return 0
+ else
+ if(M.attack_sound)
+ playsound(loc, M.attack_sound, 50, 1, 1)
+ M.do_attack_animation(src)
+ visible_message("\The [M] [M.attacktext] [src]!", \
+ "\The [M] [M.attacktext] [src]!", null, COMBAT_MESSAGE_RANGE)
+ add_logs(M, src, "attacked")
+ return 1
+
+
+/mob/living/attack_paw(mob/living/carbon/monkey/M)
+ if(isturf(loc) && istype(loc.loc, /area/start))
+ to_chat(M, "No attacking people at spawn, you jackass.")
+ return 0
+
+ if (M.a_intent == INTENT_HARM)
+ if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
+ to_chat(M, "You can't bite with your mouth covered!")
+ return 0
+ M.do_attack_animation(src, ATTACK_EFFECT_BITE)
+ if (prob(75))
+ add_logs(M, src, "attacked")
+ playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
+ visible_message("[M.name] bites [src]!", \
+ "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE)
+ return 1
+ else
+ visible_message("[M.name] has attempted to bite [src]!", \
+ "[M.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE)
+ return 0
+
+/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
+ switch(L.a_intent)
+ if("help")
+ visible_message("[L.name] rubs its head against [src].")
+ return 0
+
+ else
+ L.do_attack_animation(src)
+ if(prob(90))
+ add_logs(L, src, "attacked")
+ visible_message("[L.name] bites [src]!", \
+ "[L.name] bites [src]!", null, COMBAT_MESSAGE_RANGE)
+ playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
+ return 1
+ else
+ visible_message("[L.name] has attempted to bite [src]!", \
+ "[L.name] has attempted to bite [src]!", null, COMBAT_MESSAGE_RANGE)
+ return 0
+
+/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
+ switch(M.a_intent)
+ if ("help")
+ visible_message("[M] caresses [src] with its scythe like arm.")
+ return 0
+
+ if ("grab")
+ grabbedby(M)
+ return 0
+ if("harm")
+ M.do_attack_animation(src)
+ return 1
+ if("disarm")
+ M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
+ return 1
+
+/mob/living/ex_act(severity, target, origin)
+ if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
+ return
+ ..()
+
+//Looking for irradiate()? It's been moved to radiation.dm under the rad_act() for mobs.
+
+/mob/living/acid_act(acidpwr, acid_volume)
+ take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
+ return 1
+
+/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
if(tesla_shock && HAS_SECONDARY_FLAG(src, TESLA_IGNORE))
- return FALSE
- if(shock_damage > 0)
- if(!illusion)
- adjustFireLoss(shock_damage)
- visible_message(
- "[src] was shocked by \the [source]!", \
- "You feel a powerful shock coursing through your body!", \
- "You hear a heavy electrical crack." \
- )
- return shock_damage
-
-/mob/living/emp_act(severity)
- var/list/L = src.get_contents()
- for(var/obj/O in L)
- O.emp_act(severity)
- ..()
-
-/mob/living/singularity_act()
- var/gain = 20
- investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
- gib()
- return(gain)
-
-/mob/living/narsie_act()
- if(status_flags & GODMODE)
- return
-
- if(is_servant_of_ratvar(src) && !stat)
- to_chat(src, "You resist Nar-Sie's influence... but not all of it. Run!")
- adjustBruteLoss(35)
- if(src && reagents)
- reagents.add_reagent("heparin", 5)
- return FALSE
- if(client)
+ return FALSE
+ if(shock_damage > 0)
+ if(!illusion)
+ adjustFireLoss(shock_damage)
+ visible_message(
+ "[src] was shocked by \the [source]!", \
+ "You feel a powerful shock coursing through your body!", \
+ "You hear a heavy electrical crack." \
+ )
+ return shock_damage
+
+/mob/living/emp_act(severity)
+ var/list/L = src.get_contents()
+ for(var/obj/O in L)
+ O.emp_act(severity)
+ ..()
+
+/mob/living/singularity_act()
+ var/gain = 20
+ investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
+ gib()
+ return(gain)
+
+/mob/living/narsie_act()
+ if(status_flags & GODMODE)
+ return
+
+ if(is_servant_of_ratvar(src) && !stat)
+ to_chat(src, "You resist Nar-Sie's influence... but not all of it. Run!")
+ adjustBruteLoss(35)
+ if(src && reagents)
+ reagents.add_reagent("heparin", 5)
+ return FALSE
+ if(GLOB.cult_narsie && GLOB.cult_narsie.souls_needed[src])
+ GLOB.cult_narsie.resize(1.1)
+ GLOB.cult_narsie.souls_needed -= src
+ GLOB.cult_narsie.souls += 1
+ if((GLOB.cult_narsie.souls == GLOB.cult_narsie.soul_goal) && (GLOB.cult_narsie.resolved == FALSE))
+ GLOB.cult_narsie.resolved = TRUE
+ world << sound('sound/machines/Alarm.ogg')
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/cult_ending_helper, 1), 120)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/ending_helper), 270)
+ if(client)
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, cultoverride = TRUE)
- else
+ else
switch(rand(1, 6))
- if(1)
- new /mob/living/simple_animal/hostile/construct/armored/hostile(get_turf(src))
- if(2)
- new /mob/living/simple_animal/hostile/construct/wraith/hostile(get_turf(src))
- if(3 to 6)
- new /mob/living/simple_animal/hostile/construct/builder/hostile(get_turf(src))
- spawn_dust()
- gib()
- return TRUE
-
-
-/mob/living/ratvar_act()
- if(status_flags & GODMODE)
- return
-
- if(stat != DEAD && !is_servant_of_ratvar(src))
- for(var/obj/item/weapon/implant/mindshield/M in implants)
- qdel(M)
- if(!add_servant_of_ratvar(src))
- to_chat(src, "A blinding light boils you alive! Run!")
- adjustFireLoss(35)
- if(src)
- adjust_fire_stacks(1)
- IgniteMob()
- return FALSE
- return TRUE
-
-
-//called when the mob receives a bright flash
-/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
- if(get_eye_protection() < intensity && (override_blindness_check || !(disabilities & BLIND)))
- overlay_fullscreen("flash", type)
- addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
- return 1
-
-//called when the mob receives a loud bang
-/mob/living/proc/soundbang_act()
- return 0
-
-//to damage the clothes worn by a mob
-/mob/living/proc/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
- return
-
-
-/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
- if(A != src)
- end_pixel_y = get_standard_pixel_y_offset(lying)
- used_item = get_active_held_item()
- ..()
- floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
+ if(1)
+ new /mob/living/simple_animal/hostile/construct/armored/hostile(get_turf(src))
+ if(2)
+ new /mob/living/simple_animal/hostile/construct/wraith/hostile(get_turf(src))
+ if(3 to 6)
+ new /mob/living/simple_animal/hostile/construct/builder/hostile(get_turf(src))
+ spawn_dust()
+ gib()
+ return TRUE
+
+
+/mob/living/ratvar_act()
+ if(status_flags & GODMODE)
+ return
+
+ if(stat != DEAD && !is_servant_of_ratvar(src))
+ for(var/obj/item/weapon/implant/mindshield/M in implants)
+ qdel(M)
+ if(!add_servant_of_ratvar(src))
+ to_chat(src, "A blinding light boils you alive! Run!")
+ adjustFireLoss(35)
+ if(src)
+ adjust_fire_stacks(1)
+ IgniteMob()
+ return FALSE
+ return TRUE
+
+
+//called when the mob receives a bright flash
+/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
+ if(get_eye_protection() < intensity && (override_blindness_check || !(disabilities & BLIND)))
+ overlay_fullscreen("flash", type)
+ addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
+ return 1
+
+//called when the mob receives a loud bang
+/mob/living/proc/soundbang_act()
+ return 0
+
+//to damage the clothes worn by a mob
+/mob/living/proc/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
+ return
+
+
+/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
+ if(A != src)
+ end_pixel_y = get_standard_pixel_y_offset(lying)
+ used_item = get_active_held_item()
+ ..()
+ floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 02d001c58a..7ab7fa928d 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -407,7 +407,8 @@
/obj/item/weapon/reagent_containers/borghypo/peace,
/obj/item/weapon/holosign_creator/cyborg,
/obj/item/borg/cyborghug/peacekeeper,
- /obj/item/weapon/extinguisher)
+ /obj/item/weapon/extinguisher,
+ /obj/item/borg/projectile_dampen)
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/peace/hacked)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/peacekeeper,
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 7c2fcb178b..f988fc2477 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -171,7 +171,30 @@
attacktext = "slashes"
attack_sound = 'sound/weapons/bladeslice.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
- playstyle_string = "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls."
+ playstyle_string = "You are a Wraith. Though relatively fragile, you are fast, deadly, can phase through walls, and your attacks will lower the cooldown on phasing."
+ var/attack_refund = 10 //1 second per attack
+ var/crit_refund = 50 //5 seconds when putting a target into critical
+ var/kill_refund = 250 //full refund on kills
+
+/mob/living/simple_animal/hostile/construct/wraith/AttackingTarget() //refund jaunt cooldown when attacking living targets
+ var/prev_stat
+ if(isliving(target) && !iscultist(target))
+ var/mob/living/L = target
+ prev_stat = L.stat
+
+ . = ..()
+
+ if(. && isnum(prev_stat))
+ var/mob/living/L = target
+ var/refund = 0
+ if(QDELETED(L) || (L.stat == DEAD && prev_stat != DEAD)) //they're dead, you killed them
+ refund += kill_refund
+ else if(L.InCritical() && prev_stat == CONSCIOUS) //you knocked them into critical
+ refund += crit_refund
+ if(L.stat != DEAD && prev_stat != DEAD)
+ refund += attack_refund
+ for(var/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/S in mob_spell_list)
+ S.charge_counter = min(S.charge_counter + refund, S.charge_max)
/mob/living/simple_animal/hostile/construct/wraith/hostile //actually hostile, will move around, hit things
AIStatus = AI_ON
@@ -265,8 +288,8 @@
name = "Harvester"
real_name = "Harvester"
desc = "A long, thin construct built to herald Nar-Sie's rise. It'll be all over soon."
- icon_state = "harvester"
- icon_living = "harvester"
+ icon_state = "chosen"
+ icon_living = "chosen"
maxHealth = 60
health = 60
sight = SEE_MOBS
@@ -277,9 +300,10 @@
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/area_conversion,
/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
playstyle_string = "You are a Harvester. You are incapable of directly killing humans, but your attacks will remove their limbs: \
- Bring those who still cling to this world of illusion back to the Geometer so they may know Truth."
+ Bring those who still cling to this world of illusion back to the Geometer so they may know Truth. Your form and any you are pulling can pass through runed walls effortlessly."
can_repair_constructs = TRUE
+
/mob/living/simple_animal/hostile/construct/harvester/Bump(atom/AM)
. = ..()
if(istype(AM, /turf/closed/wall/mineral/cult) && AM != loc) //we can go through cult walls
@@ -306,6 +330,8 @@
if(!LAZYLEN(parts))
if(undismembermerable_limbs) //they have limbs we can't remove, and no parts we can, attack!
return ..()
+ C.Weaken(30)
+ visible_message("[src] paralyzes [C]!")
to_chat(src, "\"Bring [C.p_them()] to me.\"")
return FALSE
do_attack_animation(C)
@@ -314,6 +340,11 @@
return FALSE
. = ..()
+/mob/living/simple_animal/hostile/construct/harvester/Initialize()
+ . = ..()
+ var/datum/action/innate/seek_prey/seek = new()
+ seek.Grant(src)
+ seek.Activate()
///////////////////////Master-Tracker///////////////////////
@@ -326,11 +357,14 @@
var/tracking = FALSE
var/mob/living/simple_animal/hostile/construct/the_construct
+
/datum/action/innate/seek_master/Grant(var/mob/living/C)
the_construct = C
..()
/datum/action/innate/seek_master/Activate()
+ if(!SSticker.mode.eldergod)
+ the_construct.master = GLOB.blood_target
if(!the_construct.master)
to_chat(the_construct, "You have no master to seek!")
the_construct.seeking = FALSE
@@ -346,6 +380,43 @@
to_chat(the_construct, "You are now tracking your master.")
+/datum/action/innate/seek_prey
+ name = "Seek the Harvest"
+ desc = "None can hide from Nar'Sie, activate to track a survivor attempting to flee the red harvest!"
+ background_icon_state = "bg_demon"
+ buttontooltipstyle = "cult"
+ button_icon_state = "cult_mark"
+ var/tracking = FALSE
+ var/mob/living/simple_animal/hostile/construct/harvester/the_construct
+
+/datum/action/innate/seek_prey/Grant(var/mob/living/C)
+ the_construct = C
+ ..()
+
+/datum/action/innate/seek_prey/Activate()
+ if(GLOB.cult_narsie == null)
+ return
+ if(tracking)
+ desc = "None can hide from Nar'Sie, activate to track a survivor attempting to flee the red harvest!"
+ button_icon_state = "cult_mark"
+ tracking = FALSE
+ the_construct.seeking = FALSE
+ the_construct.master = GLOB.cult_narsie
+ to_chat(the_construct, "You are now tracking Nar'Sie, return to reap the harvest!")
+ return
+ else
+ if(LAZYLEN(GLOB.cult_narsie.souls_needed))
+ the_construct.master = pick(GLOB.cult_narsie.souls_needed)
+ to_chat(the_construct, "You are now tracking your prey, [the_construct.master] - harvest them!")
+ else
+ to_chat(the_construct, "Nar'Sie has completed her harvest!")
+ return
+ desc = "Activate to track Nar'Sie!"
+ button_icon_state = "sintouch"
+ tracking = TRUE
+ the_construct.seeking = TRUE
+
+
/////////////////////////////ui stuff/////////////////////////////
/mob/living/simple_animal/hostile/construct/update_health_hud()
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index a0f46922b7..f1508c6f71 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -467,6 +467,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/used_message = "All the cards seem to be blank now."
var/failure_message = "..And draw a card! It's...blank? Maybe you should try again later."
var/ling_failure = "The deck refuses to respond to a souless creature such as you."
+ var/activation_message = "The rest of the deck rapidly flashes to ash!"
var/list/possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
var/random = TRUE
var/allowmultiple = FALSE
@@ -495,6 +496,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
if(candidates.len)
theghost = pick(candidates)
spawn_guardian(user, theghost.key)
+ to_chat(user, "[activation_message]")
+ qdel(src)
else
to_chat(user, "[failure_message]")
used = FALSE
@@ -587,6 +590,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
used_message = "The injector has already been used."
failure_message = "...ERROR. BOOT SEQUENCE ABORTED. AI FAILED TO INTIALIZE. PLEASE CONTACT SUPPORT OR TRY AGAIN LATER."
ling_failure = "The holoparasites recoil in horror. They want nothing to do with a creature like you."
+ activation_message = "The injector self destructs after you inject yourself with it."
/obj/item/weapon/guardiancreator/tech/choose/traitor
possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
@@ -599,7 +603,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
/obj/item/weapon/paper/guardian
name = "Holoparasite Guide"
- icon_state = "paper_words"
+ icon_state = "alienpaper_words"
info = {"A list of Holoparasite Types
@@ -670,6 +674,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
used_message = "Someone's already taken a bite out of these fishsticks! Ew."
failure_message = "You couldn't catch any carp spirits from the seas of Lake Carp. Maybe there are none, maybe you fucked up."
ling_failure = "Carp'sie is fine with changelings, so you shouldn't be seeing this message."
+ activation_message = "You finish eating the fishsticks! Delicious!>"
allowmultiple = TRUE
allowling = TRUE
random = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index 4a2397e726..cfbd3a933d 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -478,6 +478,8 @@ Difficulty: Hard
var/speed = 3 //how many deciseconds between each step
var/currently_seeking = FALSE
var/friendly_fire_check = FALSE //if blasts produced apply friendly fire
+ var/monster_damage_boost = TRUE
+ var/damage = 10
/obj/effect/temp_visual/hierophant/chaser/Initialize(mapload, new_caster, new_target, new_speed, is_friendly_fire)
. = ..()
@@ -524,6 +526,8 @@ Difficulty: Hard
/obj/effect/temp_visual/hierophant/chaser/proc/make_blast()
new /obj/effect/temp_visual/hierophant/blast(loc, caster, friendly_fire_check)
+ B.damage = damage
+ B.monster_damage_boost = monster_damage_boost
/obj/effect/temp_visual/hierophant/telegraph
icon = 'icons/effects/96x96.dmi'
@@ -553,6 +557,7 @@ Difficulty: Hard
desc = "Get out of the way!"
duration = 9
var/damage = 10 //how much damage do we do?
+ var/monster_damage_boost = TRUE //do we deal extra damage to monsters? Used by the boss
var/list/hit_things = list() //we hit these already, ignore them
var/friendly_fire_check = FALSE
var/bursting = FALSE //if we're bursting and need to hit anyone crossing us
@@ -595,7 +600,7 @@ Difficulty: Hard
var/limb_to_hit = L.get_bodypart(pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg"))
var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!")
L.apply_damage(damage, BURN, limb_to_hit, armor)
- if(ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid))
+ if(monster_damage_boost && (ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid)))
L.adjustBruteLoss(damage)
add_logs(caster, L, "struck with a [name]")
for(var/obj/mecha/M in T.contents - hit_things) //and mechs.
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 36e69828b2..b6c6ab5d9e 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -170,8 +170,7 @@
/obj/item/weapon/paper/proc/updateinfolinks()
info_links = info
- var/i = 0
- for(i=1,i<=fields,i++)
+ for(var/i in 1 to min(fields, 15))
addtofield(i, "write", 1)
info_links = info_links + "write"
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index 7a148067d3..a1d544c2e4 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -304,16 +304,17 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
// Sound the alert if gravity was just enabled or disabled.
var/alert = 0
var/area/A = get_area(src)
- if(on && SSticker.IsRoundInProgress()) // If we turned on and the game is live.
- if(gravity_in_level() == 0)
- alert = 1
- investigate_log("was brought online and is now producing gravity for this level.", "gravity")
- message_admins("The gravity generator was brought online [A][ADMIN_COORDJMP(src)]")
- else
- if(gravity_in_level() == 1)
- alert = 1
- investigate_log("was brought offline and there is now no gravity for this level.", "gravity")
- message_admins("The gravity generator was brought offline with no backup generator. [A][ADMIN_COORDJMP(src)]")
+ if(SSticker.IsRoundInProgress())
+ if(on) // If we turned on and the game is live.
+ if(gravity_in_level() == 0)
+ alert = 1
+ investigate_log("was brought online and is now producing gravity for this level.", "gravity")
+ message_admins("The gravity generator was brought online [A][ADMIN_COORDJMP(src)]")
+ else
+ if(gravity_in_level() == 1)
+ alert = 1
+ investigate_log("was brought offline and there is now no gravity for this level.", "gravity")
+ message_admins("The gravity generator was brought offline with no backup generator. [A][ADMIN_COORDJMP(src)]")
update_icon()
update_list()
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 1997b6bcbd..fd119bf878 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -34,13 +34,61 @@
var/area/A = get_area(src)
if(A)
- var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/effects.dmi', "ghostalertsie")
+ var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/cult_effects.dmi', "ghostalertsie")
notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.", source = src, alert_overlay = alert_overlay, action=NOTIFY_ATTACK)
+ INVOKE_ASYNC(src, .proc/narsie_spawn_animation)
- narsie_spawn_animation()
+/obj/singularity/narsie/large/cult // For the new cult ending, guaranteed to end the round within 3 minutes
+ var/list/souls_needed = list()
+ var/soul_goal = 0
+ var/souls = 0
+ var/resolved = FALSE
- sleep(19)
- SSshuttle.emergency.request(null, set_coefficient = 0) //instantly arrives
+/obj/singularity/narsie/large/cult/proc/resize(var/ratio)
+ var/matrix/ntransform = matrix(transform) //aka transform.Copy()
+ ntransform.Scale(ratio)
+ animate(src, transform = ntransform, time = 40, easing = EASE_IN|EASE_OUT)
+
+/obj/singularity/narsie/large/cult/Initialize()
+ . = ..()
+ GLOB.cult_narsie = src
+ GLOB.blood_target = src
+ resize(0.6)
+ for(var/datum/mind/cult_mind in SSticker.mode.cult)
+ if(isliving(cult_mind.current))
+ var/mob/living/L = cult_mind.current
+ L.narsie_act()
+ for(var/mob/living/player in GLOB.player_list)
+ if(player.stat != DEAD && player.loc.z == ZLEVEL_STATION && !iscultist(player) && isliving(player))
+ souls_needed[player] = TRUE
+ soul_goal = round(1 + LAZYLEN(souls_needed) * 0.6)
+ INVOKE_ASYNC(src, .proc/begin_the_end)
+
+/obj/singularity/narsie/large/cult/proc/begin_the_end()
+ sleep(50)
+ priority_announce("An acausal dimensional event has been detected in your sector. Event has been flagged EXTINCTION-CLASS. Directing all available assets toward simulating solutions. SOLUTION ETA: 60 SECONDS.","Central Command Higher Dimensional Affairs", 'sound/misc/airraid.ogg')
+ sleep(550)
+ priority_announce("Simulations on acausal dimensional event complete. Deploying solution package now. Deployment ETA: TWO MINUTES. ","Central Command Higher Dimensional Affairs")
+ sleep(50)
+ set_security_level("delta")
+ SSshuttle.registerHostileEnvironment(src)
+ SSshuttle.lockdown = TRUE
+ sleep(1150)
+ if(resolved == FALSE)
+ resolved = TRUE
+ world << sound('sound/machines/Alarm.ogg')
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/cult_ending_helper), 120)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/ending_helper), 220)
+
+/obj/singularity/narsie/large/cult/Destroy()
+ GLOB.cult_narsie = null
+ return ..()
+
+/proc/ending_helper()
+ SSticker.force_ending = 1
+
+/proc/cult_ending_helper(var/no_explosion = 0)
+ SSticker.station_explosion_cinematic(no_explosion, "cult", null)
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)
@@ -134,7 +182,7 @@
return
to_chat(target, "NAR-SIE HAS LOST INTEREST IN YOU.")
target = food
- if(isliving(target))
+ if(ishuman(target))
to_chat(target, "NAR-SIE HUNGERS FOR YOUR SOUL.")
else
to_chat(target, "NAR-SIE HAS CHOSEN YOU TO LEAD HER TO HER NEXT MEAL.")
diff --git a/code/modules/projectiles/ammunition/special.dm b/code/modules/projectiles/ammunition/special.dm
index 6e99c5f1bd..bd57d7c07a 100644
--- a/code/modules/projectiles/ammunition/special.dm
+++ b/code/modules/projectiles/ammunition/special.dm
@@ -64,6 +64,25 @@
qdel(S)
..()
+/obj/item/ammo_casing/dnainjector
+ name = "rigged syringe gun spring"
+ desc = "A high-power spring that throws DNA injectors."
+ projectile_type = /obj/item/projectile/bullet/dnainjector
+ firing_effect_type = null
+
+/obj/item/ammo_casing/dnainjector/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
+ if(!BB)
+ return
+ if(istype(loc, /obj/item/weapon/gun/syringe/dna))
+ var/obj/item/weapon/gun/syringe/dna/SG = loc
+ if(!SG.syringes.len)
+ return
+
+ var/obj/item/weapon/dnainjector/S = popleft(SG.syringes)
+ var/obj/item/projectile/bullet/dnainjector/D = BB
+ S.forceMove(D)
+ D.injector = S
+ ..()
/obj/item/ammo_casing/energy/c3dbullet
projectile_type = /obj/item/projectile/bullet/midbullet3
diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm
index 951b5aeb62..b938e399df 100644
--- a/code/modules/projectiles/guns/energy/pulse.dm
+++ b/code/modules/projectiles/guns/energy/pulse.dm
@@ -5,6 +5,7 @@
item_state = null
w_class = WEIGHT_CLASS_BULKY
force = 10
+ modifystate = TRUE
flags = CONDUCT
slot_flags = SLOT_BACK
ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse, /obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
@@ -39,7 +40,7 @@
w_class = WEIGHT_CLASS_NORMAL
slot_flags = SLOT_BELT
icon_state = "pulse_carbine"
- item_state = "pulse"
+ item_state = null
cell_type = "/obj/item/weapon/stock_parts/cell/pulse/carbine"
can_flashlight = 1
flight_x_offset = 18
diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm
index 6da113b6e3..09547b0d98 100644
--- a/code/modules/projectiles/guns/syringe_gun.dm
+++ b/code/modules/projectiles/guns/syringe_gun.dm
@@ -49,18 +49,18 @@
return 1
-/obj/item/weapon/gun/syringe/attackby(obj/item/A, mob/user, params, show_msg = 1)
+/obj/item/weapon/gun/syringe/attackby(obj/item/A, mob/user, params, show_msg = TRUE)
if(istype(A, /obj/item/weapon/reagent_containers/syringe))
if(syringes.len < max_syringes)
if(!user.transferItemToLoc(A, src))
- return
+ return FALSE
to_chat(user, "You load [A] into \the [src].")
- syringes.Add(A)
+ syringes += A
recharge_newshot()
- return 1
+ return TRUE
else
- to_chat(usr, "[src] cannot hold more syringes!")
- return 0
+ to_chat(user, "[src] cannot hold more syringes!")
+ return FALSE
/obj/item/weapon/gun/syringe/rapidsyringe
name = "rapid syringe gun"
@@ -78,3 +78,29 @@
force = 2 //Also very weak because it's smaller
suppressed = 1 //Softer fire sound
can_unsuppress = 0 //Permanently silenced
+
+/obj/item/weapon/gun/syringe/dna
+ name = "modified syringe gun"
+ desc = "A syringe gun that has been modified to fit DNA injectors instead of normal syringes."
+ origin_tech = "combat=2;syndicate=2;biotech=3"
+
+/obj/item/weapon/gun/syringe/dna/Initialize()
+ . = ..()
+ chambered = new /obj/item/ammo_casing/dnainjector(src)
+
+/obj/item/weapon/gun/syringe/dna/attackby(obj/item/A, mob/user, params, show_msg = TRUE)
+ if(istype(A, /obj/item/weapon/dnainjector))
+ var/obj/item/weapon/dnainjector/D = A
+ if(D.used)
+ to_chat(user, "This injector is used up!")
+ return
+ if(syringes.len < max_syringes)
+ if(!user.transferItemToLoc(D, src))
+ return FALSE
+ to_chat(user, "You load \the [D] into \the [src].")
+ syringes += D
+ recharge_newshot()
+ return TRUE
+ else
+ to_chat(user, "[src] cannot hold more syringes!")
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index b9d14cf4c2..4b84a02fd4 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -190,7 +190,7 @@
name = "dart"
icon_state = "cbbolt"
damage = 6
- var/piercing = 0
+ var/piercing = FALSE
/obj/item/projectile/bullet/dart/New()
..()
@@ -201,15 +201,15 @@
if(iscarbon(target))
var/mob/living/carbon/M = target
if(blocked != 100) // not completely blocked
- if(M.can_inject(null, 0, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body.
+ if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body.
..()
reagents.reaction(M, INJECT)
reagents.trans_to(M, reagents.total_volume)
- return 1
+ return TRUE
else
blocked = 100
- target.visible_message("The [name] was deflected!", \
- "You were protected against the [name]!")
+ target.visible_message("\The [src] was deflected!", \
+ "You were protected against \the [src]!")
..(target, blocked)
reagents.set_reacting(TRUE)
@@ -240,7 +240,28 @@
nodamage = 1
. = ..() // Execute the rest of the code.
-
+/obj/item/projectile/bullet/dnainjector
+ name = "\improper DNA injector"
+ icon_state = "syringeproj"
+ var/obj/item/weapon/dnainjector/injector
+
+/obj/item/projectile/bullet/dnainjector/on_hit(atom/target, blocked = 0)
+ if(iscarbon(target))
+ var/mob/living/carbon/M = target
+ if(blocked != 100)
+ if(M.can_inject(null, FALSE, def_zone, FALSE))
+ if(injector.inject(M, firer))
+ QDEL_NULL(injector)
+ return TRUE
+ else
+ blocked = 100
+ target.visible_message("\The [src] was deflected!", \
+ "You were protected against \the [src]!")
+ return ..()
+
+/obj/item/projectile/bullet/dnainjector/Destroy()
+ QDEL_NULL(injector)
+ return ..()
//// SNIPER BULLETS
diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm
index ccc690350a..c9f2ee6360 100644
--- a/code/modules/ruins/lavaland_ruin_code.dm
+++ b/code/modules/ruins/lavaland_ruin_code.dm
@@ -143,6 +143,7 @@
has_id = 1
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. Do not 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!"
id_access_list = list(GLOB.access_syndicate)
+ faction = list("syndicate")
/obj/effect/mob_spawn/human/lavaland_syndicate/comms
name = "Syndicate Comms Agent"
diff --git a/code/modules/spells/spell_types/aimed.dm b/code/modules/spells/spell_types/aimed.dm
index cdac152ed2..b06f69c189 100644
--- a/code/modules/spells/spell_types/aimed.dm
+++ b/code/modules/spells/spell_types/aimed.dm
@@ -24,6 +24,7 @@
if(charge_type == "recharge")
var/refund_percent = current_amount/projectile_amount
charge_counter = charge_max * refund_percent
+ start_recharge()
remove_ranged_ability(msg)
else
msg = "[active_msg]Left-click to shoot it at a target!"
diff --git a/code/modules/uplink/uplink_item.dm b/code/modules/uplink/uplink_item.dm
index cbee8e53f2..3f5b4b4ca4 100644
--- a/code/modules/uplink/uplink_item.dm
+++ b/code/modules/uplink/uplink_item.dm
@@ -1276,6 +1276,14 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
restricted_roles = list("Chaplain")
surplus = 5 //Very low chance to get it in a surplus crate even without being the chaplain
+/datum/uplink_item/role_restricted/pie_cannon
+ name = "Banana Cream Pie Cannon"
+ desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!"
+ cost = 10
+ item = /obj/item/weapon/pneumatic_cannon/pie/selfcharge
+ restricted_roles = list("Clown")
+ surplus = 0 //No fun unless you're the clown!
+
/datum/uplink_item/role_restricted/ancient_jumpsuit
name = "Ancient Jumpsuit"
desc = "A tattered old jumpsuit that will provide absolutely no benefit to you. It fills the wearer with a strange compulsion to blurt out 'glorf'."
@@ -1291,6 +1299,13 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
cost = 2
restricted_roles = list("Curator")
limited_stock = 1 // please don't spam deadchat
+
+/datum/uplink_item/role_restricted/modified_syringe_gun
+ name = "Modified Syringe Gun"
+ desc = "A syringe gun that fires DNA injectors instead of normal syringes."
+ item = /obj/item/weapon/gun/syringe/dna
+ cost = 14
+ restricted_roles = list("Geneticist", "Chief Medical Officer")
// Pointless
/datum/uplink_item/badass
diff --git a/code/modules/uplink/uplink_item_cit.dm b/code/modules/uplink/uplink_item_cit.dm
index b835a21a8c..332254aa37 100644
--- a/code/modules/uplink/uplink_item_cit.dm
+++ b/code/modules/uplink/uplink_item_cit.dm
@@ -16,6 +16,7 @@
It requires an organic host as a home base and source of fuel." //This is the description of the actual injector. Feel free to change this for uplink purposes//
item = /obj/item/weapon/storage/box/syndie_kit/holoparasite
refundable = TRUE
- cost = 10 //I'm working off the borer. Price subject to change
+ cost = 15 //I'm working off the borer. Price subject to change
surplus = 20 //Nobody needs a ton of parasites
- exclude_modes = list(/datum/game_mode/nuclear)
\ No newline at end of file
+ exclude_modes = list(/datum/game_mode/nuclear)
+ refund_path = /obj/item/weapon/guardiancreator/tech/choose/traitor
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-1029.yml b/html/changelogs/AutoChangeLog-pr-1029.yml
new file mode 100644
index 0000000000..5557069616
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1029.yml
@@ -0,0 +1,4 @@
+author: "Lordpidey"
+delete-after: True
+changes:
+ - rscadd: "Toy toolboxes with realistic rumbling action have been added to arcade prizes."
diff --git a/html/changelogs/AutoChangeLog-pr-1030.yml b/html/changelogs/AutoChangeLog-pr-1030.yml
new file mode 100644
index 0000000000..40e5e1abd0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1030.yml
@@ -0,0 +1,4 @@
+author: "Tacolizard Forever: Plasmaman Powercreep"
+delete-after: True
+changes:
+ - tweak: "Plasmaman tanks are the same size as emergency oxygen tanks."
diff --git a/html/changelogs/AutoChangeLog-pr-1031.yml b/html/changelogs/AutoChangeLog-pr-1031.yml
new file mode 100644
index 0000000000..bb9c78ddb3
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1031.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - rscadd: "Peacekeeper cyborgs now have projectile dampening fields."
diff --git a/html/changelogs/AutoChangeLog-pr-1038.yml b/html/changelogs/AutoChangeLog-pr-1038.yml
new file mode 100644
index 0000000000..85daa80c5e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1038.yml
@@ -0,0 +1,8 @@
+author: "coiax"
+delete-after: True
+changes:
+ - rscadd: "Various vending machines, when shooting their inventory at nearby
+people, will \"demonstrate their products features\". This means that if a
+cigarette vending machine throws a lighter at you, it will be on.
+Vending machines also choose random products when throwing, rather than
+the first available one."
diff --git a/html/changelogs/AutoChangeLog-pr-1040.yml b/html/changelogs/AutoChangeLog-pr-1040.yml
new file mode 100644
index 0000000000..55633298a8
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1040.yml
@@ -0,0 +1,4 @@
+author: "Joan"
+delete-after: True
+changes:
+ - rscadd: "Proselytizing alloy shards will now proselytize all the shards in the tile, instead of requiring you to proselytize each one at a time."
diff --git a/html/changelogs/AutoChangeLog-pr-1054.yml b/html/changelogs/AutoChangeLog-pr-1054.yml
new file mode 100644
index 0000000000..130e19fc5c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1054.yml
@@ -0,0 +1,4 @@
+author: "CitadelStationBot"
+delete-after: True
+changes:
+ - bugfix: "Golems touching a shell can now choose to stay in their own body."
diff --git a/html/changelogs/AutoChangeLog-pr-1056.yml b/html/changelogs/AutoChangeLog-pr-1056.yml
new file mode 100644
index 0000000000..abf47dddbb
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1056.yml
@@ -0,0 +1,4 @@
+author: "Swindly"
+delete-after: True
+changes:
+ - rscadd: "Added modified syringe guns. They fire DNA injectors. Geneticists and CMOs can buy them from the traitor uplink for 14 TC."
diff --git a/html/changelogs/AutoChangeLog-pr-1060.yml b/html/changelogs/AutoChangeLog-pr-1060.yml
new file mode 100644
index 0000000000..e797599263
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1060.yml
@@ -0,0 +1,4 @@
+author: "Steelpoint"
+delete-after: True
+changes:
+ - rscadd: "All Pulse weapons now accurately show, by their sprites, what fire mode they are in."
diff --git a/html/changelogs/AutoChangeLog-pr-1062.yml b/html/changelogs/AutoChangeLog-pr-1062.yml
new file mode 100644
index 0000000000..336fd619aa
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1062.yml
@@ -0,0 +1,4 @@
+author: "LetterJay"
+delete-after: True
+changes:
+ - bugfix: "Cryo should now properly utilize chems as well as freeze the occupant."
diff --git a/html/changelogs/AutoChangeLog-pr-1067.yml b/html/changelogs/AutoChangeLog-pr-1067.yml
new file mode 100644
index 0000000000..ab6277afb7
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1067.yml
@@ -0,0 +1,4 @@
+author: "Gun Hog"
+delete-after: True
+changes:
+ - bugfix: "The Auxiliary Base can no longer land outside the lavaland map's boundaries."
diff --git a/html/changelogs/AutoChangeLog-pr-994.yml b/html/changelogs/AutoChangeLog-pr-994.yml
new file mode 100644
index 0000000000..bcda6769f3
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-994.yml
@@ -0,0 +1,6 @@
+author: "Robustin"
+delete-after: True
+changes:
+ - rscadd: "Summoning Nar'Sie now triggers a different ending. No shuttle is coming! Survivors must escape on a pod or survive the Red Harvest for 3 minutes. If Nar'Sie acquires enough souls, the round ends immediately with a **special ending**."
+ - rscadd: "New Harvester Sprite"
+ - rscadd: "Harvesters can now track a random survivor on the station, then switch back to tracking Nar'Sie, via a new action button."
diff --git a/icons/effects/cult_effects.dmi b/icons/effects/cult_effects.dmi
new file mode 100644
index 0000000000..58a2d3c9c9
Binary files /dev/null and b/icons/effects/cult_effects.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index fe537a8e73..eab44acdd7 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/effects/fields.dmi b/icons/effects/fields.dmi
new file mode 100644
index 0000000000..5eadb96a1a
Binary files /dev/null and b/icons/effects/fields.dmi differ
diff --git a/icons/effects/station_explosion.dmi b/icons/effects/station_explosion.dmi
index 7dcab37710..bddc66e137 100644
Binary files a/icons/effects/station_explosion.dmi and b/icons/effects/station_explosion.dmi differ
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index 95b5721d5a..72aa86f600 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ
diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi
index 4b52f33205..a7c80ba536 100644
Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ
diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi
index 3916befb12..71b1474a66 100644
Binary files a/icons/obj/guns/energy.dmi and b/icons/obj/guns/energy.dmi differ
diff --git a/icons/turf/dirt.dmi b/icons/turf/dirt.dmi
new file mode 100644
index 0000000000..4f533a6228
Binary files /dev/null and b/icons/turf/dirt.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index d8b1fc0420..b9f0293318 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -33,6 +33,7 @@
#include "code\__DEFINES\combat.dm"
#include "code\__DEFINES\construction.dm"
#include "code\__DEFINES\contracts.dm"
+#include "code\__DEFINES\cult.dm"
#include "code\__DEFINES\DNA.dm"
#include "code\__DEFINES\events.dm"
#include "code\__DEFINES\flags.dm"
@@ -196,6 +197,7 @@
#include "code\controllers\subsystem\dbcore.dm"
#include "code\controllers\subsystem\disease.dm"
#include "code\controllers\subsystem\events.dm"
+#include "code\controllers\subsystem\fields.dm"
#include "code\controllers\subsystem\fire_burning.dm"
#include "code\controllers\subsystem\garbage.dm"
#include "code\controllers\subsystem\icon_smooth.dm"
@@ -468,6 +470,7 @@
#include "code\game\gamemodes\cult\cult_items.dm"
#include "code\game\gamemodes\cult\cult_structures.dm"
#include "code\game\gamemodes\cult\ritual.dm"
+#include "code\game\gamemodes\cult\rune_spawn_action.dm"
#include "code\game\gamemodes\cult\runes.dm"
#include "code\game\gamemodes\cult\supply.dm"
#include "code\game\gamemodes\cult\talisman.dm"
@@ -709,10 +712,10 @@
#include "code\game\objects\effects\decals\decal.dm"
#include "code\game\objects\effects\decals\misc.dm"
#include "code\game\objects\effects\decals\remains.dm"
-#include "code\game\objects\effects\decals\cleanable\aliens.dm"
-#include "code\game\objects\effects\decals\cleanable\humans.dm"
-#include "code\game\objects\effects\decals\cleanable\misc.dm"
-#include "code\game\objects\effects\decals\cleanable\robots.dm"
+#include "code\game\objects\effects\decals\Cleanable\aliens.dm"
+#include "code\game\objects\effects\decals\Cleanable\humans.dm"
+#include "code\game\objects\effects\decals\Cleanable\misc.dm"
+#include "code\game\objects\effects\decals\Cleanable\robots.dm"
#include "code\game\objects\effects\effect_system\effect_system.dm"
#include "code\game\objects\effects\effect_system\effects_explosion.dm"
#include "code\game\objects\effects\effect_system\effects_foam.dm"
@@ -727,6 +730,10 @@
#include "code\game\objects\effects\spawners\structure.dm"
#include "code\game\objects\effects\spawners\vaultspawner.dm"
#include "code\game\objects\effects\spawners\xeno_egg_delivery.dm"
+#include "code\game\objects\effects\temporary_visuals\clockcult.dm"
+#include "code\game\objects\effects\temporary_visuals\cult.dm"
+#include "code\game\objects\effects\temporary_visuals\miscellaneous.dm"
+#include "code\game\objects\effects\temporary_visuals\temporary_visual.dm"
#include "code\game\objects\items\apc_frame.dm"
#include "code\game\objects\items\blueprints.dm"
#include "code\game\objects\items\body_egg.dm"
@@ -1304,6 +1311,9 @@
#include "code\modules\events\wizard\rpgloot.dm"
#include "code\modules\events\wizard\shuffle.dm"
#include "code\modules\events\wizard\summons.dm"
+#include "code\modules\fields\fields.dm"
+#include "code\modules\fields\peaceborg_dampener.dm"
+#include "code\modules\fields\turf_objects.dm"
#include "code\modules\flufftext\Dreaming.dm"
#include "code\modules\flufftext\Hallucination.dm"
#include "code\modules\flufftext\TextFilters.dm"
diff --git a/tgstation.dme.rej b/tgstation.dme.rej
deleted file mode 100644
index 2e9484f3ee..0000000000
--- a/tgstation.dme.rej
+++ /dev/null
@@ -1,16 +0,0 @@
-diff a/tgstation.dme b/tgstation.dme (rejected hunks)
-@@ -677,10 +677,10 @@
- #include "code\game\objects\effects\decals\decal.dm"
- #include "code\game\objects\effects\decals\misc.dm"
- #include "code\game\objects\effects\decals\remains.dm"
--#include "code\game\objects\effects\decals\Cleanable\aliens.dm"
--#include "code\game\objects\effects\decals\Cleanable\humans.dm"
--#include "code\game\objects\effects\decals\Cleanable\misc.dm"
--#include "code\game\objects\effects\decals\Cleanable\robots.dm"
-+#include "code\game\objects\effects\decals\cleanable\aliens.dm"
-+#include "code\game\objects\effects\decals\cleanable\humans.dm"
-+#include "code\game\objects\effects\decals\cleanable\misc.dm"
-+#include "code\game\objects\effects\decals\cleanable\robots.dm"
- #include "code\game\objects\effects\effect_system\effect_system.dm"
- #include "code\game\objects\effects\effect_system\effects_explosion.dm"
- #include "code\game\objects\effects\effect_system\effects_foam.dm"