diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm new file mode 100644 index 0000000000..6a6581dacb --- /dev/null +++ b/code/__HELPERS/areas.dm @@ -0,0 +1,93 @@ +#define BP_MAX_ROOM_SIZE 300 + +// Gets an atmos isolated contained space +// Returns an associative list of turf|dirs pairs +// The dirs are connected turfs in the same space +// break_if_found is a typecache of turf types to return false if found +/proc/detect_room(turf/origin, list/break_if_found) + if(origin.blocks_air) + return list(origin) + + . = list() + var/list/checked_turfs = list() + var/list/found_turfs = list(origin) + while(found_turfs.len) + var/turf/sourceT = found_turfs[1] + if(break_if_found[sourceT.type]) + return FALSE + found_turfs.Cut(1, 2) + var/dir_flags = checked_turfs[sourceT] + for(var/dir in GLOB.alldirs) + if(dir_flags & dir) // This means we've checked this dir before, probably from the other turf + continue + var/turf/checkT = get_step(sourceT, dir) + if(!checkT) + continue + checked_turfs[sourceT] |= dir + checked_turfs[checkT] |= turn(dir, 180) + .[sourceT] |= dir + .[checkT] |= turn(dir, 180) + var/static/list/cardinal_cache = list("[NORTH]"=TRUE, "[EAST]"=TRUE, "[SOUTH]"=TRUE, "[WEST]"=TRUE) + if(!cardinal_cache["[dir]"] || checkT.blocks_air || !CANATMOSPASS(sourceT, checkT)) + continue + found_turfs += checkT // Since checkT is connected, add it to the list to be processed + +/proc/create_area(mob/creator) + var/static/blacklisted_turfs = typecacheof(/turf/open/space) + var/static/blacklisted_areas = typecacheof(/area/space) + var/list/turfs = detect_room(get_turf(creator), blacklisted_turfs) + if(!turfs) + to_chat(creator, "The new area must be completely airtight.") + return + if(turfs.len > BP_MAX_ROOM_SIZE) + to_chat(creator, "The room you're in is too big. It is [((turfs.len / BP_MAX_ROOM_SIZE)-1)*100]% larger than allowed.") + return + // This will fuck up shuttles that use the base area type but we need to fix those anyway + var/list/areas = list("New Area" = /area, "New Shuttle Area" = /area/shuttle/custom) + for(var/i in 1 to turfs.len) + var/area/place = get_area(turfs[i]) + if(blacklisted_areas[place.type]) + continue + areas[place.name] = place + var/area_choice = input(creator, "Choose an area to expand or make a new area.", "Area Expansion") as null|anything in areas + area_choice = areas[area_choice] + + if(!area_choice) + to_chat(creator, "No choice selected. The area remains undefined.") + return + var/area/newA + var/area/oldA = get_area(get_turf(creator)) + if(!isarea(area_choice)) + var/str = trim(stripped_input(creator,"New area name:", "Blueprint Editing", "", MAX_NAME_LEN)) + if(!str || !length(str)) //cancel + return + if(length(str) > 50) + to_chat(creator, "The given name is too long. The area remains undefined.") + return + newA = new area_choice + newA.setup(str) + newA.set_dynamic_lighting() + newA.has_gravity = oldA.has_gravity + else + newA = area_choice + + for(var/i in 1 to turfs.len) + var/turf/thing = turfs[i] + var/area/old_area = thing.loc + newA.contents += thing + thing.change_area(old_area, newA) + + var/list/related_areas = oldA.related + for(var/i in 1 to related_areas.len) + var/area/place = related_areas[i] + var/list/firedoors = place.firedoors + if(!LAZYLEN(firedoors)) + continue + for(var/k in 1 to firedoors.len) + var/obj/machinery/door/firedoor/FD = firedoors[k] + FD.CalculateAffectingAreas() + + to_chat(creator, "You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered.") + return TRUE + +#undef BP_MAX_ROOM_SIZE \ No newline at end of file diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm index dd9e1f766f..e690e6b3df 100644 --- a/code/game/area/areas/shuttles.dm +++ b/code/game/area/areas/shuttles.dm @@ -43,6 +43,9 @@ name = "Hyperspace" desc = "Weeeeee" +/area/shuttle/custom + name = "Custom player shuttle" + /area/shuttle/arrival name = "Arrival Shuttle" diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index 239f59f8b7..2bccc46740 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -3,16 +3,6 @@ #define AREA_SPACE 2 #define AREA_SPECIAL 3 -#define BORDER_ERROR 0 -#define BORDER_NONE 1 -#define BORDER_BETWEEN 2 -#define BORDER_2NDTILE 3 -#define BORDER_SPACE 4 - -#define ROOM_ERR_LOLWAT 0 -#define ROOM_ERR_SPACE 1 -#define ROOM_ERR_TOOLARGE 2 - /obj/item/areaeditor name = "area modification item" icon = 'icons/obj/items_and_weapons.dmi' @@ -22,16 +12,15 @@ /obj/item/areaeditor/attack_self(mob/user) add_fingerprint(user) - var/text = "[src] \ + . = "[src] \

[station_name()] [src.name]

\ [fluffnotice]
" switch(get_area_type()) if(AREA_SPACE) - text += "

According to the [src.name], you are now in an unclaimed territory.

\ -

Mark this place as new area.

" + . += "

According to the [src.name], you are now in an unclaimed territory.

" if(AREA_SPECIAL) - text += "

This place is not noted on the [src.name].

" - return text + . += "

This place is not noted on the [src.name].

" + . += "

Create or modify an existing area

" /obj/item/areaeditor/Topic(href, href_list) @@ -41,8 +30,7 @@ usr << browse(null, "window=blueprints") return if(href_list["create_area"]) - if(get_area_type()==AREA_SPACE) - create_area(usr) + create_area(usr) updateUsrDialog() //Station blueprints!!! @@ -69,7 +57,7 @@ var/area/A = get_area() if(get_area_type() == AREA_STATION) . += "

According to \the [src], you are now in \"[html_encode(A.name)]\".

" - . += "

You may make an amendment to the drawing.

" + . += "

Change area name

" . += "

View wire colour legend

" if(!viewing) . += "

View structural data

" @@ -186,63 +174,6 @@ return message return "" -/proc/create_area(mob/living/creator) - var/res = detect_room(get_turf(creator)) - if(!islist(res)) - switch(res) - if(ROOM_ERR_SPACE) - to_chat(creator, "The new area must be completely airtight.") - return - if(ROOM_ERR_TOOLARGE) - to_chat(creator, "The new area is too large.") - return - else - to_chat(creator, "Error! Please notify administration.") - return - - var/list/turfs = res - var/str = trim(stripped_input(creator,"New area name:", "Blueprint Editing", "", MAX_NAME_LEN)) - if(!str || !length(str)) //cancel - return - if(length(str) > 50) - to_chat(creator, "The given name is too long. The area remains undefined.") - return - var/area/old = get_area(get_turf(creator)) - var/old_gravity = old.has_gravity - - var/area/A - for(var/key in turfs) - if(key == str) - A = turfs[key] - if(turfs[key]) - turfs -= turfs[key] - turfs -= key - if(A) - A.set_dynamic_lighting() - for (var/turf/T in turfs) - var/area/old_area = T.loc - A.contents += T - T.change_area(old_area, T) - - else - A = new - A.setup(str) - A.set_dynamic_lighting() - for (var/turf/T in turfs) - var/area/old_area = T.loc - A.contents += T - T.change_area(old_area, T) - A.has_gravity = old_gravity - - for(var/area/RA in old.related) - if(RA.firedoors) - for(var/D in RA.firedoors) - var/obj/machinery/door/firedoor/FD = D - FD.CalculateAffectingAreas() - - to_chat(creator, "You have created a new area, named [str]. It is now weather proof, and constructing an APC will allow it to be powered.") - return 1 - /obj/item/areaeditor/proc/edit_area() var/area/A = get_area() var/prevname = "[A.name]" @@ -280,82 +211,6 @@ M.name = replacetext(M.name,oldtitle,title) //TODO: much much more. Unnamed airlocks, cameras, etc. - -/turf/proc/check_tile_is_border() - return BORDER_NONE - -/turf/open/space/check_tile_is_border() - return BORDER_SPACE - -/turf/closed/check_tile_is_border() - return BORDER_2NDTILE - -/turf/open/check_tile_is_border() - for(var/atom/movable/AM in src) - if(!CANATMOSPASS(AM, src)) - return BORDER_2NDTILE - - return BORDER_NONE - -/turf/closed/mineral/check_tile_is_border() - return BORDER_NONE - -/proc/detect_room(turf/first) - var/list/turf/found = new - var/list/turf/pending = list(first) - var/list/border = list() - while(pending.len) - if (found.len+pending.len > 300) - return ROOM_ERR_TOOLARGE - var/turf/T = pending[1] //why byond havent list::pop()? - pending -= T - for (var/dir in GLOB.cardinals) - var/skip = 0 - for (var/obj/structure/window/W in T) - if(dir == W.dir || (W.dir in list(NORTHEAST,SOUTHEAST,NORTHWEST,SOUTHWEST))) - skip = 1 - break - if (skip) - continue - for(var/obj/machinery/door/window/D in T) - if(dir == D.dir) - skip = 1 - break - if (skip) - continue - - var/turf/NT = get_step(T,dir) - if (!isturf(NT) || (NT in found) || (NT in pending)) - continue - - switch(NT.check_tile_is_border()) - if(BORDER_NONE) - pending+=NT - if(BORDER_BETWEEN) - var/area/A = NT.loc - if(!found[A.name]) - found[A.name] = NT.loc - if(BORDER_2NDTILE) - border[NT] += dir - if(BORDER_SPACE) - return ROOM_ERR_SPACE - found+=T - - for(var/V in border) //lazy but works - var/turf/F = V - for(var/direction in GLOB.cardinals) - if(direction == border[F]) - continue //don't want to grab turfs from outside the border - var/turf/U = get_step(F, direction) - if((U in border) || (U in found)) - continue - if(U.check_tile_is_border() == BORDER_2NDTILE) - found += U - found |= F - return found - - - //Blueprint Subtypes /obj/item/areaeditor/blueprints/cyborg diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 1111e7e09e..3edd7e810c 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -772,6 +772,11 @@ winheight = min(winheight, 690) usr << browse(dat, "window=players;size=375x[winheight]") +/datum/admins/proc/create_or_modify_area() + set category = "Debug" + set name = "Create or modify area" + create_area(usr) + // // //ALL DONE diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 01f825492f..4968b6497c 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -156,7 +156,13 @@ GLOBAL_LIST_INIT(admin_verbs_debug, world.AVerbsDebug()) /client/proc/toggle_medal_disable, /client/proc/view_runtimes, /client/proc/pump_random_event, +<<<<<<< HEAD /client/proc/cmd_display_init_log +======= + /client/proc/cmd_display_init_log, + /client/proc/cmd_display_overlay_log, + /datum/admins/proc/create_or_modify_area +>>>>>>> 28e6359... makes blueprints work on station and able to expand old areas (#32280) ) GLOBAL_PROTECT(admin_verbs_possess) GLOBAL_LIST_INIT(admin_verbs_possess, list(/proc/possess, /proc/release)) diff --git a/tgstation.dme b/tgstation.dme index 038a896bc3..d45e6da203 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -88,6 +88,7 @@ #include "code\__HELPERS\_lists.dm" #include "code\__HELPERS\_logging.dm" #include "code\__HELPERS\_string_lists.dm" +#include "code\__HELPERS\areas.dm" #include "code\__HELPERS\AStar.dm" #include "code\__HELPERS\cmp.dm" #include "code\__HELPERS\files.dm"