diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm
index 6190e0c287..a6e4c8ed4f 100644
--- a/code/datums/mood_events/generic_negative_events.dm
+++ b/code/datums/mood_events/generic_negative_events.dm
@@ -201,7 +201,7 @@
/datum/mood_event/vampcandle
description = "Something is making your mind feel... loose...\n"
- mood_change = -20
+ mood_change = -10
timeout = 1 MINUTES
/datum/mood_event/drankblood_bad
diff --git a/code/game/gamemodes/bloodsucker/bloodsucker.dm b/code/game/gamemodes/bloodsucker/bloodsucker.dm
index fb6dd4604a..e784fd836d 100644
--- a/code/game/gamemodes/bloodsucker/bloodsucker.dm
+++ b/code/game/gamemodes/bloodsucker/bloodsucker.dm
@@ -21,8 +21,10 @@
required_players = 20
required_enemies = 2
recommended_enemies = 4
- reroll_friendly = 1
+ reroll_friendly = FALSE
enemy_minimum_age = 7
+ round_ends_with_antag_death = FALSE
+
announce_span = "danger"
announce_text = "Filthy, bloodsucking vampires are crawling around disguised as crewmembers!\n\
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 23703c7891..e416b2b436 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -79,6 +79,15 @@
material_drop = /obj/item/stack/sheet/mineral/wood
material_drop_amount = 5
+/obj/structure/closet/crate/coffin/examine(mob/user)
+ . = ..()
+ if(user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
+ . += {"This is a coffin which you can use to regenerate your burns and other wounds faster."}
+ . += {"You can also thicken your blood if you survive the day, and hide from the sun safely while inside."}
+ /* if(user.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
+ . += {"This is a coffin which your master can use to shield himself from the unforgiving sun.\n
+ You yourself are still human and dont need it. Yet."} */
+
/obj/structure/closet/crate/internals
desc = "An internals crate."
name = "internals crate"
diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_integration.dm b/code/modules/antagonists/bloodsucker/bloodsucker_integration.dm
index 5e38a29346..3a2725cf91 100644
--- a/code/modules/antagonists/bloodsucker/bloodsucker_integration.dm
+++ b/code/modules/antagonists/bloodsucker/bloodsucker_integration.dm
@@ -1,23 +1,22 @@
// INTEGRATION: Adding Procs and Datums to existing "classes"
/mob/living/proc/AmBloodsucker(falseIfInDisguise=FALSE)
// No Datum
- if (!mind || !mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
+ if(!mind || !mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
return FALSE
-
return TRUE
/mob/living/proc/HaveBloodsuckerBodyparts(var/displaymessage="") // displaymessage can be something such as "rising from death" for Torpid Sleep. givewarningto is the person receiving messages.
- if (!getorganslot(ORGAN_SLOT_HEART))
- if (displaymessage != "")
+ if(!getorganslot(ORGAN_SLOT_HEART))
+ if(displaymessage != "")
to_chat(src, "Without a heart, you are incapable of [displaymessage].")
return FALSE
- if (!get_bodypart(BODY_ZONE_HEAD))
- if (displaymessage != "")
+ if(!get_bodypart(BODY_ZONE_HEAD))
+ if(displaymessage != "")
to_chat(src, "Without a head, you are incapable of [displaymessage].")
return FALSE
- if (!getorgan(/obj/item/organ/brain)) // NOTE: This is mostly just here so we can do one scan for all needed parts when creating a vamp. You probably won't be trying to use powers w/out a brain.
- if (displaymessage != "")
+ if(!getorgan(/obj/item/organ/brain)) // NOTE: This is mostly just here so we can do one scan for all needed parts when creating a vamp. You probably won't be trying to use powers w/out a brain.
+ if(displaymessage != "")
to_chat(src, "Without a brain, you are incapable of [displaymessage].")
return FALSE
return TRUE
@@ -37,41 +36,38 @@
/mob/living/carbon/getBruteLoss_nonProsthetic()
var/amount = 0
for(var/obj/item/bodypart/BP in bodyparts)
- if (BP.status < 2)
+ if(BP.status < 2)
amount += BP.brute_dam
return amount
/mob/living/carbon/getFireLoss_nonProsthetic()
var/amount = 0
for(var/obj/item/bodypart/BP in bodyparts)
- if (BP.status < 2)
+ if(BP.status < 2)
amount += BP.burn_dam
return amount
/mob/living/carbon
// EXAMINING
/mob/living/carbon/human/proc/ReturnVampExamine(var/mob/viewer)
- if (!mind || !viewer.mind)
+ if(!mind || !viewer.mind)
return ""
// Target must be a Vamp
var/datum/antagonist/bloodsucker/bloodsuckerdatum = mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
- if (!bloodsuckerdatum)
+ if(!bloodsuckerdatum)
return ""
-
// Viewer is Target's Vassal?
- if (viewer.mind.has_antag_datum(ANTAG_DATUM_VASSAL) in bloodsuckerdatum.vassals)
+ if(viewer.mind.has_antag_datum(ANTAG_DATUM_VASSAL) in bloodsuckerdatum.vassals)
var/returnString = "\[This is your Master!\]"
- var/returnIcon = "[icon2html('icons/mob/hud.dmi', world, "bloodsucker_big")]"
+ var/returnIcon = "[icon2html('icons/misc/language.dmi', world, "bloodsucker")]"
returnString += "\n"
return returnIcon + returnString
-
// Viewer not a Vamp AND not the target's vassal?
- if (!viewer.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER) && !(viewer in bloodsuckerdatum.vassals))
+ if(!viewer.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER) && !(viewer in bloodsuckerdatum.vassals))
return ""
-
// Default String
var/returnString = "\[[bloodsuckerdatum.ReturnFullName(1)]\]"
- var/returnIcon = "[icon2html('icons/mob/hud.dmi', world, "bloodsucker_big")]"
+ var/returnIcon = "[icon2html('icons/misc/language.dmi', world, "bloodsucker")]"
// In Disguise (Veil)?
//if (name_override != null)
@@ -82,35 +78,35 @@
/mob/living/carbon/human/proc/ReturnVassalExamine(var/mob/viewer)
- if (!mind || !viewer.mind)
+ if(!mind || !viewer.mind)
return ""
// Am I not even a Vassal? Then I am not marked.
var/datum/antagonist/vassal/vassaldatum = mind.has_antag_datum(ANTAG_DATUM_VASSAL)
- if (!vassaldatum)
+ if(!vassaldatum)
return ""
// Only Vassals and Bloodsuckers can recognize marks.
- if (!viewer.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER) && !viewer.mind.has_antag_datum(ANTAG_DATUM_VASSAL))
+ if(!viewer.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER) && !viewer.mind.has_antag_datum(ANTAG_DATUM_VASSAL))
return ""
// Default String
var/returnString = "\["
var/returnIcon = ""
// Am I Viewer's Vassal?
- if (vassaldatum.master.owner == viewer.mind)
+ if(vassaldatum.master.owner == viewer.mind)
returnString += "This [dna.species.name] bears YOUR mark!"
- returnIcon = "[icon2html('icons/mob/hud.dmi', world, "vassal_big")]"
+ returnIcon = "[icon2html('icons/misc/mark_icons.dmi', world, "vassal")]"
// Am I someone ELSE'S Vassal?
- else if (viewer.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
+ else if(viewer.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
returnString += "This [dna.species.name] bears the mark of [vassaldatum.master.ReturnFullName(vassaldatum.master.owner.current,1)]"
- returnIcon = "[icon2html('icons/mob/hud.dmi', world, "vassal_grey_big")]"
+ returnIcon = "[icon2html('icons/misc/mark_icons.dmi', world, "vassal_grey")]"
// Are you serving the same master as I am?
- else if (viewer.mind.has_antag_datum(ANTAG_DATUM_VASSAL) in vassaldatum.master.vassals)
+ else if(viewer.mind.has_antag_datum(ANTAG_DATUM_VASSAL) in vassaldatum.master.vassals)
returnString += "[p_they(TRUE)] bears the mark of your Master"
- returnIcon = "[icon2html('icons/mob/hud.dmi', world, "bloodsucker_big")]"
+ returnIcon = "[icon2html('icons/misc/mark_icons.dmi', world, "vassal")]"
// You serve a different Master than I do.
else
returnString += "[p_they(TRUE)] bears the mark of another Bloodsucker"
- returnIcon = "[icon2html('icons/mob/hud.dmi', world, "vassal_grey_big")]"
+ returnIcon = "[icon2html('icons/misc/mark_icons.dmi', world, "vassal_grey")]"
returnString += "\]" // \n" Don't need spacers. Using . += "" in examine.dm does this on its own.
return returnIcon + returnString
@@ -124,7 +120,7 @@
return blood_volume < BLOOD_VOLUME_SAFE
var/datum/antagonist/bloodsucker/bloodsuckerdatum = mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
- if (bloodsuckerdatum.poweron_masquerade)
+ if(bloodsuckerdatum.poweron_masquerade)
return FALSE
// If a Bloodsucker is malnourished, AND if his temperature matches his surroundings (aka he hasn't fed recently and looks COLD)...
@@ -132,14 +128,14 @@
/mob/living/carbon/human/ShowAsPaleExamine()
// Check for albino, as per human/examine.dm's check.
- if (skin_tone == "albino")
+ if(skin_tone == "albino")
return TRUE
return ..() // Return vamp check
/mob/living/carbon/proc/scan_blood_volume()
// Vamps don't show up normally to scanners unless Masquerade power is on ----> scanner.dm
- if (mind)
+ if(mind)
var/datum/antagonist/bloodsucker/bloodsuckerdatum = mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if (istype(bloodsuckerdatum) && bloodsuckerdatum.poweron_masquerade)
return BLOOD_VOLUME_NORMAL
diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm
index 821f18df1a..9174692b49 100644
--- a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm
+++ b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm
@@ -47,10 +47,10 @@
var/blood_taken = min(feedAmount, target.blood_volume) * mult // Starts at 15 (now 8 since we doubled the Feed time)
target.blood_volume -= blood_taken
// Simple Animals lose a LOT of blood, and take damage. This is to keep cats, cows, and so forth from giving you insane amounts of blood.
- if (!ishuman(target))
+ if(!ishuman(target))
target.blood_volume -= (blood_taken / max(target.mob_size, 0.1)) * 3.5 // max() to prevent divide-by-zero
target.apply_damage_type(blood_taken / 3.5) // Don't do too much damage, or else they die and provide no blood nourishment.
- if (target.blood_volume <= 0)
+ if(target.blood_volume <= 0)
target.blood_volume = 0
target.death(0)
///////////
@@ -59,9 +59,9 @@
// our volume * temp, + their volume * temp, / total volume
///////////
// Reduce Value Quantity
- if (target.stat == DEAD) // Penalty for Dead Blood
+ if(target.stat == DEAD) // Penalty for Dead Blood
blood_taken /= 3
- if (!ishuman(target)) // Penalty for Non-Human Blood
+ if(!ishuman(target)) // Penalty for Non-Human Blood
blood_taken /= 2
//if (!iscarbon(target)) // Penalty for Animals (they're junk food)
// Apply to Volume
@@ -84,7 +84,7 @@
//It is called from your coffin on close (by you only)
if(poweron_masquerade == TRUE || owner.current.AmStaked())
return FALSE
- owner.current.adjustStaminaLoss(-3 * (regenRate * 2) * mult, 0) // Humans lose stamina damage really quickly. Vamps should heal more.
+ owner.current.adjustStaminaLoss(-2 + (regenRate * -10) * mult, 0) // Humans lose stamina damage really quickly. Vamps should heal more.
owner.current.adjustCloneLoss(-1 * (regenRate * 4) * mult, 0)
owner.current.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1 * (regenRate * 4) * mult) //adjustBrainLoss(-1 * (regenRate * 4) * mult, 0)
// No Bleeding
@@ -102,6 +102,9 @@
costMult = 0.25
C.ExtinguishMob()
CureDisabilities() // Extinguish Fire
+ C.remove_all_embedded_objects() // Remove Embedded!
+ owner.current.regenerate_organs() // Heal Organs (will respawn original eyes etc. but we replace right away, next)
+ CheckVampOrgans() // Heart, Eyes
else
if(owner.current.blood_volume <= 0) // No Blood? Lower Mult
mult = 0.25
@@ -128,7 +131,7 @@
for (var/targetLimbZone in missing) // 1) Find ONE Limb and regenerate it.
owner.current.regenerate_limb(targetLimbZone, 0) // regenerate_limbs() <--- If you want to EXCLUDE certain parts, do it like this ----> regenerate_limbs(0, list("head"))
var/obj/item/bodypart/L = owner.current.get_bodypart( targetLimbZone ) // 2) Limb returns Damaged
- AddBloodVolume(20 * costMult) // Costs blood to heal
+ AddBloodVolume(50 * costMult) // Costs blood to heal
L.brute_dam = 60
to_chat(owner.current, "Your flesh knits as it regrows [L]!")
playsound(owner.current, 'sound/magic/demon_consume.ogg', 50, 1)
@@ -141,12 +144,8 @@
if (istype(BP) && BP.status == 2)
message_admins("T2: [BP] ")
BP.drop_limb()
- return TRUE
- // NOTE: Limbs have a "status", like their hosts "stat". 2 is dead (aka Prosthetic). 1 seems to be idle/alive.
- */
- C.remove_all_embedded_objects() // Remove Embedded!
- owner.current.regenerate_organs() // Heal Organs (will respawn original eyes etc. but we replace right away, next)
- CheckVampOrgans() // Heart, Eyes
+ return TRUE */
+ // NOTE: Limbs have a "status", like their hosts "stat". 2 is dead (aka Prosthetic). 1 seems to be idle/alive.*/
return FALSE
/datum/antagonist/bloodsucker/proc/CureDisabilities()
diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_objectives.dm b/code/modules/antagonists/bloodsucker/bloodsucker_objectives.dm
index ecb9f703d1..63e1470576 100644
--- a/code/modules/antagonists/bloodsucker/bloodsucker_objectives.dm
+++ b/code/modules/antagonists/bloodsucker/bloodsucker_objectives.dm
@@ -43,7 +43,7 @@
// EXPLANATION
/datum/objective/bloodsucker/lair/update_explanation_text()
- explanation_text = "Create a lair by claiming a coffin."// Make sure to keep it safe!"
+ explanation_text = "Create a lair by claiming a coffin, and protect it until the end of the shift"// Make sure to keep it safe!"
// WIN CONDITIONS?
/datum/objective/bloodsucker/lair/check_completion()
@@ -63,7 +63,6 @@
// LOOKUP: /datum/crewmonitor/proc/update_data(z) for .assignment to see how to get a person's PDA.
var/list/roles = list(
"Captain",
- "Head of Security",
"Head of Personnel",
"Research Director",
"Chief Engineer",
@@ -71,7 +70,6 @@
"Quartermaster"
)
var/list/departs = list(
- "Head of Security",
"Research Director",
"Chief Engineer",
"Chief Medical Officer",
@@ -93,8 +91,6 @@
// Department?
else
switch(target_role)
- if("Head of Security")
- department_string = "Security"
if("Research Director")
department_string = "Science"
if("Chief Engineer")
@@ -260,7 +256,7 @@
var/list/all_items = owner.current.GetAllContents() // Includes items inside other items.
var/itemcount = FALSE
for(var/obj/I in all_items) //Check for items
- if(istype(I, /obj/item/organ/heart))
+ if(I == /obj/item/organ/heart)
itemcount ++
if (itemcount >= target_amount) // Got the right amount?
return TRUE
diff --git a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm
index fd6f48a97d..ef59bfe7e0 100644
--- a/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm
+++ b/code/modules/antagonists/bloodsucker/datum_bloodsucker.dm
@@ -33,7 +33,7 @@
var/foodInGut = 0 // How much food to throw up later. You shouldn't have eaten that.
var/warn_sun_locker = FALSE // So we only get the locker burn message once per day.
var/warn_sun_burn = FALSE // So we only get the sun burn message once per day.
-
+ var/had_toxlover = FALSE
// LISTS
var/static/list/defaultTraits = list (TRAIT_STABLEHEART, TRAIT_NOBREATH, TRAIT_SLEEPIMMUNE, TRAIT_NOCRITDAMAGE, TRAIT_RESISTCOLD, TRAIT_RADIMMUNE, TRAIT_VIRUSIMMUNE, TRAIT_NIGHT_VISION, \
TRAIT_NOSOFTCRIT, TRAIT_NOHARDCRIT, TRAIT_AGEUSIA, TRAIT_COLDBLOODED, TRAIT_NONATURALHEAL, TRAIT_NOMARROW, TRAIT_NOPULSE, TRAIT_NOCLONE)
@@ -185,16 +185,17 @@
for (var/T in defaultTraits)
ADD_TRAIT(owner.current, T, "bloodsucker")
if(HAS_TRAIT(owner.current, TRAIT_TOXINLOVER)) //No slime bonuses here, no thank you
+ had_toxlover = TRUE
REMOVE_TRAIT(owner.current, TRAIT_TOXINLOVER, "species")
// Traits: Species
- if (ishuman(owner.current))
+ if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
var/datum/species/S = H.dna.species
S.species_traits |= DRINKSBLOOD
// Clear Addictions
owner.current.reagents.addiction_list = list() // Start over from scratch. Lucky you! At least you're not addicted to blood anymore (if you were)
// Stats
- if (ishuman(owner.current))
+ if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
var/datum/species/S = H.dna.species
// Make Changes
@@ -233,6 +234,9 @@
// Traits
for(var/T in defaultTraits)
REMOVE_TRAIT(owner.current, T, "bloodsucker")
+ if(had_toxlover == TRUE)
+ ADD_TRAIT(owner.current, TRAIT_TOXINLOVER, "species")
+
// Traits: Species
if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
diff --git a/code/modules/antagonists/bloodsucker/datum_vassal.dm b/code/modules/antagonists/bloodsucker/datum_vassal.dm
index dcf34080d8..f582b882d8 100644
--- a/code/modules/antagonists/bloodsucker/datum_vassal.dm
+++ b/code/modules/antagonists/bloodsucker/datum_vassal.dm
@@ -47,6 +47,7 @@
objectives += vassal_objective
objectives_given += vassal_objective
give_thrall_eyes()
+ owner.current.grant_language(/datum/language/vampiric)
// Add Antag HUD
update_vassal_icons_added(owner.current, "vassal")
. = ..()
@@ -85,6 +86,7 @@
qdel(O)
objectives_given = list()
remove_thrall_eyes()
+ owner.current.remove_language(/datum/language/vampiric)
// Clear Antag HUD
update_vassal_icons_removed(owner.current)
@@ -146,5 +148,5 @@
set_antag_hud(vassal, null)
//Displayed at the start of roundend_category section, default to roundend_category header
-/datum/antagonist/vassal/roundend_report_header()
- return "
"
+/*/datum/antagonist/vassal/roundend_report_header()
+ return "
"*/
diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm
index 8339787a07..99a01fd218 100644
--- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm
+++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm
@@ -104,20 +104,33 @@
can_buckle = TRUE
var/useLock = FALSE // So we can't just keep dragging ppl on here.
var/mob/buckled
- var/convert_progress = 2 // Resets on each new character to be added to the chair. Some effects should lower it...
+ var/convert_progress = 3 // Resets on each new character to be added to the chair. Some effects should lower it...
var/disloyalty_confirm = FALSE // Command & Antags need to CONFIRM they are willing to lose their role (and will only do it if the Vassal'ing succeeds)
var/disloyalty_offered = FALSE // Has the popup been issued? Don't spam them.
- var/convert_cost = 10
+ var/convert_cost = 100
/obj/structure/bloodsucker/vassalrack/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal(src.loc, 4)
new /obj/item/stack/rods(loc, 4)
qdel(src)
+/obj/structure/bloodsucker/vassalrack/examine(mob/user)
+ . = ..()
+ if((user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) || isobserver(user))
+ . += {"This is the vassal rack, which allows you to thrall crewmembers into loyal minions in your service."}
+ . += {"You need to first secure the vassal rack by clicking on it while it is in your lair."}
+ . += {"Simply click and hold on a victim, and then drag their sprite on the vassal rack."}
+ . += {"Make sure that the victim is handcuffed, or else they can simply run away or resist, as the process is not instant."}
+ . += {"To convert the victim, simply click on the vassal rack itself. Sharp weapons work faster than other tools."}
+/* if(user.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
+ . += {"This is the vassal rack, which allows your master to thrall crewmembers into his minions.\n
+ Aid your master in bringing their victims here and keeping them secure.\n
+ You can secure victims to the vassal rack by click dragging the victim onto the rack while it is secured"} */
+
/obj/structure/bloodsucker/vassalrack/MouseDrop_T(atom/movable/O, mob/user)
- if (!O.Adjacent(src) || O == user || !isliving(O) || !isliving(user) || useLock || has_buckled_mobs() || user.incapacitated())
+ if(!O.Adjacent(src) || O == user || !isliving(O) || !isliving(user) || useLock || has_buckled_mobs() || user.incapacitated())
return
- if (!anchored && user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
+ if(!anchored && user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
to_chat(user, "Until this rack is secured in place, it cannot serve its purpose.")
return
// PULL TARGET: Remember if I was pullin this guy, so we can restore this
@@ -126,11 +139,9 @@
// * MOVE! *
O.forceMove(drop_location())
// PULL TARGET: Restore?
- if (waspulling)
+ if(waspulling)
owner.start_pulling(O, wasgrabstate, TRUE)
// NOTE: in bs_lunge.dm, we use [target.grabbedby(owner)], which simulates doing a grab action. We don't want that though...we're cutting directly back to where we were in a grab.
-
-
// Do Action!
useLock = TRUE
if(do_mob(user, O, 50))
@@ -138,19 +149,19 @@
useLock = FALSE
/obj/structure/bloodsucker/vassalrack/AltClick(mob/user)
- if (!has_buckled_mobs() || !isliving(user) || useLock)
+ if(!has_buckled_mobs() || !isliving(user) || useLock)
return
// Attempt Release (Owner vs Non Owner)
var/mob/living/carbon/C = pick(buckled_mobs)
- if (C)
- if (user == owner)
+ if(C)
+ if(user == owner)
unbuckle_mob(C)
else
user_unbuckle_mob(C,user)
/obj/structure/bloodsucker/vassalrack/proc/attach_victim(mob/living/M, mob/living/user)
// Standard Buckle Check
- if (!buckle_mob(M)) // force=TRUE))
+ if(!buckle_mob(M)) // force=TRUE))
return
// Attempt Buckle
user.visible_message("[user] straps [M] into the rack, immobilizing them.", \
@@ -164,9 +175,7 @@
m180.Turn(180)//90)//180
animate(M, transform = m180, time = 2)
M.pixel_y = -2 //M.get_standard_pixel_y_offset(120)//180)
-
update_icon()
-
// Torture Stuff
convert_progress = 2 // Goes down unless you start over.
disloyalty_confirm = FALSE // New guy gets the chance to say NO if he's special.
@@ -174,8 +183,8 @@
/obj/structure/bloodsucker/vassalrack/user_unbuckle_mob(mob/living/M, mob/user)
// Attempt Unbuckle
- if (!user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
- if (M == user)
+ if(!user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
+ if(M == user)
M.visible_message("[user] tries to release themself from the rack!",\
"You attempt to release yourself from the rack!") // For sound if not seen --> "You hear a squishy wet noise.")
else
@@ -188,7 +197,7 @@
unbuckle_mob(M)
/obj/structure/bloodsucker/vassalrack/unbuckle_mob(mob/living/buckled_mob)//, force=FALSE)
- if (!..())
+ if(!..())
return
var/matrix/m180 = matrix(buckled_mob.transform)
m180.Turn(180)//-90)//180
@@ -197,13 +206,11 @@
src.visible_message(text("[buckled_mob][buckled_mob.stat==DEAD?"'s corpse":""] slides off of the rack."))
density = FALSE
buckled_mob.AdjustKnockdown(30)
-
update_icon()
-
useLock = FALSE // Failsafe
/obj/structure/bloodsucker/vassalrack/attackby(obj/item/W, mob/user, params)
- if (has_buckled_mobs()) // Attack w/weapon vs guy standing there? Don't do an attack.
+ if(has_buckled_mobs()) // Attack w/weapon vs guy standing there? Don't do an attack.
attack_hand(user)
return FALSE
return ..()
@@ -213,14 +220,14 @@
//if(.)
// return
// Go away. Torturing.
- if (useLock)
+ if(useLock)
return
var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
// CHECK ONE: Am I claiming this? Is it in the right place?
- if (istype(bloodsuckerdatum) && !owner)
- if (!bloodsuckerdatum.lair)
+ if(istype(bloodsuckerdatum) && !owner)
+ if(!bloodsuckerdatum.lair)
to_chat(user, "You don't have a lair. Claim a coffin to make that location your lair.")
- if (bloodsuckerdatum.lair != get_area(src))
+ if(bloodsuckerdatum.lair != get_area(src))
to_chat(user, "You may only activate this structure in your lair: [bloodsuckerdatum.lair].")
return
switch(alert(user,"Do you wish to afix this structure here? Be aware you wont be able to unsecure it anymore","Secure [src]","Yes", "No"))
@@ -230,16 +237,16 @@
anchored = TRUE
return //No, you cant move this ever again
// No One Home
- if (!has_buckled_mobs())
+ if(!has_buckled_mobs())
return
// CHECK TWO: Am I a non-bloodsucker?
var/mob/living/carbon/C = pick(buckled_mobs)
- if (!istype(bloodsuckerdatum))
+ if(!istype(bloodsuckerdatum))
// Try to release this guy
user_unbuckle_mob(C, user)
return
// Bloodsucker Owner! Let the boy go.
- if (C.mind)
+ if(C.mind)
var/datum/antagonist/vassal/vassaldatum = C.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
if (istype(vassaldatum) && vassaldatum.master == bloodsuckerdatum || C.stat >= DEAD)
unbuckle_mob(C)
@@ -250,7 +257,7 @@
/obj/structure/bloodsucker/vassalrack/proc/torture_victim(mob/living/user, mob/living/target)
// Check Bloodmob/living/M, force = FALSE, check_loc = TRUE
- if (user.blood_volume < convert_cost + 5)
+ if(user.blood_volume < convert_cost + 5)
to_chat(user, "You don't have enough blood to initiate the Dark Communion with [target].")
return
// Prep...
@@ -259,21 +266,21 @@
// Step Two: Break mindshielding/antag (on approve)
// Step Three: Blood Ritual
// Conversion Process
- if (convert_progress > 0)
+ if(convert_progress > 0)
to_chat(user, "You prepare to initiate [target] into your service.")
- if (!do_torture(user,target))
+ if(!do_torture(user,target))
to_chat(user, "The ritual has been interrupted!")
else
convert_progress -- // Ouch. Stop. Don't.
// All done!
- if (convert_progress <= 0)
+ if(convert_progress <= 0)
// FAIL: Can't be Vassal
- if (!SSticker.mode.can_make_vassal(target, user, display_warning=FALSE)) // If I'm an unconvertable Antag ONLY
- to_chat(user, "[target] doesn't respond to your persuasion. It doesn't appear they can be converted to follow you. \[ALT+click to release\]")
+ if(!SSticker.mode.can_make_vassal(target, user, display_warning=FALSE) && HAS_TRAIT(target, TRAIT_MINDSHIELD)) // If I'm an unconvertable Antag ONLY
+ to_chat(user, "[target] doesn't respond to your persuasion. It doesn't appear they can be converted to follow you, they either have a mindshield or their external loyalties are too difficult for you to break.\[ALT+click to release\]")
convert_progress ++ // Pop it back up some. Avoids wasting Blood on a lost cause.
// SUCCESS: All done!
else
- if (RequireDisloyalty(target))
+ if(RequireDisloyalty(target))
to_chat(user, "[target] has external loyalties! [target.p_they(TRUE)] will require more persuasion to break [target.p_them()] to your will!")
else
to_chat(user, "[target] looks ready for the Dark Communion.")
@@ -283,8 +290,8 @@
useLock = FALSE
return
// Check: Mindshield & Antag
- if (!disloyalty_confirm && RequireDisloyalty(target))
- if (!do_disloyalty(user,target))
+ if(!disloyalty_confirm && RequireDisloyalty(target))
+ if(!do_disloyalty(user,target))
to_chat(user, "The ritual has been interrupted!")
else if (!disloyalty_confirm)
to_chat(user, "[target] refuses to give into your persuasion. Perhaps a little more?")
@@ -293,7 +300,7 @@
useLock = FALSE
return
// Check: Blood
- if (user.blood_volume < convert_cost)
+ if(user.blood_volume < convert_cost)
to_chat(user, "You don't have enough blood to initiate the Dark Communion with [target].")
useLock = FALSE
return
@@ -307,8 +314,8 @@
useLock = FALSE
return
// Convert to Vassal!
- if (bloodsuckerdatum && bloodsuckerdatum.attempt_turn_vassal(target))
- remove_loyalties(target) // In case of Mindshield, or appropriate Antag (Traitor, Internal, etc)
+ if(bloodsuckerdatum && bloodsuckerdatum.attempt_turn_vassal(target))
+ //remove_loyalties(target) // In case of Mindshield, or appropriate Antag (Traitor, Internal, etc)
//if (!target.buckled)
// to_chat(user, "The ritual has been interrupted!")
// useLock = FALSE
@@ -328,28 +335,28 @@
// Get Bodypart
var/target_string = ""
var/obj/item/bodypart/BP = null
- if (iscarbon(target))
+ if(iscarbon(target))
var/mob/living/carbon/C = target
BP = pick(C.bodyparts)
- if (BP)
+ if(BP)
target_string += BP.name
// Get Weapon
var/obj/item/I = user.get_active_held_item()
- if (!istype(I))
+ if(!istype(I))
I = user.get_inactive_held_item()
// Create Strings
var/method_string = I?.attack_verb?.len ? pick(I.attack_verb) : pick("harmed","tortured","wrenched","twisted","scoured","beaten","lashed","scathed")
var/weapon_string = I ? I.name : pick("bare hands","hands","fingers","fists")
// Weapon Bonus + SFX
- if (I)
+ if(I)
torture_time -= I.force / 4
torture_dmg_brute += I.force / 4
//torture_dmg_burn += I.
- if (I.sharpness == IS_SHARP)
+ if(I.sharpness == IS_SHARP)
torture_time -= 1
- else if (I.sharpness == IS_SHARP_ACCURATE)
+ else if(I.sharpness == IS_SHARP_ACCURATE)
torture_time -= 2
- if (istype(I, /obj/item/weldingtool))
+ if(istype(I, /obj/item/weldingtool))
var/obj/item/weldingtool/welder = I
welder.welding = TRUE
torture_time -= 5
@@ -357,15 +364,15 @@
I.play_tool_sound(target)
torture_time = max(50, torture_time * 10) // Minimum 5 seconds.
// Now run process.
- if (!do_mob(user, target, torture_time * mult))
+ if(!do_mob(user, target, torture_time * mult))
return FALSE
// SUCCESS
- if (I)
+ if(I)
playsound(loc, I.hitsound, 30, 1, -1)
I.play_tool_sound(target)
target.visible_message("[user] has [method_string] [target]'s [target_string] with [user.p_their()] [weapon_string]!", \
"[user] has [method_string] your [target_string] with [user.p_their()] [weapon_string]!")
- if (!target.is_muzzled())
+ if(!target.is_muzzled())
target.emote("scream")
target.Jitter(5)
target.apply_damages(brute = torture_dmg_brute, burn = torture_dmg_burn, def_zone = (BP ? BP.body_zone : null)) // take_overall_damage(6,0)
@@ -375,49 +382,49 @@
// OFFER YES/NO NOW!
spawn(10)
- if (useLock && target && target.client) // Are we still torturing? Did we cancel? Are they still here?
+ if(useLock && target && target.client) // Are we still torturing? Did we cancel? Are they still here?
to_chat(user, "[target] has been given the opportunity for servitude. You await their decision...")
var/alert_text = "You are being tortured! Do you want to give in and pledge your undying loyalty to [user]?"
- if (HAS_TRAIT(target, TRAIT_MINDSHIELD))
+ /* if(HAS_TRAIT(target, TRAIT_MINDSHIELD))
alert_text += "\n\nYou will no longer be loyal to the station!"
- if (SSticker.mode.AmValidAntag(target.mind))
+ if(SSticker.mode.AmValidAntag(target.mind)) */
alert_text += "\n\nYou will not lose your current objectives, but they come second to the will of your new master!"
switch(alert(target, alert_text,"THE HORRIBLE PAIN! WHEN WILL IT END?!","Yes, Master!", "NEVER!"))
if("Yes, Master!")
disloyalty_accept(target)
else
disloyalty_refuse(target)
- if (!do_torture(user,target, 2))
+ if(!do_torture(user,target, 2))
return FALSE
// NOTE: We only remove loyalties when we're CONVERTED!
return TRUE
/obj/structure/bloodsucker/vassalrack/proc/RequireDisloyalty(mob/living/target)
- return SSticker.mode.AmValidAntag(target.mind) || HAS_TRAIT(target, TRAIT_MINDSHIELD)
+ return SSticker.mode.AmValidAntag(target.mind) //|| HAS_TRAIT(target, TRAIT_MINDSHIELD)
/obj/structure/bloodsucker/vassalrack/proc/disloyalty_accept(mob/living/target)
// FAILSAFE: Still on the rack?
- if (!(locate(target) in buckled_mobs))
+ if(!(locate(target) in buckled_mobs))
return
// NOTE: You can say YES after torture. It'll apply to next time.
disloyalty_confirm = TRUE
- if (HAS_TRAIT(target, TRAIT_MINDSHIELD))
+ /*if(HAS_TRAIT(target, TRAIT_MINDSHIELD))
to_chat(target, "You give in to the will of your torturer. If they are successful, you will no longer be loyal to the station!")
-
+*/
/obj/structure/bloodsucker/vassalrack/proc/disloyalty_refuse(mob/living/target)
// FAILSAFE: Still on the rack?
- if (!(locate(target) in buckled_mobs))
+ if(!(locate(target) in buckled_mobs))
return
// Failsafe: You already said YES.
- if (disloyalty_confirm)
+ if(disloyalty_confirm)
return
to_chat(target, "You refuse to give in! You will not break!")
/obj/structure/bloodsucker/vassalrack/proc/remove_loyalties(mob/living/target)
// Find Mind Implant & Destroy
- if (HAS_TRAIT(target, TRAIT_MINDSHIELD))
+ if(HAS_TRAIT(target, TRAIT_MINDSHIELD))
for(var/obj/item/implant/I in target.implants)
if(I.type == /obj/item/implant/mindshield)
I.removed(target,silent=TRUE)
@@ -444,6 +451,15 @@
/obj/structure/bloodsucker/candelabrum/update_icon()
icon_state = "candelabrum[lit ? "_lit" : ""]"
+/obj/structure/bloodsucker/candelabrum/examine(mob/user)
+ . = ..()
+ if((user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) || isobserver(user))
+ . += {"This is a magical candle which drains at the sanity of mortals who are not under your command while it is active."}
+ . += {"You can alt click on it from any range to turn it on remotely, or simply be next to it and click on it to turn it on and off normally."}
+/* if(user.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
+ . += {"This is a magical candle which drains at the sanity of the fools who havent yet accepted your master, as long as it is active.\n
+ You can turn it on and off by clicking on it while you are next to it"} */
+
/obj/structure/bloodsucker/candelabrum/attack_hand(mob/user)
var/datum/antagonist/bloodsucker/V = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER) //I wish there was a better way to do this
var/datum/antagonist/vassal/T = user.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
@@ -477,4 +493,5 @@
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "vampcandle", /datum/mood_event/vampcandle)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// OTHER THINGS TO USE: HUMAN BLOOD. /obj/effect/decal/cleanable/blood
+
/obj/item/restraints/legcuffs/beartrap/bloodsucker
diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_lair.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_lair.dm
index f93d4d4261..f68191d6d7 100644
--- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_lair.dm
+++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_lair.dm
@@ -28,9 +28,6 @@
return
*/
-
-
-
/datum/antagonist/bloodsucker/proc/RunLair()
set waitfor = FALSE // Don't make on_gain() wait for this function to finish. This lets this code run on the side.
while(!AmFinalDeath() && coffin && lair)
@@ -64,7 +61,7 @@
// STEP TWO: DIRT
new /obj/effect/decal/cleanable/dirt (T_Dirty)
// Find Animals in Area
- if(rand(0,2) == 0)
+ /* if(rand(0,2) == 0)
var/mobCount = 0
var/mobMax = CLAMP(area_turfs.len / 25, 1, 4)
for (var/turf/T in area_turfs)
@@ -74,17 +71,16 @@
mobCount ++
if (mobCount >= mobMax) // Already at max
break
- // Spawn One
+ Spawn One
if(mobCount < mobMax)
- // Seek Out Location
+ Seek Out Location
while(area_turfs.len > 0)
- sleep(240) //We dont want this to happen often
var/turf/T = pick(area_turfs) // We use while&pick instead of a for/loop so it's random, rather than from the top of the list.
if(T && !T.density)
var/mob/living/simple_animal/SA = /mob/living/simple_animal/mouse // pick(/mob/living/simple_animal/mouse,/mob/living/simple_animal/mouse,/mob/living/simple_animal/mouse, /mob/living/simple_animal/hostile/retaliate/bat) //prob(300) /mob/living/simple_animal/mouse,
new SA (T)
break
- area_turfs -= T
+ area_turfs -= T*/
// NOTE: area_turfs is now cleared out!
if(coffin)
coffin.UnclaimCoffin()
diff --git a/code/modules/antagonists/bloodsucker/powers/bs_mesmerize.dm b/code/modules/antagonists/bloodsucker/powers/bs_mesmerize.dm
index 7d825d6f44..94bc0e11d0 100644
--- a/code/modules/antagonists/bloodsucker/powers/bs_mesmerize.dm
+++ b/code/modules/antagonists/bloodsucker/powers/bs_mesmerize.dm
@@ -11,7 +11,7 @@
button_icon_state = "power_mez"
bloodcost = 30
cooldown = 200
- target_range = 2
+ target_range = 1
power_activates_immediately = FALSE
message_Trigger = "Whom will you subvert to your will?"
must_be_capacitated = TRUE
@@ -94,8 +94,8 @@
if(do_mob(user, target, 40, 0, TRUE, extra_checks=CALLBACK(src, .proc/ContinueActive, user, target)))
PowerActivatedSuccessfully() // PAY COST! BEGIN COOLDOWN!
- var/power_time = 90 + level_current * 15
- target.silent = power_time + 50
+ var/power_time = 90 + level_current * 12
+ target.silent = power_time + 20
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, 100 + level_current * 15)
to_chat(user, "[target] is fixed in place by your hypnotic gaze.")
target.Stun(power_time)
diff --git a/code/modules/language/vampiric.dm b/code/modules/language/vampiric.dm
index e03fc235ba..6da54ce844 100644
--- a/code/modules/language/vampiric.dm
+++ b/code/modules/language/vampiric.dm
@@ -2,7 +2,7 @@
/datum/language/vampiric
name = "Blah-Sucker"
- desc = "The native language of the Bloodsucker elders, learned intuitively by Fledglings as they pass from death into immortality."
+ desc = "The native language of the Bloodsucker elders, learned intuitively by Fledglings and as they pass from death into immortality. Thralls are also given the ability to speak this as apart of their conversion ritual."
speech_verb = "growls"
ask_verb = "growls"
exclaim_verb = "snarls"
@@ -10,6 +10,7 @@
key = "b"
space_chance = 40
default_priority = 90
+ icon_state = "bloodsucker"
flags = TONGUELESS_SPEECH | LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD // Hide the icon next to your text if someone doesn't know this language.
syllables = list(
@@ -22,6 +23,3 @@
"froz","etz","tzil",
"t'","k'","t'","k'","th'","tz'"
)
-
- icon_state = "bloodsucker"
- icon = 'icons/mob/hud.dmi'
diff --git a/code/modules/mob/living/simple_animal/astral.dm b/code/modules/mob/living/simple_animal/astral.dm
index 2aafedb149..3d0c335989 100644
--- a/code/modules/mob/living/simple_animal/astral.dm
+++ b/code/modules/mob/living/simple_animal/astral.dm
@@ -27,6 +27,7 @@
unsuitable_atmos_damage = 0
minbodytemp = 0
maxbodytemp = 100000
+ blood_volume = 0
/mob/living/simple_animal/astral/death()
icon_state = "shade_dead"
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index e61cfad068..7a653f4aa4 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -14,6 +14,7 @@
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
maxbodytemp = INFINITY
minbodytemp = 0
+ blood_volume = 0
has_unlimited_silicon_privilege = 1
sentience_type = SENTIENCE_ARTIFICIAL
status_flags = NONE //no default canpush
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index b7067f8904..be900aa4ef 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -33,6 +33,7 @@
initial_language_holder = /datum/language_holder/construct
deathmessage = "collapses in a shattered heap."
hud_type = /datum/hud/constructs
+ blood_volume = 0
var/list/construct_spells = list()
var/playstyle_string = "You are a generic construct! Your job is to not exist, and you should probably adminhelp this."
var/master = null
@@ -459,4 +460,3 @@
hud_used.healths.icon_state = "[icon_state]_health5"
else
hud_used.healths.icon_state = "[icon_state]_health6"
-
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index 387973b979..7e0e43055f 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -50,6 +50,7 @@
dextrous_hud_type = /datum/hud/dextrous/drone
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
see_in_dark = 7
+ blood_volume = 0
can_be_held = TRUE
held_items = list(null, null)
var/staticChoice = "static"
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index e3ef14c784..1bd434b233 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -20,6 +20,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
icon_living = "magicOrange"
icon_dead = "magicOrange"
speed = 0
+ blood_volume = 0
a_intent = INTENT_HARM
stop_automated_movement = 1
movement_type = FLYING // Immunity to chasms and landmines, etc.
diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm
index 4e7cb0ac70..bc766f7409 100644
--- a/code/modules/mob/living/simple_animal/hostile/faithless.dm
+++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm
@@ -19,6 +19,7 @@
spacewalk = TRUE
stat_attack = UNCONSCIOUS
robust_searching = 1
+ blood_volume = 0
harm_intent_damage = 10
obj_damage = 50
@@ -42,4 +43,4 @@
var/mob/living/carbon/C = target
C.Knockdown(60)
C.visible_message("\The [src] knocks down \the [C]!", \
- "\The [src] knocks you down!")
\ No newline at end of file
+ "\The [src] knocks you down!")
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
index ece5d7e24c..a9576a467b 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
@@ -28,6 +28,7 @@
gold_core_spawnable = HOSTILE_SPAWN
del_on_death = 1
loot = list(/obj/effect/decal/cleanable/robot_debris)
+ blood_volume = 0
do_footstep = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm
index 1a894734d8..38dd17a09b 100644
--- a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm
+++ b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm
@@ -30,6 +30,7 @@
robust_searching = TRUE
stat_attack = UNCONSCIOUS
anchored = TRUE
+ blood_volume = 0
var/combatant_state = SEEDLING_STATE_NEUTRAL
var/obj/seedling_weakpoint/weak_point
var/mob/living/beam_debuff_target
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index cca39cfea6..d96889cfb6 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -50,6 +50,7 @@ Difficulty: Normal
armour_penetration = 75
melee_damage_lower = 15
melee_damage_upper = 20
+ blood_volume = 0
speed = 1
move_to_delay = 11
ranged = 1
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
index 20916c9311..51919dad24 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
@@ -22,6 +22,7 @@
environment_smash = ENVIRONMENT_SMASH_NONE
sentience_type = SENTIENCE_BOSS
layer = LARGE_MOB_LAYER
+ blood_volume = 0
var/doing_move_loop = FALSE
var/mob/living/set_target
var/timerid
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm
index 32e1c4d047..bfe8349192 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm
@@ -31,6 +31,7 @@
movement_type = FLYING
pressure_resistance = 300
gold_core_spawnable = NO_SPAWN //too spooky for science
+ blood_volume = 0
var/ghost_hair_style
var/ghost_hair_color
var/mutable_appearance/ghost_hair
diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm
index d0ae01f443..48b69a1f5c 100644
--- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm
+++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm
@@ -12,6 +12,7 @@
emote_see = list("rattles")
a_intent = INTENT_HARM
maxHealth = 40
+ blood_volume = 0
health = 40
speed = 1
harm_intent_damage = 5
diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm
index 804989e71e..da423f3788 100644
--- a/code/modules/mob/living/simple_animal/hostile/statue.dm
+++ b/code/modules/mob/living/simple_animal/hostile/statue.dm
@@ -18,6 +18,7 @@
maxHealth = 50000
health = 50000
healable = 0
+ blood_volume = 0
harm_intent_damage = 10
obj_damage = 100
diff --git a/code/modules/mob/living/simple_animal/hostile/stickman.dm b/code/modules/mob/living/simple_animal/hostile/stickman.dm
index 7a86870aa1..fa5cb151ed 100644
--- a/code/modules/mob/living/simple_animal/hostile/stickman.dm
+++ b/code/modules/mob/living/simple_animal/hostile/stickman.dm
@@ -13,6 +13,7 @@
response_disarm = "shoves"
response_harm = "hits"
speed = 0
+ blood_volume = 0
stat_attack = UNCONSCIOUS
robust_searching = 1
environment_smash = ENVIRONMENT_SMASH_NONE
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index 3bd24c4df7..32ef52a6ae 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -31,6 +31,7 @@
loot = list(/obj/item/ectoplasm)
del_on_death = TRUE
initial_language_holder = /datum/language_holder/construct
+ blood_volume = 0
/mob/living/simple_animal/shade/death()
deathmessage = "lets out a contented sigh as [p_their()] form unwinds."
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 185d717a00..d1e10ea693 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -26,6 +26,7 @@
health = 150
healable = 0
gender = NEUTER
+ blood_volume = 0 //Until someome reworks for them to have slime jelly
see_in_dark = 8
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 00ff3885ea..6ef262c7d7 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -30,7 +30,7 @@
if(iscarbon(L))
var/mob/living/carbon/C = L
var/blood_id = C.get_blood_id()
- if((blood_id == "blood" || blood_id == "jellyblood") && (method == INJECT || (method == INGEST && C.dna && C.dna.species && (DRINKSBLOOD in C.dna.species.species_traits))))
+ if((HAS_TRAIT(C, TRAIT_NOMARROW) || blood_id == "blood" || blood_id == "jellyblood") && (method == INJECT || (method == INGEST && C.dna && C.dna.species && (DRINKSBLOOD in C.dna.species.species_traits))))
C.blood_volume = min(C.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM * C.blood_ratio)
// we don't care about bloodtype here, we're just refilling the mob
diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm
index 04cec0bc91..61449fc153 100644
--- a/code/modules/reagents/reagent_containers/blood_pack.dm
+++ b/code/modules/reagents/reagent_containers/blood_pack.dm
@@ -112,14 +112,14 @@
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))
+ if(!do_mob(user, M, 50))
return
else
- if (!do_mob(user, M, 10))
+ if(!do_mob(user, M, 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)
+ 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/fraction = min(gulp_size / reagents.total_volume, 1)
diff --git a/icons/misc/language.dmi b/icons/misc/language.dmi
index dcd10a51b7..6f6f2546d5 100644
Binary files a/icons/misc/language.dmi and b/icons/misc/language.dmi differ
diff --git a/icons/misc/mark_icons.dmi b/icons/misc/mark_icons.dmi
new file mode 100644
index 0000000000..1d8472752b
Binary files /dev/null and b/icons/misc/mark_icons.dmi differ