Files
Bubberstation/code/datums/components/bubble_icon_override.dm
Ghom 96c0c0b12c Fish infusion (#87030)
## About The Pull Request
I'm adding a new infusion ~~(actually four, but two of them are just
holders for specific organs tied to a couple fish traits)~~ to the game.
As the title says, it's about fish.

The infusion is composed of three primary organs, plus another few that
can be gotten from fish with specific traits.

The primary organs are:
- Gills (lungs): Instead of breathing oxygen, you now need to stay wet
or breathe water vapor.
- fish-DNA infused stomach: Can safely eat raw fish.
- fish tail: On its own, it only speeds you up on water turfs, but it
has another effect once past the organ set threshold. It also makes you
waddle and flop like a fish while crawling (I still gotta finish sprites
on this one)

Other organs are:
- semi-aquatic lungs: A subtype of gills from fish with the 'amphibious'
trait, falls back on oxygen if there's no water. Can also be gotten from
frogs, axolotl and crabs.
- fish-DNA infused liver: From fish with the 'toxic' trait. Uses
tetrodotoxin as a healing chem instead of a toxin. Also better tolerance
to alcohol if you want to drink like a fish (ba dum tsh).
- inky tongue: From fish with the 'ink production' trait. Gives mobs the
ability to spit ink on a cooldown, blinding and confusion foes
temporarily.

The main gimmick of this infusion revolves around being drenched in
water to benefit from it, In the case you get the gills organ, this also
becomes a necessity, to not suffocate to death (alternatively, you can
breathe water vapor, without any benefit). To enable the bonus of the
organs set, three organs need to be infused. They can be gills, stomach,
tail and/or liver, while the inky tongue doesn't count towards it.

Once the threshold is reached, the following bonus are enabled:
- Wetness decays a lot slower and resists fire a bit more.
- Ink spit becomes stronger, allowing it to very briefly knock down
foes.
- Fishing bonuses and experience
- Resistance to high pressures
- Slightly expanded FOV
- drinking water and showers mildly heal you over time.
- for felinids: You won't hate getting sprayed by water or taking a
shower.
- While wet:
- - If the fish tail is implanted, crawling speed is boosted.
- - You no longer slip on wet tiles.
- - You also become slippery when lying on the floor.
- - You get a very mild damage resistance and passive stamina
regeneration, and cool down faster.
- - You resist grabs better.
- - get a very weak positive moodlet.
- However, being dry will make you quite squisher, especially against
fire damage, slower and give you a modest negative moodlet.

While working on it, I've also noticed a few things that explained why
tetrodotoxin (TTX) did jackshit at low doses, because livers have a set
toxin tolerance value, below which, any amount of toxin does nothing.
Also I've felt like reagents like multiver & co were a bit too strong
against a reagent that's supposed to work at very low doses, with slow
metabolization, so I've added a couple variables to buff TTX a bit,
making it harder to purge and resistant to liver toxin tolerance (also
added a bit of lungs damage).



## Why It's Good For The Game
I wanted to take a shot at coding a DNA infusion and see how chock-full
I could make it. DNA infusions are like a middle point between "aha,
small visual trinket" and organs with generally ok effects. I seek to
make something a bit more complex ~~(also tied to fishing ofc because
that's more or less the recurrent gag of my recent features)~~ primaly
focused around the unique theme of being strong when wet and weaker when
dry.

EDIT: The PR is now ready, have a set of screenshots of the (fairly mid)
fish tails (and gills, barely visible) on randomly generated spessman
and one consistent joe:

![immagine](https://github.com/user-attachments/assets/a4965508-22e2-4d3a-8523-29fec6bce91e)


## Changelog

🆑
add: Added a new infusion to the game: Fish. Its main gimmick revolves
around being stronger and slippery when wet while weaker when dry.
balance: Buffed tetrodotoxin a little against liver tolerance and
purging reagents.
/🆑
2024-10-09 02:03:50 +02:00

100 lines
3.5 KiB
Plaintext

/**
* A component that overrides the bubble_icon variable when equipped or implanted
* while having a simple priority system, so accessories have higher priority than
* organs, for example.
*/
/datum/component/bubble_icon_override
dupe_mode = COMPONENT_DUPE_ALLOWED
can_transfer = TRUE //sure why not
///The override to the default bubble icon for the atom
var/bubble_icon
///The priority of this bubble icon compared to others
var/priority
/datum/component/bubble_icon_override/Initialize(bubble_icon, priority)
if(!isclothing(parent) && !isorgan(parent))
return COMPONENT_INCOMPATIBLE
src.bubble_icon = bubble_icon
src.priority = priority
/datum/component/bubble_icon_override/RegisterWithParent()
if(isclothing(parent))
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equipped))
RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_dropped))
else if(isorgan(parent))
RegisterSignal(parent, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_organ_implanted))
RegisterSignal(parent, COMSIG_ORGAN_REMOVED, PROC_REF(on_organ_removed))
var/mob/living/target = get_bubble_icon_target()
if(target)
register_owner(target)
/datum/component/bubble_icon_override/proc/register_owner(mob/living/owner)
RegisterSignal(owner, COMSIG_GET_BUBBLE_ICON, PROC_REF(return_bubble_icon))
get_bubble_icon(owner)
/datum/component/bubble_icon_override/UnregisterFromParent()
UnregisterSignal(parent, list(
COMSIG_ITEM_EQUIPPED,
COMSIG_ITEM_DROPPED,
COMSIG_ORGAN_IMPLANTED,
COMSIG_ORGAN_REMOVED,
))
var/mob/living/target = get_bubble_icon_target()
if(target)
unregister_owner(target)
/datum/component/bubble_icon_override/proc/unregister_owner(mob/living/owner)
UnregisterSignal(owner, list(COMSIG_GET_BUBBLE_ICON))
get_bubble_icon(owner)
///Returns the potential wearer/owner of the object when the component is un/registered to/from it
/datum/component/bubble_icon_override/proc/get_bubble_icon_target()
if(isclothing(parent))
var/obj/item/clothing/clothing = parent
if(istype(clothing, /obj/item/clothing/accessory))
clothing = clothing.loc
if(!istype(clothing))
return null
var/mob/living/wearer = clothing.loc
if(istype(wearer) && (wearer.get_slot_by_item(clothing) & clothing.slot_flags))
return parent
else if(isorgan(parent))
var/obj/item/organ/organ = parent
return organ.owner
/datum/component/bubble_icon_override/proc/on_equipped(obj/item/source, mob/equipper, slot)
SIGNAL_HANDLER
if(slot & source.slot_flags)
register_owner(equipper)
/datum/component/bubble_icon_override/proc/on_dropped(obj/item/source, mob/dropper)
SIGNAL_HANDLER
unregister_owner(dropper)
/datum/component/bubble_icon_override/proc/on_organ_implanted(obj/item/organ/source, mob/owner)
SIGNAL_HANDLER
register_owner(owner)
/datum/component/bubble_icon_override/proc/on_organ_removed(obj/item/organ/source, mob/owner)
SIGNAL_HANDLER
unregister_owner(owner)
/**
* Get the bubble icon with the highest priority from all instances of bubble_icon_override
* currently registered with the target.
*/
/datum/component/bubble_icon_override/proc/get_bubble_icon(mob/living/target)
if(QDELETED(parent))
return
var/list/holder = list(null)
SEND_SIGNAL(target, COMSIG_GET_BUBBLE_ICON, holder)
var/bubble_icon = holder[1]
target.bubble_icon = bubble_icon || initial(target.bubble_icon)
/datum/component/bubble_icon_override/proc/return_bubble_icon(datum/source, list/holder)
SIGNAL_HANDLER
var/enemy_priority = holder[holder[1]]
if(enemy_priority < priority)
holder[1] = bubble_icon
holder[bubble_icon] = priority