diff --git a/_maps/templates/lazy_templates/ninja_den.dmm b/_maps/templates/lazy_templates/ninja_den.dmm index e6265ddf130..db0e706d3fd 100644 --- a/_maps/templates/lazy_templates/ninja_den.dmm +++ b/_maps/templates/lazy_templates/ninja_den.dmm @@ -1881,7 +1881,7 @@ /area/centcom/central_command_areas/holding) "TS" = ( /obj/structure/rack, -/obj/item/nullrod/scythe/vibro{ +/obj/item/nullrod/vibro{ damtype = "stamina"; force = 30; pixel_x = 5; diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 9d2a2be1dad..afaf6b90f06 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -500,6 +500,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Projectile with this trait will always hit the defined zone of a struck living mob. #define TRAIT_ALWAYS_HIT_ZONE "always_hit_zone" +/// Mobs with this trait do care about a few grizzly things, such as digging up graves. They also really do not like bringing people back to life or tending wounds, but love autopies, dissections and amputations. +#define TRAIT_MORBID "morbid" + // METABOLISMS // Various jobs on the station have historically had better reactions // to various drinks and foodstuffs. Security liking donuts is a classic diff --git a/code/_globalvars/phobias.dm b/code/_globalvars/phobias.dm index d9adb3c8bff..c539618e567 100644 --- a/code/_globalvars/phobias.dm +++ b/code/_globalvars/phobias.dm @@ -147,7 +147,7 @@ GLOBAL_LIST_INIT(phobia_objs, list( /obj/item/highfrequencyblade, /obj/item/katana, /obj/item/nullrod/claymore/katana, - /obj/item/nullrod/scythe/vibro, + /obj/item/nullrod/vibro, /obj/item/reagent_containers/cup/glass/bottle/sake, /obj/item/throwing_star, /obj/item/toy/katana, diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 9b82322e99a..fcf0ec974cb 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -186,6 +186,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_MIMING" = TRAIT_MIMING, "TRAIT_PREVENT_IMPLANT_AUTO_EXPLOSION" = TRAIT_PREVENT_IMPLANT_AUTO_EXPLOSION, "TRAIT_UNOBSERVANT" = TRAIT_UNOBSERVANT, + "TRAIT_MORBID" = TRAIT_MORBID, ), /obj/item/bodypart = list( "TRAIT_PARALYSIS" = TRAIT_PARALYSIS, diff --git a/code/datums/ai/hauntium/haunted_controller.dm b/code/datums/ai/hauntium/haunted_controller.dm index e8e80b41607..9eb18ed7f6c 100644 --- a/code/datums/ai/hauntium/haunted_controller.dm +++ b/code/datums/ai/hauntium/haunted_controller.dm @@ -28,7 +28,7 @@ var/haunt_equipper = TRUE if(isliving(equipper)) var/mob/living/possibly_cool = equipper - if(possibly_cool.mob_biotypes & MOB_UNDEAD) + if(possibly_cool.mob_biotypes & MOB_UNDEAD || HAS_TRAIT(possibly_cool, TRAIT_MORBID)) haunt_equipper = FALSE if(haunt_equipper) //You have now become one of the victims of the HAAAAUNTTIIIINNGGG OOOOOO~~~ diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 9214c8e459e..4ae810866f8 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -364,7 +364,7 @@ description = "Swish! Nothing but net." mood_change = 2 timeout = 5 MINUTES - + /datum/mood_event/basketball_dunk description = "Slam dunk! Boom, shakalaka!" mood_change = 2 diff --git a/code/datums/mood_events/morbid_events.dm b/code/datums/mood_events/morbid_events.dm new file mode 100644 index 00000000000..731b62569cc --- /dev/null +++ b/code/datums/mood_events/morbid_events.dm @@ -0,0 +1,41 @@ +/* Morbid Mood Events - +Any mood events related to TRAIT_MORBID. +Ususally this is an inverse of a typically good, alturistic action (such as saving someones life), punishing it with a negative mood event, +and rewards typically antisocial/unsavory actions (such as graverobbing) with a positive mood event. +Intended to push a creepy, mad scientist/doctor vibe, or someone who is downright monstrous in nature. +*/ + +// Positive Events - We did something unsavory in the name of mad science + +/datum/mood_event/morbid_dismemberment + description = "Nothing quite as satisfying as a clean dismemberment!" + mood_change = 2 + timeout = 2 MINUTES + +/datum/mood_event/morbid_dissection_success + description = "I take pride in my work. Nobody can dissect a body quite like I can." + mood_change = 2 + timeout = 2 MINUTES + +/datum/mood_event/morbid_revival_success + description = "IT LIVES! AH HA HA HA HA!!" + mood_change = 6 + timeout = 8 MINUTES + +/datum/mood_event/morbid_graverobbing + description = "The dead have no need for possessions. I, on the other hand, am very much alive and very much in need." + mood_change = 2 + timeout = 2 MINUTES + +// Negative Events - We helped someone stay alive. + +/datum/mood_event/morbid_tend_wounds + description = "Why must I waste my talents on this trivial nonsense? Tending to breathers is a waste of effort." + mood_change = -2 + timeout = 2 MINUTES + +/datum/mood_event/morbid_saved_life + description = "I could have done so much more with their corpse than I could have saving their useless life. Dreadful." + mood_change = -6 + timeout = 2 MINUTES + diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 2adec293623..bc3f637935c 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -648,7 +648,10 @@ H.emote("gasp") H.set_jitter_if_lower(200 SECONDS) SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK) - user.add_mood_event("saved_life", /datum/mood_event/saved_life) + if(HAS_TRAIT(user, TRAIT_MORBID)) + user.add_mood_event("morbid_saved_life", /datum/mood_event/morbid_saved_life) + else + user.add_mood_event("saved_life", /datum/mood_event/saved_life) log_combat(user, H, "revived", defib) do_success() return diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm index 779f07bd096..ae3cba92eb3 100644 --- a/code/modules/clothing/outfits/ert.dm +++ b/code/modules/clothing/outfits/ert.dm @@ -181,7 +181,7 @@ name = "Inquisition Commander" back = /obj/item/mod/control/pre_equipped/responsory/inquisitory/commander - r_hand = /obj/item/nullrod/scythe/talking/chainsword + r_hand = /obj/item/nullrod/vibro/talking/chainsword backpack_contents = list( /obj/item/storage/box/survival = 1, ) diff --git a/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm b/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm index a3d90cc63cc..79e11a850ee 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm @@ -41,6 +41,7 @@ rods[nullrod_type] = initial(nullrod_type.menu_description) //special non-nullrod subtyped shit rods[/obj/item/gun/ballistic/bow/divine/with_quiver] = "A divine bow and 10 quivered holy arrows." + rods[/obj/item/organ/internal/cyberimp/arm/shard/scythe] = "A bargain with something sinister." AddComponent(/datum/component/subtype_picker, rods, CALLBACK(src, PROC_REF(on_holy_weapon_picked))) /obj/item/nullrod/proc/on_holy_weapon_picked(obj/item/nullrod/holy_weapon_type) @@ -244,31 +245,7 @@ span_suicide("You try to impale yourself with [src], but it's TOO HOLY...")) return SHAME -/obj/item/nullrod/scythe - name = "reaper scythe" - desc = "Ask not for whom the bell tolls..." - icon = 'icons/obj/hydroponics/equipment.dmi' - icon_state = "scythe1" - inhand_icon_state = "scythe1" - lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi' - w_class = WEIGHT_CLASS_BULKY - armour_penetration = 35 - slot_flags = ITEM_SLOT_BACK - sharpness = SHARP_EDGED - attack_verb_continuous = list("chops", "slices", "cuts", "reaps") - attack_verb_simple = list("chop", "slice", "cut", "reap") - menu_description = "A sharp scythe which partially penetrates armor. Very effective at butchering bodies. Can be worn on the back." - -/obj/item/nullrod/scythe/Initialize(mapload) - . = ..() - AddComponent(/datum/component/butchering, \ - speed = 7 SECONDS, \ - effectiveness = 110, \ - ) - AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) - -/obj/item/nullrod/scythe/vibro +/obj/item/nullrod/vibro name = "high frequency blade" desc = "Bad references are the DNA of the soul." icon = 'icons/obj/weapons/sword.dmi' @@ -277,12 +254,24 @@ worn_icon_state = "hfrequency0" lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + w_class = WEIGHT_CLASS_BULKY + armour_penetration = 35 + slot_flags = ITEM_SLOT_BACK + sharpness = SHARP_EDGED attack_verb_continuous = list("chops", "slices", "cuts", "zandatsu's") attack_verb_simple = list("chop", "slice", "cut", "zandatsu") hitsound = 'sound/weapons/rapierhit.ogg' menu_description = "A sharp blade which partially penetrates armor. Very effective at butchering bodies. Can be worn on the back." -/obj/item/nullrod/scythe/spellblade +/obj/item/nullrod/vibro/Initialize(mapload) + . = ..() + AddComponent( + /datum/component/butchering, \ + speed = 7 SECONDS, \ + effectiveness = 110, \ + ) + +/obj/item/nullrod/vibro/spellblade name = "dormant spellblade" desc = "The blade grants the wielder nearly limitless power...if they can figure out how to turn it on, that is." icon = 'icons/obj/weapons/guns/magic.dmi' @@ -294,7 +283,7 @@ hitsound = 'sound/weapons/rapierhit.ogg' menu_description = "A sharp blade which partially penetrates armor. Very effective at butchering bodies. Can be worn on the back." -/obj/item/nullrod/scythe/talking +/obj/item/nullrod/vibro/talking name = "possessed blade" desc = "When the station falls into chaos, it's nice to have a friend by your side." icon = 'icons/obj/weapons/sword.dmi' @@ -308,11 +297,11 @@ hitsound = 'sound/weapons/rapierhit.ogg' menu_description = "A sharp blade which partially penetrates armor. Able to awaken a friendly spirit to provide guidance. Very effective at butchering bodies. Can be worn on the back." -/obj/item/nullrod/scythe/talking/Initialize(mapload) +/obj/item/nullrod/vibro/talking/Initialize(mapload) . = ..() AddComponent(/datum/component/spirit_holding) -/obj/item/nullrod/scythe/talking/chainsword +/obj/item/nullrod/vibro/talking/chainsword name = "possessed chainsaw sword" desc = "Suffer not a heretic to live." icon_state = "chainswordon" diff --git a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm new file mode 100644 index 00000000000..2c30696b453 --- /dev/null +++ b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm @@ -0,0 +1,207 @@ +/*Vorpal Scythe, or the implant null rod that isn't as strong as other null rods up until you use it to behead someone with the special death knell attack. +If the scythe isn't empowered when you sheath it, you take a heap of damage and probably a wound!*/ + +#define SCYTHE_WEAK 0 +#define SCYTHE_SATED 1 +#define SCYTHE_EMPOWERED 2 + +/obj/item/organ/internal/cyberimp/arm/shard/scythe + name = "sinister shard" + desc = "This shard seems to be directly linked to some sinister entity. It might be your god! It also gives you a really horrible rash when you hold onto it for too long." + items_to_create = list(/obj/item/vorpalscythe) + +/obj/item/organ/internal/cyberimp/arm/shard/scythe/Insert(mob/living/carbon/receiver, special, drop_if_replaced) + . = ..() + ADD_TRAIT(receiver, TRAIT_MORBID, ORGAN_TRAIT) + +/obj/item/organ/internal/cyberimp/arm/shard/scythe/Retract() + var/obj/item/vorpalscythe/scythe = active_item + if(!scythe) + return FALSE + if(scythe.empowerment < SCYTHE_SATED) + to_chat(owner, span_userdanger("[scythe] tears into you for your unworthy display of arrogance!")) + playsound(owner, 'sound/magic/demon_attack1.ogg', 50, TRUE) + var/obj/item/bodypart/part = owner.get_holding_bodypart_of_item(scythe) + if(part) + part.receive_damage(brute = 25, wound_bonus = 10, sharpness = SHARP_EDGED) + return ..() + +/obj/item/vorpalscythe + name = "vorpal scythe" + desc = "Reap what you sow." + icon = 'icons/obj/weapons/staff.dmi' + icon_state = "vorpalscythe" + inhand_icon_state = "vorpalscythe" + worn_icon_state = null + lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi' + righthand_file = 'icons/mob/inhands/64x64_righthand.dmi' + inhand_x_dimension = 64 + inhand_y_dimension = 64 + w_class = WEIGHT_CLASS_GIGANTIC + force = 10 //a lot worse than most nullrods initially. Why did you invest so much into making it vorpal, you dork. + armour_penetration = 50 //Very good armor penetration to make up for our abysmal force + reach = 2 //why yes, this does have reach + slot_flags = null + sharpness = SHARP_EDGED + attack_verb_continuous = list("chops", "slices", "cuts", "reaps") + attack_verb_simple = list("chop", "slice", "cut", "reap") + wound_bonus = 10 + bare_wound_bonus = 15 + /*What state is our scythe in? + + If it is SCYTHE_WEAK, it will harm our reaper on being sheathed. + + if it is SCYTHE_SATED, it will be able to sheath for 4 minutes. Gained from hitting a mob or performing the death knell on mindless humans. + + If it is SCYTHE_EMPOWERED, we've performed the death knell on a human with a mind. Lets you sheath for 2 minutes and grants additional force.*/ + var/empowerment = SCYTHE_WEAK + ///Our bonus to force after we have death knelled. Lasts approximately 2 minutes. + var/bonus_force_multiplier = 2 + ///Our initial force before empowerment. For tracking on the item, and in case the item somehow gains more force for some reason before we death knelled. + var/original_force + +/obj/item/vorpalscythe/examine(mob/user) + . = ..() + . += span_notice("You can perform a death knell using [src] on a human with Right-Click. If they were sentient (whether currently or at some point), [src] is empowered on a successful death knell.") + . += span_notice("[src] seems to have quite a bit of reach. You might be able to hit things from further away.") + + var/current_empowerment = empowerment + switch(current_empowerment) + if(SCYTHE_EMPOWERED) + . += span_notice("[src] is empowered and humming with energy.") + if(SCYTHE_SATED) + . += span_notice("[src] is sated, but still demands more. Perform the death knell!") + else + . += span_notice("[src] is still. Anticipating the strike. Best not anger it by denying it the opportuntiy to taste blood.") + +/obj/item/vorpalscythe/Initialize(mapload) + . = ..() + AddComponent(/datum/component/anti_magic, MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY) + AddComponent(/datum/component/effect_remover, \ + success_feedback = "You disrupt the magic of %THEEFFECT with %THEWEAPON.", \ + success_forcesay = "TO DUST WITH YE!! AWAY!!", \ + tip_text = "Clear rune", \ + on_clear_callback = CALLBACK(src, PROC_REF(on_cult_rune_removed)), \ + effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune) \ + ) + AddComponent( + /datum/component/butchering, \ + speed = 3 SECONDS, \ + effectiveness = 125, \ + ) + AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) //less good at killing revenants, much better at killing plants + +/obj/item/vorpalscythe/attack(mob/living/target, mob/living/user, params) + if(ismonkey(target) && !target.mind) //Don't empower from hitting monkeys. Hit a corgi or something, I don't know. + return ..() + + if(target.stat < DEAD && target != user) + scythe_empowerment(SCYTHE_SATED) + + return ..() + +//Borrows some amputation shear code, but much more specific +/obj/item/vorpalscythe/attack_secondary(mob/living/victim, mob/living/user, params) + if(!iscarbon(victim) || user.combat_mode) + return SECONDARY_ATTACK_CALL_NORMAL + + if(user.zone_selected != BODY_ZONE_HEAD) + return SECONDARY_ATTACK_CALL_NORMAL + + var/mob/living/carbon/potential_reaping = victim + + if(HAS_TRAIT(potential_reaping, TRAIT_NODISMEMBER)) + to_chat(user, span_warning("You do not think you can behead this creature...")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + var/head_name + var/obj/item/bodypart/head/reaped_head + + reaped_head = potential_reaping.get_bodypart(check_zone(user.zone_selected)) + if(!reaped_head) + to_chat(user, span_warning("There is no head to reap.")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + head_name = reaped_head.name + + //We're tracking this separately from empowerment so that we can use it to determine whether or not we haunt the heads we cut off. + var/potential_empowerment = SCYTHE_EMPOWERED + + if(!potential_reaping.mind) //We put this here juuuust in case there is something funky with ling checks + if(ismonkey(potential_reaping)) + to_chat(user, span_warning("A pointless existence. You'll get no benefit from this death knell beyond the satisfaction of beheading this foul thing.")) + potential_empowerment = SCYTHE_WEAK + else + to_chat(user, span_warning("This soul is almost nonexistent. But [src] can still gain something from this sacrifice. A puppet.")) + potential_empowerment = SCYTHE_SATED + + var/death_knell_speed_mod = 1 + + potential_reaping.visible_message(span_danger("[user] begins to raise [src] arove [potential_reaping]'s [head_name]."), span_userdanger("[user] begins to raise [src], aiming to slice off your [head_name]!")) + if(potential_reaping.stat >= UNCONSCIOUS || HAS_TRAIT(potential_reaping, TRAIT_INCAPACITATED)) //if the victim is incapacitated (due to paralysis, a stun, being in staminacrit, etc.), critted, unconscious, or dead, it's much easier to properly behead + death_knell_speed_mod *= 0.5 + if(potential_reaping.stat != DEAD && potential_reaping.has_status_effect(/datum/status_effect/jitter)) //jittering will make it harder to perform the death knell, even if they're still + death_knell_speed_mod *= 1.5 //Staminacritting someone who's jittering (from, say, a stun baton) won't give you enough time to slice their head off, but staminacritting someone who isn't jittering will + if(empowerment == SCYTHE_EMPOWERED) //That said, if heads are already rolling, why stop here? + death_knell_speed_mod *= 0.5 + if(ispodperson(potential_reaping) || ismonkey(potential_reaping)) //And if they're a podperson or monkey, they can just die. + death_knell_speed_mod *= 0.5 + + if(do_after(user, 15 SECONDS * death_knell_speed_mod, target = potential_reaping)) + playsound(get_turf(potential_reaping), 'sound/weapons/bladeslice.ogg', 250, TRUE) + reaped_head.dismember() + user.visible_message(span_danger("[user] swings the [src] down, slicing [potential_reaping]'s [head_name] clean off! You think the [src] may have grown stronger!"), span_notice("As you perform the death knell on [potential_reaping], the [src] gains power! For a time...")) + if(potential_empowerment == SCYTHE_SATED) //We don't want actual player heads to go wandering off, but it'll be funny if a bunch of monkeyhuman heads started floating around + reaped_head.AddComponent(/datum/component/haunted_item, \ + haunt_color = "#7be595", \ + haunt_duration = 1 MINUTES, \ + aggro_radius = null, \ + spawn_message = span_revenwarning("[reaped_head] shudders and rises up into the air in a pale green nimbus!"), \ + despawn_message = span_revenwarning("[reaped_head] falls back to the ground, stationary once more."), \ + throw_force_bonus = 0, \ + throw_force_max = 0, \ + ) + + scythe_empowerment(potential_empowerment) + + if(HAS_TRAIT(user, TRAIT_MORBID)) //You feel good about yourself, pal? + user.add_mood_event("morbid_dismemberment", /datum/mood_event/morbid_dismemberment) + + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/item/vorpalscythe/proc/scythe_empowerment(potential_empowerment = SCYTHE_WEAK) + //Determines if we are entitled to setting/resetting our timer. + //Only reset SCYTHE_EMPOWERED with an empowerment that would grant that. + //Only reset SCTHE_SATED if hitting at least simple mobs or nonmonkey carbons. + var/allow_timer_set = FALSE + + if(potential_empowerment == SCYTHE_EMPOWERED) + if(empowerment != SCYTHE_EMPOWERED) //We only empower our stats if we beheaded a human with a mind. + original_force = force + force *= bonus_force_multiplier + empowerment = potential_empowerment + allow_timer_set = TRUE + else if(empowerment < potential_empowerment) //so we don't end up weakening our scythe somehow and creating an infinite empowerment loop, only update empowerment if it is better + empowerment = potential_empowerment + allow_timer_set = TRUE + if(potential_empowerment != SCYTHE_WEAK && allow_timer_set) //And finally, if the empowerment was improved and wasn't too weak to get an empowerment, we set/reset our timer + addtimer(CALLBACK(src, PROC_REF(scythe_empowerment_end)), (4 MINUTES / empowerment), TIMER_UNIQUE | TIMER_OVERRIDE) + +/obj/item/vorpalscythe/proc/scythe_empowerment_end() + if(empowerment == SCYTHE_EMPOWERED) + force = original_force + original_force = null + empowerment = SCYTHE_WEAK + +/obj/item/vorpalscythe/proc/on_cult_rune_removed(obj/effect/target, mob/living/user) + if(!istype(target, /obj/effect/rune)) + return + + var/obj/effect/rune/target_rune = target + if(target_rune.log_when_erased) + user.log_message("erased [target_rune.cultist_name] rune using the vorpal scythe", LOG_GAME) + message_admins("[ADMIN_LOOKUPFLW(user)] erased a [target_rune.cultist_name] rune with the vorpal scythe.") + SSshuttle.shuttle_purchase_requirements_met[SHUTTLE_UNLOCK_NARNAR] = TRUE + +#undef SCYTHE_WEAK +#undef SCYTHE_SATED +#undef SCYTHE_EMPOWERED diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm index 9b3ace438f1..8ce3869bf60 100644 --- a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm @@ -237,7 +237,10 @@ dug_closed = TRUE close(user) else if(open(user, force = TRUE)) - user.add_mood_event("graverobbing", /datum/mood_event/graverobbing) + if (HAS_TRAIT(user, TRAIT_MORBID)) + user.add_mood_event("morbid_graverobbing", /datum/mood_event/morbid_graverobbing) + else + user.add_mood_event("graverobbing", /datum/mood_event/graverobbing) if(lead_tomb && first_open) user.gain_trauma(/datum/brain_trauma/magic/stalker) to_chat(user, span_boldwarning("Oh no, no no no, THEY'RE EVERYWHERE! EVERY ONE OF THEM IS EVERYWHERE!")) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 6d422157a24..395fd4f2832 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -26,7 +26,7 @@ if(2) new /obj/item/soulstone/anybody/mining(src) if(3) - new /obj/item/organ/internal/cyberimp/arm/katana(src) + new /obj/item/organ/internal/cyberimp/arm/shard/katana(src) if(4) new /obj/item/clothing/glasses/godeye(src) if(5) diff --git a/code/modules/mining/lavaland/tendril_loot.dm b/code/modules/mining/lavaland/tendril_loot.dm index 2c46fca1392..ed636d142f4 100644 --- a/code/modules/mining/lavaland/tendril_loot.dm +++ b/code/modules/mining/lavaland/tendril_loot.dm @@ -891,18 +891,18 @@ name = "Scan Target" desc = "Contact may or may not be close." -/obj/item/organ/internal/cyberimp/arm/katana - name = "dark shard" - desc = "An eerie metal shard surrounded by dark energies." +/obj/item/organ/internal/cyberimp/arm/shard + name = "dark spoon shard" + desc = "An eerie metal shard surrounded by dark energies...of soup drinking. You probably don't think you should have been able to find this." icon = 'icons/obj/lavaland/artefacts.dmi' icon_state = "cursed_katana_organ" status = ORGAN_ORGANIC organ_flags = ORGAN_FROZEN|ORGAN_UNREMOVABLE - items_to_create = list(/obj/item/cursed_katana) + items_to_create = list(/obj/item/kitchen/spoon) extend_sound = 'sound/items/unsheath.ogg' retract_sound = 'sound/items/sheath.ogg' -/obj/item/organ/internal/cyberimp/arm/katana/attack_self(mob/user, modifiers) +/obj/item/organ/internal/cyberimp/arm/shard/attack_self(mob/user, modifiers) . = ..() to_chat(user, span_userdanger("The mass goes up your arm and goes inside it!")) playsound(user, 'sound/magic/demon_consume.ogg', 50, TRUE) @@ -912,10 +912,13 @@ user.temporarilyRemoveItemFromInventory(src, TRUE) Insert(user) -/obj/item/organ/internal/cyberimp/arm/katana/screwdriver_act(mob/living/user, obj/item/screwtool) +/obj/item/organ/internal/cyberimp/arm/shard/screwdriver_act(mob/living/user, obj/item/screwtool) return -/obj/item/organ/internal/cyberimp/arm/katana/Retract() +/obj/item/organ/internal/cyberimp/arm/shard/katana + items_to_create = list(/obj/item/cursed_katana) + +/obj/item/organ/internal/cyberimp/arm/shard/katana/Retract() var/obj/item/cursed_katana/katana = active_item if(!katana || katana.shattered) return FALSE diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 4f921010b13..b5a7ff45b75 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -483,7 +483,10 @@ return FALSE visible_message(span_notice("[src] performs CPR on [target.name]!"), span_notice("You perform CPR on [target.name].")) - add_mood_event("saved_life", /datum/mood_event/saved_life) + if(HAS_TRAIT(src, TRAIT_MORBID)) + add_mood_event("morbid_saved_life", /datum/mood_event/morbid_saved_life) + else + add_mood_event("saved_life", /datum/mood_event/saved_life) log_combat(src, target, "CPRed") if (HAS_TRAIT(target, TRAIT_NOBREATH)) diff --git a/code/modules/mob_spawn/corpses/mining_corpses.dm b/code/modules/mob_spawn/corpses/mining_corpses.dm index 594687effbe..ac853119d5b 100644 --- a/code/modules/mob_spawn/corpses/mining_corpses.dm +++ b/code/modules/mob_spawn/corpses/mining_corpses.dm @@ -239,7 +239,7 @@ dame.physique = FEMALE dame.update_body() if(prob(30)) - back = /obj/item/nullrod/scythe/talking + back = /obj/item/nullrod/vibro/talking else back = /obj/item/shield/buckler belt = /obj/item/nullrod/claymore diff --git a/code/modules/surgery/amputation.dm b/code/modules/surgery/amputation.dm index f940584cd67..c1e02ec8548 100644 --- a/code/modules/surgery/amputation.dm +++ b/code/modules/surgery/amputation.dm @@ -57,6 +57,11 @@ span_notice("[user] severs [target]'s [parse_zone(target_zone)]!"), ) display_pain(target, "You can no longer feel your severed [parse_zone(target_zone)]!") + + if(HAS_TRAIT(user, TRAIT_MORBID) && ishuman(user)) + var/mob/living/carbon/human/morbid_weirdo = user + morbid_weirdo.add_mood_event("morbid_dismemberment", /datum/mood_event/morbid_dismemberment) + if(surgery.operated_bodypart) var/obj/item/bodypart/target_limb = surgery.operated_bodypart target_limb.drop_limb() diff --git a/code/modules/surgery/autopsy.dm b/code/modules/surgery/autopsy.dm index 072bfc23a41..6b3e7391292 100644 --- a/code/modules/surgery/autopsy.dm +++ b/code/modules/surgery/autopsy.dm @@ -36,6 +36,9 @@ /datum/surgery_step/autopsy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/autopsy_scanner/tool, datum/surgery/surgery, default_display_results = FALSE) ADD_TRAIT(target, TRAIT_DISSECTED, REF(src)) tool.scan_cadaver(user, target) + if(HAS_TRAIT(user, TRAIT_MORBID) && ishuman(user)) + var/mob/living/carbon/human/morbid_weirdo = user + morbid_weirdo.add_mood_event("morbid_dissection_success", /datum/mood_event/morbid_dissection_success) return ..() /datum/surgery_step/autopsy/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) diff --git a/code/modules/surgery/dissection.dm b/code/modules/surgery/dissection.dm index c00cc6bc57f..96c0f35d8b3 100644 --- a/code/modules/surgery/dissection.dm +++ b/code/modules/surgery/dissection.dm @@ -55,6 +55,9 @@ var/obj/machinery/computer/operating/operating_computer = surgery.locate_operating_computer(get_turf(target)) if (!isnull(operating_computer)) SEND_SIGNAL(operating_computer, COMSIG_OPERATING_COMPUTER_DISSECTION_COMPLETE, target) + if(HAS_TRAIT(user, TRAIT_MORBID) && ishuman(user)) + var/mob/living/carbon/human/morbid_weirdo = user + morbid_weirdo.add_mood_event("morbid_dissection_success", /datum/mood_event/morbid_dissection_success) return TRUE diff --git a/code/modules/surgery/healing.dm b/code/modules/surgery/healing.dm index 1f37d41b818..8f58553cc18 100644 --- a/code/modules/surgery/healing.dm +++ b/code/modules/surgery/healing.dm @@ -84,12 +84,15 @@ var/target_msg = "[user] fixes some of [target]'s wounds" //see above var/brute_healed = brutehealing var/burn_healed = burnhealing + var/dead_patient = FALSE if(target.stat == DEAD) //dead patients get way less additional heal from the damage they have. brute_healed += round((target.getBruteLoss() * (brute_multiplier * 0.2)),0.1) burn_healed += round((target.getFireLoss() * (burn_multiplier * 0.2)),0.1) + dead_patient = TRUE else brute_healed += round((target.getBruteLoss() * brute_multiplier),0.1) burn_healed += round((target.getFireLoss() * burn_multiplier),0.1) + dead_patient = FALSE if(!get_location_accessible(target, target_zone)) brute_healed *= 0.55 burn_healed *= 0.55 @@ -99,6 +102,10 @@ user_msg += get_progress(user, target, brute_healed, burn_healed) + if(HAS_TRAIT(user, TRAIT_MORBID) && ishuman(user) && !dead_patient) //Morbid folk don't care about tending the dead as much as tending the living + var/mob/living/carbon/human/morbid_weirdo = user + morbid_weirdo.add_mood_event("morbid_tend_wounds", /datum/mood_event/morbid_tend_wounds) + display_results( user, target, diff --git a/code/modules/surgery/revival.dm b/code/modules/surgery/revival.dm index ebd96541457..736e3982b03 100644 --- a/code/modules/surgery/revival.dm +++ b/code/modules/surgery/revival.dm @@ -89,6 +89,9 @@ target.visible_message(span_notice("...[target] wakes up, alive and aware!")) target.emote("gasp") target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 50, 199) //MAD SCIENCE + if(HAS_TRAIT(user, TRAIT_MORBID) && ishuman(user)) //Contrary to their typical hatred of resurrection, it wouldn't be very thematic if morbid people didn't love playing god + var/mob/living/carbon/human/morbid_weirdo = user + morbid_weirdo.add_mood_event("morbid_revival_success", /datum/mood_event/morbid_revival_success) return TRUE else target.visible_message(span_warning("...[target.p_they()] convulses, then lies still.")) diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index cabcc48e4eb..f111ac5625e 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -477,6 +477,9 @@ limb_snip_candidate.dismember() user.visible_message(span_danger("[src] violently slams shut, amputating [patient]'s [candidate_name]."), span_notice("You amputate [patient]'s [candidate_name] with [src].")) + if(HAS_TRAIT(user, TRAIT_MORBID)) //Freak + user.add_mood_event("morbid_dismemberment", /datum/mood_event/morbid_dismemberment) + /obj/item/shears/suicide_act(mob/living/carbon/user) user.visible_message(span_suicide("[user] is pinching [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!")) var/timer = 1 SECONDS diff --git a/icons/mob/inhands/64x64_lefthand.dmi b/icons/mob/inhands/64x64_lefthand.dmi index 61d8948a98f..4a43893cef4 100644 Binary files a/icons/mob/inhands/64x64_lefthand.dmi and b/icons/mob/inhands/64x64_lefthand.dmi differ diff --git a/icons/mob/inhands/64x64_righthand.dmi b/icons/mob/inhands/64x64_righthand.dmi index 9d3f6e679d0..89975e330ce 100644 Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ diff --git a/icons/obj/weapons/staff.dmi b/icons/obj/weapons/staff.dmi index 817fa643a02..da97e484df9 100644 Binary files a/icons/obj/weapons/staff.dmi and b/icons/obj/weapons/staff.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 5b2a6e9c189..c045b3e69ca 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1364,6 +1364,7 @@ #include "code\datums\mood_events\drug_events.dm" #include "code\datums\mood_events\generic_negative_events.dm" #include "code\datums\mood_events\generic_positive_events.dm" +#include "code\datums\mood_events\morbid_events.dm" #include "code\datums\mood_events\needs_events.dm" #include "code\datums\mutations\_combined.dm" #include "code\datums\mutations\_mutations.dm" @@ -3680,6 +3681,7 @@ #include "code\modules\jobs\job_types\chaplain\chaplain_costumes.dm" #include "code\modules\jobs\job_types\chaplain\chaplain_divine_archer.dm" #include "code\modules\jobs\job_types\chaplain\chaplain_nullrod.dm" +#include "code\modules\jobs\job_types\chaplain\chaplain_vorpal_scythe.dm" #include "code\modules\jobs\job_types\ert\ert_generic.dm" #include "code\modules\jobs\job_types\event\admin.dm" #include "code\modules\jobs\job_types\event\fugitive.dm"