Skip to content

Commit

Permalink
tweak: Vampire Tweaks and Fixes (#3660)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gottfrei authored Oct 17, 2023
1 parent 5e146da commit 4c076b5
Show file tree
Hide file tree
Showing 23 changed files with 328 additions and 278 deletions.
5 changes: 4 additions & 1 deletion code/controllers/subsystem/throwing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/datums/spell_handler/vampire_spell_handler.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

13 changes: 8 additions & 5 deletions code/datums/status_effects/debuffs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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!
Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion code/game/gamemodes/cult/cult_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
219 changes: 120 additions & 99 deletions code/game/objects/items/weapons/legcuffs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -18,169 +19,194 @@
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("<span class='suicide'>[user] is sticking [user.p_their()] head in the [name]! It looks like [user.p_theyre()] trying to commit suicide.</span>")
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, "<span class='notice'>[src] is now [armed ? "armed" : "disarmed"]</span>")
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, "<span class='warning'>This beartrap already has an IED hooked up to it!</span>")
to_chat(user, span_warning("This beartrap already has an IED hooked up to it!"))
return
if(sig)
to_chat(user, "<span class='warning'>This beartrap already has a signaler hooked up to it!</span>")
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, "<span class='notice'>You sneak [IED] underneath the pressure plate and connect the trigger wire.</span>")
desc = "A trap used to catch bears and other legged creatures. <span class='warning'>There is an IED hooked up to it.</span>"
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, "<span class='warning'>This beartrap already has an IED hooked up to it!</span>")
to_chat(user, span_warning("This beartrap already has an IED hooked up to it!"))
return
if(sig)
to_chat(user, "<span class='warning'>This beartrap already has a signaler hooked up to it!</span>")
to_chat(user, span_warning("This beartrap already has a signaler hooked up to it!"))
return
sig = I
if(sig.secured)
to_chat(user, "<span class='notice'>The signaler is secured.</span>")
to_chat(user, span_notice("The signaler is secured."))
sig = null
return
user.drop_transfer_item_to_loc(I, src)
to_chat(user, "<span class='notice'>You sneak the [sig] underneath the pressure plate and connect the trigger wire.</span>")
desc = "A trap used to catch bears and other legged creatures. <span class='warning'>There is a remote signaler hooked up to it.</span>"
if(istype(I, /obj/item/screwdriver))
if(IED)
IED.forceMove(get_turf(src))
IED = null
to_chat(user, "<span class='notice'>You remove the IED from the [src].</span>")
return
if(sig)
sig.forceMove(get_turf(src))
sig = null
to_chat(user, "<span class='notice'>You remove the signaler from the [src].</span>")
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("<span class='danger'>[L] triggers \the [src].</span>", \
"<span class='userdanger'>You trigger \the [src]!</span>")

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("<span class='danger'>[src] ensnares [C]!</span>")
C.equip_to_slot(src, slot_legcuffed)
SSblackbox.record_feedback("tally", "handcuffs", 1, type)
to_chat(C, "<span class='userdanger'>[src] ensnares you!</span>")
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"
desc = "A strong bola, made with a long steel chain. It looks heavy, enough so that it could trip somebody."
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"
Expand All @@ -189,25 +215,20 @@
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"
desc = "A primitive bola made from the remains of your enemies. It doesn't look very reliable."
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)
. = ..()

Loading

0 comments on commit 4c076b5

Please sign in to comment.