diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 384e65bdcbe..8550654b9a6 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -40,11 +40,14 @@
#define TRAIT_NOBREATH "no_breath"
#define TRAIT_ANTIMAGIC "anti_magic"
#define TRAIT_HOLY "holy"
-#define TRAIT_DEPRESSION "depression"
+#define TRAIT_DEPRESSION "depression"
#define TRAIT_JOLLY "jolly"
#define TRAIT_NOCRITDAMAGE "no_crit"
#define TRAIT_NOSLIPWATER "noslip_water"
#define TRAIT_NOSLIPALL "noslip_all"
+#define TRAIT_NODEATH "nodeath"
+#define TRAIT_NOHARDCRIT "nohardcrit"
+#define TRAIT_NOSOFTCRIT "nosoftcrit"
#define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance"
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 609ab904c3e..24786ea07ad 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -11,7 +11,7 @@
desc = "It's watching you suspiciously."
/obj/structure/closet/crate/necropolis/tendril/PopulateContents()
- var/loot = rand(1,27)
+ var/loot = rand(1,28)
switch(loot)
if(1)
new /obj/item/shared_storage/red(src)
@@ -75,6 +75,8 @@
if(27)
new /obj/item/borg/upgrade/modkit/lifesteal(src)
new /obj/item/bedsheet/cult(src)
+ if(28)
+ new /obj/item/clothing/neck/necklace/memento_mori(src)
//KA modkit design discs
/obj/item/disk/design_disk/modkit_disc
@@ -192,6 +194,65 @@
icon_state = "asclepius_active"
activated = TRUE
+//Memento Mori
+/obj/item/clothing/neck/necklace/memento_mori
+ name = "Memento Mori"
+ desc = "A golden pendant. An inscription on it says: \"Certain death tomorrow means certain life today.\""
+ icon = 'icons/obj/lavaland/artefacts.dmi'
+ icon_state = "memento_mori"
+ actions_types = list(/datum/action/item_action/hands_free/memento_mori)
+ var/mob/living/carbon/human/active_owner
+ var/death_timer_id
+
+/obj/item/clothing/neck/necklace/memento_mori/item_action_slot_check(slot)
+ if(slot == SLOT_NECK)
+ return TRUE
+
+/obj/item/clothing/neck/necklace/memento_mori/ui_action_click(mob/user, action)
+ if(!active_owner)
+ if(ishuman(user))
+ memento(user)
+ else
+ to_chat(user, "You try to free your lifeforce from the pendant...")
+ if(do_after(user, 40, target = src))
+ mori()
+
+/obj/item/clothing/neck/necklace/memento_mori/dropped(mob/user)
+ ..()
+ if(active_owner)
+ mori()
+
+/obj/item/clothing/neck/necklace/memento_mori/proc/memento(mob/living/carbon/human/user)
+ to_chat(user, "You feel your life being drained by the pendant...")
+ if(do_after(user, 40, target = src))
+ to_chat(user, "Your lifeforce is now linked to the pendant! You feel a looming death ahead of you, and yet you instinctively know that until then, you won't die.")
+ to_chat(user, "You also feel that removing the pendant now would be a really bad idea.")
+ user.add_trait(TRAIT_NODEATH, "memento_mori")
+ user.add_trait(TRAIT_NOHARDCRIT, "memento_mori")
+ user.add_trait(TRAIT_NOCRITDAMAGE, "memento_mori")
+ icon_state = "memento_mori_active"
+ active_owner = user
+ if(death_timer_id)
+ deltimer(death_timer_id)
+ death_timer_id = addtimer(CALLBACK(.proc/mori), world.time + 9000, TIMER_STOPPABLE) //15 minutes
+
+/obj/item/clothing/neck/necklace/memento_mori/proc/mori()
+ if(death_timer_id)
+ deltimer(death_timer_id)
+ death_timer_id = null
+ icon_state = "memento_mori"
+ if(!active_owner)
+ return
+ var/mob/living/carbon/human/H = active_owner //to avoid infinite looping when dust unequips the pendant
+ active_owner = null
+ to_chat(H, "You feel your life rapidly slipping away from you!")
+ H.dust(TRUE, TRUE)
+
+/datum/action/item_action/hands_free/memento_mori
+ check_flags = 0
+ name = "Memento Mori"
+ desc = "Bind your life to the pendant, preserving it yet dooming it."
+
//Wisp Lantern
/obj/item/wisp_lantern
name = "spooky lantern"
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index fbfe7cbe054..56dfcb86ae2 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -722,14 +722,14 @@
if(status_flags & GODMODE)
return
if(stat != DEAD)
- if(health <= HEALTH_THRESHOLD_DEAD)
+ if(health <= HEALTH_THRESHOLD_DEAD && !has_trait(TRAIT_NODEATH))
death()
return
- if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (has_trait(TRAIT_FAKEDEATH)) || health <= HEALTH_THRESHOLD_FULLCRIT)
+ if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (has_trait(TRAIT_FAKEDEATH)) || (health <= HEALTH_THRESHOLD_FULLCRIT && !has_trait(TRAIT_NOHARDCRIT)))
stat = UNCONSCIOUS
blind_eyes(1)
else
- if(health <= HEALTH_THRESHOLD_CRIT)
+ if(health <= HEALTH_THRESHOLD_CRIT && !has_trait(TRAIT_NOSOFTCRIT))
stat = SOFT_CRIT
else
stat = CONSCIOUS
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index ee16e4103fe..7542c0c79cb 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -26,8 +26,11 @@
/mob/living/proc/spread_bodyparts()
return
-/mob/living/dust(just_ash = FALSE)
- death(1)
+/mob/living/dust(just_ash = FALSE, drop_items = FALSE)
+ death(TRUE)
+
+ if(drop_items)
+ unequip_everything()
if(buckled)
buckled.unbuckle_mob(src,force=1)
diff --git a/icons/obj/lavaland/artefacts.dmi b/icons/obj/lavaland/artefacts.dmi
index 829f8b91702..0530f7bb3b5 100644
Binary files a/icons/obj/lavaland/artefacts.dmi and b/icons/obj/lavaland/artefacts.dmi differ