[MIRROR] Flesh Spiders Regenerate + QoL [MDB IGNORE] (#24276)

* Flesh Spiders Regenerate + QoL (#78704)

## About The Pull Request

Replaces the Healing Touch component on Changeling-spawned Flesh Spiders
with the Regenerator component, as the comment helpfully suggests.
Flesh Spiders can no longer touch themselves to heal, instead they
automatically begin regenerating their health if they go four seconds
without taking damage. It takes 6 seconds to fully regenerate, so 10
seconds to fully heal from the edge of death (less if you're not that
injured).

![image](https://github.com/tgstation/tgstation/assets/7483112/37faca55-35fe-48dc-a3ed-03f4b79860bd)

Also I changed the sprite for flesh spider eggs to a different one we
already had rather than regular spider eggs tinted red, just because I
felt like it.
Would be cool to give the spiders their own sprite some time, but that's
for another PR.

![image](https://github.com/tgstation/tgstation/assets/7483112/8ec286c4-46dc-4aec-aa98-cb4e4e432690)
_Additionally_ the flavour text for flesh spiders was kind of messed up
by being shoved into the objectives box and claiming that it was a
directive from a spider queen you don't have, so I gave them their own
slightly different antag datum to compensate.
It also actually mentions how you heal yourself, which previously was
down to trial and error or codediving.

In the course of doing this I decided to just... move flesh spiders to
their own type path. It _sort of_ made sense for them to be part of the
giant spider typepath, but they keep being modified by changes targetted
at "balancing the Giant Spiders antagonist" which this mob isn't related
to and doesn't have any reason to follow. The fact that a mob has
similar stats to another one isn't automatically a reason to share a
typepath, and now that I have looked a little at this mob I'm sort of
interested in branching it further away from "it's a spider mob but
spawned a different way" in the future.

Finally, this spider egg cluster and the midwife one would prompt ghosts
with a radial menu with a single option on it... that's a bit pointless,
so we'll bypass that menu if there is only one possible outcome.

## Why It's Good For The Game

Currently Flesh Spiders heal by clicking on themselves and standing
still for two seconds, restoring 50% of their HP. This means they can
fully regenerate over 4 seconds unless you stun them, and with 90 HP
you're not _that_ likely to kill one during the channel time.
This just feels like an odd way for the creature to operate,
regenerating instead gives it a hit-and-run strategy and adds more use
to their webs (maybe we should give them meatier or bloody webs at some
point? Might be cool).
Also clicking yourself to heal is just unintuitive and I suspect several
players just didn't realise they could do it in the first place.

## Changelog

🆑
balance: Flesh Spiders heal automatically over time if they go a short
time without taking damage, instead of healing large chunks by clicking
themselves and waiting two seconds.
qol: Spider egg clusters which only hatch into one kind of spider don't
ask you to select that one type from a radial menu with one option on
it.
qol: As a Flesh Spider, the game now tells you how you can heal
yourself.
/🆑

* Flesh Spiders Regenerate + QoL

---------

Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
SkyratBot
2023-10-11 12:08:55 -04:00
committed by GitHub
co-authored by Jacquerel
parent e8454d8a10
commit ac45950aae
7 changed files with 123 additions and 64 deletions
+1 -1
View File
@@ -178,7 +178,7 @@
return TRUE
if(!isliving(mover))
return
if(HAS_TRAIT(mover.pulledby, TRAIT_WEB_SURFER))
if(!isnull(mover.pulledby) && HAS_TRAIT(mover.pulledby, TRAIT_WEB_SURFER))
return TRUE
loc.balloon_alert(mover, "stuck in web!")
return FALSE
+21 -1
View File
@@ -14,7 +14,7 @@
/datum/antagonist/spider/on_gain()
forge_objectives(directive)
. = ..()
return ..()
/datum/antagonist/spider/greet()
. = ..()
@@ -35,3 +35,23 @@
var/datum/objective/spider/objective = new(directive)
objective.owner = owner
objectives += objective
/// Subtype for flesh spiders who don't have a queen
/datum/antagonist/spider/flesh
name = "Flesh Spider"
/datum/antagonist/spider/flesh/forge_objectives()
var/datum/objective/custom/destroy = new()
destroy.owner = owner
destroy.explanation_text = "Wreak havoc and consume living flesh."
objectives += destroy
var/datum/objective/survive/dont_die = new()
dont_die.owner = owner
objectives += dont_die
/datum/antagonist/spider/flesh/greet()
. = ..()
to_chat(owner, span_boldwarning("An abomination of flesh set upon the station by changelings, \
you are aggressive to all living beings outside of your species and know no loyalties... even to your creator. \
<br>Your malleable flesh quickly regenerates if you can avoid taking damage for a few seconds."))
@@ -0,0 +1,75 @@
/**
* Spider-esque mob summoned by changelings. Exclusively player-controlled.
* An independent hit-and-run antagonist which can make webs and heals itself if left undamaged for a few seconds.
* Not a spider subtype because it keeps getting hit by unrelated balance changes intended for the Giant Spiders gamemode.
*/
/mob/living/basic/flesh_spider
name = "flesh spider"
desc = "A odd fleshy creature in the shape of a spider. Its eyes are pitch black and soulless."
icon = 'icons/mob/simple/arachnoid.dmi'
icon_state = "flesh"
icon_living = "flesh"
icon_dead = "flesh_dead"
mob_biotypes = MOB_ORGANIC|MOB_BUG
speak_emote = list("chitters")
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
damage_coeff = list(BRUTE = 1, BURN = 1.25, TOX = 1, CLONE = 1, STAMINA = 1, OXY = 1)
basic_mob_flags = FLAMMABLE_MOB
status_flags = NONE
speed = -0.1
maxHealth = 90
health = 90
melee_damage_lower = 15
melee_damage_upper = 20
obj_damage = 30
melee_attack_cooldown = CLICK_CD_MELEE
attack_verb_continuous = "bites"
attack_verb_simple = "bite"
attack_sound = 'sound/weapons/bite.ogg'
attack_vis_effect = ATTACK_EFFECT_BITE
unsuitable_cold_damage = 4
unsuitable_heat_damage = 4
combat_mode = TRUE
faction = list() // No allies but yourself
pass_flags = PASSTABLE
unique_name = TRUE
lighting_cutoff_red = 22
lighting_cutoff_green = 5
lighting_cutoff_blue = 5
butcher_results = list(/obj/item/food/meat/slab/spider = 2, /obj/item/food/spiderleg = 8)
ai_controller = /datum/ai_controller/basic_controller/giant_spider
/mob/living/basic/flesh_spider/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_WEB_SURFER, INNATE_TRAIT)
AddElement(/datum/element/cliff_walking)
AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW)
AddElement(/datum/element/venomous, /datum/reagent/toxin/hunterspider, 5)
AddElement(/datum/element/web_walker, /datum/movespeed_modifier/fast_web)
AddElement(/datum/element/nerfed_pulling, GLOB.typecache_general_bad_things_to_easily_move)
AddElement(/datum/element/prevent_attacking_of_types, GLOB.typecache_general_bad_hostile_attack_targets, "this tastes awful!")
AddComponent(\
/datum/component/blood_walk,\
blood_type = /obj/effect/decal/cleanable/blood/bubblegum,\
blood_spawn_chance = 5,\
)
AddComponent(\
/datum/component/regenerator,\
regeneration_delay = 4 SECONDS,\
health_per_second = maxHealth / 6,\
outline_colour = COLOR_PINK,\
)
var/datum/action/cooldown/mob_cooldown/lay_web/webbing = new(src)
webbing.webbing_time *= 0.7
webbing.Grant(src)
ai_controller?.set_blackboard_key(BB_SPIDER_WEB_ACTION, webbing)
var/datum/action/cooldown/mob_cooldown/lay_web/web_spikes/spikes_web = new(src)
spikes_web.Grant(src)
var/datum/action/cooldown/mob_cooldown/lay_web/sticky_web/web_sticky = new(src)
web_sticky.Grant(src)
@@ -478,55 +478,6 @@
menu_description = "Weaker version of the nurse spider, specializing in healing their brethren and placing webbings very swiftly, but has very low amount of health and deals low damage."
ai_controller = /datum/ai_controller/basic_controller/giant_spider/weak
/**
* ### Flesh Spider
*
* A subtype of giant spider which only occurs from changelings.
* Has the base stats of a hunter, but they can heal themselves and spin webs faster.
* They also occasionally leave puddles of blood when they walk around. Flavorful!
*/
/mob/living/basic/spider/giant/hunter/flesh
name = "flesh spider"
desc = "A odd fleshy creature in the shape of a spider. Its eyes are pitch black and soulless."
icon = 'icons/mob/simple/arachnoid.dmi'
icon_state = "flesh"
icon_living = "flesh"
icon_dead = "flesh_dead"
web_speed = 0.7
maxHealth = 90
health = 90
menu_description = "Self-sufficient spider variant capable of healing themselves and producing webbbing fast."
/mob/living/basic/spider/giant/hunter/flesh/Initialize(mapload)
. = ..()
AddComponent(/datum/component/blood_walk, \
blood_type = /obj/effect/decal/cleanable/blood/bubblegum, \
blood_spawn_chance = 5)
// It might be easier and more fitting to just replace this with Regenerator
AddComponent(/datum/component/healing_touch,\
heal_brute = 45,\
heal_burn = 45,\
self_targetting = HEALING_TOUCH_SELF_ONLY,\
interaction_key = DOAFTER_SOURCE_SPIDER,\
valid_targets_typecache = typecacheof(list(/mob/living/basic/spider/giant/hunter/flesh)),\
extra_checks = CALLBACK(src, PROC_REF(can_mend)),\
action_text = "%SOURCE% begins mending themselves...",\
complete_text = "%SOURCE%'s wounds mend together.",\
)
var/datum/action/cooldown/mob_cooldown/lay_web/web_spikes/spikes_web = new(src)
spikes_web.Grant(src)
var/datum/action/cooldown/mob_cooldown/lay_web/sticky_web/web_sticky = new(src)
web_sticky.Grant(src)
/// Prevent you from healing other flesh spiders, or healing when on fire
/mob/living/basic/spider/giant/hunter/flesh/proc/can_mend(mob/living/source, mob/living/target)
if (on_fire)
balloon_alert(src, "on fire!")
return FALSE
return TRUE
/**
* ### Viper Spider (Wizard)
*
@@ -41,8 +41,9 @@
color = rgb(148, 0, 211)
/obj/structure/spider/eggcluster/bloody
icon = 'icons/mob/simple/meteor_heart.dmi'
icon_state = "eggs"
name = "bloody egg cluster"
color = rgb(255, 0, 0)
/obj/structure/spider/eggcluster/midwife
name = "midwife egg cluster"
@@ -72,6 +73,8 @@
var/cluster_type = /obj/structure/spider/eggcluster
/// Physical structure housing the spawner
var/obj/structure/spider/eggcluster/egg
/// Which antag datum do we grant?
var/granted_datum = /datum/antagonist/spider
/// The types of spiders that the spawner can produce
var/list/potentialspawns = list(
/mob/living/basic/spider/growing/spiderling/nurse,
@@ -124,10 +127,11 @@
/obj/effect/mob_spawn/ghost_role/spider/special(mob/living/basic/spider/spawned_mob, mob/mob_possessor)
. = ..()
spawned_mob.directive = directive
if (isspider(spawned_mob))
spawned_mob.directive = directive
egg.spawner = null
QDEL_NULL(egg)
var/datum/antagonist/spider/spider_antag = new(directive)
var/datum/antagonist/spider/spider_antag = new granted_datum(directive)
spawned_mob.mind.add_antag_datum(spider_antag)
/obj/effect/mob_spawn/ghost_role/spider/enriched
@@ -144,15 +148,18 @@
/obj/effect/mob_spawn/ghost_role/spider/bloody
name = "bloody egg cluster"
color = rgb(255, 0, 0)
you_are_text = "You are a bloody spider."
icon = 'icons/mob/simple/meteor_heart.dmi'
icon_state = "eggs"
you_are_text = "You are a flesh spider."
flavour_text = "An abomination of nature set upon the station by changelings. Your only goal is to kill, terrorize, and survive."
directive = "You are the spawn of a vicious changeling. You have no ambitions except to wreak havoc and ensure your own survival. You are aggressive to all living beings outside of your species, including changelings."
faction = list()
directive = null
cluster_type = /obj/structure/spider/eggcluster/bloody
potentialspawns = list(
/mob/living/basic/spider/giant/hunter/flesh,
/mob/living/basic/flesh_spider,
)
flash_window = TRUE
granted_datum = /datum/antagonist/spider/flesh
/obj/effect/mob_spawn/ghost_role/spider/midwife
name = "midwife egg cluster"
@@ -175,6 +182,14 @@
* * newname - If set, renames the mob to this name
*/
/obj/effect/mob_spawn/ghost_role/spider/create(mob/user, newname)
var/chosen_spider = length(potentialspawns) > 1 ? get_radial_choice(user) : potentialspawns[1]
if(QDELETED(src) || QDELETED(user) || isnull(chosen_spider))
return FALSE
mob_type = chosen_spider
return ..()
/// Pick a spider type from a radial menu
/obj/effect/mob_spawn/ghost_role/spider/proc/get_radial_choice(mob/user)
var/list/spider_list = list()
var/list/display_spiders = list()
for(var/choice in potentialspawns)
@@ -196,9 +211,6 @@
display_spiders[initial(spider.name)] = option
sort_list(display_spiders)
var/chosen_spider = show_radial_menu(user, egg, display_spiders, radius = 38)
chosen_spider = spider_list[chosen_spider]
if(QDELETED(src) || QDELETED(user) || !chosen_spider)
return FALSE
mob_type = chosen_spider
return ..()
return spider_list[chosen_spider]
+2 -1
View File
@@ -4549,7 +4549,6 @@
#include "code\modules\mob\living\basic\space_fauna\faithless.dm"
#include "code\modules\mob\living\basic\space_fauna\garden_gnome.dm"
#include "code\modules\mob\living\basic\space_fauna\ghost.dm"
#include "code\modules\mob\living\basic\space_fauna\headslug.dm"
#include "code\modules\mob\living\basic\space_fauna\killer_tomato.dm"
#include "code\modules\mob\living\basic\space_fauna\lightgeist.dm"
#include "code\modules\mob\living\basic\space_fauna\morph.dm"
@@ -4568,6 +4567,8 @@
#include "code\modules\mob\living\basic\space_fauna\carp\carp_controllers.dm"
#include "code\modules\mob\living\basic\space_fauna\carp\magicarp.dm"
#include "code\modules\mob\living\basic\space_fauna\carp\megacarp.dm"
#include "code\modules\mob\living\basic\space_fauna\changeling\flesh_spider.dm"
#include "code\modules\mob\living\basic\space_fauna\changeling\headslug.dm"
#include "code\modules\mob\living\basic\space_fauna\demon\demon.dm"
#include "code\modules\mob\living\basic\space_fauna\demon\demon_items.dm"
#include "code\modules\mob\living\basic\space_fauna\demon\demon_subtypes.dm"