Files
Paradise/code/ATMOSPHERICS/atmospherics.dm
Tigercat2000 bee2954d7b Ports holomap blueprints from tg/vg.
Changes:
 - Clicking "view structural data" in the station blueprints menu will
   show you ghost images of where things like disposal pipes, wires,
   atmospherics pipes, and other power machinery are originally supposed
   to go. Note, this will show you the ghost images over turfs even if the
   machinery is destroyed.
2016-05-05 22:05:39 -07:00

321 lines
11 KiB
Plaintext

/*
Quick overview:
Pipes combine to form pipelines
Pipelines and other atmospheric objects combine to form pipe_networks
Note: A single pipe_network represents a completely open space
Pipes -> Pipelines
Pipelines + Other Objects -> Pipe network
*/
/obj/machinery/atmospherics
auto_init = 0
anchored = 1
layer = 2.4 //under wires with their 2.44
idle_power_usage = 0
active_power_usage = 0
power_channel = ENVIRON
on_blueprints = TRUE
var/nodealert = 0
var/can_unwrench = 0
var/connect_types[] = list(1) //1=regular, 2=supply, 3=scrubber
var/connected_to = 1 //same as above, currently not used for anything
var/icon_connect_type = "" //"-supply" or "-scrubbers"
var/initialize_directions = 0
var/pipe_color
var/obj/item/pipe/stored
var/image/pipe_image
var/global/datum/pipe_icon_manager/icon_manager
/obj/machinery/atmospherics/New()
if(!icon_manager)
icon_manager = new()
if(!pipe_color)
pipe_color = color
color = null
if(!pipe_color_check(pipe_color))
pipe_color = null
..()
/obj/machinery/atmospherics/initialize()
..()
if(can_unwrench)
stored = new(src, make_from = src)
/obj/machinery/atmospherics/Destroy()
if(stored)
qdel(stored)
stored = null
for(var/mob/living/L in src) //ventcrawling is serious business
L.remove_ventcrawl()
L.forceMove(get_turf(src))
if(pipe_image)
qdel(pipe_image) //we have to del it, or it might keep a ref somewhere else
pipe_image = null
return ..()
// Icons/overlays/underlays
/obj/machinery/atmospherics/update_icon()
return null
/obj/machinery/atmospherics/proc/check_icon_cache(var/safety = 0)
if(!istype(icon_manager))
if(!safety) //to prevent infinite loops
icon_manager = new()
check_icon_cache(1)
return 0
return 1
/obj/machinery/atmospherics/proc/color_cache_name(var/obj/machinery/atmospherics/node)
//Don't use this for standard pipes
if(!istype(node))
return null
return node.pipe_color
/obj/machinery/atmospherics/proc/add_underlay(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type)
if(node)
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
//underlays += icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node))
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
else
//underlays += icon_manager.get_atmos_icon("underlay_intact", direction, color_cache_name(node))
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
else
//underlays += icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color)
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type)
/obj/machinery/atmospherics/proc/update_underlays()
if(check_icon_cache())
return 1
else
return 0
// Connect types
/obj/machinery/atmospherics/proc/check_connect_types(obj/machinery/atmospherics/atmos1, obj/machinery/atmospherics/atmos2)
var/i
var/list1[] = atmos1.connect_types
var/list2[] = atmos2.connect_types
for(i=1,i<=list1.len,i++)
var/j
for(j=1,j<=list2.len,j++)
if(list1[i] == list2[j])
var/n = list1[i]
return n
return 0
/obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/atmospherics/atmos1, obj/item/pipe/pipe2)
var/i
var/list1[] = atmos1.connect_types
var/list2[] = pipe2.connect_types
for(i=1,i<=list1.len,i++)
var/j
for(j=1,j<=list2.len,j++)
if(list1[i] == list2[j])
var/n = list1[i]
return n
return 0
// Pipenet related functions
/obj/machinery/atmospherics/proc/returnPipenet()
return
/obj/machinery/atmospherics/proc/returnPipenetAir()
return
/obj/machinery/atmospherics/proc/setPipenet()
return
/obj/machinery/atmospherics/proc/replacePipenet()
return
/obj/machinery/atmospherics/proc/build_network()
// Called to build a network from this node
return
/obj/machinery/atmospherics/proc/defer_build_network()
deferred_pipenet_rebuilds += src
/obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference)
return
/obj/machinery/atmospherics/proc/nullifyPipenet(datum/pipeline/P)
if(P)
P.other_atmosmch -= src
//(De)construction
/obj/machinery/atmospherics/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if(can_unwrench && istype(W, /obj/item/weapon/wrench))
var/turf/T = get_turf(src)
if (level == 1 && isturf(T) && T.intact)
to_chat(user, "<span class='danger'>You must remove the plating first.</span>")
return 1
var/datum/gas_mixture/int_air = return_air()
var/datum/gas_mixture/env_air = loc.return_air()
add_fingerprint(user)
var/unsafe_wrenching = FALSE
var/internal_pressure = int_air.return_pressure()-env_air.return_pressure()
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
if (internal_pressure > 2*ONE_ATMOSPHERE)
to_chat(user, "<span class='warning'>As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?</span>")
unsafe_wrenching = TRUE //Oh dear oh dear
if (do_after(user, 40, target = src) && isnull(gcDestroyed))
user.visible_message( \
"[user] unfastens \the [src].", \
"<span class='notice'>You have unfastened \the [src].</span>", \
"<span class='italics'>You hear ratchet.</span>")
investigate_log("was <span class='warning'>REMOVED</span> by [key_name(usr)]", "atmos")
//You unwrenched a pipe full of pressure? let's splat you into the wall silly.
if(unsafe_wrenching)
unsafe_pressure_release(user,internal_pressure)
Deconstruct()
else
return ..()
//Called when an atmospherics object is unwrenched while having a large pressure difference
//with it's locs air contents.
/obj/machinery/atmospherics/proc/unsafe_pressure_release(var/mob/user,var/pressures)
if(!user)
return
if(!pressures)
var/datum/gas_mixture/int_air = return_air()
var/datum/gas_mixture/env_air = loc.return_air()
pressures = int_air.return_pressure()-env_air.return_pressure()
var/fuck_you_dir = get_dir(src,user)
var/turf/general_direction = get_edge_target_turf(user,fuck_you_dir)
user.visible_message("<span class='danger'>[user] is sent flying by pressure!</span>","<span class='userdanger'>The pressure sends you flying!</span>")
//Values based on 2*ONE_ATMOS (the unsafe pressure), resulting in 20 range and 4 speed
user.throw_at(general_direction,pressures/10,pressures/50)
/obj/machinery/atmospherics/proc/Deconstruct()
if(can_unwrench)
stored.loc = get_turf(src)
transfer_fingerprints_to(stored)
stored = null
qdel(src)
/obj/machinery/atmospherics/construction(D, P, C)
if(C)
color = C
dir = D
initialize_directions = P
var/turf/T = loc
level = T.intact ? 2 : 1
add_fingerprint(usr)
initialize()
var/list/nodes = pipeline_expansion()
for(var/obj/machinery/atmospherics/A in nodes)
A.initialize()
A.addMember(src)
build_network()
// Find a connecting /obj/machinery/atmospherics in specified direction.
/obj/machinery/atmospherics/proc/findConnecting(var/direction)
for(var/obj/machinery/atmospherics/target in get_step(src,direction))
var/can_connect = check_connect_types(target, src)
if(can_connect && (target.initialize_directions & get_dir(target,src)))
return target
// Ventcrawling
#define VENT_SOUND_DELAY 30
/obj/machinery/atmospherics/relaymove(mob/living/user, direction)
if(!(direction & initialize_directions)) //can't go in a way we aren't connecting to
return
if(buckled_mob == user)
return
var/obj/machinery/atmospherics/target_move = findConnecting(direction)
if(target_move)
if(is_type_in_list(target_move, ventcrawl_machinery) && target_move.can_crawl_through())
user.remove_ventcrawl()
user.forceMove(target_move.loc) //handles entering and so on
user.visible_message("You hear something squeezing through the ducts.", "You climb out the ventilation system.")
else if(target_move.can_crawl_through())
if(returnPipenet() != target_move.returnPipenet())
user.update_pipe_vision(target_move)
user.loc = target_move
user.client.eye = target_move //if we don't do this, Byond only updates the eye every tick - required for smooth movement
if(world.time - user.last_played_vent > VENT_SOUND_DELAY)
user.last_played_vent = world.time
playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
else
var/can_connect = check_connect_types(target_move, src)
if((direction & initialize_directions) || (is_type_in_list(src, ventcrawl_machinery) && target_move.can_crawl_through() && can_connect)) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
user.remove_ventcrawl()
user.forceMove(src.loc)
user.visible_message("You hear something squeezing through the pipes.", "You climb out the ventilation system.")
user.canmove = 0
spawn(1)
user.canmove = 1
/obj/machinery/atmospherics/AltClick(var/mob/living/L)
if(is_type_in_list(src, ventcrawl_machinery))
L.handle_ventcrawl(src)
return
..()
/obj/machinery/atmospherics/proc/can_crawl_through()
return 1
/obj/machinery/atmospherics/proc/change_color(var/new_color)
//only pass valid pipe colors please ~otherwise your pipe will turn invisible
if(!pipe_color_check(new_color))
return
pipe_color = new_color
update_icon()
// Additional icon procs
/obj/machinery/atmospherics/proc/universal_underlays(var/obj/machinery/atmospherics/node, var/direction)
var/turf/T = get_turf(src)
if(!istype(T)) return
if(node)
var/node_dir = get_dir(src,node)
if(node.icon_connect_type == "-supply")
add_underlay_adapter(T, , node_dir, "")
add_underlay_adapter(T, node, node_dir, "-supply")
add_underlay_adapter(T, , node_dir, "-scrubbers")
else if (node.icon_connect_type == "-scrubbers")
add_underlay_adapter(T, , node_dir, "")
add_underlay_adapter(T, , node_dir, "-supply")
add_underlay_adapter(T, node, node_dir, "-scrubbers")
else
add_underlay_adapter(T, node, node_dir, "")
add_underlay_adapter(T, , node_dir, "-supply")
add_underlay_adapter(T, , node_dir, "-scrubbers")
else
add_underlay_adapter(T, , direction, "-supply")
add_underlay_adapter(T, , direction, "-scrubbers")
add_underlay_adapter(T, , direction, "")
/obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays
if(node)
if(T.intact && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
else
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
else
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type)
/obj/machinery/atmospherics/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
Deconstruct()