Addding pipe breaking/laying system

This commit is contained in:
hobnob13
2008-08-21 05:38:21 +00:00
parent 0d2c8dd0d0
commit 4d351b222f
40 changed files with 3516 additions and 2856 deletions
+4 -11
View File
@@ -15,6 +15,8 @@
#define FLOWFRAC 0.99 // fraction of gas transfered per process
#define PRESSURELIMIT 4E9 // maximum pressure (temp*content) excess before a pipe segment takes pressure damage
//FLAGS BITMASK
#define ONBACK 1 // can be put in back slot
@@ -439,7 +441,7 @@
/obj
var/throwspeed = 0.0
var/throwing = null
var/datum/module/mod
// var/datum/module/mod
/obj/mark
var/mark = ""
@@ -1898,16 +1900,6 @@ Total SMES charging rate should not exceed total power generation rate, or an ov
desc = "<B>Sleeping Pills</B>\nAdminister as required to calm person.\nCauses 10 minutes of drowsyness. MAY induce immediate sleep.\n<B>WARNING</B>: Neurodepressant! Do not overdose!\n<B>Warning</B>: Causes drowsiness!If drowsyness persists for over 15 minutes contact medical professional."
name = "Pill Canister- 'Sleeping Pills'"
/obj/item/weapon/pipe
name = "pipe"
icon = 'pipe-item.dmi'
icon_state = "straight"
var/ptype = 0
flags = TABLEPASS|DRIVABLE|FPRINT
w_class = 4
s_istate = "pipe"
level = 2
/obj/item/weapon/prox_sensor
name = "Proximity Sensor"
icon_state = "motion0"
@@ -1953,6 +1945,7 @@ Total SMES charging rate should not exceed total power generation rate, or an ov
name = "Station Intercom (Radio)"
icon_state = "intercom"
anchored = 1.0
layer = 3.1
var/number = 0
/obj/item/weapon/radio/signaler
name = "Remote Signaling Device"
+443
View File
@@ -0,0 +1,443 @@
/*
* Pipe item
* used in constrction of pipe system; can be carried, moved, rotated, unlike static pipes
* can be laid on or underfloor; when welded, is added to the static pipe network
*/
obj/item/weapon/pipe
name = "pipe"
icon = 'pipe-item.dmi'
icon_state = "straight"
flags = TABLEPASS|DRIVABLE|FPRINT
w_class = 3
s_istate = "pipe"
level = 2
var/ptype = 0 // the type of pipe item:
// 0 1 2 3 4 5 6 7 8
//"pipe", "bent pipe", "h/e pipe", "bent h/e pipe", "connector", "manifold", "junction" vent inlet
// create a new pipe
New()
..()
update()
//update the name and icon of the pipe item depending on the type
proc/update()
var/list/nlist = list("pipe", "bent pipe", "h/e pipe", "bent h/e pipe", "connector", "manifold", "junction", "vent", "inlet")
name = nlist[ptype+1] + " fitting"
updateicon()
//update the icon of the item
proc/updateicon()
var/list/islist = list("straight", "bend", "he-straight", "he-bend", "connector", "manifold", "junction", "vent", "inlet")
icon_state = islist[ptype + 1]
if(invisibility) // true if placed under floor
icon -= rgb(0,0,0,128) // fade the icon
else
icon = initial(icon) // otherwise reset to inital icon
// called to hide or unhide a pipe
// i=true if hiding
hide(var/i)
invisibility = i ? 101 : 0 // make hidden pipe items invisible
updateicon()
//called when a turf is attacked with a pipe item
// place the pipe on the turf, setting pipe level to 1 (underfloor) if the turf is not intact
proc/turf_place(turf/T, mob/user)
if(!isturf(user.loc))
return
if(get_dist(T,user) > 1)
user.client_mob() << "You can't lay pipe at a place that far away."
return
if(!T.intact && (ptype == 2 || ptype == 3 || ptype == 6) )
user.client_mob() << "That type of pipe cannot be laid under the floor."
return
user.drop_item() // drop the pipe at the user's feet
src.loc = T
level = 2 // defaults to above floor laying
if(!T.intact)
level = 1 // if floor is not intact, make a low-level pipe
anchored = 1 // anchor the item so that it can't be dragged around if placed
// otherwise able to drag underfloor pipes into intact turfs
// called when the item is dropped
dropped(mob/user)
src.anchored = 0 // set unanchored if dropped manually. Will be set anchored if placed (above)
// rotate the pipe item clockwise
verb/rotate()
set src in view(1)
if ( usr.stat || usr.restrained() )
return
var/turf/T = src.loc
if(isturf(T) && T.intact && level==1) // if the pipe is underfloor, don't rotate
return // incase the pipe has been revaled with a t-scanner
src.dir = turn(src.dir, -90)
return
// returns the p_dir from the pipe item type and dir
proc/get_pdir()
var/flip = turn(dir, 180)
var/cw = turn(dir, -90)
var/acw = turn(dir, 90)
switch(ptype)
if(0)
return dir|flip
if(1)
return dir|cw
if(2,3)
return 0
if(4,7,8)
return dir
if(5)
return dir|cw|acw
if(6)
return flip
return 0
// return the h_dir (heat-exchange pipes) from the type and the dir
proc/get_hdir()
var/flip = turn(dir, 180)
var/cw = turn(dir, -90)
switch(ptype)
if(0,1,4,5,7,8)
return 0
if(2)
return dir|flip
if(3)
return dir|cw
if(6)
return dir
return 0
/*
// test verb
// increment through the various pipe types
verb/inc()
set src in view(1)
ptype = (ptype+1)%9
update()
*/
// attack with welding tool to lay the pipe
attackby(obj/item/weapon/W, mob/user)
var/turf/T = src.loc
if(!isturf(T)) // only do anything when located on a turf
return
if(T.intact && level==1) // if the pipe is underfloor and floor is in place, don't interact
return // in case the pipe has been revealed with a t-scanner
var/pipedir = src.get_pdir()|src.get_hdir() // all possible pipe dirs including h/e
if (istype(W, /obj/item/weapon/weldingtool) )
var/obj/item/weapon/weldingtool/WT = W
if (WT.welding && WT.weldfuel>=0)
for(var/obj/machinery/M in T) // check to make sure no other pipes conflit with this one
if(M.level == src.level) // only on same level
if( (M.p_dir & pipedir) || (M.h_dir & pipedir) ) // matches at least one direction on either type of pipe
user.client_mob() << "There is already a pipe at that location and position."
return
for(var/obj/brokenpipe/BP in T) // check for broken pipes
if(BP.level == src.level)
if(BP.p_dir & pipedir)
user.client_mob() << "The broken pipe needs to be removed first."
return
// no conflicts found
WT.weldfuel--
sleep(10)
// 0 1 2 3 4 5 6 7
//"pipe", "bent pipe", "h/e pipe", "bent h/e pipe", "connector", "manifold", "junction" vent
var/obj/machinery/pipes/P
switch(ptype)
if(0,1) // straight or bent pipe
P = new/obj/machinery/pipes(T)
P.icon_state = "[pipedir]"
P.level = level
P.update()
P.updateicon()
var/list/dirs = P.get_dirs()
P.node1 = get_machine(P.level, P.loc, dirs[1])
P.node2 = get_machine(P.level, P.loc, dirs[2])
if(2,3) // straight or bent h/e pipe
P = new/obj/machinery/pipes/heat_exch(T)
P.icon_state = "[pipedir]"
P.level = 2
P.update()
P.updateicon()
var/list/dirs = P.get_dirs()
P.node1 = get_he_machine(P.level, P.loc, dirs[1])
P.node2 = get_he_machine(P.level, P.loc, dirs[2])
if(4) // connector
var/obj/machinery/connector/C = new(T)
C.dir = src.dir
C.p_dir = src.dir
C.level = level
C.buildnodes()
setlineterm(C.node, C.vnode)
if(5) //manifold
var/obj/machinery/manifold/M = new(T)
M.dir = dir
M.p_dir = pipedir
M.level = level
M.buildnodes()
setlineterm(M.node1, M.vnode1)
setlineterm(M.node2, M.vnode2)
setlineterm(M.node3, M.vnode3)
if(6) //junctions
var/obj/machinery/junction/J = new(T)
J.dir = dir
J.p_dir = src.get_pdir()
J.h_dir = src.get_hdir()
J.level = 2
J.buildnodes()
setlineterm(J.node1, J.vnode1)
setlineterm(J.node2, J.vnode2)
if(7) // vent
var/obj/machinery/vent/V = new(T)
V.dir = src.dir
V.p_dir = src.dir
V.level = level
V.buildnodes()
setlineterm(V.node, V.vnode)
if(8) // inlet
var/obj/machinery/inlet/I = new(T)
I.dir = src.dir
I.p_dir = src.dir
I.level = level
I.buildnodes()
setlineterm(I.node, I.vnode)
// for pipe objects, now do updating of pipelines if needed
switch(ptype)
if(0,1,2,3) // new regular or or h/e pipe
// number of pipes connected to P
var/pipecon = (P.node1 && P.node1.ispipe()) + (P.node2 && P.node2.ispipe())
if(Debug) world << "Pipecon [pipecon]"
if(!pipecon) // simplest case - no connection pipes (but may be machines)
var/obj/machinery/pipeline/PL = new() // create a new pipeline
P.buildnodes(PL) // set new pipe to use new pl
PL.nodes += P // and add it
PL.numnodes = 1
PL.capmult = 2
plines += PL // and new pipeline to the global list
PL.setterm() // and ensure any connections to machines are made
PL.name = "pipeline #[plines.Find(PL)]" // set the name
else if(pipecon == 1) // single connected pipe
var/obj/machinery/pipes/CP // the connected pipe
if(P.node1 && P.node1.ispipe()) // find the connected pipe
CP = P.node1
else
CP = P.node2
var/obj/machinery/pipeline/PL = CP.pl // the pipeline we connected to
P.buildnodes(PL) // set the pipeline and nodes of any adjoining pipes
if(PL.nodes[1] == CP) // if the connected pipe is at start of line nodes list
PL.nodes.Insert(1, P) // insert new pipe into start of node list
else
PL.nodes += P // otherwise, insert it at end
PL.numnodes++
PL.capmult++
PL.setterm() // connect to any machines
CP.termination = 0 // connected pipe no longer terminal
else //(pipecon==2)
var/obj/machinery/pipes/CP1 = P.node1
var/obj/machinery/pipes/CP2 = P.node2
var/obj/machinery/pipeline/PL1 = CP1.pl
var/obj/machinery/pipeline/PL2 = CP2.pl
if(PL1 == PL2) // special case - completing a loop
// make sure to check if this works properly
P.buildnodes(PL1)
PL1.nodes += P
PL1.numnodes++
PL1.capmult++
PL1.setterm()
CP1.termination = 0
CP2.termination = 0
PL1.vnode1 = PL1 // link pipeline to self
PL1.vnode2 = PL1
else // separate pipelines
P.buildnodes(PL1)
CP1.termination = 0
CP2.termination = 0
var/list/plist
if(PL1.nodes[1] == CP1)
plist = pipelist(null, PL1.nodes[PL1.nodes.len])
else
plist = pipelist(null, PL1.nodes[1])
PL1.gas.transfer_from(PL2.gas, -1)
PL1.ngas.transfer_from(PL2.ngas, -1)
plines -= PL2
for(var/obj/machinery/pipes/OP in PL2.nodes)
OP.pl = PL1
PL1.nodes = plist
PL1.numnodes = plist.len
PL1.capmult = plist.len+1
PL1.setterm()
del(PL2)
del(src) // remove the pipe item
return
// ensure that setterm() is called for a newly connected pipeline
proc/setlineterm(var/obj/machinery/node, var/obj/machinery/vnode)
if(vnode)
if( istype(vnode, /obj/machinery/pipeline) )
var/obj/machinery/pipeline/PL = vnode
node.buildnodes(PL)
PL.setterm()
else
node.buildnodes()
// set the type and orientation of a pipe fitting to the same as the pipe object it is being created from
proc/settype(var/obj/machinery/M)
if(istype(M, /obj/machinery/pipes)) // is a type of pipe
ptype = 0 // the base pipe type
var/pipedir = M.p_dir
if(istype(M, /obj/machinery/pipes/heat_exch)) //if a h/e pipe
pipedir = M.h_dir // pipedirs form h_dir
ptype = 2 // base pipetype is 2
switch(pipedir) // find the pipe orientation and type from the pipe dirs
if(3) // straight N-S
dir = SOUTH
if(12) // straight E-W
dir = EAST
if(5) // bent N-E
dir = NORTH
ptype++
if(6) // bent E-S
dir = EAST
ptype++
if(10) // bent S-W
dir = SOUTH
ptype++
if(9) // bent W-N
dir = WEST
ptype++
else if(istype(M, /obj/machinery/connector))
ptype = 4
dir = M.dir
else if(istype(M, /obj/machinery/manifold))
ptype = 5
dir = M.dir
else if(istype(M, /obj/machinery/junction))
ptype = 6
dir = M.h_dir // junction h/e pipe is always in object direction
else if(istype(M, /obj/machinery/vent))
ptype = 7
dir = M.dir
else if(istype(M, /obj/machinery/inlet))
ptype = 8
dir = M.dir
update()
+2
View File
@@ -29,6 +29,8 @@ obj/machinery/power/apc
anchored = 1
netnum = -1 // Always -1, set so that APCs aren't found as powernet nodes
// instead, all connections are done through the associated terminal object
layer = 3.1 // slightly above standard obj layer
var
area/area // the area that this APC controls
obj/item/weapon/cell/cell // the power cell object inserted in this APC (or null if none)
+2 -2
View File
@@ -55,7 +55,7 @@ obj/machinery/power/solar_control
icon_state = "solar_con"
overlays = null
if(cdir > 0)
overlays += image('enginecomputer.dmi', "solcon-o", FLY_LAYER, cdir)
overlays += image('enginecomputer.dmi', "solcon-o[cdir]", FLY_LAYER)
// Attack by AI, open interaction window
@@ -168,7 +168,7 @@ obj/machinery/power/solar_control
if (usr.stat || usr.restrained() )
return
if ((!( istype(usr, /mob/human) ) && (!( ticker ) || (ticker && ticker.mode != "monkey"))))
if (!istype(usr, /mob/ai))
if (!istype(usr, /mob/ai))
if (!istype(usr, /mob/drone))
usr.client_mob() << "\red You don't have the dexterity to do this!"
return
+1 -1
View File
@@ -18,7 +18,7 @@ obj/machinery
capmult = 0 // used for gas flow - a capacity multiplier
stat = 0 // machinery status bitflags
// currently used values: 1 - BROKEN ; 2 - NOPOWER
// currently used values: 1 - BROKEN ; 2 - NOPOWER ; 8 - MAINT
// New() and Del() add and remove machines from the global "machines" list
+37 -1
View File
@@ -91,6 +91,10 @@
for(var/obj/machinery/M in T.contents)
if(M.level == level)
if(M.p_dir & flip)
var/obj/machinery/pipes/P = M
if(istype(P))
if (P.stat & BROKEN)
continue
return M
return null
@@ -108,6 +112,10 @@
for(var/obj/machinery/M in T.contents)
if(M.level == level)
if(M.h_dir & flip)
var/obj/machinery/pipes/P = M
if(istype(P))
if (P.stat & BROKEN)
continue
return M
return null
@@ -164,4 +172,32 @@
sngas.turf_take(T, delta_gt) // grab gas from turf and direcly add it to the new gas
T.res_vars() // update turf gas vars for both cases
T.res_vars() // update turf gas vars for both cases
// Called by all pipe-related objects (except pipes themselves) when attack with a weldingtool
// Create the relevant pipe fitting item from the pipe object
// Returns true if succeeded, false otherwise
/obj/machinery/proc/attack_welder(obj/item/weapon/weldingtool/WT, mob/user)
if(WT.welding)
if(WT.weldfuel > 3)
WT.weldfuel -=3
user << "\blue Removing the [name]. Stand still as this takes some time."
var/turf/T = user.loc
sleep(50)
if ((user.loc == T && user.equipped() == WT))
// make pipe fitting
var/obj/item/weapon/pipe/P = new(src.loc)
P.settype(src)
return 1
else
user << "\blue You need more welding fuel to remove the [name]."
return 0
+1 -1
View File
@@ -8,7 +8,7 @@ obj/machinery/alarm
icon = 'stationobjs.dmi'
icon_state = "alarm:0"
anchored = 1.0
layer = 3.1
// Monitors location air quality and changes icon_state to reflect it
+5 -1
View File
@@ -59,7 +59,7 @@ obj/machinery/autolathe
attack_ai(mob/user)
return src.attack_hand(user)
// Open interaction window
// Currenty only pipe pieces can be made
attack_hand(mob/user)
@@ -82,6 +82,7 @@ obj/machinery/autolathe
L["manif"] = "Pipe manifold (15000 cc)"
L["junct"] = "Pipe junction (10000 cc)"
L["vent"] = "Pipe vent (10000 cc)"
L["inlet"] = "Pipe inlet (10000 cc)"
if (config.enable_drones)
L["drone"] = "Robot drone (150,000 cc)"
/* L["screwdriver"] = "Make Screwdriver {40 cc}"
@@ -135,6 +136,7 @@ obj/machinery/autolathe
C["manif"] = 15000
C["junct"] = 10000
C["vent"] = 10000
C["inlet"] = 10000
if (config.enable_drones)
C["drone"] = 150000
@@ -161,6 +163,8 @@ obj/machinery/autolathe
new /obj/item/weapon/pipe{ ptype = 6 }(src.loc)
if("vent")
new /obj/item/weapon/pipe{ ptype = 7 }(src.loc)
if("inlet")
new /obj/item/weapon/pipe{ ptype = 8 }(src.loc)
if("drone")
if (config.enable_drones)
var/mob/drone/drone = new /mob/drone(src.loc)
+11 -15
View File
@@ -62,25 +62,21 @@ obj/machinery/circulator
buildnodes()
var/turf/TS = get_step(src, SOUTH)
var/turf/TN = get_step(src, NORTH)
var/turf/T = src.loc
for(var/obj/machinery/M in TS)
if(M && (M.p_dir & 1))
node1 = M
break
for(var/obj/machinery/M in TN)
if(M && (M.p_dir & 2))
node2 = M
break
node1 = get_machine(level, T, SOUTH)
node2 = get_machine(level, T, NORTH)
if(node1) vnode1 = node1.getline()
if(node1)
vnode1 = node1.getline()
else
vnode1 = null
if(node2) vnode2 = node2.getline()
if(node2)
vnode2 = node2.getline()
else
vnode2 = null
// Set the current status and pumping rate (as a percentage)
+18 -8
View File
@@ -53,15 +53,12 @@
buildnodes()
var/turf/T = get_step(src.loc, src.dir)
var/fdir = turn(src.p_dir, 180)
node = get_machine(level, src.loc, dir)
for(var/obj/machinery/M in T)
if(M.p_dir & fdir)
src.node = M
break
if(node) vnode = node.getline()
if(node)
vnode = node.getline()
else
vnode = null
return
@@ -135,3 +132,16 @@
if(T && !T.density)
flow_to_turf(gas, ngas, T)
// Attack by item
// If welder, make a fitting and delete self
attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/weldingtool))
if(attack_welder(W, user))
if(connected)
connected.anchored = 0 // if connected equipment, unanchor it before deleting the connector
del(src)
else
..()
+6 -3
View File
@@ -65,7 +65,10 @@ obj/machinery/cryo_cell
line_in = get_machine(level, T, p_dir )
if(line_in) vnode = line_in.getline()
if(line_in)
vnode = line_in.getline()
else
vnode = null
@@ -203,7 +206,7 @@ obj/machinery/cryo_cell
if (stat & NOPOWER) return
if ((!( istype(G, /obj/item/weapon/grab) ) || !( ismob(G.affecting) )))
return
return
var/result = src.canReach(user, null, 1)
if (result==0)
user.client_mob() << "You can't reach [src]."
@@ -473,4 +476,4 @@ obj/machinery/cryo_cell
allow_drop()
return 0
*/
*/
+1
View File
@@ -9,6 +9,7 @@ obj/machinery/firealarm
icon = 'items.dmi'
icon_state = "firealarm"
anchored = 1
layer = 3.1 // slightly above standard obj layer
var
detecting = 1 // true if the alarm is working, false if disabled
//working = 1 // unused
+7 -4
View File
@@ -61,7 +61,10 @@ obj/machinery/freezer
line_out = get_machine(level, T, p_dir )
if(line_out) vnode = line_out.getline() // the pipeline associated with the pipe
if(line_out)
vnode = line_out.getline() // the pipeline associated with the pipe
else
vnode = null
// Update gas levels with the new levels calculated in process()
@@ -99,7 +102,7 @@ obj/machinery/freezer
attack_paw(mob/user)
return src.attack_hand(user)
// AI interact
attack_ai(mob/user)
return src.attack_hand(user)
@@ -175,11 +178,11 @@ obj/machinery/freezer
Topic(href, href_list)
..()
if ((!( istype(usr, /mob/human) ) && (!( ticker ) || (ticker && ticker.mode != "monkey"))))
if (!istype(usr, /mob/ai))
if (!istype(usr, /mob/ai))
usr.client_mob() << "\red You don't have the dexterity to do this!"
return
if ((usr.stat || usr.restrained()))
if (!istype(usr, /mob/ai))
if (!istype(usr, /mob/ai))
return
if ((usr.contents.Find(src) || (get_dist(src, usr) <= 1 && istype(src.loc, /turf))))
usr.machine = src
+23 -16
View File
@@ -42,15 +42,12 @@ obj/machinery/inlet
buildnodes()
var/turf/T = get_step(src.loc, src.dir)
var/fdir = turn(src.p_dir, 180)
node = get_machine(level, src.loc, dir)
for(var/obj/machinery/M in T)
if(M.p_dir & fdir)
src.node = M
break
if(node) vnode = node.getline()
if(node)
vnode = node.getline()
else
vnode = null
return
@@ -101,6 +98,18 @@ obj/machinery/inlet
flow_to_turf(gas, ngas, T)
// Attack by item
// If welder, make a fitting and delete self
attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/weldingtool))
if(attack_welder(W, user))
del(src)
else
..()
//Filtration Procs for Filtered Inlet
/obj/machinery/proc
@@ -328,19 +337,17 @@ obj/machinery/inletfiltered
buildnodes()
var/turf/T = get_step(src.loc, src.dir)
var/fdir = turn(src.p_dir, 180)
node = get_machine(level, src.loc, dir)
for(var/obj/machinery/M in T)
if(M.p_dir & fdir)
src.node = M
break
if(node) vnode = node.getline()
if(node)
vnode = node.getline()
else
vnode = null
return
// Returns the gas fullness value. Capmult is 2 for inlets because they in effect have two connections: the pipe, and the turf
get_gas_val(from)
+13 -3
View File
@@ -5,7 +5,7 @@
obj/machinery/junction
name = "junction"
icon = 'junct-pipe.dmi'
icon = 'pipes.dmi'
icon_state = "junction"
desc = "A junction between regular and heat-exchanger pipework."
anchored = 1
@@ -49,8 +49,8 @@ obj/machinery/junction
node2 = get_machine(level, T , p_dir ) // the regular pipe
if(node1) vnode1 = node1.getline()
if(node2) vnode2 = node2.getline()
vnode1 = node1 ? node1.getline() : null
vnode2 = node2 ? node2.getline() : null
return
@@ -111,3 +111,13 @@ obj/machinery/junction
flow_to_turf(gas, ngas, T)
// Attack by item
// If welder, make a fitting and delete self
attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/weldingtool))
if(attack_welder(W, user))
del(src)
else
..()
+1
View File
@@ -11,6 +11,7 @@ obj/machinery/light_switch
icon = 'power.dmi'
icon_state = "light1"
anchored = 1.0
layer = 3.1
var
on = 1 // true if currently switched on
area/area = null // holds the area object that this switch controls
+13 -3
View File
@@ -74,9 +74,9 @@ obj/machinery/manifold
node2 = get_machine( level, T , n2dir )
if(node1) vnode1 = node1.getline()
if(node2) vnode2 = node2.getline()
if(node3) vnode3 = node3.getline()
vnode1 = node1 ? node1.getline() : null
vnode2 = node2 ? node2.getline() : null
vnode3 = node3 ? node3.getline() : null
return
@@ -146,3 +146,13 @@ obj/machinery/manifold
// Attack by item
// If welder, make a fitting and delete self
attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/weldingtool))
if(attack_welder(W, user))
del(src)
else
..()
+40 -4
View File
@@ -3,6 +3,7 @@
*
* The meter actually reads a moving average of the flow var of the pipeline object associated with the pipe.
* Note that the value can be negative if the flow is going through the pipe "backwards"
* If attacked by a wrench, try to locate a working pipe again
*
* TODO: Add an icon overlay showing the actual movement direction of the gas.
*/
@@ -15,6 +16,7 @@ obj/machinery/meter
var
obj/machinery/pipes/target = null // the pipe object to monitor
average = 0 // the exponential moving average of the flow rate
alarm = 0 // true if pressure alarm is being shown
@@ -34,20 +36,32 @@ obj/machinery/meter
process()
if(!target)
if(!target || !target.pl)
icon_state = "meterX"
overlays = null
return
if(stat & NOPOWER)
icon_state = "meter0"
return
var/obj/machinery/pipeline/line = target.pl
use_power(5)
average = 0.5 * average + 0.5 * target.pl.flow
average = 0.5 * average + 0.5 * line.flow
var/val = min(18, round( 18.99 * ((abs(average) / 2500000)**0.25)) )
icon_state = "meter[val]"
var/pressure = line.gas.tot_gas() / line.numnodes * line.gas.temperature
if(alarm)
if(pressure < PRESSURELIMIT)
overlays = null
alarm = 0
else
if(pressure > PRESSURELIMIT)
overlays += image('pipes.dmi', "meter-o")
alarm = 1
// If the meter is clicked on, report the flow rate and temperature of the gas
@@ -55,16 +69,38 @@ obj/machinery/meter
var/mob/user = usr
if (user.currentDrone!=null)
user = user.currentDrone
if (get_dist(user, src) <= 3)
if (src.target)
user.client_mob() << text("\blue <B>Results:\nMass flow []%\nTemperature [] K</B>", round(100*abs(average)/6e6, 0.1), round(target.pl.gas.temperature,0.1))
user.client_mob() << "\blue <B>Results:\nMass flow [round(100*abs(average)/6e6, 0.1)]%\nTemperature [round(target.pl.gas.temperature,0.1)] K</B>"
if(alarm)
user.client_mob() << "\red <B>Warning! Pressure approaching pipe fracture limit!</B>"
else
user.client_mob() << "\blue <B>Results: Connection Error!</B>"
else
user.client_mob() << "\blue <B>You are too far away.</B>"
return
// Attack with weapon
// if a wrench, try to find pipe at same location and activate
attackby(var/obj/item/weapon/W, mob/user)
if(!target && istype(W, /obj/item/weapon/wrench))
target = locate(/obj/machinery/pipes, src.loc)
average = 0
if(target)
user.client_mob() << "\blue The meter has been attached to the pipe."
var/turf/T = src.loc // make sure meter is on top of pipe
src.loc = null
src.loc = T
else
..()
// Disabled routines
/*
+22 -1
View File
@@ -44,6 +44,16 @@ obj/machinery/pipeline // logical pipeline consisting of multiple /obj/machin
gasflowlist += src
// Delete a pipeline, remove from gasflowlist and pipeline list
Del()
gasflowlist -= src
plines -= src
..()
// Sets the vnode1 & vnode2 values to the machines connected at each end of the pipe
// Also orientates the pipes in the node list so that for each pipe, node1 points to previous entry, and node2 points to next
@@ -109,7 +119,8 @@ obj/machinery/pipeline // logical pipeline consisting of multiple /obj/machin
// Timed process for the pipeline.
// First do heat-exchange for every node in this pipeline
// The do standard gas flow from each end of the pipeline.
// Also check for overpressure condition
// Then do standard gas flow from each end of the pipeline.
// Also update "flow" variable to show rate of flow through the complete pipeline.
process()
@@ -128,6 +139,16 @@ obj/machinery/pipeline // logical pipeline consisting of multiple /obj/machin
P.heat_exchange(ngas, tot_node, numnodes, gtemp) // exchange heat with its turf
// check for pressure breakage
if( tot_node * gtemp > PRESSURELIMIT)
var/obj/machinery/pipes/P = pick(nodes) // pick a random pipe segment to damage
var/turf/PT = P.loc
if( (tot_node * gtemp - PT.pressure()) > PRESSURELIMIT )
P.health--
P.healthcheck()
// now do standard gas flow proc
var/delta_gt
+285 -38
View File
@@ -4,16 +4,17 @@
* Pipes do not directly contain gas, but unbroken chains of pipes are assembled into /obj/machinery/pipeline objects
* Pipelines contain a single gas reservoir that encompass all the gas that would be each individual pipe.
*
* TODO: Complete routines for pipe disassembly, damage, and exploding under pressure.
* TODO: Finalize method of showing broken pipes & pipe ends.
* TODO: Implement some method of capacity regulation
*/
#define MAXPIPEHEALTH 10 // the starting health value of each pipe
obj/machinery/pipes
name = "pipes"
icon = 'reg_pipe.dmi'
icon_state = "12"
anchored = 1
desc = "A regular pipe."
/* var/p_dir - inherited from /obj/machinery, is a bitfield of directions of pipe connections from this one */
@@ -25,7 +26,7 @@ obj/machinery/pipes
insulation = NORMPIPERATE // lower insulation value means pipe temperature is exchanged with turf at a faster rate
obj/machinery/pipeline/pl // the pipeline object which contains this pipe
health = 10 // the health of the pipe (not yet implemented)
health = MAXPIPEHEALTH // the health of the pipe
// Create a new pipe, and update the p_dir according to the icon_state.
@@ -62,6 +63,9 @@ obj/machinery/pipes
node1 = get_machine(level, src.loc, dirs[1])
node2 = get_machine(level, src.loc, dirs[2])
if(!line) // If no pipeline was specified, just needed to revalidate the local nodes
return
if(pl) // If the pipeline is already set, there is no need to propagate anymore
return
@@ -162,6 +166,30 @@ obj/machinery/pipes
return list(dirs[2], dirs[1]) // otherwise swap order
// examine verb - show description and amount of damage
examine()
set src in view(1)
if(usr && !usr.stat)
usr.client_mob() << "[desc] The pipe is [damagetext()][(stat & MAINT)?" and the flanges are unfastened.":"."]"
// return text description of the damage state of the pipe
// used in examine verb and when repairing
proc/damagetext()
if(health == MAXPIPEHEALTH)
return "undamaged"
if(health > 0.7*MAXPIPEHEALTH)
return "slightly damaged"
if(health > 0.3*MAXPIPEHEALTH)
return "damaged"
else
return "badly damaged"
// Update the icon_state and overlays
// Depends on pipe level and visibility, broken status, and whether this is an unterminated end of a pipe
@@ -171,9 +199,6 @@ obj/machinery/pipes
var/is = "[p_dir]"
if(stat & BROKEN)
is += "-b"
// Set invisibility status depending on whether this pipe is below floor level
// Also sets a faded (alpha blended) icon_state for the pipe so it can be shown with a T-scanner
@@ -187,20 +212,21 @@ obj/machinery/pipes
src.icon_state = is
// If either node is null, this is an unterminated pipe
// unless a matching broken pipe is present
// Show special overlays to indicate this
var/list/dirs = get_node_dirs()
overlays = null
if(!node1 && !node2) // neither end of pipe is connected
overlays += image('pipes.dmi', "discon", FLY_LAYER, dirs[1])
overlays += image('pipes.dmi', "discon", FLY_LAYER, dirs[2])
else if(!node1) // node1 is not connected
overlays += image('pipes.dmi', "discon", FLY_LAYER, dirs[1])
if(!node1) // node1 is not connected
if(!findbrokenpipe(T, dirs[1], level, 0)) // no broken pipe present
overlays += image('pipes.dmi', "discon[dirs[1]]", FLY_LAYER)
else if(!node2) // node2 is not connected
overlays += image('pipes.dmi', "discon", FLY_LAYER, dirs[2])
if(!findbrokenpipe(T, dirs[2], level, 0)) // no broken pipe present
overlays += image('pipes.dmi', "discon[dirs[2]]", FLY_LAYER)
return
@@ -243,38 +269,258 @@ obj/machinery/pipes
// Routines to allow cutting and damage of pipes
// Not yet implemented
/*
attackby(obj/item/weapon/W, mob/user)
if (istype(W, /obj/item/weapon/weldingtool))
if (istype(W, /obj/item/weapon/wrench))
if(stat & MAINT)
stat &= ~MAINT
user.client_mob() << "\blue You fasten the pipe flanges."
else
stat |= MAINT
user.client_mob() << "\blue You unfasten the pipe flanges. The pipe can now be cut."
else if (istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(WT.welding && WT.weldfuel > 3)
WT.weldfuel -=3
if(WT.welding)
user.client_mob() << "\blue Cutting the pipe. Stand still as this takes some time."
var/turf/T = user.loc
sleep(50)
if(stat & MAINT)
if(WT.weldfuel > 3)
WT.weldfuel -=3
if ((user.loc == T && user.equipped() == W))
user.client_mob() << "\blue Cutting the pipe. Stand still as this takes some time."
var/turf/T = user.loc
sleep(50)
if ((user.loc == T && user.equipped() == W))
// make pipe fitting
var/obj/item/weapon/pipe/P = new(src.loc)
P.settype(src)
del(src)
else
user.client_mob() << "\blue You need more welding fuel to cut the pipe."
else
if(health < MAXPIPEHEALTH)
if(WT.weldfuel > 1)
WT.weldfuel--
user.client_mob() << "\blue Repairing the pipe."
sleep(5)
health = min(health+MAXPIPEHEALTH/10, MAXPIPEHEALTH)
user.client_mob() << "\blue The pipe is now [damagetext()]."
healthcheck()
return
else
user.client_mob() << "\blue You need more welding fuel to repair the pipe."
else
user.client_mob() << "You cannot repair the pipe as it is undamaged."
return
// make pipe fitting
sleep(1)
else
var/aforce = W.force
var/aforce = round(W.force/10+0.5,1)
src.health = max(0, src.health - aforce)
healthcheck()
..()
return
proc/healthcheck()
//if(health<1)
// pipe effected by an explosion
ex_act(severity)
switch(severity)
if(1.0)
del(src)
return
if(2.0)
health -= rand(MAXPIPEHEALTH*0.5,MAXPIPEHEALTH*1.5)
healthcheck()
return
if(3.0)
health -= rand(0,MAXPIPEHEALTH*1.5)
healthcheck()
return
// pipe is in a fire
burn(fi_amount)
if(fi_amount > 1800000)
var/turf/T = src.loc
if(prob(5) && T.temp > 1600) // if turf temp exceeds pipe melting point, take damage
health -= round( T.temp/1500) // damage depends on the actual temperature
healthcheck()
/*
// test verb - destroy a pipe
verb/destroy()
set src in view()
health=0
healthcheck()
*/
// Check the pipe hp, and break it if low enough
proc/healthcheck()
if(health<=0) // check health, if low enough
health = 0 // break the pipe
breakpipe()
// break a pipe
// create a broken pipe object in place, then delete this pipe
// pipe Del() proc handles updating of the containing pipeline
proc/breakpipe()
if(!isturf(src.loc)) // sanity check
return
// create the broken pipe object
var/obj/brokenpipe/BP = new(src.loc) // in same loc as original
BP.update(src) // update brokenpipe vars from this pipe
// deletes the pipe segement
del(src)
// Delete the pipe
// must handle updating of the containing pipeline object
// three possible cases:
// pipe is the only node in a line -> delete the line
// pipe is at one end of a line -> shorten the line
// pipe is in the middle of a line -> split the line into two pieces
// also handle redistribution of gas in the pipeline(s)
Del()
var/obj/machinery/pipeline/line = pl
var/turf/T = src.loc
if(!pl || !isturf(T)) // sanity check
return ..() // just delete
var/linepos = line.nodes.Find(src) // the position of this pipe in the pipeline
if(linepos == 1 && line.numnodes == 1) // single pipe pipeline
// no other nodes in the pipeline, so remove it completely
line.gas.leak(T) // dump all gas in line into turf
src.pl = null
// update linked machines to reflect new status
if(line.vnode1)
line.vnode1.buildnodes()
if(line.vnode2)
line.vnode2.buildnodes()
line.nodes -= src // remove reference to this pipe object (to prevent infinite loop)
del(line) // remove the line
else if(linepos == 1 || linepos == line.numnodes) // pipe was at one end of pipeline
var/obj/substance/gas/G = new() // temporary holder for gas
G.transfer_from(line.gas, line.gas.tot_gas() / line.numnodes) // transfer gas from line to temp
G.leak(T) // dump fraction of line gas into turf
line.nodes -= src
line.numnodes--
line.capmult = 1 + line.numnodes
src.loc = null
line.ngas.replace_by(line.gas)
// now update line and connected machines links between nodes
if(linepos == 1) // pipe at start of pipeline
if(line.vnode1) line.vnode1.buildnodes()
var/obj/machinery/pipes/P = line.nodes[1]
P.buildnodes(null) // rebuild the local nodes of the next pipe
line.vnode1 = null
else // pipe at end of pipeline
if(line.vnode2) line.vnode2.buildnodes()
var/obj/machinery/pipes/P = line.nodes[line.numnodes]
P.buildnodes(null) // rebuild the local nodes of the next pipeline
line.vnode2 = null
else // pipe is somewhere in middle of pipeline - split into two
//world << "total : [line.gas.tot_gas()]"
//world << "pos [linepos] of [line.numnodes]"
var/linenodes = line.numnodes
var/obj/machinery/pipeline/newline = new()
newline.nodes = line.nodes.Copy(linepos+1)
line.nodes.Cut(linepos)
line.numnodes = linepos-1
line.capmult = 1 + line.numnodes
newline.numnodes = newline.nodes.len
plines += newline
newline.name = "pipeline #[plines.len]"
newline.capmult = 1 + newline.numnodes
for(var/obj/machinery/pipes/P in newline.nodes)
P.pl = newline
src.loc = null
src.node1.buildnodes(null)
src.node2.buildnodes(null)
line.setterm()
newline.setterm()
// transfer fraction of gas which will be in second line
newline.gas.transfer_from(line.gas, line.gas.tot_gas() * (linenodes - linepos ) / linenodes)
//world << "in 1([line.name]): [line.gas.tot_gas()]"
//world << "in 2([newline.name]): [newline.gas.tot_gas()]"
var/obj/substance/gas/G = new()
G.transfer_from(line.gas, line.gas.tot_gas() / (line.numnodes+1))
//world << "to turf: [G.tot_gas()]"
G.leak(T) // dump pipe's share of gas into the turf
line.ngas.replace_by(line.gas)
newline.ngas.replace_by(newline.gas)
//world << "in 1([line.name]): [line.gas.tot_gas()]"
..() // perform actual deletion of pipe object
/*
* Heat_exch - Heat-exchange pipe subtype. Same as a standard pipe, but uses different icon, has lower insulation value
@@ -300,25 +546,23 @@ obj/machinery/pipes
updateicon()
var/turf/T = src.loc
var/list/dirs = get_node_dirs()
var/is = "[h_dir]"
if(stat & BROKEN)
is += "-b"
src.icon_state = is
overlays = null
if(!node1 && !node2)
overlays += image('pipes.dmi', "discon-he", FLY_LAYER, dirs[1])
overlays += image('pipes.dmi', "discon-he", FLY_LAYER, dirs[2])
else if(!node1)
overlays += image('pipes.dmi', "discon-he", FLY_LAYER, dirs[1])
else if(!node2)
overlays += image('pipes.dmi', "discon-he", FLY_LAYER, dirs[2])
return
if(!node1) // node1 is not connected
if(!findbrokenpipe(T, dirs[1], level, 1)) // no broken pipe present
overlays += image('pipes.dmi', "discon-he[dirs[1]]", FLY_LAYER)
else if(!node2) // node2 is not connected
if(!findbrokenpipe(T, dirs[2], level, 1)) // no broken pipe present
overlays += image('pipes.dmi', "discon-he[dirs[2]]", FLY_LAYER)
// Return list of directions corresponding to h_dir bitflags
@@ -349,6 +593,9 @@ obj/machinery/pipes
node1 = get_he_machine(level, src.loc, dirs[1])
node2 = get_he_machine(level, src.loc, dirs[2])
if(!line)
return
if(pl)
return
+1
View File
@@ -11,6 +11,7 @@ obj/machinery/sec_lock
icon = 'stationobjs.dmi'
icon_state = "sec_lock"
anchored = 1.0
layer = 3.1
var
obj/item/weapon/card/id/scan = null // the inserted ID card
+4 -4
View File
@@ -63,12 +63,12 @@ obj/machinery/valve
var/turf/T = src.loc
node1 = get_machine(level, T, dir ) // the h/e pipe
node1 = get_machine(level, T, dir )
node2 = get_machine(level, T , turn(dir, 180) ) // the regular pipe
node2 = get_machine(level, T , turn(dir, 180) )
if(node1) vnode1 = node1.getline()
if(node2) vnode2 = node2.getline()
vnode1 = node1 ? node1.getline() : null
vnode2 = node2 ? node2.getline() : null
return
+16 -24
View File
@@ -37,15 +37,9 @@ obj/machinery/vent
// Find the connected machine or pipe to the vent pipe.
buildnodes()
var/turf/T = get_step(src.loc, src.dir)
var/fdir = turn(src.p_dir, 180)
for(var/obj/machinery/M in T)
if(M.p_dir & fdir)
src.node = M
break
if(node) vnode = node.getline()
node = get_machine(level, src.loc, dir)
vnode = node ? node.getline() : null
return
@@ -92,6 +86,16 @@ obj/machinery/vent
flow_to_turf(gas, ngas, T)
// Attack by item
// If welder, make a fitting and delete self
attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/weldingtool))
if(attack_welder(W, user))
del(src)
else
..()
obj/machinery/emergencyrelease
@@ -127,15 +131,9 @@ obj/machinery/emergencyrelease
// Find the connected machine or pipe to the vent pipe.
buildnodes()
var/turf/T = get_step(src.loc, src.dir)
var/fdir = turn(src.p_dir, 180)
for(var/obj/machinery/M in T)
if(M.p_dir & fdir)
src.node = M
break
if(node) vnode = node.getline()
node = get_machine(level, src.loc, dir)
vnode = node ? node.getline() : null
return
@@ -235,15 +233,9 @@ obj/machinery/regulator
// Find the connected machine or pipe to the vent pipe.
buildnodes()
var/turf/T = get_step(src.loc, src.dir)
var/fdir = turn(src.p_dir, 180)
for(var/obj/machinery/M in T)
if(M.p_dir & fdir)
src.node = M
break
if(node) vnode = node.getline()
node = get_machine(level, src.loc, dir)
vnode = node ? node.getline() : null
return
+122
View File
@@ -0,0 +1,122 @@
/*
* Broken Pipe -- a broken pipe object
*
* This object is substituted for a /obj/machinery/pipes object when it is broken
*
* TODO: make removable and/or repairable
*
*/
obj/brokenpipe
name = "a broken pipe"
icon = 'reg_pipe.dmi'
icon_state = "12-b"
anchored = 1
var/p_dir = 0 // the p_dir or h_dir of the original pipe
var/ptype = 0 // pipe type of orginal pipe
// 0 = regular, 1 = h/e
// Create a new broken pipe,
New()
..()
updateicon()
// Set the state of the brokenpipe
// Copies data from the original pipe object
proc/update(var/obj/machinery/pipes/P)
ptype = 0 // defaults for regular pipe
p_dir = P.p_dir
if(istype(P, /obj/machinery/pipes/heat_exch)) // h/e pipe
ptype = 1
p_dir = P.h_dir
level = P.level
updateicon()
// Update the broken pipe icon depending on the pipe dirs and type
proc/updateicon()
var/is
switch(ptype)
if(0)
icon = 'reg_pipe.dmi'
is = "[p_dir]-b"
if(1)
icon = 'heat_pipe.dmi'
is = "[p_dir]-b"
var/turf/T = src.loc
if ((src.level == 1 && isturf(T) && T.intact))
src.invisibility = 101
is += "-f"
else
src.invisibility = null
icon_state = is
return
// Called when a pipe is revealed or hidden when a floor tile is removed, etc.
// Just call updateicon(), since all is handled there already
hide(var/i)
updateicon()
// attack with item
// if welder, delete the pipe
attackby(obj/item/weapon/W, mob/user)
if (istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(WT.welding)
if(WT.weldfuel > 2)
WT.weldfuel -=2
user.client_mob() << "\blue Removing the broken pipe. Stand still as this takes some time."
var/turf/T = user.loc
sleep(30)
if ((user.loc == T && user.equipped() == W))
del(src)
else
user.client_mob() << "\blue You need more welding fuel to remove the pipe."
else
..()
return
// Global proc - look for a matching broken pipe
// step direction dirn from turf OT
// must match level and ptype
// returns true if found, false otherwise
proc/findbrokenpipe(var/turf/OT, var/dirn, var/lev, var/pipetype)
var/turf/T = get_step(OT, dirn) // look in this turf
var/flipdir = turn(dirn,180) // for brokenpipe matching this pdir
for(var/obj/brokenpipe/BP in T)
if(BP.p_dir & flipdir)
if(BP.level == lev && BP.ptype == pipetype)
return 1 // found a matching brokenpipe
return 0 // found no match
+13
View File
@@ -472,4 +472,17 @@
//Pops up the take-off / put-on dialog, but for yourself.
/mob/human/proc/ShowMyInv()
set category = "Debug"
src.show_inv(src)
// Show all admins
/mob/verb/Admins()
set category = "Debug"
for(var/A in admins)
world << "[A] = [admins[A]]"
/mob/verb/plasma()
set category = "Debug"
new /obj/machinery/atmoalter/canister/poisoncanister(src.loc)
+4
View File
@@ -895,6 +895,10 @@ turf/proc/tot_old_gas()
/turf/proc/tot_tmp_gas()
return tmpco2 + tmpoxy + tmppoison + tsl_gas + tn2
// return the "pressure" of a turf
/turf/proc/pressure()
return src.tot_gas() * src.temp
// return the gas contents of a turf as a gas obj
+1 -3
View File
@@ -82,7 +82,6 @@
return
/obj/substance/proc/leak(turf)
return
/obj/substance/chemical/proc/volume()
@@ -219,10 +218,9 @@ heat is conserved between exchanges
#define TURF_ADD_FRAC 0.95 //cooling due to release of gas into tile
#define TURF_TAKE_FRAC 1.06 //heating due to pressurization into pipework
// Not used?
/obj/substance/gas/leak(T as turf)
turf_add(T, src.co2 + src.oxygen + src.plasma + src.n2)
turf_add(T, -1)
return
+7 -2
View File
@@ -170,9 +170,10 @@
step(user.pulling, get_dir(user.pulling.loc, src))
return
/turf/space/attackby(obj/item/weapon/tile/T as obj, mob/user as mob)
/turf/space/attackby(obj/item/weapon/W, mob/user)
if (istype(T, /obj/item/weapon/tile))
if (istype(W, /obj/item/weapon/tile))
var/obj/item/weapon/tile/T = W
T.build(src)
T.amount--
T.add_fingerprint(user)
@@ -180,6 +181,10 @@
user.u_equip(T)
del(T)
return
else if (istype(W, /obj/item/weapon/pipe) )
var/obj/item/weapon/pipe/pipe = W
if(locate(/obj/lattice) in src)
pipe.turf_place(src, user)
return
/turf/space/updatecell()
+1 -1
View File
@@ -23,7 +23,7 @@
dat += variable(usr, V, D.vars[V]) //get the text for that variable
dat += "</BODY>"
usr.client_mob() << browse(dat, "window=\ref[D]") // display the browser pop-up
usr << browse(dat, "window=\ref[D]") // display the browser pop-up
// return a HTML formatted string displaying a variable
+4
View File
@@ -2610,6 +2610,10 @@
else if (istype(C, /obj/item/weapon/cable_coil) )
var/obj/item/weapon/cable_coil/coil = C
coil.turf_place(src, user)
else if (istype(C, /obj/item/weapon/pipe) )
var/obj/item/weapon/pipe/pipe = C
pipe.turf_place(src, user)
return
/turf/station/floor/unburn()
-352
View File
@@ -77,358 +77,6 @@
// pipe item
// used in constrction of pipe system; can be carried, moved, rotated, unlike static pipes
// does not carry gas at this time
/obj/item/weapon/pipe/New()
..()
update()
//update the name and icon of the pipe item depending on the type
/obj/item/weapon/pipe/proc/update()
var/list/nlist = list("pipe", "bent pipe", "h/e pipe", "bent h/e pipe", "connector", "manifold", "junction", "vent")
name = nlist[ptype+1] + " fitting"
updateicon()
//update the icon of the item
/obj/item/weapon/pipe/proc/updateicon()
var/list/islist = list("straight", "bend", "he-straight", "he-bend", "connector", "manifold", "junction", "vent")
icon_state = islist[ptype + 1]
if(invisibility) // true if placed under floor
icon -= rgb(0,0,0,128) // fade the icon
else
icon = initial(icon) // otherwise reset to inital icon
// called to hide or unhide a pipe
// i=true if hiding
/obj/item/weapon/pipe/hide(var/i)
invisibility = i ? 101 : 0 // make hidden pipe items invisible
updateicon()
//called when a turf is attacked with a pipe item
// place the pipe on the turf, setting pipe level to 1 (underfloor) if the turf is not intact
/obj/item/weapon/pipe/proc/turf_place(turf/T, mob/user)
if(!isturf(user.loc))
return
if(get_dist(T,user) > 1)
user.client_mob() << "You can't lay pipe at a place that far away."
return
if(!T.intact && (ptype == 2 || ptype == 3 || ptype == 6) )
user.client_mob() << "That type of pipe cannot be laid under the floor."
return
user.drop_item() // drop the pipe at the user's feet
src.loc = T
level = 2 // defaults to above floor laying
if(!T.intact)
level = 1 // if floor is not intact, make a low-level pipe
anchored = 1 // anchor the item so that it can't be dragged around if placed
// otherwise able to drag underfloor pipes into intact turfs
// called when an item is dropped
/obj/item/weapon/pipe/dropped(mob/user)
src.anchored = 0 // set unanchored if dropped manually. Will be set anchored if placed (above)
// rotate the pipe item clockwise
/obj/item/weapon/pipe/verb/rotate()
set src in view(1)
if ( usr.stat || usr.restrained() )
return
var/turf/T = src.loc
if(isturf(T) && T.intact && level==1) // if the pipe is underfloor, don't rotate
return // incase the pipe has been revaled with a t-scanner
src.dir = turn(src.dir, -90)
return
// returns the p_dir from the pipe item type and dir
/obj/item/weapon/pipe/proc/get_pdir()
var/flip = turn(dir, 180)
var/cw = turn(dir, -90)
var/acw = turn(dir, 90)
switch(ptype)
if(0)
return dir|flip
if(1)
return dir|cw
if(2,3)
return 0
if(4,7)
return dir
if(5)
return dir|cw|acw
if(6)
return flip
return 0
// return the h_dir (heat-exchange pipes) from the type and the dir
/obj/item/weapon/pipe/proc/get_hdir()
var/flip = turn(dir, 180)
var/cw = turn(dir, -90)
switch(ptype)
if(0,1,4,5,7)
return 0
if(2)
return dir|flip
if(3)
return dir|cw
if(6)
return dir
return 0
// test verb
/obj/item/weapon/pipe/verb/inc()
set src in view(1)
ptype = (ptype+1)%8
update()
/obj/item/weapon/pipe/attackby(obj/item/weapon/W, mob/user)
var/turf/T = src.loc
if(T.intact && level==1) // if the pipe is underfloor, don't interact
return // in case the pipe has been revealed with a t-scanner
var/pipedir = src.get_pdir()|src.get_hdir() // all possible pipe dirs including h/e
if (istype(W, /obj/item/weapon/weldingtool) )
var/obj/item/weapon/weldingtool/WT = W
if (WT.welding && WT.weldfuel>=0)
WT.weldfuel--
for(var/obj/machinery/M in T) // check to make sure no other pipes conflit with this one
if(M.level == src.level) // only on same level
if( (M.p_dir & pipedir) || (M.h_dir & pipedir) ) // matches at least one direction on either type of pipe
user.client_mob() << "There is already a pipe at that location and position."
return
// no conflicts found
// 0 1 2 3 4 5 6 7
//"pipe", "bent pipe", "h/e pipe", "bent h/e pipe", "connector", "manifold", "junction" vent
var/obj/machinery/pipes/P
switch(ptype)
if(0,1) // straight or bent pipe
P = new/obj/machinery/pipes(T)
P.icon_state = "[pipedir]"
P.level = level
P.update()
P.updateicon()
var/list/dirs = P.get_dirs()
P.node1 = get_machine(P.level, P.loc, dirs[1])
P.node2 = get_machine(P.level, P.loc, dirs[2])
if(2,3) // straight or bent h/e pipe
P = new/obj/machinery/pipes/heat_exch(T)
P.icon_state = "[pipedir]"
P.level = 2
P.update()
P.updateicon()
var/list/dirs = P.get_dirs()
P.node1 = get_he_machine(P.level, P.loc, dirs[1])
P.node2 = get_he_machine(P.level, P.loc, dirs[2])
if(4) // connector
var/obj/machinery/connector/C = new(T)
C.dir = src.dir
C.p_dir = src.dir
C.level = level
C.buildnodes()
setlineterm(C.node, C.vnode)
if(5) //manifold
var/obj/machinery/manifold/M = new(T)
M.dir = dir
M.p_dir = pipedir
M.level = level
M.buildnodes()
setlineterm(M.node1, M.vnode1)
setlineterm(M.node2, M.vnode2)
setlineterm(M.node3, M.vnode3)
if(6) //junctions
var/obj/machinery/junction/J = new(T)
J.dir = dir
J.p_dir = src.get_pdir()
J.h_dir = src.get_hdir()
J.level = 2
J.buildnodes()
setlineterm(J.node1, J.vnode1)
setlineterm(J.node2, J.vnode2)
if(7) // vent
var/obj/machinery/vent/V = new(T)
V.dir = src.dir
V.p_dir = src.dir
V.level = level
V.buildnodes()
setlineterm(V.node, V.vnode)
// for pipe objects, now do updating of pipelines if needed
switch(ptype)
if(0,1,2,3) // new regular or or h/e pipe
// number of pipes connected to P
var/pipecon = (P.node1 && P.node1.ispipe()) + (P.node2 && P.node2.ispipe())
if(Debug) world << "Pipecon [pipecon]"
if(!pipecon) // simplest case - no connection pipes (but may be machines)
var/obj/machinery/pipeline/PL = new() // create a new pipeline
P.buildnodes(PL) // set new pipe to use new pl
PL.nodes += P // and add it
PL.numnodes = 1
PL.capmult = 2
plines += PL // and new pipeline to the global list
PL.setterm() // and ensure any connections to machines are made
PL.name = "pipeline #[plines.Find(PL)]" // set the name
else if(pipecon == 1) // single connected pipe
var/obj/machinery/pipes/CP // the connected pipe
if(P.node1 && P.node1.ispipe()) // find the connected pipe
CP = P.node1
else
CP = P.node2
var/obj/machinery/pipeline/PL = CP.pl // the pipeline we connected to
P.buildnodes(PL) // set the pipeline and nodes of any adjoining pipes
if(PL.nodes[1] == CP) // if the connected pipe is at start of line nodes list
PL.nodes.Insert(1, P) // insert new pipe into start of node list
else
PL.nodes += P // otherwise, insert it at end
PL.numnodes++
PL.capmult++
PL.setterm() // connect to any machines
CP.termination = 0 // connected pipe no longer terminal
else //(pipecon==2)
var/obj/machinery/pipes/CP1 = P.node1
var/obj/machinery/pipes/CP2 = P.node2
var/obj/machinery/pipeline/PL1 = CP1.pl
var/obj/machinery/pipeline/PL2 = CP2.pl
if(PL1 == PL2) // special case - completing a loop
// make sure to check if this works properly
P.buildnodes(PL1)
PL1.nodes += P
PL1.numnodes++
PL1.capmult++
PL1.setterm()
CP1.termination = 0
CP2.termination = 0
PL1.vnode1 = PL1 // link pipeline to self
PL1.vnode2 = PL1
else // separate pipelines
P.buildnodes(PL1)
CP1.termination = 0
CP2.termination = 0
var/list/plist
if(PL1.nodes[1] == CP1)
plist = pipelist(null, PL1.nodes[PL1.nodes.len])
else
plist = pipelist(null, PL1.nodes[1])
PL1.gas.transfer_from(PL2.gas, -1)
PL1.ngas.transfer_from(PL2.ngas, -1)
plines -= PL2
for(var/obj/machinery/pipes/OP in PL2.nodes)
OP.pl = PL1
PL1.nodes = plist
PL1.numnodes = plist.len
PL1.capmult = plist.len+1
PL1.setterm()
del(PL2)
del(src) // remove the pipe item
return
// ensure that setterm() is called for a newly connected pipeline
/proc/setlineterm(var/obj/machinery/node, var/obj/machinery/vnode)
if(vnode)
if( istype(vnode, /obj/machinery/pipeline) )
var/obj/machinery/pipeline/PL = vnode
node.buildnodes(PL)
PL.setterm()
else
node.buildnodes()
//Filter Attackby Procs
//Remove & Replace cover