mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
180 lines
5.8 KiB
Plaintext
180 lines
5.8 KiB
Plaintext
// Returns the atom sitting on the turf.
|
|
// For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf.
|
|
/proc/get_atom_on_turf(var/atom/movable/M)
|
|
var/atom/mloc = M
|
|
while(mloc && mloc.loc && !istype(mloc.loc, /turf/))
|
|
mloc = mloc.loc
|
|
return mloc
|
|
|
|
/proc/iswall(turf/T)
|
|
return (istype(T, /turf/simulated/wall) || istype(T, /turf/unsimulated/wall) || istype(T, /turf/simulated/shuttle/wall))
|
|
|
|
/proc/isfloor(turf/T)
|
|
return (istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor))
|
|
|
|
/proc/turf_clear(turf/T)
|
|
for(var/atom/A in T)
|
|
if(A.simulated)
|
|
return 0
|
|
return 1
|
|
|
|
// Picks a turf without a mob from the given list of turfs, if one exists.
|
|
// If no such turf exists, picks any random turf from the given list of turfs.
|
|
/proc/pick_mobless_turf_if_exists(var/list/start_turfs)
|
|
if(!start_turfs.len)
|
|
return null
|
|
|
|
var/list/available_turfs = list()
|
|
for(var/start_turf in start_turfs)
|
|
var/mob/M = locate() in start_turf
|
|
if(!M)
|
|
available_turfs += start_turf
|
|
if(!available_turfs.len)
|
|
available_turfs = start_turfs
|
|
return pick(available_turfs)
|
|
|
|
// Picks a turf that is clearance tiles away from the map edge given by dir, on z-level Z
|
|
/proc/pick_random_edge_turf(var/dir, var/Z, var/clearance = TRANSITIONEDGE + 1)
|
|
if(!dir)
|
|
return
|
|
switch(dir)
|
|
if(NORTH)
|
|
return locate(rand(clearance, world.maxx - clearance), world.maxy - clearance, Z)
|
|
if(SOUTH)
|
|
return locate(rand(clearance, world.maxx - clearance), clearance, Z)
|
|
if(EAST)
|
|
return locate(world.maxx - clearance, rand(clearance, world.maxy - clearance), Z)
|
|
if(WEST)
|
|
return locate(clearance, rand(clearance, world.maxy - clearance), Z)
|
|
|
|
/proc/is_below_sound_pressure(var/turf/T)
|
|
var/datum/gas_mixture/environment = T ? T.return_air() : null
|
|
var/pressure = environment ? environment.return_pressure() : 0
|
|
if(pressure < SOUND_MINIMUM_PRESSURE)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/*
|
|
Turf manipulation
|
|
*/
|
|
|
|
//Returns an assoc list that describes how turfs would be changed if the
|
|
//turfs in turfs_src were translated by shifting the src_origin to the dst_origin
|
|
/proc/get_turf_translation(turf/src_origin, turf/dst_origin, list/turfs_src)
|
|
var/list/turf_map = list()
|
|
for(var/turf/source in turfs_src)
|
|
var/x_pos = (source.x - src_origin.x)
|
|
var/y_pos = (source.y - src_origin.y)
|
|
var/z_pos = (source.z - src_origin.z)
|
|
|
|
var/turf/target = locate(dst_origin.x + x_pos, dst_origin.y + y_pos, dst_origin.z + z_pos)
|
|
if(!target)
|
|
error("Null turf in translation @ ([dst_origin.x + x_pos], [dst_origin.y + y_pos], [dst_origin.z + z_pos])")
|
|
turf_map[source] = target //if target is null, preserve that information in the turf map
|
|
|
|
return turf_map
|
|
|
|
/proc/translate_turfs(var/list/translation, var/area/base_area = null, var/turf/base_turf)
|
|
for(var/turf/source in translation)
|
|
|
|
var/turf/target = translation[source]
|
|
|
|
if(target)
|
|
if(base_area) ChangeArea(target, get_area(source))
|
|
var/leave_turf = base_turf ? base_turf : get_base_turf_by_area(base_area ? base_area : source)
|
|
translate_turf(source, target, leave_turf)
|
|
if(base_area) ChangeArea(source, base_area)
|
|
|
|
//change the old turfs (Currently done by translate_turf for us)
|
|
//for(var/turf/source in translation)
|
|
// source.ChangeTurf(base_turf ? base_turf : get_base_turf_by_area(source), 1, 1)
|
|
|
|
// Parmaters for stupid historical reasons are:
|
|
// T - Origin
|
|
// B - Destination
|
|
/proc/translate_turf(var/turf/T, var/turf/B, var/turftoleave = null)
|
|
|
|
//You can stay, though.
|
|
if(istype(T,/turf/space))
|
|
error("Tried to translate a space turf: src=[log_info_line(T)] dst=[log_info_line(B)]")
|
|
return FALSE // TODO - Is this really okay to do nothing?
|
|
|
|
var/turf/X //New Destination Turf
|
|
|
|
//Are we doing shuttlework? Just to save another type check later.
|
|
var/shuttlework = 0
|
|
|
|
//Shuttle turfs handle their own fancy moving.
|
|
if(istype(T,/turf/simulated/shuttle))
|
|
shuttlework = 1
|
|
var/turf/simulated/shuttle/SS = T
|
|
if(!SS.landed_holder) SS.landed_holder = new(turf = SS)
|
|
X = SS.landed_holder.land_on(B)
|
|
|
|
//Generic non-shuttle turf move.
|
|
else
|
|
var/old_dir1 = T.dir
|
|
var/old_icon_state1 = T.icon_state
|
|
var/old_icon1 = T.icon
|
|
var/old_underlays = T.underlays.Copy()
|
|
var/old_decals = T.decals ? T.decals.Copy() : null
|
|
|
|
X = B.ChangeTurf(T.type)
|
|
X.set_dir(old_dir1)
|
|
X.icon_state = old_icon_state1
|
|
X.icon = old_icon1
|
|
X.copy_overlays(T, TRUE)
|
|
X.underlays = old_underlays
|
|
X.decals = old_decals
|
|
|
|
//Move the air from source to dest
|
|
var/turf/simulated/ST = T
|
|
if(istype(ST) && ST.zone)
|
|
var/turf/simulated/SX = X
|
|
if(!SX.air)
|
|
SX.make_air()
|
|
SX.air.copy_from(ST.zone.air)
|
|
ST.zone.remove(ST)
|
|
|
|
var/z_level_change = FALSE
|
|
if(T.z != X.z)
|
|
z_level_change = TRUE
|
|
|
|
//Move the objects. Not forceMove because the object isn't "moving" really, it's supposed to be on the "same" turf.
|
|
for(var/obj/O in T)
|
|
if(O.simulated)
|
|
O.loc = X
|
|
O.update_light()
|
|
if(z_level_change) // The objects still need to know if their z-level changed.
|
|
O.onTransitZ(T.z, X.z)
|
|
|
|
//Move the mobs unless it's an AI eye or other eye type.
|
|
for(var/mob/M in T)
|
|
if(isEye(M)) continue // If we need to check for more mobs, I'll add a variable
|
|
M.loc = X
|
|
|
|
if(z_level_change) // Same goes for mobs.
|
|
M.onTransitZ(T.z, X.z)
|
|
|
|
if(istype(M, /mob/living))
|
|
var/mob/living/LM = M
|
|
LM.check_shadow() // Need to check their Z-shadow, which is normally done in forceMove().
|
|
|
|
if(shuttlework)
|
|
var/turf/simulated/shuttle/SS = T
|
|
SS.landed_holder.leave_turf(turftoleave)
|
|
else if(turftoleave)
|
|
T.ChangeTurf(turftoleave)
|
|
else
|
|
T.ChangeTurf(get_base_turf_by_area(T))
|
|
|
|
return TRUE
|
|
|
|
//Used for border objects. This returns true if this atom is on the border between the two specified turfs
|
|
//This assumes that the atom is located inside the target turf
|
|
/atom/proc/is_between_turfs(var/turf/origin, var/turf/target)
|
|
if (flags & ON_BORDER)
|
|
var/testdir = get_dir(target, origin)
|
|
return (dir & testdir)
|
|
return TRUE
|