diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm
index 81ee5c3989..1464927c3a 100644
--- a/code/datums/mood_events/generic_negative_events.dm
+++ b/code/datums/mood_events/generic_negative_events.dm
@@ -243,6 +243,11 @@
description = "I have been scorched by the unforgiving rays of the sun.\n"
mood_change = -6
timeout = 15 MINUTES
+
+/datum/mood_event/bloodsucker_disgust
+ description = "Something I recently ate was horrifyingly disgusting.\n"
+ mood_change = -5
+ timeout = 5 MINUTES
/datum/mood_event/nanite_sadness
description = "+++++++HAPPINESS SUPPRESSION+++++++\n"
diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm
index 0179c60ef1..e774cf4250 100644
--- a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm
+++ b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm
@@ -315,7 +315,7 @@
bloodsuckerdatum.handle_eat_human_food(food_nutrition)
-/datum/antagonist/bloodsucker/proc/handle_eat_human_food(var/food_nutrition) // Called from snacks.dm and drinks.dm
+/datum/antagonist/bloodsucker/proc/handle_eat_human_food(food_nutrition, puke_blood = TRUE, masquerade_override) // Called from snacks.dm and drinks.dm
set waitfor = FALSE
if(!owner.current || !iscarbon(owner.current))
return
@@ -324,14 +324,14 @@
C.nutrition -= food_nutrition
foodInGut += food_nutrition
// Already ate some bad clams? Then we can back out, because we're already sick from it.
- if (foodInGut != food_nutrition)
+ if(foodInGut != food_nutrition)
return
// Haven't eaten, but I'm in a Human Disguise.
- else if (poweron_masquerade)
+ else if(poweron_masquerade && !masquerade_override)
to_chat(C, "Your stomach turns, but your \"human disguise\" keeps the food down...for now.")
// Keep looping until we purge. If we have activated our Human Disguise, we ignore the food. But it'll come up eventually...
var/sickphase = 0
- while (foodInGut)
+ while(foodInGut)
sleep(50)
C.adjust_disgust(10 * sickphase)
// Wait an interval...
@@ -340,24 +340,29 @@
if(C.stat == DEAD)
return
// Put up disguise? Then hold off the vomit.
- if(poweron_masquerade)
+ if(poweron_masquerade && !masquerade_override)
if(sickphase > 0)
to_chat(C, "Your stomach settles temporarily. You regain your composure...for now.")
sickphase = 0
continue
switch(sickphase)
- if (1)
+ if(1)
to_chat(C, "You feel unwell. You can taste ash on your tongue.")
C.Stun(10)
- if (2)
+ if(2)
to_chat(C, "Your stomach turns. Whatever you ate tastes of grave dirt and brimstone.")
C.Dizzy(15)
C.Stun(13)
- if (3)
+ if(3)
to_chat(C, "You purge the food of the living from your viscera! You've never felt worse.")
- C.vomit(foodInGut * 4, foodInGut * 2, 0) // (var/lost_nutrition = 10, var/blood = 0, var/stun = 1, var/distance = 0, var/message = 1, var/toxic = 0)
- C.blood_volume = max(0, C.blood_volume - foodInGut * 2)
+ //Puke blood only if puke_blood is true, and loose some blood, else just puke normally.
+ if(puke_blood)
+ C.blood_volume = max(0, C.blood_volume - foodInGut * 2)
+ C.vomit(foodInGut * 4, foodInGut * 2, 0)
+ else
+ C.vomit(foodInGut * 4, FALSE, 0)
C.Stun(30)
//C.Dizzy(50)
foodInGut = 0
+ SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "vampdisgust", /datum/mood_event/bloodsucker_disgust)
sickphase ++
diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm
index 53c3389695..d3525c951d 100644
--- a/code/modules/hydroponics/grown/tomato.dm
+++ b/code/modules/hydroponics/grown/tomato.dm
@@ -36,7 +36,7 @@
plantname = "Blood-Tomato Plants"
product = /obj/item/reagent_containers/food/snacks/grown/tomato/blood
mutatelist = list()
- reagents_add = list(/datum/reagent/blood = 0.2, /datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.1)
+ reagents_add = list(/datum/reagent/blood/tomato = 0.2, /datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.1)
rarity = 20
/obj/item/reagent_containers/food/snacks/grown/tomato/blood
@@ -47,7 +47,7 @@
splat_type = /obj/effect/gibspawner/generic
filling_color = "#FF0000"
foodtype = FRUIT | GROSS
- grind_results = list(/datum/reagent/consumable/ketchup = 0, /datum/reagent/blood = 0)
+ grind_results = list(/datum/reagent/consumable/ketchup = 0, /datum/reagent/blood/tomato = 0)
distill_reagent = /datum/reagent/consumable/ethanol/bloody_mary
// Blue Tomato
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index 4aabd82d6a..bd6c37973f 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -221,3 +221,13 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
rs += "[R.name], [R.volume]"
return rs.Join(" | ")
+
+//For easy bloodsucker disgusting and blood removal
+/datum/reagent/proc/disgust_bloodsucker(mob/living/carbon/C, disgust, blood_change, blood_puke = TRUE, force)
+ if(isvamp(C))
+ var/datum/antagonist/bloodsucker/bloodsuckerdatum = C.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
+ if(disgust)
+ bloodsuckerdatum.handle_eat_human_food(disgust, blood_puke, force)
+ if(blood_change)
+ bloodsuckerdatum.AddBloodVolume(blood_change)
+
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index 4b65776ce9..e22f8caf89 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -579,8 +579,8 @@ All effects don't start immediately, but rather get worse over time; the rate is
value = 1.3
/datum/reagent/consumable/ethanol/bloody_mary/on_mob_life(mob/living/carbon/C)
- if((HAS_TRAIT(C, TRAIT_NOMARROW)))
- return
+ if(isvamp(C))
+ disgust_bloodsucker(FALSE, 1) //Bloodsuckers get SOME blood from it, for style reasons.
if(C.blood_volume < (BLOOD_VOLUME_NORMAL*C.blood_ratio))
C.blood_volume = min((BLOOD_VOLUME_NORMAL*C.blood_ratio), C.blood_volume + 3) //Bloody Mary quickly restores blood loss.
..()
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index adc30ecdc9..9794b58112 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -13,7 +13,7 @@
shot_glass_icon_state = "shotglassred"
pH = 7.4
-/datum/reagent/blood/reaction_mob(mob/living/L, method=TOUCH, reac_volume)
+/datum/reagent/blood/reaction_mob(mob/living/L, method = TOUCH, reac_volume)
if(data && data["viruses"])
for(var/thing in data["viruses"])
var/datum/disease/D = thing
@@ -26,6 +26,18 @@
else //ingest, patch or inject
L.ForceContractDisease(D)
+ if(data["blood_type"] == "SY")
+ //Synthblood is very disgusting to bloodsuckers. They will puke it out to expel it, unless they have masquarade on
+ switch(reac_volume)
+ if(0 to 3)
+ disgust_bloodsucker(L, 3, FALSE, FALSE, FALSE)
+ if(3 to 6)
+ //If theres more than 8 units, they will start expelling it, even if they are masquarading.
+ disgust_bloodsucker(L, 5, FALSE, FALSE, TRUE)
+ else
+ //If they have too much in them, they will also puke out their blood.
+ disgust_bloodsucker(L, 7, -5, TRUE, TRUE)
+
if(iscarbon(L))
var/mob/living/carbon/C = L
var/blood_id = C.get_blood_id()
@@ -37,10 +49,8 @@
L.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
/datum/reagent/blood/on_mob_life(mob/living/carbon/C) //Because lethals are preferred over stamina. damnifino.
- if((HAS_TRAIT(C, TRAIT_NOMARROW)))
- return //We dont want vampires getting toxed from blood
var/blood_id = C.get_blood_id()
- if((blood_id == /datum/reagent/blood || blood_id == /datum/reagent/blood/jellyblood))
+ if((blood_id in GLOB.blood_reagent_types) && !HAS_TRAIT(C, TRAIT_NOMARROW))
if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type))) //we only care about bloodtype here because this is where the poisoning should be
C.adjustToxLoss(rand(2,8)*REM, TRUE, TRUE) //forced to ensure people don't use it to gain beneficial toxin as slime person
..()
@@ -117,7 +127,7 @@
if(!istype(D, /datum/disease/advance))
preserve += D
data["viruses"] = preserve
- return 1
+ return TRUE
/datum/reagent/blood/proc/get_diseases()
. = list()
@@ -142,6 +152,13 @@
taste_mult = 1.3
pH = 4
+/datum/reagent/blood/tomato
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Tomato Blood"
+ description = "This highly resembles blood, but it doesnt actually function like it, resembling more ketchup, with a more blood-like consistency."
+ taste_description = "sap" //Like tree sap?
+ pH = 7.45
+
/datum/reagent/blood/jellyblood/on_mob_life(mob/living/carbon/M)
if(prob(10))
if(M.dna?.species?.exotic_bloodtype != "GEL")
diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm
index 2f5fb067ea..3296586c94 100644
--- a/code/modules/reagents/reagent_containers/blood_pack.dm
+++ b/code/modules/reagents/reagent_containers/blood_pack.dm
@@ -89,7 +89,7 @@
blood_type = "BUG"
/obj/item/reagent_containers/blood/attackby(obj/item/I, mob/user, params)
- if (istype(I, /obj/item/pen) || istype(I, /obj/item/toy/crayon))
+ if(istype(I, /obj/item/pen) || istype(I, /obj/item/toy/crayon))
if(!user.is_literate())
to_chat(user, "You scribble illegibly on the label of [src]!")
return
@@ -107,25 +107,31 @@
else
return ..()
-/obj/item/reagent_containers/blood/attack(mob/M, mob/user, def_zone)
- if(user.a_intent == INTENT_HELP && reagents.total_volume > 0)
- if (user != M)
- to_chat(user, "You force [M] to drink from the [src]")
- user.visible_message("[user] forces [M] to drink from the [src].")
- if(!do_mob(user, M, 50))
+/obj/item/reagent_containers/blood/attack(mob/living/carbon/C, mob/user, def_zone)
+ if(user.a_intent == INTENT_HELP && reagents.total_volume > 0 && iscarbon(C) && user.a_intent == INTENT_HELP)
+ if(C.is_mouth_covered())
+ to_chat(user, "You cant drink from the [src] while your mouth is covered.")
+ return
+ if(user != C)
+ user.visible_message("[user] forces [C] to drink from the [src].", \
+ "You force [C] to drink from the [src]")
+ if(!do_mob(user, C, 50))
return
else
- if(!do_mob(user, M, 10))
+ if(!do_mob(user, C, 10))
return
+
to_chat(user, "You take a sip from the [src].")
user.visible_message("[user] puts the [src] up to their mouth.")
if(reagents.total_volume <= 0) // Safety: In case you spam clicked the blood bag on yourself, and it is now empty (below will divide by zero)
return
- var/gulp_size = 5
+ var/gulp_size = 3
var/fraction = min(gulp_size / reagents.total_volume, 1)
- reagents.reaction(M, INGEST, fraction) //checkLiked(fraction, M) // Blood isn't food, sorry.
- reagents.trans_to(M, gulp_size)
- playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
+ reagents.reaction(C, INGEST, fraction) //checkLiked(fraction, M) // Blood isn't food, sorry.
+ reagents.trans_to(C, gulp_size)
+ reagents.remove_reagent(src, 2) //Inneficency, so hey, IVs are usefull.
+ playsound(C.loc,'sound/items/drink.ogg', rand(10, 50), TRUE)
+ return
..()
/obj/item/reagent_containers/blood/bluespace
@@ -133,3 +139,14 @@
desc = "Contains blood used for transfusion, this one has been made with bluespace technology to hold much more blood. Must be attached to an IV drip."
icon_state = "bsbloodpack"
volume = 600 //its a blood bath!
+
+/obj/item/reagent_containers/blood/bluespace/attack(mob/living/carbon/C, mob/user, def_zone)
+ if(user.a_intent == INTENT_HELP)
+ if(user != C)
+ to_chat(user, "You can't force people to drink from the [src]. Nothing comes out from it.")
+ return
+ else
+ to_chat(user, "You try to suck on the [src], but nothing comes out.")
+ return
+ else
+ ..()