From 1344a49758fffc5b3a77503da18d8febd3c2d4f5 Mon Sep 17 00:00:00 2001 From: NanakoAC Date: Tue, 5 Jul 2016 21:32:04 +0100 Subject: [PATCH] Mouse Spawning Fixes (#513) Mice will no longer spawn in closed systems with nowhere to ventcrawl to. Mice can no longer spawn in breached areas and die immediately. A spawnpoint with a safe environment will always be chosen. --- code/modules/mob/dead/observer/observer.dm | 108 +++++++++++++++++++-- html/changelogs/Nanako-MouseSpawning.yml | 37 +++++++ 2 files changed, 136 insertions(+), 9 deletions(-) create mode 100644 html/changelogs/Nanako-MouseSpawning.yml diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 41ed12bcc6d..bde0c1db5c8 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -442,16 +442,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp //find a viable mouse candidate var/mob/living/simple_animal/mouse/host - var/obj/machinery/atmospherics/unary/vent_pump/vent_found - var/list/found_vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/v in machines) - if(!v.welded && v.z == T.z) - found_vents.Add(v) - if(found_vents.len) - vent_found = pick(found_vents) - host = new /mob/living/simple_animal/mouse(vent_found.loc) + var/obj/machinery/atmospherics/unary/vent_pump/spawnpoint = find_mouse_spawnpoint(T.z) + + if (spawnpoint) + host = new /mob/living/simple_animal/mouse(spawnpoint.loc) else - src << "Unable to find any unwelded vents to spawn mice at." + src << "Unable to find any safe, unwelded vents to spawn mice at. The station must be quite a mess! Trying again might work, if you think there's still a safe place. " if(host) if(config.uneducated_mice) @@ -460,6 +456,100 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp host.ckey = src.ckey host << "You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent." +/proc/find_mouse_spawnpoint(var/ZLevel) + //This function will attempt to find a good spawnpoint for mice, and prevent them from spawning in closed vent systems with no escape + //It does this by bruteforce: Picks a random vent, tests if it has enough connections, if not, repeat + //Continues either until a valid one is found (in which case we return it), or until we hit a limit on attempts.. + //If we hit the limit without finding a valid one, then the best one we found is selected + + var/list/found_vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/v in machines) + if(!v.welded && v.z == ZLevel) + found_vents.Add(v) + + if (found_vents.len == 0) + return null//Every vent on the map is welded? Sucks to be a mouse + + var/attempts = 0 + var/max_attempts = min(20, found_vents.len) + var/target_connections = 30//Any vent with at least this many connections is good enough + + var/obj/machinery/atmospherics/unary/vent_pump/bestvent = null + var/best_connections = 0 + while (attempts < max_attempts) + attempts++ + var/obj/machinery/atmospherics/unary/vent_pump/testvent = pick(found_vents) + + if (!testvent.network)//this prevents runtime errors + continue + + var/turf/T = get_turf(testvent) + + + + //We test the environment of the tile, to see if its habitable for a mouse + //----------------------------------- + var/atmos_suitable = 1 + + var/maxtemp = 390 + var/mintemp = 210 + var/min_oxy = 5 + var/max_phoron = 1 + var/max_co2 = 5 + var/min_pressure = 80 + + var/datum/gas_mixture/Environment = T.return_air() + if(Environment) + + if(Environment.temperature > maxtemp) + atmos_suitable = 0 + else if (Environment.temperature < mintemp) + atmos_suitable = 0 + else if(Environment.gas["oxygen"] < min_oxy) + atmos_suitable = 0 + else if(Environment.gas["phoron"] > max_phoron) + atmos_suitable = 0 + else if(Environment.gas["carbon_dioxide"] > max_co2) + atmos_suitable = 0 + else if(Environment.return_pressure() < min_pressure) + atmos_suitable = 0 + else + atmos_suitable = 0 + + if (!atmos_suitable) + continue + //---------------------- + + + + + //Now we test the vent connections, and ensure the vent we spawn at is connected enough to give the mouse free movement + var/list/connections = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in testvent.network.normal_members) + if(temp_vent.welded) + continue + if(temp_vent == testvent)//Our testvent shouldn't count itself as a connection + continue + + connections += temp_vent + + if(connections.len > best_connections) + best_connections = connections.len + bestvent = testvent + + if (connections.len >= target_connections) + return testvent + //If we've found one that's good enough, then we stop looking + + + //IF we get here, then we hit the limit without finding a valid one. + //This would probably only be likely to happen if the station is full of holes and pipes are broken everywhere + if (bestvent == null) + //If bestvent is null, then every vent we checked was either welded or unsafe to spawn at. The user will be given a message reflecting this. + return null + else + return bestvent + /mob/dead/observer/verb/view_manfiest() set name = "View Crew Manifest" set category = "Ghost" diff --git a/html/changelogs/Nanako-MouseSpawning.yml b/html/changelogs/Nanako-MouseSpawning.yml new file mode 100644 index 00000000000..fc4ab6e906a --- /dev/null +++ b/html/changelogs/Nanako-MouseSpawning.yml @@ -0,0 +1,37 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Nanako + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - bugfix: "Mice will no longer spawn in closed systems with nowhere to ventcrawl to" + - bugfix: "Mice can no longer spawn in breached areas and die immediately. A spawnpoint with a safe environment will always be chosen"