This commit is contained in:
Artur
2020-03-24 16:55:46 +02:00
parent c6a8515297
commit 9bb7529a49
15 changed files with 60 additions and 81 deletions
@@ -1,12 +1,6 @@
// 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))
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.
/mob/living/proc/HaveBloodsuckerBodyparts(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 != "")
to_chat(src, "<span class='warning'>Without a heart, you are incapable of [displaymessage].</span>")
@@ -21,33 +15,6 @@
return FALSE
return TRUE
// GET DAMAGE
// Do NOT count the damage on prosthetics for this.
/mob/living/proc/getBruteLoss_nonProsthetic()
return getBruteLoss()
/mob/living/proc/getFireLoss_nonProsthetic()
return getFireLoss()
/mob/living/carbon/getBruteLoss_nonProsthetic()
var/amount = 0
for(var/obj/item/bodypart/BP in bodyparts)
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)
amount += BP.burn_dam
return amount
/mob/living/carbon
// EXAMINING
/mob/living/carbon/human/proc/ReturnVampExamine(var/mob/viewer)
if(!mind || !viewer.mind)
@@ -99,7 +99,7 @@
var/amInCoffinWhileTorpor = istype(C.loc, /obj/structure/closet/crate/coffin) && (mult == 0 || HAS_TRAIT(C, TRAIT_DEATHCOMA)) // Check for mult 0 OR death coma. (mult 0 means we're testing from coffin)
if(amInCoffinWhileTorpor)
mult *= 4 // Increase multiplier if we're sleeping in a coffin.
fireheal = min(C.getFireLoss_nonProsthetic(), regenRate) // NOTE: Burn damage ONLY heals in torpor.
fireheal = min(C.getFireLoss(), regenRate) // NOTE: Burn damage ONLY heals in torpor.
costMult = 0.25
C.ExtinguishMob()
CureDisabilities() // Extinguish Fire
@@ -113,7 +113,7 @@
//if (C.getFireLoss() > owner.current.getMaxHealth())
// fireheal = regenRate / 2
// BRUTE: Always Heal
var/bruteheal = min(C.getBruteLoss_nonProsthetic(), regenRate)
var/bruteheal = min(C.getBruteLoss(), regenRate)
var/toxinheal = min(C.getToxLoss(), regenRate)
// Heal if Damaged
if(bruteheal + fireheal + toxinheal > 0) // Just a check? Don't heal/spend, and return.
@@ -130,24 +130,23 @@
return TRUE // Healed! Done for this tick.
if(amInCoffinWhileTorpor) // Limbs? (And I have no other healing)
var/list/missing = owner.current.get_missing_limbs() // Heal Missing
if (missing.len) // Cycle through ALL limbs and regen them!
if(missing.len) // Cycle through ALL limbs and regen them!
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
var/obj/item/bodypart/L = owner.current.get_bodypart(targetLimbZone) // 2) Limb returns Damaged
AddBloodVolume(50 * costMult) // Costs blood to heal
L.brute_dam = 60
to_chat(owner.current, "<span class='notice'>Your flesh knits as it regrows [L]!</span>")
playsound(owner.current, 'sound/magic/demon_consume.ogg', 50, 1)
// DONE! After regenerating ANY number of limbs, we stop here.
return TRUE
/*else // REMOVED: For now, let's just leave prosthetics on. Maybe you WANT to be a robovamp.
else // REMOVED: For now, let's just leave prosthetics on. Maybe you WANT to be a robovamp. In actuality, robovamps are very bad.
// Remove Prosthetic/False Limb
for(var/obj/item/bodypart/BP in C.bodyparts)
message_admins("T1: [BP] ")
if (istype(BP) && BP.status == 2)
message_admins("T2: [BP] ")
if(istype(BP) && BP.status == 2)
to_chat(owner.current, "<span class='notice'>Your body expels the [BP]!</span>")
BP.drop_limb()
return TRUE */
return TRUE
// NOTE: Limbs have a "status", like their hosts "stat". 2 is dead (aka Prosthetic). 1 seems to be idle/alive.*/
return FALSE
@@ -180,7 +179,10 @@
if(owner.current.blood_volume < BLOOD_VOLUME_BAD / 2)
owner.current.blur_eyes(8 - 8 * (owner.current.blood_volume / BLOOD_VOLUME_BAD))
// Nutrition
owner.current.nutrition = min(owner.current.blood_volume, NUTRITION_LEVEL_FED) // <-- 350 //NUTRITION_LEVEL_FULL
if(owner.current.blood_volume < BLOOD_VOLUME_NORMAL)
owner.current.nutrition = min(owner.current.blood_volume, NUTRITION_LEVEL_WELL_FED)
else if(owner.current.blood_volume < BLOOD_VOLUME_SAFE)
owner.current.nutrition = min(owner.current.blood_volume, NUTRITION_LEVEL_FED) // <-- 350 //NUTRITION_LEVEL_FULL
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DEATH
@@ -190,7 +192,7 @@
/datum/antagonist/bloodsucker/proc/HandleDeath()
// FINAL DEATH
// Fire Damage? (above double health)
if(owner.current.getFireLoss_nonProsthetic() >= owner.current.maxHealth * 2.5)
if(owner.current.getFireLoss() >= owner.current.maxHealth * 3)
FinalDeath()
return
// Staked while "Temp Death" or Asleep
@@ -210,8 +212,8 @@
// for (var/datum/action/bloodsucker/masquerade/P in powers)
// P.Deactivate()
// TEMP DEATH
var/total_brute = owner.current.getBruteLoss_nonProsthetic()
var/total_burn = owner.current.getFireLoss_nonProsthetic()
var/total_brute = owner.current.getBruteLoss()
var/total_burn = owner.current.getFireLoss()
var/total_toxloss = owner.current.getToxLoss() //This is neater than just putting it in total_damage
var/total_damage = total_brute + total_burn + total_toxloss
// Died? Convert to Torpor (fake death)
@@ -219,7 +221,7 @@
Torpor_Begin()
to_chat(owner, "<span class='danger'>Your immortal body will not yet relinquish your soul to the abyss. You enter Torpor.</span>")
sleep(30) //To avoid spam
if (poweron_masquerade == TRUE)
if(poweron_masquerade == TRUE)
to_chat(owner, "<span class='warning'>Your wounds will not heal until you disable the <span class='boldnotice'>Masquerade</span> power.</span>")
// End Torpor:
else // No damage, OR toxin healed AND brute healed and NOT in coffin (since you cannot heal burn)
@@ -229,17 +231,14 @@
Torpor_End()
// Fake Unconscious
if(poweron_masquerade == TRUE && total_damage >= owner.current.getMaxHealth() - HEALTH_THRESHOLD_FULLCRIT)
owner.current.Unconscious(20,1)
//HEALTH_THRESHOLD_CRIT 0
//HEALTH_THRESHOLD_FULLCRIT -30
//HEALTH_THRESHOLD_DEAD -100
owner.current.Unconscious(20, 1)
/datum/antagonist/bloodsucker/proc/Torpor_Begin(amInCoffin=FALSE)
/datum/antagonist/bloodsucker/proc/Torpor_Begin(amInCoffin = FALSE)
owner.current.stat = UNCONSCIOUS
owner.current.fakedeath("bloodsucker") // Come after UNCONSCIOUS or else it fails
ADD_TRAIT(owner.current, TRAIT_FAKEDEATH, "bloodsucker") // Come after UNCONSCIOUS or else it fails
ADD_TRAIT(owner.current, TRAIT_NODEATH, "bloodsucker") // Without this, you'll just keep dying while you recover.
ADD_TRAIT(owner.current, TRAIT_RESISTHIGHPRESSURE, "bloodsucker") // So you can heal in 0 G. otherwise you just...heal forever.
ADD_TRAIT(owner.current, TRAIT_RESISTLOWPRESSURE, "bloodsucker") // So you can heal in 0 G. otherwise you just...heal forever.
ADD_TRAIT(owner.current, TRAIT_RESISTLOWPRESSURE, "bloodsucker")
// Visuals
owner.current.update_sight()
owner.current.reload_fullscreen()
@@ -248,10 +247,9 @@
if(power.active && !power.can_use_in_torpor)
power.DeactivatePower()
/datum/antagonist/bloodsucker/proc/Torpor_End()
REMOVE_TRAIT(owner.current, TRAIT_FAKEDEATH, "bloodsucker")
owner.current.stat = SOFT_CRIT
owner.current.cure_fakedeath("bloodsucker") // Come after SOFT_CRIT or else it fails
REMOVE_TRAIT(owner.current, TRAIT_NODEATH, "bloodsucker")
REMOVE_TRAIT(owner.current, TRAIT_RESISTHIGHPRESSURE, "bloodsucker")
REMOVE_TRAIT(owner.current, TRAIT_RESISTLOWPRESSURE, "bloodsucker")
@@ -288,14 +286,15 @@
owner.current.visible_message("<span class='warning'>[owner.current]'s skin crackles and dries, their skin and bones withering to dust. A hollow cry whips from what is now a sandy pile of remains.</span>", \
"<span class='userdanger'>Your soul escapes your withering body as the abyss welcomes you to your Final Death.</span>", \
"<span class='italics'>You hear a dry, crackling sound.</span>")
sleep(50)
owner.current.dust()
// Fledglings get Gibbed
else
owner.current.visible_message("<span class='warning'>[owner.current]'s skin bursts forth in a spray of gore and detritus. A horrible cry echoes from what is now a wet pile of decaying meat.</span>", \
"<span class='userdanger'>Your soul escapes your withering body as the abyss welcomes you to your Final Death.</span>", \
"<span class='italics'>You hear a wet, bursting sound.</span>")
owner.current.gib(TRUE, FALSE, FALSE)//Brain cloning is wierd and allows hellbounds. Lets destroy the brain for safety.
playsound(owner.current.loc, 'sound/effects/tendril_destroyed.ogg', 40, 1)
owner.current.gib(TRUE, FALSE, FALSE) //Brain cloning is wierd and allows hellbounds. Lets destroy the brain for safety.
playsound(owner.current, 'sound/effects/tendril_destroyed.ogg', 40, TRUE)
@@ -305,15 +304,15 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/mob/proc/CheckBloodsuckerEatFood(var/food_nutrition)
/mob/proc/CheckBloodsuckerEatFood(food_nutrition)
if(!isliving(src))
return
var/mob/living/L = src
if(!L.AmBloodsucker())
if(!AmBloodsucker(L))
return
// We're a bloodsucker? Try to eat food...
var/datum/antagonist/bloodsucker/bloodsuckerdatum = mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
bloodsuckerdatum.bloodsucker_disgust(food_nutrition)
var/datum/antagonist/bloodsucker/B = L.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
B.handle_eat_human_food(food_nutrition)
/datum/antagonist/bloodsucker/proc/handle_eat_human_food(food_nutrition, puke_blood = TRUE, masquerade_override) // Called from snacks.dm and drinks.dm
@@ -132,7 +132,7 @@
/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())
return
if(!anchored && isbloodsucker(user))
if(!anchored && AmBloodsucker(user))
to_chat(user, "<span class='danger'>Until this rack is secured in place, it cannot serve its purpose.</span>")
return
// PULL TARGET: Remember if I was pullin this guy, so we can restore this
@@ -185,7 +185,7 @@
/obj/structure/bloodsucker/vassalrack/user_unbuckle_mob(mob/living/M, mob/user)
// Attempt Unbuckle
if(!isbloodsucker(user))
if(!AmBloodsucker(user))
if(M == user)
M.visible_message("<span class='danger'>[user] tries to release themself from the rack!</span>",\
"<span class='danger'>You attempt to release yourself from the rack!</span>") // For sound if not seen --> "<span class='italics'>You hear a squishy wet noise.</span>")
@@ -462,7 +462,7 @@
/obj/structure/bloodsucker/candelabrum/examine(mob/user)
. = ..()
if((isbloodsucker()) || isobserver(user))
if((AmBloodsucker(user)) || isobserver(user))
. += {"<span class='cult'>This is a magical candle which drains at the sanity of mortals who are not under your command while it is active.</span>"}
. += {"<span class='cult'>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.</span>"}
/* if(user.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
@@ -471,12 +471,12 @@
/obj/structure/bloodsucker/candelabrum/attack_hand(mob/user)
var/datum/antagonist/vassal/T = user.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
if(isbloodsucker(user) || istype(T))
if(AmBloodsucker(user) || istype(T))
toggle()
/obj/structure/bloodsucker/candelabrum/AltClick(mob/user)
// Bloodsuckers can turn their candles on from a distance. SPOOOOKY.
if(isbloodsucker(user))
if(AmBloodsucker(user))
toggle()
/obj/structure/bloodsucker/candelabrum/proc/toggle(mob/user)
@@ -493,7 +493,7 @@
if(lit)
for(var/mob/living/carbon/human/H in viewers(7, src))
var/datum/antagonist/vassal/T = H.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
if(isbloodsucker(H) || T) //We dont want vassals or vampires affected by this
if(AmBloodsucker(H) || T) //We dont want vassals or vampires affected by this
return
H.hallucination = 20
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "vampcandle", /datum/mood_event/vampcandle)
@@ -267,7 +267,7 @@
to_chat(user, "<span class='notice'>You are full. Further blood will be wasted.</span>")
warning_full = TRUE
// Blood Remaining? (Carbons/Humans only)
if(iscarbon(target) && !target.AmBloodsucker(1))
if(iscarbon(target) && !AmBloodsucker(target, TRUE))
if(target.blood_volume <= BLOOD_VOLUME_BAD && warning_target_bloodvol > BLOOD_VOLUME_BAD)
to_chat(user, "<span class='warning'>Your victim's blood volume is fatally low!</span>")
else if(target.blood_volume <= BLOOD_VOLUME_OKAY && warning_target_bloodvol > BLOOD_VOLUME_OKAY)
@@ -33,6 +33,15 @@
if(was_running)
user.toggle_move_intent()
while(bloodsuckerdatum && ContinueActive(user) || user.m_intent == MOVE_INTENT_RUN)
if(istype(user.buckled, /obj/vehicle)) //We dont want people using fortitude being able to use vehicles
var/obj/vehicle/V = user.buckled
var/datum/component/riding/VRD = V.GetComponent(/datum/component/riding)
if(VRD)
VRD.force_dismount(user)
to_chat(user, "<span class='notice'>You trip off the [V], your muscles too heavy for it to support you.</span>")
else
V.unbuckle_mob(user, force = TRUE)
to_chat(user, "<span class='notice'>You fall off the [V], your weight making you too heavy to be supported by it.</span>")
// Pay Blood Toll (if awake)
if(user.stat == CONSCIOUS)
bloodsuckerdatum.AddBloodVolume(-0.5) // Used to be 0.3 blood per 2 seconds, but we're making it more expensive to keep on.
+1 -1
View File
@@ -78,7 +78,7 @@
make_podman = 1
break
else
if(M.ckey == ckey && M.stat == DEAD && !M.suiciding)
if(M.ckey == ckey && M.stat == DEAD && !M.suiciding && AmBloodsucker(M))
make_podman = 1
if(isliving(M))
var/mob/living/L = M
@@ -88,7 +88,7 @@
else
to_chat(user, "<span class='notice'>You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments.</span>")
SSblackbox.record_feedback("nested tally", "hivelord_core", 1, list("[type]", "used", "self"))
if(!isbloodsucker(H))
if(!AmBloodsucker(H))
H.revive(full_heal = TRUE)
else
H.revive(full_heal = FALSE)
@@ -252,7 +252,7 @@
return 0
if(M.getorgan(/obj/item/organ/alien/hivenode))
return 0
if(isbloodsucker(M))
if(AmBloodsucker(M))
return 0
if(ismonkey(M))
+1 -1
View File
@@ -853,7 +853,7 @@
/mob/living/carbon/proc/can_defib()
var/tlimit = DEFIB_TIME_LIMIT * 10
var/obj/item/organ/heart = getorgan(/obj/item/organ/heart)
if(suiciding || hellbound || HAS_TRAIT(src, TRAIT_HUSK) || isbloodsucker())
if(suiciding || hellbound || HAS_TRAIT(src, TRAIT_HUSK) || AmBloodsucker())
return
if((world.time - timeofdeath) > tlimit)
return
+1 -1
View File
@@ -354,7 +354,7 @@
if(m_intent == MOVE_INTENT_RUN)
m_intent = MOVE_INTENT_WALK
else
if (HAS_TRAIT(src,TRAIT_NORUNNING)) // FULPSTATION 7/10/19 So you can't run during fortitude.
if (HAS_TRAIT(src,TRAIT_NORUNNING))
to_chat(src, "You find yourself unable to run.")
return FALSE
m_intent = MOVE_INTENT_RUN
+1 -1
View File
@@ -214,7 +214,7 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
//For easy bloodsucker disgusting and blood removal
/datum/reagent/proc/disgust_bloodsucker(mob/living/carbon/C, disgust, blood_change, blood_puke = TRUE, force)
if(isvamp(C))
if(AmBloodsucker(C))
var/datum/antagonist/bloodsucker/bloodsuckerdatum = C.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if(disgust)
bloodsuckerdatum.handle_eat_human_food(disgust, blood_puke, force)
@@ -579,7 +579,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
value = 1.3
/datum/reagent/consumable/ethanol/bloody_mary/on_mob_life(mob/living/carbon/C)
if(isvamp(C))
if(AmBloodsucker(C))
disgust_bloodsucker(FALSE, 1) //Bloodsuckers get SOME blood from it, for style reasons.
if(C.blood_volume < (BLOOD_VOLUME_NORMAL*C.blood_ratio))
C.blood_volume = min((BLOOD_VOLUME_NORMAL*C.blood_ratio), C.blood_volume + 3) //Bloody Mary quickly restores blood loss.
@@ -448,7 +448,7 @@
..()
/datum/reagent/consumable/condensedcapsaicin/reaction_mob(mob/living/M, method, reac_volume)
if(isbloodsucker(M))
if(AmBloodsucker(M))
switch(method)
if(INGEST)
if(prob(min(30, current_cycle)))