diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm
index 975b6037f6b..70054ebad5a 100644
--- a/code/__DEFINES/hud.dm
+++ b/code/__DEFINES/hud.dm
@@ -43,6 +43,7 @@
//Middle left indicators
#define ui_lingchemdisplay "WEST,CENTER-1:15"
#define ui_lingstingdisplay "WEST:6,CENTER-3:11"
+#define ui_blooddisplay "WEST:6,CENTER:-2"
//Lower center, persistent menu
#define ui_sstore1 "CENTER-5:10,SOUTH:5"
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index ff312bb15ca..8d8ee0c7350 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -1104,3 +1104,33 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/splash)
#undef HUNGER_STATE_HUNGRY
#undef HUNGER_STATE_STARVING
#undef HUNGER_STATE_VERY_HUNGRY
+
+#define FORMAT_BLOOD_LEVEL_HUD_MAPTEXT(value) MAPTEXT("
[round(value,1)]
")
+
+/**
+ * Blood Level HUD
+ *
+ * Automatically registers to the mob's life and updates its maptext depending on the
+ * mob's blood. Used for mobs that
+ * 1- Should always know how much blood they have
+ * 2- Have their blood level changing every life tick (which is why we don't manually call updates).
+ */
+/atom/movable/screen/blood_level
+ name = "Blood Level"
+ icon_state = "blood_display"
+ screen_loc = ui_blooddisplay
+
+/atom/movable/screen/blood_level/Initialize(mapload, datum/hud/hud_owner)
+ . = ..()
+ if(isnull(hud_owner))
+ return INITIALIZE_HINT_QDEL
+ RegisterSignal(hud_owner.mymob, COMSIG_LIVING_LIFE, PROC_REF(on_mob_life))
+
+/atom/movable/screen/blood_level/proc/on_mob_life(mob/living/source, seconds_per_tick, times_fired)
+ SIGNAL_HANDLER
+
+ if(!isliving(source))
+ return
+ maptext = FORMAT_BLOOD_LEVEL_HUD_MAPTEXT(source.blood_volume)
+
+#undef FORMAT_BLOOD_LEVEL_HUD_MAPTEXT
diff --git a/code/_onclick/hud/soulscythe.dm b/code/_onclick/hud/soulscythe.dm
new file mode 100644
index 00000000000..7a98b416731
--- /dev/null
+++ b/code/_onclick/hud/soulscythe.dm
@@ -0,0 +1,4 @@
+/datum/hud/soulscythe/New(mob/living/simple_animal/soulscythe/owner)
+ . = ..()
+ var/atom/movable/screen/using = new /atom/movable/screen/blood_level(null, src)
+ static_inventory += using
diff --git a/code/modules/mining/lavaland/mining_loot/megafauna/bubblegum.dm b/code/modules/mining/lavaland/mining_loot/megafauna/bubblegum.dm
index c16c58dc282..ca75af9f81f 100644
--- a/code/modules/mining/lavaland/mining_loot/megafauna/bubblegum.dm
+++ b/code/modules/mining/lavaland/mining_loot/megafauna/bubblegum.dm
@@ -266,15 +266,15 @@
return TRUE
/obj/item/soulscythe/proc/use_blood(amount = 0, message = TRUE)
- if(amount > soul.blood_level)
+ if(amount > soul.blood_volume)
if(message)
to_chat(soul, span_warning("Not enough blood!"))
return FALSE
- soul.blood_level -= amount
+ soul.blood_volume -= amount
return TRUE
/obj/item/soulscythe/proc/give_blood(amount)
- soul.blood_level = min(MAX_BLOOD_LEVEL, soul.blood_level + amount)
+ soul.blood_volume = min(MAX_BLOOD_LEVEL, soul.blood_volume + amount)
/obj/item/soulscythe/proc/on_resist(mob/living/user)
SIGNAL_HANDLER
@@ -384,17 +384,13 @@
mob_biotypes = MOB_SPIRIT
faction = list()
weather_immunities = list(TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE)
- /// Blood level, used for movement and abilities in a soulscythe
- var/blood_level = MAX_BLOOD_LEVEL
-
-/mob/living/simple_animal/soulscythe/get_status_tab_items()
- . = ..()
- . += "Blood: [blood_level]/[MAX_BLOOD_LEVEL]"
+ blood_volume = MAX_BLOOD_LEVEL
+ hud_type = /datum/hud/soulscythe
/mob/living/simple_animal/soulscythe/Life(seconds_per_tick, times_fired)
. = ..()
if(!stat)
- blood_level = min(MAX_BLOOD_LEVEL, blood_level + round(1 * seconds_per_tick))
+ blood_volume = min(MAX_BLOOD_LEVEL, blood_volume + round(1 * seconds_per_tick))
/obj/projectile/soulscythe
name = "soulslash"
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index 2c9bd61a401..e2ffbfccd3c 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -24,6 +24,8 @@
mutanttongue = /obj/item/organ/tongue/vampire
///some starter text sent to the vampire initially, because vampires have shit to do to stay alive
var/info_text = "You are a Vampire. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability."
+ /// UI displaying how much blood we have
+ var/atom/movable/screen/blood_level/blood_display
/datum/species/human/vampire/check_roundstart_eligible()
if(check_holidays(HALLOWEEN))
@@ -36,10 +38,15 @@
new_vampire.skin_tone = "albino"
new_vampire.update_body(0)
RegisterSignal(new_vampire, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(damage_weakness))
+ if(new_vampire.hud_used)
+ on_hud_created(new_vampire)
+ else
+ RegisterSignal(new_vampire, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created))
/datum/species/human/vampire/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
. = ..()
UnregisterSignal(C, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS)
+ QDEL_NULL(blood_display)
/datum/species/human/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick, times_fired)
. = ..()
@@ -63,6 +70,14 @@
vampire.adjust_fire_stacks(3 * seconds_per_tick)
vampire.ignite_mob()
+///Gives the blood HUD to the vampire so they always know how much blood they have.
+/datum/species/human/vampire/proc/on_hud_created(mob/source)
+ SIGNAL_HANDLER
+ var/datum/hud/blood_hud = source.hud_used
+ blood_display = new(null, blood_hud)
+ blood_hud.infodisplay += blood_display
+ blood_hud.show_hud(blood_hud.hud_version)
+
/datum/species/human/vampire/proc/damage_weakness(datum/source, list/damage_mods, damage_amount, damagetype, def_zone, sharpness, attack_direction, obj/item/attacking_item)
SIGNAL_HANDLER
@@ -203,17 +218,5 @@
name = "vampire heart"
color = COLOR_CRAYON_BLACK
-/obj/item/organ/heart/vampire/on_mob_insert(mob/living/carbon/receiver)
- . = ..()
- RegisterSignal(receiver, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(get_status_tab_item))
-
-/obj/item/organ/heart/vampire/on_mob_remove(mob/living/carbon/heartless)
- . = ..()
- UnregisterSignal(heartless, COMSIG_MOB_GET_STATUS_TAB_ITEMS)
-
-/obj/item/organ/heart/vampire/proc/get_status_tab_item(mob/living/carbon/source, list/items)
- SIGNAL_HANDLER
- items += "Blood Level: [source.blood_volume]/[BLOOD_VOLUME_MAXIMUM]"
-
#undef VAMPIRES_PER_HOUSE
#undef VAMP_DRAIN_AMOUNT
diff --git a/icons/hud/screen_gen.dmi b/icons/hud/screen_gen.dmi
index f77266a28f1..b0c3eeb9b1b 100644
Binary files a/icons/hud/screen_gen.dmi and b/icons/hud/screen_gen.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index d87ddad517e..96f313152e8 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -623,6 +623,7 @@
#include "code\_onclick\hud\screen_object_holder.dm"
#include "code\_onclick\hud\screen_objects.dm"
#include "code\_onclick\hud\screentip.dm"
+#include "code\_onclick\hud\soulscythe.dm"
#include "code\_onclick\hud\parallax\parallax.dm"
#include "code\_onclick\hud\parallax\random_layer.dm"
#include "code\_onclick\hud\rendering\plane_master_controller.dm"