mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-15 20:22:07 +00:00
* Adds support to the wet_floor component to avoid displaying its overlay, makes ice turfs no longer receive said wet overlay (#79275) ## About The Pull Request The title says it all, really. I always thought ice looked a bit silly, and always wondered why. Today, I found out it was because of the `wet_floor` component adding an overlay that suddenly made a turf that should look continuous, tiled, which in turn gave some very ugly visuals. Ice already looks slippery, you can tell that it's ice, and the overlay that was added to it just didn't really help telegraph that any better than the sprite itself already does. That's why I added support to make it so it would be possible to force the overlay to just not be applied to the turf that's affected by the component, to make it all look a bit better overall. I added it to the ice turfs as a proof of concept, although I guess it could also be used on other turfs that are always "wet", like the bananium floors, but I didn't really care enough to touch that yet, and I guess the bananium floors can use it a bit better than ice did. I did notice in this PR that the smoothing of ice seemed to potentially be broken, but that's something to look into at a later time. ## Why It's Good For The Game Look at this ice and how much smoother it looks like now:  ## Changelog 🆑 GoldenAlpharex code: Added support to the wet_floor component to make it so the wet overlay could not be applied to certain turfs if desired. fix: Ice turfs no longer look tiled, and instead look smooth when placed next to one-another. /🆑 * Adds support to the wet_floor component to avoid displaying its overlay, makes ice turfs no longer receive said wet overlay --------- Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
227 lines
8.0 KiB
Plaintext
227 lines
8.0 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
|
|
/// Should we display an overlay for this component? Useful mainly for turfs
|
|
/// that already look wets or just don't need the visuals for any other reason.
|
|
var/should_display_overlay = TRUE
|
|
|
|
/datum/component/wet_floor/InheritComponent(datum/newcomp, orig, strength, duration_minimum, duration_add, duration_maximum, _permanent, _should_display_overlay)
|
|
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, _should_display_overlay = TRUE)
|
|
if(!isopenturf(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
should_display_overlay = _should_display_overlay
|
|
add_wet(strength, duration_minimum, duration_add, duration_maximum, _permanent, _should_display_overlay)
|
|
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()
|
|
if(!should_display_overlay)
|
|
if(!current_overlay)
|
|
return
|
|
|
|
var/turf/parent_turf = parent
|
|
parent_turf.cut_overlay(current_overlay)
|
|
current_overlay = null
|
|
return
|
|
|
|
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/parent_turf = parent
|
|
parent_turf.cut_overlay(current_overlay)
|
|
parent_turf.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, _should_display_overlay = TRUE)
|
|
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)
|
|
|
|
should_display_overlay = _should_display_overlay
|
|
|
|
/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()
|