From 4c076b59756e4a48af53f8c63fd947bfce652b8b Mon Sep 17 00:00:00 2001
From: Zwei <35403274+Gottfrei@users.noreply.github.com>
Date: Tue, 17 Oct 2023 03:26:11 +0300
Subject: [PATCH] tweak: Vampire Tweaks and Fixes (#3660)
---
code/controllers/subsystem/throwing.dm | 5 +-
.../spell_handler/vampire_spell_handler.dm | 2 +-
code/datums/status_effects/debuffs.dm | 13 +-
code/game/gamemodes/cult/cult_items.dm | 2 +-
code/game/objects/items/weapons/legcuffs.dm | 219 ++++++++++--------
.../antagonists/vampire/vampire_datum.dm | 18 +-
.../vampire/vampire_powers/bestia_powers.dm | 55 +++--
.../vampire_powers/dantalion_powers.dm | 13 +-
.../vampire_powers/gargantua_powers.dm | 40 ++--
.../vampire_powers/hemomancer_powers.dm | 2 +-
code/modules/flufftext/Hallucination.dm | 8 +-
code/modules/mob/living/carbon/human/human.dm | 13 +-
.../mob/living/carbon/human/human_damage.dm | 26 +--
.../mob/living/carbon/human/human_defense.dm | 10 +-
.../living/carbon/human/species/_species.dm | 4 +-
code/modules/mob/living/living.dm | 15 +-
code/modules/mob/living/living_defense.dm | 40 ++--
.../mob/living/simple_animal/damage_procs.dm | 14 +-
.../hostile/mining/marrow_weaver.dm | 2 +-
.../mob/living/simple_animal/simple_animal.dm | 5 -
.../mob/living/simple_animal/slime/life.dm | 2 +-
.../tgui/interfaces/VampireTrophiesStatus.js | 96 ++++----
tgui/packages/tgui/public/tgui.bundle.js | 2 +-
23 files changed, 328 insertions(+), 278 deletions(-)
diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm
index e50ca5182c4..cd08c1bd044 100644
--- a/code/controllers/subsystem/throwing.dm
+++ b/code/controllers/subsystem/throwing.dm
@@ -89,7 +89,6 @@ SUBSYSTEM_DEF(throwing)
var/tilestomove = CEILING(min(((((world.time + world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed * MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait), 1)
while(tilestomove-- > 0)
if((dist_travelled >= maxrange || AM.loc == target_turf) && has_gravity(AM, AM.loc))
- hitcheck() //Just to be sure
finalize()
return
@@ -109,6 +108,10 @@ SUBSYSTEM_DEF(throwing)
AM.Move(step, get_dir(AM, step))
+ if(!AM.throwing) // we hit something during our move
+ finalize(hit = TRUE)
+ return
+
dist_travelled++
if(dist_travelled > MAX_THROWING_DIST)
diff --git a/code/datums/spell_handler/vampire_spell_handler.dm b/code/datums/spell_handler/vampire_spell_handler.dm
index 1788dae11eb..ecb1281ebc3 100644
--- a/code/datums/spell_handler/vampire_spell_handler.dm
+++ b/code/datums/spell_handler/vampire_spell_handler.dm
@@ -63,6 +63,6 @@
var/datum/antagonist/vampire/vampire = user?.mind?.has_antag_datum(/datum/antagonist/vampire)
if(!vampire)
return
- to_chat(user, span_boldnotice("You have [vampire.bloodusable] left to use."))
+ to_chat(user, span_boldnotice("You have [vampire.bloodusable] blood left to use."))
SSblackbox.record_feedback("tally", "vampire_powers_used", 1, "[spell]") // Only log abilities which require blood
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 0676833d57e..6449952184b 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -233,10 +233,13 @@
qdel(src)
return
+ if(owner.resting) // abuses are not allowed
+ owner.StopResting()
+
if(t_hearts && prob(t_hearts * 10)) // 60% on MAX
owner.adjustFireLoss(t_hearts) // 6 MAX
- if(t_eyes && !owner.incapacitated() && prob(30 + t_eyes * 7)) // 100% on MAX
+ if(!owner.incapacitated() && prob(30 + t_eyes * 7)) // 100% on MAX
// lets check our arms first
var/obj/item/left_hand = owner.l_hand
var/obj/item/right_hand = owner.r_hand
@@ -284,11 +287,11 @@
if(force_left > force_right)
if(!owner.hand)
owner.swap_hand()
- left_hand.attack(target, owner, "head") // yes! right in the neck
+ left_hand.attack(target, owner, BODY_ZONE_HEAD) // yes! right in the neck
else if(force_right)
if(owner.hand)
owner.swap_hand()
- right_hand.attack(target, owner, "head")
+ right_hand.attack(target, owner, BODY_ZONE_HEAD)
return
// here goes nothing!
@@ -298,8 +301,8 @@
owner.a_intent_change(INTENT_HARM)
if(owner.hand && owner.l_hand != found_gun)
owner.swap_hand()
- found_gun.process_fire(target, owner, zone_override = "head") // hell yeah! few headshots for mr. vampire!
- found_gun.attack(owner, owner, "head") // attack ourselves also in case gun has no ammo
+ found_gun.process_fire(target, owner, zone_override = BODY_ZONE_HEAD) // hell yeah! few headshots for mr. vampire!
+ found_gun.attack(owner, owner, BODY_ZONE_HEAD) // attack ourselves also in case gun has no ammo
// start of `living` level status procs.
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 03130e5514f..570acd78514 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -65,7 +65,7 @@
icon_state = "bola_cult"
item_state = "bola_cult"
breakouttime = 45
- weaken = 2 SECONDS
+ weaken_amt = 2 SECONDS
/obj/item/restraints/legcuffs/bola/cult/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(iscultist(hit_atom))
diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm
index f2d43581af2..4020c79f3eb 100644
--- a/code/game/objects/items/weapons/legcuffs.dm
+++ b/code/game/objects/items/weapons/legcuffs.dm
@@ -9,7 +9,8 @@
w_class = WEIGHT_CLASS_NORMAL
origin_tech = "engineering=3;combat=3"
slowdown = 7
- breakouttime = 300 //Deciseconds = 30s = 0.5 minute
+ breakouttime = 30 SECONDS
+
/obj/item/restraints/legcuffs/beartrap
name = "bear trap"
@@ -18,161 +19,185 @@
icon_state = "beartrap"
desc = "A trap used to catch bears and other legged creatures."
origin_tech = "engineering=4"
- var/armed = 0
+ var/armed = FALSE
var/trap_damage = 20
var/obj/item/grenade/iedcasing/IED = null
var/obj/item/assembly/signaler/sig = null
+
/obj/item/restraints/legcuffs/beartrap/New()
..()
icon_state = "[initial(icon_state)][armed]"
+
/obj/item/restraints/legcuffs/beartrap/Destroy()
QDEL_NULL(IED)
QDEL_NULL(sig)
return ..()
+
/obj/item/restraints/legcuffs/beartrap/suicide_act(mob/user)
- user.visible_message("[user] is sticking [user.p_their()] head in the [name]! It looks like [user.p_theyre()] trying to commit suicide.")
+ user.visible_message(span_suicide("[user] is sticking [user.p_their()] head in the [name]! It looks like [user.p_theyre()] trying to commit suicide."))
playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
return BRUTELOSS
+
/obj/item/restraints/legcuffs/beartrap/attack_self(mob/user)
..()
if(ishuman(user) && !user.stat && !user.restrained())
armed = !armed
icon_state = "[initial(icon_state)][armed]"
- to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]")
+ to_chat(user, span_notice("[src] is now [armed ? "armed" : "disarmed"]"))
+
/obj/item/restraints/legcuffs/beartrap/attackby(obj/item/I, mob/user) //Let's get explosive.
if(istype(I, /obj/item/grenade/iedcasing))
if(IED)
- to_chat(user, "This beartrap already has an IED hooked up to it!")
+ to_chat(user, span_warning("This beartrap already has an IED hooked up to it!"))
return
if(sig)
- to_chat(user, "This beartrap already has a signaler hooked up to it!")
+ to_chat(user, span_warning("This beartrap already has a signaler hooked up to it!"))
return
IED = I
user.drop_transfer_item_to_loc(I, src)
message_admins("[key_name_admin(user)] has rigged a beartrap with an IED.")
add_game_logs("has rigged a beartrap with an IED.", user)
- to_chat(user, "You sneak [IED] underneath the pressure plate and connect the trigger wire.")
- desc = "A trap used to catch bears and other legged creatures. There is an IED hooked up to it."
+ to_chat(user, span_notice("You sneak [IED] underneath the pressure plate and connect the trigger wire."))
+ desc = "A trap used to catch bears and other legged creatures. [span_warning("There is an IED hooked up to it.")]"
+
if(istype(I, /obj/item/assembly/signaler))
if(IED)
- to_chat(user, "This beartrap already has an IED hooked up to it!")
+ to_chat(user, span_warning("This beartrap already has an IED hooked up to it!"))
return
if(sig)
- to_chat(user, "This beartrap already has a signaler hooked up to it!")
+ to_chat(user, span_warning("This beartrap already has a signaler hooked up to it!"))
return
sig = I
if(sig.secured)
- to_chat(user, "The signaler is secured.")
+ to_chat(user, span_notice("The signaler is secured."))
sig = null
return
user.drop_transfer_item_to_loc(I, src)
- to_chat(user, "You sneak the [sig] underneath the pressure plate and connect the trigger wire.")
- desc = "A trap used to catch bears and other legged creatures. There is a remote signaler hooked up to it."
- if(istype(I, /obj/item/screwdriver))
- if(IED)
- IED.forceMove(get_turf(src))
- IED = null
- to_chat(user, "You remove the IED from the [src].")
- return
- if(sig)
- sig.forceMove(get_turf(src))
- sig = null
- to_chat(user, "You remove the signaler from the [src].")
- return
+ to_chat(user, span_notice("You sneak the [sig] underneath the pressure plate and connect the trigger wire."))
+ desc = "A trap used to catch bears and other legged creatures. [span_warning("There is a remote signaler hooked up to it.")]"
..()
-/obj/item/restraints/legcuffs/beartrap/Crossed(AM as mob|obj, oldloc)
- if(armed && isturf(src.loc))
- if( (iscarbon(AM) || isanimal(AM)) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/hostile/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator))
- var/mob/living/L = AM
- armed = 0
- icon_state = "[initial(icon_state)][armed]"
- playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
- L.visible_message("[L] triggers \the [src].", \
- "You trigger \the [src]!")
-
- if(IED && isturf(src.loc))
- IED.active = 1
- message_admins("[key_name_admin(usr)] has triggered an IED-rigged [name].")
- add_game_logs("has triggered an IED-rigged [name].", usr)
- spawn(IED.det_time)
- IED.prime()
-
- if(sig && isturf(src.loc))
- sig.signal()
-
- if(ishuman(AM))
- var/mob/living/carbon/H = AM
- if(H.lying)
- H.apply_damage(trap_damage, BRUTE,"chest")
- else
- H.apply_damage(trap_damage, BRUTE,(pick("l_leg", "r_leg")))
- if(!H.legcuffed && H.get_num_legs() >= 2) //beartrap can't cuff you leg if there's already a beartrap or legcuffs.
- H.equip_to_slot(src, slot_legcuffed)
- SSblackbox.record_feedback("tally", "handcuffs", 1, type)
-
- else
- L.apply_damage(trap_damage, BRUTE)
- ..()
-/obj/item/restraints/legcuffs/beartrap/energy
- name = "energy snare"
- armed = 1
- icon_state = "e_snare"
- trap_damage = 0
- flags = DROPDEL
+/obj/item/restraints/legcuffs/beartrap/screwdriver_act(mob/user, obj/item/I)
+ . = TRUE
+
+ if(!I.use_tool(src, user, 0, volume = I.tool_volume))
+ return
+
+ if(IED)
+ IED.forceMove(get_turf(src))
+ IED = null
+ to_chat(user, span_notice("You remove the IED from [src]."))
+ return
-/obj/item/restraints/legcuffs/beartrap/energy/New()
+ if(sig)
+ sig.forceMove(get_turf(src))
+ sig = null
+ to_chat(user, span_notice("You remove the signaler from [src]."))
+ return
+
+
+/obj/item/restraints/legcuffs/beartrap/Crossed(atom/movable/AM, oldloc)
..()
- addtimer(CALLBACK(src, PROC_REF(dissipate)), 100)
-/obj/item/restraints/legcuffs/beartrap/energy/proc/dissipate()
- if(!ismob(loc))
- do_sparks(1, 1, src)
- qdel(src)
+ if(!armed || !isturf(loc))
+ return
+
+ if(!iscarbon(AM) && !isanimal(AM))
+ return
+
+ var/mob/living/moving_thing = AM
+ if(moving_thing.flying)
+ return
+
+ armed = FALSE
+ icon_state = "[initial(icon_state)][armed]"
+ playsound(src.loc, 'sound/effects/snap.ogg', 50, TRUE)
+ moving_thing.visible_message(span_danger("[moving_thing] triggers [src]."),
+ span_userdanger("You trigger [src]!"))
+
+ if(IED)
+ IED.active = TRUE
+ message_admins("[key_name_admin(usr)] has triggered an IED-rigged [name].")
+ add_game_logs("has triggered an IED-rigged [name].", usr)
+ addtimer(CALLBACK(src, PROC_REF(delayed_prime)), IED.det_time)
+
+ if(sig)
+ sig.signal()
+
+ if(ishuman(moving_thing))
+ var/mob/living/carbon/human/moving_human = moving_thing
+ if(moving_human.lying)
+ moving_human.apply_damage(trap_damage, BRUTE, BODY_ZONE_CHEST)
+ else
+ moving_human.apply_damage(trap_damage, BRUTE, (pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)))
+
+ if(!moving_human.legcuffed && moving_human.get_num_legs() >= 2) //beartrap can't cuff you leg if there's already a beartrap or legcuffs.
+ moving_human.equip_to_slot(src, slot_legcuffed)
+ SSblackbox.record_feedback("tally", "handcuffs", 1, type)
+
+ return
+
+ moving_thing.apply_damage(trap_damage, BRUTE)
+
-/obj/item/restraints/legcuffs/beartrap/energy/attack_hand(mob/user)
- Crossed(user) //honk
+/obj/item/restraints/legcuffs/beartrap/proc/delayed_prime()
+ if(!QDELETED(src) && !QDELETED(IED))
+ IED.prime()
-/obj/item/restraints/legcuffs/beartrap/energy/cyborg
- breakouttime = 40 // Cyborgs shouldn't have a strong restraint
/obj/item/restraints/legcuffs/bola
name = "bola"
desc = "A restraining device designed to be thrown at the target. Upon connecting with said target, it will wrap around their legs, making it difficult for them to move quickly."
icon_state = "bola"
item_state = "bola"
- breakouttime = 60//easy to apply, easy to break out of
+ breakouttime = 6 SECONDS //easy to apply, easy to break out of
gender = NEUTER
origin_tech = "engineering=3;combat=1"
hitsound = 'sound/effects/snap.ogg'
///the duration of the stun in seconds
- var/weaken = 0
+ var/weaken_amt = 0
throw_speed = 4
+
/obj/item/restraints/legcuffs/bola/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
- playsound(loc,'sound/weapons/bolathrow.ogg', 50, TRUE)
- if(!..())
- return
+ playsound(loc, 'sound/weapons/bolathrow.ogg', 50, TRUE)
+ ..()
+
/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed,
return//abort
- var/mob/living/carbon/C = hit_atom
- if(!C.legcuffed && C.get_num_legs() >= 2)
- visible_message("[src] ensnares [C]!")
- C.equip_to_slot(src, slot_legcuffed)
- SSblackbox.record_feedback("tally", "handcuffs", 1, type)
- to_chat(C, "[src] ensnares you!")
- C.Weaken(weaken)
- playsound(loc, hitsound, 50, TRUE)
- if(istype(src, /obj/item/restraints/legcuffs/bola/sinew))
- src.flags = DROPDEL
+
+ var/mob/living/carbon/target = hit_atom
+ if(target.legcuffed || target.get_num_legs() < 2)
+ return
+
+ var/datum/antagonist/vampire/vamp = target.mind?.has_antag_datum(/datum/antagonist/vampire)
+ if(vamp && HAS_TRAIT_FROM(target, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT))
+ if(vamp.bloodusable)
+ vamp.bloodusable = max(vamp.bloodusable - 10, 0)
+ target.visible_message(span_danger("[target] deflects [src]!"),
+ span_notice("You deflect [src], it costs you 10 usable blood."))
+ return
+
+ REMOVE_TRAIT(target, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT)
+
+ target.visible_message(span_danger("[src] ensnares [target]!"))
+ to_chat(target, span_userdanger("[src] ensnares you!"))
+ target.equip_to_slot(src, slot_legcuffed)
+ if(weaken_amt)
+ target.Weaken(weaken_amt)
+ playsound(loc, hitsound, 50, TRUE)
+ SSblackbox.record_feedback("tally", "handcuffs", 1, type)
+ if(istype(src, /obj/item/restraints/legcuffs/bola/sinew))
+ src.flags = DROPDEL
+
/obj/item/restraints/legcuffs/bola/tactical //traitor variant
name = "reinforced bola"
@@ -180,7 +205,8 @@
icon_state = "bola_r"
breakouttime = 100
origin_tech = "engineering=4;combat=3"
- weaken = 2 SECONDS
+ weaken_amt = 2 SECONDS
+
/obj/item/restraints/legcuffs/bola/energy //For Security
name = "energy bola"
@@ -189,14 +215,8 @@
item_state = "ebola"
hitsound = 'sound/weapons/tase.ogg'
w_class = WEIGHT_CLASS_SMALL
- breakouttime = 40
+ breakouttime = 4 SECONDS
-/obj/item/restraints/legcuffs/bola/energy/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
- if(iscarbon(hit_atom))
- var/obj/item/restraints/legcuffs/beartrap/B = new /obj/item/restraints/legcuffs/beartrap/energy/cyborg(get_turf(hit_atom))
- B.Crossed(hit_atom, null)
- qdel(src)
- ..()
/obj/item/restraints/legcuffs/bola/sinew
name = "skull bola"
@@ -204,10 +224,11 @@
icon_state = "bola_s"
item_state = "bola_watcher"
+
/obj/item/restraints/legcuffs/bola/sinew/dropped(mob/living/user)
if(flags & DROPDEL)
user.apply_damage(10, BRUTE, (pick("l_leg", "r_leg")))
- new /obj/item/restraints/handcuffs/sinew(loc)
- new /obj/item/stack/sheet/bone(loc)
- new /obj/item/stack/sheet/bone(loc)
+ new /obj/item/restraints/handcuffs/sinew(user.loc)
+ new /obj/item/stack/sheet/bone(user.loc, 2)
. = ..()
+
diff --git a/code/modules/antagonists/vampire/vampire_datum.dm b/code/modules/antagonists/vampire/vampire_datum.dm
index 7a4be1e06c5..fea211493c5 100644
--- a/code/modules/antagonists/vampire/vampire_datum.dm
+++ b/code/modules/antagonists/vampire/vampire_datum.dm
@@ -31,20 +31,19 @@
var/list/dissected_humans = list()
/// Associated list of all damage modifiers human vampire has.
var/list/damage_modifiers = list(
- "brute" = 0,
- "burn" = 0,
- "tox" = 0,
- "oxy" = 0,
- "clone" = 0,
- "brain" = 0,
- "stamina" = 0
+ BRUTE = 0,
+ BURN = 0,
+ TOX = 0,
+ OXY = 0,
+ CLONE = 0,
+ BRAIN = 0,
+ STAMINA = 0
)
/datum/antagonist/vampire/Destroy(force, ...)
owner.current.create_log(CONVERSION_LOG, "De-vampired")
draining = null
- QDEL_LIST(powers)
QDEL_NULL(subclass)
return ..()
@@ -256,6 +255,9 @@
var/spell = new path(owner)
if(istype(spell, /obj/effect/proc_holder/spell))
owner.AddSpell(spell)
+ if(istype(spell, /obj/effect/proc_holder/spell/vampire) && subclass)
+ var/obj/effect/proc_holder/spell/vampire/v_spell = spell
+ v_spell.on_trophie_update(src, force = TRUE)
if(istype(spell, /obj/effect/proc_holder/spell/vampire/self/dissect_info) && subclass)
subclass.spell_TGUI = spell
diff --git a/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm b/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm
index 7e6af7bb100..6d659344596 100644
--- a/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm
+++ b/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm
@@ -259,7 +259,7 @@
action_icon_state = "vampire_claws"
create_attack_logs = FALSE
base_cooldown = 5 SECONDS
- required_blood = 20
+ required_blood = 10
deduct_blood_on_cast = FALSE
var/is_dissecting = FALSE
@@ -332,7 +332,7 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
var/list/all_organs = list()
for(var/obj/item/organ/internal/organ in target.internal_organs)
- if(!is_type_in_list(organ, GLOB.vampire_dissect_organs))
+ if(!is_type_in_list(organ, GLOB.vampire_dissect_organs) || (organ.status & ORGAN_ROBOT))
continue
if(istype(organ, /obj/item/organ/internal/heart) && \
(t_hearts >= vampire.subclass.crit_organ_cap || t_hearts >= MAX_TROPHIES_PER_TYPE_CRITICAL))
@@ -462,6 +462,7 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
gain_desc = "You can now use the ability Check Trophies to familiarize yourself with all the passive effects granted."
action_icon_state = "blood_rush"
human_req = FALSE
+ stat_allowed = UNCONSCIOUS
create_attack_logs = FALSE
base_cooldown = 1 SECONDS
@@ -481,7 +482,7 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
/obj/effect/proc_holder/spell/vampire/self/dissect_info/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
- ui = new(user, src, ui_key, "VampireTrophiesStatus", "Trophies Status", 650, 800, master_ui, state)
+ ui = new(user, src, ui_key, "VampireTrophiesStatus", "Trophies Status", 700, 800, master_ui, state)
ui.set_autoupdate(FALSE)
ui.open()
@@ -622,7 +623,7 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "ashen_skull"
pass_flags = PASSTABLE | PASSGRILLE | PASSFENCE
- speed = 0.5
+ speed = 1
range = 5
damage = 5
armour_penetration = 100
@@ -733,10 +734,6 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
user.visible_message(span_danger("[user] starts moving with unnatural speed!"), \
span_notice("You lunge into the air..."))
- var/prev_layer = user.layer
- var/prev_flying = user.flying
- var/prev_pixel_x = user.pixel_x
- var/prev_pixel_y = user.pixel_y
var/leap_range = targeting.range
var/distance = get_dist(user, target)
@@ -744,8 +741,6 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
leap_range = distance + 1
user.layer = LOW_LANDMARK_LAYER
- user.flying = TRUE
- user.canmove = FALSE
user.pass_flags |= (PASSTABLE|PASSGRILLE|PASSFENCE|PASSMOB)
var/dir_switch = FALSE
@@ -754,6 +749,8 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
if(QDELETED(user))
return
+ user.canmove = FALSE
+ user.flying = TRUE
var/direction = get_dir(user, target)
var/turf/next_step = get_step(user, direction)
user.face_atom(target)
@@ -789,11 +786,11 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
if(QDELETED(user))
return
- user.layer = prev_layer
- user.flying = prev_flying
- user.pixel_y = prev_pixel_y
- user.pixel_y = prev_pixel_x
- user.transform = old_transform
+ user.layer = initial(user.layer)
+ user.flying = initial(user.flying)
+ user.pixel_y = initial(user.pixel_y)
+ user.pixel_y = initial(user.pixel_x)
+ user.transform = initial(user.transform)
user.canmove = TRUE
user.pass_flags &= ~(PASSTABLE|PASSGRILLE|PASSFENCE|PASSMOB)
@@ -1019,6 +1016,7 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
original_body = user
vampire_animal.status_flags |= GODMODE
+ user.notransform = TRUE
user.status_flags |= GODMODE
vampire_animal.canmove = FALSE
user.forceMove(vampire_animal)
@@ -1058,6 +1056,8 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
original_body.forceMove(get_turf(user))
original_body.canmove = FALSE
user.mind.transfer_to(original_body)
+ var/datum/antagonist/vampire/vampire = original_body.mind?.has_antag_datum(/datum/antagonist/vampire)
+ vampire?.draw_HUD()
var/obj/effect/temp_visual/vamp_mist_out/effect = new(get_turf(user))
effect.alpha = 0
@@ -1079,6 +1079,7 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
stack_trace("Spell or original_body was qdeled during the [src] work.")
return
+ original_body.notransform = FALSE
original_body.status_flags &= ~GODMODE
original_body.canmove = TRUE
is_transformed = FALSE
@@ -1561,6 +1562,9 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
if(human_vampire.loc != src)
return
+ if(human_vampire.stat == CONSCIOUS)
+ human_vampire.KnockOut() // to be sure
+
// cleansing reagents
for(var/datum/reagent/reagent in human_vampire.reagents.reagent_list)
if(istype(reagent, /datum/reagent/medicine/spaceacillin) || istype(reagent, /datum/reagent/medicine/mutadone))
@@ -2074,7 +2078,10 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
var/t_kidneys = vampire.get_trophies("kidneys")
if(t_kidneys)
- heal_ordered_damage(t_kidneys, list(BRUTE, BURN, TOX, OXY, CLONE)) // 10 life-leech on MAX
+ var/mob/living/who = src
+ if(health >= maxHealth && human_vampire)
+ who = human_vampire
+ who.heal_ordered_damage(t_kidneys, list(BRUTE, BURN, TOX, OXY, CLONE)) // 10 life-leech on MAX
var/t_livers = vampire.get_trophies("livers")
if(t_livers && human_vampire && l_target.mind && l_target.ckey)
@@ -2152,13 +2159,15 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
/mob/living/simple_animal/hostile/vampire/hound/AttackingTarget()
. = ..()
- var/mob/living/target = .
- if(!istype(target) || !vampire)
+
+ if(!. || !isliving(target) || !vampire)
return
- if(target.affects_vampire(src) && prob(vampire.get_trophies("eyes") * 3)) // 30% chance MAX
- target.Stun(1 SECONDS)
- target.visible_message(span_danger("[src] scares [target]!"))
+ var/mob/living/l_target = target
+
+ if(l_target.affects_vampire(src) && prob(vampire.get_trophies("eyes") * 3)) // 30% chance MAX
+ l_target.Stun(1 SECONDS)
+ l_target.visible_message(span_danger("[src] scares [l_target]!"))
/mob/living/simple_animal/hostile/vampire/hound/add_spells()
@@ -2200,7 +2209,7 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
melee_damage_lower = 5
melee_damage_upper = 10
armour_penetration = 50
- pass_flags = PASSTABLE | PASSFENCE | PASSGRILLE | PASSMOB
+ pass_flags = PASSTABLE | PASSFENCE | PASSMOB
/mob/living/simple_animal/hostile/vampire/bats_summoned/Initialize(mapload, datum/antagonist/vampire/vamp, mob/living/carbon/human/h_vampire, obj/effect/proc_holder/spell/vampire/metamorphosis/meta_spell)
@@ -2258,7 +2267,7 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list(
/mob/living/simple_animal/hostile/vampire/bats_summoned/Found(atom/A)
if(isliving(A))
var/mob/living/victim = A
- if(victim.mind && (!isvampire(victim) && !isvampirethrall(victim))) // target sentient first
+ if(victim.mind && victim.stat != DEAD && (!isvampire(victim) && !isvampirethrall(victim))) // target sentient first
return TRUE
return FALSE
diff --git a/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm b/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm
index 49a6b7b2a37..8c35f8e63e8 100644
--- a/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm
+++ b/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm
@@ -14,6 +14,7 @@
desc = "You use a large portion of your power to sway those loyal to none to be loyal to you only."
gain_desc = "You have gained the ability to thrall people to your will."
action_icon_state = "vampire_enthrall"
+ need_active_overlay = TRUE
required_blood = 150
deduct_blood_on_cast = FALSE
@@ -296,12 +297,12 @@
/obj/effect/proc_holder/spell/vampire/hysteria/cast(list/targets, mob/user)
- for(var/mob/living/carbon/human/H as anything in targets)
- if(!H.affects_vampire(user))
+ for(var/mob/living/carbon/human/target in targets)
+ if(!target.affects_vampire(user))
continue
- SEND_SOUND(H, 'sound/hallucinations/over_here1.ogg')
- H.Slowed(4 SECONDS)
- H.flash_eyes(2, TRUE) // flash to give them a second to lose track of who is who
- new /obj/effect/hallucination/delusion(get_turf(user), H, skip_nearby = FALSE)
+ SEND_SOUND(target, 'sound/hallucinations/over_here1.ogg')
+ target.Slowed(4 SECONDS)
+ target.flash_eyes(2, TRUE) // flash to give them a second to lose track of who is who
+ new /obj/effect/hallucination/delusion(get_turf(user), target, skip_nearby = FALSE)
diff --git a/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm b/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm
index f355dddfc0a..1facb14919b 100644
--- a/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm
+++ b/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm
@@ -88,8 +88,8 @@
/obj/effect/proc_holder/spell/vampire/self/overwhelming_force
name = "Overwhelming Force"
- desc = "When toggled you will automatically pry open doors that you bump into if you do not have access."
- gain_desc = "You have gained the ability to force open doors at a small blood cost."
+ desc = "When toggled you will automatically pry open doors that you bump into if you do not have access. Also deflects any thrown bola."
+ gain_desc = "You have gained the ability to force open doors and deflect bola at a small blood cost."
base_cooldown = 2 SECONDS
action_icon_state = "OH_YEAAAAH"
@@ -172,34 +172,30 @@
new /obj/effect/temp_visual/demonic_grasp(loc)
-/obj/item/projectile/magic/demonic_grasp/on_hit(atom/target, blocked, hit_zone)
+/obj/item/projectile/magic/demonic_grasp/on_hit(mob/living/target, blocked, hit_zone)
. = ..()
- if(!isliving(target))
+ if(!istype(target) || !firer || !target.affects_vampire(firer))
return
- playsound(get_turf(target), 'sound/misc/demon_attack1.ogg', 50, TRUE)
- var/mob/living/L = target
- L.Immobilize(3 SECONDS)
- new /obj/effect/temp_visual/demonic_grasp(loc)
- var/throw_target
- if(!firer)
- return
-
- if(!L.affects_vampire(firer))
- return
+ var/target_turf = get_turf(target)
+ target.Immobilize(5 SECONDS)
+ playsound(target_turf, 'sound/misc/demon_attack1.ogg', 50, TRUE)
+ new /obj/effect/temp_visual/demonic_grasp(target_turf)
+ var/throw_target
switch(firer.a_intent)
if(INTENT_DISARM)
- throw_target = get_edge_target_turf(L, get_dir(firer, L))
- L.throw_at(throw_target, 2, 5, spin = FALSE, callback = CALLBACK(src, PROC_REF(create_snare), L)) // shove away
-
+ throw_target = get_edge_target_turf(target, get_dir(firer, target))
+ target.throw_at(throw_target, 2, 5, spin = FALSE, callback = CALLBACK(src, PROC_REF(create_snare), target)) // shove away
if(INTENT_GRAB)
- throw_target = get_step(firer, get_dir(firer, L))
- L.throw_at(throw_target, 2, 5, spin = FALSE, diagonals_first = TRUE, callback = CALLBACK(src, PROC_REF(create_snare), L)) // pull towards
+ throw_target = get_step(firer, get_dir(firer, target))
+ target.throw_at(throw_target, 2, 5, spin = FALSE, diagonals_first = TRUE, callback = CALLBACK(src, PROC_REF(create_snare), target)) // pull towards
+ else
+ create_snare(target)
-/obj/item/projectile/magic/demonic_grasp/proc/create_snare(mob/target)
- new /obj/effect/temp_visual/demonic_snare(target.loc)
+/obj/item/projectile/magic/demonic_grasp/proc/create_snare(mob/living/target)
+ new /obj/effect/temp_visual/demonic_snare(get_turf(target))
/obj/effect/temp_visual/demonic_grasp
@@ -211,7 +207,7 @@
/obj/effect/temp_visual/demonic_snare
icon = 'icons/effects/vampire_effects.dmi'
icon_state = "immobilized"
- duration = 3 SECONDS
+ duration = 5 SECONDS
/obj/effect/proc_holder/spell/vampire/charge
diff --git a/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm b/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm
index b54d0536cd4..5e4e08c385f 100644
--- a/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm
+++ b/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm
@@ -314,7 +314,7 @@
name = "Sanguine Pool"
desc = "You shift your form into a pool of blood, making you invulnerable and able to move through anything that's not a wall or space. You leave a trail of blood behind you when you do this."
gain_desc = "You have gained the ability to shift into a pool of blood, allowing you to evade pursuers with great mobility."
- jaunt_duration = 3 SECONDS
+ jaunt_duration = 8 SECONDS
clothes_req = FALSE
panel = "Vampire"
school = "vampire"
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 78c718b929a..dc422a4d46b 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -438,14 +438,14 @@ GLOBAL_LIST_INIT(major_hallutinations, list("fake"=20,"death"=10,"xeno"=10,"sing
/obj/effect/hallucination/delusion/New(loc, mob/living/carbon/T, force_kind = null, duration = 30 SECONDS, skip_nearby = TRUE, custom_icon = null, custom_icon_file = null)
. = ..()
target = T
- var/image/A = null
- var/kind = force_kind ? force_kind : pick("clown", "carp", "corgi", "skeleton", "zombie", "demon", "bear", "goat", "alien", "faithless", "pink", "migo", "horror", "blob", "fly", "legion", "morph", "pirate", "wizard", "eskimo", "syndie1", "syndie2", "fleshling")
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(H.stat == DEAD || H == target)
continue
if(skip_nearby && (H in view(target)))
continue
+ var/image/A = null
+ var/kind = force_kind ? force_kind : pick("clown", "carp", "corgi", "skeleton", "zombie", "demon", "bear", "goat", "alien", "faithless", "pink", "migo", "horror", "blob", "fly", "legion", "morph", "pirate", "wizard", "eskimo", "syndie1", "syndie2", "fleshling")
switch(kind)
if("clown")//Clown
A = image('icons/mob/simple_human.dmi',H,"clown")
@@ -499,8 +499,8 @@ GLOBAL_LIST_INIT(major_hallutinations, list("fake"=20,"death"=10,"xeno"=10,"sing
if(target.client)
delusions |= A
target.client.images |= A
- sleep(duration)
- qdel(src)
+ QDEL_IN(src, duration)
+
/obj/effect/hallucination/delusion/Destroy()
for(var/image/I in delusions)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index a31a30da77d..0e28877270b 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -917,20 +917,13 @@
number += MFP.flash_protect
for(var/obj/item/organ/internal/cyberimp/eyes/EFP in internal_organs)
number += EFP.flash_protect
-
- var/datum/antagonist/vampire/vampire = mind?.has_antag_datum(/datum/antagonist/vampire)
- if(vampire?.get_ability(/datum/vampire_passive/eyes_flash_protection))
- number++
- if(vampire?.get_ability(/datum/vampire_passive/eyes_welding_protection))
- number++
-
return number
/mob/living/carbon/human/check_ear_prot()
- var/datum/antagonist/vampire/vampire = mind?.has_antag_datum(/datum/antagonist/vampire)
- if(vampire?.get_ability(/datum/vampire_passive/ears_bang_protection))
- return HEARING_PROTECTION_TOTAL
+ . = ..()
+ if(.)
+ return
if(!can_hear())
return HEARING_PROTECTION_TOTAL
if(istype(l_ear, /obj/item/clothing/ears/earmuffs))
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 7d0ee56265e..12169490a74 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -26,7 +26,7 @@
if(sponge)
if(dna.species && amount > 0)
if(use_brain_mod)
- amount = amount * (dna.species.brain_mod + get_vampire_bonus("brain"))
+ amount = amount * (dna.species.brain_mod + get_vampire_bonus(BRAIN))
sponge.damage = clamp(sponge.damage + amount, 0, 120)
if(sponge.damage >= 120 && stat != DEAD)
visible_message("[src] goes limp, [p_their()] facial expression utterly blank.")
@@ -44,7 +44,7 @@
if(sponge)
if(dna.species && amount > 0)
if(use_brain_mod)
- amount = amount * (dna.species.brain_mod + get_vampire_bonus("brain"))
+ amount = amount * (dna.species.brain_mod + get_vampire_bonus(BRAIN))
sponge.damage = clamp(amount, 0, 120)
if(sponge.damage >= 120 && stat != DEAD)
visible_message("[src] goes limp, [p_their()] facial expression utterly blank.")
@@ -90,7 +90,7 @@
/mob/living/carbon/human/adjustBruteLoss(amount, updating_health = TRUE, damage_source = null, robotic = FALSE)
if(amount > 0)
if(dna.species)
- amount = amount * (dna.species.brute_mod + get_vampire_bonus("brute"))
+ amount = amount * (dna.species.brute_mod + get_vampire_bonus(BRUTE))
take_overall_damage(amount, 0, updating_health, used_weapon = damage_source)
else
heal_overall_damage(-amount, 0, updating_health, FALSE, robotic)
@@ -100,7 +100,7 @@
/mob/living/carbon/human/adjustFireLoss(amount, updating_health = TRUE, damage_source = null, robotic = FALSE)
if(amount > 0)
if(dna.species)
- amount = amount * (dna.species.burn_mod + get_vampire_bonus("burn"))
+ amount = amount * (dna.species.burn_mod + get_vampire_bonus(BURN))
take_overall_damage(0, amount, updating_health, used_weapon = damage_source)
else
heal_overall_damage(0, -amount, updating_health, FALSE, robotic)
@@ -109,7 +109,7 @@
/mob/living/carbon/human/proc/adjustBruteLossByPart(amount, organ_name, obj/damage_source = null, updating_health = TRUE)
if(dna.species && amount > 0)
- amount = amount * (dna.species.brute_mod + get_vampire_bonus("brute"))
+ amount = amount * (dna.species.brute_mod + get_vampire_bonus(BRUTE))
if(organ_name in bodyparts_by_name)
var/obj/item/organ/external/O = get_organ(organ_name)
@@ -122,7 +122,7 @@
/mob/living/carbon/human/proc/adjustFireLossByPart(amount, organ_name, obj/damage_source = null, updating_health = TRUE)
if(dna.species && amount > 0)
- amount = amount * (dna.species.burn_mod + get_vampire_bonus("burn"))
+ amount = amount * (dna.species.burn_mod + get_vampire_bonus(BURN))
if(organ_name in bodyparts_by_name)
var/obj/item/organ/external/O = get_organ(organ_name)
@@ -136,7 +136,7 @@
/mob/living/carbon/human/adjustCloneLoss(amount, updating_health)
if(dna.species && amount > 0)
- amount = amount * (dna.species.clone_mod + get_vampire_bonus("clone"))
+ amount = amount * (dna.species.clone_mod + get_vampire_bonus(CLONE))
. = ..()
var/heal_prob = max(0, 80 - getCloneLoss())
@@ -179,7 +179,7 @@
oxyloss = 0
return FALSE
if(dna.species && amount > 0)
- amount = amount * (dna.species.oxy_mod + get_vampire_bonus("oxy"))
+ amount = amount * (dna.species.oxy_mod + get_vampire_bonus(OXY))
. = ..()
/mob/living/carbon/human/setOxyLoss(amount, updating_health)
@@ -187,12 +187,12 @@
oxyloss = 0
return FALSE
if(dna.species && amount > 0)
- amount = amount * (dna.species.oxy_mod + get_vampire_bonus("oxy"))
+ amount = amount * (dna.species.oxy_mod + get_vampire_bonus(OXY))
. = ..()
/mob/living/carbon/human/adjustToxLoss(amount, updating_health)
if(dna.species && amount > 0)
- amount = amount * (dna.species.tox_mod + get_vampire_bonus("tox"))
+ amount = amount * (dna.species.tox_mod + get_vampire_bonus(TOX))
. = ..()
if(amount > 0 && mind)
@@ -202,17 +202,17 @@
/mob/living/carbon/human/setToxLoss(amount, updating_health)
if(dna.species && amount > 0)
- amount = amount * (dna.species.tox_mod + get_vampire_bonus("tox"))
+ amount = amount * (dna.species.tox_mod + get_vampire_bonus(TOX))
. = ..()
/mob/living/carbon/human/adjustStaminaLoss(amount, updating_health)
if(dna.species && amount > 0)
- amount = amount * (dna.species.stamina_mod + get_vampire_bonus("stamina"))
+ amount = amount * (dna.species.stamina_mod + get_vampire_bonus(STAMINA))
. = ..()
/mob/living/carbon/human/setStaminaLoss(amount, updating_health)
if(dna.species && amount > 0)
- amount = amount * (dna.species.stamina_mod + get_vampire_bonus("stamina"))
+ amount = amount * (dna.species.stamina_mod + get_vampire_bonus(STAMINA))
. = ..()
////////////////////////////////////////////
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index a10161b1a4d..86273e7924a 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -542,14 +542,15 @@ emp_act
dna.species.spec_attacked_by(I, user, affecting, user.a_intent, src)
+
//this proc handles being hit by a thrown atom
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
var/obj/item/I
var/throwpower = 30
- if(istype(AM, /obj/item))
+ if(isitem(AM))
I = AM
throwpower = I.throwforce
- if(I.thrownby == src) //No throwing stuff at yourself to trigger reactions
+ if(locateUID(I.thrownby) == src) //No throwing stuff at yourself to trigger reactions
return ..()
SEND_SIGNAL(src, COMSIG_CARBON_HITBY)
if(check_shields(AM, throwpower, "\the [AM.name]", THROWN_PROJECTILE_ATTACK))
@@ -565,9 +566,10 @@ emp_act
skipcatch = TRUE //can't catch the now embedded item
if(!blocked)
dna.species.spec_hitby(AM, src)
- return ..()
+ return ..(AM, skipcatch, hitpush, blocked, throwingdatum)
+
-/mob/living/carbon/human/proc/embed_item_inside(var/obj/item/I)
+/mob/living/carbon/human/proc/embed_item_inside(obj/item/I)
if(ismob(I.loc))
var/mob/M = I.loc
M.drop_item_ground(I)
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index 272ce877de8..5645c648fac 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -406,7 +406,7 @@
switch(damagetype)
if(BRUTE)
- damage = damage * brute_mod
+ damage = damage * (brute_mod + H.get_vampire_bonus(BRUTE))
if(damage)
H.damageoverlaytemp = 20
@@ -414,7 +414,7 @@
H.UpdateDamageIcon()
if(BURN)
- damage = damage * burn_mod
+ damage = damage * (burn_mod + H.get_vampire_bonus(BURN))
if(damage)
H.damageoverlaytemp = 20
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 0f8f485ea39..aaa527fb703 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -925,10 +925,23 @@
addtimer(CALLBACK(src, PROC_REF(clear_fullscreen), "flash", 25), 25)
return TRUE
+
/mob/living/proc/check_eye_prot()
- return 0
+ var/number = 0
+ var/datum/antagonist/vampire/vampire = mind?.has_antag_datum(/datum/antagonist/vampire)
+ if(vampire?.get_ability(/datum/vampire_passive/eyes_flash_protection))
+ number++
+ if(vampire?.get_ability(/datum/vampire_passive/eyes_welding_protection))
+ number++
+ return number
+
/mob/living/proc/check_ear_prot()
+ var/datum/antagonist/vampire/vampire = mind?.has_antag_datum(/datum/antagonist/vampire)
+ if(vampire?.get_ability(/datum/vampire_passive/ears_bang_protection))
+ return HEARING_PROTECTION_TOTAL
+ return HEARING_PROTECTION_NONE
+
// The src mob is trying to strip an item from someone
// Override if a certain type of mob should be behave differently when stripping items (can't, for example)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 15a83ac05ec..433ebf6b1eb 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -85,9 +85,10 @@
else
return 0
+
//this proc handles being hit by a thrown atom
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
- if(istype(AM, /obj/item))
+ if(isitem(AM))
var/obj/item/I = AM
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
var/dtype = BRUTE
@@ -104,21 +105,30 @@
playsound(loc, 'sound/weapons/genhit.ogg',volume, TRUE, -1) //...play genhit.ogg.
else if(!I.throwhitsound && I.throwforce > 0) //Otherwise, if the item doesn't have a throwhitsound and has a throwforce greater than zero...
- playsound(loc, 'sound/weapons/genhit1.ogg', volume, 1, -1)//...play genhit1.ogg
+ playsound(loc, 'sound/weapons/genhit1.ogg', volume, TRUE, -1)//...play genhit1.ogg
if(!I.throwforce)// Otherwise, if the item's throwforce is 0...
- playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg.
- if(!blocked)
- visible_message("[src.declent_ru(NOMINATIVE)] получа[pluralize_ru(src.gender,"ет","ют")] удар [I.declent_ru(INSTRUMENTAL)].",
- "[src.declent_ru(NOMINATIVE)] получа[pluralize_ru(src.gender,"ет","ют")] удар [I.declent_ru(INSTRUMENTAL)].")
- var/armor = run_armor_check(zone, "melee", "Броня защитила [parse_zone(zone)].", "[pluralize_ru(src.gender,"Твоя","Ваша")] броня смягчила удар по [parse_zone(zone)].", I.armour_penetration) // TODO: перевод зон
- apply_damage(I.throwforce, dtype, zone, armor, is_sharp(I), I)
- if(I.thrownby)
- add_attack_logs(I.thrownby, src, "Hit with thrown [I]", !I.throwforce ? ATKLOG_ALMOSTALL : null) // Only message if the person gets damages
- else
- return 1
- else
- playsound(loc, 'sound/weapons/genhit.ogg', 50, TRUE, -1)
- ..()
+ playsound(loc, 'sound/weapons/throwtap.ogg', TRUE, volume, -1)//...play throwtap.ogg.
+
+ if(blocked)
+ return TRUE
+
+ var/mob/thrower = locateUID(I.thrownby)
+ if(thrower)
+ add_attack_logs(thrower, src, "Hit with thrown [I]", !I.throwforce ? ATKLOG_ALMOSTALL : null) // Only message if the person gets damages
+
+ visible_message(span_danger("[src.declent_ru(NOMINATIVE)] получа[pluralize_ru(src.gender,"ет","ют")] удар [I.declent_ru(INSTRUMENTAL)]."),
+ span_userdanger("[src.declent_ru(NOMINATIVE)] получа[pluralize_ru(src.gender,"ет","ют")] удар [I.declent_ru(INSTRUMENTAL)]."))
+ var/armor = run_armor_check(zone, "melee", "Броня защитила [parse_zone(zone)].", "[pluralize_ru(src.gender,"Твоя","Ваша")] броня смягчила удар по [parse_zone(zone)].", I.armour_penetration) // TODO: перевод зон
+
+ apply_damage(I.throwforce, dtype, zone, armor, is_sharp(I), I)
+ if(QDELETED(src)) //Damage can delete the mob.
+ return
+
+ return ..()
+
+ playsound(loc, 'sound/weapons/genhit.ogg', 50, TRUE, -1)
+ return ..()
+
/**
* Proc that checks if our mob is strong enough to prevent mecha melee attacks from pushing and paralyzing
diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm
index 8712a1eaf34..0d017b4deeb 100644
--- a/code/modules/mob/living/simple_animal/damage_procs.dm
+++ b/code/modules/mob/living/simple_animal/damage_procs.dm
@@ -11,27 +11,29 @@
. = STATUS_UPDATE_HEALTH
if(updating_health)
updatehealth()
+ if(!ckey && !stat && AIStatus == AI_IDLE)//Not unconscious
+ toggle_ai(AI_ON)
/mob/living/simple_animal/adjustBruteLoss(amount, updating_health = TRUE)
if(damage_coeff[BRUTE])
- return adjustHealth(amount * damage_coeff[BRUTE], updating_health)
+ return adjustHealth(amount * (damage_coeff[BRUTE] + get_vampire_bonus(BRUTE)), updating_health)
/mob/living/simple_animal/adjustFireLoss(amount, updating_health)
if(damage_coeff[BURN])
- return adjustHealth(amount * damage_coeff[BURN], updating_health)
+ return adjustHealth(amount * (damage_coeff[BURN] + get_vampire_bonus(BURN)), updating_health)
/mob/living/simple_animal/adjustOxyLoss(amount, updating_health)
if(damage_coeff[OXY])
- return adjustHealth(amount * damage_coeff[OXY], updating_health)
+ return adjustHealth(amount * (damage_coeff[OXY] + get_vampire_bonus(OXY)), updating_health)
/mob/living/simple_animal/adjustToxLoss(amount, updating_health)
if(damage_coeff[TOX])
- return adjustHealth(amount * damage_coeff[TOX], updating_health)
+ return adjustHealth(amount * (damage_coeff[TOX] + get_vampire_bonus(TOX)), updating_health)
/mob/living/simple_animal/adjustCloneLoss(amount, updating_health)
if(damage_coeff[CLONE])
- return adjustHealth(amount * damage_coeff[CLONE], updating_health)
+ return adjustHealth(amount * (damage_coeff[CLONE] + get_vampire_bonus(CLONE)), updating_health)
/mob/living/simple_animal/adjustStaminaLoss(amount, updating_health)
if(damage_coeff[STAMINA])
- return ..(amount*damage_coeff[STAMINA], updating_health)
+ return ..(amount * (damage_coeff[STAMINA] + get_vampire_bonus(STAMINA)), updating_health)
diff --git a/code/modules/mob/living/simple_animal/hostile/mining/marrow_weaver.dm b/code/modules/mob/living/simple_animal/hostile/mining/marrow_weaver.dm
index 66d5f64c092..83da964d877 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining/marrow_weaver.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining/marrow_weaver.dm
@@ -35,7 +35,7 @@
var/anger_move_to_delay = 8
var/anger_speed = 4
-/mob/living/simple_animal/hostile/asteroid/marrowweaver/adjustHealth(amount)
+/mob/living/simple_animal/hostile/asteroid/marrowweaver/adjustHealth(amount, updating_health = TRUE)
if(buttmad == 0)
if(health < maxHealth/3)
buttmad = 1
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 1da83582093..db69be8f1c5 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -628,11 +628,6 @@
if(pulledby || shouldwakeup)
toggle_ai(AI_ON)
-/mob/living/simple_animal/adjustHealth(amount, updating_health = TRUE)
- . = ..()
- if(!ckey && !stat)//Not unconscious
- if(AIStatus == AI_IDLE)
- toggle_ai(AI_ON)
/mob/living/simple_animal/onTransitZ(old_z, new_z)
..()
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
index 7c55167bd00..e41fae01119 100644
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -190,7 +190,7 @@
var/mob/living/carbon/C = M
var/feed_mod = round(age_state.feed/3)
- if((C.dna.species.clone_mod + C.get_vampire_bonus("clone")) > 0)
+ if((C.dna.species.clone_mod + C.get_vampire_bonus(CLONE)) > 0)
C.adjustCloneLoss(rand(2, 4) + feed_mod)
C.adjustToxLoss(rand(1, 2) + feed_mod)
else
diff --git a/tgui/packages/tgui/interfaces/VampireTrophiesStatus.js b/tgui/packages/tgui/interfaces/VampireTrophiesStatus.js
index a5923804806..895203d6397 100644
--- a/tgui/packages/tgui/interfaces/VampireTrophiesStatus.js
+++ b/tgui/packages/tgui/interfaces/VampireTrophiesStatus.js
@@ -9,7 +9,7 @@ const roundTenths = function (input) {
export const VampireTrophiesStatus = (props, context) => {
return (
-
+
@@ -51,7 +51,7 @@ const Trophies = (props, context) => {
textAlign="center"
verticalAlign="middle">
-
+
{
color="transparent"
/>
-
+
{
color="transparent"
/>
-
+
{
color="transparent"
/>
-
+
{
color="transparent"
/>
-
+
{
color="transparent"
/>
-
+
{
color="red"
textAlign="center"
verticalAlign="middle">
-
+
-
+
-
+
-
+