Fixes bad buds and toxin healing
This commit is contained in:
@@ -30,14 +30,17 @@
|
||||
// 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)
|
||||
@@ -45,6 +48,7 @@
|
||||
amount += BP.burn_dam
|
||||
return amount
|
||||
|
||||
/mob/living/carbon
|
||||
// EXAMINING
|
||||
/mob/living/carbon/human/proc/ReturnVampExamine(var/mob/viewer)
|
||||
if (!mind || !viewer.mind)
|
||||
|
||||
@@ -10,53 +10,27 @@
|
||||
//
|
||||
// Show as dead when...
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/antagonist/bloodsucker/proc/LifeTick() // Should probably run from life.dm, same as handle_changeling
|
||||
/datum/antagonist/bloodsucker/proc/LifeTick()// Should probably run from life.dm, same as handle_changeling, but will be an utter pain to move
|
||||
set waitfor = FALSE // Don't make on_gain() wait for this function to finish. This lets this code run on the side.
|
||||
|
||||
var/notice_healing = FALSE
|
||||
while (owner && !AmFinalDeath()) // owner.has_antag_datum(ANTAG_DATUM_BLOODSUCKER) == src
|
||||
|
||||
// Deduct Blood
|
||||
if (owner.current.stat == CONSCIOUS && !poweron_feed && !HAS_TRAIT(owner.current, TRAIT_DEATHCOMA))
|
||||
while(owner && !AmFinalDeath()) // owner.has_antag_datum(ANTAG_DATUM_BLOODSUCKER) == src
|
||||
if(owner.current.stat == CONSCIOUS && !poweron_feed && !HAS_TRAIT(owner.current, TRAIT_DEATHCOMA)) // Deduct Blood
|
||||
AddBloodVolume(-0.09) // -.15 (before tick went from 10 to 30, but we also charge more for faking life now)
|
||||
|
||||
// Heal
|
||||
if (HandleHealing(1))
|
||||
if (notice_healing == FALSE && owner.current.blood_volume > 0)
|
||||
if(HandleHealing(1)) // Heal
|
||||
if(notice_healing == FALSE && owner.current.blood_volume > 0)
|
||||
to_chat(owner, "<span class='notice'>The power of your blood begins knitting your wounds...</span>")
|
||||
notice_healing = TRUE
|
||||
else if (notice_healing == TRUE)
|
||||
notice_healing = FALSE
|
||||
|
||||
// Apply Low Blood Effects
|
||||
HandleStarving()
|
||||
|
||||
// Death
|
||||
HandleDeath()
|
||||
|
||||
// Standard Update
|
||||
update_hud()
|
||||
|
||||
// Daytime Sleep in Coffin
|
||||
else if(notice_healing == TRUE)
|
||||
notice_healing = FALSE // Apply Low Blood Effects
|
||||
HandleStarving() // Death
|
||||
HandleDeath() // Standard Update
|
||||
update_hud()// Daytime Sleep in Coffin
|
||||
if (SSticker.mode.is_daylight() && !HAS_TRAIT_FROM(owner.current, TRAIT_DEATHCOMA, "bloodsucker"))
|
||||
if(istype(owner.current.loc, /obj/structure/closet/crate/coffin))
|
||||
Torpor_Begin()
|
||||
|
||||
// Wait before next pass
|
||||
sleep(10)//sleep(30)
|
||||
|
||||
// Free my Vassals! (if I haven't yet)
|
||||
FreeAllVassals()
|
||||
|
||||
|
||||
|
||||
|
||||
// Wait before next pass
|
||||
sleep(10)
|
||||
FreeAllVassals() // Free my Vassals! (if I haven't yet)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -64,18 +38,14 @@
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/datum/antagonist/bloodsucker/proc/AddBloodVolume(value)
|
||||
owner.current.blood_volume = CLAMP(owner.current.blood_volume + value, 0, maxBloodVolume)
|
||||
update_hud()
|
||||
|
||||
|
||||
/datum/antagonist/bloodsucker/proc/HandleFeeding(mob/living/carbon/target, mult=1)
|
||||
// mult: SILENT feed is 1/3 the amount
|
||||
|
||||
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))
|
||||
target.blood_volume -= (blood_taken / max(target.mob_size, 0.1)) * 3.5 // max() to prevent divide-by-zero
|
||||
@@ -83,33 +53,26 @@
|
||||
if (target.blood_volume <= 0)
|
||||
target.blood_volume = 0
|
||||
target.death(0)
|
||||
|
||||
///////////
|
||||
// Shift Body Temp (toward Target's temp, by volume taken)
|
||||
owner.current.bodytemperature = ((owner.current.blood_volume * owner.current.bodytemperature) + (blood_taken * target.bodytemperature)) / (owner.current.blood_volume + blood_taken)
|
||||
// our volume * temp, + their volume * temp, / total volume
|
||||
///////////
|
||||
|
||||
// Reduce Value Quantity
|
||||
if (target.stat == DEAD) // Penalty for Dead Blood
|
||||
blood_taken /= 3
|
||||
if (!ishuman(target)) // Penalty for Non-Human Blood
|
||||
blood_taken /= 2
|
||||
//if (!iscarbon(target)) // Penalty for Animals (they're junk food)
|
||||
|
||||
|
||||
// Apply to Volume
|
||||
AddBloodVolume(blood_taken)
|
||||
|
||||
// Reagents (NOT Blood!)
|
||||
if(target.reagents && target.reagents.total_volume)
|
||||
target.reagents.reaction(owner.current, INGEST, 1) // Run Reaction: what happens when what they have mixes with what I have?
|
||||
target.reagents.trans_to(owner.current, 1) // Run transfer of 1 unit of reagent from them to me.
|
||||
|
||||
// Blood Gulp Sound
|
||||
owner.current.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, 1) // Play THIS sound for user only. The "null" is where turf would go if a location was needed. Null puts it right in their head.
|
||||
|
||||
|
||||
/datum/mood_event/drankblood
|
||||
description = "<span class='nicegreen'>I have fed greedly from that which nourishes me.</span>\n"
|
||||
mood_change = 10
|
||||
@@ -166,86 +129,60 @@
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
/datum/antagonist/bloodsucker/proc/HandleHealing(mult = 1)
|
||||
|
||||
// NOTE: Mult of 0 is just a TEST to see if we are injured and need to go into Torpor!
|
||||
// It is called from your coffin on close (by you only)
|
||||
|
||||
if (poweron_masquerade == TRUE || owner.current.AmStaked())
|
||||
//It is called from your coffin on close (by you only)
|
||||
if(poweron_masquerade == TRUE || owner.current.AmStaked())
|
||||
return FALSE
|
||||
|
||||
owner.current.adjustStaminaLoss(-2 * (regenRate * 4) * mult, 0) // Humans lose stamina damage really quickly. Vamps should heal more.
|
||||
owner.current.adjustStaminaLoss(-3 * (regenRate * 4) * 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
|
||||
if (ishuman(owner.current))
|
||||
if (ishuman(owner.current)) //NOTE Current bleeding is horrible, not to count the amount of blood ballistics delete.
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
H.bleed_rate = 0
|
||||
|
||||
// Damage Heal: Do I have damage to ANY bodypart?
|
||||
if (iscarbon(owner.current))
|
||||
if (iscarbon(owner.current)) // Damage Heal: Do I have damage to ANY bodypart?
|
||||
var/mob/living/carbon/C = owner.current
|
||||
var/costMult = 1 // Coffin makes it cheaper
|
||||
|
||||
// BURN: Heal in Coffin while Fakedeath, or when damage above maxhealth (you can never fully heal fire)
|
||||
var/fireheal = 0
|
||||
var/fireheal = 0 // BURN: Heal in Coffin while Fakedeath, or when damage above maxhealth (you can never fully heal fire)
|
||||
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 *= 5 // Increase multiplier if we're sleeping in a coffin.
|
||||
fireheal = min(C.getFireLoss_nonProsthetic(), regenRate) // NOTE: Burn damage ONLY heals in torpor.
|
||||
costMult = 0.25
|
||||
// Extinguish Fire
|
||||
C.ExtinguishMob()
|
||||
C.ExtinguishMob() // Extinguish Fire
|
||||
else
|
||||
// No Blood? Lower Mult
|
||||
if (owner.current.blood_volume <= 0)
|
||||
if (owner.current.blood_volume <= 0) // No Blood? Lower Mult
|
||||
mult = 0.25
|
||||
// Crit from burn? Lower damage to maximum allowed.
|
||||
//if (C.getFireLoss() > owner.current.getMaxHealth())
|
||||
// fireheal = regenRate / 2
|
||||
// BRUTE: Always Heal
|
||||
var/bruteheal = min(C.getBruteLoss_nonProsthetic(), regenRate)
|
||||
|
||||
var/toxinheal = min(C.getToxLoss(), regenRate)
|
||||
// Heal if Damaged
|
||||
if (bruteheal + fireheal > 0)
|
||||
// Just a check? Don't heal/spend, and return.
|
||||
if (bruteheal + fireheal + toxinheal > 0) // Just a check? Don't heal/spend, and return.
|
||||
if (mult == 0)
|
||||
return TRUE
|
||||
// We have damage. Let's heal (one time)
|
||||
C.adjustBruteLoss(-bruteheal * mult, forced=TRUE)// Heal BRUTE / BURN in random portions throughout the body.
|
||||
C.adjustFireLoss(-fireheal * mult, forced=TRUE)
|
||||
C.adjustToxLoss(-toxinheal * mult * 2, forced=TRUE) //Toxin healing because vamps arent immune
|
||||
//C.heal_overall_damage(bruteheal * mult, fireheal * mult) // REMOVED: We need to FORCE this, because otherwise, vamps won't heal EVER. Swapped to above.
|
||||
|
||||
// Pay Cost
|
||||
AddBloodVolume((bruteheal * -0.5 + fireheal * -1) / mult * costMult) // Costs blood to heal
|
||||
|
||||
// Healed! Done for this tick.
|
||||
return TRUE
|
||||
|
||||
// Limbs? (And I have no other healing)
|
||||
if (amInCoffinWhileTorpor)
|
||||
|
||||
// Heal Missing
|
||||
var/list/missing = owner.current.get_missing_limbs()
|
||||
if (missing.len)
|
||||
// Cycle through ALL limbs and regen them!
|
||||
for (var/targetLimbZone in missing)
|
||||
// 1) Find ONE Limb and regenerate it.
|
||||
//var/targetLimbZone = pick(missing)
|
||||
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!
|
||||
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"))
|
||||
// 2) Limb returns Damaged
|
||||
var/obj/item/bodypart/L = owner.current.get_bodypart( targetLimbZone )
|
||||
var/obj/item/bodypart/L = owner.current.get_bodypart( targetLimbZone ) // 2) Limb returns Damaged
|
||||
AddBloodVolume(20 * 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.
|
||||
// Remove Prosthetic/False Limb
|
||||
for(var/obj/item/bodypart/BP in C.bodyparts)
|
||||
@@ -256,38 +193,26 @@
|
||||
return TRUE
|
||||
// NOTE: Limbs have a "status", like their hosts "stat". 2 is dead (aka Prosthetic). 1 seems to be idle/alive.
|
||||
*/
|
||||
|
||||
// Cure Final Disabilities
|
||||
CureDisabilities()
|
||||
|
||||
// Remove Embedded!
|
||||
C.remove_all_embedded_objects()
|
||||
// Heal Organs (will respawn original eyes etc. but we replace right away, next)
|
||||
owner.current.regenerate_organs()
|
||||
// Eyes/Heart
|
||||
CureDisabilities() // Cure Final Disabilities
|
||||
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 FALSE
|
||||
|
||||
|
||||
/datum/antagonist/bloodsucker/proc/CureDisabilities()
|
||||
var/mob/living/carbon/C = owner.current
|
||||
|
||||
C.cure_blind(list(EYE_DAMAGE))//()
|
||||
C.cure_nearsighted(EYE_DAMAGE)
|
||||
C.set_blindness(0) // Added 9/2/19
|
||||
C.set_blurriness(0) // Added 9/2/19
|
||||
C.update_tint() // Added 9/2/19
|
||||
C.update_sight() // Added 9/2/19
|
||||
|
||||
for(var/O in C.internal_organs) //owner.current.adjust_eye_damage(-100) // This was removed by TG
|
||||
var/obj/item/organ/organ = O
|
||||
organ.setOrganDamage(0)
|
||||
|
||||
owner.current.cure_husk()
|
||||
|
||||
|
||||
// I am hungry!
|
||||
// I am thirsty for blud!
|
||||
/datum/antagonist/bloodsucker/proc/HandleStarving()
|
||||
|
||||
// High: Faster Healing
|
||||
@@ -311,7 +236,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/antagonist/bloodsucker/proc/HandleDeath()
|
||||
// FINAL DEATH
|
||||
// FINAL DEATH
|
||||
// Fire Damage? (above double health)
|
||||
if (owner.current.getFireLoss_nonProsthetic() >= owner.current.getMaxHealth() * 2)
|
||||
FinalDeath()
|
||||
@@ -328,16 +253,15 @@
|
||||
if (!owner.current.HaveBloodsuckerBodyparts())
|
||||
FinalDeath()
|
||||
return
|
||||
|
||||
// Disable Powers: Masquerade * NOTE * This should happen as a FLAW!
|
||||
//if (stat >= UNCONSCIOUS)
|
||||
// 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_damage = total_brute + total_burn
|
||||
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)
|
||||
if (owner.current.stat >= DEAD)
|
||||
Torpor_Begin()
|
||||
@@ -345,8 +269,8 @@
|
||||
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 brute healed and NOT in coffin (since you cannot heal burn)
|
||||
if (total_damage <= 0 || total_brute <= 0 && !istype(owner.current.loc, /obj/structure/closet/crate/coffin))
|
||||
else // No damage, OR toxin healed AND brute healed and NOT in coffin (since you cannot heal burn)
|
||||
if (total_damage <= 0 || total_toxloss <= 0 && total_brute <= 0 && !istype(owner.current.loc, /obj/structure/closet/crate/coffin))
|
||||
// Not Daytime, Not in Torpor
|
||||
if (!SSticker.mode.is_daylight() && HAS_TRAIT_FROM(owner.current, TRAIT_DEATHCOMA, "bloodsucker"))
|
||||
Torpor_End()
|
||||
@@ -377,8 +301,8 @@
|
||||
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") // So you can heal in 0 G. otherwise you just...heal forever.
|
||||
REMOVE_TRAIT(owner.current, TRAIT_RESISTLOWPRESSURE, "bloodsucker") // So you can heal in 0 G. otherwise you just...heal forever.
|
||||
REMOVE_TRAIT(owner.current, TRAIT_RESISTHIGHPRESSURE, "bloodsucker")
|
||||
REMOVE_TRAIT(owner.current, TRAIT_RESISTLOWPRESSURE, "bloodsucker")
|
||||
to_chat(owner, "<span class='warning'>You have recovered from Torpor.</span>")
|
||||
|
||||
|
||||
@@ -395,20 +319,18 @@
|
||||
return !current || QDELETED(current) || !isliving(current) || isbrain(current) || !get_turf(current) // NOTE: "isliving()" is not the same as STAT == CONSCIOUS. This is to make sure you're not a BORG (aka silicon)
|
||||
|
||||
/datum/antagonist/bloodsucker/proc/FinalDeath()
|
||||
|
||||
if(!iscarbon(owner.current)) //Check for non carbons.
|
||||
owner.current.gib()
|
||||
return
|
||||
playsound(get_turf(owner.current), 'sound/effects/tendril_destroyed.ogg', 60, 1)
|
||||
owner.current.drop_all_held_items()
|
||||
owner.current.unequip_everything()
|
||||
var/mob/living/carbon/C = owner.current
|
||||
C.remove_all_embedded_objects()
|
||||
|
||||
// Make me UN-CLONEABLE
|
||||
owner.current.hellbound = TRUE // This was done during creation, but let's do it again one more time...to make SURE this guy stays dead.
|
||||
|
||||
|
||||
// Free my Vassals!
|
||||
FreeAllVassals()
|
||||
|
||||
// Elders get Dusted
|
||||
if (vamplevel >= 4) // (vamptitle)
|
||||
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>", \
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
var/datum/species/S = H.dna.species
|
||||
// Make Changes
|
||||
S.brutemod *= 0.5
|
||||
S.burnmod += 0.2 // <-------------------- Start small, but burn mod increases based on rank!
|
||||
S.burnmod += 0.1 // <-------------------- Start small, but burn mod increases based on rank!
|
||||
S.coldmod = 0
|
||||
S.stunmod *= 0.25
|
||||
S.siemens_coeff *= 0.75 //base electrocution coefficient 1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*
|
||||
#define HUNTER_SCAN_MIN_DISTANCE 8
|
||||
#define HUNTER_SCAN_MAX_DISTANCE 35
|
||||
#define HUNTER_SCAN_PING_TIME 20 //5s update time.
|
||||
@@ -103,7 +104,7 @@
|
||||
|
||||
// TAKEN FROM: /datum/action/changeling/pheromone_receptors // pheromone_receptors.dm for a version of tracking that Changelings have!
|
||||
|
||||
/*
|
||||
|
||||
/datum/status_effect/agent_pinpointer/hunter_edition
|
||||
alert_type = /obj/screen/alert/status_effect/agent_pinpointer/hunter_edition
|
||||
minimum_range = HUNTER_SCAN_MIN_DISTANCE
|
||||
@@ -159,7 +160,7 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
|
||||
|
||||
/datum/action/bloodsucker/trackvamp/
|
||||
@@ -169,35 +170,25 @@
|
||||
background_icon_state = "vamp_power_off" //And this is the state for the background icon
|
||||
icon_icon = 'icons/mob/actions/bloodsucker.dmi' //This is the file for the ACTION icon
|
||||
button_icon_state = "power_hunter" //And this is the state for the action icon
|
||||
|
||||
// Action-Related
|
||||
amToggle = FALSE
|
||||
cooldown = 200 // 10 ticks, 1 second.
|
||||
amToggle = FALSE // Action-Related
|
||||
cooldown = 300 // 10 ticks, 1 second.
|
||||
bloodcost = 0
|
||||
|
||||
|
||||
|
||||
/datum/action/bloodsucker/trackvamp/ActivatePower()
|
||||
|
||||
var/mob/living/user = owner
|
||||
|
||||
to_chat(user, "<span class='notice'>You look around, scanning your environment and discerning signs of any filthy, wretched affronts to the natural order.</span>")
|
||||
|
||||
if (!do_mob(user,owner,80))
|
||||
return
|
||||
|
||||
// Add Power
|
||||
// REMOVED //user.apply_status_effect(/datum/status_effect/agent_pinpointer/hunter_edition)
|
||||
// We don't track direction anymore!
|
||||
|
||||
// Return text indicating direction
|
||||
display_proximity()
|
||||
|
||||
// NOTE: DON'T DEACTIVATE!
|
||||
//DeactivatePower()
|
||||
|
||||
|
||||
|
||||
/datum/action/bloodsucker/trackvamp/proc/display_proximity()
|
||||
// Pick target
|
||||
var/turf/my_loc = get_turf(owner)
|
||||
@@ -209,7 +200,7 @@
|
||||
var/list/datum/mind/monsters = list()
|
||||
monsters += SSticker.mode.bloodsuckers
|
||||
monsters += SSticker.mode.devils
|
||||
monsters += SSticker.mode.cult
|
||||
//monsters += SSticker.mode.cult
|
||||
monsters += SSticker.mode.wizards
|
||||
monsters += SSticker.mode.apprentices
|
||||
monsters += SSticker.mode.servants_of_ratvar
|
||||
@@ -301,3 +292,4 @@
|
||||
|
||||
var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh)
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
attack_verb = list("staked")
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
force = 6
|
||||
throwforce = 10
|
||||
@@ -43,19 +42,14 @@
|
||||
obj_integrity = 30
|
||||
max_integrity = 30
|
||||
//embedded_fall_pain_multiplier
|
||||
|
||||
var/staketime = 120 // Time it takes to embed the stake into someone's chest.
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/stake/basic
|
||||
name = "wooden stake"
|
||||
// This exists so Hardened/Silver Stake can't have a welding torch used on them.
|
||||
|
||||
|
||||
/obj/item/stake/basic/attackby(obj/item/W, mob/user, params)
|
||||
if (istype(W, /obj/item/weldingtool))
|
||||
if(istype(W, /obj/item/weldingtool))
|
||||
//if (amWelded)
|
||||
// to_chat(user, "<span class='warning'>This stake has already been treated with fire.</span>")
|
||||
// return
|
||||
@@ -67,27 +61,24 @@
|
||||
"<span class='notice'>You scorch the pointy end of [src] with the welding tool.</span>", \
|
||||
"<span class='italics'>You hear welding.</span>")
|
||||
// 8 Second Timer
|
||||
if (!do_mob(user, src, 80))
|
||||
if(!do_mob(user, src, 80))
|
||||
return
|
||||
|
||||
// Create the Stake
|
||||
qdel(src)
|
||||
var/obj/item/stake/hardened/new_item = new(usr.loc)
|
||||
user.put_in_hands(new_item)
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
/obj/item/stake/afterattack(atom/target, mob/user, proximity)
|
||||
//to_chat(world, "<span class='notice'>DEBUG: Staking </span>")
|
||||
// Invalid Target, or not targetting chest with HARM intent?
|
||||
if (!iscarbon(target) || check_zone(user.zone_selected) != "chest" || user.a_intent != INTENT_HARM)
|
||||
if(!iscarbon(target) || check_zone(user.zone_selected) != "chest" || user.a_intent != INTENT_HARM)
|
||||
return
|
||||
var/mob/living/carbon/C = target
|
||||
// Needs to be Down/Slipped in some way to Stake.
|
||||
if (!C.can_be_staked())
|
||||
if(!C.can_be_staked() || target == user)
|
||||
to_chat(user, "<span class='danger'>You cant stake [target] when they are moving moving about! They have to be laying down!</span>")
|
||||
return
|
||||
// Oops! Can't.
|
||||
if(HAS_TRAIT(C, TRAIT_PIERCEIMMUNE))
|
||||
@@ -96,68 +87,35 @@
|
||||
// Make Attempt...
|
||||
to_chat(user, "<span class='notice'>You put all your weight into embedding the stake into [target]'s chest...</span>")
|
||||
playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1)
|
||||
if (!do_mob(user, C, staketime, 0, 1, extra_checks=CALLBACK(C, /mob/living/carbon/proc/can_be_staked))) // user / target / time / uninterruptable / show progress bar / extra checks
|
||||
if(!do_mob(user, C, staketime, 0, 1, extra_checks=CALLBACK(C, /mob/living/carbon/proc/can_be_staked))) // user / target / time / uninterruptable / show progress bar / extra checks
|
||||
return
|
||||
|
||||
// Drop & Embed Stake
|
||||
user.visible_message("<span class='danger'>[user.name] drives the [src] into [target]'s chest!</span>", \
|
||||
"<span class='danger'>You drive the [src] into [target]'s chest!</span>")
|
||||
playsound(get_turf(target), 'sound/effects/splat.ogg', 40, 1)
|
||||
|
||||
user.dropItemToGround(src, TRUE) //user.drop_item() // "drop item" doesn't seem to exist anymore. New proc is user.dropItemToGround() but it doesn't seem like it's needed now?
|
||||
|
||||
var/obj/item/bodypart/B = C.get_bodypart("chest") // This was all taken from hitby() in human_defense.dm
|
||||
B.embedded_objects |= src
|
||||
add_mob_blood(target)//Place blood on the stake
|
||||
loc = C // Put INSIDE the character
|
||||
B.receive_damage(w_class * embedding.embedded_impact_pain_multiplier)
|
||||
|
||||
if (C.mind)
|
||||
if(C.mind)
|
||||
var/datum/antagonist/bloodsucker/bloodsucker = C.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
|
||||
if (bloodsucker)
|
||||
if(bloodsucker)
|
||||
// If DEAD or TORPID...kill vamp!
|
||||
if (C.StakeCanKillMe()) // NOTE: This is the ONLY time a staked Torpid vamp dies.
|
||||
if(C.StakeCanKillMe()) // NOTE: This is the ONLY time a staked Torpid vamp dies.
|
||||
bloodsucker.FinalDeath()
|
||||
return
|
||||
else
|
||||
to_chat(target, "<span class='userdanger'>You have been staked! Your powers are useless, your death forever, while it remains in place.</span>")
|
||||
to_chat(user, "<span class='warning'>You missed [C.p_their(TRUE)]'s heart! It would be easier if [C.p_they(TRUE)] weren't struggling so much.</span>")
|
||||
|
||||
|
||||
|
||||
// Can this target be staked? If someone stands up before this is complete, it fails. Best used on someone stationary.
|
||||
/mob/living/carbon/proc/can_be_staked()
|
||||
//return resting || IsKnockdown() || IsUnconscious() || (stat && (stat != SOFT_CRIT || pulledby)) || (has_trait(TRAIT_FAKEDEATH)) || resting || IsStun() || IsFrozen() || (pulledby && pulledby.grab_state >= GRAB_NECK)
|
||||
return !(src.canmove)
|
||||
return (src.resting)
|
||||
// ABOVE: Taken from update_mobility() in living.dm
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/stack/sheet/mineral/wood/attackby(obj/item/W, mob/user, params) // NOTE: sheet_types.dm is where the WOOD stack lives. Maybe move this over there.
|
||||
// Taken from /obj/item/stack/rods/attackby in [rods.dm]
|
||||
if (W.get_sharpness())
|
||||
user.visible_message("[user] begins whittling [src] into a pointy object.", \
|
||||
"<span class='notice'>You begin whittling [src] into a sharp point at one end.</span>", \
|
||||
"<span class='italics'>You hear wood carving.</span>")
|
||||
// 8 Second Timer
|
||||
if (!do_mob(user, src, 80))
|
||||
return
|
||||
// Make Stake
|
||||
var/obj/item/stake/basic/new_item = new(usr.loc)
|
||||
user.visible_message("[user] finishes carving a stake out of [src].", \
|
||||
"<span class='notice'>You finish carving a stake out of [src].</span>")
|
||||
// Prepare to Put in Hands (if holding wood)
|
||||
var/obj/item/stack/sheet/mineral/wood/thisStack = src
|
||||
var/replace = (user.get_inactive_held_item()==thisStack)
|
||||
// Use Wood
|
||||
thisStack.use(1)
|
||||
// If stack depleted, put item in that hand (if it had one)
|
||||
if (!thisStack && replace)
|
||||
user.put_in_hands(new_item)
|
||||
|
||||
|
||||
/obj/item/stake/hardened
|
||||
// Created by welding and acid-treating a simple stake.
|
||||
name = "hardened stake"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
desc = "Withstand egregious physical wounds and walk away from attacks that would stun, pierce, and dismember lesser beings. You cannot run while active."
|
||||
button_icon_state = "power_fortitude"
|
||||
bloodcost = 5
|
||||
cooldown = 40
|
||||
cooldown = 80
|
||||
bloodsucker_can_buy = TRUE
|
||||
amToggle = TRUE
|
||||
warn_constant_cost = TRUE
|
||||
@@ -15,12 +15,9 @@
|
||||
var/this_resist // So we can raise and lower your brute resist based on what your level_current WAS.
|
||||
|
||||
/datum/action/bloodsucker/fortitude/ActivatePower()
|
||||
|
||||
var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
|
||||
var/mob/living/user = owner
|
||||
|
||||
to_chat(user, "<span class='notice'>Your flesh, skin, and muscles become as steel.</span>")
|
||||
|
||||
// Traits & Effects
|
||||
ADD_TRAIT(user, TRAIT_PIERCEIMMUNE, "fortitude")
|
||||
ADD_TRAIT(user, TRAIT_NODISMEMBER, "fortitude")
|
||||
@@ -31,27 +28,21 @@
|
||||
this_resist = max(0.3, 0.7 - level_current * 0.1)
|
||||
H.physiology.brute_mod *= this_resist//0.5
|
||||
H.physiology.burn_mod *= this_resist//0.5
|
||||
|
||||
// Stop Running (Taken from /datum/quirk/nyctophobia in negative.dm)
|
||||
var/was_running = (user.m_intent == MOVE_INTENT_RUN)
|
||||
if (was_running)
|
||||
user.toggle_move_intent()
|
||||
|
||||
while(bloodsuckerdatum && ContinueActive(user) || user.m_intent == MOVE_INTENT_RUN)
|
||||
|
||||
// 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.
|
||||
|
||||
sleep(20) // Check every few ticks that we haven't disabled this power
|
||||
|
||||
// Return to Running (if you were before)
|
||||
if (was_running && user.m_intent != MOVE_INTENT_RUN)
|
||||
user.toggle_move_intent()
|
||||
|
||||
/datum/action/bloodsucker/fortitude/DeactivatePower(mob/living/user = owner, mob/living/target)
|
||||
..()
|
||||
|
||||
// Restore Traits & Effects
|
||||
REMOVE_TRAIT(user, TRAIT_PIERCEIMMUNE, "fortitude")
|
||||
REMOVE_TRAIT(user, TRAIT_NODISMEMBER, "fortitude")
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
// FOLLOW: Target follows you, spouting random phrases from their history (or maybe Poly's or NPC's vocab?)
|
||||
// ATTACK: Target finds a nearby non-Bloodsucker victim to attack.
|
||||
|
||||
|
||||
/datum/action/bloodsucker/targeted/mesmerize
|
||||
name = "Mesmerize"
|
||||
desc = "Dominate the mind of a mortal who can see your eyes."
|
||||
button_icon_state = "power_mez"
|
||||
bloodcost = 30
|
||||
cooldown = 200
|
||||
target_range = 5
|
||||
target_range = 3
|
||||
power_activates_immediately = FALSE
|
||||
message_Trigger = "Whom will you subvert to your will?"
|
||||
must_be_capacitated = TRUE
|
||||
@@ -81,24 +80,23 @@
|
||||
if (display_error)
|
||||
to_chat(owner, "<span class='warning'>Your victim must be facing you to see into your eyes.</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/action/bloodsucker/targeted/mesmerize/FireTargetedPower(atom/A)
|
||||
// set waitfor = FALSE <---- DONT DO THIS!We WANT this power to hold up ClickWithPower(), so that we can unlock the power when it's done.
|
||||
|
||||
var/mob/living/carbon/target = A
|
||||
var/mob/living/user = owner
|
||||
|
||||
if(istype(target))
|
||||
target.Stun(40) //Utterly useless without this, its okay since there are so many checks to go through
|
||||
target.silent += 40 //Shhhh little lamb
|
||||
target.silent += 45 //Shhhh little lamb
|
||||
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, 45) //So you cant rotate with combat mode, plus fancy status alert
|
||||
|
||||
if(do_mob(user, target, 40, 0, TRUE, extra_checks=CALLBACK(src, .proc/ContinueActive, user, target)))
|
||||
PowerActivatedSuccessfully() // PAY COST! BEGIN COOLDOWN!
|
||||
ADD_TRAIT(target, TRAIT_MUTE, "bloodsucker_mesmerize")
|
||||
target.silent += 100 + level_current * 15
|
||||
var/power_time = 90 + level_current * 15
|
||||
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, 100 + level_current * 15)
|
||||
to_chat(user, "<span class='notice'>[target] is fixed in place by your hypnotic gaze.</span>")
|
||||
target.Stun(power_time)
|
||||
//target.silent += power_time / 10 // Silent isn't based on ticks.
|
||||
@@ -110,7 +108,6 @@
|
||||
// They Woke Up! (Notice if within view)
|
||||
if(istype(user) && target.stat == CONSCIOUS && (target in view(10, get_turf(user))) )
|
||||
to_chat(user, "<span class='warning'>[target] has snapped out of their trance.</span>")
|
||||
REMOVE_TRAIT(target, TRAIT_MUTE, "bloodsucker_mesmerize")
|
||||
|
||||
|
||||
/datum/action/bloodsucker/targeted/mesmerize/ContinueActive(mob/living/user, mob/living/target)
|
||||
|
||||
@@ -4,4 +4,7 @@
|
||||
var/datum/antagonist/rev/rev = mind.has_antag_datum(/datum/antagonist/rev)
|
||||
if(rev)
|
||||
rev.remove_revolutionary(TRUE)
|
||||
var/datum/antagonist/bloodsucker/V = mind.has_antag_datum(/datum/antagonist/bloodsucker)
|
||||
if(V)
|
||||
mind.remove_antag_datum(V)
|
||||
..()
|
||||
|
||||
Reference in New Issue
Block a user