Punishable by death in 7 sectors! Kronkaine buff package. (#90192)

## About The Pull Request

![kronkus_complete_ultimate](https://github.com/user-attachments/assets/c3288739-bf8d-47c7-8b61-65cf2c5bdded)

### Kronkus vine buffs:

Kronkus seeds are now three times as common.

The Kronkus vine has a greatly increased endurance stat(10->40) so it
does not die on you while you run around gathering ingredients and
matures quicker (8->6)

### Kronkaine buffs:

* The instant stamina boost restores **double stamina**(12 per u) when
injected or smoked.

* Now also restores stamina over time based on volume: **0.08 stamina
per unit each cycle**.

* Heart damage from kronkaine is now also dose dependant, overdose
damage has been adjusted to account for this.

* Reaction requires less ammonia(5->3u) and welding fuel(10->5u). 

* Added an alternate reaction that uses lye instead of ammonia, also
takes 3u.

* Added some new drug messages for when using these optimized methods of
administration.

* Reworked how the anti-purging mechanic works, now it only punishes you
with adrenal fatigue while you take >30 stamina damage while trying to
purge. This makes life saving OD treatment less annoying, but still
prevents abuse mid combat in a more elegant way.

The amount of heart damage inflicted is much lower if used at low doses,
the same as before at 20u and greater if more than 20u is administered.

The heart damage formula is : **0.1 + 0.04 * volume (+0.5 if overdosed)
damage per cycle**.

It should work out to something like a 27.5u lethal dose with a pristine
heart.



### Kronkus extract buffs:

Lasts twice as long.

More heart damage per cycle 0.1 -> 0.2. This value is still pretty
modest.

UPDATE: I had previously buffed the stamina regen of this reagent, but
now kronkaine itself has stamina regen per cycle.

#### Technical changes:

proc/copy_to can now trigger on_transfer and pass exposure methoid if
the new copy_method parameter is set.

This enables sources that use copy_to like smoke clouds to trigger
INHALE dependent effects like the new kronkaine enhancement.
Infinite hyposprays now also have the inject method like normal
hyposprays.

These two were the only two cases where reagents where reagents were
added to a mob using copy_to.

#### Fixes:
kronkus extracts heart damage now uses seconds_per_tick.

## Why It's Good For The Game

After surveying the available discussion on the subject, the kronkaine
drug itself seems to be generally well received.

However the rarity of the seed and the arcane preparation method has
limited player engagement with the mechanic.
There is confusion regarding both the preparation and, especially
regarding how the stamina restoring effect works.

This PR seeks to make things a little smoother and more pleasant without
making a rare thing into a trivial thing,.

Players seems to mostly use the action speed part of kronkaine so I have
massively buffed the stamina restoration part in a flavourful way to
encourage more types of players to plant the seeds should they find
them.

Over time more and more stuff have been added to the maintenance loot
spawn lists which have diluted the spawn chance of the seed packet which
contributes to the problem.

This PR increases the weight from 1 -> 3.

## Changelog

🆑
balance: kronkaine now restores double stamina when smoked or injected.
balance: kronkaine now restores stamina each cycle, the effect is dose
dependant.
balance: kronkaine now causes heart damage in a dose dependant manner,
instead of a flat value.
balance: kronkus seed packs are now three times as common.
balance: the kronkaine anti-purging disease now only triggers if you
take stamina damage while using purging chems.
balance: the kronkaine reaction uses less ammonia and welding fuel.
add: added an alternative kronkaine reaction that uses lye instead of
ammonia.
balance: kronkus extract now lasts twice as long but deals a bit more
heart damage(0.1->0.2)
balance: the kronkus vine plant is now a lot hardier(endurance: 10 ->
40) and matures a bit quicker.
tweak: kronkaine now warns the user more if it is about to kill your
heart.
fix: kronkus extract now inflicts heart damage correctly. 
/🆑
This commit is contained in:
Krysonism
2025-04-29 17:15:52 -06:00
committed by Shadow-Quill
parent 942b97a08f
commit 8a94c8f464
9 changed files with 73 additions and 24 deletions
+1 -1
View File
@@ -204,7 +204,7 @@ GLOBAL_LIST_INIT(uncommon_loot, list(//uncommon: useful items
/obj/item/beacon = 1,
/obj/item/paper/fluff/stations/soap = 1, //recipes count as crafting.
/obj/item/plaque = 1,
/obj/item/seeds/kronkus = 1,
/obj/item/seeds/kronkus = 3,
/obj/item/seeds/odious_puffball = 1,
/obj/item/stack/sheet/mineral/wood/fifty = 1,
/obj/item/stock_parts/power_store/cell/high = 1,
@@ -392,7 +392,7 @@
return FALSE
var/fraction = (seconds_per_tick SECONDS) / initial(lifetime)
reagents.copy_to(smoker, reagents.total_volume, fraction)
reagents.copy_to(smoker, reagents.total_volume, fraction, copy_methods = INHALE)
reagents.expose(smoker, INHALE, fraction)
return TRUE
+1 -1
View File
@@ -24,7 +24,7 @@
/obj/item/food/drug/moon_rock
name = "moon rock"
desc = "A small hard lump of kronkaine freebase.\nIt is said the average kronkaine addict causes as much criminal damage as four cat burglars, two arsonists and one rabid pit bull terrier combined."
desc = "A small hard lump of kronkaine freebase.\nIt is said the average kronkaine addict causes as much criminal damage as four cat burglars, two arsonists and one rabid pit bull terrier combined.\n\nNotorious in the medical community for causing dangerous interactions with purging meds!"
icon_state = "moon_rock1"
food_reagents = list(/datum/reagent/drug/kronkaine = 10)
+3 -4
View File
@@ -8,10 +8,9 @@
product = /obj/item/food/grown/kronkus
//shitty stats, because botany is easy
lifespan = 60
endurance = 10
maturation = 8
endurance = 40
maturation = 6
production = 4
yield = 3
growthstages = 3
growing_icon = 'icons/obj/service/hydroponics/growing.dmi'
reagents_add = list(/datum/reagent/consumable/nutriment = 0.05)
@@ -23,7 +22,7 @@
/obj/item/food/grown/kronkus
seed = /obj/item/seeds/kronkus
name = "kronkus vine segment"
desc = "A piece of mature kronkus vine. It exudes a sharp and noxious odor."
desc = "A piece of mature kronkus vine. It exudes a sharp and noxious odor.\n\nIt can be fermented to create a crude extract used by space-barge hobos to keep awake when the engine fumes creeps into their shacks.\n\nFurther processing is said to yield kronkaine, but infoteks regarding this subject are tightly controlled."
icon_state = "kronkus"
filling_color = "#37946e"
foodtypes = VEGETABLES | TOXIC
@@ -538,13 +538,15 @@
* * multiplier - multiplies each reagent amount by this number well byond their available volume before transfering. used to create reagents from thin air if you ever need to
* * preserve_data - preserve user data of all reagents after transfering
* * no_react - if TRUE will not handle reactions
* * copy_methods - forwards reagent exposure method flags like INGEST & INHALE to reagent.on_transfer to trigger transfer effects.
*/
/datum/reagents/proc/copy_to(
atom/target,
amount = 1,
multiplier = 1,
preserve_data = TRUE,
no_react = FALSE
no_react = FALSE,
copy_methods
)
if(QDELETED(target) || !total_volume)
return
@@ -578,6 +580,8 @@
if(preserve_data)
trans_data = copy_data(reagent)
transfered_amount = target_holder.add_reagent(reagent.type, transfer_amount, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT)
if(copy_methods && !no_react)
reagent.on_transfer(target, copy_methods, transfer_amount)
if(!transfered_amount)
continue
total_transfered_amount += transfered_amount
@@ -762,6 +762,15 @@
overdose_threshold = 50
addiction_types = list(/datum/addiction/maintenance_drugs = 35)
/*Kronkaine is a rare natural stimulant that can help you instantly clear stamina damage in combat,
but it also greatly aids civilians by letting them perform everyday actions like cleaning, building, pick pocketing and even performing surgery at double speed.
The main part of the stamina regeneration happens instantly once the reagent is added to the player and is doubled if smoked or injected.
After the initial burst of stamina, it also imparts stamina restoration per cycle.
The instant and gradual restoration effects as well as the heart damage are dose dependant, encouraging the player to push the limit of what is safe and reeasonable!
If you have at over 25u in your body you restore more than 20 stamina per cycle, enough to revive you from stamina crit, beware that this is a potentially fatal overdose!*/
/datum/reagent/drug/kronkaine
name = "Kronkaine"
description = "A highly illegal stimulant from the edge of the galaxy.\nIt is said the average kronkaine addict causes as much criminal damage as five stick up men, two rascals and one proferssional cambringo hustler combined."
@@ -789,43 +798,76 @@
. = ..()
kronkaine_fiend.add_actionspeed_modifier(/datum/actionspeed_modifier/kronkaine)
kronkaine_fiend.sound_environment_override = SOUND_ENVIRONMENT_HANGAR
SEND_SOUND(kronkaine_fiend, sound('sound/effects/health/fastbeat.ogg', repeat = TRUE, channel = CHANNEL_HEARTBEAT, volume = 30))
/datum/reagent/drug/kronkaine/on_mob_end_metabolize(mob/living/kronkaine_fiend)
. = ..()
kronkaine_fiend.remove_actionspeed_modifier(/datum/actionspeed_modifier/kronkaine)
kronkaine_fiend.sound_environment_override = NONE
//Stop the rapid heartneats, we make sure we are not in crit as to not mess with the heartbeats from organ/heart.
if(!kronkaine_fiend.stat)
kronkaine_fiend.stop_sound_channel(CHANNEL_HEARTBEAT)
/datum/reagent/drug/kronkaine/on_transfer(atom/kronkaine_receptacle, methods, trans_volume)
. = ..()
if(!iscarbon(kronkaine_receptacle))
return
var/mob/living/carbon/druggo = kronkaine_receptacle
if(druggo.adjustStaminaLoss(-6 * trans_volume, updating_stamina = FALSE))
//The drug is more effective if smoked or injected, restoring more stamina per unit.
var/stamina_heal_per_unit
if(methods & (INJECT|INHALE))
stamina_heal_per_unit = 12
if(trans_volume >= 3)
SEND_SOUND(druggo, sound('sound/items/weapons/flash_ring.ogg')) //The efffect is often refered to as the "kronkaine bells".
to_chat(druggo, span_danger("Your ears ring as your blood pressure suddenly spikes!"))
to_chat(druggo, span_nicegreen("You feel an amazing rush!"))
else if(prob(15))
to_chat(druggo, span_nicegreen(pick("You feel the cowardice melt away...", "You feel unbothered by the judgements of others.", "My life feels lovely!", "You lower your snout... and suddenly feel more charitable!")))
else
stamina_heal_per_unit = 6
if(druggo.adjustStaminaLoss(-stamina_heal_per_unit * trans_volume))
return UPDATE_MOB_HEALTH
//I wish i could give it some kind of bonus when smoked, but we don't have an INHALE method.
/datum/reagent/drug/kronkaine/on_mob_life(mob/living/carbon/kronkaine_fiend, seconds_per_tick, times_fired)
. = ..()
var/need_mob_update
kronkaine_fiend.add_mood_event("tweaking", /datum/mood_event/stimulant_medium)
if(kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
. = UPDATE_MOB_HEALTH
if(kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, (0.1 + 0.04 * volume) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
need_mob_update = UPDATE_MOB_HEALTH
if(kronkaine_fiend.get_organ_loss(ORGAN_SLOT_HEART) >= 75 && prob(15))
to_chat(kronkaine_fiend, span_userdanger("You feel like your heart is about to explode!"))
playsound(kronkaine_fiend, 'sound/effects/singlebeat.ogg', 200, TRUE)
kronkaine_fiend.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick)
kronkaine_fiend.AdjustSleeping(-2 SECONDS * REM * seconds_per_tick)
kronkaine_fiend.adjust_drowsiness(-10 SECONDS * REM * seconds_per_tick)
if(volume < 10)
return
for(var/possible_purger in kronkaine_fiend.reagents.reagent_list)
if(istype(possible_purger, /datum/reagent/medicine/c2/multiver) || istype(possible_purger, /datum/reagent/medicine/haloperidol))
kronkaine_fiend.ForceContractDisease(new /datum/disease/adrenal_crisis(), FALSE, TRUE) //We punish players for purging, since unchecked purging would allow players to reap the stamina healing benefits without any drawbacks. This also has the benefit of making haloperidol a counter, like it is supposed to be.
break
/* Do not try to cheese the overdose threshhold with purging chems to become stamina immune, if you purge and take stamina damage you will be punished!
The reason why I choose to add the adrenal crisis anti-cheese mechanic is because the main combat benefit is so front loaded, you could easily negate all the risk and downsides by mixing it with a small amount of a purger like haloperidol.
I think that level of safety goes against the design we would like achieve with drugs; great rewards but at the cost of great risk.*/
if(kronkaine_fiend.getStaminaLoss() > 30)
for(var/possible_purger in kronkaine_fiend.reagents.reagent_list)
if(istype(possible_purger, /datum/reagent/medicine/c2/multiver) || istype(possible_purger, /datum/reagent/medicine/haloperidol))
if(kronkaine_fiend.HasDisease(/datum/disease/adrenal_crisis))
break
kronkaine_fiend.visible_message(span_bolddanger("[kronkaine_fiend.name] suddenly tenses up, it looks like the shock is causing their body to shut down!"), span_userdanger("The sudden shock in combination with the cocktail of drugs and purgatives in your body makes your adrenal system go haywire. Uh oh!"))
kronkaine_fiend.ForceContractDisease(new /datum/disease/adrenal_crisis(), FALSE, TRUE) //We punish players for purging, since unchecked purging would allow players to reap the stamina healing benefits without any drawbacks. This also has the benefit of making haloperidol a counter, like it is supposed to be.
break
need_mob_update = kronkaine_fiend.adjustStaminaLoss(-0.8 * volume * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)
if(need_mob_update)
return UPDATE_MOB_HEALTH
/datum/reagent/drug/kronkaine/overdose_process(mob/living/kronkaine_fiend, seconds_per_tick, times_fired)
. = ..()
if(kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
if(kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
. = UPDATE_MOB_HEALTH
kronkaine_fiend.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick)
if(SPT_PROB(10, seconds_per_tick))
to_chat(kronkaine_fiend, span_danger(pick("You feel like your heart is going to explode!", "Your ears are ringing!", "You sweat like a pig!", "You clench your jaw and grind your teeth.", "You feel prickles of pain in your chest.")))
to_chat(kronkaine_fiend, span_danger(pick("Your heart is racing!", "Your ears are ringing!", "You sweat like a pig!", "You clench your jaw and grind your teeth.", "You feel prickles of pain in your chest.")))
/datum/reagent/drug/kronkaine/overdose_start(mob/living/affected_mob)
. = ..()
SEND_SOUND(affected_mob, sound('sound/effects/health/fastbeat.ogg', repeat = TRUE, channel = CHANNEL_HEARTBEAT, volume = 90))
///dirty kronkaine, aka gore. far worse overdose effects.
/datum/reagent/drug/kronkaine/gore
@@ -3169,13 +3169,14 @@
description = "A frothy extract made from fermented kronkus vine pulp.\nHighly bitter due to the presence of a variety of kronkamines."
taste_description = "bitterness"
color = "#228f63"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
addiction_types = list(/datum/addiction/stimulants = 5)
/datum/reagent/kronkus_extract/on_mob_life(mob/living/carbon/kronkus_enjoyer)
/datum/reagent/kronkus_extract/on_mob_life(mob/living/carbon/kronkus_enjoyer, seconds_per_tick)
. = ..()
var/need_mob_update
need_mob_update = kronkus_enjoyer.adjustOrganLoss(ORGAN_SLOT_HEART, 0.1)
need_mob_update = kronkus_enjoyer.adjustOrganLoss(ORGAN_SLOT_HEART, 0.2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)
need_mob_update += kronkus_enjoyer.adjustStaminaLoss(-6, updating_stamina = FALSE)
if(need_mob_update)
return UPDATE_MOB_HEALTH
@@ -123,7 +123,7 @@
//These drug item reactions should probably be converted to fermichem in the future.
/datum/chemical_reaction/moon_rock //botany is real easy so it requires a lot of kronkus_extract, make it cheaper if it doesnt get made.
required_reagents = list(/datum/reagent/kronkus_extract = 15, /datum/reagent/fuel = 10, /datum/reagent/ammonia = 5)
required_reagents = list(/datum/reagent/kronkus_extract = 15, /datum/reagent/fuel = 5, /datum/reagent/ammonia = 3)
mob_react = FALSE
reaction_flags = REACTION_INSTANT
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRUG | REACTION_TAG_ORGAN | REACTION_TAG_DAMAGING
@@ -135,6 +135,9 @@
new_rock.pixel_x = rand(-6, 6)
new_rock.pixel_y = rand(-6, 6)
/datum/chemical_reaction/moon_rock/draintek
required_reagents = list(/datum/reagent/kronkus_extract = 15, /datum/reagent/fuel = 5, /datum/reagent/lye = 3)
/datum/chemical_reaction/blastoff_ampoule
required_reagents = list(/datum/reagent/silver = 10, /datum/reagent/toxin/cyanide = 10, /datum/reagent/lye = 5)
mob_react = FALSE
@@ -55,7 +55,7 @@
trans = reagents.trans_to(affected_mob, amount_per_transfer_from_this, transferred_by = user, methods = INJECT)
else
reagents.expose(affected_mob, INJECT, fraction)
trans = reagents.copy_to(affected_mob, amount_per_transfer_from_this)
trans = reagents.copy_to(affected_mob, amount_per_transfer_from_this, copy_methods = INJECT)
to_chat(user, span_notice("[trans] unit\s injected. [reagents.total_volume] unit\s remaining in [src]."))
log_combat(user, affected_mob, "injected", src, "([contained])")
return TRUE