diff --git a/code/__DEFINES/melee.dm b/code/__DEFINES/melee.dm index 55240946de0..7d3e70a2284 100644 --- a/code/__DEFINES/melee.dm +++ b/code/__DEFINES/melee.dm @@ -10,6 +10,7 @@ #define MARTIALART_PSYCHOBRAWL "psychotic brawling" #define MARTIALART_SLEEPINGCARP "sleeping carp" #define MARTIALART_WRESTLING "wrestling" +#define MARTIALART_JUNGLEARTS "jungle arts" /// The number of hits required to crit a target #define HITS_TO_CRIT(damage) round(HUMAN_MAXHEALTH / damage, 0.1) // SKYRAT EDIT - changes the magic health number of 100 to HUMAN_MAXHEALTH. diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 000f77b7fd6..d2e366f87f9 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -207,6 +207,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NEVER_WOUNDED "never_wounded" /// Species with this trait have 50% extra chance of bleeding from piercing and slashing wounds #define TRAIT_EASYBLEED "easybleed" +/// Mob recovers from addictions at an accelerated rate +#define TRAIT_ADDICTIONRESILIENT "addiction_resilient" #define TRAIT_TOXINLOVER "toxinlover" /// Doesn't get overlays from being in critical. #define TRAIT_NOCRITOVERLAY "no_crit_overlay" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 456d9e81cef..97c7d951e75 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -158,6 +158,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ACT_AS_CULTIST" = TRAIT_ACT_AS_CULTIST, "TRAIT_ACT_AS_HERETIC" = TRAIT_ACT_AS_HERETIC, "TRAIT_ADAMANTINE_EXTRACT_ARMOR" = TRAIT_ADAMANTINE_EXTRACT_ARMOR, + "TRAIT_ADDICTIONRESILIENT" = TRAIT_ADDICTIONRESILIENT, "TRAIT_ADVANCEDTOOLUSER" = TRAIT_ADVANCEDTOOLUSER, "TRAIT_AGENDER" = TRAIT_AGENDER, "TRAIT_AGEUSIA" = TRAIT_AGEUSIA, diff --git a/code/datums/martial/junglearts.dm b/code/datums/martial/junglearts.dm new file mode 100644 index 00000000000..475ebe1cc11 --- /dev/null +++ b/code/datums/martial/junglearts.dm @@ -0,0 +1,84 @@ +/datum/martial_art/jungle_arts + name = "Jungle Arts" + id = MARTIALART_JUNGLEARTS + pacifist_style = TRUE + +/datum/martial_art/jungle_arts/disarm_act(mob/living/attacker, mob/living/defender) + return jungle_attack(attacker, defender) + +/datum/martial_art/jungle_arts/grab_act(mob/living/attacker, mob/living/defender) + return jungle_attack(attacker, defender, TRUE) + +/datum/martial_art/jungle_arts/harm_act(mob/living/attacker, mob/living/defender) + return jungle_attack(attacker, defender) + +/datum/martial_art/jungle_arts/proc/jungle_attack(mob/living/attacker, mob/living/defender, grab_attack) + var/atk_verb + switch(rand(1,6)) + if(1) + atk_verb = "dragged" + var/obj/item/organ/tail/tail = attacker.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) + if(isnull(tail) && defender.stat != CONSCIOUS || defender.IsParalyzed()) + return MARTIAL_ATTACK_INVALID + + attacker.do_attack_animation(defender, ATTACK_EFFECT_CLAW) + attacker.emote("spin") + defender.visible_message( + span_danger("[attacker]'s tail [atk_verb] [defender] down to the ground!"), + span_userdanger("Your body twists as you're [atk_verb] to the ground by [attacker]'s tail!"), + span_hear("You hear a snap, followed by a thud!"), + null, + attacker, + ) + to_chat(attacker, span_danger("You latch your tail to [defender], [atk_verb] them to the ground!")) + defender.apply_damage(rand(5, 10), attacker.get_attack_type()) + playsound(attacker, 'sound/items/weapons/whip.ogg', 50, TRUE, -1) + defender.Knockdown(2 SECONDS) + if(HAS_TRAIT(attacker, TRAIT_PACIFISM)) + attacker.add_mood_event("bypassed_pacifism", /datum/mood_event/pacifism_bypassed) + + if(6) + var/obj/item/organ/tail/tail = attacker.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) + if(isnull(tail)) + return MARTIAL_ATTACK_INVALID + + atk_verb = pick("whipped", "flogged", "lashed") + attacker.do_attack_animation(defender, ATTACK_EFFECT_CLAW) + defender.visible_message( + span_danger("[attacker]'s tail [atk_verb] [defender] in one quick motion!"), + span_userdanger("You feel a sharp sting as you're [atk_verb] by [attacker]!"), + span_hear("You hear a sharp whipping noise!"), + null, + attacker, + ) + to_chat(attacker, span_danger("In one motion, you [atk_verb] [defender] quickly!")) + defender.apply_damage(rand(10, 15), attacker.get_attack_type()) + playsound(attacker, 'sound/items/weapons/whip.ogg', 50, TRUE, -1) + defender.drop_all_held_items() + if(HAS_TRAIT(attacker, TRAIT_PACIFISM)) + attacker.add_mood_event("bypassed_pacifism", /datum/mood_event/pacifism_bypassed) + + else + atk_verb = pick("chomp", "gnaw", "chew") + if(defender.check_block(attacker, 0, "[attacker]'s [atk_verb]", UNARMED_ATTACK)) + return MARTIAL_ATTACK_FAIL + + attacker.do_attack_animation(defender, ATTACK_EFFECT_BITE) + defender.visible_message( + span_danger("[attacker] [atk_verb]s [defender] violently!"), + span_userdanger("You're viciously [atk_verb]ed by [attacker]!"), + span_hear("You hear a violent gnawing sound!"), + null, + attacker, + ) + to_chat(attacker, span_danger("You [atk_verb] [defender] with vicious force!")) + defender.apply_damage(rand(10, 20), damagetype = BRUTE, sharpness = SHARP_POINTY, wound_bonus = 50) + playsound(attacker, 'sound/items/weapons/bite.ogg', 50, TRUE, -1) + if(HAS_TRAIT(attacker, TRAIT_PACIFISM)) + attacker.add_mood_event("bypassed_pacifism", /datum/mood_event/pacifism_bypassed) + + if(atk_verb) + log_combat(attacker, defender, "[atk_verb] (Jungle Arts)") + return MARTIAL_ATTACK_SUCCESS + + return MARTIAL_ATTACK_FAIL diff --git a/code/datums/mood_events/drug_events.dm b/code/datums/mood_events/drug_events.dm index ad248ea7336..8ff18dd7dcd 100644 --- a/code/datums/mood_events/drug_events.dm +++ b/code/datums/mood_events/drug_events.dm @@ -85,6 +85,16 @@ mood_change = 9 timeout = 3 MINUTES +/datum/mood_event/antinarcotic_medium + description = "I wish I was numb again!" + mood_change = -4 + timeout = 3 MINUTES + +/datum/mood_event/antinarcotic_heavy + description = "NO!! Make the cotton come back!" + mood_change = -9 + timeout = 3 MINUTES + /datum/mood_event/stimulant_medium description = "I have so much energy! I feel like I could do anything!" mood_change = 4 @@ -124,3 +134,8 @@ description = "I feel my soul degrading!" mood_change = -8 timeout = 8 MINUTES + +/datum/mood_event/sadness_inverse + description = "I'M SO SAD..." + mood_change = -150 + special_screen_obj = "mood_happiness_bad" diff --git a/code/game/objects/effects/particles/smoke.dm b/code/game/objects/effects/particles/smoke.dm index cc4fec35839..323e4ffbdce 100644 --- a/code/game/objects/effects/particles/smoke.dm +++ b/code/game/objects/effects/particles/smoke.dm @@ -37,6 +37,13 @@ spawning = 2 velocity = list(0, 0.25, 0) +/particles/smoke/steam/mald + icon_state = list("steam_1" = 1, "steam_2" = 1, "steam_3" = 2) + velocity = list(0, 0.25, 0) + lifespan = 1 SECONDS + fade = 0.5 SECONDS + position = list(-1, 12, 0) + /particles/smoke/cig icon_state = list("steam_1" = 2, "steam_2" = 1, "steam_3" = 1) count = 1 diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 5518722475f..4f373c2cf9d 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -105,6 +105,8 @@ overdose_threshold = 20 ph = 9 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + inverse_chem_val = 0.3 + inverse_chem = /datum/reagent/inverse/krokodil addiction_types = list(/datum/addiction/opioids = 18) //7.2 per 2 seconds /datum/reagent/drug/krokodil/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) @@ -203,6 +205,8 @@ color = "#FAFAFA" overdose_threshold = 20 taste_description = "salt" // because they're bathsalts? + inverse_chem_val = 0.3 + inverse_chem = /datum/reagent/inverse/bath_salts addiction_types = list(/datum/addiction/stimulants = 25) //8 per 2 seconds ph = 8.2 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED @@ -253,6 +257,8 @@ description = "Amps you up, gets you going, and rapidly restores stamina damage. Side effects include breathlessness and toxicity." color = "#78FFF0" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + inverse_chem_val = 0.5 + inverse_chem = /datum/reagent/inverse/aranesp addiction_types = list(/datum/addiction/stimulants = 8) metabolized_traits = list(TRAIT_STIMULATED) @@ -277,6 +283,8 @@ overdose_threshold = 20 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED taste_description = "paint thinner" + inverse_chem_val = 0.4 + inverse_chem = /datum/reagent/inverse/happiness addiction_types = list(/datum/addiction/hallucinogens = 18) metabolized_traits = list(TRAIT_FEARLESS, TRAIT_ANALGESIA) diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm index c0b7667ac65..0fc7a3d26d7 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm @@ -937,3 +937,412 @@ Basically, we fill the time between now and 2s from now with hands based off the metabolization_rate = 0.1 * REM tox_damage = 0 metabolized_traits = list(TRAIT_IMMUNODEFICIENCY) + +/datum/reagent/inverse/krokodil + name = "Permonid" + description = "Highly potent sedative that provides the best benefits for pain management and surgery. Extremely addictive." + color = "#15b5dd55" + metabolization_rate = 0.1 * REM + overdose_threshold = 20 + ph = 2.5 + addiction_types = list(/datum/addiction/opioids = 30) + metabolized_traits = list(TRAIT_ANALGESIA) + tox_damage = 0 + +/datum/reagent/inverse/krokodil/expose_mob(mob/living/carbon/exposed_carbon, methods=TOUCH, reac_volume) + . = ..() + if(!(methods & (TOUCH|VAPOR|PATCH))) + return + + for(var/datum/surgery/surgery as anything in exposed_carbon.surgeries) + surgery.speed_modifier = max(0.3, surgery.speed_modifier) + +/datum/reagent/inverse/krokodil/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + affected_mob.add_mood_event("smacked out", /datum/mood_event/narcotic_heavy) + +/datum/reagent/inverse/krokodil/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() + affected_mob.set_jitter_if_lower(10 SECONDS) + affected_mob.set_dizzy_if_lower(5 SECONDS) + if(SPT_PROB(10, seconds_per_tick)) + affected_mob.emote("drool") + if(SPT_PROB(5, seconds_per_tick)) + to_chat(affected_mob, span_warning("You briefly lose control of your legs!")) + affected_mob.Knockdown(5 SECONDS) + if(SPT_PROB(5, seconds_per_tick)) + to_chat(affected_mob, span_warning("The muscles in your arms give out!")) + affected_mob.drop_all_held_items() + +/datum/reagent/inverse/bath_salts + name = "Monkey Dust" + description = "Oop aak chee aak eek chee. Eek aak oop chee oop aak aak!!" + color = "#7e3900" + ph = 14 + metabolization_rate = 0.2 * REM + tox_damage = 0 + /// The martial art we teach (to monkies) + var/datum/martial_art/jungle_arts/jungle_arts + +/datum/reagent/inverse/bath_salts/on_mob_metabolize(mob/living/carbon/affected_mob) + . = ..() + if(is_simian(affected_mob)) + affected_mob.gain_trauma(/datum/brain_trauma/special/primal_instincts, TRAUMA_RESILIENCE_ABSOLUTE) + affected_mob.add_traits(list(TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE, TRAIT_ANALGESIA, TRAIT_STIMULATED), type) + jungle_arts = new(src) + jungle_arts.locked_to_use = TRUE + jungle_arts.teach(affected_mob) + +/datum/reagent/inverse/bath_salts/on_mob_end_metabolize(mob/living/carbon/affected_mob) + . = ..() + QDEL_NULL(jungle_arts) + if(is_simian(affected_mob)) + affected_mob.cure_trauma_type(/datum/brain_trauma/special/primal_instincts, resilience = TRAUMA_RESILIENCE_ABSOLUTE) + affected_mob.remove_traits(list(TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE, TRAIT_ANALGESIA, TRAIT_STIMULATED), type) + affected_mob.Sleeping(30 SECONDS) + +/datum/reagent/inverse/bath_salts/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(holder.has_reagent(/datum/reagent/drug/bath_salts)) + holder.remove_reagent(type, volume) + return + + if(is_simian(affected_mob)) + var/need_mob_update + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + + if(holder.has_reagent(/datum/reagent/consumable/monkey_energy)) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + + if(need_mob_update) + . = UPDATE_MOB_HEALTH + + else if(SPT_PROB(10, seconds_per_tick)) + affected_mob.emote(pick("screech","scratch","jump","look")) + +/datum/reagent/inverse/aranesp + name = "Epoetin Alfa" + description = "Synthetic medication that induces blood regeneration, liver healing and wound clotting in patients. Causes adverse side effects when excessively used over time." + color = "#dee4ff" + metabolization_rate = 0.25 * REM + overdose_threshold = 20 + ph = 6.1 + tox_damage = 0 + +/datum/reagent/inverse/aranesp/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(overdosed) + return + var/need_mob_update + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, -1 * REM * seconds_per_tick) + for(var/datum/wound/iter_wound as anything in affected_mob.all_wounds) + if(iter_wound.blood_flow) + if(holder.has_reagent(/datum/reagent/medicine/coagulant, 3)) + return + else + holder.add_reagent(/datum/reagent/medicine/coagulant, 0.2 * REM * seconds_per_tick) + + if(affected_mob.blood_volume < BLOOD_VOLUME_NORMAL) + need_mob_update += affected_mob.blood_volume += min(3 * seconds_per_tick, BLOOD_VOLUME_NORMAL) + + switch(current_cycle) + if(10) + to_chat(affected_mob, span_warning("You feel a migraine coming on...")) + affected_mob.adjust_eye_blur(2 SECONDS * REM * seconds_per_tick) + + if(15 to 30) + if(SPT_PROB(5, seconds_per_tick)) + to_chat(affected_mob, span_warning("Your head aches as your vision blurs.")) + affected_mob.adjust_eye_blur(5 SECONDS * REM * seconds_per_tick) + if(SPT_PROB(5, seconds_per_tick)) + to_chat(affected_mob, span_warning("Your face contorts as a sudden pain forms in your head.")) + affected_mob.Stun(1 SECONDS) + + if(31 to 45) + if(SPT_PROB(5, seconds_per_tick)) + to_chat(affected_mob, span_warning("Intense pressure forms in your head, you can barely see!")) + affected_mob.adjust_eye_blur(10 SECONDS * REM * seconds_per_tick) + affected_mob.adjust_confusion_up_to(5 SECONDS, 20 SECONDS) + affected_mob.adjust_hallucinations(10 SECONDS) + if(SPT_PROB(5, seconds_per_tick)) + to_chat(affected_mob, span_warning("You lose focus and stare ahead.")) + affected_mob.Stun(3 SECONDS) + affected_mob.emote(pick("stare","drool","moan","look")) + if(SPT_PROB(5, seconds_per_tick)) + to_chat(affected_mob, span_warning("Your inhaling becomes more stressed, it's getting harder to breathe!")) + holder.add_reagent(/datum/reagent/toxin/histamine, 4 * REM * seconds_per_tick) + + if(46 to INFINITY) + if(SPT_PROB(5, seconds_per_tick)) + to_chat(affected_mob, span_warning("It feels like your head is going to implode!")) + affected_mob.adjust_eye_blur(10 SECONDS * REM * seconds_per_tick) + affected_mob.adjust_confusion_up_to(10 SECONDS, 20 SECONDS) + affected_mob.adjust_hallucinations(30 SECONDS) + if(SPT_PROB(5, seconds_per_tick)) + to_chat(affected_mob, span_warning("You can't bring yourself to focus at all!")) + affected_mob.Stun(5 SECONDS) + affected_mob.emote(pick("stare","drool","tremble","shake")) + if(SPT_PROB(5, seconds_per_tick)) + to_chat(affected_mob, span_warning("Your breathing becomes weak and raspy, you can barely stay conscious!")) + holder.add_reagent(/datum/reagent/toxin/histamine, 6 * REM * seconds_per_tick) + affected_mob.losebreath += 3 + need_mob_update = TRUE + + if(need_mob_update) + return UPDATE_MOB_HEALTH + +/datum/reagent/inverse/aranesp/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update + if(SPT_PROB(10, seconds_per_tick)) + to_chat(affected_mob, span_warning("It feels like your head is going to implode!")) + affected_mob.adjust_eye_blur(10 SECONDS * REM * seconds_per_tick) + affected_mob.adjust_confusion_up_to(10 SECONDS, 20 SECONDS) + affected_mob.adjust_hallucinations(30 SECONDS) + if(SPT_PROB(10, seconds_per_tick)) + to_chat(affected_mob, span_warning("You can't bring yourself to focus at all!")) + affected_mob.Stun(50) + affected_mob.emote(pick("stare","drool","tremble","shake")) + if(SPT_PROB(10, seconds_per_tick)) + to_chat(affected_mob, span_warning("Your breathing becomes weak and raspy, you can barely stay conscious!")) + holder.add_reagent(/datum/reagent/toxin/histamine, 6 * REM * seconds_per_tick) + affected_mob.losebreath += 3 + need_mob_update = TRUE + + if(need_mob_update) + return UPDATE_MOB_HEALTH + +/datum/reagent/inverse/happiness + name = "Sadness" + description = "Causes severe depressive behavior in users, and actively purges other antidepressants." + color = "#0004ff" + ph = 12 + metabolization_rate = 0.1 * REM + tox_damage = 0 + penetrates_skin = TOUCH|VAPOR + +/datum/reagent/inverse/happiness/on_mob_metabolize(mob/living/carbon/affected_mob) + . = ..() + affected_mob.add_mood_event("sadness_inverse", /datum/mood_event/sadness_inverse) + switch(volume) + if(1 to INFINITY) // prevents microdosing from repeating this line + affected_mob.say("What?? No... NO...", forced = type) + +/datum/reagent/inverse/happiness/on_mob_end_metabolize(mob/living/carbon/affected_mob) + . = ..() + affected_mob.clear_mood_event("sadness_inverse") + +/datum/reagent/inverse/happiness/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) + . = ..() + if(methods & (TOUCH|VAPOR)) + exposed_mob.emote("cry") + return + +/datum/reagent/inverse/happiness/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(affected_mob.mob_mood?.has_mood_of_category("friendly_hug") && !HAS_TRAIT(affected_mob, TRAIT_BADTOUCH)) + holder.remove_reagent(type, volume) + return + + holder.remove_reagent(/datum/reagent/drug/happiness, 5 * REM * seconds_per_tick) + holder.remove_reagent(/datum/reagent/medicine/psicodine, 5 * REM * seconds_per_tick) + + affected_mob.mob_mood.adjust_sanity(-7.5 * REM * seconds_per_tick, minimum = SANITY_INSANE) + if(affected_mob.mob_mood != null && affected_mob.mob_mood.sanity < (SANITY_CRAZY)) + affected_mob.adjust_drowsiness_up_to(5 SECONDS, 30 SECONDS) + if(SPT_PROB(25, seconds_per_tick)) + affected_mob.emote(pick("cry","frown","pout","whimper","sigh")) + if(SPT_PROB(3, seconds_per_tick)) + affected_mob.say(pick("Why are we still here? Just to suffer?","To live is to suffer!","Life is suffering. It is the nature of existence!","Each day we wake up is another day closer to death.","Sometimes I can hear my bones straining under the weight of all the lives I'm not living.","There are no beautiful surfaces without a terrible depth."), forced = type) + +/datum/reagent/inverse/baldium + name = "Maldium" + description = "Potent psychotropic that causes intense anger within users." + color = "#ff0000" + ph = 1 + metabolization_rate = 0.4 * REM + tox_damage = 0 + var/delayed_burn_damage = 0 + +/datum/reagent/inverse/baldium/on_mob_metabolize(mob/living/carbon/affected_mob) + . = ..() + affected_mob.add_shared_particles(/particles/smoke/steam/mald) + affected_mob.manual_emote("inhales sharply.") + to_chat(affected_mob, span_warning("You can't help but find everything more irritating.")) + +/datum/reagent/inverse/baldium/on_mob_end_metabolize(mob/living/carbon/affected_mob) + . = ..() + affected_mob.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#fe0000") + affected_mob.remove_shared_particles(/particles/smoke/steam/mald) + affected_mob.manual_emote("exhales sharply.") + to_chat(affected_mob, span_warning("You feel an intense burning sensation as your anger subsides!")) + +/datum/reagent/inverse/baldium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + delayed_burn_damage += (seconds_per_tick * 1) + if(holder.has_reagent(/datum/reagent/consumable/salt)) + holder.remove_reagent(/datum/reagent/inverse/baldium, 3 * REM * seconds_per_tick) + holder.remove_reagent(/datum/reagent/consumable/salt, 1 * REM * seconds_per_tick) + + switch(current_cycle) + if(5) + affected_mob.add_atom_colour("#fe0000", TEMPORARY_COLOUR_PRIORITY) + if(!HAS_TRAIT(affected_mob, TRAIT_PACIFISM)) + var/turf/angery_blast = get_turf(affected_mob) + goonchem_vortex(angery_blast, 1, 4) + to_chat(affected_mob, span_warning("You can't control yourself as you yell out ANGRILY!!")) + affected_mob.emote("scream") + affected_mob.say(pick("RAGE!! UNLEASH THE RAGE!!","I'M SO ANGRY!!","WHY I OUGHTA...","AAARRRGGHH!!"), forced = type) + else + to_chat(affected_mob, span_warning("You calmly yet firmly state your discontent.")) + affected_mob.say(pick("Aaahhhh...","Rage, woo yeah...","I'm slightly upset...",), forced = type) + + if(6 to INFINITY) + if(SPT_PROB(10, seconds_per_tick)) + affected_mob.manual_emote(pick("breathes rapidly!","huffs, and puffs...","stares MENACINGLY!","sighs AGGRESSIVELY!","sheds a tear ANGRILY!")) + +/datum/reagent/inverse/baldium/on_mob_delete(mob/living/affected_mob) + . = ..() + affected_mob.log_message("has taken [delayed_burn_damage] burn damage from maldium's aftereffects", LOG_ATTACK) + affected_mob.adjustFireLoss(delayed_burn_damage, updating_health = TRUE, required_bodytype = affected_bodytype) + +/datum/reagent/inverse/colorful_reagent + name = "Dulling Reagent" + description = "Extremely drab coloring pigment that is favored by corporations who wish to maximize suffering." + color = COLOR_GRAY + ph = 10 + metabolization_rate = 0.4 * REM + tox_damage = 0 + /// Whenever this reagent can color mob limbs and organs upon exposure + var/can_color_mobs = TRUE + /// Whenever this reagent can color mob equipment when they're exposed to it externally + var/can_color_clothing = TRUE + /// Whenever this reagent can color mob organs when taken internally, false by default as this would cause chaotic flickering of victim's eyes + var/can_color_organs = FALSE + /// Stores the original color after reagent wears off + var/datum/callback/color_callback + /// Used when applying colors on valid things + var/list/random_color_list = list("#1a1a1a","#2e2e2e","#424242","#565656","#6a6a6a","#7e7e7e","#929292","#a6a6a6","#bababa","#cecece") + +/datum/reagent/inverse/colorful_reagent/on_mob_metabolize(mob/living/carbon/affected_mob) + . = ..() + affected_mob.gain_trauma(/datum/brain_trauma/mild/color_blindness, TRAUMA_RESILIENCE_ABSOLUTE) + +/datum/reagent/inverse/colorful_reagent/on_mob_end_metabolize(mob/living/carbon/affected_mob) + . = ..() + affected_mob.cure_trauma_type(/datum/brain_trauma/mild/color_blindness, resilience = TRAUMA_RESILIENCE_ABSOLUTE) + +/datum/reagent/inverse/colorful_reagent/overdose_start(mob/living/affected_mob) + . = ..() + metabolization_rate = 0.04 * REM + +/datum/reagent/inverse/colorful_reagent/New() + color_callback = CALLBACK(src, PROC_REF(UpdateColor)) + SSticker.OnRoundstart(color_callback) + return ..() + +/datum/reagent/inverse/colorful_reagent/Destroy() + LAZYREMOVE(SSticker.round_end_events, color_callback) + color_callback = null + return ..() + +/datum/reagent/inverse/colorful_reagent/proc/UpdateColor() + color_callback = null + color = pick(random_color_list) + +/datum/reagent/inverse/colorful_reagent/expose_mob(mob/living/exposed_mob, methods, reac_volume, show_message, touch_protection) + . = ..() + var/picked_color = pick(random_color_list) + var/color_filter = color_transition_filter(picked_color, SATURATION_OVERRIDE) + if (can_color_clothing && (methods & (TOUCH|VAPOR|INHALE))) + var/include_flags = INCLUDE_HELD|INCLUDE_ACCESSORIES + if (methods & (VAPOR|INHALE) || touch_protection >= 1) + include_flags |= INCLUDE_POCKETS + for (var/obj/item/to_color in exposed_mob.get_equipped_items(include_flags)) + to_color.add_atom_colour(color_filter, WASHABLE_COLOUR_PRIORITY) + + if (ishuman(exposed_mob)) + var/mob/living/carbon/human/exposed_human = exposed_mob + exposed_human.set_facial_haircolor(picked_color, update = FALSE) + exposed_human.set_haircolor(picked_color) + + if (!can_color_mobs) + return + + if (!iscarbon(exposed_mob)) + exposed_mob.add_atom_colour(color_filter, WASHABLE_COLOUR_PRIORITY) + return + + var/mob/living/carbon/exposed_carbon = exposed_mob + + for (var/obj/item/organ/organ as anything in exposed_carbon.organs) + organ.add_atom_colour(color_filter, WASHABLE_COLOUR_PRIORITY) + + for (var/obj/item/bodypart/part as anything in exposed_carbon.bodyparts) + part.add_atom_colour(color_filter, WASHABLE_COLOUR_PRIORITY) + +/datum/reagent/inverse/colorful_reagent/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + + if (!iscarbon(affected_mob)) + if (can_color_mobs) + affected_mob.add_atom_colour(color_transition_filter(pick(random_color_list), SATURATION_OVERRIDE), WASHABLE_COLOUR_PRIORITY) + return + + if(!can_color_organs) + return + + var/mob/living/carbon/carbon_mob = affected_mob + var/color_priority = WASHABLE_COLOUR_PRIORITY + if (current_cycle >= 30) + color_priority = FIXED_COLOUR_PRIORITY + + for (var/obj/item/organ/organ as anything in carbon_mob.organs) + organ.add_atom_colour(color_transition_filter(pick(random_color_list), SATURATION_OVERRIDE), color_priority) + +/datum/reagent/inverse/colorful_reagent/expose_atom(atom/exposed_atom, reac_volume) + . = ..() + if(!isliving(exposed_atom)) + exposed_atom.add_atom_colour(color_transition_filter(pick(random_color_list), SATURATION_OVERRIDE), WASHABLE_COLOUR_PRIORITY) + +/datum/reagent/inverse/gravitum + name = "Newtonium" + description = "Experimental reagent that induces heavy gravokinetic effects on users." + color = "#4b0082" + ph = 2.3 + metabolization_rate = 1 * REM + overdose_threshold = 30 + tox_damage = 0 + +/datum/reagent/inverse/gravitum/on_mob_metabolize(mob/living/affected_mob) + . = ..() + affected_mob.AddElement(/datum/element/forced_gravity, gravity = 5, ignore_turf_gravity = TRUE, can_override = FALSE) + +/datum/reagent/inverse/gravitum/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() + affected_mob.RemoveElement(/datum/element/forced_gravity, gravity = 5, ignore_turf_gravity = TRUE, can_override = FALSE) + +/datum/reagent/inverse/gravitum/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + + switch(current_cycle) + if(10) + for(var/obj/item/bodypart/leg/leg in affected_mob.bodyparts) + affected_mob.cause_wound_of_type_and_severity(WOUND_BLUNT, leg, WOUND_SEVERITY_MODERATE) + to_chat(affected_mob, span_warning("Your legs start to cave in to your overwhelming gravity!")) + + if(20) + for(var/obj/item/bodypart/leg/leg in affected_mob.bodyparts) + affected_mob.cause_wound_of_type_and_severity(WOUND_BLUNT, leg, WOUND_SEVERITY_SEVERE) + to_chat(affected_mob, span_warning("Your bones fragment horribly as the gravity pounds on you!")) + + if(30) + for(var/obj/item/bodypart/leg/leg in affected_mob.bodyparts) + affected_mob.cause_wound_of_type_and_severity(WOUND_BLUNT, leg, WOUND_SEVERITY_CRITICAL) + to_chat(affected_mob, span_warning("The gravity of this situation makes your bones snap like popsicle sticks!")) + +/datum/reagent/inverse/gravitum/overdose_start(mob/living/carbon/affected_mob) + . = ..() + affected_mob.AddElement(/datum/element/squish, 120 SECONDS) + for(var/obj/item/bodypart/leg/leg in affected_mob.bodyparts) + affected_mob.cause_wound_of_type_and_severity(WOUND_SLASH, leg, WOUND_SEVERITY_SEVERE) diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index ecd84c27776..350ba0f073d 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -1845,3 +1845,38 @@ if(affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE)) . = UPDATE_MOB_HEALTH affected_mob.adjust_disgust(-10 * REM * seconds_per_tick) + +/datum/reagent/medicine/naloxone + name = "Naloxone" + description = "Opioid antagonist that purges drowsiness and narcotics from the patient, restores breath loss and accelerates addiction recovery." + color = "#f5f5dc" + metabolization_rate = 0.2 * REM + ph = 4 + penetrates_skin = TOUCH|VAPOR + chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + metabolized_traits = list(TRAIT_ADDICTIONRESILIENT) + var/static/list/opiates_to_clear = list( + /datum/reagent/medicine/morphine, + /datum/reagent/impedrezene, + /datum/reagent/toxin/fentanyl, + /datum/reagent/drug/krokodil, + /datum/reagent/inverse/krokodil, + ) + +/datum/reagent/medicine/naloxone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + for(var/opiate in opiates_to_clear) + holder.remove_reagent(opiate, 3 * REM * seconds_per_tick) + + if(affected_mob.mob_mood?.get_mood_event("numb")) + affected_mob.clear_mood_event("numb") + affected_mob.add_mood_event("not numb", /datum/mood_event/antinarcotic_medium) + + if(affected_mob.mob_mood?.get_mood_event("smacked out")) + affected_mob.clear_mood_event("smacked out") + affected_mob.add_mood_event("not smacked out", /datum/mood_event/antinarcotic_heavy) + + affected_mob.adjust_drowsiness(-5 SECONDS * REM * seconds_per_tick) + if(affected_mob.losebreath >= 1) + affected_mob.losebreath -= 1 * REM * seconds_per_tick + return UPDATE_MOB_HEALTH diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index d8b7d1ac039..e043aac636b 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -2143,6 +2143,8 @@ color = COLOR_GRAY taste_description = "rainbows" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + inverse_chem_val = 0.3 + inverse_chem = /datum/reagent/inverse/colorful_reagent /// Whenever this reagent can color mob limbs and organs upon exposure var/can_color_mobs = TRUE /// Whenever this reagent can color mob equipment when they're exposed to it externally @@ -2329,6 +2331,8 @@ taste_description = "bitterness" penetrates_skin = NONE chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + inverse_chem_val = 0.3 + inverse_chem = /datum/reagent/inverse/baldium /datum/reagent/baldium/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection = 0) . = ..() @@ -2811,6 +2815,8 @@ taste_mult = 0 // oderless and tasteless metabolization_rate = 0.1 * REAGENTS_METABOLISM //20 times as long, so it's actually viable to use var/time_multiplier = 1 MINUTES //1 minute per unit of gravitum on objects. Seems overpowered, but the whole thing is very niche + inverse_chem_val = 0.3 + inverse_chem = /datum/reagent/inverse/gravitum chemical_flags = REAGENT_CAN_BE_SYNTHESIZED self_consuming = TRUE //this works on objects, so it should work on skeletons and robots too diff --git a/code/modules/reagents/chemistry/recipes/drugs.dm b/code/modules/reagents/chemistry/recipes/drugs.dm index 47917ac326b..531b8b4ba40 100644 --- a/code/modules/reagents/chemistry/recipes/drugs.dm +++ b/code/modules/reagents/chemistry/recipes/drugs.dm @@ -81,6 +81,7 @@ results = list(/datum/reagent/drug/bath_salts = 7) required_reagents = list(/datum/reagent/toxin/bad_food = 1, /datum/reagent/saltpetre = 1, /datum/reagent/consumable/nutriment = 1, /datum/reagent/space_cleaner = 1, /datum/reagent/consumable/enzyme = 1, /datum/reagent/consumable/tea = 1, /datum/reagent/mercury = 1) required_temp = 374 + reaction_flags = REACTION_CLEAR_INVERSE reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRUG | REACTION_TAG_ORGAN | REACTION_TAG_DAMAGING /datum/chemical_reaction/aranesp @@ -92,6 +93,7 @@ results = list(/datum/reagent/drug/happiness = 4) required_reagents = list(/datum/reagent/nitrous_oxide = 2, /datum/reagent/medicine/epinephrine = 1, /datum/reagent/consumable/ethanol = 1) required_catalysts = list(/datum/reagent/toxin/plasma = 5) + reaction_flags = REACTION_CLEAR_INVERSE reaction_tags = REACTION_TAG_EASY | REACTION_TAG_DRUG | REACTION_TAG_ORGAN | REACTION_TAG_DAMAGING /datum/chemical_reaction/pumpup diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index 8704a19778c..07d81164906 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -388,3 +388,8 @@ required_catalysts = list(/datum/reagent/consumable/ethanol = 3) optimal_ph_max = 11 reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_OTHER | REACTION_TAG_DRUG + +/datum/chemical_reaction/medicine/naloxone + results = list(/datum/reagent/medicine/naloxone = 4) + required_reagents = list(/datum/reagent/medicine/morphine = 1, /datum/reagent/hydrogen_peroxide = 1, /datum/reagent/bromine = 1, /datum/reagent/consumable/ethanol = 1) + reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_OTHER diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index 1af5de87161..fe730392394 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -537,6 +537,7 @@ /datum/chemical_reaction/colorful_reagent results = list(/datum/reagent/colorful_reagent = 5) required_reagents = list(/datum/reagent/stable_plasma = 1, /datum/reagent/uranium/radium = 1, /datum/reagent/drug/space_drugs = 1, /datum/reagent/medicine/cryoxadone = 1, /datum/reagent/consumable/triple_citrus = 1) + reaction_flags = REACTION_CLEAR_INVERSE /datum/chemical_reaction/life required_reagents = list(/datum/reagent/medicine/strange_reagent = 1, /datum/reagent/medicine/c2/synthflesh = 1, /datum/reagent/blood = 1) @@ -602,18 +603,37 @@ /datum/chemical_reaction/monkey required_reagents = list(/datum/reagent/monkey_powder = 50, /datum/reagent/water = 1) reaction_flags = REACTION_INSTANT - mix_message = span_danger("Expands into a brown mass before shaping itself into a monkey!.") + mix_message = span_danger("Expands into a brown mass before shaping itself into a monkey!") /datum/chemical_reaction/monkey/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) - var/mob/living/carbon/M = holder.my_atom - var/location = get_turf(M) - if(iscarbon(M)) - if(ismonkey(M)) - M.gib(DROP_ALL_REMAINS) + var/mob/living/carbon/maybe_monkey = holder.my_atom + var/location = maybe_monkey.drop_location() + if(iscarbon(maybe_monkey)) + if(ismonkey(maybe_monkey)) + maybe_monkey.gib(DROP_ALL_REMAINS) + to_chat(maybe_monkey, span_danger("You body is torn to shreds as a monkey bursts out of you!")) else - M.vomit(VOMIT_CATEGORY_BLOOD) + maybe_monkey.vomit(VOMIT_CATEGORY_BLOOD) + to_chat(maybe_monkey, span_danger("You vomit out blood, making you feel grossly monkeyish.")) new /mob/living/carbon/human/species/monkey(location, TRUE) +/datum/chemical_reaction/angry_monkey + required_reagents = list(/datum/reagent/monkey_powder = 50, /datum/reagent/inverse/bath_salts = 10) + reaction_flags = REACTION_INSTANT + mix_message = span_danger("Expands into a brown mass before shaping itself into a pissed off monkey!") + +/datum/chemical_reaction/angry_monkey/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) + var/mob/living/carbon/maybe_monkey = holder.my_atom + var/location = maybe_monkey.drop_location() + if(iscarbon(maybe_monkey)) + if(ismonkey(maybe_monkey)) + maybe_monkey.gib(DROP_ALL_REMAINS) + to_chat(maybe_monkey, span_danger("You body is torn to shreds as a pissed off monkey bursts out of you!")) + else + maybe_monkey.vomit(VOMIT_CATEGORY_BLOOD) + to_chat(maybe_monkey, span_danger("You vomit out blood, making you feel grossly monkeyish.")) + new /mob/living/carbon/human/species/monkey/angry(location, TRUE) + //water electrolysis /datum/chemical_reaction/electrolysis results = list(/datum/reagent/oxygen = 2.5, /datum/reagent/hydrogen = 5) diff --git a/code/modules/reagents/withdrawal/_addiction.dm b/code/modules/reagents/withdrawal/_addiction.dm index 3345aed7a37..8d32dce3d2c 100644 --- a/code/modules/reagents/withdrawal/_addiction.dm +++ b/code/modules/reagents/withdrawal/_addiction.dm @@ -82,6 +82,9 @@ if(affected_carbon.mind.remove_addiction_points(type, addiction_loss_per_stage[withdrawal_stage + 1] * seconds_per_tick)) //If true was returned, we lost the addiction! return + if(!on_drug_of_this_addiction && HAS_TRAIT(affected_carbon, TRAIT_ADDICTIONRESILIENT) && affected_carbon.mind.remove_addiction_points(type, addiction_loss_per_stage[withdrawal_stage + 2] * seconds_per_tick)) + return + if(!current_addiction_cycle) //Dont do the effects if were not on drugs return FALSE diff --git a/tgstation.dme b/tgstation.dme index 0e31811bc45..dd370d240e8 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1867,6 +1867,7 @@ #include "code\datums\martial\_martial.dm" #include "code\datums\martial\boxing.dm" #include "code\datums\martial\cqc.dm" +#include "code\datums\martial\junglearts.dm" #include "code\datums\martial\krav_maga.dm" #include "code\datums\martial\mushpunch.dm" #include "code\datums\martial\plasma_fist.dm"