Mindshield fix and thrall buff

This commit is contained in:
Artur
2019-12-09 19:08:42 +02:00
parent d184bdd77a
commit 488c0f1833
18 changed files with 143 additions and 191 deletions
@@ -744,3 +744,31 @@
#undef ABDUCTOR_MAX_TEAMS
#undef REVENANT_SPAWN_THRESHOLD
//////////////////////////////////////////////
// //
// BLOODSUCKERS //
// //
//////////////////////////////////////////////
/datum/dynamic_ruleset/latejoin/bloodsucker
name = "Bloodsucker Infiltrator"
config_tag = "latejoin_bloodsucker"
antag_datum = ANTAG_DATUM_BLOODSUCKER
antag_flag = ROLE_TRAITOR
restricted_roles = list("AI", "Cyborg")
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 1
weight = 3
cost = 10
requirements = list(90,80,70,60,55,50,45,40,35,30)
high_population_requirement = 30
repeatable = TRUE
/datum/dynamic_ruleset/latejoin/bloodsucker/execute()
var/mob/M = pick(candidates)
assigned += M.mind
M.mind.special_role = antag_flag
if(mode.make_bloodsucker(M.mind))
mode.bloodsuckers += M
return TRUE
@@ -784,38 +784,36 @@
// BLOODSUCKERS //
// //
//////////////////////////////////////////////
/* Doesnt work just yet
/datum/dynamic_ruleset/roundstart/bloodsucker
name = "bloodsucker"
name = "Bloodsuckers"
config_tag = "bloodsucker"
persistent = TRUE
antag_flag = ROLE_BLOODSUCKER
antag_datum = /datum/antagonist/bloodsucker/
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster", "Chaplain")
restricted_roles = list("AI", "Cyborg")
required_candidates = 1
weight = 3
cost = 15
scaling_cost = 10
requirements = list(80,70,60,50,50,50,50,50,50,50)
//antag_cap = list(1,1,1,1,1,2,2,2,2,2) There will be just as many vamp hunters as vampires, right?
high_population_requirement = 50
var/datum/antagonist/bloodsucker/V
antag_datum = ANTAG_DATUM_BLOODSUCKER
minimum_required_age = 0
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
restricted_roles = list("Cyborg", "AI")
required_candidates = 1
weight = 2
cost = 15
scaling_cost = 10
requirements = list(90,80,70,60,50,50,50,50,50,50)
high_population_requirement = 50
antag_cap = list(1,1,1,1,1,2,2,2,2,2)
/datum/dynamic_ruleset/roundstart/bloodsucker/pre_execute()
var/num_bloodsuckers = antag_cap[indice_pop] * (scaled_times + 1)
for (var/i = 1 to num_bloodsuckers)
var/mob/M = pick_n_take(candidates)
assigned += M.mind
V += M.mind
M.mind.special_role = ROLE_TRAITOR
M.mind.restricted_roles = restricted_roles
mode.assign_monster_hunters(num_bloodsuckers,TRUE, assigned)
return TRUE
var/num_bloodsuckers = antag_cap[indice_pop] * (scaled_times + 1)
for (var/i = 1 to num_bloodsuckers)
var/mob/M = pick_n_take(candidates)
assigned += M.mind
M.mind.special_role = ROLE_BLOODSUCKER
M.mind.restricted_roles = restricted_roles
return TRUE
/datum/dynamic_ruleset/roundstart/bloodsucker/execute()
//check_start_sunlight() The procs that make a vampire SHOULD enable sunlight by itself
for(var/datum/mind/M in assigned)
if(!mode.make_bloodsucker(M))
V -= M.mind
return TRUE
*/
mode.check_start_sunlight()
for(var/datum/mind/M in assigned)
if(mode.make_bloodsucker(M))
mode.bloodsuckers += M
return TRUE
@@ -26,7 +26,7 @@
if(target.mind.has_antag_datum(/datum/antagonist/brainwashed))
target.mind.remove_antag_datum(/datum/antagonist/brainwashed)
if(target.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
if(target.mind.has_antag_datum(ANTAG_DATUM_VASSAL))
SSticker.mode.remove_vassal(target.mind)
if(target.mind.has_antag_datum(/datum/antagonist/rev/head) || target.mind.unconvertable || target.mind.has_antag_datum(/datum/antagonist/gang/boss))
@@ -15,7 +15,7 @@
var/notice_healing = FALSE
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)
AddBloodVolume(-0.1) // -.15 (before tick went from 10 to 30, but we also charge more for faking life now)
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>")
@@ -116,9 +116,9 @@
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.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.
AddBloodVolume((bruteheal * -0.5 + fireheal * -1) / mult * costMult) // Costs blood to heal
return TRUE // Healed! Done for this tick.
@@ -316,44 +316,34 @@
/datum/antagonist/bloodsucker/proc/handle_eat_human_food(var/food_nutrition) // Called from snacks.dm and drinks.dm
set waitfor = FALSE
if (!owner.current || !iscarbon(owner.current))
return
var/mob/living/carbon/C = owner.current
// Remove Nutrition, Give Bad Food
C.nutrition -= food_nutrition
foodInGut += food_nutrition
// Already ate some bad clams? Then we can back out, because we're already sick from it.
if (foodInGut != food_nutrition)
return
// Haven't eaten, but I'm in a Human Disguise.
else if (poweron_masquerade)
to_chat(C, "<span class='notice'>Your stomach turns, but your \"human disguise\" keeps the food down...for now.</span>")
// Keep looping until we purge. If we have activated our Human Disguise, we ignore the food. But it'll come up eventually...
var/sickphase = 0
while (foodInGut)
sleep(50)
C.adjust_disgust(10 * sickphase)
// Wait an interval...
sleep(50 + 50 * sickphase) // At intervals of 100, 150, and 200. (10 seconds, 15 seconds, and 20 seconds)
// Died? Cancel
if (C.stat == DEAD)
if(C.stat == DEAD)
return
// Put up disguise? Then hold off the vomit.
if (poweron_masquerade)
if (sickphase > 0)
if(poweron_masquerade)
if(sickphase > 0)
to_chat(C, "<span class='notice'>Your stomach settles temporarily. You regain your composure...for now.</span>")
sickphase = 0
continue
switch(sickphase)
if (1)
to_chat(C, "<span class='warning'>You feel unwell. You can taste ash on your tongue.</span>")
@@ -369,5 +359,4 @@
C.Stun(30)
//C.Dizzy(50)
foodInGut = 0
sickphase ++
@@ -73,7 +73,7 @@
return
//daylight_time -= TIME_BLOODSUCKER_BURN_INTERVAL
// Issue Level Up!
if (!issued_XP && time_til_cycle <= 15)
if(!issued_XP && time_til_cycle <= 15)
issued_XP = TRUE
vamps_rank_up()
@@ -86,9 +86,7 @@
/obj/effect/sunlight/proc/hud_tick()
set waitfor = FALSE
while(!cancel_me)
// Update all Bloodsucker sunlight huds
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
if(!istype(M) || !istype(M.current))
@@ -96,7 +94,6 @@
var/datum/antagonist/bloodsucker/bloodsuckerdatum = M.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if(istype(bloodsuckerdatum))
bloodsuckerdatum.update_sunlight(max(0, time_til_cycle), amDay) // This pings all HUDs
sleep(10)
time_til_cycle --
@@ -42,8 +42,6 @@
// TO ADD:
//var/static/list/defaultOrgans = list (/obj/item/organ/heart/vampheart,/obj/item/organ/heart/vampeyes)
/datum/antagonist/bloodsucker/on_gain()
SSticker.mode.bloodsuckers |= owner // Add if not already in here (and you might be, if you were picked at round start)
SSticker.mode.check_start_sunlight()// Start Sunlight? (if first Vamp)
@@ -163,16 +161,15 @@
// Name First
fullname = (vampname ? vampname : owner.current.name)
// Title
if (vamptitle)
if(vamptitle)
fullname = vamptitle + " " + fullname
// Rep
if (include_rep && vampreputation)
if(include_rep && vampreputation)
fullname = fullname + " the " + vampreputation
return fullname
/datum/antagonist/bloodsucker/proc/BuyPower(datum/action/bloodsucker/power)//(obj/effect/proc_holder/spell/power)
powers += power
power.Grant(owner.current)// owner.AddSpell(power)
@@ -201,8 +198,7 @@
var/mob/living/carbon/human/H = owner.current
var/datum/species/S = H.dna.species
// Make Changes
S.brutemod *= 0.5
S.burnmod += 0.1 // <-------------------- Start small, but burn mod increases based on rank!
S.brutemod *= 0.5 // <-------------------- 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
@@ -318,7 +314,7 @@ datum/antagonist/bloodsucker/proc/SpendRank()
if(ishuman(owner.current))
var/mob/living/carbon/human/H = owner.current
var/datum/species/S = H.dna.species
S.burnmod += 0.025 // Slightly more burn damage
S.burnmod *= 0.025 // Slightly more burn damage
S.stunmod *= 0.95 // Slightly less stun time.
S.punchdamagelow += 0.5
S.punchdamagehigh += 0.5 // NOTE: This affects the hitting power of Brawn.
@@ -337,7 +333,6 @@ datum/antagonist/bloodsucker/proc/SpendRank()
SelectReputation(am_fledgling=FALSE, forced=TRUE)
to_chat(owner.current, "<span class='notice'>You are now a rank [vamplevel] Bloodsucker. Your strength, resistence, health, feed rate, regen rate, and maximum blood have all increased!</span>")
to_chat(owner.current, "<span class='notice'>Your existing powers have all ranked up as well!</span>")
to_chat(owner.current, "<span class='warning'>However, your weakness to fire and sunlight have also increased!</span>")
update_hud(TRUE)
owner.current.playsound_local(null, 'sound/effects/pope_entry.ogg', 25, 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.
@@ -355,8 +350,6 @@ datum/antagonist/bloodsucker/proc/SpendRank()
/datum/antagonist/bloodsucker/create_team(datum/team/team)
return
// Create Objectives
/datum/antagonist/bloodsucker/proc/forge_bloodsucker_objectives() // Fledgling vampires can have different objectives.
@@ -416,11 +409,6 @@ datum/antagonist/bloodsucker/proc/SpendRank()
/datum/antagonist/bloodsucker/get_team()
return clan
//Name shown on antag list
/datum/antagonist/bloodsucker/antag_listing_name()
return ..() + "([ReturnFullName(TRUE)])"
@@ -434,11 +422,6 @@ datum/antagonist/bloodsucker/proc/SpendRank()
//Individual roundend report
/datum/antagonist/bloodsucker/roundend_report()
// Get the default Objectives
@@ -700,22 +683,22 @@ datum/antagonist/bloodsucker/proc/SpendRank()
/datum/antagonist/bloodsucker/proc/update_hud(updateRank=FALSE)
// No Hud? Get out.
if (!owner.current.hud_used)
if(!owner.current.hud_used)
return
// Update Blood Counter
if (owner.current.hud_used.blood_display)
var/valuecolor = "#FF6666"
if (owner.current.blood_volume > BLOOD_VOLUME_SAFE)
if(owner.current.blood_volume > BLOOD_VOLUME_SAFE)
valuecolor = "#FFDDDD"
else if (owner.current.blood_volume > BLOOD_VOLUME_BAD)
else if(owner.current.blood_volume > BLOOD_VOLUME_BAD)
valuecolor = "#FFAAAA"
owner.current.hud_used.blood_display.update_counter(owner.current.blood_volume, valuecolor)
// Update Rank Counter
if (owner.current.hud_used.vamprank_display)
if(owner.current.hud_used.vamprank_display)
var/valuecolor = vamplevel_unspent ? "#FFFF00" : "#FF0000"
owner.current.hud_used.vamprank_display.update_counter(vamplevel, valuecolor)
if (updateRank) // Only change icon on special request.
if(updateRank) // Only change icon on special request.
owner.current.hud_used.vamprank_display.icon_state = (vamplevel_unspent > 0) ? "rank_up" : "rank"
@@ -4,14 +4,13 @@
/datum/antagonist/bloodsucker/proc/attempt_turn_vassal(mob/living/carbon/C)
C.silent = 0
return SSticker.mode.make_vassal(C,owner)
/datum/antagonist/bloodsucker/proc/FreeAllVassals()
for (var/datum/antagonist/vassal/V in vassals)
SSticker.mode.remove_vassal(V.owner)
/datum/antagonist/vassal
name = "Vassal"//WARNING: DO NOT SELECT" // "Vassal"
roundend_category = "vassals"
@@ -28,62 +27,64 @@
return ..()
/datum/antagonist/vassal/on_gain()
SSticker.mode.vassals |= owner // Add if not already in here (and you might be, if you were picked at round start)
// Mindslave Add
if (master)
if(master)
var/datum/antagonist/bloodsucker/B = master.owner.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if (B)
if(B)
B.vassals |= src
owner.enslave_mind_to_creator(master.owner.current)
// Master Pinpointer
owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer/vassal_edition)
// Powers
var/datum/action/bloodsucker/vassal/recuperate/new_Recuperate = new ()
new_Recuperate.Grant(owner.current)
powers += new_Recuperate
// Give Vassal Objective
var/datum/objective/bloodsucker/vassal/vassal_objective = new
vassal_objective.owner = owner
vassal_objective.generate_objective()
objectives += vassal_objective
objectives_given += vassal_objective
give_thrall_eyes()
// Add Antag HUD
update_vassal_icons_added(owner.current, "vassal")
. = ..()
/datum/antagonist/vassal/proc/give_thrall_eyes()
var/obj/item/organ/eyes/vassal/E = new
E.Insert(owner.current)
/obj/item/organ/eyes/vassal/
lighting_alpha = 180 // LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE <--- This is too low a value at 128. We need to SEE what the darkness is so we can hide in it.
see_in_dark = 12
flash_protect = -1 //These eyes are weaker to flashes, but let you see in the dark
/datum/antagonist/vassal/proc/remove_thrall_eyes()
// Eyes
var/obj/item/organ/eyes/E = new
E.Insert(owner.current)
/datum/antagonist/vassal/on_removal()
SSticker.mode.vassals -= owner // Add if not already in here (and you might be, if you were picked at round start)
// Mindslave Remove
if (master && master.owner)
master.vassals -= src
if (owner.enslaved_to == master.owner.current)
owner.enslaved_to = null
// Master Pinpointer
owner.current.remove_status_effect(/datum/status_effect/agent_pinpointer/vassal_edition)
// Powers
while(powers.len)
var/datum/action/power = pick(powers)
powers -= power
power.Remove(owner.current)
// Remove Hunter Objectives
for(var/O in objectives_given)
objectives -= O
qdel(O)
objectives_given = list()
remove_thrall_eyes()
// Clear Antag HUD
update_vassal_icons_removed(owner.current)
@@ -97,7 +98,6 @@
owner.current.playsound_local(null, 'sound/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE)
//owner.store_memory("You became the mortal servant of [master.owner.current], a bloodsucking vampire!")
antag_memory += "You became the mortal servant of <b>[master.owner.current]</b>, a bloodsucking vampire!<br>"
// And to your new Master...
to_chat(master.owner, "<span class='userdanger'>[owner.current] has become addicted to your immortal blood. [owner.current.p_they(TRUE)] [owner.current.p_are()] now your undying servant!</span>")
master.owner.current.playsound_local(null, 'sound/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE)
@@ -111,7 +111,6 @@
//if (master && master.owner)
// to_chat(master.owner, "<span class='userdanger'>You feel the bond with your vassal [owner.current] has somehow been broken!</span>")
/datum/status_effect/agent_pinpointer/vassal_edition
id = "agent_pinpointer"
alert_type = /obj/screen/alert/status_effect/agent_pinpointer/vassal_edition
@@ -139,7 +138,7 @@
var/datum/atom_hud/antag/bloodsucker/hud = GLOB.huds[ANTAG_HUD_BLOODSUCKER]
hud.join_hud(vassal)
set_antag_hud(vassal, icontype) // Located in icons/mob/hud.dmi
owner.current.hud_list[ANTAG_HUD].icon = image('icons/mob/hud.dmi', owner.current, "bloodsucker")
owner.current.hud_list[ANTAG_HUD].icon = image('icons/mob/hud.dmi', owner.current, "bloodsucker")
/datum/antagonist/vassal/proc/update_vassal_icons_removed(mob/living/vassal)
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_BLOODSUCKER]
@@ -3,44 +3,34 @@
/datum/antagonist/bloodsucker/proc/CheckVampOrgans()
// Do I have any parts that need replacing?
var/obj/item/organ/O
// Heart
O = owner.current.getorganslot(ORGAN_SLOT_HEART)
if (!istype(O, /obj/item/organ/heart/vampheart))
if(!istype(O, /obj/item/organ/heart/vampheart))
qdel(O)
var/obj/item/organ/heart/vampheart/H = new
H.Insert(owner.current)
H.Stop() // Now...stop beating!
// Eyes
O = owner.current.getorganslot(ORGAN_SLOT_EYES)
if (!istype(O, /obj/item/organ/eyes/vampeyes))
if(!istype(O, /obj/item/organ/eyes/vassal/bloodsucker))
qdel(O)
var/obj/item/organ/eyes/vampeyes/E = new
var/obj/item/organ/eyes/vassal/bloodsucker/E = new
E.Insert(owner.current)
/datum/antagonist/bloodsucker/proc/RemoveVampOrgans()
// Heart
var/obj/item/organ/heart/H = new
H.Insert(owner.current)
// Eyes
var/obj/item/organ/eyes/E = new
E.Insert(owner.current)
// HEART: OVERWRITE //
/obj/item/organ/heart/proc/HeartStrengthMessage()
if (beating)
return "a healthy"
return "<span class='danger'>an unstable</span>"
// HEART //
/obj/item/organ/heart/vampheart
beating = 0
var/fakingit = 0
@@ -64,16 +54,11 @@
if (fakingit)
return "a healthy"
return "<span class='danger'>no</span>" // Bloodsuckers don't have a heartbeat at all when stopped (default is "an unstable")
// EYES //
/obj/item/organ/eyes/vampeyes
lighting_alpha = 180 // LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE <--- This is too low a value at 128. We need to SEE what the darkness is so we can hide in it.
see_in_dark = 12
flash_protect = -1
//sight_flags = SEE_TURFS // Taken from augmented_eyesight.dm
/obj/item/organ/eyes/vassal/bloodsucker
flash_protect = 2 //Eye healing isnt working properly
sight_flags = SEE_MOBS // Taken from augmented_eyesight.dm
/*
// LIVER //
@@ -113,7 +113,7 @@
// 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.resting)
return (src.resting || src.lying)
// ABOVE: Taken from update_mobility() in living.dm
/obj/item/stake/hardened
@@ -19,17 +19,15 @@
/datum/antagonist/bloodsucker/proc/ClaimCoffin(obj/structure/closet/crate/claimed) // NOTE: This can be any "closet" that you are resting AND inside of.
// ALREADY CLAIMED
if (claimed.resident)
if (claimed.resident == owner.current)
if(claimed.resident)
if(claimed.resident == owner.current)
to_chat(owner, "This is your [src].")
else
to_chat(owner, "This [src] has already been claimed by another.")
return FALSE
// Bloodsucker Learns new Recipes!
owner.teach_crafting_recipe(/datum/crafting_recipe/bloodsucker/vassalrack)
owner.teach_crafting_recipe(/datum/crafting_recipe/bloodsucker/candelabrum)
// This is my Lair
coffin = claimed
lair = get_area(claimed)
@@ -37,12 +35,9 @@
to_chat(owner, "<span class='userdanger'>You have claimed the [claimed] as your place of immortal rest! Your lair is now [lair].</span>")
to_chat(owner, "<span class='danger'>You have learned new construction recipes to improve your lair.</span>")
to_chat(owner, "<span class='announce'>Bloodsucker Tip: Find new lair recipes in the misc tab of the <i>Crafting Menu</i> at the bottom of the screen, including the <i>Persuasion Rack</i> for converting crew into Vassals.</span><br><br>")
RunLair() // Start
return TRUE
// crate.dm
/obj/structure/closet/crate
var/mob/living/resident // This lets bloodsuckers claim any "closet" as a Coffin, so long as they could get into it and close it. This locks it in place, too.
@@ -101,13 +96,12 @@
/obj/structure/closet/crate/proc/ClaimCoffin(mob/living/claimant) // NOTE: This can be any "closet" that you are resting AND inside of.
// Bloodsucker Claim
var/datum/antagonist/bloodsucker/bloodsuckerdatum = claimant.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if (bloodsuckerdatum)
if(bloodsuckerdatum)
// Vamp Successfuly Claims Me?
if (bloodsuckerdatum.ClaimCoffin(src))
if(bloodsuckerdatum.ClaimCoffin(src))
resident = claimant
anchored = 1 // No moving this
/obj/structure/closet/crate/coffin/Destroy()
UnclaimCoffin()
return ..()
@@ -139,30 +133,32 @@
return ..()
/obj/structure/closet/crate/coffin/close(mob/living/user)
var/turf/Turf = get_turf(src)
var/area/A = get_area(src)
if (!..())
return FALSE
// Only the User can put themself into Torpor (if you're already in it, you'll start to heal)
if ((user in src))
if((user in src))
// Bloodsucker Only
var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if (bloodsuckerdatum)
if(bloodsuckerdatum)
LockMe(user)
Turf = get_turf(user) //we may have moved. adjust as needed...
A = get_area(src)
// Claim?
if (!bloodsuckerdatum.coffin && !resident)
if(!bloodsuckerdatum.coffin && !resident && (is_station_level(Turf.z) || !A.map_name == "Space"))
switch(alert(user,"Do you wish to claim this as your coffin? [get_area(src)] will be your lair.","Claim Lair","Yes", "No"))
if("Yes")
ClaimCoffin(user)
// Stake? No Heal!
if (user.AmStaked())
if (user.AmStaked()) // Stake? No Heal!
to_chat(bloodsuckerdatum.owner.current, "<span class='userdanger'>You are staked! Remove the offending weapon from your heart before sleeping.</span>")
return
// Heal
if (bloodsuckerdatum.HandleHealing(0)) // Healing Mult 0 <--- We only want to check if healing is valid!
if(bloodsuckerdatum.HandleHealing(0)) // Healing Mult 0 <--- We only want to check if healing is valid!
to_chat(bloodsuckerdatum.owner.current, "<span class='notice'>You enter the horrible slumber of deathless Torpor. You will heal until you are renewed.</span>")
bloodsuckerdatum.Torpor_Begin()
// Level Up?
bloodsuckerdatum.SpendRank() // Auto-Fails if not appropriate
return TRUE
/obj/structure/closet/crate/coffin/attackby(obj/item/W, mob/user, params)
@@ -209,14 +205,6 @@
broken = FALSE
locked = TRUE
// Look up recipes.dm OR pneumaticCannon.dm
/datum/crafting_recipe/bloodsucker/blackcoffin
name = "Black Coffin"
@@ -400,11 +400,8 @@
// FAILSAFE: Still on the rack?
if (!(locate(target) in buckled_mobs))
return
// NOTE: You can say YES after torture. It'll apply to next time.
disloyalty_confirm = TRUE
if (HAS_TRAIT(target, TRAIT_MINDSHIELD))
to_chat(target, "<span class='boldnotice'>You give in to the will of your torturer. If they are successful, you will no longer be loyal to the station!</span>")
@@ -419,7 +416,6 @@
/obj/structure/bloodsucker/vassalrack/proc/remove_loyalties(mob/living/target)
// Find Mind Implant & Destroy
if (HAS_TRAIT(target, TRAIT_MINDSHIELD))
for(var/obj/item/implant/I in target.implants)
@@ -24,31 +24,33 @@
return TRUE
/datum/action/bloodsucker/cloak/ActivatePower()
var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
var/mob/living/user = owner
while (bloodsuckerdatum && ContinueActive(user))
// Fade from sight
var/was_running = (user.m_intent == MOVE_INTENT_RUN)
if(was_running)
user.toggle_move_intent()
ADD_TRAIT(user, TRAIT_NORUNNING, "cloak of darkness")
while(bloodsuckerdatum && ContinueActive(user) || user.m_intent == MOVE_INTENT_RUN)
// Pay Blood Toll (if awake)
owner.alpha = max(0, owner.alpha - min(75, 20 + 15 * level_current))
bloodsuckerdatum.AddBloodVolume(-0.2)
ADD_TRAIT(user, TRAIT_NORUNNING, "cloak of darkness")
sleep(5)
sleep(5) // 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/cloak/ContinueActive(mob/living/user, mob/living/target)
if (!..())
return FALSE
// Must be CONSCIOUS
if(user.stat == !CONSCIOUS)
if(user.stat == !CONSCIOUS) // Must be CONSCIOUS
to_chat(owner, "<span class='warning'>Your cloak failed due to you falling unconcious! </span>")
return FALSE
// Must be DARK
var/turf/T = owner.loc
var/turf/T = owner.loc // Must be DARK
if(istype(T) && T.get_lumcount() > light_min)
to_chat(owner, "<span class='warning'>Your cloak failed due to there being too much light!</span>")
return FALSE
return TRUE
/datum/action/bloodsucker/cloak/DeactivatePower(mob/living/user = owner, mob/living/target)
..()
REMOVE_TRAIT(user, TRAIT_NORUNNING, "cloak of darkness")
@@ -30,7 +30,7 @@
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)
if(was_running)
user.toggle_move_intent()
while(bloodsuckerdatum && ContinueActive(user) || user.m_intent == MOVE_INTENT_RUN)
// Pay Blood Toll (if awake)
@@ -38,7 +38,7 @@
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)
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)
@@ -94,7 +94,7 @@
puff.set_up(3, 0, get_turf(owner))
puff.start()
// TELEPORT: Move to Coffin & Close it!
do_teleport(owner, bloodsuckerdatum.coffin, no_effects = TRUE, forced = TRUE) // in teleport.dm?
do_teleport(owner, bloodsuckerdatum.coffin, no_effects = TRUE, forced = TRUE, channel = TELEPORT_CHANNEL_QUANTUM) // in teleport.dm?
// SLEEP
user.resting = TRUE
//user.Unconscious(30,0)
@@ -56,9 +56,9 @@
user.canmove = FALSE //Dont move while doing the thing, or itll break
safety --
// Did I get knocked down?
if (owner && owner.incapacitated(ignore_restraints=TRUE,ignore_grab=TRUE))// owner.incapacitated())
if(owner && owner.incapacitated(ignore_restraints=TRUE, ignore_grab=TRUE))// owner.incapacitated())
// We're gonna cancel. But am I on the ground? Spin me!
if (user.resting)
if(user.resting)
var/send_dir = get_dir(owner, T)
new /datum/forced_movement(owner, get_ranged_target_turf(owner, send_dir, 1), 1, FALSE)
owner.spin(10)
@@ -66,7 +66,7 @@
// Spin/Stun people we pass.
//var/mob/living/newtarget = locate(/mob/living) in oview(1, owner)
var/list/mob/living/foundtargets = list()
for (var/mob/living/newtarget in oview(1, owner))
for(var/mob/living/newtarget in oview(1, owner))
if (newtarget && newtarget != target && !(newtarget in foundtargets))//!newtarget.IsKnockdown())
if (rand(0, 5) < level_current)
playsound(get_turf(newtarget), "sound/weapons/punch[rand(1,4)].ogg", 15, 1, -1)
@@ -11,7 +11,7 @@
button_icon_state = "power_mez"
bloodcost = 30
cooldown = 200
target_range = 3
target_range = 2
power_activates_immediately = FALSE
message_Trigger = "Whom will you subvert to your will?"
must_be_capacitated = TRUE
@@ -89,13 +89,13 @@
if(istype(target))
target.Stun(40) //Utterly useless without this, its okay since there are so many checks to go through
target.silent += 45 //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!
var/power_time = 90 + level_current * 15
target.silent += power_time + 50
target.silent = power_time + 50
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)
@@ -101,7 +101,7 @@
// Move & Freeze
if (isturf(target_turf))
do_teleport(owner, target_turf, no_effects=TRUE, forced = TRUE) // in teleport.dm?
do_teleport(owner, target_turf, no_effects=TRUE, channel = TELEPORT_CHANNEL_QUANTUM) // in teleport.dm?
user.next_move = world.time + mist_delay / 2
user.Stun(mist_delay / 2, ignore_canstun = TRUE)
@@ -5,7 +5,6 @@
amToggle = TRUE
bloodcost = 5
cooldown = 100
// Deal STAMINA damage over time, trickle down blood, and heal wounds.
/datum/action/bloodsucker/vassal/recuperate/CheckCanUse(display_error)
. = ..()
@@ -13,39 +12,27 @@
return
if (owner.stat >= DEAD)
return FALSE
var/mob/living/carbon/C = owner
if (C.getBruteLoss() <= 0)
if (display_error)
to_chat(owner, "You have no brute damage to recover from.")
return FALSE
return TRUE
/datum/action/bloodsucker/vassal/recuperate/ActivatePower()
to_chat(owner, "<span class='notice'>Your muscles clench and your skin crawls as your master's immortal blood knits your wounds and gives you stamina.</span>")
var/mob/living/carbon/C = owner
var/mob/living/carbon/human/H
if (ishuman(owner))
if(ishuman(owner))
H = owner
while (ContinueActive(owner))
var/bruteheal = min(C.getBruteLoss(), 1.5)
C.heal_overall_damage(bruteheal)
C.blood_volume -= 0.6
if (C.getStaminaLoss() < 60)
C.adjustStaminaLoss(10, forced = TRUE)
while(ContinueActive(owner))
C.adjustBruteLoss(-1.5)
C.adjustFireLoss(-0.5)
C.adjustToxLoss(-2, forced = TRUE)
C.blood_volume -= 0.2
C.adjustStaminaLoss(-15)
// Stop Bleeding
if (istype(H) && H.bleed_rate > 0 && rand(20) == 0)
if(istype(H) && H.bleed_rate > 0 && rand(20) == 0)
H.bleed_rate --
C.Jitter(5)
sleep(10)
// DONE!
//DeactivatePower(owner)
/datum/action/bloodsucker/vassal/recuperate/ContinueActive(mob/living/user, mob/living/target)
return ..() && user.stat <= DEAD && user.blood_volume > 0 && user.getBruteLoss() > 0
return ..() && user.stat <= DEAD && user.blood_volume > 500