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
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

+40
View File
@@ -0,0 +1,40 @@
<FONT color='blue'><B>Changes from previous version.</B></FONT><BR>
<HR><PRE>
Features
========
Map changed to a version similar to GoonStation 13.
Added an AI role to the station, with suitable equipment.
Bug-fixes
=========
Submitted By Fixed By Description
Stephen001 Stephen001 Fixed the Prison Station's map
Zjm7891 Zjm7891 Fixed bug involving APC's without external power eating screwdriver
Zjm7891 Zjm7891 Fixed bug #2002391
Coral Zjm7891 Fixed Emergency Close
Animay3 Zjm7891 Fixed CTF mode crashing server.
Nickr5 Zjm7891 Fixed closet/chair immobilisation bug
Trafalgar Hobnob Made weldingtools ignite plasma when present.
Zjm7891 Zjm7891 Attacking with certian items ignored range
Cecilff2 Stephen001 Grab stages would not advance past passive.
Zjm7891 Zjm7891 AI could no longer use equipment
Cecilff2 Stephen001 Grab stages would not advance past passive.
Kurper Stephen001 DNA Add would not append data properly.
Animay Trafalgar Attack delays were removed.
Trafalgar Trafalgar Disconnecting cameras would not cut off viewers.
Trafalgar Trafalgar Humans and AI could open each others inventory window.
Murrawhip Stephen001 You could move into many objects through obstacles.
Darkman1920 Stephen001 Inventory Windows would not close on URL-unsafe names.
Animay Murrawhip Monkeys could talk while sleeping.
Animay Trafalgar Closets could be used to bypass window doors.
Animay Hobnob Vote toggling provided misleading messages.
Animay Stephen001 Spawning 50 glass in Sandbox mode spawned 50 metal.
Animay Trafalgar It was possible to attack through windows.
Animay Stephen001 World log would not trim say and OOC text.
Trafalgar Trafalgar Game ticker would count at double the intended speed.
Trafalgar Trafalgar Timers would not actually secure to igniters.
Trafalgar Trafalgar Ranks were not always consistent with access numbers.
Trafalgar Trafalgar Fixed bad grammar on some admin messages.
Trafalgar Trafalgar The AI could perform all the actions a human could.
Trafalgar Trafalgar The AI could not see it's APC if the APC was turned off.
</PRE>
+12 -1
View File
@@ -1,8 +1,15 @@
// DM Environment file for SS13A.dme.
// DM Environment file for OpenSS13.dme.
// All manual changes should be made outside the BEGIN_ and END_ blocks.
// New source code should be placed in .dm files: choose File/New --> Code File.
// BEGIN_INTERNALS
/*
FILE: Code\demo.dm
DIR: Code
UPDATE_OBJ_TREE: ON
MAP_ICON_TYPE: 0
AUTO_FILE_DIR: ON
*/
// END_INTERNALS
// BEGIN_FILE_DIR
#define FILE_DIR .
@@ -17,6 +24,7 @@
#define FILE_DIR "Code/Machinery/Door"
#define FILE_DIR "Code/Machinery/Power"
#define FILE_DIR "Code/mob"
#define FILE_DIR "Code/Object"
#define FILE_DIR "Icons"
#define FILE_DIR "Interface"
// END_FILE_DIR
@@ -28,6 +36,7 @@
// BEGIN_INCLUDE
#include "ss13h_new.dmp"
#include "Code\!atoms.dm"
#include "Code\_debug.dm"
#include "Code\aaaDefines.dm"
#include "Code\ai_area_selection.dm"
#include "Code\airtunnel.dm"
@@ -69,6 +78,7 @@
#include "Code\Effects\water.dm"
#include "Code\Item\Weapon\aimodules.dm"
#include "Code\Item\Weapon\multitool.dm"
#include "Code\Item\Weapon\pipe.dm"
#include "Code\Item\Weapon\weldingtool.dm"
#include "Code\Machinery\_machinery.dm"
#include "Code\Machinery\_pipe_misc.dm"
@@ -141,6 +151,7 @@
#include "Code\Machinery\Power\turbine.dm"
#include "Code\mob\ai.dm"
#include "Code\mob\drone.dm"
#include "Code\Object\brokenpipe.dm"
// END_INCLUDE
+2356 -2357
View File
File diff suppressed because it is too large Load Diff