Files
+37 21b4095dfd [MDB IGNORE] [IDB IGNORE] Upstream Sync - 04/17/2026 (#5453)
Upstream 04/17/2026

fixes https://github.com/Bubberstation/Bubberstation/issues/5549

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com>
Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com>
Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com>
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com>
Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com>
Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com>
Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com>
Co-authored-by: loganuk <fakeemail123@aol.com>
Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com>
Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com>
Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com>
Co-authored-by: Lucy <lucy@absolucy.moe>
Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com>
Co-authored-by: Isratosh <Isratosh@hotmail.com>
Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com>
Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com>
Co-authored-by: Alexander V. <volas@ya.ru>
Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com>
Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
Co-authored-by: Cameron Lennox <killer65311@gmail.com>
Co-authored-by: Tim <timothymtorres@gmail.com>
Co-authored-by: Iamgoofball <iamgoofball@gmail.com>
Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com>
Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com>
Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com>
Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com>
Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com>
Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com>
Co-authored-by: Josh <josh.adam.powell@gmail.com>
Co-authored-by: Josh Powell <josh.powell@softwire.com>
Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com>
Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com>
Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com>
Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
2026-05-16 00:56:00 +02:00

186 lines
7.8 KiB
Plaintext

/**
* Player-piloted brute mob. Mostly just a "move and click" kind of guy.
* Has a variant which takes damage when away from blob tiles
*/
/mob/living/basic/blob_minion/blobbernaut
name = "blobbernaut"
desc = "A hulking, mobile chunk of blobmass."
icon_state = "blobbernaut"
base_icon_state = "blobbernaut"
icon_living = "blobbernaut"
icon_dead = "blobbernaut_dead"
health = BLOBMOB_BLOBBERNAUT_HEALTH
maxHealth = BLOBMOB_BLOBBERNAUT_HEALTH
damage_coeff = list(BRUTE = 0.5, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1)
melee_damage_lower = BLOBMOB_BLOBBERNAUT_DMG_SOLO_LOWER
melee_damage_upper = BLOBMOB_BLOBBERNAUT_DMG_SOLO_UPPER
melee_attack_cooldown = CLICK_CD_MELEE
obj_damage = BLOBMOB_BLOBBERNAUT_DMG_OBJ
attack_verb_continuous = "slams"
attack_verb_simple = "slam"
attack_sound = 'sound/effects/blob/blobattack.ogg'
verb_say = "gurgles"
verb_ask = "demands"
verb_exclaim = "roars"
verb_yell = "bellows"
pressure_resistance = 50
mob_size = MOB_SIZE_LARGE
ai_controller = /datum/ai_controller/basic_controller/blobbernaut
loot = null
///The overlay for veins.
var/mutable_appearance/vein_overlay
///The overlay for our eyes
var/mutable_appearance/eyes_overlay
///emissive eyes
var/static/mutable_appearance/eyes_emissive
/mob/living/basic/blob_minion/blobbernaut/Initialize(mapload)
. = ..()
AddElement(/datum/element/swabable, CELL_LINE_TABLE_BLOBBERNAUT, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5)
AddElement(/datum/element/damage_threshold, 10)
var/static/list/food_types = list(
/obj/item/food/egg,
/obj/item/food/rawegg,
/obj/item/food/friedegg,
/obj/item/food/boiledegg,
/obj/item/flashlight/flare,
/obj/item/reagent_containers/cup/soda_cans/shamblers,
)
AddComponent(/datum/component/tameable, food_types = food_types, tame_chance = 25, bonus_tame_chance = 15)
update_appearance()
/mob/living/basic/blob_minion/blobbernaut/death(gibbed)
flick("[icon_state]_death", src)
playsound(src, 'sound/mobs/non-humanoids/blobmob/blobbernaut_death.ogg', 100, TRUE)
update_overlays()
return ..()
/mob/living/basic/blob_minion/blobbernaut/create_mob_hud()
. = ..()
if(!.)
return
hud_used.add_screen_object(/atom/movable/screen/healths/blob/overmind, HUD_BLOBBERNAUT_OVERMIND, HUD_GROUP_INFO, update_screen = TRUE)
/mob/living/basic/blob_minion/blobbernaut/on_strain_updated(mob/eye/blob/overmind, datum/blobstrain/new_strain)
. = ..()
if(new_strain)
attack_verb_continuous = new_strain.blobbernaut_message
melee_damage_upper = BLOBMOB_BLOBBERNAUT_DMG_UPPER
melee_damage_lower = BLOBMOB_BLOBBERNAUT_DMG_LOWER
vein_overlay?.color = new_strain.complementary_color
eyes_overlay?.color = new_strain.complementary_color
//revert independent blobbernauts to the pale sprite so they can be recoloured
icon_dead = "[base_icon_state]_dead"
icon_living = base_icon_state
new_strain.RegisterSignal(src, COMSIG_HOSTILE_POST_ATTACKINGTARGET, TYPE_PROC_REF(/datum/blobstrain/, blobbernaut_attack))
else
attack_verb_continuous = initial(attack_verb_continuous)
melee_damage_upper = BLOBMOB_BLOBBERNAUT_DMG_SOLO_UPPER
melee_damage_lower = BLOBMOB_BLOBBERNAUT_DMG_SOLO_LOWER
//Our overmind has died and our veins turns a mournful amethyst to complement our pale strainless body.
vein_overlay?.color = "#7d6eb4"
eyes_overlay?.color = COLOR_WHITE
update_appearance()
/mob/living/basic/blob_minion/blobbernaut/update_overlays()
. = ..()
if(!vein_overlay)
vein_overlay = mutable_appearance(icon, "[base_icon_state]_veins", appearance_flags = RESET_COLOR | KEEP_APART)
///Give it independent olive green veins until strain modifies it
vein_overlay.color = COLOR_OLIVE_GREEN
if(!eyes_overlay)
eyes_overlay = mutable_appearance(icon, "[base_icon_state]_eyes", appearance_flags = RESET_COLOR | KEEP_APART)
eyes_overlay.color = "#ffc90e" //blobber eye yellow
if(!eyes_emissive)
eyes_emissive = emissive_appearance(icon, "[base_icon_state]_eyes", src)
if(stat != DEAD)
. += vein_overlay
. += eyes_overlay
. += eyes_emissive
/// This variant is the one actually spawned by blob factories, takes damage when away from blob tiles
/mob/living/basic/blob_minion/blobbernaut/minion
/// Is our factory dead?
var/orphaned = FALSE
/mob/living/basic/blob_minion/blobbernaut/minion/Life(seconds_per_tick)
. = ..()
if (!.)
return FALSE
var/damage_sources = 0
var/list/blobs_in_area = range(2, src)
if(!(locate(/obj/structure/blob) in blobs_in_area))
damage_sources++
if (orphaned)
damage_sources++
else
var/particle_colour = atom_colours?[FIXED_COLOUR_PRIORITY] || COLOR_BLACK
if (locate(/obj/structure/blob/special/core) in blobs_in_area)
heal_overall_damage(maxHealth * BLOBMOB_BLOBBERNAUT_HEALING_CORE * seconds_per_tick)
var/obj/effect/temp_visual/heal/heal_effect = new /obj/effect/temp_visual/heal(get_turf(src))
heal_effect.color = particle_colour
if (locate(/obj/structure/blob/special/node) in blobs_in_area)
heal_overall_damage(maxHealth * BLOBMOB_BLOBBERNAUT_HEALING_NODE * seconds_per_tick)
var/obj/effect/temp_visual/heal/heal_effect = new /obj/effect/temp_visual/heal(get_turf(src))
heal_effect.color = particle_colour
if (damage_sources == 0)
return FALSE
// take 2.5% of max health as damage when not near the blob or if the naut has no factory, 5% if both
apply_damage(maxHealth * BLOBMOB_BLOBBERNAUT_HEALTH_DECAY * damage_sources * seconds_per_tick, damagetype = TOX) // We reduce brute damage
//hopefully this sound won't get too annoying.
if(prob(20))
playsound(src, 'sound/items/weapons/sear.ogg', 5, vary = TRUE)
//create aooearances for the naut damage effect
var/mutable_appearance/naut_damage_overlay = mutable_appearance(icon, "[base_icon_state]_veins", appearance_flags = RESET_COLOR | KEEP_APART)
//modify appearances to intitially have no effect
naut_damage_overlay.color = vein_overlay.color
//flick naut damage overlays
var/atom/movable/flick_visual/naut_damage_animation = flick_overlay_view(naut_damage_overlay, seconds_per_tick)
//make flick objects obey dirs
naut_damage_animation.vis_flags |= VIS_INHERIT_DIR
//animate the naut damage overlays to fade in the 180 vein hue shift and emsissive.
animate(naut_damage_animation, time = seconds_per_tick / 2, easing = SINE_EASING, color = RotateHue(vein_overlay.color, 180))
animate(time = seconds_per_tick / 2, easing = SINE_EASING, color = vein_overlay.color)
return TRUE
/// Called by the blob creation power to give us a mind and a basic task orientation
/mob/living/basic/blob_minion/blobbernaut/minion/proc/assign_key(ckey, datum/blobstrain/blobstrain)
key = ckey
flick("blobbernaut_produce", src)
health = maxHealth / 2 // Start out injured to encourage not beelining away from the blob
SEND_SOUND(src, sound('sound/effects/blob/blobattack.ogg'))
SEND_SOUND(src, sound('sound/effects/blob/attackblob.ogg'))
to_chat(src, span_infoplain("You are powerful, hard to kill, and slowly regenerate near nodes and cores, [span_cult_large("but will slowly die if not near the blob")] or if the factory that made you is killed."))
to_chat(src, span_infoplain("You can communicate with other blobbernauts and overminds <b>telepathically</b> by attempting to speak normally"))
to_chat(src, span_infoplain("Your overmind's blob reagent is: <b><font color=\"[blobstrain.color]\">[blobstrain.name]</b></font>!"))
to_chat(src, span_infoplain("The <b><font color=\"[blobstrain.color]\">[blobstrain.name]</b></font> reagent [blobstrain.shortdesc ? "[blobstrain.shortdesc]" : "[blobstrain.description]"]"))
/// Called by our factory to inform us that it's not going to support us financially any more
/mob/living/basic/blob_minion/blobbernaut/minion/on_factory_destroyed()
. = ..()
orphaned = TRUE
throw_alert("nofactory", /atom/movable/screen/alert/nofactory)
///brand new orange look to match the classic spore.
/mob/living/basic/blob_minion/blobbernaut/independent
icon_state = "blobbernaut_independent"
icon_living = "blobbernaut_independent"
icon_dead = "blobbernaut_independent_dead"