Mindshield fix and thrall buff
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user