Files
88d7efe291 Fleshmind - Attempt 3 (#4914)
## About This Pull Request
Brought back based off of
https://github.com/Bubberstation/Bubberstation/pull/2007, made
functional again by myself.
Original Code: https://github.com/Skyrat-SS13/Skyrat-tg/pull/14023

Fleshmind is a PVE event that incorporates some PVP elements in the
later stages of its growth. You defeat it by destroying all its
processors. It has six stages of growth with each stage expanding on its
abilities and the structures and mobs it can deploy. It will announce to
the entire station each time it gains a level or loses a level. Each
level means it has a new processor.

- **Level 1:** The start when it spawns in. It will spawn some basic
structures.
- **Level 2:** It will begin to spawn screamers and whisperers
- **Level 3:** The wireweed is much more situated, and this is the point
where it spawns a very dangerous mech. This is the point where it
becomes very critical. It also starts to spawn Babblers (structures that
spew propaganda into comms) and Modulators. (Gives you hallucinations)
- **Level 4** No new special abilities.
- **Level 5** No new special abilities
- **Level 6** It automatically calls the emergency shuttle to hijack and
spawns a deathsquad on Centcomm. This ends the round.

**Counters:**
- Fight in groups. Carry a melee weapon. (You can still melee the
mechivers and try to kill them before they convert you)
- Wirecutters cut wireweed.
- Ion Weaponry is extremely useful. It also stuns all the mobs.
- Target the processors. If you can pick them off in space, it has
practically zero EVA abilities.
- If someone gets assimilated, should get them to medical if you kill
them.

To run it requires 35 active players and a minimum of an hour to have
passed.
## Why It's Good For The Game
With mold being disabled, there is a missing PVE element in the game,
this fills that niche while also playing around with the idea of
temporary conversion antags in a way that I think works really well.

Wireweed/fleshmind also distracts the crew and security enough to
provide clever antagonists with an opening to commit crimes and get away
with them while the crew has their hands full.

## Proof of Testing
It's been test merged for two months now, it works.
## Changelog
🆑 xPokee, StrangeWeirdKitten, Gandalf2k15
add: New midround event: Fleshmind
/🆑

---------

Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
Co-authored-by: Artur Lang <24881678+Arturlang@users.noreply.github.com>
Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com>
2026-02-17 15:38:34 +01:00

236 lines
7.3 KiB
Plaintext

/obj/structure/mob_spawner
name = "nest"
desc = "A nasty looking pile of sticks and debris."
icon = 'modular_skyrat/modules/decay_subsystem/icons/nests.dmi'
icon_state = "nest"
density = FALSE
anchored = TRUE
layer = TABLE_LAYER
max_integrity = 100
light_range = 2
light_power = 1
light_color = LIGHT_COLOR_LAVA
faction = list(NEST_FACTION)
var/spawn_delay = 0
/// What mob to spawn
var/list/monster_types = list(/mob/living/basic/blackmesa/xen/headcrab)
/// How many mobs can we spawn?
var/max_mobs = 3
var/spawned_mobs = 0
/// How long it takes for a new mob to emerge after being triggered.
var/spawn_cooldown = 30 SECONDS
/// How long it takes to regenerate mobs to spawn again
var/regenerate_time = 20 MINUTES
var/retaliated = FALSE
/// How long it takes for us to retaliate again.
var/retaliate_cooldown = 20 SECONDS
var/list/registered_turfs = list()
/// What loot do we spawn upon death?
var/list/loot = list()
/// Do spawned mobs become ghost controllable?
var/ghost_controllable = FALSE
/// The range at which these are triggered.
var/trigger_range = 5
/// Does this nest passively spawn mobs too?
var/passive_spawning = FALSE
/obj/structure/mob_spawner/Initialize(mapload)
. = ..()
calculate_trigger_turfs()
if(passive_spawning)
START_PROCESSING(SSobj, src)
/obj/structure/mob_spawner/proc/calculate_trigger_turfs()
for(var/turf/open/seen_turf in view(trigger_range, src))
registered_turfs += seen_turf
RegisterSignal(seen_turf, COMSIG_ATOM_ENTERED, PROC_REF(proximity_trigger))
/obj/structure/mob_spawner/atom_destruction(damage_flag)
if(loot)
for(var/path in loot)
var/number = loot[path]
if(!isnum(number))//Default to 1
number = 1
for(var/i in 1 to number)
new path (loc)
playsound(src, 'sound/effects/blob/blobattack.ogg', 100)
return ..()
/obj/structure/mob_spawner/Destroy()
for(var/t in registered_turfs)
UnregisterSignal(t, COMSIG_ATOM_ENTERED)
registered_turfs = null
if(passive_spawning)
STOP_PROCESSING(SSobj, src)
return ..()
/obj/structure/mob_spawner/process(seconds_per_tick)
if(passive_spawning)
if(spawned_mobs >= max_mobs)
return
if(spawn_delay > world.time)
return
spawn_delay = world.time + spawn_cooldown
spawn_mob()
/obj/structure/mob_spawner/proc/proximity_trigger(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) // Bubber edit ORG: /obj/structure/mob_spawner/proc/proximity_trigger(datum/source, atom/movable/AM)
SIGNAL_HANDLER
if(spawned_mobs >= max_mobs)
return
if(spawn_delay > world.time)
return
spawn_delay = world.time + spawn_cooldown
if(!isliving(arrived))
return
var/mob/living/entered_mob = arrived
if((NEST_FACTION in entered_mob.faction))
return
spawn_mob()
/obj/structure/mob_spawner/proc/spawn_mob()
var/sound/sound_to_play = pick('modular_skyrat/master_files/sound/effects/rustle1.ogg', 'modular_skyrat/master_files/sound/effects/rustle2.ogg')
playsound(src, sound_to_play, 100)
do_squish(0.8, 1.2)
spawned_mobs++
var/chosen_mob_type = pick(monster_types)
var/mob/living/spawned_mob = new chosen_mob_type(loc)
spawned_mob.flags_1 |= (flags_1 & ADMIN_SPAWNED_1)
spawned_mob.faction = faction
spawned_mob.ghost_controllable = ghost_controllable
RegisterSignal(spawned_mob, COMSIG_LIVING_DEATH, PROC_REF(mob_death))
visible_message(span_danger("[spawned_mob] emerges from [src]."))
/obj/structure/mob_spawner/proc/mob_death(mob/living/dead_guy, gibbed)
SIGNAL_HANDLER
spawned_mobs--
UnregisterSignal(dead_guy, COMSIG_LIVING_DEATH)
/obj/structure/mob_spawner/attacked_by(obj/item/I, mob/living/user)
. = ..()
do_jiggle_sr()
if(!retaliated)
visible_message(span_danger("[src] grubbles angrily!"))
var/chosen_mob_type = pick(monster_types)
var/mob/living/simple_animal/L = new chosen_mob_type(loc)
visible_message(span_danger("[L] emerges from [src]."))
retaliated = TRUE
addtimer(CALLBACK(src, PROC_REF(ready_retaliate)), retaliate_cooldown)
/obj/structure/mob_spawner/proc/ready_retaliate()
retaliated = FALSE
visible_message(span_danger("[src] calms down."))
/*
* CUSTOM SPAWNERS
*/
/obj/structure/mob_spawner/spiders
name = "sticky cobwebs"
desc = "A mush of sticky cobwebs and nasty looking eggs..."
icon_state = "nest_spider"
light_color = LIGHT_COLOR_BLOOD_MAGIC
monster_types = list(/mob/living/basic/spider/giant/hunter, /mob/living/basic/spider/giant/)
loot = list(/obj/item/spider_egg = 4)
/obj/item/spider_egg
name = "spider egg"
desc = "A white egg with something crawling around inside. Looks... fragile."
icon = 'modular_skyrat/modules/decay_subsystem/icons/loot.dmi'
icon_state = "spider_egg"
/obj/item/spider_egg/attack_self(mob/user, modifiers)
. = ..()
to_chat(user, span_danger("You begin to crack open [src]..."))
if(do_after(user, 3 SECONDS, src))
to_chat(user, span_userdanger("You crack [src] open, something monsterous crawls out!"))
playsound(src, 'sound/effects/blob/blobattack.ogg', 100)
new /mob/living/basic/spider/giant/ (user.loc)
qdel(src)
/obj/structure/mob_spawner/bush
name = "bloody bush"
desc = "A bush... oozing blood?"
icon_state = "nest_grass"
light_color = LIGHT_COLOR_GREEN
monster_types = list(/mob/living/basic/killer_tomato)
loot = list(/obj/item/seeds/random = 3)
max_mobs = 6
/obj/structure/mob_spawner/beehive
name = "beehive"
desc = "Filled with little beings that exist only to make your life a living hell."
icon_state = "nest_bee"
light_color = LIGHT_COLOR_BRIGHT_YELLOW
monster_types = list(/mob/living/basic/bee)
max_mobs = 15
spawn_cooldown = 5 SECONDS
loot = list(/obj/item/food/honeycomb = 5, /obj/item/queen_bee)
var/swarmed = FALSE
/obj/structure/mob_spawner/beehive/attacked_by(obj/item/I, mob/living/user)
. = ..()
if(!swarmed)
playsound(src, 'sound/mobs/non-humanoids/bee/bee.ogg', 100)
visible_message(span_userdanger("[src] buzzes violently as bees pour out!"))
for(var/i=1, i<max_mobs, ++i)
new /mob/living/basic/bee (loc)
swarmed = TRUE
/obj/structure/mob_spawner/beehive/toxic
name = "oozing beehive"
desc = "A beehive... it looks off however, it's oozing some kind of green glowing goop."
icon_state = "nest_bee_toxic"
monster_types = list(/mob/living/basic/bee/toxin)
max_mobs = 6
color = LIGHT_COLOR_ELECTRIC_GREEN
/obj/structure/mob_spawner/snake
name = "disgusting eggs"
desc = "These pulsating eggs are oozing out a puss like substance..."
icon_state = "nest_eggs"
light_color = LIGHT_COLOR_BRIGHT_YELLOW
monster_types = list(/mob/living/basic/snake)
max_mobs = 8
spawn_cooldown = 5 SECONDS
/obj/structure/mob_spawner/rats
name = "nasty nest"
desc = "A nest crawling with... something!"
icon_state = "nest_rats"
light_color = LIGHT_COLOR_GREEN
max_mobs = 8
spawn_cooldown = 15 SECONDS
monster_types = list(/mob/living/basic/mouse/rat)
loot = list(/obj/item/seeds/replicapod = 2)
/obj/structure/mob_spawner/grapes
name = "grapevine"
desc = "A grapevine... with... eggs?"
icon_state = "nest_grapes"
light_color = LIGHT_COLOR_PURPLE
monster_types = list(/mob/living/simple_animal/hostile/ooze/grapes)
loot = list(/obj/item/resurrection_crystal)
/obj/structure/mob_spawner/grapes/atom_destruction(damage_flag)
if(loot)
for(var/path in loot)
var/number = loot[path]
if(!isnum(number))//Default to 1
number = 1
for(var/i in 1 to number)
new path (loc)
playsound(src, 'sound/effects/blob/blobattack.ogg', 100)
new /mob/living/basic/vatbeast(loc)
return ..()