From 3b5990121f4ec3aa44beea3437b9eba94f68fbf8 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Tue, 13 Oct 2015 16:54:46 +0200 Subject: [PATCH 1/2] Blobs locations are now more random. Blobs now randomly pick a random turf without obstructions in maintenance, instead of from a pre-determined list of locations. Blobs also now log their spawn location, which admins can use to jump to it. Space vines and nuclear discs have been updated to use the same mechanics. --- baystation12.dme | 2 ++ code/_helpers/areas.dm | 21 +++++++++++++++++ code/_helpers/functional.dm | 14 +++++++++++ code/_helpers/turfs.dm | 9 ++++++++ code/_helpers/unsorted.dm | 23 ++++--------------- code/game/area/Space Station 13 areas.dm | 8 +++---- code/game/machinery/nuclear_bomb.dm | 12 ++++++---- code/game/objects/effects/landmarks.dm | 4 ---- code/global.dm | 1 - code/modules/admin/admin_attack_log.dm | 5 +++- code/modules/events/blob.dm | 6 +++-- .../hydroponics/spreading/spreading.dm | 15 ++++-------- 12 files changed, 74 insertions(+), 46 deletions(-) create mode 100644 code/_helpers/areas.dm create mode 100644 code/_helpers/functional.dm diff --git a/baystation12.dme b/baystation12.dme index 14b6b5dae8f..e0cbae09942 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 00000000000..b5987c0ce16 --- /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 00000000000..c5ecfb631a6 --- /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 85836281143..ca5c60be9d9 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 fb79b29cb90..61193e27548 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 7cd0a708d88..87e54a9adaf 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 d02d3522a4a..76710309ee2 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 9dfe1c3b196..ed518a6f53d 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 a4605187260..ea2be0b0447 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 967a4375da7..918739ec8ff 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 bc1888f14df..7ca66a8260a 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 e8f2cfa9189..d7f5aef71a3 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 From 58dfe817f1bfe5e29ac01fa13fe8d0a864518358 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Tue, 13 Oct 2015 18:50:02 +0200 Subject: [PATCH 2/2] Changelog entry. --- html/changelogs/PsiOmegaDelta-RandomBlob.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/PsiOmegaDelta-RandomBlob.yml diff --git a/html/changelogs/PsiOmegaDelta-RandomBlob.yml b/html/changelogs/PsiOmegaDelta-RandomBlob.yml new file mode 100644 index 00000000000..00b1b632476 --- /dev/null +++ b/html/changelogs/PsiOmegaDelta-RandomBlob.yml @@ -0,0 +1,5 @@ +author: PsiOmegaDelta +delete-after: True +changes: + - tweak: "Blobs can now spawn anywhere in maintenance, rather than picking location from a pre-determined list." + \ No newline at end of file