diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 9fd3794520..66b4bd5e73 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -99,15 +99,17 @@ evolve() return for(var/obj/item/trash/garbage in range(1, src)) - if(prob(2)) - qdel(garbage) - evolve_plague() - return + if(is_station_level(z)) + if(prob(2)) + qdel(garbage) + evolve_plague() + return for(var/obj/effect/decal/cleanable/blood/gibs/leftovers in range(1, src)) - if(prob(2)) - qdel(leftovers) - evolve_plague() - return + if(is_station_level(z)) + if(prob(2)) + qdel(leftovers) + evolve_plague() + return /** *Checks the mouse cap, if it's above the cap, doesn't spawn a mouse. If below, spawns a mouse and adds it to cheeserats. @@ -202,4 +204,5 @@ GLOBAL_VAR(tom_existed) /mob/living/simple_animal/mouse/handle_environment(datum/gas_mixture/environment) . = ..() - miasma() + if(is_station_level(z)) + miasma() diff --git a/code/modules/mob/living/simple_animal/hostile/plaguerat.dm b/code/modules/mob/living/simple_animal/hostile/plaguerat.dm index 331dc1eb75..2b92894317 100644 --- a/code/modules/mob/living/simple_animal/hostile/plaguerat.dm +++ b/code/modules/mob/living/simple_animal/hostile/plaguerat.dm @@ -1,3 +1,6 @@ +#define RAT_VENT_CHANCE 1.75 +GLOBAL_LIST_EMPTY(plague_rats) + /mob/living/simple_animal/hostile/plaguerat name = "plague rat" desc = "A large decaying rat. It spreads its filth and emits a putrid odor to create more of its kind." @@ -11,8 +14,8 @@ gender = NEUTER speak_chance = 1 turns_per_move = 5 - maxHealth = 15 - health = 15 + maxHealth = 100 + health = 100 see_in_dark = 6 obj_damage = 10 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1) @@ -22,8 +25,8 @@ response_disarm_simple = "skoff at" response_harm_continuous = "slashes" response_harm_simple = "slash" - melee_damage_lower = 5 - melee_damage_upper = 7 + melee_damage_lower = 6 + melee_damage_upper = 8 attack_verb_continuous = "slashes" attack_verb_simple = "slash" attack_sound = 'sound/weapons/punch1.ogg' @@ -34,27 +37,69 @@ mob_biotypes = MOB_ORGANIC|MOB_BEAST var/datum/action/cooldown/scavenge var/last_spawn_time = 0 - ///Number assigned to rats and mice, checked when determining infighting. + var/in_vent = FALSE + var/min_next_vent = 0 + var/obj/machinery/atmospherics/components/unary/entry_vent + var/obj/machinery/atmospherics/components/unary/exit_vent /mob/living/simple_animal/hostile/plaguerat/Initialize() . = ..() - SSmobs.cheeserats += src + GLOB.plague_rats += src AddComponent(/datum/component/swarming) AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) scavenge = new /datum/action/cooldown/scavenge scavenge.Grant(src) /mob/living/simple_animal/hostile/plaguerat/Destroy() - SSmobs.cheeserats -= src + GLOB.plague_rats -= src return ..() +/mob/living/simple_animal/hostile/plaguerat/Life(seconds, times_fired) + . = ..() + //Don't try to path to one target for too long. If it takes longer than a certain amount of time, assume it can't be reached and find a new one + //Literally only here to prevent farming and that's it. + if(!client) //don't do this shit if there's a client, they're capable of ventcrawling manually + if(in_vent) + target = null + if(entry_vent && get_dist(src, entry_vent) <= 1) + var/list/vents = list() + var/datum/pipeline/entry_vent_parent = entry_vent.parents[1] + for(var/obj/machinery/atmospherics/components/unary/temp_vent in entry_vent_parent.other_atmosmch) + vents += temp_vent + if(!vents.len) + entry_vent = null + in_vent = FALSE + return + exit_vent = pick(vents) + visible_message("[src] crawls into the ventilation ducts!") + + loc = exit_vent + var/travel_time = round(get_dist(loc, exit_vent.loc) / 2) + addtimer(CALLBACK(src, .proc/exit_vents), travel_time) //come out at exit vent in 2 to 20 seconds + + + if(world.time > min_next_vent && !entry_vent && !in_vent && prob(RAT_VENT_CHANCE)) //small chance to go into a vent + for(var/obj/machinery/atmospherics/components/unary/v in view(7,src)) + if(!v.welded) + entry_vent = v + in_vent = TRUE + walk_to(src, entry_vent) + break + /mob/living/simple_animal/hostile/plaguerat/BiologicalLife(seconds, times_fired) if(!(. = ..())) return if(isopenturf(loc)) var/turf/open/T = src.loc + var/datum/gas_mixture/stank = new + var/miasma_moles = T.air.get_moles(GAS_MIASMA) + stank.set_moles(GAS_MIASMA,5) + stank.set_temperature(BODYTEMP_NORMAL) if(T.air) - T.atmos_spawn_air("miasma=5;TEMP=293.15") + if(miasma_moles < 200) + T.assume_air(stank) + T.air_update_turf() + if(prob(40)) scavenge.Trigger() if(prob(50)) @@ -66,9 +111,10 @@ playsound(src, 'sound/effects/sparks2.ogg', 100, TRUE) C.deconstruct() for(var/obj/O in range(1,src)) - if(istype(O, /obj/item/trash) || istype(O, /obj/effect/decal/cleanable/blood/gibs)) + if((world.time - last_spawn_time) > 10 SECONDS && istype(O, /obj/item/trash) || istype(O, /obj/effect/decal/cleanable/blood/gibs)) qdel(O) be_fruitful() + last_spawn_time = world.time /mob/living/simple_animal/hostile/plaguerat/CanAttack(atom/the_target) if(istype(the_target,/mob/living/simple_animal)) @@ -86,14 +132,29 @@ */ /mob/living/simple_animal/hostile/plaguerat/proc/be_fruitful() - var/cap = CONFIG_GET(number/ratcap) - if(LAZYLEN(SSmobs.cheeserats) >= cap) + var/cap = 10 + if(LAZYLEN(GLOB.plague_rats) >= cap) visible_message("[src] gnaws into its food, [cap] rats are now on the station!") return var/mob/living/newmouse = new /mob/living/simple_animal/hostile/plaguerat(loc) - SSmobs.cheeserats += newmouse visible_message("[src] gnaws into its food, attracting another rat!") +/mob/living/simple_animal/hostile/plaguerat/proc/exit_vents() + if(!exit_vent || exit_vent.welded) + loc = entry_vent + entry_vent = null + return + loc = exit_vent.loc + entry_vent = null + exit_vent = null + in_vent = FALSE + var/area/new_area = get_area(loc) + message_admins("[src] came out at [new_area][ADMIN_JMP(loc)]!") + if(new_area) + new_area.Entered(src) + visible_message("[src] climbs out of the ventilation ducts!") + min_next_vent = world.time + 900 //90 seconds between ventcrawls + /** *Creates a chance to spawn more trash or gibs to repopulate. Otherwise, spawns a corpse or dirt. */ @@ -116,16 +177,12 @@ if(1 to 3) var/pickedtrash = pick(GLOB.ratking_trash) to_chat(owner, "Excellent, you find more trash to spread your filth!") - new /obj/effect/decal/cleanable/dirt(T) new pickedtrash(T) if(4 to 6) to_chat(owner, "You find blood and gibs to feed your young!") new /obj/effect/decal/cleanable/blood/gibs(T) - new /obj/effect/decal/cleanable/blood/(T) - if(7 to 18) - to_chat(owner, "A corpse rises from the ground. Best to leave it alone.") - new /obj/effect/mob_spawn/human/corpse/assistant(T) - if(19 to 100) + if(!locate(/obj/effect/decal/cleanable/blood) in T) + new /obj/effect/decal/cleanable/blood/(T) + if(7 to 100) to_chat(owner, "Drat. Nothing.") - new /obj/effect/decal/cleanable/dirt(T) StartCooldown()