Makes the backrooms spawn round start (#21835)

* possible to enter

* movable proc and door crush

* Update door.dm

* backrooms

* another proc instead of duplicate text

* Update door.dm

* vending too

* remove the lag

* fix roundstart

* rust_g was out of date

* Update MaintStation.dmm

* Update machines.dm

* Update machines.dm

* Update dependencies.sh

* Update machines.dm

* Update change_turf.dm

* Update change_turf.dm

* fixes

* Update change_turf.dm

* Update change_turf.dm

* Update random.dm

* Update reagentgrinder.dm

* Update reagentgrinder.dm

* revert

* own subsystem

* cleanup

* rename

* fans

* stuff

* safe

* Update maintrooms.dm

* Update maintrooms.dm

* Update maintrooms.dm

* Update level_traits.dm

* Update maintrooms.dm

* Update maintrooms.dm

* Update maintrooms.dm

* Update rust_g.dll

* helper

* rename and shuffle

* nope

* fixed runtimes

* Update subsystems.dm
This commit is contained in:
Molti
2024-05-31 01:06:05 -05:00
committed by GitHub
parent d843b1b2c5
commit 44e613bce5
26 changed files with 23037 additions and 22866 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -87,6 +87,7 @@
#define ADMIN_PUNISHMENT_SMSPIDER "SM Spider"
#define ADMIN_PUNISHMENT_FLASHBANG "Flashbang"
#define ADMIN_PUNISHMENT_WIBBLY "Wibblify"
#define ADMIN_PUNISHMENT_BACKROOMS "Backrooms"
#define AHELP_ACTIVE 1
#define AHELP_CLOSED 2

View File

@@ -150,7 +150,8 @@ Always compile, always use that verb, and always make sure that it works for wha
ZTRAIT_GRAVITY = TRUE, \
ZTRAIT_NOPHASE = TRUE, \
ZTRAIT_NOXRAY = TRUE, \
ZTRAIT_BASETURF = /turf/open/floor/plating)
ZTRAIT_BOMBCAP_MULTIPLIER = 0.5, \
ZTRAIT_BASETURF = /turf/open/floor/plating/backrooms)
///Z level traits for Away Missions
#define ZTRAITS_AWAY list(ZTRAIT_AWAY = TRUE)

View File

@@ -170,6 +170,7 @@
#define INIT_ORDER_ECHELON -10
#define INIT_ORDER_LIGHTING -20
#define INIT_ORDER_SHUTTLE -21
#define INIT_ORDER_BACKROOMS -30 // relies on basically everything to be initialized first
#define INIT_ORDER_MINOR_MAPPING -40
#define INIT_ORDER_BLUESPACE_LOCKER -45
#define INIT_ORDER_DISCORD -60

View File

@@ -25,6 +25,7 @@
#define ROOM_RATING_DEATH (1<<3)
//For categorizing rooms
///Random is the default, so it doesn't need to be included in the weighted list to spawn
#define ROOM_TYPE_RANDOM "random"
#define ROOM_TYPE_SPACE "space"
#define ROOM_TYPE_RUIN "ruin"

View File

@@ -30,3 +30,5 @@ GLOBAL_VAR(station_level_z_scratch)
#define is_secret_level(z) SSmapping.level_trait(z, ZTRAIT_SECRET)
#define is_reebe(z) SSmapping.level_trait(z, ZTRAIT_REEBE)
#define is_backrooms(z) SSmapping.level_trait(z, ZTRAIT_PROCEDURAL_MAINTS)

View File

@@ -0,0 +1,92 @@
SUBSYSTEM_DEF(backrooms)
name = "Procedural Generation"
init_order = INIT_ORDER_BACKROOMS
flags = SS_NO_FIRE
var/datum/map_generator/dungeon_generator/backrooms_generator
/datum/controller/subsystem/backrooms/Initialize(timeofday)
#ifdef LOWMEMORYMODE
return SS_INIT_NO_NEED
#endif
#ifdef UNIT_TESTS // This whole subsystem just introduces a lot of odd confounding variables into unit test situations, so let's just not bother with doing an initialize here.
return SS_INIT_NO_NEED
#endif
generate_backrooms()
return SS_INIT_SUCCESS
/datum/controller/subsystem/backrooms/proc/generate_backrooms()
var/list/errorList = list()
SSmapping.LoadGroup(errorList, "Backrooms", "map_files/generic", "MaintStation.dmm", default_traits = ZTRAITS_BACKROOM_MAINTS, silent = TRUE)
if(errorList.len) // failed to load
message_admins("Backrooms failed to load!")
log_game("Backrooms failed to load!")
for(var/area/A as anything in GLOB.areas)
if(istype(A, /area/procedurally_generated/maintenance/the_backrooms))
A.RunGeneration()
backrooms_generator = A.map_generator
break
if(backrooms_generator && istype(backrooms_generator))
var/min_x = backrooms_generator.min_x
var/max_x = backrooms_generator.max_x
var/min_y = backrooms_generator.min_y
var/max_y = backrooms_generator.max_y
var/z_level = backrooms_generator.z_level
for(var/turf/current_turf in block(locate(min_x,min_y,z_level),locate(max_x,max_y,z_level)))
if(current_turf.x == min_x || current_turf.x == max_x || current_turf.y == min_y || current_turf.y == max_y)
current_turf.empty(null, flags = CHANGETURF_DEFER_CHANGE | CHANGETURF_IGNORE_AIR)
current_turf.place_on_top(/turf/closed/indestructible/backrooms, flags = CHANGETURF_DEFER_CHANGE | CHANGETURF_IGNORE_AIR)
addtimer(CALLBACK(src, PROC_REF(generate_exit)), 1 MINUTES)
/datum/controller/subsystem/backrooms/proc/generate_exit()
var/list/backrooms_level = SSmapping.levels_by_trait(ZTRAIT_PROCEDURAL_MAINTS)
if(LAZYLEN(backrooms_level))
var/turf/way_out = find_safe_turf(zlevels = backrooms_level, dense_atoms = FALSE)
new /obj/effect/portal/permanent/one_way/backrooms(way_out)
/obj/effect/portal/permanent/one_way/backrooms/get_link_target_turf()
var/list/valid_lockers = typecacheof(typesof(/obj/structure/closet) - typesof(/obj/structure/closet/body_bag)\
- typesof(/obj/structure/closet/secure_closet) - typesof(/obj/structure/closet/cabinet)\
- typesof(/obj/structure/closet/cardboard) \
- typesof(/obj/structure/closet/supplypod) - typesof(/obj/structure/closet/stasis)\
- typesof(/obj/structure/closet/abductor) - typesof(/obj/structure/closet/bluespace), only_root_path = TRUE) //stolen from bluespace lockers
var/list/lockers_list = list()
for(var/obj/structure/closet/L in GLOB.lockers)
if(!is_station_level(L.z))
continue
if(!is_type_in_typecache(L, valid_lockers))
continue
if(L.opened)
continue
lockers_list += L
var/obj/structure/closet/exit = pick(lockers_list)
if(!exit)
exit = new(get_safe_random_station_turf())
return get_turf(exit)
/obj/effect/portal/permanent/one_way/backrooms/teleport(atom/movable/M, force)
. = ..()
if(.)
var/obj/structure/closet/end = locate() in get_turf(M)
if(end)
M.forceMove(end) //get in the locker, nerd
/obj/effect/portal/permanent/backrooms
icon_state = "wooden_tv"
/obj/effect/spawner/backrooms_portal
name = "backrooms two way portal spawner"
/obj/effect/spawner/backrooms_portal/Initialize(mapload)
var/backrooms_level = SSmapping.levels_by_trait(ZTRAIT_PROCEDURAL_MAINTS)
if(LAZYLEN(backrooms_level))
var/turf/way_out = find_safe_turf(zlevels = backrooms_level, dense_atoms = FALSE)
create_portal_pair(get_turf(src), way_out, _lifespan = -1, newtype = /obj/effect/portal/permanent/backrooms)
qdel(src)

View File

@@ -68,6 +68,9 @@
var/room_datum_path = /datum/dungeon_room
var/room_theme_path = /datum/dungeon_room_theme
///A list of the probability that a type of room theme can be selected. look at mapping.dm in yog defines
var/list/probability_room_types = list()
///Weighted list of the types that spawns if the turf is open
var/weighted_open_turf_types = list(/turf/open/floor/plating = 10)
///Expanded list of the types that spawns if the turf is open

View File

@@ -220,7 +220,7 @@
return
for(var/turf/room_turf in interior)
//we want to remove everything in the loc but don't want to change the loc type in this way
room_turf.empty(null, ignore_typecache = protected_atoms)
room_turf.empty(pickweight(weighted_open_turf_types), ignore_typecache = protected_atoms, flags = CHANGETURF_DEFER_CHANGE | CHANGETURF_IGNORE_AIR)
room_turf.place_on_top(pick(room_theme.get_random_flooring()), flags = CHANGETURF_DEFER_CHANGE | CHANGETURF_IGNORE_AIR)
return
@@ -251,7 +251,8 @@
if(istype(other_side_of_door, /turf/open/space))
num_of_doors_to_gen--
continue
door_spot.empty(pick(room_theme.get_random_flooring()), ignore_typecache = protected_atoms, flags = CHANGETURF_DEFER_CHANGE | CHANGETURF_IGNORE_AIR)
door_spot.empty(pickweight(weighted_open_turf_types), ignore_typecache = protected_atoms, flags = CHANGETURF_DEFER_CHANGE | CHANGETURF_IGNORE_AIR)
door_spot.place_on_top(pick(room_theme.get_random_flooring()), flags = CHANGETURF_DEFER_CHANGE | CHANGETURF_IGNORE_AIR)
var/door_path = room_theme.get_random_door()
if(ispath(door_path))
var/obj/machinery/door/new_door = new door_path(door_spot)

View File

@@ -1,3 +1,8 @@
///If it spawns firedoors to ensure mass spacing doesn't happen
#define ATMOS_CONTROL_FIREDOORS "spawn_firedoors"
///If it spawns atmos fans to ensure mass spacing doesn't happen
#define ATMOS_CONTROL_FANS "spawn_fans"
/datum/map_generator/dungeon_generator/maintenance
weighted_open_turf_types = list(
/turf/open/floor/plating = 10,
@@ -6,22 +11,42 @@
weighted_closed_turf_types = list(/turf/closed/wall = 5, /turf/closed/wall/rust = 2 )
room_datum_path = /datum/dungeon_room/maintenance
room_theme_path = /datum/dungeon_room_theme/maintenance
probability_room_types = list(ROOM_TYPE_RUIN = 75, ROOM_TYPE_SPACE = 20)
///Boolean, whether or not firelocks are added to the maintenance
var/atmos_control = ATMOS_CONTROL_FIREDOORS
///Boolean, wether or not apcs are added to the maintenance
var/include_apcs = TRUE
//var/list/used_spawn_points = list()
/datum/map_generator/dungeon_generator/maintenance/build_dungeon()
. = ..()
add_firelocks()
add_apcs()
wire_apcs()
if(atmos_control)
add_atmos_control()
if(include_apcs)
add_apcs()
wire_apcs()
add_maint_loot()
/datum/map_generator/dungeon_generator/maintenance/proc/add_firelocks()
/datum/map_generator/dungeon_generator/maintenance/proc/add_atmos_control()
///we only want to look to place firedoors every 5 tiles, so we don't place too many
var/step_increment = 5
var/consecutive_firedoor_limit = 3
var/list/fire_door_spawn_points = list()
var/fire_doors_path = /obj/effect/mapping_helpers/firedoor_border_spawner
var/fire_doors_path
switch(atmos_control)
if(ATMOS_CONTROL_FANS)
fire_doors_path = /obj/structure/fans/tiny/indestructible
if(ATMOS_CONTROL_FIREDOORS)
fire_doors_path = /obj/effect/mapping_helpers/firedoor_border_spawner
if(!fire_doors_path)
return
//spawn vertical lines of atmos control
for(var/y in min_y to max_y step step_increment)
fire_door_spawn_points = list()
for(var/turf/current_turf in block(locate(min_x,y,z_level),locate(max_x,y,z_level)))
@@ -34,7 +59,10 @@
if(fire_door_spawn_points.len > consecutive_firedoor_limit && current_turf.is_blocked_turf(TRUE))
fire_door_spawn_points = list()
fire_doors_path = /obj/effect/mapping_helpers/firedoor_border_spawner/horizontal
if(atmos_control == ATMOS_CONTROL_FIREDOORS)
fire_doors_path = /obj/effect/mapping_helpers/firedoor_border_spawner/horizontal
//spawn horizontal lines of atmos control
for(var/x in min_x to max_x step step_increment)
fire_door_spawn_points = list()
for(var/turf/current_turf in block(locate(x,min_y,z_level),locate(x,max_y,z_level)))
@@ -148,7 +176,7 @@
attempts--
//We're not actually building these so they can break if Init doesn't trigger right like using a generator mid round
if(!apc_placed.area)
if(apc_placed && !apc_placed.area)
apc_placed.area = get_area(apc_placed.loc)
/datum/map_generator/dungeon_generator/maintenance/proc/wire_apcs()
@@ -261,3 +289,26 @@
//what the fuck how did you get here
brazil = TRUE
return "blocked directions: [blocked_directions], against a wall: [against_wall], in a one tile hallway: [blocking_passage], brazil: [brazil]"
////////////////////////////////////////////////////////////////
//------------Generator specifically for the Z level----------//
////////////////////////////////////////////////////////////////
/datum/map_generator/dungeon_generator/maintenance/backrooms
//since there are no firelocks, the place needs to be hard to space and replenish air automatically
weighted_open_turf_types = list(
/turf/open/floor/plating/backrooms = 10,
/turf/open/floor/plating/rust = 1,
)
probability_room_types = list(ROOM_TYPE_RUIN = 75)
//removes firelocks and apcs as the area is large enough that it annihilates the server if it has a bunch of firelocks
atmos_control = null
include_apcs = FALSE
/turf/open/floor/plating/backrooms
baseturfs = /turf/open/floor/plating/backrooms
#undef ATMOS_CONTROL_FIREDOORS
#undef ATMOS_CONTROL_FANS

View File

@@ -4,19 +4,22 @@
/datum/dungeon_room/maintenance/generate_room_theme()
if(!room_type)
if(completed_room && is_ruin_compatible() && prob(75))
//because ruins are a special type we overwrite the previous flags so the only possible theme is the ruin type
room_type = ROOM_TYPE_RUIN
else if(completed_room && prob(20))
room_type = ROOM_TYPE_SPACE
else
var/list/room_types = generator_ref.probability_room_types
//if the room is a completed room, decide what special room type it should roll
if(completed_room)
for(var/type_check in room_types) //go through all types that the generator allows
if(type_check == ROOM_TYPE_RUIN && !is_ruin_compatible()) //the ruin type is special and needs to have a specific shape of room to work
continue
if(prob(room_types[type_check])) //get the probability of that ruin type from the list
room_type = type_check
if(!room_type) //if a room type wasn't picked, default to random
room_type = ROOM_TYPE_RANDOM
if(!room_danger_level)
if(completed_room && prob(50))
room_danger_level = ROOM_RATING_HOSTILE
else
room_danger_level = ROOM_RATING_SAFE

View File

@@ -168,4 +168,6 @@
/area/procedurally_generated/maintenance/the_backrooms
name = "The Backrooms"
requires_power = FALSE
map_generator = /datum/map_generator/dungeon_generator/maintenance/backrooms

View File

@@ -1359,3 +1359,10 @@
ADD_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT)
ADD_TRAIT(pulling, TRAIT_HANDS_BLOCKED, CHOKEHOLD_TRAIT)
/atom/movable/proc/sendToBackrooms()
var/backrooms_level = SSmapping.levels_by_trait(ZTRAIT_PROCEDURAL_MAINTS)
if(LAZYLEN(backrooms_level))
var/turf/destination = find_safe_turf(zlevels = backrooms_level, dense_atoms = FALSE)
if(destination)
forceMove(destination)
return TRUE

View File

@@ -445,6 +445,8 @@
var/turf/location = get_turf(src)
//add_blood doesn't work for borgs/xenos, but add_blood_floor does.
L.add_splatter_floor(location)
if(prob(1)) //no clip out of reality into the backrooms
INVOKE_ASYNC(L, TYPE_PROC_REF(/mob/living, clip_into_backrooms))
for(var/obj/mecha/M in get_turf(src))
M.take_damage(DOOR_CRUSH_DAMAGE)

View File

@@ -10,8 +10,8 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
var/list/allowed_contents = typecache_filter_list_reverse(get_all_contentsIgnoring(ignore_typecache), ignored_atoms)
allowed_contents -= src
for(var/i in 1 to allowed_contents.len)
var/thing = allowed_contents[i]
qdel(thing)
var/atom/thing = allowed_contents[i]
qdel(thing, force=TRUE)
if(turf_type)
ChangeTurf(turf_type, baseturf_type, flags)

View File

@@ -233,3 +233,15 @@ INITIALIZE_IMMEDIATE(/turf/closed/indestructible/splashscreen)
smoothing_groups = SMOOTH_GROUP_HIERO_WALL
canSmoothWith = SMOOTH_GROUP_HIERO_WALL
/turf/closed/indestructible/backrooms
name = "wall"
desc = "A huge chunk of metal used to separate rooms."
icon = 'icons/turf/walls/wall.dmi'
icon_state = "wall-0"
base_icon_state = "wall"
baseturfs = /turf/open/floor/plating/backrooms
smoothing_flags = SMOOTH_BITMASK
smoothing_groups = SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS
canSmoothWith = SMOOTH_GROUP_WALLS

View File

@@ -1147,7 +1147,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
ADMIN_PUNISHMENT_SCARIFY,
ADMIN_PUNISHMENT_SMSPIDER,
ADMIN_PUNISHMENT_FLASHBANG,
ADMIN_PUNISHMENT_WIBBLY)
ADMIN_PUNISHMENT_WIBBLY,
ADMIN_PUNISHMENT_BACKROOMS)
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
@@ -1334,6 +1335,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(ADMIN_PUNISHMENT_WIBBLY)
apply_wibbly_filters(target, 888)
to_chat(target, span_warning("Something feels very... wibbly!"))
if(ADMIN_PUNISHMENT_BACKROOMS)
INVOKE_ASYNC(target, TYPE_PROC_REF(/mob/living, clip_into_backrooms))
punish_log(target, punishment)

View File

@@ -41,14 +41,3 @@
if (z_list && z >= 1 && z <= z_list.len)
return z_list[z]
CRASH("Unmanaged z-level [z]! maxz = [world.maxz], z_list.len = [z_list ? z_list.len : "null"]")
/datum/controller/subsystem/mapping/proc/generate_backrooms()
var/datum/space_level/backrooms = add_new_zlevel("The Backrooms", ZTRAITS_BACKROOM_MAINTS, contain_turfs = FALSE)
backrooms.set_linkage(SELFLOOPING)
var/area/procedurally_generated/maintenance/the_backrooms/suffer = new()
suffer.setup("The Backrooms")
for(var/turf/to_contain as anything in Z_TURFS(backrooms.z_value))
var/area/old_area = to_contain.loc
to_contain.ChangeTurf(/turf/open/genturf, flags = CHANGETURF_DEFER_CHANGE)
to_contain.change_area(old_area, suffer)
suffer.RunGeneration()

View File

@@ -282,6 +282,10 @@
. = ..()
air_update_turf()
//Visible, indestructible fans
/obj/structure/fans/tiny/indestructible
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
//Inivisible, indestructible fans
/obj/structure/fans/tiny/invisible
name = "air flow blocker"

View File

@@ -1710,3 +1710,22 @@ GLOBAL_LIST_EMPTY(fire_appearances)
var/ERROR_ERROR_LANDMARK_ERROR = "ERROR-ERROR: ERROR landmark missing!"
log_mapping(ERROR_ERROR_LANDMARK_ERROR)
CRASH(ERROR_ERROR_LANDMARK_ERROR)
//plays a short clipping animation then send the mob into the backrooms
/mob/living/proc/clip_into_backrooms()
playsound(get_turf(src), 'yogstation/sound/effects/backrooms_clipping.ogg', 80, FALSE)
set_resting(FALSE)
Immobilize(1.9 SECONDS, TRUE, TRUE)
var/x_diff = 4
var/y_diff = 1
var/rotation = 40
if(prob(50))
rotation *= -1
animate(src, pixel_x = x_diff, pixel_y = y_diff, time = 0.5, transform = matrix(rotation + x_diff, MATRIX_ROTATE), loop = 18, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
animate(pixel_x = -x_diff , pixel_y = -y_diff, transform = matrix(rotation - x_diff, MATRIX_ROTATE), time = 0.5, flags = ANIMATION_RELATIVE)
sleep(1.8 SECONDS)
pixel_x = 0
pixel_y = 0
set_resting(FALSE)
transform = matrix()
sendToBackrooms()

View File

@@ -601,7 +601,6 @@ GLOBAL_LIST_EMPTY(vending_products)
new /obj/effect/gibspawner/human/bodypartless(get_turf(C))
C.apply_damage(max(0, squish_damage - crit_rebate))
C.AddElement(/datum/element/squish, 18 SECONDS)
else
L.visible_message("<span class='danger'>[L] is crushed by [src]!</span>", \
"<span class='userdanger'>You are crushed by [src]!</span>")
@@ -609,10 +608,13 @@ GLOBAL_LIST_EMPTY(vending_products)
if(crit_case)
L.apply_damage(squish_damage)
L.AddElement(/datum/element/squish, 18 SECONDS)
L.Paralyze(60)
L.emote("scream")
playsound(L, 'sound/effects/blobattack.ogg', 40, TRUE)
playsound(L, 'sound/effects/splat.ogg', 50, TRUE)
if(prob(1)) //send them to the backrooms
INVOKE_ASYNC(L, TYPE_PROC_REF(/mob/living, clip_into_backrooms))
var/matrix/M = matrix()
M.Turn(pick(90, 270))

View File

@@ -8,7 +8,7 @@ export BYOND_MAJOR=515
export BYOND_MINOR=1633
#rust_g git tag
export RUST_G_VERSION=1.2.0-yogs1
export RUST_G_VERSION=1.2.0-yogs2
#node version
export NODE_VERSION=14

Binary file not shown.

View File

@@ -409,6 +409,7 @@
#include "code\controllers\subsystem\assets.dm"
#include "code\controllers\subsystem\atoms.dm"
#include "code\controllers\subsystem\augury.dm"
#include "code\controllers\subsystem\backrooms.dm"
#include "code\controllers\subsystem\blackbox.dm"
#include "code\controllers\subsystem\callback.dm"
#include "code\controllers\subsystem\chat.dm"

Binary file not shown.