From 3b5990121f4ec3aa44beea3437b9eba94f68fbf8 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Tue, 13 Oct 2015 16:54:46 +0200 Subject: [PATCH] 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 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