Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e4f04af
Stop time on a lone Reflex Surge
Jackriip Nov 11, 2026
34d4842
Paint the stopped-time afterimages the ring's green
Jackriip Nov 11, 2026
86cd344
Make the lone Reflex Surge slow the world instead of stopping it
Jackriip Nov 11, 2026
df73bd6
Run the dilation on its own timer and keep the user's shots in colour
Jackriip Nov 11, 2026
5d39c96
Keep the user's slow-mo shots in colour and drop deleted things from …
Jackriip Nov 11, 2026
e29bb28
Slow do_after, queued bursts, mechs, turrets and grenade fuses in the…
Jackriip Nov 11, 2026
c865602
Slow gore animation in the dilation field
Jackriip Nov 11, 2026
e348ff4
Turn off the reflex dodge while the Sandevistan user has the world sl…
Jackriip Nov 11, 2026
1a9b11b
Keep the green afterimage trail for the rest of a surge that slowed t…
Jackriip Nov 11, 2026
2af43b4
Let mobs on their own Cascade surge run at full speed in a dilation f…
Jackriip Nov 11, 2026
c739e14
Let dermal plating deflect bullets from the front
Jackriip Nov 11, 2026
53d7947
Run surging mobs at their tier's rate relative to the Sandevistan user
Jackriip Nov 11, 2026
f52637c
Fly every bullet in the dilation field at the field's pace
Jackriip Nov 11, 2026
c0572b6
Slow the weather and the world's sounds for the Sandevistan user duri…
Jackriip Nov 11, 2026
82d56d4
Merge branch 'feature/sandevistan-relative' into feature/sandevistan-…
Jackriip Nov 11, 2026
1b2b68b
Run the Sandevistan slow-mo for the whole surge with no freeze, and l…
Jackriip Nov 11, 2026
2751857
Merge remote-tracking branch 'origin2/feature/hyperviolence-mega' int…
Jackriip Nov 11, 2026
5b8102e
Compute the deflect cap without float drift
Jackriip Nov 11, 2026
9da0e7e
Merge remote-tracking branch 'origin2/feature/hyperviolence-mega' int…
Jackriip Nov 11, 2026
f003e3e
Let the deflect test force a glance past the shared cap
Jackriip Nov 11, 2026
b8ccd88
Roll the Sandevistan ring with the slow-mo, tint behind its front, fl…
Jackriip Nov 11, 2026
b4c7271
Merge remote-tracking branch 'origin2/feature/hyperviolence-mega' int…
Jackriip Nov 11, 2026
5ac509e
Keep a surging NPC's shots untinted, and bring the slow-mo tests in l…
Jackriip Nov 11, 2026
3116f29
Run the Sandevistan user's own mech or vehicle at full speed in their…
Jackriip Nov 11, 2026
09e0e2d
Merge remote-tracking branch 'origin2/feature/hyperviolence-mega' int…
Jackriip Nov 11, 2026
d5cc4e5
Merge commit 'refs/tmp/pr535' into tm/sandy-deflect
Jackriip Nov 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions code/__HELPERS/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,18 @@ GLOBAL_LIST_INIT(skin_tone_names, list(

var/endtime = world.time + delay
var/starttime = world.time
var/dilation_tick = world.time // VOIDCREW EDIT ADDITION - cyberware time dilation
. = TRUE
while (world.time < endtime)
stoplag(1)

// VOIDCREW EDIT ADDITION START - cyberware time dilation (voidcrew/modules/cyberware/ware_sandy_timestop.dm): a slowed body works slower, a frozen one not at all
var/dilation_lost = cyberware_time_lost(user, world.time - dilation_tick)
dilation_tick = world.time
endtime += dilation_lost
starttime += dilation_lost
// VOIDCREW EDIT ADDITION END

if(!QDELETED(progbar))
progbar.update(world.time - starttime)

Expand Down
6 changes: 5 additions & 1 deletion code/datums/components/ranged_attacks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,12 @@
INVOKE_ASYNC(src, PROC_REF(async_fire_ranged_attack), firer, target, modifiers)
if(isnull(burst_shots))
return
// VOIDCREW EDIT CHANGE START - cyberware time dilation (voidcrew/modules/cyberware/ware_sandy_timestop.dm): each burst shot waits for the mob's own clock, so a slowed mob's burst slows down too
cyberware_burst_start = cyberware_burst_clock(firer)
for(var/i in 1 to (burst_shots - 1))
addtimer(CALLBACK(src, PROC_REF(async_fire_ranged_attack), firer, target, modifiers), i * burst_intervals)
addtimer(CALLBACK(src, PROC_REF(cyberware_burst_shot), firer, target, modifiers, i), i * burst_intervals)
// ORIGINAL: addtimer(CALLBACK(src, PROC_REF(async_fire_ranged_attack), firer, target, modifiers), i * burst_intervals)
// VOIDCREW EDIT CHANGE END

/// Actually fire the damn thing
/datum/component/ranged_attacks/proc/async_fire_ranged_attack(mob/living/basic/firer, atom/target, modifiers)
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/grenades/_grenade.dm
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
active = TRUE
icon_state = (base_icon_state || initial(icon_state)) + "_active"
SEND_SIGNAL(src, COMSIG_GRENADE_ARMED, det_time, delayoverride)
addtimer(CALLBACK(src, PROC_REF(detonate)), isnull(delayoverride)? det_time : delayoverride)
addtimer(CALLBACK(src, PROC_REF(cyberware_fuse_done)), isnull(delayoverride)? det_time : delayoverride) // VOIDCREW EDIT CHANGE - cyberware time dilation (voidcrew/modules/cyberware/ware_sandy_timestop.dm): the fuse burns slow in a slowed field. ORIGINAL: addtimer(CALLBACK(src, PROC_REF(detonate)), isnull(delayoverride)? det_time : delayoverride)

/**
* detonate (formerly prime) refers to when the grenade actually delivers its payload (whether or not a boom/bang/detonation is involved)
Expand Down
8 changes: 8 additions & 0 deletions code/game/sound/sound.dm
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,14 @@
if(HAS_TRAIT(src, TRAIT_SOUND_DEBUGGED))
to_chat(src, span_admin("Max Range-[max_distance] Distance-[distance] Vol-[round(sound_to_use.volume, 0.01)] Sound-[sound_to_use.file]"))

// VOIDCREW EDIT CHANGE START - cyberware: a Sandevistan user hears the slowed world slowed (voidcrew/modules/cyberware/ware_sandy_senses.dm)
if(length(GLOB.cyberware_time_fields))
var/sandy_frequency = sound_to_use.frequency
cyberware_dilate_heard(src, turf_source, sound_to_use, usr)
SEND_SOUND(src, sound_to_use)
sound_to_use.frequency = sandy_frequency // the datum can be shared with the next listener
return
// VOIDCREW EDIT CHANGE END
SEND_SOUND(src, sound_to_use)

/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, channel = 0, pressure_affected = FALSE, sound/S)
Expand Down
11 changes: 11 additions & 0 deletions code/modules/projectiles/gun.dm
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,12 @@
if(!user || !firing_burst)
firing_burst = FALSE
return FALSE
// VOIDCREW EDIT ADDITION START - cyberware time dilation (voidcrew/modules/cyberware/ware_sandy_timestop.dm): each burst shot waits for the shooter's own clock, so a burst slows or stops with them
var/dilation_wait = cyberware_burst_wait(user, cyberware_burst_start, cyberware_burst_gap, iteration - 1)
if(dilation_wait > 0)
addtimer(CALLBACK(src, PROC_REF(process_burst), user, target, message, params, zone_override, random_spread, burst_spread_mult, iteration), dilation_wait)
return TRUE
// VOIDCREW EDIT ADDITION END
if(!issilicon(user))
if(iteration > 1 && !(user.is_holding(src))) //for burst firing
firing_burst = FALSE
Expand Down Expand Up @@ -517,6 +523,11 @@
if(user && HAS_TRAIT(user, TRAIT_DOUBLE_TAP))
modified_burst_delay = ROUND_UP(burst_delay * 0.5)
modified_fire_delay = ROUND_UP(fire_delay * 0.5)
// VOIDCREW EDIT ADDITION START - cyberware time dilation (voidcrew/modules/cyberware/ware_sandy_timestop.dm): a slowed shooter's gun cycles slowly too
cyberware_burst_start = cyberware_burst_clock(user)
cyberware_burst_gap = modified_burst_delay
modified_fire_delay = cyberware_dilated_time(user, modified_fire_delay)
// VOIDCREW EDIT ADDITION END

if(burst_size > 1)
firing_burst = TRUE
Expand Down
2 changes: 1 addition & 1 deletion code/modules/vehicles/mecha/_mecha.dm
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@

SEND_SIGNAL(user, COMSIG_MOB_USED_CLICK_MECH_MELEE, src)
if(target.mech_melee_attack(src, user))
TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown)
TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, cyberware_dilated_time(src, melee_cooldown)) // VOIDCREW EDIT CHANGE - cyberware time dilation (voidcrew/modules/cyberware/ware_sandy_timestop.dm). ORIGINAL: TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown)

/// Driver alt clicks anything while in mech
/obj/vehicle/sealed/mecha/proc/on_click_alt(mob/user, atom/target, params)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/vehicles/mecha/equipment/mecha_equipment.dm
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
return TRUE

/obj/item/mecha_parts/mecha_equipment/proc/action(mob/source, atom/target, list/modifiers)
TIMER_COOLDOWN_START(chassis, COOLDOWN_MECHA_EQUIPMENT(type), equip_cooldown)//Cooldown is on the MECH so people dont bypass it by switching equipment
TIMER_COOLDOWN_START(chassis, COOLDOWN_MECHA_EQUIPMENT(type), cyberware_dilated_time(chassis, equip_cooldown)) // VOIDCREW EDIT CHANGE - cyberware time dilation (voidcrew/modules/cyberware/ware_sandy_timestop.dm): a slowed mech's weapons cycle slowly. ORIGINAL: TIMER_COOLDOWN_START(chassis, COOLDOWN_MECHA_EQUIPMENT(type), equip_cooldown)//Cooldown is on the MECH so people dont bypass it by switching equipment
SEND_SIGNAL(source, COMSIG_MOB_USED_MECH_EQUIPMENT, chassis)
chassis.use_energy(energy_drain)
return TRUE
Expand Down
2 changes: 2 additions & 0 deletions tgstation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -7229,6 +7229,8 @@
#include "voidcrew\modules\cyberware\ware_pro_combat.dm"
#include "voidcrew\modules\cyberware\ware_pro_utility.dm"
#include "voidcrew\modules\cyberware\ware_registry.dm"
#include "voidcrew\modules\cyberware\ware_sandy_senses.dm"
#include "voidcrew\modules\cyberware\ware_sandy_timestop.dm"
#include "voidcrew\modules\cyberware\ware_second_wind.dm"
#include "voidcrew\modules\cyberware\ware_street.dm"
#include "voidcrew\modules\cyberware\ware_street_passives.dm"
Expand Down
16 changes: 8 additions & 8 deletions tools/gear_catalog/ratings/cyberware.json
Original file line number Diff line number Diff line change
Expand Up @@ -449,21 +449,21 @@
"/obj/item/organ/cyberimp/cyberware/dermal_mesh": {
"confidence": "high",
"group": "Armor and frame",
"hash": "5b60dbb7a15c8084",
"hash": "",
"name": "Dermal Mesh weave",
"note": "While online, adds physiology armor to a human wearer: melee 15, bullet 15, laser 10, wound 5. The armor is removed during an EMP reboot or an over-capacity brownout.",
"note": "While online, adds physiology armor to a human wearer: melee 15, bullet 15, laser 10, wound 5. Bullets and buckshot pellets from the front glance off at 15% (each pellet rolls on its own), keep flying at reduced damage and cost the wearer 5 stamina each. Never lasers, energy, melee or shots into the back. Shares the dodge arbiter: dodge plus glance never stop more than 60% of shots. The armor and the glance are off during an EMP reboot or an over-capacity brownout.",
"rank": 5,
"reason": "15 melee, 15 bullet, 10 laser on the whole body, on top of whatever you wear. A clear step up for load 2 and 2,000 cr. EMP switches it off for 9 s.",
"reason": "15 melee, 15 bullet, 10 laser on the whole body, on top of whatever you wear, and one bullet in seven from the front glances off. A clear step up for load 2 and 2,000 cr. EMP switches it off for 9 s.",
"tier": "yellow"
},
"/obj/item/organ/cyberimp/cyberware/dermal_mesh/hardweave": {
"confidence": "medium",
"group": "Armor and frame",
"hash": "",
"name": "Hardweave plating",
"note": "While online, adds physiology armor to a human wearer: melee 20, bullet 20, laser 15, energy 10, wound 10. The armor is removed during an EMP reboot or an over-capacity brownout.",
"note": "While online, adds physiology armor to a human wearer: melee 20, bullet 20, laser 15, energy 10, wound 10. Bullets and buckshot pellets from the front glance off at 30% (each pellet rolls on its own), keep flying at reduced damage and cost the wearer 5 stamina each. Never lasers, energy, melee or shots into the back. Shares the dodge arbiter: dodge plus glance never stop more than 60% of shots. The armor and the glance are off during an EMP reboot or an over-capacity brownout.",
"rank": 3,
"reason": "20 melee, 20 bullet, 15 laser, 10 energy and 10 wound armor on the whole body, on top of whatever you wear. A size up from the Mesh and well short of the Slabskin Plate, which adds bomb, fire and acid. Load 3, 3,000 cr at reputation 4. EMP switches it off for 9 s.",
"reason": "20 melee, 20 bullet, 15 laser, 10 energy and 10 wound armor on the whole body, on top of whatever you wear, and nearly a third of bullets from the front glance off. A size up from the Mesh and well short of the Slabskin Plate, which adds bomb, fire, acid and a bigger glance. Load 3, 3,000 cr at reputation 4. Strong for yellow against gunfire from the front, still useless against lasers and flanking. EMP switches it off for 9 s.",
"tier": "yellow"
},
"/obj/item/organ/cyberimp/cyberware/doppler": {
Expand Down Expand Up @@ -779,11 +779,11 @@
"/obj/item/organ/cyberimp/cyberware/slabskin": {
"confidence": "high",
"group": "Armor and frame",
"hash": "7b785a3adf8b7c37",
"hash": "",
"name": "Slabskin plate",
"note": "While online it adds built-in armor to the bearer (melee 25, bullet 25, laser 25, energy 20, bomb 25, fire 20, acid 20, wound 15), and any brute or burn hit of 5 or more throws sparks and often a ricochet sound so others can see the plate. The armor switches off while the ware is EMP'd or browned out.",
"note": "While online it adds built-in armor to the bearer (melee 25, bullet 25, laser 25, energy 20, bomb 25, fire 20, acid 20, wound 15), and any brute or burn hit of 5 or more throws sparks and often a ricochet sound so others can see the plate. Bullets and buckshot pellets from the front glance off at 45% (each pellet rolls on its own), keep flying at reduced damage and cost the wearer 5 stamina each. Never lasers, energy, melee or shots into the back. Shares the dodge arbiter: dodge plus glance never stop more than 60% of shots. The armor and the glance switch off while the ware is EMP'd or browned out.",
"rank": 1,
"reason": "25 armor against melee, bullets and lasers on the whole body, multiplied on top of whatever you wear, plus bomb, fire, acid and wounds. About a second armor vest that covers your head and limbs. Load 6, 3 vouchers at reputation 22. EMP switches it off for 9 s.",
"reason": "25 armor against melee, bullets and lasers on the whole body, multiplied on top of whatever you wear, plus bomb, fire, acid and wounds, and almost half of bullets from the front glance off. About a second armor vest that covers your head and limbs, and the best answer to a gunline in the game. Load 6, 3 vouchers at reputation 22. EMP switches it off for 9 s.",
"tier": "red"
},
"/obj/item/organ/cyberimp/cyberware/slipwire": {
Expand Down
8 changes: 8 additions & 0 deletions voidcrew/modules/bounties/chrome/bounty_chrome_cascade.dm
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@
return FALSE
return ..()

/datum/bounty_chrome_move/cascade/tell(atom/target)
cyberware_time_untint(owner) // its glow shows through a Sandevistan's slowed world (ware_sandy_timestop.dm)
return ..()

/datum/bounty_chrome_move/cascade/clear_tell()
. = ..()
cyberware_time_retint(owner)

/datum/bounty_chrome_move/cascade/tell_text(atom/target)
return "[owner]'s spine lights up with a rising whine."

Expand Down
24 changes: 21 additions & 3 deletions voidcrew/modules/cyberware/cyberware_anim.dm
Original file line number Diff line number Diff line change
Expand Up @@ -641,16 +641,20 @@
var/ring_alpha = 235
/// How long the ring takes to roll out and fade.
var/ring_time = 0.65 SECONDS
/// How far the ring rolls out when it stops time (ware_sandy_timestop.dm).
var/stop_ring_scale = 7.5

/obj/item/organ/cyberimp/cyberware/cascade/milspec
ring_scale = 2.7
ring_alpha = 190
ring_time = 0.55 SECONDS
stop_ring_scale = 6.5

/obj/item/organ/cyberimp/cyberware/cascade/street
ring_scale = 2.2
ring_alpha = 140
ring_time = 0.45 SECONDS
stop_ring_scale = 5.5

/obj/item/organ/cyberimp/cyberware/cascade/cyberware_worn_key()
return "[..()]-[node_look]"
Expand Down Expand Up @@ -735,8 +739,20 @@
/obj/item/organ/cyberimp/cyberware/cascade/proc/roll_ring()
ring_timer = null
var/turf/here = get_turf(owner)
if(here)
new /obj/effect/temp_visual/cyberware_time_ring(here, ring_scale, ring_alpha, ring_time)
if(!here)
return
new /obj/effect/temp_visual/cyberware_time_ring(here, ring_scale, ring_alpha, ring_time)

/// The world slows as the window opens: the green ring rolls out past the edge of the screen at once, with the
/// tint behind its front, instead of waiting for the last spine node.
/obj/item/organ/cyberimp/cyberware/cascade/proc/roll_stop_ring()
if(ring_timer)
deltimer(ring_timer)
ring_timer = null
var/turf/here = get_turf(owner)
if(!here)
return
new /obj/effect/temp_visual/cyberware_time_ring(here, stop_ring_scale, ring_alpha, ring_time, TRUE)

/// The crash: nodes die hips to neck and stay dark.
/obj/item/organ/cyberimp/cyberware/cascade/proc/play_crash()
Expand Down Expand Up @@ -784,9 +800,11 @@
randomdir = FALSE
duration = 0.65 SECONDS

/obj/effect/temp_visual/cyberware_time_ring/Initialize(mapload, max_scale = 3.3, peak_alpha = 235, ring_time = 0.65 SECONDS)
/obj/effect/temp_visual/cyberware_time_ring/Initialize(mapload, max_scale = 3.3, peak_alpha = 235, ring_time = 0.65 SECONDS, green = FALSE)
duration = ring_time
. = ..()
if(green)
color = cyberware_time_stop_green()
add_overlay(emissive_appearance(icon, icon_state, src))
transform = matrix().Scale(0.2)
alpha = peak_alpha
Expand Down
Binary file not shown.
32 changes: 32 additions & 0 deletions voidcrew/modules/cyberware/ware_legend.dm
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@
var/window_alert = /atom/movable/screen/alert/status_effect/cyberware_cascade
/// What the bearer reads on activation.
var/online_message = "CASCADE ONLINE."
/// How fast the world runs through the window when no other player is near (ware_sandy_timestop.dm).
var/dilation_scale = 0.2
/// How much faster than normal the bearer runs in the window. A surging mob in someone else's field runs at its
/// multiplier over theirs.
var/time_multiplier = 5

/obj/item/organ/cyberimp/cyberware/cascade/on_mob_remove(mob/living/carbon/organ_owner, special = FALSE, movement_flags)
. = ..()
Expand Down Expand Up @@ -125,10 +130,29 @@
cooldown_time = 60 SECONDS
click_to_activate = FALSE

/// Whether a press now would end a running window: a player's own press only. An NPC's AI never turns its surge off.
/datum/action/cooldown/cyberware/cascade_surge/proc/can_cut_short()
if(!isliving(owner))
return FALSE
var/mob/living/surger = owner
return !!surger.ckey && !!surger.has_status_effect(/datum/status_effect/cyberware_cascade_window)

/// The cooldown starts as the window opens, so pressing again to end the window early looks past it.
/datum/action/cooldown/cyberware/cascade_surge/IsAvailable(feedback = FALSE)
if(!can_cut_short())
return ..()
var/cooldown_end = next_use_time
next_use_time = 0
. = ..()
next_use_time = cooldown_end

/datum/action/cooldown/cyberware/cascade_surge/Activate(atom/target)
if(!isliving(owner))
return FALSE
var/mob/living/surger = owner
if(can_cut_short()) // the second press: back to real time, and the crash
surger.remove_status_effect(/datum/status_effect/cyberware_cascade_window)
return TRUE
if(surger.has_status_effect(/datum/status_effect/cyberware_cascade_window) || surger.has_status_effect(/datum/status_effect/cyberware_cascade_crash))
surger.balloon_alert(surger, "lattice still cycling!")
return FALSE
Expand Down Expand Up @@ -188,6 +212,8 @@
online_message = lattice.online_message
crash_duration = lattice.crash_duration
crash_stamina = lattice.crash_stamina
dilation_scale = lattice.dilation_scale
time_multiplier = lattice.time_multiplier
return ..()

/datum/status_effect/cyberware_cascade_window/on_apply()
Expand All @@ -205,9 +231,11 @@
)
owner.balloon_alert(owner, "cascade online")
cyberware_cascade_window_fx(owner)
try_time_stop() // ware_sandy_timestop.dm
return TRUE

/datum/status_effect/cyberware_cascade_window/on_remove()
end_time_stop()
owner.remove_movespeed_modifier(speed_type)
owner.remove_movespeed_mod_immunities(id, /datum/movespeed_modifier/reagent)
cyberware_unregister_dodge_source(owner, id)
Expand Down Expand Up @@ -240,6 +268,10 @@
steps_taken++
if(steps_taken % afterimage_interval) // cheaper chrome leaves a sparser trail
return
if(time_stop) // green while the world is slowed
stopped_afterimage(old_loc)
return
trail_hue = cyberware_time_trail_hue(owner, trail_hue) // ware_sandy_timestop.dm
new /obj/effect/temp_visual/decoy/fading/cascade(old_loc, owner, trail_hue, afterimage_alpha)
trail_hue = (trail_hue + CYBERWARE_CASCADE_HUE_STEP) % 360

Expand Down
4 changes: 4 additions & 0 deletions voidcrew/modules/cyberware/ware_line_sandy.dm
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
afterimage_alpha = 120
window_alert = /atom/movable/screen/alert/status_effect/cyberware_cascade/aftermarket
online_message = "REFLEX RIG ONLINE."
dilation_scale = 0.5
time_multiplier = 2

/datum/action/cooldown/cyberware/cascade_surge/street
name = "Reflex Surge"
Expand Down Expand Up @@ -89,6 +91,8 @@
afterimage_alpha = 160
window_alert = /atom/movable/screen/alert/status_effect/cyberware_cascade/aftermarket
online_message = "LATTICE ONLINE."
dilation_scale = 0.35
time_multiplier = 1 / 0.35

/datum/action/cooldown/cyberware/cascade_surge/milspec
name = "Reflex Surge"
Expand Down
12 changes: 11 additions & 1 deletion voidcrew/modules/cyberware/ware_military_body.dm
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@
*/
/obj/item/organ/cyberimp/cyberware/slabskin
name = "\improper Slabskin plate"
desc = "A keel and rib plates of sintered ceramic, grown into the skin of the chest and back. Bullets leave scuffs and a noise like a dropped pan."
desc = "A keel and rib plates of sintered ceramic, grown into the skin of the chest and back. Bullets leave scuffs, when they don't bounce off with a noise like a dropped pan."
icon_state = "slabskin"
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_CYBERWARE_DERMAL
Expand All @@ -276,13 +276,16 @@
/// TRUE while the plate armor is mixed into the bearer's physiology.
/// Guards the failing-gated passive hooks against double add/subtract.
var/plate_armor_applied = FALSE
/// Percent of bullets from the front that glance off, through the shared dodge arbiter. The top of the dermal ladder.
var/deflect_chance = 45

/obj/item/organ/cyberimp/cyberware/slabskin/on_mob_insert(mob/living/carbon/organ_owner, special = FALSE, movement_flags)
. = ..()
RegisterSignal(organ_owner, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_damaged))

/obj/item/organ/cyberimp/cyberware/slabskin/chrome_passives_on(mob/living/carbon/bearer)
. = ..()
cyberware_register_deflect_source(bearer, REF(src), CALLBACK(src, PROC_REF(get_deflect_chance)))
if(plate_armor_applied || !ishuman(bearer))
return
plate_armor_applied = TRUE
Expand All @@ -291,6 +294,7 @@

/obj/item/organ/cyberimp/cyberware/slabskin/chrome_passives_off(mob/living/carbon/bearer)
. = ..()
cyberware_unregister_deflect_source(bearer, REF(src))
if(!plate_armor_applied)
return
plate_armor_applied = FALSE // reset before the validity skip, or the plate never re-arms after a bearer deletes
Expand All @@ -303,6 +307,12 @@
. = ..()
UnregisterSignal(organ_owner, COMSIG_MOB_APPLY_DAMAGE)

/// Deflect-source callback: nothing while failing.
/obj/item/organ/cyberimp/cyberware/slabskin/proc/get_deflect_chance()
if(organ_flags & ORGAN_FAILING)
return 0
return deflect_chance

/**
* Signal proc for [COMSIG_MOB_APPLY_DAMAGE]: the telegraph. Solid brute or
* burn hits spark and ping off the plate where everyone can see them.
Expand Down
Loading