/turf icon = 'icons/turf/floors.dmi' level = 1 var/intact = 1 // baseturfs can be either a list or a single turf type. // In class definition like here it should always be a single type. // A list will be created in initialization that figures out the baseturf's baseturf etc. // In the case of a list it is sorted from bottom layer to top. // This shouldn't be modified directly, use the helper procs. var/list/baseturfs = /turf/open/space var/temperature = T20C var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to var/blocks_air = FALSE flags_1 = CAN_BE_DIRTY_1 var/image/obscured //camerachunks var/list/image/blueprint_data //for the station blueprints, images of objects eg: pipes var/explosion_level = 0 //for preventing explosion dodging var/explosion_id = 0 var/list/decals var/requires_activation //add to air processing after initialize? var/changing_turf = FALSE /turf/vv_edit_var(var_name, new_value) var/static/list/banned_edits = list("x", "y", "z") if(var_name in banned_edits) return FALSE . = ..() /turf/Initialize() if(initialized) stack_trace("Warning: [src]([type]) initialized multiple times!") initialized = TRUE assemble_baseturfs() levelupdate() if(smooth) queue_smooth(src) visibilityChanged() for(var/atom/movable/AM in src) Entered(AM) var/area/A = loc if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(A)) add_overlay(/obj/effect/fullbright) if(requires_activation) CalculateAdjacentTurfs() SSair.add_to_active(src) if (light_power && light_range) update_light() if (opacity) has_opaque_atom = TRUE ComponentInitialize() return INITIALIZE_HINT_NORMAL /turf/proc/Initalize_Atmos(times_fired) CalculateAdjacentTurfs() /turf/Destroy(force) . = QDEL_HINT_IWILLGC if(!changing_turf) stack_trace("Incorrect turf deletion") changing_turf = FALSE if(force) ..() //this will completely wipe turf state var/turf/B = new world.turf(src) for(var/A in B.contents) qdel(A) for(var/I in B.vars) B.vars[I] = null return SSair.remove_from_active(src) visibilityChanged() QDEL_LIST(blueprint_data) initialized = FALSE requires_activation = FALSE ..() /turf/attack_hand(mob/user) user.Move_Pulled(src) /turf/proc/handleRCL(obj/item/twohanded/rcl/C, mob/user) if(C.loaded) for(var/obj/structure/cable/LC in src) if(!LC.d1 || !LC.d2) LC.handlecable(C, user) return C.loaded.place_turf(src, user) C.is_empty(user) /turf/attackby(obj/item/C, mob/user, params) if(..()) return TRUE if(can_lay_cable() && istype(C, /obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/coil = C for(var/obj/structure/cable/LC in src) if(!LC.d1 || !LC.d2) LC.attackby(C,user) return coil.place_turf(src, user) return TRUE else if(istype(C, /obj/item/twohanded/rcl)) handleRCL(C, user) return FALSE /turf/CanPass(atom/movable/mover, turf/target) if(!target) return FALSE if(istype(mover)) // turf/Enter(...) will perform more advanced checks return !density stack_trace("Non movable passed to turf CanPass : [mover]") return FALSE /turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area) // 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.Collide(obstacle) return FALSE //Then, check the turf itself if (!src.CanPass(mover, src)) mover.Collide(src) return FALSE var/atom/movable/topmost_bump var/top_layer = FALSE //Next, check objects to block entry that are on the border for(var/atom/movable/obstacle in src) if(!obstacle.CanPass(mover, mover.loc, 1) && (forget != obstacle)) if(obstacle.flags_1 & ON_BORDER_1) mover.Collide(obstacle) return FALSE else if(obstacle.layer > top_layer) topmost_bump = obstacle top_layer = obstacle.layer if(topmost_bump) mover.Collide(topmost_bump) return FALSE return TRUE //Nothing found to block so return success! /turf/Entered(atom/movable/AM) ..() if(explosion_level && AM.ex_check(explosion_id)) AM.ex_act(explosion_level) // If an opaque movable atom moves around we need to potentially update visibility. if (AM.opacity) has_opaque_atom = TRUE // Make sure to do this before reconsider_lights(), incase we're on instant updates. Guaranteed to be on in this case. reconsider_lights() /turf/open/Entered(atom/movable/AM) ..() //melting if(isobj(AM) && air && air.temperature > T0C) var/obj/O = AM if(O.flags_2 & FROZEN_2) O.make_unfrozen() /turf/proc/is_plasteel_floor() return FALSE // A proc in case it needs to be recreated or badmins want to change the baseturfs /turf/proc/assemble_baseturfs(turf/fake_baseturf_type) var/static/list/created_baseturf_lists = list() var/turf/current_target if(fake_baseturf_type) if(length(fake_baseturf_type)) // We were given a list, just apply it and move on baseturfs = fake_baseturf_type return current_target = fake_baseturf_type else if(length(baseturfs)) return // No replacement baseturf has been given and the current baseturfs value is already a list/assembled if(!baseturfs) current_target = initial(baseturfs) || type // This should never happen but just in case... stack_trace("baseturfs var was null for [type]. Failsafe activated and it has been given a new baseturfs value of [current_target].") else current_target = baseturfs // If we've made the output before we don't need to regenerate it if(created_baseturf_lists[current_target]) var/list/premade_baseturfs = created_baseturf_lists[current_target] if(length(premade_baseturfs)) baseturfs = premade_baseturfs.Copy() else baseturfs = premade_baseturfs return baseturfs var/turf/next_target = initial(current_target.baseturfs) //Most things only have 1 baseturf so this loop won't run in most cases if(current_target == next_target) baseturfs = current_target created_baseturf_lists[current_target] = current_target return current_target var/list/new_baseturfs = list(current_target) for(var/i=0;current_target != next_target;i++) if(i > 100) // A baseturfs list over 100 members long is silly // Because of how this is all structured it will only runtime/message once per type stack_trace("A turf <[type]> created a baseturfs list over 100 members long. This is most likely an infinite loop.") message_admins("A turf <[type]> created a baseturfs list over 100 members long. This is most likely an infinite loop.") break new_baseturfs.Insert(1, next_target) current_target = next_target next_target = initial(current_target.baseturfs) baseturfs = new_baseturfs created_baseturf_lists[new_baseturfs[new_baseturfs.len]] = new_baseturfs.Copy() return new_baseturfs /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/open/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) /turf/proc/phase_damage_creatures(damage,mob/U = null)//>Ninja Code. Hurts and knocks out creatures on this turf //NINJACODE for(var/mob/living/M in src) if(M==U) continue//Will not harm U. Since null != M, can be excluded to kill everyone. M.adjustBruteLoss(damage) M.Unconscious(damage * 4) for(var/obj/mecha/M in src) M.take_damage(damage*2, BRUTE, "melee", 1) /turf/proc/Bless() flags_1 |= NOJAUNT_1 /turf/storage_contents_dump_act(obj/item/storage/src_object, mob/user) if(src_object.contents.len) to_chat(usr, "You start dumping out the contents...") if(!do_after(usr,20,target=src_object)) return FALSE var/list/things = src_object.contents.Copy() var/datum/progressbar/progress = new(user, things.len, src) while (do_after(usr, 10, TRUE, src, FALSE, CALLBACK(src_object, /obj/item/storage.proc/mass_remove_from_storage, src, things, progress))) stoplag(1) qdel(progress) return TRUE ////////////////////////////// //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 FALSE return abs(x - T.x) + abs(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 == INVISIBILITY_MAXIMUM) O.singularity_act() ScrapeAway() return(2) /turf/proc/can_have_cabling() return TRUE /turf/proc/can_lay_cable() return can_have_cabling() & !intact /turf/proc/visibilityChanged() GLOB.cameranet.updateVisibility(src) /turf/proc/burn_tile() /turf/proc/is_shielded() /turf/contents_explosion(severity, target) var/affecting_level if(severity == 1) affecting_level = 1 else if(is_shielded()) affecting_level = 3 else if(intact) affecting_level = 2 else affecting_level = 1 for(var/V in contents) var/atom/A = V if(A.level >= affecting_level) if(ismovableatom(A)) var/atom/movable/AM = A if(!AM.ex_check(explosion_id)) continue A.ex_act(severity, target) CHECK_TICK /turf/narsie_act(force, ignore_mobs, probability = 20) . = (prob(probability) || force) for(var/I in src) var/atom/A = I if(ignore_mobs && ismob(A)) continue if(ismob(A) || .) A.narsie_act() /turf/ratvar_act(force, ignore_mobs, probability = 40) . = (prob(probability) || force) for(var/I in src) var/atom/A = I if(ignore_mobs && ismob(A)) continue if(ismob(A) || .) A.ratvar_act() /turf/proc/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) underlay_appearance.icon = icon underlay_appearance.icon_state = icon_state underlay_appearance.dir = adjacency_dir return TRUE /turf/proc/add_blueprints(atom/movable/AM) var/image/I = new I.appearance = AM.appearance I.appearance_flags = RESET_COLOR|RESET_ALPHA|RESET_TRANSFORM I.loc = src I.setDir(AM.dir) I.alpha = 128 LAZYADD(blueprint_data, I) /turf/proc/add_blueprints_preround(atom/movable/AM) if(!SSticker.HasRoundStarted()) add_blueprints(AM) /turf/proc/is_transition_turf() return /turf/acid_act(acidpwr, acid_volume) . = 1 var/acid_type = /obj/effect/acid if(acidpwr >= 200) //alien acid power acid_type = /obj/effect/acid/alien var/has_acid_effect = FALSE for(var/obj/O in src) if(intact && O.level == 1) //hidden under the floor continue if(istype(O, acid_type)) var/obj/effect/acid/A = O A.acid_level = min(A.level + acid_volume * acidpwr, 12000)//capping acid level to limit power of the acid has_acid_effect = 1 continue O.acid_act(acidpwr, acid_volume) if(!has_acid_effect) new acid_type(src, acidpwr, acid_volume) /turf/proc/acid_melt() return /turf/handle_fall(mob/faller, forced) faller.lying = pick(90, 270) if(!forced) return if(has_gravity(src)) playsound(src, "bodyfall", 50, 1) /turf/proc/add_decal(decal,group) LAZYINITLIST(decals) if(!decals[group]) decals[group] = list() decals[group] += decal add_overlay(decals[group]) /turf/proc/remove_decal(group) LAZYINITLIST(decals) cut_overlay(decals[group]) decals[group] = null /turf/proc/photograph(limit=20) var/image/I = new() I.add_overlay(src) for(var/V in contents) var/atom/A = V if(A.invisibility) continue I.add_overlay(A) if(limit) limit-- else return I return I /turf/AllowDrop() return TRUE