mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-31 20:11:56 +00:00
## About The Pull Request This adds a new element for movables that grants turfs they're in traits, changes lava and the chasm component to check for traits instead, ditto for turf slowdown. It also implements another trait that prevents wet floor from slipping people, as well as some other changes (feel free to opine on them really): - Tables and conveyor belts now stop turf slowdown, much like catwalks, as I imagine people walking on them are not really touching the floor. (I'd include protection against lava too... until they melt, but that'd mean finding a way to have these objects burn in the first place, and lava code is still stupid despite a years old refactor I did) - Tables also stop slippery turfs from slipping (bananas, soaps etc. still apply). I wish there were a way to make some objects slippery by coating them in water vapor or splashing water/lube, but that's outside the scope of this PR. - Fixed an edge case in which a mob standing on a lava turf would be left permanently visually on fire if the lava is changed to another kind of turf. - Removed unused code from stone tiles. I'm going to include these traits in that global list for admin-added traits... tomorrow perhaps. 💤 ## Why It's Good For The Game Replacing some hard-coded mechanics with easier to use traits and an element, which I also need for the submerge element PR. ## Changelog 🆑 refactor: Replaced hardcoded "safeties" for lava, chasms and ignoring turf slowdowns on catwalks with traits. balance: much like catwalks, tables and conveyors also disable turf slowdowns. balance: slippery turfs won't slip you when walking on a table. fix: Fixed an edge case in which a mob standing on a lava turf would be left visually but permanently on fire if the lava is changed to another kind of turf. /🆑
212 lines
7.4 KiB
Plaintext
212 lines
7.4 KiB
Plaintext
/datum/component/wet_floor
|
|
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
|
can_transfer = TRUE
|
|
var/highest_strength = TURF_DRY
|
|
var/lube_flags = NONE //why do we have this?
|
|
var/list/time_left_list //In deciseconds.
|
|
var/static/mutable_appearance/permafrost_overlay = mutable_appearance('icons/effects/water.dmi', "ice_floor")
|
|
var/static/mutable_appearance/ice_overlay = mutable_appearance('icons/turf/overlays.dmi', "snowfloor")
|
|
var/static/mutable_appearance/water_overlay = mutable_appearance('icons/effects/water.dmi', "wet_floor_static")
|
|
var/static/mutable_appearance/generic_turf_overlay = mutable_appearance('icons/effects/water.dmi', "wet_static")
|
|
var/current_overlay
|
|
var/permanent = FALSE
|
|
var/last_process = 0
|
|
|
|
/datum/component/wet_floor/InheritComponent(datum/newcomp, orig, strength, duration_minimum, duration_add, duration_maximum, _permanent)
|
|
if(!newcomp) //We are getting passed the arguments of a would-be new component, but not a new component
|
|
add_wet(arglist(args.Copy(3)))
|
|
else //We are being passed in a full blown component
|
|
var/datum/component/wet_floor/WF = newcomp //Lets make an assumption
|
|
if(WF.gc()) //See if it's even valid, still. Also does LAZYLEN and stuff for us.
|
|
CRASH("Wet floor component tried to inherit another, but the other was able to garbage collect while being inherited! What a waste of time!")
|
|
for(var/i in WF.time_left_list)
|
|
add_wet(text2num(i), WF.time_left_list[i])
|
|
|
|
/datum/component/wet_floor/Initialize(strength, duration_minimum, duration_add, duration_maximum, _permanent = FALSE)
|
|
if(!isopenturf(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
add_wet(strength, duration_minimum, duration_add, duration_maximum)
|
|
permanent = _permanent
|
|
if(!permanent)
|
|
START_PROCESSING(SSwet_floors, src)
|
|
addtimer(CALLBACK(src, PROC_REF(gc), TRUE), 1) //GC after initialization.
|
|
last_process = world.time
|
|
|
|
/datum/component/wet_floor/RegisterWithParent()
|
|
RegisterSignal(parent, COMSIG_TURF_IS_WET, PROC_REF(is_wet))
|
|
RegisterSignal(parent, COMSIG_TURF_MAKE_DRY, PROC_REF(dry))
|
|
|
|
/datum/component/wet_floor/UnregisterFromParent()
|
|
UnregisterSignal(parent, list(COMSIG_TURF_IS_WET, COMSIG_TURF_MAKE_DRY))
|
|
|
|
/datum/component/wet_floor/Destroy()
|
|
STOP_PROCESSING(SSwet_floors, src)
|
|
var/turf/T = parent
|
|
qdel(T.GetComponent(/datum/component/slippery))
|
|
if(istype(T)) //If this is false there is so many things wrong with it.
|
|
T.cut_overlay(current_overlay)
|
|
else
|
|
stack_trace("Warning: Wet floor component wasn't on a turf when being destroyed! This is really bad!")
|
|
return ..()
|
|
|
|
/datum/component/wet_floor/proc/update_overlay()
|
|
var/intended
|
|
if(!isfloorturf(parent))
|
|
intended = generic_turf_overlay
|
|
else
|
|
switch(highest_strength)
|
|
if(TURF_WET_PERMAFROST)
|
|
intended = permafrost_overlay
|
|
if(TURF_WET_ICE)
|
|
intended = ice_overlay
|
|
else
|
|
intended = water_overlay
|
|
if(current_overlay != intended)
|
|
var/turf/T = parent
|
|
T.cut_overlay(current_overlay)
|
|
T.add_overlay(intended)
|
|
current_overlay = intended
|
|
|
|
/datum/component/wet_floor/proc/AfterSlip(mob/living/slipped)
|
|
if(highest_strength != TURF_WET_LUBE)
|
|
return
|
|
|
|
slipped.set_confusion_if_lower(8 SECONDS)
|
|
|
|
/datum/component/wet_floor/proc/update_flags()
|
|
var/intensity
|
|
lube_flags = SLIPPERY_TURF
|
|
switch(highest_strength)
|
|
if(TURF_WET_WATER)
|
|
intensity = 60
|
|
lube_flags |= NO_SLIP_WHEN_WALKING
|
|
if(TURF_WET_LUBE)
|
|
intensity = 80
|
|
lube_flags |= SLIDE | GALOSHES_DONT_HELP
|
|
if(TURF_WET_ICE)
|
|
intensity = 120
|
|
lube_flags |= SLIDE | GALOSHES_DONT_HELP
|
|
if(TURF_WET_PERMAFROST)
|
|
intensity = 120
|
|
lube_flags |= SLIDE_ICE | GALOSHES_DONT_HELP
|
|
if(TURF_WET_SUPERLUBE)
|
|
intensity = 120
|
|
lube_flags |= SLIDE | GALOSHES_DONT_HELP | SLIP_WHEN_CRAWLING
|
|
else
|
|
qdel(parent.GetComponent(/datum/component/slippery))
|
|
return
|
|
|
|
parent.LoadComponent(/datum/component/slippery, intensity, lube_flags, CALLBACK(src, PROC_REF(AfterSlip)))
|
|
|
|
/datum/component/wet_floor/proc/dry(datum/source, strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY)
|
|
SIGNAL_HANDLER
|
|
|
|
for(var/i in time_left_list)
|
|
if(text2num(i) <= strength)
|
|
time_left_list[i] = max(0, time_left_list[i] - duration_decrease)
|
|
if(immediate)
|
|
check()
|
|
|
|
/datum/component/wet_floor/proc/max_time_left()
|
|
. = 0
|
|
for(var/i in time_left_list)
|
|
. = max(., time_left_list[i])
|
|
|
|
/datum/component/wet_floor/process()
|
|
var/turf/open/T = parent
|
|
var/diff = world.time - last_process
|
|
var/decrease = 0
|
|
var/t = T.GetTemperature()
|
|
switch(t)
|
|
if(-INFINITY to T0C)
|
|
add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice!
|
|
if(T0C to T0C + 100)
|
|
decrease = ((T.air.temperature - T0C) / SSwet_floors.temperature_coeff) * (diff / SSwet_floors.time_ratio)
|
|
if(T0C + 100 to INFINITY)
|
|
decrease = INFINITY
|
|
decrease = max(0, decrease)
|
|
if((is_wet() & TURF_WET_ICE) && t > T0C) //Ice melts into water!
|
|
for(var/obj/O in T.contents)
|
|
O.unfreeze()
|
|
add_wet(TURF_WET_WATER, max_time_left())
|
|
dry(null, TURF_WET_ICE)
|
|
dry(null, ALL, FALSE, decrease)
|
|
check()
|
|
last_process = world.time
|
|
|
|
/datum/component/wet_floor/proc/update_strength()
|
|
highest_strength = 0 //Not bitflag.
|
|
for(var/i in time_left_list)
|
|
highest_strength = max(highest_strength, text2num(i))
|
|
|
|
/datum/component/wet_floor/proc/is_wet()
|
|
SIGNAL_HANDLER
|
|
|
|
. = 0
|
|
for(var/i in time_left_list)
|
|
. |= text2num(i)
|
|
|
|
/datum/component/wet_floor/PreTransfer()
|
|
var/turf/O = parent
|
|
O.cut_overlay(current_overlay)
|
|
//That turf is no longer slippery, we're out of here
|
|
//Slippery components don't transfer due to callbacks
|
|
qdel(O.GetComponent(/datum/component/slippery))
|
|
|
|
/datum/component/wet_floor/PostTransfer()
|
|
if(!isopenturf(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
var/turf/T = parent
|
|
T.add_overlay(current_overlay)
|
|
//Make sure to add/update any slippery component on the new turf (update_flags calls LoadComponent)
|
|
update_flags()
|
|
|
|
//NB it's possible we get deleted after this, due to inherit
|
|
|
|
/datum/component/wet_floor/proc/add_wet(type, duration_minimum = 0, duration_add = 0, duration_maximum = MAXIMUM_WET_TIME, _permanent = FALSE)
|
|
var/static/list/allowed_types = list(TURF_WET_WATER, TURF_WET_LUBE, TURF_WET_ICE, TURF_WET_PERMAFROST, TURF_WET_SUPERLUBE)
|
|
if(duration_minimum <= 0 || !type)
|
|
return FALSE
|
|
if(type in allowed_types)
|
|
return _do_add_wet(type, duration_minimum, duration_add, duration_maximum)
|
|
else
|
|
. = NONE
|
|
for(var/i in allowed_types)
|
|
if(!(type & i))
|
|
continue
|
|
. |= _do_add_wet(i, duration_minimum, duration_add, duration_maximum)
|
|
if(_permanent)
|
|
permanent = TRUE
|
|
STOP_PROCESSING(SSwet_floors, src)
|
|
|
|
/datum/component/wet_floor/proc/_do_add_wet(type, duration_minimum, duration_add, duration_maximum)
|
|
var/time = 0
|
|
if(LAZYACCESS(time_left_list, "[type]"))
|
|
time = clamp(LAZYACCESS(time_left_list, "[type]") + duration_add, duration_minimum, duration_maximum)
|
|
else
|
|
time = min(duration_minimum, duration_maximum)
|
|
LAZYSET(time_left_list, "[type]", time)
|
|
check(TRUE)
|
|
return TRUE
|
|
|
|
/datum/component/wet_floor/proc/gc(on_init = FALSE)
|
|
if(!LAZYLEN(time_left_list))
|
|
if(on_init)
|
|
var/turf/T = parent
|
|
stack_trace("Warning: Wet floor component gc'd right after initialization! What a waste of time and CPU! Type = [T? T.type : "ERROR - NO PARENT"], Location = [istype(T)? AREACOORD(T) : "ERROR - INVALID PARENT"].")
|
|
qdel(src)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/datum/component/wet_floor/proc/check(force_update = FALSE)
|
|
var/changed = FALSE
|
|
for(var/i in time_left_list)
|
|
if(time_left_list[i] <= 0)
|
|
time_left_list -= i
|
|
changed = TRUE
|
|
if(changed || force_update)
|
|
update_strength()
|
|
update_overlay()
|
|
update_flags()
|
|
gc()
|