Files
Paradise/code/game/turfs/turf.dm
2015-07-15 17:22:56 +02:00

427 lines
11 KiB
Plaintext

/turf
icon = 'icons/turf/floors.dmi'
level = 1.0
luminosity = 1
//for floors, use is_plating(), is_plasteel_floor() and is_light_floor()
var/intact = 1
//Properties for open tiles (/floor)
var/oxygen = 0
var/carbon_dioxide = 0
var/nitrogen = 0
var/toxins = 0
//Properties for airtight tiles (/wall)
var/thermal_conductivity = 0.05
var/heat_capacity = 1
//Properties for both
var/temperature = T20C
var/blocks_air = 0
var/icon_old = null
var/pathweight = 1
//Mining resource generation stuff.
var/has_resources
var/list/resources
var/PathNode/PNode = null //associated PathNode in the A* algorithm
var/dynamic_lighting = 1
flags = 0
/turf/New()
..()
for(var/atom/movable/AM as mob|obj in src)
spawn( 0 )
src.Entered(AM)
return
/turf/Destroy()
return QDEL_HINT_HARDDEL_NOW
// Adds the adjacent turfs to the current atmos processing
/turf/Del()
if(air_master)
for(var/direction in cardinal)
if(atmos_adjacent_turfs & direction)
var/turf/simulated/T = get_step(src, direction)
if(istype(T))
air_master.add_to_active(T)
..()
/turf/ex_act(severity)
return 0
/turf/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/beam/pulse))
src.ex_act(2)
..()
return 0
/turf/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/bullet/gyro))
explosion(src, -1, 0, 2)
..()
return 0
/turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area)
if (!mover)
return 1
// First, make sure it can leave its square
if(isturf(mover.loc))
// Nothing but border objects stop you from leaving a tile, only one loop is needed
for(var/obj/obstacle in mover.loc)
if(!obstacle.CheckExit(mover, src) && obstacle != mover && obstacle != forget)
mover.Bump(obstacle, 1)
return 0
var/list/large_dense = list()
//Next, check objects to block entry that are on the border
for(var/atom/movable/border_obstacle in src)
if(border_obstacle.flags&ON_BORDER)
if(!border_obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != border_obstacle))
mover.Bump(border_obstacle, 1)
return 0
else
large_dense += border_obstacle
//Then, check the turf itself
if (!src.CanPass(mover, src))
mover.Bump(src, 1)
return 0
//Finally, check objects/mobs to block entry that are not on the border
for(var/atom/movable/obstacle in large_dense)
if(!obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != obstacle))
mover.Bump(obstacle, 1)
return 0
return 1 //Nothing found to block so return success!
/turf/Entered(atom/atom as mob|obj)
..()
//vvvvv Infared beam stuff vvvvv
if ((atom && atom.density && !( istype(atom, /obj/effect/beam) )))
for(var/obj/effect/beam/i_beam/I in src)
spawn( 0 )
if (I)
I.hit()
break
//^^^^^ Infared beam stuff ^^^^^
if(!istype(atom, /atom/movable))
return
var/atom/movable/M = atom
if(!M.simulated) return
var/loopsanity = 100
if(ismob(M))
if(!M:lastarea)
M:lastarea = get_area(M.loc)
if(M:lastarea.has_gravity == 0)
inertial_drift(M)
/*
if(M.flags & NOGRAV)
inertial_drift(M)
*/
else if(!istype(src, /turf/space))
M:inertia_dir = 0
..()
var/objects = 0
for(var/atom/A as mob|obj|turf|area in range(1))
if(!A.simulated) return
if(objects > loopsanity) break
objects++
spawn( 0 )
if ((A && M))
A.HasProximity(M, 1)
return
return
/turf/proc/adjacent_fire_act(turf/simulated/floor/source, temperature, volume)
return
/turf/proc/is_plating()
return 0
/turf/proc/is_asteroid_floor()
return 0
/turf/proc/is_plasteel_floor()
return 0
/turf/proc/is_light_floor()
return 0
/turf/proc/is_grass_floor()
return 0
/turf/proc/is_wood_floor()
return 0
/turf/proc/is_carpet_floor()
return 0
/turf/proc/is_catwalk()
return 0
/turf/proc/return_siding_icon_state() //used for grass floors, which have siding.
return 0
/turf/proc/inertial_drift(atom/movable/A as mob|obj)
if(!(A.last_move)) return
if(istype(A, /obj/spacepod) && src.x > 2 && src.x < (world.maxx - 1) && src.y > 2 && src.y < (world.maxy-1))
var/obj/spacepod/SP = A
if(SP.Process_Spacemove(1))
SP.inertia_dir = 0
return
spawn(5)
if((SP && (SP.loc == src)))
if(SP.inertia_dir)
step(SP, SP.inertia_dir)
return
if(istype(A, /obj/structure/stool/bed/chair/cart/) && src.x > 2 && src.x < (world.maxx - 1) && src.y > 2 && src.y < (world.maxy-1))
var/obj/structure/stool/bed/chair/cart/JC = A //A bomb!
if(JC.Process_Spacemove(1))
JC.inertia_dir = 0
return
spawn(5)
if((JC && (JC.loc == src)))
if(JC.inertia_dir)
step(JC, JC.inertia_dir)
return
JC.inertia_dir = JC.last_move
step(JC, JC.inertia_dir)
if((istype(A, /mob/) && src.x > 2 && src.x < (world.maxx - 1) && src.y > 2 && src.y < (world.maxy-1)))
var/mob/M = A
if(M.Process_Spacemove(1))
M.inertia_dir = 0
return
spawn(5)
if((M && !(M.anchored) && !(M.pulledby) && (M.loc == src)))
if(M.inertia_dir)
step(M, M.inertia_dir)
return
M.inertia_dir = M.last_move
step(M, M.inertia_dir)
return
/turf/proc/levelupdate()
for(var/obj/O in src)
if(O.level == 1)
O.hide(src.intact)
// override for space turfs, since they should never hide anything
/turf/space/levelupdate()
for(var/obj/O in src)
if(O.level == 1)
O.hide(0)
// Removes all signs of lattice on the pos of the turf -Donkieyo
/turf/proc/RemoveLattice()
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
qdel(L)
//Creates a new turf
/turf/proc/ChangeTurf(var/path)
if(!path) return
if(path == type) return src
var/old_opacity = opacity
var/old_dynamic_lighting = dynamic_lighting
var/list/old_affecting_lights = affecting_lights
var/old_lighting_overlay = lighting_overlay
if(air_master)
air_master.remove_from_active(src)
var/turf/W = new path(src)
if(istype(W, /turf/simulated))
W:Assimilate_Air()
W.RemoveLattice()
for(var/turf/space/S in range(W,1))
S.update_starlight()
lighting_overlay = old_lighting_overlay
affecting_lights = old_affecting_lights
if((old_opacity != opacity) || (dynamic_lighting != old_dynamic_lighting))
reconsider_lights()
if(dynamic_lighting != old_dynamic_lighting)
if(dynamic_lighting)
lighting_build_overlays()
else
lighting_clear_overlays()
W.levelupdate()
W.CalculateAdjacentTurfs()
return W
//////Assimilate Air//////
/turf/simulated/proc/Assimilate_Air()
if(air)
var/aoxy = 0//Holders to assimilate air from nearby turfs
var/anitro = 0
var/aco = 0
var/atox = 0
var/atemp = 0
var/turf_count = 0
for(var/direction in cardinal)//Only use cardinals to cut down on lag
var/turf/T = get_step(src,direction)
if(istype(T,/turf/space))//Counted as no air
turf_count++//Considered a valid turf for air calcs
continue
else if(istype(T,/turf/simulated/floor))
var/turf/simulated/S = T
if(S.air)//Add the air's contents to the holders
aoxy += S.air.oxygen
anitro += S.air.nitrogen
aco += S.air.carbon_dioxide
atox += S.air.toxins
atemp += S.air.temperature
turf_count ++
air.oxygen = (aoxy/max(turf_count,1))//Averages contents of the turfs, ignoring walls and the like
air.nitrogen = (anitro/max(turf_count,1))
air.carbon_dioxide = (aco/max(turf_count,1))
air.toxins = (atox/max(turf_count,1))
air.temperature = (atemp/max(turf_count,1))//Trace gases can get bant
if(air_master)
air_master.add_to_active(src)
/turf/proc/ReplaceWithLattice()
src.ChangeTurf(/turf/space)
new /obj/structure/lattice( locate(src.x, src.y, src.z) )
/turf/proc/kill_creatures(mob/U = null)//Will kill people/creatures and damage mechs./N
//Useful to batch-add creatures to the list.
for(var/mob/living/M in src)
if(M==U) continue//Will not harm U. Since null != M, can be excluded to kill everyone.
spawn(0)
M.gib()
for(var/obj/mecha/M in src)//Mecha are not gibbed but are damaged.
spawn(0)
M.take_damage(100, "brute")
/turf/proc/Bless()
flags |= NOJAUNT
/////////////////////////////////////////////////////////////////////////
// Navigation procs
// Used for A-star pathfinding
////////////////////////////////////////////////////////////////////////
///////////////////////////
//Cardinal only movements
///////////////////////////
// Returns the surrounding cardinal turfs with open links
// Including through doors openable with the ID
/turf/proc/CardinalTurfsWithAccess(var/obj/item/weapon/card/id/ID)
var/list/L = new()
var/turf/simulated/T
for(var/dir in cardinal)
T = get_step(src, dir)
if(istype(T) && !T.density)
if(!LinkBlockedWithAccess(src, T, ID))
L.Add(T)
return L
// Returns the surrounding cardinal turfs with open links
// Don't check for ID, doors passable only if open
/turf/proc/CardinalTurfs()
var/list/L = new()
var/turf/simulated/T
for(var/dir in cardinal)
T = get_step(src, dir)
if(istype(T) && !T.density)
if(!LinkBlocked(src, T))
L.Add(T)
return L
///////////////////////////
//All directions movements
///////////////////////////
// Returns the surrounding simulated turfs with open links
// Including through doors openable with the ID
/turf/proc/AdjacentTurfsWithAccess(var/obj/item/weapon/card/id/ID = null,var/list/closed)//check access if one is passed
var/list/L = new()
var/turf/simulated/T
for(var/dir in list(NORTHWEST,NORTHEAST,SOUTHEAST,SOUTHWEST,NORTH,EAST,SOUTH,WEST)) //arbitrarily ordered list to favor non-diagonal moves in case of ties
T = get_step(src,dir)
if(T in closed) //turf already proceeded in A*
continue
if(istype(T) && !T.density)
if(!LinkBlockedWithAccess(src, T, ID))
L.Add(T)
return L
//Idem, but don't check for ID and goes through open doors
/turf/proc/AdjacentTurfs(var/list/closed)
var/list/L = new()
var/turf/simulated/T
for(var/dir in list(NORTHWEST,NORTHEAST,SOUTHEAST,SOUTHWEST,NORTH,EAST,SOUTH,WEST)) //arbitrarily ordered list to favor non-diagonal moves in case of ties
T = get_step(src,dir)
if(T in closed) //turf already proceeded by A*
continue
if(istype(T) && !T.density)
if(!LinkBlocked(src, T))
L.Add(T)
return L
// check for all turfs, including unsimulated ones
/turf/proc/AdjacentTurfsSpace(var/obj/item/weapon/card/id/ID = null, var/list/closed)//check access if one is passed
var/list/L = new()
var/turf/T
for(var/dir in list(NORTHWEST,NORTHEAST,SOUTHEAST,SOUTHWEST,NORTH,EAST,SOUTH,WEST)) //arbitrarily ordered list to favor non-diagonal moves in case of ties
T = get_step(src,dir)
if(T in closed) //turf already proceeded by A*
continue
if(istype(T) && !T.density)
if(!ID)
if(!LinkBlocked(src, T))
L.Add(T)
else
if(!LinkBlockedWithAccess(src, T, ID))
L.Add(T)
return L
//////////////////////////////
//Distance procs
//////////////////////////////
//Distance associates with all directions movement
/turf/proc/Distance(var/turf/T)
return get_dist(src,T)
// This Distance proc assumes that only cardinal movement is
// possible. It results in more efficient (CPU-wise) pathing
// for bots and anything else that only moves in cardinal dirs.
/turf/proc/Distance_cardinal(turf/T)
if(!src || !T) return 0
return abs(src.x - T.x) + abs(src.y - T.y)
////////////////////////////////////////////////////
/turf/singularity_act()
if(intact)
for(var/obj/O in contents) //this is for deleting things like wires contained in the turf
if(O.level != 1)
continue
if(O.invisibility == 101)
O.singularity_act()
ChangeTurf(/turf/space)
return(2)