diff --git a/_maps/RandomRooms/10x10/sk_rdm176_spacewindowroom.dmm b/_maps/RandomRooms/10x10/sk_rdm176_spacewindowroom.dmm new file mode 100644 index 0000000000000..3ab666b30ba50 --- /dev/null +++ b/_maps/RandomRooms/10x10/sk_rdm176_spacewindowroom.dmm @@ -0,0 +1,143 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"b" = ( +/obj/effect/mapping_helpers/space_window_placer, +/turf/open/space/basic, +/area/template_noop) +"k" = ( +/obj/machinery/light/floor, +/turf/open/floor/iron, +/area/template_noop) +"t" = ( +/turf/open/floor/iron, +/area/template_noop) +"G" = ( +/obj/effect/mapping_helpers/space_window_placer, +/obj/effect/spawner/lootdrop/maintenance/four, +/turf/open/space/basic, +/area/template_noop) +"Y" = ( +/obj/effect/mapping_helpers/space_window_placer, +/obj/effect/spawner/lootdrop/maintenance/two, +/turf/open/space/basic, +/area/template_noop) + +(1,1,1) = {" +b +b +b +b +b +b +b +b +b +b +"} +(2,1,1) = {" +b +k +t +t +t +t +t +t +k +b +"} +(3,1,1) = {" +b +t +G +b +t +t +b +G +t +b +"} +(4,1,1) = {" +b +t +b +k +t +t +k +b +t +b +"} +(5,1,1) = {" +b +t +t +t +Y +Y +t +t +t +b +"} +(6,1,1) = {" +b +t +t +t +b +Y +t +t +t +b +"} +(7,1,1) = {" +b +t +b +k +t +t +k +b +t +b +"} +(8,1,1) = {" +b +t +G +b +t +t +b +G +t +b +"} +(9,1,1) = {" +b +k +t +t +t +t +t +t +k +b +"} +(10,1,1) = {" +b +b +b +b +b +b +b +b +b +b +"} diff --git a/code/game/objects/effects/spawners/roomspawner.dm b/code/game/objects/effects/spawners/roomspawner.dm index 01f3e47265ad3..2444e6cf3aca1 100644 --- a/code/game/objects/effects/spawners/roomspawner.dm +++ b/code/game/objects/effects/spawners/roomspawner.dm @@ -42,13 +42,61 @@ room_width = 10 room_height = 5 icon_state = "random_room_alternative" - rooms = list("sk_rdm011_barbershop","sk_rdm031_deltarobotics","sk_rdm039_deltaclutter1","sk_rdm040_deltabotnis","sk_rdm045_deltacafeteria","sk_rdm046_deltaarcade","sk_rdm082_maintmedical","sk_rdm091_skidrow","sk_rdm100_meetingroom","sk_rdm105_phage","sk_rdm125_courtroom","sk_rdm126_gaschamber","sk_rdm127_oldaichamber","sk_rdm128_radiationtherapy","sk_rdm150_smallmedlobby","sk_rdm151_ratburger","sk_rdm152_geneticsoffice","sk_rdm153_hobowithpeter","sk_rdm154_butchersden","sk_rdm155_punjiconveyor","sk_rdm156_oldairlock_interchange","sk_rdm161_kilovault") + rooms = list( + "sk_rdm011_barbershop", + "sk_rdm031_deltarobotics", + "sk_rdm039_deltaclutter1", + "sk_rdm040_deltabotnis", + "sk_rdm045_deltacafeteria", + "sk_rdm046_deltaarcade", + "sk_rdm082_maintmedical", + "sk_rdm091_skidrow", + "sk_rdm100_meetingroom", + "sk_rdm105_phage", + "sk_rdm125_courtroom", + "sk_rdm126_gaschamber", + "sk_rdm127_oldaichamber", + "sk_rdm128_radiationtherapy", + "sk_rdm150_smallmedlobby", + "sk_rdm151_ratburger", + "sk_rdm152_geneticsoffice", + "sk_rdm153_hobowithpeter", + "sk_rdm154_butchersden", + "sk_rdm155_punjiconveyor", + "sk_rdm156_oldairlock_interchange", + "sk_rdm161_kilovault") /obj/effect/spawner/room/special/tenxten_terrestrial name = "10x10 terrestrial room" room_width = 10 room_height = 10 icon_state = "random_room_alternative" - rooms = list("sk_rdm033_deltalibrary","sk_rdm060_snakefighter","sk_rdm062_roosterdome","sk_rdm070_pubbybar","sk_rdm083_bigtheatre","sk_rdm098_graffitiroom","sk_rdm102_podrepairbay","sk_rdm106_sanitarium","sk_rdm129_beach","sk_rdm130_benoegg","sk_rdm131_confinementroom","sk_rdm132_conveyorroom","sk_rdm133_oldoffice","sk_rdm134_snowforest","sk_rdm141_6sectorsdown","sk_rdm142_olddiner","sk_rdm143_gamercave","sk_rdm144_smallmagician","sk_rdm145_ladytesla_altar","sk_rdm146_blastdoor_interchange","sk_rdm147_advbotany","sk_rdm148_botany_apiary","sk_rdm157_chess","sk_rdm159_kilosnakepit","sk_rdm167_library_ritual") + rooms = list( + "sk_rdm033_deltalibrary", + "sk_rdm060_snakefighter", + "sk_rdm062_roosterdome", + "sk_rdm070_pubbybar", + "sk_rdm083_bigtheatre", + "sk_rdm098_graffitiroom", + "sk_rdm102_podrepairbay", + "sk_rdm106_sanitarium", + "sk_rdm129_beach", + "sk_rdm130_benoegg", + "sk_rdm131_confinementroom", + "sk_rdm132_conveyorroom", + "sk_rdm133_oldoffice", + "sk_rdm134_snowforest", + "sk_rdm141_6sectorsdown", + "sk_rdm142_olddiner", + "sk_rdm143_gamercave", + "sk_rdm144_smallmagician", + "sk_rdm145_ladytesla_altar", + "sk_rdm146_blastdoor_interchange", + "sk_rdm147_advbotany", + "sk_rdm148_botany_apiary", + "sk_rdm157_chess", + "sk_rdm159_kilosnakepit", + "sk_rdm167_library_ritual", + "sk_rdm176_spacewindowroom") /obj/effect/spawner/room/fivexfour name = "5x4 room spawner" room_width = 5 diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm index c8b48f2ac056f..bffe486e34f8c 100644 --- a/code/modules/mapping/mapping_helpers.dm +++ b/code/modules/mapping/mapping_helpers.dm @@ -394,3 +394,176 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava) qdel(src) return CRASH("Failed to find a portable atmospherics or a portables connector at [AREACOORD(src)]") + +// This will put directional windows to adjucant turfs if airs will likely be vaccuumed. +// Putting this on a space turf is recommended. If you put this on an open tile, it will place directional windows anyway. +// If a turf is not valid to put a tile, it will automatically make a turf for failsafe. +// NOTE: This helper is specialised for space-proof, not just for standard mapping. +/obj/effect/mapping_helpers/space_window_placer + name = "Placer: Spaceproof directional windows" + icon_state = "space_directional_window_placer" + late = TRUE + + /** Mapper options **/ + /// Determines which window type it will create + var/window_type = /obj/structure/window/reinforced + + /** internal code variables - not for mappers **/ + /// used to skip a direction on a turf + var/skip_direction + /// there are a few stuff that "CanAtmosPass()" is not reliable + var/static/list/unliable_atmos_blockers + + +/obj/effect/mapping_helpers/space_window_placer/Initialize(mapload) + . = ..() + if(!unliable_atmos_blockers) + unliable_atmos_blockers = typecacheof(list(/obj/machinery/door)) + +/obj/effect/mapping_helpers/space_window_placer/LateInitialize() + . = ..() + if(!z || !x || !y) + CRASH("It's not unable to place Spaceproof directional windoe placer - xyz is null.") + + var/turf/my_turf = get_turf(src) + if(!my_turf) + CRASH("Spaceproof directional windoe placer failed to find a turf.") + + // checks if turfs are fine to place a directional window + var/unliable_atmos_blocking + for(var/turf/each_turf in get_adjacent_open_turfs(my_turf)) + if(isspaceturf(each_turf) || isopenspace(each_turf)) + continue + + if(!each_turf.CanAtmosPass(my_turf)) + for(var/atom/movable/movable_content as anything in each_turf.contents) + if(is_type_in_typecache(movable_content, unliable_atmos_blockers)) + unliable_atmos_blocking = TRUE + break + if(unliable_atmos_blocking) + break + + var/list/nearby_turfs = list() + for(var/turf/each_turf in get_adjacent_open_turfs(my_turf)) + if(unliable_atmos_blocking) + var/obj/effect/mapping_helpers/space_window_placer/nearby_placer = locate() in each_turf + if(nearby_placer) // we don't place windows there + give a value to skip directon + nearby_placer.skip_direction |= get_dir(each_turf, my_turf) + continue + if(skip_direction & get_dir(my_turf, each_turf)) + continue + nearby_turfs += each_turf + + + // well, it's a bad idea to put a directional window here. Mapping failsafe process here. + if(unliable_atmos_blocking && (isspaceturf(my_turf) || isopenspace(my_turf))) + my_turf.PlaceOnTop(list(/turf/open/floor/plating, /turf/open/floor/iron), flags = CHANGETURF_INHERIT_AIR) + for(var/turf/each_turf in nearby_turfs) + if(isspaceturf(each_turf) || isopenspace(each_turf)) + var/obj/d_glass = new window_type(my_turf) + d_glass.dir = get_dir(my_turf, each_turf) + else + var/improper_dir = get_dir(each_turf, my_turf) + for(var/obj/structure/window/d_glass in each_turf.contents) + if(d_glass.dir == improper_dir) + qdel(d_glass) + qdel(src) + return + + // puts a directional window for each direction. + for(var/turf/each_turf in nearby_turfs) + if(!each_turf.CanAtmosPass(my_turf) || isspaceturf(each_turf) || isopenspace(each_turf)) + continue + + var/obj/d_glass = new window_type(each_turf) + d_glass.dir = get_dir(d_glass, my_turf) + + qdel(src) + +/obj/effect/mapping_helpers/group_window_placer + name = "Placer: Grouped directional windows" + icon_state = "group_directional_window_placer" + late = TRUE + + /** Mapper options **/ + /// Determines which window type it will create. + /// Make a subtype of this mapping helper to change this value instead of manual change in DMM. + var/window_type = /obj/structure/window/reinforced + /// Directional window will not be placed to a direction from the adjacent turf where a fulltile glass exists. + /// If you set this TRUE, the windows will be placed. + var/place_onto_fulltile_window + /// Set TRUE to ignore group chain initialization + var/single + + /** internal code variables - not for mappers **/ + /// failsafe var to prevent it to run a code + var/to_be_initialized + /// a list of mappers that will be initialized together. + var/list/init_group + +/obj/effect/mapping_helpers/group_window_placer/LateInitialize() + . = ..() + if(to_be_initialized) + return + + if(!z || !x || !y) + CRASH("It's not unable to use group_window_placer - xyz is null.") + + var/turf/my_turf = get_turf(src) + if(!my_turf) + CRASH("group_window_placer failed to find a turf.") + + if(single) + to_be_initialized = TRUE + finish_late_init(list(WEAKREF(src))) + return + + init_group = list() + build_group(init_group) + finish_late_init() + +/obj/effect/mapping_helpers/group_window_placer/proc/build_group(list/chain_init_group) + if(to_be_initialized) // shouldn't reach here but just in case + return + to_be_initialized = TRUE + chain_init_group[WEAKREF(src)] = TRUE + for(var/turf/each_turf in get_adjacent_open_turfs(get_turf(src))) + var/obj/effect/mapping_helpers/group_window_placer/placer = locate() in each_turf + if(!placer || chain_init_group[WEAKREF(placer)] || placer.to_be_initialized) + continue + placer.build_group(chain_init_group) + +/obj/effect/mapping_helpers/group_window_placer/proc/finish_late_init() + for(var/datum/weakref/each_ref in init_group) + var/obj/effect/mapping_helpers/group_window_placer/each_placer = each_ref.resolve() + var/turf/my_turf = get_turf(each_placer) + var/list/nearby_turfs = list() + for(var/turf/each_turf in get_adjacent_open_turfs(my_turf)) + if(each_turf.density) + continue + if(locate(/obj/effect/mapping_helpers/group_window_placer) in each_turf) + continue + // skip this - that direction should be connected + if(locate(/obj/effect/mapping_helpers/space_window_placer) in each_turf) + continue + // skip this - you won't want to have two directional window in the same directional spot. + // NOTE: this is "SPACE" window placer, not "GROUP" + if(place_onto_fulltile_window) + var/is_fulltile + for(var/obj/structure/window/window_on_turf in my_turf.contents) + if(window_on_turf.fulltile) + is_fulltile = TRUE + break + if(is_fulltile) + continue + nearby_turfs += each_turf + + for(var/turf/each_turf in nearby_turfs) + var/obj/d_glass = new each_placer.window_type(my_turf) + d_glass.dir = get_dir(my_turf, each_turf) + + for(var/datum/weakref/each_ref in init_group) + var/obj/effect/mapping_helpers/group_window_placer/each_placer = each_ref.resolve() + qdel(each_placer) + init_group.Cut() + diff --git a/code/modules/mapping/random_rooms.dm b/code/modules/mapping/random_rooms.dm index 1e884ffbf0f9c..fc0559e960894 100644 --- a/code/modules/mapping/random_rooms.dm +++ b/code/modules/mapping/random_rooms.dm @@ -1509,6 +1509,15 @@ template_width = 5 weight = 2 +/datum/map_template/random_room/sk_rdm176 + name = "Room with spaceproof windows" + room_id = "sk_rdm176_spacewindowroom" + mappath = "_maps/RandomRooms/10x10/sk_rdm176_spacewindowroom.dmm" + centerspawner = FALSE + template_height = 10 + template_width = 10 + weight = 1 + //Flandstation Dedicated Random Room /datum/map_template/random_room/sk_rdm_fln_01 diff --git a/icons/effects/mapping_helpers.dmi b/icons/effects/mapping_helpers.dmi index 08d666a0a614e..ddaf12b1677f3 100644 Binary files a/icons/effects/mapping_helpers.dmi and b/icons/effects/mapping_helpers.dmi differ