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 "Loyal to their bloodsucking masters, the Vassals were:

" +/*/datum/antagonist/vassal/roundend_report_header() + return "Loyal to their bloodsucking masters, the Vassals were:

"*/ 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