diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index 376d31cab6cd7..73b9a2c418b4a 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -36,6 +36,7 @@ GLOBAL_LIST_EMPTY(pai_list)
GLOBAL_LIST_EMPTY(available_ai_shells)
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list(),list())) // One for each AI_* status define
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
+GLOBAL_LIST_EMPTY(all_mimites) //all mimites and their subtypes
GLOBAL_LIST_EMPTY(bots_list)
GLOBAL_LIST_EMPTY(ai_eyes)
GLOBAL_LIST_EMPTY(suit_sensors_list) //all people with suit sensors on
diff --git a/code/modules/events/mimite_infestation.dm b/code/modules/events/mimite_infestation.dm
index da20c300f0bb8..59c02b9e1b3df 100644
--- a/code/modules/events/mimite_infestation.dm
+++ b/code/modules/events/mimite_infestation.dm
@@ -6,13 +6,14 @@
/datum/round_event/mimite_infestation
- announceWhen = 400
+ announceWhen = 200
// 50% chance of being incremented by one
- var/spawncount = 2
+ var/spawncount = 3
fakeable = TRUE
/datum/round_event/mimite_infestation/setup()
announceWhen = rand(announceWhen, announceWhen + 50)
+ endWhen = 3600 //60 min
if(prob(50))
spawncount++
@@ -21,7 +22,6 @@
for(var/mob/living/simple_animal/hostile/mimite/A)
if(A.stat != DEAD)
living_mimites = TRUE
-
if(living_mimites || fake)
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS)
@@ -43,7 +43,23 @@
while(spawncount > 0 && vents.len)
var/obj/vent = pick_n_take(vents)
var/mob/living/simple_animal/hostile/mimite/new_mimite = new(vent.loc)
+ switch(length(GLOB.player_list))
+ if(0 to 20)
+ new_mimite.remaining_replications = 3
+ if(20 to 40)
+ new_mimite.remaining_replications = 4
+ else
+ new_mimite.remaining_replications = 5
spawncount--
+ announce_to_ghosts(new_mimite)
message_admins("[ADMIN_LOOKUPFLW(new_mimite)] has been spawned by an event.")
log_game("mimites where spawned by an event.")
return SUCCESSFUL_SPAWN
+
+
+/datum/round_event/mimite_infestation/end()
+ if(LAZYLEN(GLOB.all_mimites) >= 1) //If they're still around at the end of 60 min, turn of replication permanently
+ for(var/mob/living/simple_animal/hostile/mimite/M in GLOB.all_mimites)
+ M.eventongoing = FALSE
+ else
+ priority_announce("Sensors are no-longer detecting an outbreak of Mimites, well done crew!", "Lifesign Alert", SSstation.announcer.get_rand_alert_sound())
diff --git a/code/modules/mob/living/simple_animal/hostile/mimite.dm b/code/modules/mob/living/simple_animal/hostile/mimite.dm
index 3e4e314126ef4..bd7599902d93e 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimite.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimite.dm
@@ -1,4 +1,5 @@
-#define MIMITE_COOLDOWN 80
+#define MIMITE_COOLDOWN 60
+#define MIMITE_VENT_COOLDOWN 100
/mob/living/simple_animal/hostile/mimite
name = "Mimite"
@@ -14,13 +15,12 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
deathmessage = "splatters into a pile of black gunk!"
del_on_death = TRUE
-
response_help = "touches"
response_disarm = "pushes"
response_harm = "hits"
speed = 3
- maxHealth = 75
- health = 75
+ maxHealth = 50
+ health = 50
gender = NEUTER
mob_biotypes = list(MOB_INORGANIC)
wander = FALSE
@@ -66,19 +66,26 @@
var/travelling_in_vent = 0
var/replicate = TRUE
var/venthunt = TRUE
+ var/mimite_lastmove = null //Updates/Stores position of the mimite while it's moving
+ var/mimite_stuck = 0 //If mimite_lastmove hasn't changed, this will increment until it reaches mimite_stuck_threshold
+ var/mimite_stuck_threshold = 10 //if this == mimite_stuck, it'll force the mimite to stop moving
+ var/attemptingventcrawl = FALSE
+ var/eventongoing = TRUE
+ var/remaining_replications = 4
/mob/living/simple_animal/hostile/mimite/Initialize()
. = ..()
AddElement(/datum/element/point_of_interest)
+ GLOB.all_mimites += src
var/image/I = image(icon = 'icons/mob/hud.dmi', icon_state = "hudcultist", layer = DATA_HUD_PLANE, loc = src)
I.alpha = 200
I.appearance_flags = RESET_ALPHA
add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/mimites, "hudcultist", I)
/mob/living/simple_animal/hostile/mimite/examine(mob/user)
- if(morphed)
+ if(morphed && replicate && venthunt)
. = form.examine(user)
- if(get_dist(user,src)<=2)
+ if(get_dist(user,src)<=4)
. += "It doesn't look quite right..."
else
. = ..()
@@ -179,6 +186,8 @@
if(LAZYLEN(things) >= 1)
var/atom/movable/T = pick(things)
assume(T)
+ else
+ approachvent()
/mob/living/simple_animal/hostile/mimite/can_track(mob/living/user)
if(morphed)
@@ -194,7 +203,7 @@
/mob/living/simple_animal/hostile/mimite/attack_hand(mob/living/carbon/human/M)
if(morphed)
M.Knockdown(40)
- M.reagents.add_reagent(/datum/reagent/toxin/morphvenom/mimite, 10)
+ M.reagents.add_reagent(/datum/reagent/toxin/morphvenom/mimite, 5)
to_chat(M, "[src] bites you!")
visible_message("[src] violently bites [M]!",\
"You ambush [M]!", null, COMBAT_MESSAGE_RANGE)
@@ -203,72 +212,99 @@
..()
/mob/living/simple_animal/hostile/mimite/Life()
- ..()
- if(QDELETED(entry_vent))
- entry_vent = null
+ . = ..()
if(isturf(loc) && replicate)
- mimite_growth += rand(0,2)
- if(mimite_growth >= 250)
+ mimite_growth += rand(1,6)
+ if(mimite_growth >= 350 && remaining_replications)
if(!grow_as)
- grow_as = pick(/mob/living/simple_animal/hostile/mimite, /mob/living/simple_animal/hostile/mimite/crate, /mob/living/simple_animal/hostile/mimite/ranged)
+ grow_as = pick_weight(list(/mob/living/simple_animal/hostile/mimite = 50, /mob/living/simple_animal/hostile/mimite/ranged = 45, /mob/living/simple_animal/hostile/mimite/crate = 5))
var/mob/living/simple_animal/hostile/mimite/S = new grow_as(src.loc)
- playsound(S.loc, 'sound/effects/meatslap.ogg', 20, TRUE)
+ remaining_replications--
+ S.remaining_replications = remaining_replications
+ playsound(S.loc, 'sound/effects/meatslap.ogg', 60, TRUE)
mimite_growth = 0
+ approachvent()
if(AIStatus == AI_STATUS_OFF || client)
return
- if(venthunt)
- if(travelling_in_vent)
- if(isturf(loc))
- travelling_in_vent = 0
+ if(venthunt && !attemptingventcrawl && mimite_time <= world.time && prob(25))
+ approachvent()
+ if(attemptingventcrawl && entry_vent)
+ SSmove_manager.move_to(src, entry_vent, 1)
+ tryventcrawl()
+ if(isStuck())
+ SSmove_manager.stop_looping(src)
+
+/mob/living/simple_animal/hostile/mimite/proc/approachvent()
+ for(var/obj/machinery/atmospherics/components/unary/vent_pump/v in view(6,src))
+ if(!v.welded)
+ entry_vent = v
+ SSmove_manager.move_to(src, entry_vent, 1)
+ break
+ tryventcrawl()
+
+/mob/living/simple_animal/hostile/mimite/proc/tryventcrawl()
+ attemptingventcrawl = TRUE
+ mimite_time = world.time + MIMITE_VENT_COOLDOWN
+ if(QDELETED(entry_vent))
+ entry_vent = null
+ if(travelling_in_vent)
+ if(isturf(loc))
+ travelling_in_vent = 0
+ entry_vent = null
+ attemptingventcrawl = FALSE
+ else if(entry_vent)
+ if(get_dist(src, entry_vent) <= 3)
+ var/list/vents = list()
+ var/datum/pipeline/entry_vent_parent = entry_vent.parents[1]
+ for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in entry_vent_parent.other_atmosmch)
+ vents.Add(temp_vent)
+ if(!vents.len)
entry_vent = null
- else if(entry_vent)
- if(get_dist(src, entry_vent) <= 3)
- var/list/vents = list()
- var/datum/pipeline/entry_vent_parent = entry_vent.parents[1]
- for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in entry_vent_parent.other_atmosmch)
- vents.Add(temp_vent)
- if(!vents.len)
+ attemptingventcrawl = FALSE
+ return
+ var/obj/machinery/atmospherics/components/unary/vent_pump/exit_vent = pick(vents)
+ var/travel_time = round(get_dist(loc, exit_vent.loc) * 2)
+ travelling_in_vent = 1
+ spawn(travel_time)
+ if(!exit_vent || exit_vent.welded)
+ forceMove(entry_vent)
entry_vent = null
+ attemptingventcrawl = FALSE
+ travelling_in_vent = 0
return
- var/obj/machinery/atmospherics/components/unary/vent_pump/exit_vent = pick(vents)
- if(prob(50))
+ else
visible_message("[src] scrambles into the ventilation ducts!", \
- "You hear something scampering through the ventilation ducts.")
-
- spawn(rand(20,60))
- forceMove(exit_vent)
- var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
- spawn(travel_time)
-
- if(!exit_vent || exit_vent.welded)
- forceMove(entry_vent)
- entry_vent = null
- return
-
- if(prob(50))
- audible_message("You hear something scampering through the ventilation ducts.")
- sleep(travel_time)
-
- if(!exit_vent || exit_vent.welded)
- forceMove(entry_vent)
- entry_vent = null
- return
- forceMove(exit_vent.loc)
- entry_vent = null
- var/area/new_area = get_area(loc)
- if(new_area)
- new_area.Entered(src)
- SSmove_manager.move_away(src, exit_vent, 4)
- //=================
- else if(prob(1))
- //ventcrawl!
- for(var/obj/machinery/atmospherics/components/unary/vent_pump/v in view(6,src))
- if(!v.welded)
- entry_vent = v
- SSmove_manager.move_to(src, entry_vent, 1)
- break
+ "You hear something scampering through the ventilation ducts.")
+ forceMove(exit_vent.loc)
+ entry_vent = null
+ attemptingventcrawl = FALSE
+ travelling_in_vent = 0
+ var/area/new_area = get_area(loc)
+ if(new_area)
+ new_area.Entered(src)
+ SSmove_manager.move_away(src, exit_vent, 4)
+ else
+ entry_vent = null
+ attemptingventcrawl = FALSE
+ travelling_in_vent = 0
+ return
+
+/mob/living/simple_animal/hostile/mimite/proc/isStuck()
+ //Check to see if the mimite is stuck due to things like windows or doors or windowdoors
+ if(mimite_lastmove)
+ if(mimite_lastmove == src.loc)
+ if(mimite_stuck_threshold >= ++mimite_stuck)
+ mimite_stuck = 0
+ mimite_lastmove = null
+ return 1
+ else
+ mimite_lastmove = null
+ else
+ mimite_lastmove = src.loc
+ return 0
/mob/living/simple_animal/hostile/mimite/death(gibbed)
+ GLOB.all_mimites -= src
new /obj/effect/decal/cleanable/oil(get_turf(src))
..()
@@ -285,7 +321,6 @@
melee_damage = 15
speed = 4
move_to_delay = 4
- replicate = FALSE
venthunt = FALSE
morphed = TRUE
@@ -315,8 +350,8 @@
morphed = FALSE
vision_range = 9
aggro_vision_range = 9
- M.Knockdown(60)
- M.reagents.add_reagent(/datum/reagent/toxin/morphvenom/mimite, 15)
+ M.Knockdown(20)
+ M.reagents.add_reagent(/datum/reagent/toxin/morphvenom/mimite, 10)
to_chat(M, "[src] bites you!")
visible_message("[src] violently bites [M]!",\
"You ambush [M]!", null, COMBAT_MESSAGE_RANGE)