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, "The markings pulse with a \ - small flash of red light, then fall dark.") + 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"