Merge pull request #681 from LeDrascol/quirk-bloodfledge-overhaul

Bloodsucker Fledgling quirk overhaul
This commit is contained in:
BongaTheProto
2023-01-24 13:10:44 -05:00
committed by GitHub
11 changed files with 611 additions and 145 deletions

View File

@@ -17,7 +17,7 @@
#define TRAIT_PHARMA "hepatic_pharmacokinesis" #define TRAIT_PHARMA "hepatic_pharmacokinesis"
#define TRAIT_CHOKE_SLUT "choke_slut" #define TRAIT_CHOKE_SLUT "choke_slut"
#define BLOODFLEDGE "BloodFledge"//splurt change #define TRAIT_BLOODFLEDGE "BloodFledge"
#define TRAIT_INCUBUS "Incubus" #define TRAIT_INCUBUS "Incubus"
#define TRAIT_SUCCUBUS "Succubus" #define TRAIT_SUCCUBUS "Succubus"

View File

@@ -57,7 +57,7 @@
/datum/reagent/blood/on_mob_life(mob/living/carbon/C) //Because lethals are preferred over stamina. damnifino. /datum/reagent/blood/on_mob_life(mob/living/carbon/C) //Because lethals are preferred over stamina. damnifino.
var/blood_id = C.get_blood_id() var/blood_id = C.get_blood_id()
if((blood_id in GLOB.blood_reagent_types) && !HAS_TRAIT(C, TRAIT_NOMARROW) && !HAS_TRAIT(C, BLOODFLEDGE)) if((blood_id in GLOB.blood_reagent_types) && !HAS_TRAIT(C, TRAIT_NOMARROW) && !HAS_TRAIT(C, TRAIT_BLOODFLEDGE))
if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type))) //we only care about bloodtype here because this is where the poisoning should be if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type))) //we only care about bloodtype here because this is where the poisoning should be
C.adjustToxLoss(rand(2,8)*REAGENTS_EFFECT_MULTIPLIER, TRUE, TRUE) //forced to ensure people don't use it to gain beneficial toxin as slime person C.adjustToxLoss(rand(2,8)*REAGENTS_EFFECT_MULTIPLIER, TRUE, TRUE) //forced to ensure people don't use it to gain beneficial toxin as slime person
..() ..()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -23,3 +23,14 @@
/datum/mood_event/dorsualiphobic_mood_negative /datum/mood_event/dorsualiphobic_mood_negative
description = span_warning("I can't let anyone find out if I'm wearing a backpack or not!\n") description = span_warning("I can't let anyone find out if I'm wearing a backpack or not!\n")
mood_change = -4 mood_change = -4
// Matches drinking synth blood (drankblood_synth)
/datum/mood_event/drankblood_slime
description = span_boldwarning("I drank liquid slime. What is wrong with me?\n")
mood_change = -7
timeout = 15 MINUTES
/datum/mood_event/drank_cursed_bad
description = span_warning("I can feel a pale curse from the blood I drank.\n")
mood_change = -1
timeout = 2 MINUTES

View File

@@ -20,3 +20,8 @@
/datum/mood_event/dorsualiphobic_mood_positive /datum/mood_event/dorsualiphobic_mood_positive
description = span_nicegreen("Nobody will know if I'm wearing a backpack or not.\n") description = span_nicegreen("Nobody will know if I'm wearing a backpack or not.\n")
mood_change = 1 mood_change = 1
/datum/mood_event/drank_cursed_good
description = span_nicegreen("I\'ve tasted sympathy from a fellow curse bearer.\n")
mood_change = 1
timeout = 2 MINUTES

View File

@@ -365,87 +365,164 @@
var/mob/living/carbon/human/H = quirk_holder var/mob/living/carbon/human/H = quirk_holder
H.adjust_nutrition(-0.09)//increases their nutrition loss rate to encourage them to gain a partner they can essentially leech off of H.adjust_nutrition(-0.09)//increases their nutrition loss rate to encourage them to gain a partner they can essentially leech off of
/datum/quirk/vampire//splurt change start /datum/quirk/bloodfledge
name = "Bloodsucker Fledgeling" name = "Bloodsucker Fledgling"
desc = "You are a fledgeling of an ancient Bloodsucker bloodline; your skin is incurably pale and your mouth glimmers with vampiric fangs. Only blood will sate your hungers, and holy energies will cause your flesh to char." desc = "You are a fledgling belonging to ancient Bloodsucker bloodline. While the blessing has yet to fully convert you, some things have changed. Only blood will sate your hungers, and holy energies will cause your flesh to char. <b>This is NOT an antagonist role!</b>"
value = 0 value = 2
medical_record_text = "this person was partially infected by a bloodsucker" medical_record_text = "Patient exhibits onset symptoms of a sanguine curse."
mob_trait = BLOODFLEDGE mob_trait = TRAIT_BLOODFLEDGE
gain_text = span_notice("You feel an otherworldly thirst.") gain_text = span_notice("You feel a sanguine thirst.")
lose_text = span_notice("you feel an otherworldy burden remove itself") lose_text = span_notice("You feel the sanguine thirst fade away.")
processing_quirk = TRUE processing_quirk = TRUE
/datum/quirk/vampire/add() /datum/quirk/bloodfledge/add()
. = ..() . = ..()
var/mob/living/carbon/human/H = quirk_holder
ADD_TRAIT(H,TRAIT_NO_PROCESS_FOOD,ROUNDSTART_TRAIT)
ADD_TRAIT(H,TRAIT_COLDBLOODED,ROUNDSTART_TRAIT)
ADD_TRAIT(H,TRAIT_NOBREATH,ROUNDSTART_TRAIT)
ADD_TRAIT(H,TRAIT_NOTHIRST,ROUNDSTART_TRAIT)
ADD_TRAIT(H,TRAIT_QUICKER_CARRY,ROUNDSTART_TRAIT)
ADD_TRAIT(H,TRAIT_AUTO_CATCH_ITEM,ROUNDSTART_TRAIT)//these two make the vampire fast and enables some sexy "bet you didnt think i could do this" romance
if(!H.dna.skin_tone_override)
H.skin_tone = "albino"
var/datum/action/vbite/B = new
var/datum/action/vrevive/R = new
B.Grant(H)
R.Grant(H)
H.grant_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_BLOODSUCKER)
/datum/quirk/vampire/on_process() // Define quirk mob
var/mob/living/carbon/human/quirk_mob = quirk_holder
// Add quirk traits
ADD_TRAIT(quirk_mob,TRAIT_NO_PROCESS_FOOD,ROUNDSTART_TRAIT)
ADD_TRAIT(quirk_mob,TRAIT_NOTHIRST,ROUNDSTART_TRAIT)
// Set skin tone, if possible
if(!quirk_mob.dna.skin_tone_override)
quirk_mob.skin_tone = "albino"
// Add quirk ability action datums
var/datum/action/bloodfledge/bite/act_bite = new
var/datum/action/bloodfledge/revive/act_revive = new
act_bite.Grant(quirk_mob)
act_revive.Grant(quirk_mob)
// Add quirk language
quirk_mob.grant_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_BLOODSUCKER)
/datum/quirk/bloodfledge/on_process()
. = ..() . = ..()
var/mob/living/carbon/human/H = quirk_holder
var/area/A = get_area(H) // Check if the current area is a coffin
if(istype(A, /area/service/chapel) && H.mind?.assigned_role != "Chaplain") if(istype(quirk_holder.loc, /obj/structure/closet/crate/coffin))
H.adjustStaminaLoss(2) // Define quirk mob
H.adjust_nutrition(-0.3)//changed these to be less deadly and more of an inconvinience var/mob/living/carbon/human/quirk_mob = quirk_holder
H.adjust_disgust(1)
if(istype(H.loc, /obj/structure/closet/crate/coffin))//heals the vampire if in a coffin, except burn which fire can be considered holy // Quirk mob must be injured
H.heal_overall_damage(4,4) if(quirk_mob.health >= quirk_mob.maxHealth)
H.adjust_disgust(-7)
H.adjustOxyLoss(-4)
H.adjustCloneLoss(-4)
H.adjustBruteLoss(-0.3)
H.adjustFireLoss(-0.3)
if(!is_species(H, /datum/species/jelly)) //checks species
H.adjustToxLoss(-5)//heals toxin if not slime
else
H.adjustToxLoss(5)//heals toxin if slime
return return
if(H.nutrition == 0)
if(H.staminaloss < 99)//makes them tired but dosent stun them // Prevent healing for robots
H.adjustStaminaLoss(3, FALSE, TRUE) // This caused numerous technical issues
if(quirk_mob.mob_biotypes & MOB_ROBOTIC)
// Display a warning chat message (10% chance)
if(prob(20))
to_chat(quirk_mob, span_warning("Your mechanical body rejects the curse's healing properties!"))
// Return without healing, due robotic nature
return
// Nutrition (blood) level must be above STARVING
if(quirk_mob.nutrition <= NUTRITION_LEVEL_STARVING)
// Display a warning chat message (10% chance)
if(prob(20))
to_chat(quirk_mob, span_warning("You need more blood before you can regenerate!"))
// Return without healing, due to lack of blood
return
// Define initial health
var/health_start = quirk_mob.health
// Heal brute and burn
// Accounts for robotic limbs
quirk_mob.heal_overall_damage(2,2)
/*
// Heal brute
quirk_mob.adjustBruteLoss(-2)
// Heal burn
quirk_mob.adjustFireLoss(-2)
*/
// Heal oxygen
quirk_mob.adjustOxyLoss(-2)
// Heal clone
quirk_mob.adjustCloneLoss(-2)
// Check for slime race
// NOT a slime
if(!isslimeperson(quirk_mob))
// Heal toxin
quirk_mob.adjustToxLoss(-2)
// IS a slime
else else
H.adjustStaminaLoss(-1,FALSE, FALSE)//this also helps with if someone is stuck in the chapel for way too long, and i tested with a stun sword that stunning for sec is still possible // Grant toxin (heals slimes)
if(prob(2)) //2 percent chance (if it was true randome D:<) quirk_mob.adjustToxLoss(2)
to_chat(H, span_warning("I need blood NOW!!!"))
/datum/quirk/vampire/remove() // Update health
. = ..() quirk_mob.updatehealth()
var/mob/living/carbon/human/H = quirk_holder
var/datum/action/vbite/B = locate() in H.actions
var/datum/action/vrevive/R = locate() in H.actions
REMOVE_TRAIT(H, TRAIT_NO_PROCESS_FOOD, ROUNDSTART_TRAIT)
REMOVE_TRAIT(H, TRAIT_COLDBLOODED, ROUNDSTART_TRAIT)
REMOVE_TRAIT(H, TRAIT_NOBREATH, ROUNDSTART_TRAIT)
REMOVE_TRAIT(H, TRAIT_NOTHIRST, ROUNDSTART_TRAIT)
REMOVE_TRAIT(H,TRAIT_QUICKER_CARRY,ROUNDSTART_TRAIT)
REMOVE_TRAIT(H,TRAIT_AUTO_CATCH_ITEM,ROUNDSTART_TRAIT)
B.Remove(H)
R.Remove(H)
H.remove_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_BLOODSUCKER)
/datum/quirk/vampire/on_spawn() // Determine healed amount
var/mob/living/carbon/human/H = quirk_holder var/health_restored = quirk_mob.health - health_start
var/obj/item/card/id/vampire/vcard = new /obj/item/card/id/vampire
H.equip_to_slot(vcard, ITEM_SLOT_BACKPACK) // Remove nutrition (blood) as compensation for healing
vcard.registered_name = H.real_name // Amount is equal to 50% of healing done
vcard.update_label(addtext(vcard.registered_name, " the vampire")) quirk_mob.adjust_nutrition(health_restored*-1)
//var/obj/item/card/id/I = H.get_idcard(FALSE) maybe later, hop can just give the extra card proper access if needed, as for banking, that can be set on spawn by the player using the card in hand
//vcard.access = I.access /datum/quirk/bloodfledge/remove()
H.regenerate_icons()
. = ..() . = ..()
// Define quirk mob
var/mob/living/carbon/human/quirk_mob = quirk_holder
// Remove quirk traits
REMOVE_TRAIT(quirk_mob, TRAIT_NO_PROCESS_FOOD, ROUNDSTART_TRAIT)
REMOVE_TRAIT(quirk_mob, TRAIT_NOTHIRST, ROUNDSTART_TRAIT)
// Remove quirk ability action datums
var/datum/action/bloodfledge/bite/act_bite = locate() in quirk_mob.actions
var/datum/action/bloodfledge/revive/act_revive = locate() in quirk_mob.actions
act_bite.Remove(quirk_mob)
act_revive.Remove(quirk_mob)
// Remove quirk language
quirk_mob.remove_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_BLOODSUCKER)
/datum/quirk/bloodfledge/on_spawn()
. = ..()
// Define quirk mob
var/mob/living/carbon/human/quirk_mob = quirk_holder
// Create vampire ID card
var/obj/item/card/id/vampire/id_vampire = new /obj/item/card/id/vampire(get_turf(quirk_holder))
// Update card information
id_vampire.registered_name = quirk_mob.real_name
id_vampire.update_label(addtext(id_vampire.registered_name, "'s Bloodfledge"))
// Determine banking ID information
for(var/bank_account in SSeconomy.bank_accounts)
// Define current iteration's account
var/datum/bank_account/account = bank_account
// Check for match
if(account.account_id == quirk_mob.account_id)
// Add to cards list
account.bank_cards += src
// Assign account
id_vampire.registered_account = account
// Stop searching
break
// Try to add ID to backpack
var/id_in_bag = quirk_mob.equip_to_slot_if_possible(id_vampire, ITEM_SLOT_BACKPACK) || FALSE
// Text for where the item was sent
var/id_location = (id_in_bag ? "in your backpack" : "at your feet" )
// Alert user in chat
// This should not post_add, because the ID is added by on_spawn
to_chat(quirk_holder, span_boldnotice("There is a bloodfledge's ID card [id_location], linked to your station account. It functions as a spare ID, but lacks job access."))
/datum/quirk/werewolf //adds the werewolf quirk /datum/quirk/werewolf //adds the werewolf quirk
name = "Werewolf" name = "Werewolf"

View File

@@ -1,4 +1,5 @@
#define BLOOD_DRAIN_NUM 50 #define BLOODFLEDGE_DRAIN_NUM 50
#define BLOODFLEDGE_COOLDOWN_BITE 60
// //
// Quirk: Hypnotic Gaze // Quirk: Hypnotic Gaze
@@ -109,77 +110,430 @@
// Quirk: Bloodsucker Fledgling / Vampire // Quirk: Bloodsucker Fledgling / Vampire
// //
/datum/action/vbite // Basic action preset
name = "Bite" /datum/action/bloodfledge
button_icon_state = "power_feed" name = "Broken Bloodfledge Ability"
desc = "You shouldn't be seeing this!"
button_icon_state = "power_torpor"
background_icon_state = "vamp_power_off"
buttontooltipstyle = "cult"
icon_icon = 'icons/mob/actions/bloodsucker.dmi' icon_icon = 'icons/mob/actions/bloodsucker.dmi'
desc = "Sink your vampiric fangs into the person you are grabbing." button_icon = 'icons/mob/actions/bloodsucker.dmi'
// Action: Bite
/datum/action/bloodfledge/bite
name = "Fledgling Bite"
desc = "Sink your vampiric fangs into the person you are grabbing, and attempt to drink their blood."
button_icon_state = "power_feed"
var/drain_cooldown = 0 var/drain_cooldown = 0
/datum/action/vbite/Trigger() /datum/action/bloodfledge/bite/Trigger()
. = ..() . = ..()
if(iscarbon(owner))
var/mob/living/carbon/H = owner // Check for carbon owner
if(H.nutrition >= 500) if(!iscarbon(owner))
to_chat(H, span_notice("You are too full to drain any more."))
return return
// Define action owner
var/mob/living/carbon/action_owner = owner
// Check for cooldown
if(drain_cooldown >= world.time) if(drain_cooldown >= world.time)
to_chat(H, span_notice("You just drained blood, wait a few seconds.")) // Warn the user, then return
to_chat(action_owner, span_notice("That ability isn't ready yet."))
return return
if(!H.pulling || !iscarbon(H.pulling))
if(H.getStaminaLoss() >= 80 && H.nutrition > 20)//prevents being stunlocked in the chapel
to_chat(H,(span_notice("you use some of your power to energize")))
H.adjustStaminaLoss(-20)
H.adjust_nutrition(-20)
H.resting = TRUE
if(H.pulling && (iscarbon(H.pulling) || (istype(H.pulling,/obj/structure/arachnid/cocoon) && locate(/mob/living/carbon) in H.pulling.contents)))
var/mob/living/carbon/victim
if(iscarbon(H.pulling))
victim = H.pulling
else if(istype(H.pulling,/obj/structure/arachnid/cocoon))
victim = locate(/mob/living/carbon) in H.pulling.contents
drain_cooldown = world.time + 25
if(victim.anti_magic_check(FALSE, TRUE, FALSE, 0))
to_chat(victim, span_warning("[H] tries to bite you, but stops before touching you!"))
to_chat(H, span_warning("[victim] is blessed! You stop just in time to avoid catching fire."))
return
//Here we check now for both the garlic cloves on the neck and for blood in the victims bloodstream.
if(!blood_sucking_checks(victim, TRUE, TRUE))
return
H.visible_message(span_danger("[H] bites down on [victim]'s neck!"))
victim.add_splatter_floor(get_turf(victim), TRUE)
to_chat(victim, span_userdanger("[H] is draining your blood!"))
if(!do_after(H, 30, target = victim))
return
var/blood_volume_difference = BLOOD_VOLUME_MAXIMUM - H.blood_volume //How much capacity we have left to absorb blood
var/drained_blood = min(victim.blood_volume, BLOOD_DRAIN_NUM, blood_volume_difference)
H.reagents.add_reagent(/datum/reagent/blood/, drained_blood)
to_chat(victim, span_danger("[H] has taken some of your blood!"))
to_chat(H, span_notice("You drain some blood!"))
playsound(H, 'sound/items/drink.ogg', 30, 1, -2)
victim.blood_volume = clamp(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
log_combat(H,victim,"vampire bit")//logs the biting action for admins
if(!victim.blood_volume)
to_chat(H, span_warning("You finish off [victim]'s blood supply!"))
// Check for any grabbed target
if(!action_owner.pulling)
// Warn the user, then return
to_chat(action_owner, span_warning("You need a victim first!"))
return
/datum/action/vrevive // Limit maximum nutrition
name = "Resurrect" if(action_owner.nutrition >= NUTRITION_LEVEL_FAT)
button_icon_state = "power_strength" // Warn the user, then return
icon_icon = 'icons/mob/actions/bloodsucker.dmi' to_chat(action_owner, span_notice("You are too full to drain any more."))
desc = "Use all your energy to come back to life!" return
/datum/action/vrevive/Trigger() // Limit maximum potential nutrition
. = ..() if(action_owner.nutrition + BLOODFLEDGE_DRAIN_NUM >= NUTRITION_LEVEL_FAT)
var/mob/living/carbon/C = owner // Warn the user, then return
var/mob/living/carbon/human/H = owner to_chat(action_owner, span_notice("You would become too full by draining any more blood."))
if(H.stat == DEAD && istype(C.loc, /obj/structure/closet/crate/coffin)) return
H.revive(TRUE, FALSE)
H.set_nutrition(0) // Check for muzzle
H.Daze(20) if(action_owner.is_muzzled())
H.drunkenness = 70 // Warn the user, then return
to_chat(action_owner, span_notice("You can't bite things while muzzled!"))
return
// Define pulled target
var/pull_target = action_owner.pulling
// Define bite target
var/mob/living/carbon/bite_target
// Check if the target is carbon
if(iscarbon(pull_target))
// Set the bite target
bite_target = pull_target
// Or cocooned carbon
else if(istype(pull_target,/obj/structure/arachnid/cocoon))
// Define if cocoon has a valid target
// This cannot use pull_target
var/possible_cocoon_target = locate(/mob/living/carbon) in action_owner.pulling.contents
// Check defined cocoon target
if(possible_cocoon_target)
// Set the bite target
bite_target = possible_cocoon_target
// Or a blood tomato
else if(istype(pull_target,/obj/item/reagent_containers/food/snacks/grown/tomato/blood))
// Warn the user, then return
to_chat(action_owner, span_danger("You plunge your fangs into [pull_target]! It's not very nutritious."))
return
// This doesn't actually interact with the item
// Or none of the above
else else
to_chat(H,span_warning("You need to be dead and in a coffin to revive!")) // Warn the user, then return
to_chat(action_owner, span_warning("You can't drain blood from [pull_target]!"))
return
// Check for anti-magic
if(bite_target.anti_magic_check(FALSE, TRUE, FALSE, 0))
// Warn the user and target, then return
to_chat(bite_target, span_warning("[action_owner] tries to bite you, but stops before touching you!"))
to_chat(action_owner, span_warning("[bite_target] is blessed! You stop just in time to avoid catching fire."))
return
// Check for garlic necklace or garlic in the bloodstream
if(!blood_sucking_checks(bite_target, TRUE, TRUE))
// Warn the user and target, then return
to_chat(bite_target, span_warning("[action_owner] tries to bite you, but is warded off by your Allium Sativum!"))
to_chat(action_owner, span_warning("You sense that [bite_target] is protected by Allium Sativum, and refrain from biting them."))
return
// Define bite target's blood volume
var/target_blood_volume = bite_target.blood_volume
// Check for sufficient blood volume
if(!target_blood_volume)
// Warn the user, then return
to_chat(action_owner, span_warning("There's not enough blood in [bite_target]!"))
return
// Check if total blood would become too low
if((target_blood_volume - BLOODFLEDGE_DRAIN_NUM) <= BLOOD_VOLUME_OKAY)
// Check for aggressive grab
if(action_owner.grab_state < GRAB_AGGRESSIVE)
// Warn the user, then return
to_chat(action_owner, span_warning("You sense that [bite_target] is running low on blood. You'll need a tighter grip on [bite_target.p_them()] to continue."))
return
// Check for pacifist
if(HAS_TRAIT(action_owner, TRAIT_PACIFISM))
// Warn the user, then return
to_chat(action_owner, span_warning("You can't drain any more blood from [bite_target] without hurting [bite_target.p_them()]!"))
return
// Set cooldown and action times
var/time_cooldown = BLOODFLEDGE_COOLDOWN_BITE
var/time_interact = 30
// Check for voracious
if(HAS_TRAIT(action_owner, TRAIT_VORACIOUS))
// Make times twice as fast
time_cooldown *= 0.5
time_interact*= 0.5
// Set cooldown
drain_cooldown = world.time + time_cooldown
// Display local chat message
action_owner.visible_message(span_danger("[action_owner] begins to bite down on [bite_target]'s neck!"))
// Warn bite target
to_chat(bite_target, span_userdanger("[action_owner] has bitten your neck, and is trying to drain your blood!"))
// Play a bite sound effect
playsound(action_owner, 'sound/weapons/bite.ogg', 30, 1, -2)
// Try to perform action timer
if(!do_after(action_owner, time_interact, target = bite_target))
// When failing
// Display a local chat message
action_owner.visible_message(span_danger("[action_owner]'s fangs are prematurely torn from [bite_target]'s neck, spilling [bite_target.p_their()] blood!"))
// Bite target "drops" the blood
// This creates large blood splatter
bite_target.bleed(BLOODFLEDGE_DRAIN_NUM, FALSE)
// Play splatter sound
playsound(get_turf(target), 'sound/effects/splat.ogg', 40, 1)
// Check for masochism
if(!HAS_TRAIT(bite_target, TRAIT_MASO))
// Force bite_target to play the scream emote
bite_target.emote("scream")
// Log the biting action failure
log_combat(action_owner,bite_target,"bloodfledge bitten (interrupted)")
// Return
return
// Check if bite target species has blood
if(NOBLOOD in bite_target.dna.species.species_traits)
// Warn the user and target, then return
to_chat(bite_target, span_warning("[action_owner] tried to drain you, but didn't find any blood!"))
to_chat(action_owner, span_warning("[bite_target] doesn't have any blood to drink!"))
return
// Create blood splatter
bite_target.add_splatter_floor(get_turf(bite_target), TRUE)
// Checks for exotic species blood below
// Variable for species with non-blood blood volumes
var/blood_valid = TRUE
// Variable for gaining blood volume
var/blood_transfer = FALSE
// Name of blood volume to be taken
// Action owner assumes blood until after drinking
var/blood_name = "blood"
// Check bite target for synth blood
if(bite_target.mob_biotypes & MOB_ROBOTIC)
// Mark blood as invalid
blood_valid = FALSE
// Set blood type name
blood_name = "coolant"
// Check if the action owner is also a synth
if (action_owner.mob_biotypes & MOB_ROBOTIC)
// Allow gaining blood from this
blood_transfer = TRUE
// Action owner is not a synth
else
// Warn the user
to_chat(action_owner, span_warning("That didn't taste like blood at all..."))
// Add disgust
action_owner.adjust_disgust(2)
// Cause negative mood
SEND_SIGNAL(action_owner, COMSIG_ADD_MOOD_EVENT, "bloodfledge_drank_synth", /datum/mood_event/drankblood_synth)
// Check if bite target is a slime
if (isslimeperson(bite_target))
// Mark blood as invalid
blood_valid = FALSE
// Set blood type name
blood_name = "slime"
// Check if the action owner is also a slime
if(isslimeperson(action_owner))
// Allow gaining blood from this
blood_transfer = TRUE
// Action owner is not a slime
else
// Warn the user
to_chat(action_owner, span_warning("You feel a sloshing presence inside you, but it dies out after a few moments."))
// Add disgust
action_owner.adjust_disgust(2)
// Cause negative mood
SEND_SIGNAL(action_owner, COMSIG_ADD_MOOD_EVENT, "bloodfledge_drank_slime", /datum/mood_event/drankblood_slime)
// End of species blood checks
// Define user's remaining capacity to absorb blood
var/blood_volume_difference = BLOOD_VOLUME_MAXIMUM - action_owner.blood_volume
var/drained_blood = min(target_blood_volume, BLOODFLEDGE_DRAIN_NUM, blood_volume_difference)
// Remove blood from bite target
bite_target.blood_volume = clamp(target_blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
// Perform a blood transfer
// This is done to transfer compatible diseases
// Grants nothing, unless blood transfer variable is set
bite_target.transfer_blood_to(action_owner, (blood_transfer ? drained_blood : 0), TRUE)
// Check if action owner received valid (nourishing) blood
if(blood_valid)
// Add blood reagent to the user
action_owner.reagents.add_reagent(/datum/reagent/blood/, drained_blood)
// Alert the bite target and local user of success
// Yes, this is AFTER the message for non-valid blood
to_chat(bite_target, span_danger("[action_owner] has taken some of your [blood_name]!"))
to_chat(action_owner, span_notice("You've drained some of [bite_target]'s [blood_name]!"))
// Alert the action holder if blood volume limit was exceeded
if(blood_transfer && (action_owner.blood_volume >= BLOOD_VOLUME_MAXIMUM))
to_chat(action_owner, span_warning("You body fails to absorb any more [blood_name]. The remainder has been lost."))
// Play a heartbeat sound effect
// This was changed to match bloodsucker
playsound(action_owner, 'sound/effects/singlebeat.ogg', 30, 1, -2)
// Log the biting action success
log_combat(action_owner,bite_target,"bloodfledge bitten (successfully), transferring [blood_name]")
// Mood events
// Check if bite target is dead or undead
if((bite_target.stat >= DEAD) || (bite_target.mob_biotypes & MOB_UNDEAD))
// Warn the user
to_chat(action_owner, span_warning("The rotten [blood_name] tasted foul."))
// Add disgust
action_owner.adjust_disgust(2)
// Cause negative mood
SEND_SIGNAL(action_owner, COMSIG_ADD_MOOD_EVENT, "bloodfledge_drank_dead", /datum/mood_event/drankblood_dead)
// Check if bite target's blood has been depleted
if(!bite_target.blood_volume)
// Warn the user
to_chat(action_owner, span_warning("You've depleted [bite_target]'s [blood_name] supply!"))
// Cause negative mood
SEND_SIGNAL(action_owner, COMSIG_ADD_MOOD_EVENT, "bloodfledge_drank_killed", /datum/mood_event/drankkilled)
// Check if bite target has cursed blood
if(HAS_TRAIT(bite_target, TRAIT_CURSED_BLOOD))
// Check action owner for cursed blood
var/owner_cursed = HAS_TRAIT(action_owner, TRAIT_CURSED_BLOOD)
// Set chat message based on action owner's trait status
var/warn_message = (owner_cursed ? "You taste the unholy touch of a familiar curse in [bite_target]\'s blood." : "You experience a sensation of intense dread just after drinking from [bite_target]. Something about their blood feels... wrong.")
// Alert user in chat
to_chat(action_owner, span_notice(warn_message))
// Set mood type based on curse status
var/mood_type = (owner_cursed ? /datum/mood_event/drank_cursed_good : /datum/mood_event/drank_cursed_bad)
// Cause mood event
SEND_SIGNAL(action_owner, COMSIG_ADD_MOOD_EVENT, "bloodfledge_drank_cursed_blood", mood_type)
// Action: Revive
/datum/action/bloodfledge/revive
name = "Fledgling Revive"
desc = "Expend all of your remaining energy to escape death."
button_icon_state = "power_strength"
/datum/action/bloodfledge/revive/Trigger()
. = ..()
// Define mob
var/mob/living/carbon/human/action_owner = owner
// Early check for being dead
// Users are most likely to click this while alive
if(action_owner.stat != DEAD)
// Warn user in chat
to_chat(action_owner, "You can't use this ability while alive!")
// Return
return
// Define failure message
var/revive_failed
// Condition: Mob isn't in a closed coffin
if(!istype(action_owner.loc, /obj/structure/closet/crate/coffin))
revive_failed += "\n- You need to be in a closed coffin!"
// Condition: Insufficient nutrition (blood)
if(action_owner.nutrition <= NUTRITION_LEVEL_STARVING)
revive_failed += "\n- You don't have enough blood left!"
// Condition: Can be revived
// This is used by revive(), and must be checked here to prevent false feedback
if(!action_owner.can_be_revived())
revive_failed += "\n- Your body is too weak to sustain life!"
// Condition: Damage limit, brute
if(action_owner.getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE)
revive_failed += "\n- Your body is too battered!"
// Condition: Damage limit, burn
if(action_owner.getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE)
revive_failed += "\n- Your body is too badly burned!"
// Condition: Suicide
if(action_owner.suiciding)
revive_failed += "\n- You chose this path."
// Condition: No revivals
if(HAS_TRAIT(action_owner, TRAIT_NOCLONE))
revive_failed += "\n- You only had one chance."
// Condition: Demonic contract
if(action_owner.hellbound)
revive_failed += "\n- The soul pact must be honored."
// Check for failure
if(revive_failed)
// Set combined message
revive_failed = span_warning("You can't revive right now because: [revive_failed]")
// Alert user in chat of failure
to_chat(action_owner, revive_failed)
// Return
return
// Define time dead
// Used for revive policy
var/time_dead = world.time - action_owner.timeofdeath
// Revive the action owner
action_owner.revive()
// Alert the user in chat of success
action_owner.visible_message(span_notice("An ominous energy radiates from the [action_owner.loc]..."), span_warning("You've expended all remaining blood to bring your body back to life!"))
// Play a haunted sound effect
playsound(action_owner, 'sound/hallucinations/growl1.ogg', 30, 1, -2)
// Remove all nutrition (blood)
action_owner.set_nutrition(0)
// Apply daze effect
action_owner.Daze(20)
// Define time limit for revival
// Determines memory loss, using defib time and policies
var/revive_time_limit = CONFIG_GET(number/defib_cmd_time_limit) * 10
// Define revive time threshold
// Late causes memory loss, according to policy
var/time_late = revive_time_limit && (time_dead > revive_time_limit)
// Define policy to use
var/list/policies = CONFIG_GET(keyed_list/policy)
var/time_policy = time_late? policies[POLICYCONFIG_ON_DEFIB_LATE] : policies[POLICYCONFIG_ON_DEFIB_INTACT]
// Check if policy exists
if(time_policy)
// Alert user in chat of policy
to_chat(action_owner, time_policy)
// Log the revival and effective policy
action_owner.log_message("revived using a vampire quirk ability after being dead for [time_dead] deciseconds. Considered [time_late? "late" : "memory-intact"] revival under configured policy limits.", LOG_GAME)
// //
// Quirk: Werewolf // Quirk: Werewolf

View File

@@ -8,9 +8,12 @@
desc = "A cheap ID used by slave traders. This guy seems to run the show." desc = "A cheap ID used by slave traders. This guy seems to run the show."
/obj/item/card/id/vampire /obj/item/card/id/vampire
name = "Vampire ID" name = "Bloodfledge ID"
desc = "An ID made to easily recognize vampires without needing to do tests" desc = "An ID made to easily recognize bloodsucker fledglings without requiring medical scans."
icon = 'modular_splurt/icons/obj/card.dmi'
icon_state = "vampire" icon_state = "vampire"
assignment = "Bloodsucker Fledgling"
uses_overlays = FALSE
/obj/item/card/id/away/hotel/splurt /obj/item/card/id/away/hotel/splurt
name = "Staff ID" name = "Staff ID"

View File

@@ -28,16 +28,18 @@
/datum/reagent/blood/on_mob_life(mob/living/carbon/C) /datum/reagent/blood/on_mob_life(mob/living/carbon/C)
. = ..() . = ..()
if(HAS_TRAIT(C,BLOODFLEDGE)) if(HAS_TRAIT(C,TRAIT_BLOODFLEDGE))
C.adjust_nutrition(6) //3/4ed this, felt it was a bit too much C.adjust_nutrition(6)
C.adjust_disgust(-3) //makes the churches effects easily negated C.adjust_disgust(-2) // Negates the chapel's disgust effect
C.adjustStaminaLoss(1) // Mitigates the chapel's stamina effect
/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M) /datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M)
. = ..() . = ..()
//makes holy water slightly disgusting and hungering for vampires // Makes holy water disgusting and hungering for bloodfledges
if(HAS_TRAIT(M,BLOODFLEDGE)) // Directly antithetic to the effects of blood
M.adjust_disgust(1) if(HAS_TRAIT(M,TRAIT_BLOODFLEDGE))
M.adjust_nutrition(-0.1) M.adjust_disgust(2)
M.adjust_nutrition(-6)
// Cursed blood effect moved here // Cursed blood effect moved here
if(HAS_TRAIT(M, TRAIT_CURSED_BLOOD)) if(HAS_TRAIT(M, TRAIT_CURSED_BLOOD))

View File

@@ -24,3 +24,17 @@
w_class = WEIGHT_CLASS_BULKY w_class = WEIGHT_CLASS_BULKY
sharpness = SHARP_POINTY sharpness = SHARP_POINTY
attack_verb = list("slashed", "cut") attack_verb = list("slashed", "cut")
// Synth power cord interaction override
/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
// Define user
var/mob/living/carbon/human/cord_user = user
// Check for bloodfledge
if(HAS_TRAIT(cord_user, TRAIT_BLOODFLEDGE))
// Warn user and return
to_chat(cord_user, span_warning("You try to siphon energy from [target], but a sanguine force prevents you from absorbing any charge!"))
return
// Return normally
. = ..()

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B