mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-12 00:27:31 +01:00
88d7efe291
## 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>
95 lines
3.5 KiB
Plaintext
95 lines
3.5 KiB
Plaintext
/// A component for ai-controlled atoms which plays a sound if they switch to a living target which they can attack
|
|
/datum/component/aggro_emote
|
|
/// Blackboard key in which target data is stored
|
|
var/target_key
|
|
/// If we want to limit emotes to only play at mobs
|
|
var/living_only
|
|
/// List of emotes to play
|
|
var/list/emote_list
|
|
// BUBBER EDIT - START: FLESHMIND
|
|
/// Audiable emotes to play
|
|
var/list/audible_emote_list
|
|
/// Do we taunt the target?
|
|
var/list/speak_list
|
|
/// Do we play any sounds?
|
|
var/list/sounds
|
|
// BUBBER EDIT - END
|
|
/// Chance to play an emote
|
|
var/emote_chance
|
|
/// Chance to subtract every time we play an emote (permanently)
|
|
var/subtract_chance
|
|
/// Minimum chance to play an emote
|
|
var/minimum_chance
|
|
|
|
/datum/component/aggro_emote/Initialize(
|
|
target_key = BB_BASIC_MOB_CURRENT_TARGET,
|
|
living_only = FALSE,
|
|
list/emote_list,
|
|
list/speak_list, // BUBBER EDIT - ADDITION: FLESHMIND
|
|
list/sounds, // BUBBER EDIT - ADDITION: FLESHMIND
|
|
list/audible_emote_list, // BUBBER EDIT - ADDITION: FLESHMIND
|
|
emote_chance = 30,
|
|
minimum_chance = 2,
|
|
subtract_chance = 7,
|
|
)
|
|
. = ..()
|
|
if (!isatom(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
var/atom/atom_parent = parent
|
|
if (!atom_parent.ai_controller)
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
src.target_key = target_key
|
|
src.emote_list = emote_list
|
|
src.speak_list = speak_list // BUBBER EDIT - ADDITION: FLESHMIND
|
|
src.sounds = sounds // BUBBER EDIT - ADDITION: FLESHMIND
|
|
src.audible_emote_list = audible_emote_list // BUBBER EDIT - ADDITION: FLESHMIND
|
|
src.emote_chance = emote_chance
|
|
src.minimum_chance = minimum_chance
|
|
src.subtract_chance = subtract_chance
|
|
|
|
/datum/component/aggro_emote/RegisterWithParent()
|
|
. = ..()
|
|
RegisterSignal(parent, COMSIG_AI_BLACKBOARD_KEY_SET(target_key), PROC_REF(on_target_changed))
|
|
|
|
/datum/component/aggro_emote/UnregisterFromParent()
|
|
UnregisterSignal(parent, COMSIG_AI_BLACKBOARD_KEY_SET(target_key))
|
|
return ..()
|
|
|
|
/// When we get a new target, see if we want to bark at it
|
|
/datum/component/aggro_emote/proc/on_target_changed(atom/source)
|
|
SIGNAL_HANDLER
|
|
var/atom/new_target = source.ai_controller.blackboard[target_key]
|
|
// BUBBER EDIT - START: FLESHMIND
|
|
var/mob/living/mob = source
|
|
/// Used to pick and choose between emotes and audiable sounds
|
|
|
|
// Grab the number length of each list
|
|
var/emotes_length = emote_list?.len
|
|
var/audible_emote_length = audible_emote_list?.len
|
|
var/speak_emote_length = speak_list?.len
|
|
// Add them all together
|
|
var/total_choices_length = audible_emote_length + speak_emote_length + emotes_length
|
|
//Pick a random number between 1 and the total length of every list
|
|
var/random_number_in_range = rand(1, total_choices_length)
|
|
var/sound_to_play = length(sounds) > 0 ? pick(sounds) : null
|
|
// Calculate the emote chance and determin if you'll run an emote
|
|
emote_chance = max(emote_chance - subtract_chance, minimum_chance)
|
|
// BUBBER EDIT - END
|
|
if (isnull(new_target) || !prob(emote_chance))
|
|
return
|
|
if (living_only && !isliving(new_target))
|
|
return // If we don't want to bark at food items or chairs or windows
|
|
|
|
// BUBBER EDIT - START: FLESHMIND
|
|
/// Randomly choose between each emote
|
|
if(random_number_in_range <= audible_emote_length)
|
|
source.manual_emote("[pick(audible_emote_list)]")
|
|
playsound(source, sound_to_play, 80, vary = TRUE)
|
|
else if(random_number_in_range <= (audible_emote_length + emotes_length))
|
|
source.manual_emote("[pick(emote_list)] at [new_target].")
|
|
else
|
|
INVOKE_ASYNC(mob, TYPE_PROC_REF(/atom/movable, say), pick(speak_list), forced = "AI Controller")
|
|
playsound(source, sound_to_play, 80, vary = TRUE)
|
|
// BUBBER EDIT - END
|