[MIRROR] Rebalanced spider security events (#10939)

Co-authored-by: SatinIsle <98125273+SatinIsle@users.noreply.github.com>
Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-05-27 11:57:34 -07:00
committed by GitHub
parent 2fba42c706
commit 64e25f1d06
6 changed files with 158 additions and 1 deletions

View File

@@ -1256,6 +1256,8 @@
#define REAGENT_ID_PHORON "phoron"
#define REAGENT_SPIDERTOXIN "Spidertoxin"
#define REAGENT_ID_SPIDERTOXIN "spidertoxin"
#define REAGENT_WARNINGTOXIN "Warningtoxin"
#define REAGENT_ID_WARNINGTOXIN "warningtoxin"
#define REAGENT_LEAD "Lead"
#define REAGENT_ID_LEAD "lead"
#define REAGENT_PLASTICIDE "Plasticide"

View File

@@ -1,2 +1,2 @@
/obj/effect/spider/spiderling/virgo
grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/hunter)
grow_as = list(/mob/living/simple_mob/animal/giant_spider/event, /mob/living/simple_mob/animal/giant_spider/hunter/event)

View File

@@ -124,6 +124,10 @@
pain_emote_1p = list("chitter", "click")
pain_emote_3p = list("chitters", "clicks")
var/warning_warmup = 2 SECONDS // How long the leap telegraphing is.
var/warning_sound = 'sound/weapons/spiderlunge.ogg'
/mob/living/simple_mob/animal/giant_spider/Initialize(mapload)
. = ..()
AddComponent(/datum/component/swarming)
@@ -161,5 +165,53 @@
if(poison_per_bite)
poison_per_bite *= 1.3
// A different type of much weaker bite with different effects for event spawned spiders before becoming hostile
/mob/living/simple_mob/animal/giant_spider/proc/warning_bite(mob/living/A)
set waitfor = FALSE
set_AI_busy(TRUE)
// Telegraph, since getting bitten suddenly feels bad.
do_windup_animation(A, warning_warmup)
addtimer(CALLBACK(src, PROC_REF(warning_leap), A), warning_warmup) // For the telegraphing.
/mob/living/simple_mob/animal/giant_spider/proc/warning_leap(mob/living/A)
// Do the actual leap.
status_flags |= LEAPING // Lets us pass over everything.
visible_message(span_danger("\The [src] leaps at \the [A]!"))
throw_at(get_step(get_turf(A), get_turf(src)), 4, 1, src)
playsound(src, warning_sound, 75, 1)
addtimer(CALLBACK(src, PROC_REF(warning_finish), A), 0.5 SECONDS) // For the throw to complete. It won't hold up the AI ticker due to waitfor being false.
/mob/living/simple_mob/animal/giant_spider/proc/warning_finish(mob/living/A)
if(status_flags & LEAPING)
status_flags &= ~LEAPING // Revert special passage ability.
. = FALSE
// Now for the bite.
var/mob/living/victim = null
for(var/mob/living/L in oview(1,src)) // So player-controlled spiders only need to click the tile to stun them.
if(L == src)
continue
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.check_shields(damage = 0, damage_source = src, attacker = src, def_zone = null, attack_text = "the leap"))
continue // We were blocked.
victim = L
break
if(victim)
A.reagents.add_reagent(REAGENT_ID_WARNINGTOXIN, poison_per_bite)
victim.visible_message(span_danger("\The [src] has bitten \the [victim]!"))
to_chat(victim, span_critical("\The [src] bites you and retreats!"))
. = TRUE
step_away(src,victim,3)
set_AI_busy(FALSE)
/decl/mob_organ_names/spider
hit_zones = list("cephalothorax", "abdomen", "left forelegs", "right forelegs", "left hind legs", "right hind legs", "pedipalp", "mouthparts")

View File

@@ -0,0 +1,87 @@
////// Spiders that are spawned for the security event now have a specific unique AI that only does warning bites on non-hostiles.
/mob/living/simple_mob/animal/giant_spider/event
ai_holder_type = /datum/ai_holder/simple_mob/melee/event_spider
/mob/living/simple_mob/animal/giant_spider/hunter/event
ai_holder_type = /datum/ai_holder/simple_mob/melee/event_spider
/datum/ai_holder/simple_mob/melee/event_spider
hostile = FALSE
retaliate = TRUE
var/next_warning = 0
/datum/ai_holder/simple_mob/melee/event_spider/handle_stance_strategical()
ai_log("++++++++++ Slow Process Beginning ++++++++++", AI_LOG_TRACE)
ai_log("handle_stance_strategical() : Called.", AI_LOG_TRACE)
//We got left around for some reason. Goodbye cruel world.
if(!holder)
qdel(src)
ai_log("handle_stance_strategical() : LTT=[lose_target_time]", AI_LOG_TRACE)
if(lose_target_time && (lose_target_time + lose_target_timeout < world.time)) // We were tracking an enemy but they are gone.
ai_log("handle_stance_strategical() : Giving up a chase.", AI_LOG_DEBUG)
remove_target()
if(stance in STANCES_COMBAT)
request_help() // Call our allies.
switch(stance)
if(STANCE_IDLE)
if(istype(holder,/mob/living/simple_mob/animal/giant_spider) && (world.time > next_warning))
do_warning_bite()
if(speak_chance) // In the long loop since otherwise it wont shut up.
handle_idle_speaking()
if(hostile || vore_hostile)
ai_log("handle_stance_strategical() : STANCE_IDLE, going to find_target().", AI_LOG_TRACE)
find_target()
if(should_go_home())
ai_log("handle_stance_tactical() : STANCE_IDLE, going to go home.", AI_LOG_TRACE)
go_home()
else if(should_follow_leader())
ai_log("handle_stance_tactical() : STANCE_IDLE, going to follow leader.", AI_LOG_TRACE)
set_stance(STANCE_FOLLOW)
else if(should_wander())
ai_log("handle_stance_tactical() : STANCE_IDLE, going to wander randomly.", AI_LOG_TRACE)
handle_wander_movement()
if(STANCE_APPROACH)
if(target)
ai_log("handle_stance_strategical() : STANCE_APPROACH, going to calculate_path([target]).", AI_LOG_TRACE)
calculate_path(target)
walk_to_target()
if(STANCE_MOVE)
if(hostile && find_target()) // This will switch its stance.
ai_log("handle_stance_strategical() : STANCE_MOVE, found target and was interrupted.", AI_LOG_TRACE)
return
if(STANCE_FOLLOW)
if(hostile && find_target()) // This will switch its stance.
ai_log("handle_stance_strategical() : STANCE_FOLLOW, found target and was interrupted.", AI_LOG_TRACE)
return
else if(leader)
ai_log("handle_stance_strategical() : STANCE_FOLLOW, going to calculate_path([leader]).", AI_LOG_TRACE)
calculate_path(leader)
walk_to_leader()
ai_log("handle_stance_strategical() : Exiting.", AI_LOG_TRACE)
ai_log("++++++++++ Slow Process Ending ++++++++++", AI_LOG_TRACE)
/datum/ai_holder/simple_mob/melee/event_spider/proc/do_warning_bite()
if(!istype(holder,/mob/living/simple_mob/animal/giant_spider))
return
var/list/intruders = list()
var/mob/living/intruder
var/mob/living/simple_mob/animal/giant_spider/S = holder
for(var/mob/living/L in oview(S,3))
if(can_attack(L))
intruders |= L
if(intruders.len)
intruder = pick(intruders)
next_warning = world.time + 30 SECONDS
S.warning_bite(intruder)

View File

@@ -139,6 +139,21 @@
color = "#2CE893"
strength = 5
/datum/reagent/toxin/warningtoxin
name = REAGENT_WARNINGTOXIN
id = REAGENT_ID_WARNINGTOXIN
description = "A weaker toxin produced by giant spiders applied only in warning bites, known to slow a people down a lot."
color = "#2CE893"
strength = 1
/datum/reagent/toxin/warningtoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
var/poison_strength = strength * M.species.chem_strength_tox
if(strength && alien != IS_DIONA)
M.adjustToxLoss(poison_strength * removed)
M.druggy = max(M.druggy, 10)
M.make_jittery(5)
M.add_chemical_effect(CE_SLOWDOWN, 5)
/datum/reagent/toxin/phoron
name = REAGENT_PHORON
id = REAGENT_ID_PHORON

View File

@@ -3540,6 +3540,7 @@
#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\webslinger.dm"
#include "code\modules\mob\living\simple_mob\subtypes\animal\hyena\hyena.dm"
#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\armadillo_ch.dm"
#include "code\modules\mob\living\simple_mob\subtypes\animal\giant_spider\event_spiders.dm"
#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\cockroach.dm"
#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\crab.dm"
#include "code\modules\mob\living\simple_mob\subtypes\animal\passive\fish.dm"