Skip to content

Commit

Permalink
Werewolf Update + Silver Overhaul (#1231)
Browse files Browse the repository at this point in the history
* Werewolf and Silver Bane tweaks

* Fixes

* Forgot STA

* Roguetown reference??

* Adds claw sprites

* Guayo updates

---------

Co-authored-by: NPC1314 <110836368+NPC1314@users.noreply.github.com>
  • Loading branch information
BadAtThisGame302 and NPC1314 authored Dec 16, 2024
1 parent cf56e76 commit 1d50393
Show file tree
Hide file tree
Showing 28 changed files with 709 additions and 753 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/medical.dm
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,5 @@
#define WOUND_SEVERITY_CRITICAL 4
/// Wounds that are almost immediately fatal, such as a dissected aorta
#define WOUND_SEVERITY_FATAL 5
/// This wound has werewolf infection
#define WOUND_SEVERITY_BIOHAZARD 6
4 changes: 2 additions & 2 deletions code/_onclick/hud/ghost.dm
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@
// Store the current time for the player
GLOB.job_respawn_delays[G.ckey] = world.time + target_job.same_job_respawn_delay

verbs -= /client/proc/descend
for(var/turf/spawn_loc in GLOB.underworldcoinspawns)
var/mob/living/carbon/spirit/O = new /mob/living/carbon/spirit(spawn_loc)
O.livingname = G.name
O.ckey = G.ckey
SSdroning.area_entered(get_area(O), O.client)
verbs -= /client/proc/descend
return

// var/take_triumph = FALSE
Expand All @@ -70,12 +70,12 @@
if(C.skeletons)
G.returntolobby()
if(alert("Travel with the boatman?", "", "Yes", "No") == "Yes")
verbs -= /client/proc/descend
for(var/turf/spawn_loc in GLOB.underworldcoinspawns)
var/mob/living/carbon/spirit/O = new /mob/living/carbon/spirit(spawn_loc)
O.livingname = G.name
O.ckey = G.ckey
SSdroning.area_entered(get_area(O), O.client)
verbs -= /client/proc/descend
/* if(world.time < G.ghostize_time + RESPAWNTIME)
var/ttime = round((G.ghostize_time + RESPAWNTIME - world.time) / 10)
var/list/thingsz = list("My connection to the world is still too strong.",\
Expand Down
56 changes: 46 additions & 10 deletions code/_onclick/item_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
*/
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
if(user.check_arm_grabbed(user.active_hand_index))
to_chat(user, "<span class='notice'>I can't move my arm!</span>")
to_chat(user, span_notice("I can't move my arm!"))
return
if(!user.has_hand_for_held_index(user.active_hand_index, TRUE)) //we obviously have a hadn, but we need to check for fingers/prosthetics
to_chat(user, "<span class='warning'>I can't move the fingers.</span>")
to_chat(user, span_warning("I can't move the fingers."))
return
if(!istype(src, /obj/item/grabbing))
if(HAS_TRAIT(user, TRAIT_CHUNKYFINGERS))
to_chat(user, "<span class='warning'>...What?</span>")
to_chat(user, span_warning("...What?"))
return
if(tool_behaviour && target.tool_act(user, src, tool_behaviour))
return
Expand Down Expand Up @@ -80,7 +80,7 @@
return FALSE

if(force && HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='warning'>I don't want to harm other living beings!</span>")
to_chat(user, span_warning("I don't want to harm other living beings!"))
return

M.lastattacker = user.real_name
Expand Down Expand Up @@ -363,12 +363,12 @@
verbu = pick(user.used_intent.attack_verb)
if(newforce > 1)
if(user.rogfat_add(5))
user.visible_message("<span class='danger'>[user] [verbu] [src] with [I]!</span>")
user.visible_message(span_danger("[user] [verbu] [src] with [I]!"))
else
user.visible_message("<span class='warning'>[user] [verbu] [src] with [I]!</span>")
user.visible_message(span_warning("[user] [verbu] [src] with [I]!"))
newforce = 1
else
user.visible_message("<span class='warning'>[user] [verbu] [src] with [I]!</span>")
user.visible_message(span_warning("[user] [verbu] [src] with [I]!"))
take_damage(newforce, I.damtype, "melee", 1)
if(newforce > 1)
I.take_damage(1, BRUTE, "melee")
Expand All @@ -390,12 +390,12 @@
verbu = pick(user.used_intent.attack_verb)
if(newforce > 1)
if(user.rogfat_add(5))
user.visible_message("<span class='danger'>[user] [verbu] [src] with [I]!</span>")
user.visible_message(span_danger("[user] [verbu] [src] with [I]!"))
else
user.visible_message("<span class='warning'>[user] [verbu] [src] with [I]!</span>")
user.visible_message(span_warning("[user] [verbu] [src] with [I]!"))
newforce = 1
else
user.visible_message("<span class='warning'>[user] [verbu] [src] with [I]!</span>")
user.visible_message(span_warning("[user] [verbu] [src] with [I]!"))

take_damage(newforce, I.damtype, "melee", 1)
if(newforce > 1)
Expand Down Expand Up @@ -451,6 +451,42 @@
return "body"

/obj/item/proc/funny_attack_effects(mob/living/target, mob/living/user, nodmg)
if(is_silver)
if(world.time < src.last_used + 120)
to_chat(user, span_notice("The silver effect is on cooldown."))
return

if(ishuman(target) && target.mind)
var/mob/living/carbon/human/s_user = user
var/mob/living/carbon/human/H = target
var/datum/antagonist/werewolf/W = H.mind.has_antag_datum(/datum/antagonist/werewolf/)
var/datum/antagonist/vampirelord/lesser/V = H.mind.has_antag_datum(/datum/antagonist/vampirelord/lesser)
var/datum/antagonist/vampirelord/V_lord = H.mind.has_antag_datum(/datum/antagonist/vampirelord/)
if(V)
if(V.disguised)
H.visible_message("<font color='white'>The silver weapon weakens the curse temporarily!</font>")
to_chat(H, span_userdanger("I'm hit by my BANE!"))
H.apply_status_effect(/datum/status_effect/debuff/silver_curse)
src.last_used = world.time
else
H.visible_message("<font color='white'>The silver weapon weakens the curse temporarily!</font>")
to_chat(H, span_userdanger("I'm hit by my BANE!"))
H.apply_status_effect(/datum/status_effect/debuff/silver_curse)
src.last_used = world.time
if(V_lord)
if(V_lord.vamplevel < 4 && !V)
H.visible_message("<font color='white'>The silver weapon weakens the curse temporarily!</font>")
to_chat(H, span_userdanger("I'm hit by my BANE!"))
H.apply_status_effect(/datum/status_effect/debuff/silver_curse)
src.last_used = world.time
if(V_lord.vamplevel == 4 && !V)
to_chat(s_user, "<font color='red'> The silver weapon fails!</font>")
H.visible_message(H, span_userdanger("This feeble metal can't hurt me, I AM ANCIENT!"))
if(W && W.transformed == TRUE)
H.visible_message("<font color='white'>The silver weapon weakens the curse temporarily!</font>")
to_chat(H, span_userdanger("I'm hit by my BANE!"))
H.apply_status_effect(/datum/status_effect/debuff/silver_curse)
src.last_used = world.time
return

/mob/living/attacked_by(obj/item/I, mob/living/user)
Expand Down
12 changes: 8 additions & 4 deletions code/_onclick/other_mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,19 @@

next_attack_msg.Cut()

var/datum/wound/caused_wound
if(!nodmg)
caused_wound = affecting.bodypart_attacked_by(BCLASS_BITE, dam2do, user, user.zone_selected, crit_message = TRUE)

if(!nodmg)
playsound(src, "smallslash", 100, TRUE, -1)
if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
if(user.mind && mind)
if(user.mind.has_antag_datum(/datum/antagonist/werewolf))
if(!src.mind.has_antag_datum(/datum/antagonist/werewolf))
if(prob(10))
addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living/carbon/human, werewolf_infect)), 3 MINUTES)
if(istype(user.dna.species, /datum/species/werewolf))
caused_wound?.werewolf_infect_attempt()
if(prob(30))
user.werewolf_feed(src)
if(user.mind.has_antag_datum(/datum/antagonist/zombie) && !src.mind.has_antag_datum(/datum/antagonist/zombie))
INVOKE_ASYNC(H, TYPE_PROC_REF(/mob/living/carbon/human, zombie_infect_attempt))

Expand Down
9 changes: 3 additions & 6 deletions code/datums/status_effects/rogue/debuff.dm
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,14 @@
/datum/status_effect/debuff/silver_curse
id = "silver_curse"
alert_type = /atom/movable/screen/alert/status_effect/debuff/silver_curse
duration = 5 SECONDS
/* Pointless subtype, code doesnt handle it well, dont use
/datum/status_effect/debuff/silver_curse/greater
duration = 10 SECONDS
*/
effectedstats = list("strength" = -2,"perception" = -2,"intelligence" = -2, "constitution" = -2, "endurance" = -2,"speed" = -2)
duration = 45 SECONDS

/atom/movable/screen/alert/status_effect/debuff/silver_curse
name = "Silver Curse"
desc = "My BANE!"
icon_state = "hunger3"


// PINTLEDESTRUCTION

/datum/status_effect/debuff/pintledestruction
Expand Down
82 changes: 71 additions & 11 deletions code/datums/wounds/_wound.dm
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,22 @@ GLOBAL_LIST_INIT(primordial_wounds, init_primordial_wounds())
/// Some wounds make no sense on a dismembered limb and need to go
var/qdel_on_droplimb = FALSE

/// Werewolf infection probability for bites on this wound
var/werewolf_infection_probability = 15
/// Time taken until werewolf infection comes in
var/werewolf_infection_time = 2 MINUTES
/// Actual infection timer
var/werewolf_infection_timer

/datum/wound/Destroy(force)
. = ..()
if(bodypart_owner)
remove_from_bodypart()
else if(owner)
remove_from_mob()
if(werewolf_infection_timer)
deltimer(werewolf_infection_timer)
werewolf_infection_timer = null
bodypart_owner = null
owner = null

Expand All @@ -90,9 +100,9 @@ GLOBAL_LIST_INIT(primordial_wounds, init_primordial_wounds())
return
var/visible_name = name
if(is_sewn())
visible_name += " <span class='green'>(sewn)</span>"
visible_name += span_green("(sewn)")
if(is_clotted())
visible_name += " <span class='danger'>(clotted)</span>"
visible_name += span_danger("(clotted)")
return visible_name

/// Description of this wound returned to the player when the bodypart is checked with check_for_injuries()
Expand Down Expand Up @@ -148,11 +158,11 @@ GLOBAL_LIST_INIT(primordial_wounds, init_primordial_wounds())
else if(owner)
remove_from_mob()
LAZYADD(affected.wounds, src)
sortList(affected.wounds, GLOBAL_PROC_REF(cmp_wound_severity_dsc))
sortTim(affected.wounds, GLOBAL_PROC_REF(cmp_wound_severity_dsc))
bodypart_owner = affected
owner = bodypart_owner.owner
on_bodypart_gain(affected)
on_mob_gain(affected.owner)
INVOKE_ASYNC(src, PROC_REF(on_mob_gain), affected.owner) //this is literally a fucking lint error like new species cannot possible spawn with wounds until after its ass
if(crit_message)
var/message = get_crit_message(affected.owner, affected)
if(message)
Expand Down Expand Up @@ -223,6 +233,10 @@ GLOBAL_LIST_INIT(primordial_wounds, init_primordial_wounds())
/datum/wound/proc/on_mob_gain(mob/living/affected)
if(mob_overlay)
affected.update_damage_overlays()
if(werewolf_infection_timer)
deltimer(werewolf_infection_timer)
werewolf_infection_timer = null
werewolf_infect_attempt()

/// Removes this wound from a given, simpler than adding to a bodypart - No extra effects
/datum/wound/proc/remove_from_mob()
Expand All @@ -249,7 +263,7 @@ GLOBAL_LIST_INIT(primordial_wounds, init_primordial_wounds())
/// Called on handle_wounds(), on the life() proc
/datum/wound/proc/on_death()
return

/// Heals this wound by the given amount, and deletes it if it's healed completely
/datum/wound/proc/heal_wound(heal_amount)
// Wound cannot be healed normally, whp is null
Expand All @@ -258,12 +272,13 @@ GLOBAL_LIST_INIT(primordial_wounds, init_primordial_wounds())
var/amount_healed = min(whp, round(heal_amount, DAMAGE_PRECISION))
whp -= amount_healed
if(whp <= 0)
if(bodypart_owner)
remove_from_bodypart(src)
else if(owner)
remove_from_mob(src)
else
qdel(src)
if(!should_persist())
if(bodypart_owner)
remove_from_bodypart(src)
else if(owner)
remove_from_mob(src)
else
qdel(src)
return amount_healed

/// Sews the wound up, changing its properties to the sewn ones
Expand All @@ -285,6 +300,16 @@ GLOBAL_LIST_INIT(primordial_wounds, init_primordial_wounds())
owner?.update_damage_overlays()
return TRUE

/// Checks if this wound has a special infection (zombie or werewolf)
/datum/wound/proc/has_special_infection()
return (werewolf_infection_timer)

/// Some wounds cannot go away naturally
/datum/wound/proc/should_persist()
if(has_special_infection())
return TRUE
return FALSE

/// Cauterizes the wound
/datum/wound/proc/cauterize_wound()
if(!can_cauterize)
Expand All @@ -302,6 +327,41 @@ GLOBAL_LIST_INIT(primordial_wounds, init_primordial_wounds())
/datum/wound/proc/is_clotted()
return !isnull(clotting_threshold) && (bleed_rate <= clotting_threshold)

/datum/wound/proc/werewolf_infect_attempt()
if(QDELETED(src) || QDELETED(owner) || QDELETED(bodypart_owner))
return FALSE
if(werewolf_infection_timer || !ishuman(owner) || !prob(werewolf_infection_probability))
return
var/mob/living/carbon/human/human_owner = owner
if(!human_owner.can_werewolf())
return
if(human_owner.stat >= DEAD) //forget it
return
to_chat(human_owner, span_danger("I feel horrible... REALLY horrible..."))
human_owner.mob_timers["puke"] = world.time
human_owner.vomit(1, blood = TRUE, stun = FALSE)
werewolf_infection_timer = addtimer(CALLBACK(src, PROC_REF(wake_werewolf)), werewolf_infection_time, TIMER_STOPPABLE)
severity = WOUND_SEVERITY_BIOHAZARD
if(bodypart_owner)
sortTim(bodypart_owner.wounds, GLOBAL_PROC_REF(cmp_wound_severity_dsc))
return TRUE

/datum/wound/proc/wake_werewolf()
if(QDELETED(src) || QDELETED(owner) || QDELETED(bodypart_owner))
return FALSE
if(!ishuman(owner))
return FALSE
var/mob/living/carbon/human/human_owner = owner
var/datum/antagonist/werewolf/wolfy = human_owner.werewolf_check()
if(!wolfy)
return FALSE
werewolf_infection_timer = null
owner.flash_fullscreen("redflash3")
to_chat(owner, span_danger("It hurts... Is this really the end for me?"))
owner.emote("scream") // heres your warning to others bro
owner.Knockdown(1)
return wolfy

/// Returns whether or not this wound should embed a weapon
/proc/should_embed_weapon(datum/wound/wound_or_boolean, obj/item/weapon)
if(!istype(wound_or_boolean))
Expand Down
4 changes: 3 additions & 1 deletion code/datums/wounds/arteries.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
sleep_healing = 0
embed_chance = 0

werewolf_infection_probability = 100

/datum/wound/artery/can_stack_with(datum/wound/other)
if(istype(other, /datum/wound/artery) && (type == other.type))
return FALSE
Expand Down Expand Up @@ -79,7 +81,7 @@
"MY HEART IS TORN!",
"MY HEART IS BLEEDING!",
)
to_chat(affected, "<span class='userdanger'>[pick(heartaches)]</span>")
to_chat(affected, span_userdanger("[pick(heartaches)]"))
if(HAS_TRAIT(affected, TRAIT_CRITICAL_WEAKNESS))
affected.death()
if(affected.mind.has_antag_datum(/datum/antagonist/vampirelord/))
Expand Down
2 changes: 2 additions & 0 deletions code/datums/wounds/bruises.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
can_cauterize = FALSE
passive_healing = 0.5

werewolf_infection_probability = 0

/datum/wound/bruise/small
name = "bruise"
whp = 15
Expand Down
2 changes: 2 additions & 0 deletions code/datums/wounds/dislocations.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
critical = TRUE
passive_healing = 0.25
qdel_on_droplimb = TRUE

werewolf_infection_probability = 0
/// Whether or not we can be surgically relocated
var/can_relocate = TRUE

Expand Down
Loading

0 comments on commit 1d50393

Please sign in to comment.