[MIRROR] Turf slip component [NEEDS TESTING] (#11730)

Co-authored-by: Will <7099514+Willburd@users.noreply.github.com>
Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-09-24 06:25:51 -07:00
committed by GitHub
parent 4cbd46aef9
commit c9191132df
5 changed files with 109 additions and 57 deletions

View File

@@ -39,5 +39,11 @@
locate(min(CENTER.x+(H_RADIUS),world.maxx), min(CENTER.y+(V_RADIUS),world.maxy), CENTER.z) \
)
// Wet turfs have different slipping intensities
#define TURFSLIP_DRY 0
#define TURFSLIP_WET 1
#define TURFSLIP_LUBE 2
#define TURFSLIP_ICE 3
///Returns all turfs in a zlevel
#define Z_TURFS(ZLEVEL) block(1, 1, ZLEVEL, world.maxx, world.maxy, ZLEVEL)

View File

@@ -0,0 +1,91 @@
/datum/component/turfslip
var/mob/living/owner
var/slip_dist = TURFSLIP_WET
var/dirtslip = FALSE
/datum/component/turfslip/Initialize()
if (!isliving(parent))
return COMPONENT_INCOMPATIBLE
owner = parent
RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(move_react))
/datum/component/turfslip/proc/start_slip(var/turf/simulated/start, var/is_dirt)
var/slip_stun = 6
var/floor_type = "wet"
var/already_slipping = (slip_dist > 1)
// Handle dirt slipping
dirtslip = is_dirt
if(dirtslip)
slip_stun = 10
if(start.dirt > 50)
floor_type = "dirty"
else if(start.is_outdoors())
floor_type = "uneven"
// Proper sliding behavior
switch(start.wet)
if(TURFSLIP_LUBE)
floor_type = "slippery"
slip_dist = 99 //Skill issue.
slip_stun = 10
dirtslip = FALSE
if(TURFSLIP_ICE)
floor_type = "icy"
slip_stun = 4
slip_dist = rand(1,3)
dirtslip = FALSE
// Only start the slip timer if we are not already sliding
if(!already_slipping)
owner.slip("the [floor_type] floor", slip_stun)
addtimer(CALLBACK(src, PROC_REF(next_slip)), 1)
/datum/component/turfslip/proc/move_react(atom/source, atom/oldloc, direction, forced, list/old_locs, momentum_change)
SIGNAL_HANDLER
// Can the mob slip?
if(QDELETED(owner) || isbelly(owner.loc))
qdel(src)
return
// Can the turf be slipped on?
var/turf/simulated/ground = get_turf(owner)
if(!ground || !ground.check_slipping(owner,dirtslip))
qdel(src)
return
addtimer(CALLBACK(src, PROC_REF(next_slip)), 1)
/datum/component/turfslip/proc/next_slip()
// check tile for next slip
if(!step(owner, owner.dir) || dirtslip) // done sliding, failed to move, dirt also only slips once
qdel(src)
return
// Kill the slip if it's over
if(!--slip_dist)
qdel(src)
return
/datum/component/turfslip/Destroy(force = FALSE)
UnregisterSignal(owner, COMSIG_MOVABLE_MOVED)
owner.inertia_dir = 0
owner = null
slip_dist = 0
. = ..()
////////////////////////////////////////////////////////////////////////////////////////
// Helper proc
////////////////////////////////////////////////////////////////////////////////////////
/turf/proc/check_slipping(var/mob/living/M)
return FALSE
/turf/simulated/check_slipping(var/mob/living/M,var/dirtslip)
if(M.buckled)
return FALSE
if(!wet && !(dirtslip && (dirt > 50 || is_outdoors() == OUTDOORS_YES)))
return FALSE
if(wet == TURFSLIP_WET && M.m_intent == I_WALK)
return FALSE
return TRUE

View File

@@ -1,6 +1,6 @@
/turf/simulated
name = "station"
var/wet = 0
var/wet = TURFSLIP_DRY
var/image/wet_overlay = null
//Mining resources (for the large drills).
@@ -24,7 +24,7 @@
// This is not great.
/turf/simulated/proc/wet_floor(var/wet_val = 1)
if(wet > 2) //Can't mop up ice
if(wet >= TURFSLIP_ICE) //Can't mop up ice
return
wet = wet_val
if(wet_overlay)
@@ -34,13 +34,13 @@
if(wet_cleanup_timer)
deltimer(wet_cleanup_timer)
wet_cleanup_timer = null
if(wet == 2)
if(wet == TURFSLIP_LUBE)
wet_cleanup_timer = addtimer(CALLBACK(src, PROC_REF(wet_floor_finish)), 160 SECONDS, TIMER_STOPPABLE)
else
wet_cleanup_timer = addtimer(CALLBACK(src, PROC_REF(wet_floor_finish)), 40 SECONDS, TIMER_STOPPABLE)
/turf/simulated/proc/wet_floor_finish()
wet = 0
wet = TURFSLIP_DRY
if(wet_cleanup_timer)
deltimer(wet_cleanup_timer)
wet_cleanup_timer = null
@@ -51,14 +51,14 @@
/turf/simulated/proc/freeze_floor()
if(!wet) // Water is required for it to freeze.
return
wet = 3 // icy
wet = TURFSLIP_ICE
if(wet_overlay)
cut_overlay(wet_overlay)
wet_overlay = null
wet_overlay = image('icons/turf/overlays.dmi',src,"snowfloor")
add_overlay(wet_overlay)
spawn(5 MINUTES)
wet = 0
wet = TURFSLIP_DRY
if(wet_overlay)
cut_overlay(wet_overlay)
wet_overlay = null
@@ -95,8 +95,8 @@
dirtoverlay.alpha = min((dirt - 50) * 5, 255)
/turf/simulated/Entered(atom/A, atom/OL)
if (isliving(A))
var/dirtslip = FALSE
if (isliving(A))
var/mob/living/M = A
if(M.lying || M.flying || M.is_incorporeal() || !(M.flags & ATOM_INITIALIZED)) // Also ignore newly spawning mobs
return ..()
@@ -136,57 +136,11 @@
bloodDNA = null
var/turf_is_outdoors = is_outdoors()
if(src.wet || (dirtslip && (dirt > 50 || turf_is_outdoors == OUTDOORS_YES)))
if(M.buckled || (src.wet == 1 && M.m_intent == I_WALK))
return
var/slip_dist = 1
var/slip_stun = 6
var/floor_type = "wet"
if(dirtslip)
slip_stun = 10
if(dirt > 50)
floor_type = "dirty"
else if(turf_is_outdoors)
floor_type = "uneven"
if(src.wet == 0 && M.m_intent == I_WALK)
return
switch(src.wet)
if(2) // Lube
floor_type = "slippery"
slip_dist = 4
slip_stun = 10
if(3) // Ice
floor_type = "icy"
slip_stun = 4
slip_dist = rand(1,3)
if(M.slip("the [floor_type] floor", slip_stun))
addtimer(CALLBACK(src, PROC_REF(handle_slipping), M, slip_dist, dirtslip), 0)
else
M.inertia_dir = 0
else
M.inertia_dir = 0
if(check_slipping(M,dirtslip))
var/datum/component/turfslip/TSC = M.LoadComponent(/datum/component/turfslip)
TSC.start_slip(src,dirtslip)
..()
/turf/simulated/proc/handle_slipping(var/mob/living/M, var/slip_dist, var/dirtslip)
PRIVATE_PROC(TRUE)
if(!M || !slip_dist)
return
if(isbelly(M.loc)) // Stop the slip if we're in a belly.
return
if(!step(M, M.dir) && !dirtslip)
return // done sliding, failed to move
// check tile for next slip
if(!dirtslip)
var/turf/simulated/ground = get_turf(M)
if(!istype(ground,/turf/simulated))
return // stop sliding as it is impossible to be on wet terrain?
if(ground.wet != 2)
return // done sliding, not lubed
addtimer(CALLBACK(src, PROC_REF(handle_slipping), M, --slip_dist, dirtslip), 1)
//returns 1 if made bloody, returns 0 otherwise
/turf/simulated/add_blood(mob/living/carbon/human/M as mob)
if (!..())

View File

@@ -1524,7 +1524,7 @@
for(var/turf/simulated/T in trange(5, get_turf(holder.my_atom)))
if(!istype(T))
continue
T.wet = 1
T.wet = TURFSLIP_WET
T.freeze_floor()
..()

View File

@@ -602,6 +602,7 @@
#include "code\datums\components\recursive_move.dm"
#include "code\datums\components\resize_guard.dm"
#include "code\datums\components\swarm.dm"
#include "code\datums\components\turfslip.dm"
#include "code\datums\components\tethered_item.dm"
#include "code\datums\components\animations\dizzy.dm"
#include "code\datums\components\animations\jittery.dm"