diff --git a/baystation12.dme b/baystation12.dme index 14b6b5dae8..e0cbae0994 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -32,9 +32,11 @@ #include "code\__defines\research.dm" #include "code\__defines\species_languages.dm" #include "code\__defines\turfs.dm" +#include "code\_helpers\areas.dm" #include "code\_helpers\atmospherics.dm" #include "code\_helpers\datum_pool.dm" #include "code\_helpers\files.dm" +#include "code\_helpers\functional.dm" #include "code\_helpers\game.dm" #include "code\_helpers\global_lists.dm" #include "code\_helpers\icons.dm" diff --git a/code/_helpers/areas.dm b/code/_helpers/areas.dm new file mode 100644 index 0000000000..b5987c0ce1 --- /dev/null +++ b/code/_helpers/areas.dm @@ -0,0 +1,21 @@ +//Takes: Area type as text string or as typepath OR an instance of the area. +//Returns: A list of all turfs in areas of that type in the world. +/proc/get_area_turfs(var/areatype, var/list/predicates) + if(!areatype) return null + if(istext(areatype)) areatype = text2path(areatype) + if(isarea(areatype)) + var/area/areatemp = areatype + areatype = areatemp.type + + var/list/turfs = new/list() + for(var/areapath in typesof(areatype)) + var/area/A = locate(areapath) + for(var/turf/T in A.contents) + if(!predicates || all_predicates_true(T, predicates)) + turfs += T + return turfs + +/proc/pick_area_turf(var/areatype, var/list/predicates) + var/list/turfs = get_area_turfs(areatype, predicates) + if(turfs && turfs.len) + return pick(turfs) diff --git a/code/_helpers/functional.dm b/code/_helpers/functional.dm new file mode 100644 index 0000000000..c5ecfb631a --- /dev/null +++ b/code/_helpers/functional.dm @@ -0,0 +1,14 @@ +/proc/all_predicates_true(var/input, var/list/predicates) + for(var/i = 1 to predicates.len) + if(!call(predicates[i])(input)) + return FALSE + return TRUE + +/proc/any_predicate_true(var/input, var/list/predicates) + if(!predicates.len) + return TRUE + + for(var/i = 1 to predicates.len) + if(call(predicates[i])(input)) + return TRUE + return FALSE diff --git a/code/_helpers/turfs.dm b/code/_helpers/turfs.dm index 8583628114..ca5c60be9d 100644 --- a/code/_helpers/turfs.dm +++ b/code/_helpers/turfs.dm @@ -32,3 +32,12 @@ if(!available_turfs.len) available_turfs = start_turfs return pick(available_turfs) + +/proc/turf_contains_dense_objects(var/turf/T) + return T.contains_dense_objects() + +/proc/not_turf_contains_dense_objects(var/turf/T) + return !turf_contains_dense_objects(T) + +/proc/is_station_turf(var/turf/T) + return T && isStationLevel(T.z) diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index fb79b29cb9..61193e2754 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -229,14 +229,14 @@ Turf and target are seperate in case you want to teleport some distance from a t #define LOCATE_COORDS(X, Y, Z) locate(between(1, X, world.maxx), between(1, Y, world.maxy), Z) /proc/getcircle(turf/center, var/radius) //Uses a fast Bresenham rasterization algorithm to return the turfs in a thin circle. if(!radius) return list(center) - + var/x = 0 var/y = radius var/p = 3 - 2 * radius - + . = list() while(y >= x) // only formulate 1/8 of circle - + . += LOCATE_COORDS(center.x - x, center.y - y, center.z) //upper left left . += LOCATE_COORDS(center.x - y, center.y - x, center.z) //upper upper left . += LOCATE_COORDS(center.x + y, center.y - x, center.z) //upper upper right @@ -247,7 +247,7 @@ Turf and target are seperate in case you want to teleport some distance from a t . += LOCATE_COORDS(center.x + x, center.y + y, center.z) //lower right right if(p < 0) - p += 4*x++ + 6; + p += 4*x++ + 6; else p += 4*(x++ - y--) + 10; @@ -718,21 +718,6 @@ proc/GaussRandRound(var/sigma,var/roundto) if(istype(N, areatype)) areas += N return areas -//Takes: Area type as text string or as typepath OR an instance of the area. -//Returns: A list of all turfs in areas of that type of that type in the world. -/proc/get_area_turfs(var/areatype) - if(!areatype) return null - if(istext(areatype)) areatype = text2path(areatype) - if(isarea(areatype)) - var/area/areatemp = areatype - areatype = areatemp.type - - var/list/turfs = new/list() - for(var/area/N in world) - if(istype(N, areatype)) - for(var/turf/T in N) turfs += T - return turfs - //Takes: Area type as text string or as typepath OR an instance of the area. //Returns: A list of all atoms (objs, turfs, mobs) in areas of that type of that type in the world. /proc/get_area_all_atoms(var/areatype) diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 7cd0a708d8..87e54a9ada 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -61,8 +61,8 @@ var/list/teleportlocs = list() for(var/area/AR in world) if(istype(AR, /area/shuttle) || istype(AR, /area/syndicate_station) || istype(AR, /area/wizard_station)) continue if(teleportlocs.Find(AR.name)) continue - var/turf/picked = pick(get_area_turfs(AR.type)) - if (picked.z in config.station_levels) + var/turf/picked = pick_area_turf(AR.type, list(/proc/is_station_turf)) + if (picked) teleportlocs += AR.name teleportlocs[AR.name] = AR @@ -78,8 +78,8 @@ var/list/ghostteleportlocs = list() if(istype(AR, /area/turret_protected/aisat) || istype(AR, /area/derelict) || istype(AR, /area/tdome) || istype(AR, /area/shuttle/specops/centcom)) ghostteleportlocs += AR.name ghostteleportlocs[AR.name] = AR - var/turf/picked = pick(get_area_turfs(AR.type)) - if (picked.z in config.player_levels) + var/turf/picked = pick_area_turf(AR.type, list(/proc/is_station_turf)) + if (picked) ghostteleportlocs += AR.name ghostteleportlocs[AR.name] = AR diff --git a/code/game/machinery/nuclear_bomb.dm b/code/game/machinery/nuclear_bomb.dm index d02d3522a4..76710309ee 100644 --- a/code/game/machinery/nuclear_bomb.dm +++ b/code/game/machinery/nuclear_bomb.dm @@ -418,10 +418,14 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob) nuke_disks |= src /obj/item/weapon/disk/nuclear/Destroy() - if(!nuke_disks.len && blobstart.len > 0) - var/obj/D = new /obj/item/weapon/disk/nuclear(pick(blobstart)) - message_admins("[src], the last authentication disk, has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") - log_game("[src], the last authentication disk, has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") + nuke_disks -= src + if(!nuke_disks.len) + var/turf/T = pick_area_turf(/area/maintenance, /proc/not_turf_contains_dense_objects) + if(T) + var/obj/D = new /obj/item/weapon/disk/nuclear(T) + log_and_message_admins_with_location("[src], the last authentication disk, has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).", T.x, T.y, T.z) + else + log_and_message_admins("[src], the last authentication disk, has been destroyed. Failed to respawn disc!") ..() /obj/item/weapon/disk/nuclear/touch_map_edge() diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 9dfe1c3b19..ed518a6f53 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -52,10 +52,6 @@ prisonsecuritywarp += loc qdel(src) return - if("blobstart") - blobstart += loc - qdel(src) - return if("xeno_spawn") xeno_spawn += loc qdel(src) diff --git a/code/global.dm b/code/global.dm index a460518726..ea2be0b044 100644 --- a/code/global.dm +++ b/code/global.dm @@ -71,7 +71,6 @@ var/list/tdomeobserve = list() var/list/tdomeadmin = list() var/list/prisonsecuritywarp = list() // Prison security goes to these. var/list/prisonwarped = list() // List of players already warped. -var/list/blobstart = list() var/list/ninjastart = list() var/list/cardinal = list(NORTH, SOUTH, EAST, WEST) diff --git a/code/modules/admin/admin_attack_log.dm b/code/modules/admin/admin_attack_log.dm index 967a4375da..918739ec8f 100644 --- a/code/modules/admin/admin_attack_log.dm +++ b/code/modules/admin/admin_attack_log.dm @@ -1,6 +1,9 @@ /mob/var/lastattacker = null /mob/var/lastattacked = null -/mob/var/attack_log = list( ) +/mob/var/attack_log = list() + +proc/log_and_message_admins_with_location(var/message, var/x, var/y, var/z, var/mob/user = usr) + log_and_message_admins("[message] (JMP)", user) proc/log_and_message_admins(var/message as text, var/mob/user = usr) log_admin(user ? "[key_name(user)] [message]" : "EVENT [message]") diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index bc1888f14d..7ca66a8260 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -1,6 +1,5 @@ /datum/event/blob announceWhen = 12 - endWhen = 120 var/obj/effect/blob/core/Blob @@ -8,10 +7,13 @@ level_seven_announcement() /datum/event/blob/start() - var/turf/T = pick(blobstart) + var/turf/T = pick_area_turf(/area/maintenance, list(/proc/is_station_turf, /proc/not_turf_contains_dense_objects)) if(!T) + log_and_message_admins("Blob failed to find a viable turf.") kill() return + + log_and_message_admins_with_location("Event: Blob spawned at \the [get_area(T)] ([T.x],[T.y],[T.z])", T.x, T.y, T.z) Blob = new /obj/effect/blob/core(T) for(var/i = 1; i < rand(3, 4), i++) Blob.process() diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index e8f2cfa918..d7f5aef71a 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -3,15 +3,8 @@ /proc/spacevine_infestation(var/potency_min=70, var/potency_max=100, var/maturation_min=5, var/maturation_max=15) spawn() //to stop the secrets panel hanging - var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas - for(var/areapath in typesof(/area/hallway)) - var/area/A = locate(areapath) - for(var/turf/simulated/floor/F in A.contents) - if(turf_clear(F)) - turfs += F - - if(turfs.len) //Pick a turf to spawn at if we can - var/turf/simulated/floor/T = pick(turfs) + var/turf/T = pick_area_turf(/area/hallway, list(/proc/is_station_turf, /proc/not_turf_contains_dense_objects)) + if(T) var/datum/seed/seed = plant_controller.create_random_seed(1) seed.set_trait(TRAIT_SPREAD,2) // So it will function properly as vines. seed.set_trait(TRAIT_POTENCY,rand(potency_min, potency_max)) // 70-100 potency will help guarantee a wide spread and powerful effects. @@ -23,9 +16,9 @@ vine.mature_time = 0 vine.process() - message_admins("Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])") + log_and_message_admins_with_location("Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])", T.x, T.y, T.z) return - message_admins("Event: Spacevines failed to find a viable turf.") + log_and_message_admins("Event: Spacevines failed to find a viable turf.") /obj/effect/dead_plant anchored = 1