Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bloodsucker Sol rework #3236

Merged
merged 16 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions code/__DEFINES/bloodsuckers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
/// Once blood is this high, will exit Frenzyshak
#define FRENZY_THRESHOLD_EXIT 250

/// Minimum blood required for bloodsucker oozelings to auto-revive
#define OOZELING_MIN_REVIVE_BLOOD_THRESHOLD (FRENZY_THRESHOLD_ENTER * 10)

/**
* Vassal defines
*/
Expand Down Expand Up @@ -67,6 +70,8 @@
#define BP_CANT_USE_WHILE_INCAPACITATED (1<<3)
/// This Power can't be used while unconscious
#define BP_CANT_USE_WHILE_UNCONSCIOUS (1<<4)
/// This Power can't be used during Sol
#define BP_CANT_USE_DURING_SOL (1<<5)

/// This Power can be purchased by Bloodsuckers
#define BLOODSUCKER_CAN_BUY (1<<0)
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/traits/monkestation/declarations.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#define TRAIT_VAULTING "vaulting" //simian trait
/// Ethereals with this trait will not suffer negative effects from overcharge.
#define TRAIT_ETHEREAL_NO_OVERCHARGE "ethereal_no_overcharge"
/// Oozelings with this trait will not lose limbs from low blood/nutrition.
#define TRAIT_OOZELING_NO_CANNIBALIZE "oozeling_no_cannibalize"
/// Indicates that they've inhaled helium.
#define TRAIT_HELIUM "helium"
/// Allows the user to start any surgery, anywhere. Mostly used by abductor scientists.
Expand Down
3 changes: 2 additions & 1 deletion code/__DEFINES/~monkestation/actionspeed_modification.dm
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#define ACTIONSPEED_ID_BORER "borer"
#define ACTIONSPEED_ID_BORER "borer"
#define ACTIONSPEED_ID_BLOODSUCKER_SOL "bloodsucker_sol"
1 change: 1 addition & 0 deletions code/_globalvars/traits/_traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_OCCULTIST" = TRAIT_OCCULTIST,
"TRAIT_OIL_FRIED" = TRAIT_OIL_FRIED,
"TRAIT_ON_ELEVATED_SURFACE" = TRAIT_ON_ELEVATED_SURFACE,
"TRAIT_OOZELING_NO_CANNIBALIZE" = TRAIT_OOZELING_NO_CANNIBALIZE,
"TRAIT_ORBITING_FORBIDDEN" = TRAIT_ORBITING_FORBIDDEN,
"TRAIT_OVERWATCHED" = TRAIT_OVERWATCHED,
"TRAIT_OVERWATCH_IMMUNE" = TRAIT_OVERWATCH_IMMUNE,
Expand Down
4 changes: 2 additions & 2 deletions code/modules/mob/living/carbon/carbon_defense.dm
Original file line number Diff line number Diff line change
Expand Up @@ -519,12 +519,12 @@
add_mood_event("hug", /datum/mood_event/bad_touch_bear_hug)

// Let people know if they hugged someone really warm or really cold
if(helper.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)
if(helper.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT || helper.has_status_effect(/datum/status_effect/bloodsucker_sol)) // monkestation edit: bloodsucker sol
to_chat(src, span_warning("It feels like [helper] is over heating as [helper.p_they()] hug[helper.p_s()] you."))
else if(helper.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
to_chat(src, span_warning("It feels like [helper] is freezing as [helper.p_they()] hug[helper.p_s()] you."))

if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT || has_status_effect(/datum/status_effect/bloodsucker_sol)) // monkestation edit: bloodsucker sol
to_chat(helper, span_warning("It feels like [src] is over heating as you hug [p_them()]."))
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
to_chat(helper, span_warning("It feels like [src] is freezing as you hug [p_them()]."))
Expand Down
7 changes: 7 additions & 0 deletions monkestation/code/__HELPERS/_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,10 @@
for(var/i=1, i<c_list.len, ++i)
c_list[i]=c_list[i+1]
c_list[c_list.len] = first_obj

/// Returns TRUE if the list has any items that are in said typecache, FALSE otherwise.
/proc/typecached_item_in_list(list/things, list/typecache)
. = FALSE
for(var/datum/thingy as anything in things)
if(is_type_in_typecache(thingy, typecache))
return TRUE
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
TRAIT_RADIMMUNE,
TRAIT_GENELESS,
TRAIT_STABLEHEART,
TRAIT_STABLELIVER,
TRAIT_NOSOFTCRIT,
TRAIT_NOHARDCRIT,
TRAIT_AGEUSIA,
Expand All @@ -100,15 +101,21 @@
TRAIT_HARDLY_WOUNDED,
TRAIT_NO_MIRROR_REFLECTION,
TRAIT_ETHEREAL_NO_OVERCHARGE,
TRAIT_OOZELING_NO_CANNIBALIZE,
)
/// Traits applied during Torpor.
var/static/list/torpor_traits = list(
TRAIT_DEATHCOMA,
TRAIT_FAKEDEATH,
TRAIT_NODEATH,
TRAIT_RESISTHIGHPRESSURE,
TRAIT_RESISTLOWPRESSURE
TRAIT_RESISTLOWPRESSURE,
)
/// A typecache of organs we'll expel during Torpor.
var/static/list/yucky_organ_typecache = typecacheof(list(
/obj/item/organ/internal/body_egg,
/obj/item/organ/internal/zombie_infection,
))

/**
* Apply innate effects is everything given to the mob
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
// Apply to Volume
AddBloodVolume(blood_taken)
// Reagents (NOT Blood!)
if(target.reagents && target.reagents.total_volume)
if(target.reagents?.total_volume)
target.reagents.trans_to(owner.current, INGEST, 1) // Run transfer of 1 unit of reagent from them to me.
owner.current.playsound_local(null, 'sound/effects/singlebeat.ogg', vol = 40, vary = TRUE) // 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.
total_blood_drank += blood_taken
Expand All @@ -76,11 +76,16 @@

/// Constantly runs on Bloodsucker's LifeTick, and is increased by being in Torpor/Coffins
/datum/antagonist/bloodsucker/proc/HandleHealing(mult = 1)
var/actual_regen = bloodsucker_regen_rate + additional_regen
if(QDELETED(owner?.current))
return
var/in_torpor = is_in_torpor()
// Don't heal if I'm staked or on Masquerade (+ not in a Coffin). Masqueraded Bloodsuckers in a Coffin however, will heal.
if(owner.current.am_staked() || (HAS_TRAIT(owner.current, TRAIT_MASQUERADE) && !is_in_torpor()))
if(owner.current.am_staked())
return FALSE
owner.current.adjustCloneLoss(-1 * (actual_regen * 4) * mult, 0)
if(!in_torpor && (HAS_TRAIT(owner.current, TRAIT_MASQUERADE) || owner.current.has_status_effect(/datum/status_effect/bloodsucker_sol)))
return FALSE
var/actual_regen = bloodsucker_regen_rate + additional_regen
owner.current.adjustCloneLoss(-1 * (actual_regen * 4) * mult)
owner.current.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1 * (actual_regen * 4) * mult) //adjustBrainLoss(-1 * (actual_regen * 4) * mult, 0)
if(!iscarbon(owner.current)) // Damage Heal: Do I have damage to ANY bodypart?
return
Expand All @@ -89,23 +94,23 @@
var/bruteheal = min(user.getBruteLoss_nonProsthetic(), actual_regen) // BRUTE: Always Heal
var/fireheal = 0 // BURN: Heal in Coffin while Fakedeath, or when damage above maxhealth (you can never fully heal fire)
// Checks if you're in a coffin here, additionally checks for Torpor right below it.
var/amInCoffin = istype(user.loc, /obj/structure/closet/crate/coffin)
if(amInCoffin && is_in_torpor())
if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE) && (COOLDOWN_FINISHED(src, bloodsucker_spam_healing)))
to_chat(user, span_alert("You do not heal while your Masquerade ability is active."))
COOLDOWN_START(src, bloodsucker_spam_healing, BLOODSUCKER_SPAM_MASQUERADE)
return
fireheal = min(user.getFireLoss_nonProsthetic(), actual_regen)
mult *= 5 // Increase multiplier if we're sleeping in a coffin.
costMult /= 2 // Decrease cost if we're sleeping in a coffin.
user.extinguish_mob()
user.remove_all_embedded_objects() // Remove Embedded!
if(check_limbs(costMult))
return TRUE
// In Torpor, but not in a Coffin? Heal faster anyways.
else if(is_in_torpor())
fireheal = min(user.getFireLoss_nonProsthetic(), actual_regen) / 1.2 // 20% slower than being in a coffin
mult *= 3
if(in_torpor)
if(istype(user.loc, /obj/structure/closet/crate/coffin))
if(HAS_TRAIT(owner.current, TRAIT_MASQUERADE) && (COOLDOWN_FINISHED(src, bloodsucker_spam_healing)))
to_chat(user, span_alert("You do not heal while your Masquerade ability is active."))
COOLDOWN_START(src, bloodsucker_spam_healing, BLOODSUCKER_SPAM_MASQUERADE)
return
fireheal = min(user.getFireLoss_nonProsthetic(), actual_regen)
mult *= 5 // Increase multiplier if we're sleeping in a coffin.
costMult /= 2 // Decrease cost if we're sleeping in a coffin.
user.extinguish_mob()
user.remove_all_embedded_objects() // Remove Embedded!
if(check_limbs(costMult))
return TRUE
// In Torpor, but not in a Coffin? Heal faster anyways.
else
fireheal = min(user.getFireLoss_nonProsthetic(), actual_regen) / 1.2 // 20% slower than being in a coffin
mult *= 3
// Heal if Damaged
if((bruteheal + fireheal > 0) && mult > 0) // Just a check? Don't heal/spend, and return.
// We have damage. Let's heal (one time)
Expand Down Expand Up @@ -164,16 +169,9 @@
bloodsuckeruser.revive()
for(var/datum/wound/iter_wound as anything in bloodsuckeruser.all_wounds)
iter_wound.remove_wound()
// From [powers/panacea.dm]
var/list/bad_organs = list(
bloodsuckeruser.get_organ_by_type(/obj/item/organ/internal/body_egg),
bloodsuckeruser.get_organ_by_type(/obj/item/organ/internal/zombie_infection))
for(var/tumors in bad_organs)
var/obj/item/organ/yucky_organs = tumors
if(!istype(yucky_organs))
continue
yucky_organs.Remove(bloodsuckeruser)
yucky_organs.forceMove(get_turf(bloodsuckeruser))
for(var/obj/item/organ/organ as anything in typecache_filter_list(bloodsuckeruser.organs, yucky_organ_typecache))
organ.Remove(bloodsuckeruser)
organ.forceMove(bloodsuckeruser.drop_location())

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Expand All @@ -198,7 +196,7 @@
final_death()
return
// Fire Damage? (above double health)
if(owner.current.getFireLoss() >= owner.current.maxHealth * 2.5)
if(owner.current.getFireLoss() >= (owner.current.maxHealth * 2.5))
final_death()
return
// Staked while "Temp Death" or Asleep
Expand All @@ -208,12 +206,13 @@
// Temporary Death? Convert to Torpor.
if(is_in_torpor())
return
to_chat(owner.current, span_danger("Your immortal body will not yet relinquish your soul to the abyss. You enter Torpor."))
to_chat(owner.current, span_userdanger("Your immortal body will not yet relinquish your soul to the abyss. You enter Torpor."))
check_begin_torpor(TRUE)

/datum/antagonist/bloodsucker/proc/HandleStarving() // I am thirsty for blood!
// Nutrition - The amount of blood is how full we are.
owner.current.set_nutrition(min(bloodsucker_blood_volume, NUTRITION_LEVEL_FED))
if(!isoozeling(owner.current))
owner.current.set_nutrition(min(bloodsucker_blood_volume, NUTRITION_LEVEL_FED))

// BLOOD_VOLUME_GOOD: [336] - Pale
// handled in bloodsucker_integration.dm
Expand Down Expand Up @@ -286,7 +285,7 @@
owner.current.drop_all_held_items()
owner.current.unequip_everything()
user.remove_all_embedded_objects()
playsound(owner.current, 'sound/effects/tendril_destroyed.ogg', 40, TRUE)
playsound(owner.current, 'sound/effects/tendril_destroyed.ogg', vol = 40, vary = TRUE)

if(SEND_SIGNAL(src, BLOODSUCKER_FINAL_DEATH) & DONT_DUST)
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,6 @@
mood_change = 10
timeout = 6 MINUTES

/datum/mood_event/daylight_1
description = "<span class='boldwarning'>I slept poorly in a makeshift coffin during the day.</span>\n"
mood_change = -3
timeout = 6 MINUTES

/datum/mood_event/daylight_2
description = "<span class='boldwarning'>I have been scorched by the unforgiving rays of the sun.</span>\n"
mood_change = -6
timeout = 6 MINUTES

///Candelabrum's mood event to non Bloodsucker/Vassals
/datum/mood_event/vampcandle
description = "<span class='boldwarning'>Something is making your mind feel... loose.</span>\n"
Expand Down
Loading
Loading