Files
2020-02-16 19:40:21 -08:00

263 lines
8.7 KiB
Plaintext

///////////////////
//Turf Procs/Vars//
///////////////////
/turf/var/obj/fluid/active_liquid
//this is messy!
//this is for turf/space/fluid oceans. Using this in place of turf/canpass() because this one can account for shitt like windows and tables.
/turf/proc/ocean_canpass()
if( density )
return 0
for( var/A in contents )
var/atom/thing = A
if (!A) continue
if(IS_SOLID_TO_FLUID(thing) && thing.density) return 0 // && !istype(thing,/obj/grille) && !istype(thing,/obj/table) && !istype(thing,/obj/structure/girder)) return 0
LAGCHECK(LAG_LOW)
return 1
turf/simulated/floor/plating/airless/ocean_canpass()
.= 0
/turf/selftilenotify()
if (src.active_liquid && src.active_liquid.group && !canpass())
src.active_liquid.group.displace(src.active_liquid)
else
///HEY HEY LOOK AT ME TODO : This is kind of a band-aid. I'm not sure why, but tilenotify() doesn't trigger when it should sometimes. do this to be absolutely sure!
for (var/dir in cardinal)
var/turf/T = get_step(src, dir)
if(T.active_liquid)
T.active_liquid.blocked_dirs = 0
if (T.active_liquid.group && !T.active_liquid.group.updating)
T.active_liquid.group.update_loop()
break
if(T.active_airborne_liquid)
T.active_airborne_liquid.blocked_dirs = 0
if (T.active_airborne_liquid.group && !T.active_airborne_liquid.group.updating)
T.active_airborne_liquid.group.update_loop()
break
return ..()
/turf/tilenotify()
if(src.active_liquid)
src.active_liquid.blocked_dirs = 0
if (src.active_liquid.group && !src.active_liquid.group.updating)
src.active_liquid.group.update_loop()
if(src.active_airborne_liquid)
src.active_airborne_liquid.blocked_dirs = 0
if (src.active_airborne_liquid.group && !src.active_airborne_liquid.group.updating)
src.active_airborne_liquid.group.update_loop()
return ..()
/turf/proc/fluid_react(var/datum/reagents/R, var/react_volume, var/airborne = 0) //this should happen whenever a liquid reagent hits a simulated tile
LAGCHECK(LAG_MED)
if (react_volume <= 0) return
if (!IS_VALID_FLUIDREACT_TURF(src)) return
if (airborne)
for(var/reagent_id in R.reagent_list)
if (ban_from_airborne_fluid.Find(reagent_id)) return
LAGCHECK(LAG_MED)
else
for(var/reagent_id in R.reagent_list)
if (ban_from_fluid.Find(reagent_id)) return
LAGCHECK(LAG_MED)
var/datum/fluid_group/FG
var/obj/fluid/F
var/fluid_and_group_already_exist = 0
if (airborne)
if (!src.active_airborne_liquid)
FG = new /datum/fluid_group/airborne
F = unpool(/obj/fluid/airborne)
src.active_airborne_liquid = F
F.set_up(src)
if (react_volume == 0)
react_volume = 1
else
F = src.active_airborne_liquid
if (F.group)
FG = F.group
fluid_and_group_already_exist = 1
else
FG = new /datum/fluid_group/airborne
if (react_volume == 0)
react_volume = 1
else
if (!src.active_liquid)
FG = new
F = unpool(/obj/fluid)
src.active_liquid = F
F.set_up(src)
if (react_volume == 0)
react_volume = 1
else
F = src.active_liquid
if (F.group)
FG = F.group
fluid_and_group_already_exist = 1
else
FG = new
if (react_volume == 0)
react_volume = 1
R.trans_to_direct(FG.reagents,react_volume)
FG.add(F, react_volume, guarantee_is_member = fluid_and_group_already_exist)
if (!airborne)
var/turf/simulated/floor/T = src
if (T.messy <= 0) return
if (istype(T))
var/found_cleanable = 0
for (var/obj/decal/cleanable/C in T)
if (!T.cleanable_fluid_react(C, 1)) // Some cleanables need special treatment
found_cleanable = 1 //there exists a cleanable without a special case
LAGCHECK(LAG_LOW)
if (found_cleanable)
T.cleanable_fluid_react(0,1)
/turf/proc/fluid_react_single(var/reagent_name, var/react_volume, var/airborne = 0) //same as the above, but using a reagent_id instead of a datum
LAGCHECK(LAG_MED)
if (react_volume <= 0) return
if (!IS_VALID_FLUIDREACT_TURF(src)) return
if (airborne)
if (ban_from_airborne_fluid.Find(reagent_name)) return
else
if (ban_from_fluid.Find(reagent_name)) return
LAGCHECK(LAG_LOW)
var/datum/fluid_group/FG
var/obj/fluid/F
var/fluid_and_group_already_exist = 0
if (airborne)
if (!src.active_airborne_liquid)
FG = new /datum/fluid_group/airborne
F = unpool(/obj/fluid/airborne)
src.active_airborne_liquid = F
F.set_up(src)
if (react_volume == 0)
react_volume = 1
else
F = src.active_airborne_liquid
if (F.group)
FG = F.group
fluid_and_group_already_exist = 1
else
FG = new /datum/fluid_group/airborne
if (react_volume == 0)
react_volume = 1
else
if (!src.active_liquid)
FG = new
F = unpool(/obj/fluid)
src.active_liquid = F
F.set_up(src)
if (react_volume == 0)
react_volume = 1
else
F = src.active_liquid
if (F.group)
FG = F.group
fluid_and_group_already_exist = 1
else
FG = new
if (react_volume == 0)
react_volume = 1
FG.reagents.add_reagent(reagent_name,react_volume)
FG.add(F, react_volume, guarantee_is_member = fluid_and_group_already_exist)
F.done_init()
.= F
if (!airborne)
var/turf/simulated/floor/T = src
if (T.messy <= 0) return
if (istype(T))
var/found_cleanable = 0
for (var/obj/decal/cleanable/C in T)
if (!T.cleanable_fluid_react(C, 1))
found_cleanable = 1
LAGCHECK(LAG_LOW)
if (found_cleanable)
T.cleanable_fluid_react(0,1)
/turf/proc/react_all_cleanables() //Same procedure called in fluid_react and fluid_react_single. copypasted cause i dont wanna proc call overhead up in hea
/turf/simulated/floor/react_all_cleanables() //Same procedure called in fluid_react and fluid_react_single. copypasted cause i dont wanna proc call overhead up in hea
if (src.messy <= 0) return //hey this is CLEAN so don't even bother looping through contents, thanks!!
var/found_cleanable = 0
for (var/obj/decal/cleanable/C in src)
if (!src.cleanable_fluid_react(C, 1)) // Some cleanables need special treatment
found_cleanable = 1 //there exists a cleanable without a special case
LAGCHECK(LAG_LOW)
if (found_cleanable)
src.cleanable_fluid_react(0,1)
//called whenever a cleanable is spawned. Returns 1 on success
//grab_any_amount will be True when a fluid spreads onto a tile that may have cleanables on it
/turf/simulated/proc/cleanable_fluid_react(var/obj/decal/cleanable/possible_cleanable = 0, var/grab_any_amount = 0)
LAGCHECK(LAG_MED)
if (!IS_VALID_FLUIDREACT_TURF(src)) return
//if possible_cleanable has a value, handle exclusively this decal. don't search thru the turf.
if (possible_cleanable)
if (possible_cleanable.qdeled || possible_cleanable.pooled) return
if (istype(possible_cleanable, /obj/decal/cleanable/blood/dynamic))
var/obj/decal/cleanable/blood/dynamic/blood = possible_cleanable
var/blood_dna = blood.blood_DNA
var/blood_type = blood.blood_type
var/is_tracks = istype(possible_cleanable,/obj/decal/cleanable/blood/dynamic/tracks)
if (blood.blood_volume >= 13 || src.active_liquid || grab_any_amount)
if (blood.reagents)
var/datum/reagents/R = new(blood.reagents.maximum_volume) //Store reagents, delete cleanable, and then fluid react. prevents recursion
blood.reagents.copy_to(R)
var/blood_volume = blood.blood_volume
blood.clean_forensic()
src.fluid_react(R,is_tracks ? 0 : blood_volume)
else
var/reagent = blood.sample_reagent
var/amt = blood.blood_volume
blood.clean_forensic()
src.fluid_react_single(reagent,is_tracks ? 0 : amt)
if (src.active_liquid)
src.active_liquid.blood_DNA = blood_dna
src.active_liquid.blood_type = blood_type
return 1
return 0
//all right, tally up the cleanables and attempt to call fluid_reacts on them
var/list/cleanables = list()
for (var/obj/decal/cleanable/C in src)
if (C.qdeled || C.pooled) continue
//if (C.dry) continue
if (istype(C,/obj/decal/cleanable/blood/dynamic)) continue // handled above
if (!C.can_fluid_absorb) continue
cleanables += C
if (!src.active_liquid && (cleanables.len < 3 && !grab_any_amount))
return 0 //If the tile has an active liquid already, there is no requirement
for (var/obj/decal/cleanable/C in cleanables)
LAGCHECK(LAG_LOW)
if (C && C.reagents)
for(var/reagent_id in C.reagents.reagent_list)
if (ban_stacking_into_fluid.Find(reagent_id)) return
var/datum/reagents/R = new(C.reagents.maximum_volume) //Store reagents, delete cleanable, and then fluid react. prevents recursion
C.reagents.copy_to(R)
C.clean_forensic()
src.fluid_react(R, R.total_volume)
else if (C && C.can_sample && C.sample_reagent)
if ((!grab_any_amount && ban_stacking_into_fluid.Find(C.sample_reagent)) || ban_from_fluid.Find(C.sample_reagent)) return
var/sample = C.sample_reagent
var/amt = C.sample_amt
C.clean_forensic()
src.fluid_react_single(sample, amt)
return 1