diff --git a/_maps/map_files/Theseus/Theseus.dmm b/_maps/map_files/Theseus/Theseus.dmm index 44601ce3d175..b67b5083e13d 100644 --- a/_maps/map_files/Theseus/Theseus.dmm +++ b/_maps/map_files/Theseus/Theseus.dmm @@ -3137,7 +3137,11 @@ /obj/structure/cable/yellow{ icon_state = "12" }, -/obj/effect/landmark/navigate_destination, +/obj/structure/chair{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/effect/landmark/start/security_officer, /turf/open/floor/iron, /area/station/security/office) "bem" = ( @@ -3799,6 +3803,7 @@ /obj/structure/cable/yellow{ icon_state = "3" }, +/obj/effect/landmark/navigate_destination, /turf/open/floor/iron, /area/station/security/office) "bnw" = ( @@ -5344,10 +5349,14 @@ /turf/open/floor/engine, /area/station/engineering/atmospherics_engine) "bPi" = ( -/obj/item/kirbyplants/fullysynthetic, /obj/effect/turf_decal/trimline/red/line{ dir = 1 }, +/obj/structure/table, +/obj/item/folder/red{ + pixel_x = 6; + pixel_y = 4 + }, /turf/open/floor/iron, /area/station/security/brig) "bPL" = ( @@ -9003,6 +9012,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/trimline/red/filled/line, +/obj/structure/cable/yellow{ + icon_state = "132" + }, /turf/open/floor/iron/dark, /area/station/security/brig) "dnd" = ( @@ -9274,14 +9286,14 @@ /turf/open/floor/iron, /area/station/hallway/primary/fore) "dqG" = ( -/obj/structure/table, -/obj/machinery/photocopier{ - pixel_x = -1; - pixel_y = 4 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/chair{ + pixel_y = -2 + }, +/obj/effect/landmark/start/head_of_security, +/obj/machinery/light_switch/directional/north, /turf/open/floor/iron, /area/station/security/office) "dqW" = ( @@ -11127,6 +11139,20 @@ /obj/machinery/light/small/maintenance/directional/north, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"ebW" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/table, +/obj/item/paper/crumpled{ + pixel_x = -4; + pixel_y = -1 + }, +/obj/item/food/donut{ + pixel_x = 8; + pixel_y = 7 + }, +/turf/open/floor/iron, +/area/station/security/office) "ebX" = ( /obj/machinery/airalarm/directional/north, /obj/item/clothing/under/misc/assistantformal, @@ -12269,14 +12295,13 @@ /turf/open/floor/plating, /area/station/maintenance/port/aft) "exe" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Security Office"; - req_one_access_txt = "1;4" - }, /obj/structure/cable/yellow{ icon_state = "3" }, /obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + name = "Security Office" + }, /turf/open/floor/iron/dark, /area/station/security/office) "exn" = ( @@ -13227,7 +13252,15 @@ /obj/structure/cable/yellow{ icon_state = "9" }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = 2; + pixel_y = 4 + }, +/obj/item/pen{ + pixel_x = -3; + pixel_y = 5 + }, /turf/open/floor/iron, /area/station/security/office) "eOW" = ( @@ -14367,6 +14400,7 @@ /area/station/security/brig) "fkG" = ( /obj/machinery/light/small/directional/south, +/obj/effect/mapping_helpers/lightsout, /turf/open/floor/wood, /area/station/command/heads_quarters/hos) "fkN" = ( @@ -14409,8 +14443,8 @@ /turf/open/floor/iron, /area/station/commons/dorms) "fle" = ( -/obj/structure/chair{ - pixel_y = -2 +/obj/structure/filingcabinet/chestdrawer{ + name = "case files" }, /turf/open/floor/iron, /area/station/security/office) @@ -17006,6 +17040,7 @@ /obj/effect/turf_decal/trimline/red/corner{ dir = 1 }, +/obj/machinery/vending/coffee, /turf/open/floor/iron/dark, /area/station/security/office/hall) "gpZ" = ( @@ -19437,6 +19472,10 @@ }, /turf/open/floor/iron, /area/station/cargo/miningoffice) +"hnf" = ( +/obj/structure/table, +/turf/open/floor/iron, +/area/station/security/office) "hnj" = ( /obj/machinery/door/airlock/virology/glass{ name = "Test Subject Cell"; @@ -19682,11 +19721,12 @@ /area/station/hallway/primary/central/starboard) "htm" = ( /obj/structure/table, -/obj/machinery/telephone/security, -/obj/structure/cable/yellow{ - icon_state = "4" +/obj/item/poster/random_official{ + pixel_y = 3 + }, +/obj/item/poster/random_official{ + pixel_y = 9 }, -/obj/machinery/power/data_terminal, /turf/open/floor/iron, /area/station/security/office) "hts" = ( @@ -20458,6 +20498,24 @@ /obj/machinery/newscaster/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/central/starboard) +"hLE" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/table, +/obj/item/folder/red{ + pixel_x = -5 + }, +/obj/item/pen{ + pixel_x = -4; + pixel_y = -1 + }, +/obj/item/storage/secure/briefcase{ + pixel_x = 5; + pixel_y = 7 + }, +/turf/open/floor/iron, +/area/station/security/office) "hLF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable/yellow{ @@ -22136,18 +22194,16 @@ /area/station/security/pig) "itw" = ( /obj/structure/table, -/obj/item/reagent_containers/food/drinks/coffee{ - pixel_x = -4; - pixel_y = 2 - }, -/obj/item/folder/red{ - pixel_x = 6; - pixel_y = 4 - }, /obj/item/radio/intercom/directional/east, /obj/effect/turf_decal/trimline/red/line{ dir = 1 }, +/obj/machinery/telephone/security, +/obj/structure/cable/yellow{ + icon_state = "1" + }, +/obj/machinery/telephone/security, +/obj/machinery/power/data_terminal, /turf/open/floor/iron, /area/station/security/brig) "itB" = ( @@ -23779,6 +23835,12 @@ }, /turf/open/floor/iron/white, /area/station/hallway/secondary/entry) +"iXU" = ( +/obj/structure/cable/yellow{ + icon_state = "6" + }, +/turf/open/floor/iron, +/area/station/security/brig) "iYi" = ( /obj/machinery/navbeacon{ location = "9.3-Escape-3"; @@ -25242,6 +25304,11 @@ }, /turf/open/floor/plating, /area/station/cargo/storage) +"jAc" = ( +/obj/structure/table, +/obj/machinery/projector, +/turf/open/floor/iron, +/area/station/security/office) "jAj" = ( /obj/effect/turf_decal/tile/neutral, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -26487,16 +26554,15 @@ /turf/open/floor/iron/dark, /area/station/security/office/hall) "jYA" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Security Office"; - req_one_access_txt = "1;4" - }, /obj/structure/cable/yellow{ icon_state = "3" }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + name = "Security Office" + }, /turf/open/floor/iron/dark, /area/station/security/office) "jYH" = ( @@ -26707,6 +26773,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/security/office) +"kcJ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/item/kirbyplants/random, +/turf/open/floor/iron, +/area/station/hallway/primary/fore) "kcL" = ( /obj/structure/chair/stool/directional/west, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -27531,6 +27603,10 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/landmark/start/security_officer, /turf/open/floor/iron, /area/station/security/office) "ksR" = ( @@ -27864,14 +27940,13 @@ /turf/open/floor/iron/dark, /area/station/security/detectives_office/private_investigators_office) "kzq" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Security Office"; - req_one_access_txt = "1;4" - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + name = "Security Office" + }, /turf/open/floor/iron/dark, /area/station/security/office) "kzs" = ( @@ -29388,6 +29463,20 @@ /obj/effect/spawner/random/structure/crate, /turf/open/floor/iron, /area/station/cargo/warehouse) +"ldb" = ( +/obj/structure/cable/yellow{ + icon_state = "3" + }, +/obj/structure/table, +/obj/item/storage/box/evidence{ + pixel_x = -4 + }, +/obj/item/toy/crayon/white{ + pixel_x = 9; + pixel_y = 7 + }, +/turf/open/floor/iron, +/area/station/security/office) "lde" = ( /obj/structure/table/reinforced, /obj/effect/turf_decal/tile/bar, @@ -32277,9 +32366,6 @@ /obj/structure/cable/yellow{ icon_state = "3" }, -/obj/structure/cable/yellow{ - icon_state = "10" - }, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -32560,6 +32646,10 @@ icon_state = "12" }, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/landmark/start/security_officer, /turf/open/floor/iron, /area/station/security/office) "mna" = ( @@ -33574,21 +33664,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"mGc" = ( -/obj/structure/table, -/obj/item/folder/red{ - pixel_x = -5 - }, -/obj/item/pen{ - pixel_x = -4; - pixel_y = -1 - }, -/obj/item/storage/secure/briefcase{ - pixel_x = 5; - pixel_y = 7 - }, -/turf/open/floor/iron, -/area/station/security/office) "mGx" = ( /obj/structure/sign/warning/vacuum/external{ pixel_x = 32 @@ -34373,6 +34448,7 @@ /obj/machinery/camera/directional/north{ c_tag = "Fore Primary Hallway Cells" }, +/obj/item/kirbyplants/random, /turf/open/floor/iron, /area/station/hallway/primary/fore) "mRC" = ( @@ -34441,9 +34517,6 @@ /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory/upper) "mSE" = ( -/obj/structure/filingcabinet/chestdrawer{ - name = "case files" - }, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -34671,10 +34744,8 @@ /obj/structure/cable/yellow{ icon_state = "12" }, -/obj/structure/chair{ - dir = 8 - }, /obj/effect/decal/cleanable/dirt, +/obj/structure/table, /turf/open/floor/iron, /area/station/security/office) "mXg" = ( @@ -41133,12 +41204,6 @@ /obj/effect/turf_decal/tile/bar/half/contrasted, /turf/open/floor/iron/white, /area/station/medical/pharmacy) -"poD" = ( -/obj/structure/chair{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/security/office) "poJ" = ( /obj/effect/turf_decal/tile/red/opposingcorners, /obj/effect/turf_decal/tile/blue/opposingcorners{ @@ -44554,16 +44619,13 @@ /turf/open/floor/iron, /area/station/commons/locker) "qCP" = ( -/obj/structure/table, -/obj/item/poster/random_official{ - pixel_y = 3 - }, -/obj/item/poster/random_official{ - pixel_y = 9 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/button/door/directional/north{ + name = "Shutter Control"; + id = "security_meeting" + }, /turf/open/floor/iron, /area/station/security/office) "qCV" = ( @@ -48385,15 +48447,10 @@ /turf/open/floor/iron, /area/station/hallway/secondary/command) "rYX" = ( -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = 2; - pixel_y = 4 - }, -/obj/item/pen{ - pixel_x = -3; - pixel_y = 5 +/obj/structure/chair{ + dir = 4 }, +/obj/effect/landmark/start/security_officer, /turf/open/floor/iron, /area/station/security/office) "rZp" = ( @@ -50057,6 +50114,7 @@ pixel_y = 6 }, /obj/item/storage/secure/safe/directional/north, +/obj/machinery/light_switch/directional/east, /turf/open/floor/wood, /area/station/command/heads_quarters/hos) "sDV" = ( @@ -50156,10 +50214,6 @@ }, /turf/open/floor/wood, /area/station/command/heads_quarters/captain/private) -"sFp" = ( -/obj/machinery/vending/coffee, -/turf/open/floor/iron, -/area/station/security/office) "sFr" = ( /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 8 @@ -52888,10 +52942,6 @@ }, /turf/open/floor/carpet/blue, /area/station/medical/medbay/lobby) -"tKK" = ( -/obj/machinery/photocopier, -/turf/open/floor/wood, -/area/station/command/heads_quarters/hos) "tLb" = ( /obj/structure/rack, /obj/effect/spawner/random/clothing/costume, @@ -53011,6 +53061,15 @@ /obj/structure/overfloor_catwalk/iron_dark, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"tOJ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/table, +/obj/machinery/photocopier{ + pixel_x = -1; + pixel_y = 4 + }, +/turf/open/floor/iron, +/area/station/security/office) "tOO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/overfloor_catwalk/iron_dark, @@ -53325,6 +53384,13 @@ /obj/structure/table, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"tUg" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/landmark/start/security_officer, +/turf/open/floor/iron, +/area/station/security/office) "tUp" = ( /obj/docking_port/stationary{ name = "arrivals"; @@ -53489,6 +53555,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/effect/landmark/start/warden, /turf/open/floor/iron, /area/station/security/office) "tXy" = ( @@ -53977,6 +54044,16 @@ }, /turf/open/floor/iron/white, /area/station/hallway/secondary/entry) +"ugR" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/landmark/start/security_officer, +/turf/open/floor/iron, +/area/station/security/office) "ugS" = ( /obj/effect/turf_decal/stripes/corner{ dir = 4 @@ -56259,11 +56336,10 @@ /turf/open/floor/iron, /area/station/security/brig) "uZI" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Security Office"; - req_one_access_txt = "1;4" - }, /obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security{ + name = "Security Office" + }, /turf/open/floor/iron/dark, /area/station/security/office) "uZL" = ( @@ -59315,15 +59391,6 @@ /turf/open/floor/iron/dark, /area/station/command/bridge) "wjw" = ( -/obj/structure/table, -/obj/item/paper/crumpled{ - pixel_x = -4; - pixel_y = -1 - }, -/obj/item/food/donut{ - pixel_x = 8; - pixel_y = 7 - }, /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/station/security/office) @@ -60019,6 +60086,9 @@ "wvy" = ( /obj/effect/spawner/structure/window/prepainted/marsexec, /obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters{ + id = "security_meeting" + }, /turf/open/floor/plating, /area/station/security/office) "wvz" = ( @@ -60062,6 +60132,10 @@ }, /turf/open/floor/iron, /area/station/construction/storage_wing) +"wvU" = ( +/obj/effect/mapping_helpers/lightsout, +/turf/open/floor/iron, +/area/station/security/office) "wwq" = ( /obj/structure/cable/yellow{ icon_state = "12" @@ -63123,20 +63197,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/disposal) -"xCp" = ( -/obj/structure/cable/yellow{ - icon_state = "12" - }, -/obj/structure/table, -/obj/item/toy/crayon/white{ - pixel_x = 9; - pixel_y = 7 - }, -/obj/item/storage/box/evidence{ - pixel_x = -4 - }, -/turf/open/floor/iron, -/area/station/security/office) "xCF" = ( /obj/structure/transit_tube/curved{ dir = 4 @@ -63315,6 +63375,9 @@ /area/station/hallway/primary/starboard) "xFd" = ( /obj/machinery/light/directional/south, +/obj/structure/cable/yellow{ + icon_state = "24" + }, /turf/open/floor/iron, /area/station/security/brig) "xFj" = ( @@ -92469,7 +92532,7 @@ bLG uik trg smg -yfL +iXU itw wWn jal @@ -92989,7 +93052,7 @@ xwK lzR dGq xwK -egG +kcJ pay wGX aQg @@ -94010,7 +94073,7 @@ jvP wvy hMc kdU -dEn +tOJ fle htm wvy @@ -94269,7 +94332,7 @@ chm dVb dvS dvS -kra +wvU uZI qUb sNh @@ -94783,7 +94846,7 @@ taJ kcs xve mOd -poD +dvS wvy dpC sNh @@ -95040,7 +95103,7 @@ xTA rYX beg ksK -mGc +dvS flN cLL vzd @@ -95294,10 +95357,10 @@ mft tjG flN tXj -vzY +ldb eOG -ksK -sFp +hLE +dvS rAR cLL nSV @@ -95549,10 +95612,10 @@ leQ wZf qDH doA -wvy +flN dqG -dvS -xCp +jAc +kra aGW aGW aGW @@ -95806,12 +95869,12 @@ wZf wZf aVZ doA -wvy +flN qCP -dvS +hnf mXf -aGW -poD +ebW +dvS uSp cLL tMU @@ -96063,11 +96126,11 @@ sCK tWI aRh doA -wvy +flN mSE -dvS +tUg mmZ -ksK +ugR wjw cLL cLL @@ -97348,7 +97411,7 @@ heA pJG lAK gJJ -tKK +upB uMQ vXw ahz diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index 351108aa43cf..f24af50871bf 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -107,3 +107,30 @@ do { \ #define LIGHTS_RANDOMLY_BROKEN #define TURF_IS_DYNAMICALLY_LIT(T) (!(T.always_lit || T.loc.luminosity)) + +// Machinery lights +///How much power emergency lights will consume per tick +#define LIGHT_EMERGENCY_POWER_USE 0.2 +// status values shared between lighting fixtures and items +#define LIGHT_OK 0 +#define LIGHT_EMPTY 1 +#define LIGHT_BROKEN 2 +#define LIGHT_BURNED 3 + +///Min time for a spark to happen in a broken light +#define BROKEN_SPARKS_MIN (3 MINUTES) +///Max time for a spark to happen in a broken light +#define BROKEN_SPARKS_MAX (9 MINUTES) + +///Amount of time that takes an ethereal to take energy from the lights +#define LIGHT_DRAIN_TIME 2.5 SECONDS +///Amount of charge the ethereal gain after the drain +#define LIGHT_POWER_GAIN 35 + +///How many reagents the lights can hold +#define LIGHT_REAGENT_CAPACITY 5 + +//Status for light constructs +#define LIGHT_CONSTRUCT_EMPTY 1 +#define LIGHT_CONSTRUCT_WIRED 2 +#define LIGHT_CONSTRUCT_CLOSED 3 diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm index b5c9dee21095..485af212cd3e 100644 --- a/code/controllers/subsystem/explosions.dm +++ b/code/controllers/subsystem/explosions.dm @@ -505,6 +505,22 @@ SUBSYSTEM_DEF(explosions) far_dist += devastation_range * 20 shake_the_room(epicenter, original_max_distance, far_dist, devastation_range, heavy_impact_range) + // Flicker lights + var/effective_range = devastation_range * 5 + heavy_impact_range * 2 + light_impact_range + for(var/obj/machinery/light/L as anything in INSTANCES_OF(/obj/machinery/light)) + if(!isturf(L.loc)) + continue + + var/dist = get_dist_euclidean(L.loc, epicenter) + if(dist > effective_range) + continue + + var/delay = clamp(ceil(dist) * (0.1 SECONDS), 0, 5 SECONDS) + if(delay) + addtimer(CALLBACK(L, TYPE_PROC_REF(/obj/machinery/light, flicker), pick(1, 3)), delay) + else + L.flicker(pick(1, 3)) + /datum/controller/subsystem/explosions/proc/perform_explosion(epicenter, list/act_turfs, heavy_power, dev_power, flame_power, turf_tally_ptr, movable_tally_ptr) var/turf_tally = 0 var/movable_tally = 0 diff --git a/code/controllers/subsystem/sound_cache.dm b/code/controllers/subsystem/sound_cache.dm index 38fb82419ac9..56ed140af4ef 100644 --- a/code/controllers/subsystem/sound_cache.dm +++ b/code/controllers/subsystem/sound_cache.dm @@ -44,7 +44,7 @@ SUBSYSTEM_DEF(sound_cache) for(var/i in 1 to length(paths)) reconstructed[i] = "[paths[i]]" - var/list/out = rustg_sound_length_list(paths) + var/list/out = rustg_sound_length_list(reconstructed) var/list/successes = out[RUSTG_SOUNDLEN_SUCCESSES] for(var/sound_path in successes) sound_lengths[sound_path] = text2num(successes[sound_path]) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index cf32db7d7685..fafd301e4127 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -478,6 +478,7 @@ SUBSYSTEM_DEF(ticker) living.notransform = TRUE living.client?.init_verbs() livings += living + if(livings.len) addtimer(CALLBACK(src, PROC_REF(release_characters), livings), 30, TIMER_CLIENT_TIME) diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 68c20eb8d43b..46b6d7a16ebe 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -134,8 +134,8 @@ return // Non mobs speakers can be small - if (!ismob(target)) - extra_classes |= "small" + if (target.chat_class) + extra_classes |= target.chat_class var/list/prefixes diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 637e60edcd01..1251ca840138 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -110,6 +110,11 @@ var/datum/alarm_handler/alarm_manager + /// A lazylist of ckeys that have entered this area. See display_flavor() + var/list/ckeys_that_have_been_here + /// A weighted list of flavor texts for display_flavor(). + var/list/flavor_texts + /** * A list of teleport locations * @@ -478,7 +483,11 @@ GLOBAL_LIST_EMPTY(teleportlocs) /// Called when a living mob that spawned here, joining the round, receives the player client. /area/proc/on_joining_game(mob/living/boarder) - return + SHOULD_CALL_PARENT(TRUE) + if(prob(5) && boarder.client && ishuman(boarder)) + LAZYADDASSOC(ckeys_that_have_been_here, boarder.ckey, TRUE) + spawn(0) + display_flavor(boarder) ///Called by airalarms and firealarms to communicate the status of the area to relevant machines /area/proc/communicate_fire_alert(code) @@ -505,3 +514,9 @@ GLOBAL_LIST_EMPTY(teleportlocs) var/old = spook_level spook_level += adj SEND_SIGNAL(src, AREA_SPOOK_LEVEL_CHANGED, src, old) + +/area/proc/display_flavor(mob/living/carbon/human/pawn) + if(!length(flavor_texts)) + return + + to_chat(pawn, pick_weight(flavor_texts)) diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm index 8531a6ec91db..5e2993e9e036 100644 --- a/code/game/area/areas/shuttles.dm +++ b/code/game/area/areas/shuttles.dm @@ -112,9 +112,16 @@ /area/shuttle/arrival name = "Arrival Shuttle" area_flags = UNIQUE_AREA// SSjob refers to this area for latejoiners - + flavor_texts = list( + span_statsgood("Bootprints paint the floor with grime. You are home.") = 1, + span_statsgood("The quiet metallic creaking of the shuttle comforts you as it pulls into the station.") = 1, + span_statsgood("Hundreds, perhaps thousands of footsteps have eaten away at the floors where you stand.") = 1, + span_statsgood("The soft droning of the vessel's drive is comforting. You can hear your heart beating in it's cage.") = 1, + span_statsgood("Thousands of scratches adorn the view ports from the unspeakable volume of particles brushing against them.") = 1 + ) /area/shuttle/arrival/on_joining_game(mob/living/boarder) + . = ..() boarder.update_parallax_teleport() /area/shuttle/pod_1 diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 05cfef4bfcee..75dc41c8d03d 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -72,6 +72,8 @@ var/tmp/chat_color /// A luminescence-shifted value of the last color calculated for chatmessage overlays var/tmp/chat_color_darkened + /// Class to attach to runechat. + var/tmp/chat_class ///Holds merger groups currently active on the atom. Do not access directly, use GetMergeGroup() instead. var/tmp/list/datum/merger/mergers diff --git a/code/game/machinery/projector.dm b/code/game/machinery/projector.dm new file mode 100644 index 000000000000..c3ef8c544e5c --- /dev/null +++ b/code/game/machinery/projector.dm @@ -0,0 +1,142 @@ +// This is currently just used for the sec intro and is written as such. Fix it if you want to use it. Or bug me about it. +/obj/machinery/projector + name = "projector" + icon = 'icons/obj/machines/projector.dmi' + base_icon_state = "projector" + icon_state = "projector0" + + dir = SOUTH + light_on = FALSE + light_color = LIGHT_COLOR_BABY_BLUE + light_power = 0.4 + light_inner_range = 0.8 + light_outer_range = 3 + + var/playing = FALSE + +/obj/machinery/projector/Initialize(mapload) + . = ..() + if(!SSticker.HasRoundStarted()) + SSticker.OnRoundstart(CALLBACK(src, PROC_REF(play), 5 SECONDS)) + +/obj/machinery/projector/update_icon_state() + icon_state = "[base_icon_state][playing]" + return ..() + +/obj/machinery/projector/proc/play(initial_delay = 3 SECONDS) + set waitfor = FALSE + + say("Incoming transmission.") + if(initial_delay) + sleep(initial_delay) + + var/turf/destination = get_ranged_target_turf(src, SOUTH, 2) + var/obj/effect/overlay/holoray/ray = new(loc) + var/obj/effect/abstract/projected_image/guy = new(destination) + + + guy.icon = icon + guy.icon_state = "sec" + + guy.makeHologram() + guy.add_overlay(emissive_appearance(guy.icon, guy.icon_state, alpha = 180)) + + guy.alpha = 0 + ray.alpha = 0 + update_ray(ray, destination, destination) + + animate(ray, alpha = 255, time = 2 SECONDS) + animate(guy, alpha = 255, time = 2 SECONDS) + + visible_message("[icon2html(src, viewers(src))] [src] clicks on.") + playing = TRUE + set_light(l_on = TRUE) + update_appearance() + + sleep(4 SECONDS) + + var/list/phrases = list( + 'sound/misc/sec_intro/1.ogg' = "BEGIN TRANSMISSION.", + 'sound/misc/sec_intro/2.ogg' = "HELLO PEACEKEEPERS.", + 'sound/misc/sec_intro/3.ogg' = "YOUR JOB IS TO ENSURE COMPLIANCE WITH THE MANAGERS.", + 'sound/misc/sec_intro/4.ogg' = "THIS IS TO ENSURE THE SAFETY OF THE PUBLIC.", + 'sound/misc/sec_intro/5.ogg' = "YOU WILL BE PAID HANDSOMELY FOR YOUR WORK.", + 'sound/misc/sec_intro/6.ogg' = "DO NOT ALLOW THE TERRIBLE THING TO SPREAD.", + 'sound/misc/sec_intro/7.ogg' = "END TRANSMISSION.", + ) + + SSsound_cache.cache_sounds(phrases) + + for(var/sound in phrases) + guy.say(phrases[sound]) + playsound(src, sound, 100, FALSE) + sleep(SSsound_cache.get_sound_length(sound) + 0.6 SECONDS) + + animate(guy, alpha = 0, time = 2 SECONDS) + animate(ray, alpha = 0, time = 2 SECONDS) + + sleep(2 SECONDS) + + visible_message("[icon2html(src, viewers(src))] [src] clicks off.") + playing = FALSE + set_light(l_on = FALSE) + update_appearance() + + qdel(guy) + qdel(ray) + +/obj/machinery/projector/proc/update_ray(obj/effect/overlay/holoray/ray, turf/new_turf, turf/old_turf, animate = TRUE) + var/disty = old_turf.y - ray.y + var/distx = old_turf.x - ray.x + var/newangle + if(!disty) + if(distx >= 0) + newangle = 90 + else + newangle = 270 + else + newangle = arctan(distx/disty) + if(disty < 0) + newangle += 180 + else if(distx < 0) + newangle += 360 + + var/matrix/new_transform = matrix() + new_transform.Scale(1, sqrt(distx * distx + disty * disty)) + new_transform.Turn(newangle) + + if (animate) + animate(ray, transform = new_transform, time = 1) + else + ray.transform = new_transform + +/obj/machinery/projector/proc/makeicon() + var/mob/living/carbon/human/H = new() + H.equipOutfit(new /datum/outfit/centcom/ert/commander) + + var/icon/icon = getFlatIcon(H) + // Zoom in on the top of the head and the chest + // I have no idea how to do this dynamically. + icon.Scale(64, 64) + + // This is probably better as a Crop, but I cannot figure it out. + icon.Shift(WEST, 15) + icon.Shift(SOUTH, 30) + + icon.Crop(1, 1, 32, 32) + + if(!fexists("data/saved_icons.dmi")) + fcopy("", "data/saved_icons.dmi") + + var/icon/local = icon("data/saved_icons.dmi") + local.Insert(icon, "temp") + fcopy(local, "data/saved_icons.dmi") + +/obj/effect/abstract/projected_image + name = "projection" + chat_class = null + + light_color = LIGHT_COLOR_BABY_BLUE + light_power = 0.4 + light_inner_range = 0.5 + light_outer_range = 2 diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index f2765f52e280..b61f33203627 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -47,27 +47,63 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) var/high_priority = FALSE /// Does what it says on the tin. var/delete_after_roundstart = TRUE + /// Does this delete itself if the marked atom is deleted? + var/delete_if_marked_atom_deleted = FALSE /// Tracks if this spawn has been used or not. var/used = FALSE + /// The atom we're tracking. + var/atom/marked_atom + /obj/effect/landmark/start/proc/after_round_start() if(delete_after_roundstart) qdel(src) /obj/effect/landmark/start/Initialize(mapload) . = ..() + set_marked_atom(find_marked_atom()) + GLOB.start_landmarks_list += src LAZYADD(GLOB.start_landmarks_by_name[name], src) if(high_priority) LAZYADD(GLOB.high_priority_spawns[name], src) /obj/effect/landmark/start/Destroy() + if(marked_atom) + unset_marked_atom() + GLOB.start_landmarks_list -= src LAZYREMOVE(GLOB.start_landmarks_by_name[name], src) if(high_priority) LAZYREMOVE(GLOB.high_priority_spawns[name], src) return ..() +/// Returns the landmark atom. Allows job landmarks to define the actual atom to call JoinPlayerHere() on. +/obj/effect/landmark/start/proc/find_marked_atom() + return locate(/obj/structure/chair, loc) || src + +/// Call this to get the actual spawn location of the atom. +/obj/effect/landmark/start/proc/get_spawn_location() + return marked_atom + +/obj/effect/landmark/start/proc/set_marked_atom(atom/new_atom) + PRIVATE_PROC(TRUE) + + marked_atom = new_atom + if(marked_atom != src) + RegisterSignal(marked_atom, COMSIG_PARENT_QDELETING, PROC_REF(marked_gone)) + +/obj/effect/landmark/start/proc/unset_marked_atom() + PRIVATE_PROC(TRUE) + + marked_atom = null + +/obj/effect/landmark/start/proc/marked_gone(datum/source) + SIGNAL_HANDLER + unset_marked_atom() + if(delete_if_marked_atom_deleted) + qdel(src) + // START LANDMARKS FOLLOW. Don't change the names unless // you are refactoring shitty landmark code. /obj/effect/landmark/start/assistant diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index c7897ef01fa0..3e9e16859878 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -32,11 +32,6 @@ // // The explosion cannot insta-kill anyone with 30% or more health. -#define LIGHT_OK 0 -#define LIGHT_EMPTY 1 -#define LIGHT_BROKEN 2 -#define LIGHT_BURNED 3 - /obj/item/lightreplacer @@ -258,8 +253,3 @@ /obj/item/lightreplacer/cyborg/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, CYBORG_ITEM_TRAIT) - -#undef LIGHT_OK -#undef LIGHT_EMPTY -#undef LIGHT_BROKEN -#undef LIGHT_BURNED diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index c22462a38695..757abce144ec 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -2,6 +2,8 @@ /obj animate_movement = SLIDE_STEPS speech_span = SPAN_ROBOT + chat_class = "small" + var/obj_flags = CAN_BE_HIT var/damtype = BRUTE diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm index 5b48ab07c2b5..03b58e86eb1e 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -159,6 +159,9 @@ if(!ishuman(H)) return + if(!H.time_of_death_stats) + to_chat(usr, span_warning("[H] has not died.")) + return H.show_death_stats(usr) diff --git a/code/modules/antagonists/gang/handler.dm b/code/modules/antagonists/gang/handler.dm index 5e9952253442..56992bc33fc9 100644 --- a/code/modules/antagonists/gang/handler.dm +++ b/code/modules/antagonists/gang/handler.dm @@ -14,7 +14,6 @@ #define CREW_SIZE_MAX 8 -GLOBAL_VAR_INIT(deaths_during_shift, 0) ///Forces the Families theme to be the one in this variable via variable editing. Used for debugging. GLOBAL_VAR(families_override_theme) @@ -63,8 +62,6 @@ GLOBAL_VAR(families_override_theme) var/midround_ruleset = FALSE /// Whether we want to use the 30 to 15 minute timer instead of the 60 to 30 minute timer, for Dynamic. var/use_dynamic_timing = FALSE - /// Keeps track of the amount of deaths since the calling of pre_setup_analogue() if this is a midround handler. Used to prevent a high wanted level due to a large amount of deaths during the shift prior to the activation of this handler / the midround ruleset. - var/deaths_during_shift_at_beginning = 0 /// List of all eligible starting family members / undercover cops. Set externally (passed by reference) by gamemode / ruleset; used internally. Note that dynamic uses a list of mobs to handle candidates while game_modes use lists of minds! Don't be fooled! var/list/antag_candidates = list() @@ -102,10 +99,7 @@ GLOBAL_VAR(families_override_theme) * and the modification of gangs_to_generate, gang_balance_cap, and midround_ruleset. * It is intended to take the place of the code that would normally occupy the pre_setup() * or pre_execute() proc, were the code localized to the game_mode or dynamic_ruleset datum respectively - * as opposed to this handler. As such, it picks players to be chosen for starting familiy members - * or undercover cops prior to assignment to jobs. Sets start_time, default end_time, - * and the current value of deaths_during_shift, to ensure the wanted level only cares about - * the deaths since this proc has been called. + * as opposed to this handler. As such, it picks players to be chosen for starting familiy members. * Takes no arguments. */ /datum/gang_handler/proc/pre_setup_analogue() @@ -114,25 +108,29 @@ GLOBAL_VAR(families_override_theme) current_theme = new theme_to_use else current_theme = new GLOB.families_override_theme + message_admins("Families has chosen the theme: [current_theme.name]") log_game("FAMILIES: The following theme has been chosen: [current_theme.name]") + var/gangsters_to_make = length(current_theme.involved_gangs) * current_theme.starting_gangsters for(var/i in 1 to gangsters_to_make) if (!antag_candidates.len) break var/taken = pick_n_take(antag_candidates) // original used antag_pick, but that's local to game_mode and rulesets use pick_n_take so this is fine maybe + var/datum/mind/gangbanger if(istype(taken, /mob)) var/mob/T = taken gangbanger = T.mind else gangbanger = taken + gangbangers += gangbanger gangbanger.restricted_roles = restricted_jobs log_game("[key_name(gangbanger)] has been selected as a starting gangster!") if(!midround_ruleset) GLOB.pre_setup_antags += gangbanger - deaths_during_shift_at_beginning = GLOB.deaths_during_shift // don't want to mix up pre-families and post-families deaths + start_time = world.time end_time = start_time + ((60 MINUTES) / (midround_ruleset ? 2 : 1)) // midround families rounds end quicker return TRUE @@ -206,202 +204,3 @@ GLOBAL_VAR(families_override_theme) /datum/gang_handler/proc/announce_gang_locations() priority_announce(current_theme.description, current_theme.name, sound_type = 'sound/voice/beepsky/radio.ogg') sent_announcement = TRUE - -/// Internal. Checks if our wanted level has changed; calls update_wanted_level. Only updates wanted level post the initial announcement and until the cops show up. After that, it's locked. -/datum/gang_handler/proc/check_wanted_level() - if(cops_arrived) - update_wanted_level(wanted_level) // at this point, we still want to update people's star huds, even though they're mostly locked, because not everyone is around for the last update before the rest of this proc gets shut off forever, and that's when the wanted bar switches from gold stars to red / blue to signify the arrival of the space cops - return - if(!sent_announcement) - return - var/new_wanted_level - if(GLOB.joined_player_list.len > LOWPOP_FAMILIES_COUNT) - switch(GLOB.deaths_during_shift - deaths_during_shift_at_beginning) // if this is a midround ruleset, we only care about the deaths since the families were activated, not since shiftstart - if(0 to TWO_STARS_HIGHPOP-1) - new_wanted_level = 1 - if(TWO_STARS_HIGHPOP to THREE_STARS_HIGHPOP-1) - new_wanted_level = 2 - if(THREE_STARS_HIGHPOP to FOUR_STARS_HIGHPOP-1) - new_wanted_level = 3 - if(FOUR_STARS_HIGHPOP to FIVE_STARS_HIGHPOP-1) - new_wanted_level = 4 - if(FIVE_STARS_HIGHPOP to INFINITY) - new_wanted_level = 5 - else - switch(GLOB.deaths_during_shift - deaths_during_shift_at_beginning) - if(0 to TWO_STARS_LOW-1) - new_wanted_level = 1 - if(TWO_STARS_LOW to THREE_STARS_LOW-1) - new_wanted_level = 2 - if(THREE_STARS_LOW to FOUR_STARS_LOW-1) - new_wanted_level = 3 - if(FOUR_STARS_LOW to FIVE_STARS_LOW-1) - new_wanted_level = 4 - if(FIVE_STARS_LOW to INFINITY) - new_wanted_level = 5 - update_wanted_level(new_wanted_level) - -/// Internal. Updates the icon states for everyone, and calls procs that send out announcements / change the end_time if the wanted level has changed. -/datum/gang_handler/proc/update_wanted_level(newlevel) - if(newlevel > wanted_level) - on_gain_wanted_level(newlevel) - else if (newlevel < wanted_level) - on_lower_wanted_level(newlevel) - wanted_level = newlevel - for(var/i in GLOB.player_list) - var/mob/M = i - if(!M.hud_used?.wanted_lvl) - continue - var/datum/hud/H = M.hud_used - H.wanted_lvl.level = newlevel - H.wanted_lvl.cops_arrived = cops_arrived - H.wanted_lvl.update_appearance() - -/// Internal. Updates the end_time and sends out an announcement if the wanted level has increased. Called by update_wanted_level(). -/datum/gang_handler/proc/on_gain_wanted_level(newlevel) - var/announcement_message - switch(newlevel) - if(2) - if(!sent_second_announcement) // when you hear that they're "arriving in 5 minutes," that's a goddamn guarantee - end_time = start_time + ((50 MINUTES) / (use_dynamic_timing ? 2 : 1)) - announcement_message = "Small amount of police vehicles have been spotted en route towards [station_name()]." - if(3) - if(!sent_second_announcement) - end_time = start_time + ((40 MINUTES) / (use_dynamic_timing ? 2 : 1)) - announcement_message = "A large detachment police vehicles have been spotted en route towards [station_name()]." - if(4) - if(!sent_second_announcement) - end_time = start_time + ((35 MINUTES) / (use_dynamic_timing ? 2 : 1)) - announcement_message = "A detachment of top-trained agents has been spotted on their way to [station_name()]." - if(5) - if(!sent_second_announcement) - end_time = start_time + ((30 MINUTES) / (use_dynamic_timing ? 2 : 1)) - announcement_message = "The fleet enroute to [station_name()] now consists of national guard personnel." - if(!midround_ruleset) // stops midround rulesets from announcing janky ass times - announcement_message += " They will arrive at the [(end_time - start_time) / (1 MINUTES)] minute mark." - if(newlevel == 1) // specific exception to stop the announcement from triggering right after the families themselves are announced because aesthetics - return - priority_announce(announcement_message) - -/// Internal. Updates the end_time and sends out an announcement if the wanted level has decreased. Called by update_wanted_level(). -/datum/gang_handler/proc/on_lower_wanted_level(newlevel) - var/announcement_message - switch(newlevel) - if(1) - if(!sent_second_announcement) - end_time = start_time + ((60 MINUTES) / (use_dynamic_timing ? 2 : 1)) - announcement_message = "There are now only a few police vehicle headed towards [station_name()]." - if(2) - if(!sent_second_announcement) - end_time = start_time + ((50 MINUTES) / (use_dynamic_timing ? 2 : 1)) - announcement_message = "There seem to be fewer police vehicles headed towards [station_name()]." - if(3) - if(!sent_second_announcement) - end_time = start_time + ((40 MINUTES) / (use_dynamic_timing ? 2 : 1)) - announcement_message = "There are no longer top-trained agents in the fleet headed towards [station_name()]." - if(4) - if(!sent_second_announcement) - end_time = start_time + ((35 MINUTES) / (use_dynamic_timing ? 2 : 1)) - announcement_message = "The convoy enroute to [station_name()] seems to no longer consist of national guard personnel." - if(!midround_ruleset) - announcement_message += " They will arrive at the [(end_time - start_time) / (1 MINUTES)] minute mark." - priority_announce(announcement_message) - -/// Internal. Polls ghosts and sends in a team of space cops according to the wanted level, accompanied by an announcement. Will let the shuttle leave 10 minutes after sending. Freezes the wanted level. -/datum/gang_handler/proc/send_in_the_fuzz() - var/team_size - var/cops_to_send - var/announcement_message = "PUNK ASS BALLA BITCH" - var/announcer = "Spinward Stellar Coalition" - if(GLOB.joined_player_list.len > LOWPOP_FAMILIES_COUNT) - switch(wanted_level) - if(1) - team_size = 8 - cops_to_send = /datum/antagonist/ert/families/beatcop - announcement_message = "Hello, crewmembers of [station_name()]! We've received a few calls about some potential violent gang activity on board your station, so we're sending some beat cops to check things out. Nothing extreme, just a courtesy call. However, while they check things out for about 10 minutes, we're going to have to ask that you keep your escape shuttle parked.\n\nHave a pleasant day!" - announcer = "Spinward Stellar Coalition Police Department" - if(2) - team_size = 9 - cops_to_send = /datum/antagonist/ert/families/beatcop/armored - announcement_message = "Crewmembers of [station_name()]. We have received confirmed reports of violent gang activity from your station. We are dispatching some armed officers to help keep the peace and investigate matters. Do not get in their way, and comply with any and all requests from them. We have blockaded the local warp gate, and your shuttle cannot depart for another 10 minutes.\n\nHave a secure day." - announcer = "Spinward Stellar Coalition Police Department" - if(3) - team_size = 10 - cops_to_send = /datum/antagonist/ert/families/beatcop/swat - announcement_message = "Crewmembers of [station_name()]. We have received confirmed reports of extreme gang activity from your station resulting in heavy civilian casualties. The Spinward Stellar Coalition does not tolerate abuse towards our citizens, and we will be responding in force to keep the peace and reduce civilian casualties. We have your station surrounded, and all gangsters must drop their weapons and surrender peacefully.\n\nHave a secure day." - announcer = "Spinward Stellar Coalition Police Department" - if(4) - team_size = 11 - cops_to_send = /datum/antagonist/ert/families/beatcop/fbi - announcement_message = "We are dispatching our top agents to [station_name()] at the request of the Spinward Stellar Coalition government due to an extreme terrorist level threat against this Daedalus Industries owned station. All gangsters must surrender IMMEDIATELY. Failure to comply can and will result in death. We have blockaded your warp gates and will not allow any escape until the situation is resolved within our standard response time of 10 minutes.\n\nSurrender now or face the consequences of your actions." - announcer = "Federal Bureau of Investigation" - if(5) - team_size = 12 - cops_to_send = /datum/antagonist/ert/families/beatcop/military - announcement_message = "Due to an insane level of civilian casualties aboard [station_name()], we have dispatched the National Guard to curb any and all gang activity on board the station. We have heavy cruisers watching the shuttle. Attempt to leave before we allow you to, and we will obliterate your station and your escape shuttle.\n\nYou brought this on yourselves by murdering so many civilians." - announcer = "Spinward Stellar Coalition National Guard" - else - switch(wanted_level) - if(1) - team_size = 5 - cops_to_send = /datum/antagonist/ert/families/beatcop - announcement_message = "Hello, crewmembers of [station_name()]! We've received a few calls about some potential violent gang activity on board your station, so we're sending some beat cops to check things out. Nothing extreme, just a courtesy call. However, while they check things out for about 10 minutes, we're going to have to ask that you keep your escape shuttle parked.\n\nHave a pleasant day!" - announcer = "Spinward Stellar Coalition Police Department" - if(2) - team_size = 6 - cops_to_send = /datum/antagonist/ert/families/beatcop/armored - announcement_message = "Crewmembers of [station_name()]. We have received confirmed reports of violent gang activity from your station. We are dispatching some armed officers to help keep the peace and investigate matters. Do not get in their way, and comply with any and all requests from them. We have blockaded the local warp gate, and your shuttle cannot depart for another 10 minutes.\n\nHave a secure day." - announcer = "Spinward Stellar Coalition Police Department" - if(3) - team_size = 7 - cops_to_send = /datum/antagonist/ert/families/beatcop/swat - announcement_message = "Crewmembers of [station_name()]. We have received confirmed reports of extreme gang activity from your station resulting in heavy civilian casualties. The Spinward Stellar Coalition does not tolerate abuse towards our citizens, and we will be responding in force to keep the peace and reduce civilian casualties. We have your station surrounded, and all gangsters must drop their weapons and surrender peacefully.\n\nHave a secure day." - announcer = "Spinward Stellar Coalition Police Department" - if(4) - team_size = 8 - cops_to_send = /datum/antagonist/ert/families/beatcop/fbi - announcement_message = "We are dispatching our top agents to [station_name()] at the request of the Spinward Stellar Coalition government due to an extreme terrorist level threat against this Daedalus Industries owned station. All gangsters must surrender IMMEDIATELY. Failure to comply can and will result in death. We have blockaded your warp gates and will not allow any escape until the situation is resolved within our standard response time of 10 minutes.\n\nSurrender now or face the consequences of your actions." - announcer = "Federal Bureau of Investigation" - if(5) - team_size = 10 - cops_to_send = /datum/antagonist/ert/families/beatcop/military - announcement_message = "Due to an insane level of civilian casualties aboard [station_name()], we have dispatched the National Guard to curb any and all gang activity on board the station. We have heavy cruisers watching the shuttle. Attempt to leave before we allow you to, and we will obliterate your station and your escape shuttle.\n\nYou brought this on yourselves by murdering so many civilians." - announcer = "Spinward Stellar Coalition National Guard" - - priority_announce(announcement_message, announcer, sound_type = 'sound/effects/families_police.ogg') - var/list/candidates = poll_ghost_candidates("Do you want to help clean up crime on this station?", "deathsquad") - - - if(candidates.len) - //Pick the (un)lucky players - var/numagents = min(team_size,candidates.len) - - var/list/spawnpoints = GLOB.emergencyresponseteamspawn - var/index = 0 - while(numagents && candidates.len) - var/spawnloc = spawnpoints[index+1] - //loop through spawnpoints one at a time - index = (index + 1) % spawnpoints.len - var/mob/dead/observer/chosen_candidate = pick(candidates) - candidates -= chosen_candidate - if(!chosen_candidate.key) - continue - - //Spawn the body - var/mob/living/carbon/human/cop = new(spawnloc) - chosen_candidate.client.prefs.safe_transfer_prefs_to(cop, is_antag = TRUE) - cop.key = chosen_candidate.key - - //Give antag datum - var/datum/antagonist/ert/families/ert_antag = new cops_to_send - - cop.mind.add_antag_datum(ert_antag) - cop.mind.set_assigned_role(SSjob.GetJobType(ert_antag.ert_job_path)) - SSjob.SendToLateJoin(cop) - - //Logging and cleanup - log_game("[key_name(cop)] has been selected as an [ert_antag.name]") - numagents-- - cops_arrived = TRUE - update_wanted_level(wanted_level) // gotta make sure everyone's wanted level display looks nice - return TRUE diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index 5ba357e19713..2e9e8c619a30 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -475,7 +475,7 @@ GLOBAL_LIST_INIT(job_display_order, list( spawnpoint.used = TRUE - return spawnpoint + return spawnpoint.get_spawn_location() /// Finds a valid latejoin spawn point, checking for events and special conditions. /datum/job/proc/get_latejoin_spawn_point() diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm index cb09f4124425..57ee925b55a9 100644 --- a/code/modules/mapping/mapping_helpers.dm +++ b/code/modules/mapping/mapping_helpers.dm @@ -863,11 +863,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava) return INITIALIZE_HINT_LATELOAD /obj/effect/mapping_helpers/lightsout/LateInitialize() - var/obj/machinery/power/apc/gaypc = locate() in loc - if(!gaypc) - CRASH("Lights-Out Helper missing APC at [COORD(src)]") - gaypc.lighting = gaypc.setsubsystem(1) //fuck you oldcode - gaypc.update() + var/area/A = get_area(src) + A.lightswitch = FALSE + A.power_change() qdel(src) // ----------- diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index ab5483f96bc2..70615bb626fb 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -269,7 +269,6 @@ /mob/dead/new_player/Move() return 0 - /mob/dead/new_player/proc/close_spawn_windows() src << browse(null, "window=playersetup") src << browse(null, "window=latechoices") //closes late choices window (Hey numbnuts go make this tgui) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 30f2dcad87d7..af845b53d1ab 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -38,16 +38,32 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift) . = ..() - if(client && !suiciding && !(client in GLOB.dead_players_during_shift)) - GLOB.dead_players_during_shift += client - GLOB.deaths_during_shift++ - if(!QDELETED(dna)) //The gibbed param is bit redundant here since dna won't exist at this point if they got deleted. dna.species.spec_death(gibbed, src) - if(SSticker.HasRoundStarted()) - SSblackbox.ReportDeath(src) - log_message("has died (BRUTE: [src.getBruteLoss()], BURN: [src.getFireLoss()], TOX: [src.getToxLoss()], OXY: [src.getOxyLoss()], CLONE: [src.getCloneLoss()])", LOG_ATTACK) + if(!SSticker.HasRoundStarted()) + return + + //* PAST THIS POINT THE ROUND HAS STARTED *// + + SSblackbox.ReportDeath(src) + log_message("has died (BRUTE: [src.getBruteLoss()], BURN: [src.getFireLoss()], TOX: [src.getToxLoss()], OXY: [src.getOxyLoss()], CLONE: [src.getCloneLoss()])", LOG_ATTACK) + + if(mind) + var/turf/T = get_turf(src) + var/obj/machinery/light/nearest_light + var/closest = INFINITY + for(var/obj/machinery/light/L in range(5, T)) + var/dist = get_dist(L, T) + if(dist > closest || L.constant_flickering || L.status != LIGHT_OK) + continue + + if(dist < closest || prob(50)) + nearest_light = L + closest = dist + + if(nearest_light) + addtimer(CALLBACK(nearest_light, TYPE_PROC_REF(/obj/machinery/light, start_flickering)), rand(20 SECONDS, 60 SECONDS)) /mob/living/carbon/human/proc/makeSkeleton() ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index bb78cf5afd5c..8394608c7e92 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -29,6 +29,21 @@ if(shoes && body_position == STANDING_UP && loc == NewLoc && has_gravity(loc)) SEND_SIGNAL(shoes, COMSIG_SHOES_STEP_ACTION) +/mob/living/carbon/human/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) + . = ..() + + if(!client || !isturf(old_loc) || !isturf(loc)) + return + + var/area/my_area = loc:loc + if(LAZYACCESS(my_area.ckeys_that_have_been_here, ckey)) + return + + LAZYADDASSOC(my_area.ckeys_that_have_been_here, ckey, TRUE) + + if(prob(1)) + my_area.display_flavor(src) + /mob/living/carbon/human/Process_Spacemove(movement_dir = 0, continuous_move = FALSE) if(movement_type & FLYING || HAS_TRAIT(src, TRAIT_FREE_FLOAT_MOVEMENT)) return TRUE diff --git a/code/modules/power/lighting/_light_defines.dm b/code/modules/power/lighting/_light_defines.dm deleted file mode 100644 index 5bc4762db5e9..000000000000 --- a/code/modules/power/lighting/_light_defines.dm +++ /dev/null @@ -1,25 +0,0 @@ -///How much power emergency lights will consume per tick -#define LIGHT_EMERGENCY_POWER_USE 0.2 -// status values shared between lighting fixtures and items -#define LIGHT_OK 0 -#define LIGHT_EMPTY 1 -#define LIGHT_BROKEN 2 -#define LIGHT_BURNED 3 - -///Min time for a spark to happen in a broken light -#define BROKEN_SPARKS_MIN (3 MINUTES) -///Max time for a spark to happen in a broken light -#define BROKEN_SPARKS_MAX (9 MINUTES) - -///Amount of time that takes an ethereal to take energy from the lights -#define LIGHT_DRAIN_TIME 2.5 SECONDS -///Amount of charge the ethereal gain after the drain -#define LIGHT_POWER_GAIN 35 - -///How many reagents the lights can hold -#define LIGHT_REAGENT_CAPACITY 5 - -//Status for light constructs -#define LIGHT_CONSTRUCT_EMPTY 1 -#define LIGHT_CONSTRUCT_WIRED 2 -#define LIGHT_CONSTRUCT_CLOSED 3 diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index 5f037edc5000..79f34375f1f0 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -196,21 +196,26 @@ DEFINE_INTERACTABLE(/obj/machinery/light) if(on) if(instant) turn_on(trigger, play_sound) + else if(maploaded) turn_on(trigger) maploaded = FALSE + else if(!turning_on) turning_on = TRUE addtimer(CALLBACK(src, PROC_REF(turn_on), trigger, play_sound), rand(LIGHT_ON_DELAY_LOWER, LIGHT_ON_DELAY_UPPER)) + else if(has_emergency_power(LIGHT_EMERGENCY_POWER_USE) && !turned_off()) if(use_power != NO_POWER_USE) use_power = IDLE_POWER_USE emergency_mode = TRUE START_PROCESSING(SSmachines, src) + else if(use_power != NO_POWER_USE) use_power = IDLE_POWER_USE set_light(0) + update_appearance() if(on != on_gs) @@ -485,11 +490,12 @@ DEFINE_INTERACTABLE(/obj/machinery/light) if(status != LIGHT_OK) break on = !on - update(FALSE, TRUE) //PARIAH EDIT CHANGE + update(FALSE, TRUE) sleep(rand(5, 15)) + on = (status == LIGHT_OK) - update(FALSE, TRUE) //PARIAH EDIT CHANGE - . = TRUE //did we actually flicker? + update(FALSE, TRUE) + flickering = FALSE // ai attack - make lights flicker, because why not diff --git a/daedalus.dme b/daedalus.dme index 5ba195abd5d4..1e3d66e685d4 100644 --- a/daedalus.dme +++ b/daedalus.dme @@ -1341,6 +1341,7 @@ #include "code\game\machinery\PDApainter.dm" #include "code\game\machinery\prisongate.dm" #include "code\game\machinery\prisonlabor.dm" +#include "code\game\machinery\projector.dm" #include "code\game\machinery\quantum_pad.dm" #include "code\game\machinery\recharger.dm" #include "code\game\machinery\rechargestation.dm" @@ -3934,7 +3935,6 @@ #include "code\modules\power\apc\apc_networking.dm" #include "code\modules\power\apc\apc_power_proc.dm" #include "code\modules\power\apc\apc_tool_act.dm" -#include "code\modules\power\lighting\_light_defines.dm" #include "code\modules\power\lighting\floor_light.dm" #include "code\modules\power\lighting\light.dm" #include "code\modules\power\lighting\light_construct.dm" diff --git a/icons/obj/machines/projector.dmi b/icons/obj/machines/projector.dmi new file mode 100644 index 000000000000..bfb9ac525b39 Binary files /dev/null and b/icons/obj/machines/projector.dmi differ diff --git a/modular_pariah/modules/aesthetics/lights/code/lighting.dm b/modular_pariah/modules/aesthetics/lights/code/lighting.dm index 8bdbe6697b19..7ae2fdd19369 100644 --- a/modular_pariah/modules/aesthetics/lights/code/lighting.dm +++ b/modular_pariah/modules/aesthetics/lights/code/lighting.dm @@ -46,6 +46,9 @@ playsound(src.loc, 'modular_pariah/modules/aesthetics/lights/sound/light_on.ogg', 65, 1) /obj/machinery/light/proc/start_flickering() + if(constant_flickering) + return + on = FALSE update(FALSE, TRUE, FALSE) @@ -54,6 +57,9 @@ flicker_timer = addtimer(CALLBACK(src, PROC_REF(flicker_on)), rand(5, 10)) /obj/machinery/light/proc/stop_flickering() + if(!constant_flickering) + return + constant_flickering = FALSE if(flicker_timer) diff --git a/sound/misc/sec_intro/1.ogg b/sound/misc/sec_intro/1.ogg new file mode 100644 index 000000000000..e7095cf55eb4 Binary files /dev/null and b/sound/misc/sec_intro/1.ogg differ diff --git a/sound/misc/sec_intro/2.ogg b/sound/misc/sec_intro/2.ogg new file mode 100644 index 000000000000..9145b6d5cdb7 Binary files /dev/null and b/sound/misc/sec_intro/2.ogg differ diff --git a/sound/misc/sec_intro/3.ogg b/sound/misc/sec_intro/3.ogg new file mode 100644 index 000000000000..981ba81a93cf Binary files /dev/null and b/sound/misc/sec_intro/3.ogg differ diff --git a/sound/misc/sec_intro/4.ogg b/sound/misc/sec_intro/4.ogg new file mode 100644 index 000000000000..f90ad8c3d064 Binary files /dev/null and b/sound/misc/sec_intro/4.ogg differ diff --git a/sound/misc/sec_intro/5.ogg b/sound/misc/sec_intro/5.ogg new file mode 100644 index 000000000000..f0d7149ea7dc Binary files /dev/null and b/sound/misc/sec_intro/5.ogg differ diff --git a/sound/misc/sec_intro/6.ogg b/sound/misc/sec_intro/6.ogg new file mode 100644 index 000000000000..cea382b8162b Binary files /dev/null and b/sound/misc/sec_intro/6.ogg differ diff --git a/sound/misc/sec_intro/7.ogg b/sound/misc/sec_intro/7.ogg new file mode 100644 index 000000000000..4dff99c85e4a Binary files /dev/null and b/sound/misc/sec_intro/7.ogg differ