water pipes base + pda support

This commit is contained in:
Tastyfish
2012-01-24 15:45:51 -05:00
parent d6de48663e
commit a591aef35c
29 changed files with 4210 additions and 8 deletions

View File

@@ -466,6 +466,10 @@ proc/process_ghost_teleport_locs()
name = "Atmospherics"
icon_state = "atmos"
/area/atmos/plumbing
name = "Plumbing"
icon_state = "toilet"
//Maintenance
/area/maintenance/atmos_control

View File

@@ -58,6 +58,9 @@ datum/controller/game_controller
for(var/obj/machinery/atmospherics/machine in world)
machine.build_network()
for(var/obj/machinery/water/machine in world)
machine.build_network()
world << "\red \b Initializing atmos machinery."
sleep(-1)
for(var/obj/machinery/atmospherics/unary/vent_pump/T in world)
@@ -120,6 +123,9 @@ datum/controller/game_controller
for(var/datum/pipe_network/network in pipe_networks)
network.process()
for(var/datum/water/pipe_network/network in water_pipe_networks)
network.process()
for(var/datum/powernet/P in powernets)
P.reset()

View File

@@ -775,6 +775,15 @@
user << "\blue \t [re]"
else
user << "\blue No active chemical agents found in [A]."
else if(istype(A,/obj/machinery/water/pipe))
var/datum/water/pipeline/P = A:parent
if(P.reagents.reagent_list.len > 0)
var/reagents_length = P.reagents.reagent_list.len
user << "\blue [reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found at [P.return_pressure()]kPa."
for (var/re in P.reagents.reagent_list)
user << "\blue \t [re]"
else
user << "\blue No active chemical agents found in [A]."
else
user << "\blue No significant chemical agents found in [A]."

View File

@@ -34,6 +34,7 @@
name = "Power-ON Cartridge"
icon_state = "cart-e"
access_engine = 1
access_reagent_scanner = 1
medical
name = "Med-U Cartridge"

View File

@@ -59,11 +59,15 @@ datum
return the_id
trans_to(var/obj/target, var/amount=1, var/multiplier=1, var/preserve_data=1)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
if (!target )
if(!target || src.total_volume <= 0)
return
if (!target.reagents || src.total_volume<=0)
var/datum/reagents/R
if(istype(target,/datum/reagents))
R = target
else if(target.reagents)
R = target.reagents
else
return
var/datum/reagents/R = target.reagents
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
var/part = amount / src.total_volume
var/trans_data = null
@@ -81,11 +85,15 @@ datum
return amount
copy_to(var/obj/target, var/amount=1, var/multiplier=1, var/preserve_data=1)
if(!target)
if(!target || src.total_volume <= 0)
return
if(!target.reagents || src.total_volume<=0)
var/datum/reagents/R
if(istype(target,/datum/reagents))
R = target
else if(target.reagents)
R = target.reagents
else
return
var/datum/reagents/R = target.reagents
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
var/part = amount / src.total_volume
var/trans_data = null

View File

@@ -597,8 +597,29 @@
var/amount_per_transfer_from_this = 10
var/possible_transfer_amounts = list(10,25,50,100)
var/obj/machinery/water/portables_connector/connected_port
var/max_pressure = 4*ONE_ATMOSPHERE
attackby(obj/item/weapon/W as obj, mob/user as mob)
return
if (istype(W, /obj/item/weapon/wrench))
if(connected_port)
disconnect()
user << "\blue You disconnect [name] from the port."
update_icon()
return
else
var/obj/machinery/water/portables_connector/possible_port = locate(/obj/machinery/water/portables_connector/) in loc
if(possible_port)
if(connect(possible_port))
user << "\blue You connect [name] to the port."
update_icon()
return
else
user << "\blue [name] failed to connect to the port."
return
else
user << "\blue Nothing happens."
return
New()
var/datum/reagents/R = new/datum/reagents(1000)
@@ -650,6 +671,43 @@
new /obj/effect/effect/water(src.loc)
del(src)
proc/connect(obj/machinery/water/portables_connector/new_port)
//Make sure not already connected to something else
if(connected_port || !new_port || new_port.connected_device)
return 0
//Make sure are close enough for a valid connection
if(new_port.loc != loc)
return 0
//Perform the connection
connected_port = new_port
connected_port.connected_device = src
anchored = 1 //Prevent movement
//Actually enforce the air sharing
var/datum/water/pipe_network/network = connected_port.return_network(src)
if(network && !network.reagents.Find(reagents))
network.reagents += reagents
network.update = 1
return 1
proc/disconnect()
if(!connected_port)
return 0
var/datum/water/pipe_network/network = connected_port.return_network(src)
if(network)
network.reagents -= reagents
anchored = 0
connected_port.connected_device = null
connected_port = null
return 1
/obj/item/weapon/reagent_containers
@@ -723,7 +781,8 @@
/obj/machinery/disease2/incubator,
/obj/machinery/disease2/isolator,
/obj/machinery/disease2/biodestroyer,
/mob/living/simple_animal/livestock/cow
/mob/living/simple_animal/livestock/cow,
/obj/machinery/water/glass_connector
)
examine()
@@ -2822,6 +2881,13 @@
..()
reagents.add_reagent("water",1000)
update_icon()
overlays = 0
if(connected_port)
var/image/I = image('atmos.dmi', "can-connector")
I.pixel_x = 7
overlays += I
/obj/structure/reagent_dispensers/fueltank
name = "fueltank"
desc = "A fueltank"
@@ -2832,6 +2898,13 @@
..()
reagents.add_reagent("fuel",1000)
update_icon()
overlays = 0
if(connected_port)
var/image/I = image('atmos.dmi', "can-connector")
I.pixel_x = 7
overlays += I
/obj/structure/reagent_dispensers/peppertank
name = "Pepper Spray Refiller"
desc = "Refill pepper spray canisters."

View File

@@ -0,0 +1,147 @@
obj/machinery/water/binary
dir = SOUTH
initialize_directions = SOUTH|NORTH
var/datum/reagents/r1
var/datum/reagents/r2
var/obj/machinery/water/node1
var/obj/machinery/water/node2
var/datum/water/pipe_network/network1
var/datum/water/pipe_network/network2
var/max_volume = 400
var/max_pressure = 3 * ONE_ATMOSPHERE
New()
..()
switch(dir)
if(NORTH)
initialize_directions = NORTH|SOUTH
if(SOUTH)
initialize_directions = NORTH|SOUTH
if(EAST)
initialize_directions = EAST|WEST
if(WEST)
initialize_directions = EAST|WEST
r1 = new(max_volume)
r1.my_atom = src
r2 = new(max_volume)
r2.my_atom = src
// Housekeeping and pipe network stuff below
network_expand(datum/water/pipe_network/new_network, obj/machinery/water/pipe/reference)
if(reference == node1)
network1 = new_network
else if(reference == node2)
network2 = new_network
if(new_network.normal_members.Find(src))
return 0
new_network.normal_members += src
return null
Del()
loc = null
if(node1)
node1.disconnect(src)
del(network1)
if(node2)
node2.disconnect(src)
del(network2)
node1 = null
node2 = null
..()
initialize()
if(node1 && node2) return
var/node2_connect = dir
var/node1_connect = turn(dir, 180)
for(var/obj/machinery/water/target in get_step(src,node1_connect))
if(target.initialize_directions & get_dir(target,src))
node1 = target
break
for(var/obj/machinery/water/target in get_step(src,node2_connect))
if(target.initialize_directions & get_dir(target,src))
node2 = target
break
update_icon()
build_network()
if(!network1 && node1)
network1 = new /datum/water/pipe_network()
network1.normal_members += src
network1.build_network(node1, src)
if(!network2 && node2)
network2 = new /datum/water/pipe_network()
network2.normal_members += src
network2.build_network(node2, src)
return_network(obj/machinery/water/reference)
build_network()
if(reference==node1)
return network1
if(reference==node2)
return network2
return null
reassign_network(datum/water/pipe_network/old_network, datum/water/pipe_network/new_network)
if(network1 == old_network)
network1 = new_network
if(network2 == old_network)
network2 = new_network
return 1
return_network_reagents(datum/water/pipe_network/reference)
var/list/results = list()
if(network1 == reference)
results += r1
if(network2 == reference)
results += r2
return results
disconnect(obj/machinery/water/reference)
if(reference==node1)
del(network1)
node1 = null
else if(reference==node2)
del(network2)
node2 = null
return null
proc/return_pressure1()
return r1.total_volume / r1.maximum_volume * max_pressure
proc/return_pressure2()
return r2.total_volume / r2.maximum_volume * max_pressure
proc/mingle_dc1_with_turf()
mingle_outflow_with_turf(get_turf(src), r1.total_volume,
turn(dir, 180),
reagents = r1, pressure = return_pressure1())
proc/mingle_dc2_with_turf()
mingle_outflow_with_turf(get_turf(src), r2.total_volume,
dir,
reagents = r2, pressure = return_pressure2())

View File

@@ -0,0 +1,77 @@
/obj/machinery/water/binary/fixture
name = "water fixture connection"
icon = 'water_fixtures.dmi'
icon_state = "fixture"
level = 1
layer = 2.9
var/obj/parent
hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
initialize()
..()
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
update_icon()
process()
..()
// handle leaks
if(!network1 && r1.total_volume > 0)
mingle_dc1_with_turf()
if(!network2 && r2.total_volume > 0)
mingle_dc2_with_turf()
proc/fill(amount)
if(!parent || !parent.reagents || amount <= 0) return
amount = min(amount, parent.reagents.maximum_volume-parent.reagents.total_volume)
var/parent_pressure = parent.reagents.total_volume / parent.reagents.maximum_volume
if(return_pressure1() > parent_pressure)
r1.trans_to(parent, amount)
if(network1)
network1.update = 1
return amount
else
return 0
proc/drain(amount)
if(!parent || !parent.reagents || amount <= 0) return
amount = min(amount, r2.maximum_volume-r2.total_volume)
var/parent_pressure = parent.reagents.total_volume / parent.reagents.maximum_volume
if(return_pressure2() < parent_pressure)
parent.reagents.trans_to(r2, amount)
if(network2)
network2.update = 1
return amount
else
return 0
attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/env_air = loc.return_air()
if ((return_pressure1()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
add_fingerprint(user)
return 1
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe(loc, make_from=src)
del(src)

View File

@@ -0,0 +1,198 @@
/*
Every cycle, the pump uses the reagents in reagents_in to try and make reagents_out the perfect pressure.
node1, r1, network1 correspond to input
node2, r2, network2 correspond to output
Thus, the two variables affect pump operation are set in New():
r1.total_volume
This is the volume of gas available to the pump that may be transfered to the output
r2.total_volume
Higher quantities of this cause more air to be perfected later
but overall network volume is also increased as this increases...
*/
obj/machinery/water/binary/pump
icon = 'pump.dmi'
icon_state = "intact_off"
name = "Water pump"
desc = "A pump"
var/on = 0
var/target_pressure = ONE_ATMOSPHERE
var/frequency = 0
var/id = null
var/datum/radio_frequency/radio_connection
/*
attack_hand(mob/user)
on = !on
update_icon()
*/
update_icon()
if(node1&&node2)
icon_state = "intact_[on?("on"):("off")]"
else
if(node1)
icon_state = "exposed_1_off"
else if(node2)
icon_state = "exposed_2_off"
else
icon_state = "exposed_3_off"
return
process()
// ..()
if(stat & (NOPOWER|BROKEN))
return
if(!on)
return 0
var/output_starting_pressure = return_pressure2()
if( (target_pressure - output_starting_pressure) < 0.01)
//No need to pump liquid if target is already reached!
return 1
//Calculate necessary moles to transfer using PV=nRT
if(r1.total_volume > 0)
var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_vol = pressure_delta * r2.maximum_volume / max_pressure
//Actually transfer the reagents
r1.trans_to(r2, transfer_vol)
if(network1)
network1.update = 1
if(network2)
network2.update = 1
else if(r2.total_volume > 0) // leak out 1->2
mingle_dc2_with_turf()
return 1
//Radio remote control
proc
set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, filter = RADIO_ATMOSIA)
broadcast_status()
if(!radio_connection)
return 0
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.source = src
signal.data = list(
"tag" = id,
"device" = "AGP",
"power" = on,
"target_output" = target_pressure,
"sigtype" = "status"
)
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
return 1
interact(mob/user as mob)
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output pressure: </b>
[round(target_pressure,0.1)]kPa | <a href='?src=\ref[src];set_press=1'>Change</a>
"}
user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_pump")
onclose(user, "atmo_pump")
initialize()
..()
if(frequency)
set_frequency(frequency)
receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
return 0
if("power" in signal.data)
on = text2num(signal.data["power"])
if("power_toggle" in signal.data)
on = !on
if("set_output_pressure" in signal.data)
target_pressure = between(
0,
text2num(signal.data["set_output_pressure"]),
ONE_ATMOSPHERE*50
)
if("status" in signal.data)
spawn(2)
broadcast_status()
return //do not update_icon
spawn(2)
broadcast_status()
update_icon()
return
attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
user << "\red Access denied."
return
usr.machine = src
interact(user)
return
Topic(href,href_list)
if(href_list["power"])
on = !on
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
usr.machine = src
src.update_icon()
src.updateUsrDialog()
return
power_change()
..()
update_icon()
attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if (!(stat & NOPOWER) && on)
user << "\red You cannot unwrench this [src], turn it off first."
return 1
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/env_air = loc.return_air()
if ((return_pressure1()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
add_fingerprint(user)
return 1
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe(loc, make_from=src)
del(src)

View File

@@ -0,0 +1,189 @@
obj/machinery/water/trinary
dir = SOUTH
initialize_directions = SOUTH|NORTH|WEST
var/datum/reagents/r1
var/datum/reagents/r2
var/datum/reagents/r3
var/obj/machinery/water/node1
var/obj/machinery/water/node2
var/obj/machinery/water/node3
var/datum/water/pipe_network/network1
var/datum/water/pipe_network/network2
var/datum/water/pipe_network/network3
var/max_volume = 400
var/max_pressure = 3 * ONE_ATMOSPHERE
New()
..()
switch(dir)
if(NORTH)
initialize_directions = EAST|NORTH|SOUTH
if(SOUTH)
initialize_directions = SOUTH|WEST|NORTH
if(EAST)
initialize_directions = EAST|WEST|SOUTH
if(WEST)
initialize_directions = WEST|NORTH|EAST
r1 = new(max_volume)
r1.my_atom = src
r2 = new(max_volume)
r2.my_atom = src
r3 = new(max_volume)
r3.my_atom = src
// Housekeeping and pipe network stuff below
network_expand(datum/water/pipe_network/new_network, obj/machinery/water/pipe/reference)
if(reference == node1)
network1 = new_network
else if(reference == node2)
network2 = new_network
else if (reference == node3)
network3 = new_network
if(new_network.normal_members.Find(src))
return 0
new_network.normal_members += src
return null
Del()
loc = null
if(node1)
node1.disconnect(src)
del(network1)
if(node2)
node2.disconnect(src)
del(network2)
if(node3)
node3.disconnect(src)
del(network3)
node1 = null
node2 = null
node3 = null
..()
initialize()
if(node1 && node2 && node3) return
var/node1_connect = turn(dir, -180)
var/node2_connect = turn(dir, -90)
var/node3_connect = dir
for(var/obj/machinery/water/target in get_step(src,node1_connect))
if(target.initialize_directions & get_dir(target,src))
node1 = target
break
for(var/obj/machinery/water/target in get_step(src,node2_connect))
if(target.initialize_directions & get_dir(target,src))
node2 = target
break
for(var/obj/machinery/water/target in get_step(src,node3_connect))
if(target.initialize_directions & get_dir(target,src))
node3 = target
break
update_icon()
build_network()
if(!network1 && node1)
network1 = new /datum/water/pipe_network()
network1.normal_members += src
network1.build_network(node1, src)
if(!network2 && node2)
network2 = new /datum/water/pipe_network()
network2.normal_members += src
network2.build_network(node2, src)
if(!network3 && node3)
network3 = new /datum/water/pipe_network()
network3.normal_members += src
network3.build_network(node3, src)
return_network(obj/machinery/water/reference)
build_network()
if(reference==node1)
return network1
if(reference==node2)
return network2
if(reference==node3)
return network3
return null
reassign_network(datum/water/pipe_network/old_network, datum/water/pipe_network/new_network)
if(network1 == old_network)
network1 = new_network
if(network2 == old_network)
network2 = new_network
if(network3 == old_network)
network3 = new_network
return 1
return_network_reagents(datum/water/pipe_network/reference)
var/list/results = list()
if(network1 == reference)
results += r1
if(network2 == reference)
results += r2
if(network3 == reference)
results += r3
return results
disconnect(obj/machinery/water/reference)
if(reference==node1)
del(network1)
node1 = null
else if(reference==node2)
del(network2)
node2 = null
else if(reference==node3)
del(network3)
node3 = null
return null
proc/return_pressure1()
return r1.total_volume / r1.maximum_volume * max_pressure
proc/return_pressure2()
return r2.total_volume / r2.maximum_volume * max_pressure
proc/return_pressure3()
return r3.total_volume / r3.maximum_volume * max_pressure
proc/mingle_dc1_with_turf()
mingle_outflow_with_turf(get_turf(src), r1.total_volume,
turn(dir, 180),
reagents = r1, pressure = return_pressure1())
proc/mingle_dc2_with_turf()
mingle_outflow_with_turf(get_turf(src), r2.total_volume,
turn(dir, -90),
reagents = r2, pressure = return_pressure2())
proc/mingle_dc3_with_turf()
mingle_outflow_with_turf(get_turf(src), r3.total_volume,
dir,
reagents = r3, pressure = return_pressure3())

View File

@@ -0,0 +1,190 @@
obj/machinery/water/trinary/filter
icon = 'filter.dmi'
icon_state = "intact_off"
density = 1
name = "Liquid filter"
req_access = list(access_atmospherics)
var/on = 0
var/temp = null // -- TLE
var/target_pressure = ONE_ATMOSPHERE
var/list/filter_types = list()
var/filter_types_text
var/frequency = 0
var/datum/radio_frequency/radio_connection
proc
set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
New()
if(filter_types_text)
filter_types = dd_text2list(filter_types_text, ";")
filter_types_text = null
if(radio_controller)
initialize()
..()
update_icon()
if(node2 && node3 && node1)
icon_state = "intact_[on?("on"):("off")]"
else
icon_state = "hintact_off"
on = 0
return
New()
..()
process()
..()
if(!on)
return 0
var/output_starting_pressure = return_pressure3()
if(output_starting_pressure >= target_pressure)
//No need to mix if target is already full!
return 1
//Calculate necessary volume to transfer
var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_vol = pressure_delta * r3.maximum_volume / max_pressure
//Actually transfer the reagents
if(transfer_vol > 0)
var/datum/reagents/removed = new(transfer_vol)
removed.my_atom = src
r1.trans_to(removed, transfer_vol)
var/datum/reagents/filtered_out = new(transfer_vol)
filtered_out.my_atom = src
// transfer each type in filter list
for(var/T in filter_types)
var/datum/reagent/R = removed.has_reagent(T)
if(!R) continue
filtered_out.add_reagent(T, R.volume)
removed.remove_reagent(T, R.volume)
filtered_out.trans_to(r2, filtered_out.total_volume)
removed.trans_to(r3, removed.total_volume)
if(network2)
network2.update = 1
else if(r2.total_volume > 0) // leak out 1->2
mingle_dc2_with_turf()
if(network3)
network3.update = 1
else if(r3.total_volume > 0) // leak out 1->3
mingle_dc3_with_turf()
if(network1)
network1.update = 1
return 1
initialize()
set_frequency(frequency)
..()
attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/env_air = loc.return_air()
if ((return_pressure1()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
add_fingerprint(user)
return 1
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe(loc, make_from=src)
del(src)
obj/machinery/water/trinary/filter/attack_hand(user as mob) // -- TLE
if(..())
return
if(!src.allowed(user))
user << "\red Access denied."
return
var/dat
dat += {"
<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Filtering: </b><a href='?src=\ref[src];add=1'>Add</a><hr>"}
for(var/T in filter_types)
dat += "<a href='?src=\ref[src];remove=[T]'>[T]</a><br>"
dat += {"<HR><B>Desirable output pressure:</B>
[src.target_pressure] | <a href='?src=\ref[src];set_press=1'>Change</a>
"}
/*
user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD>[dat]","window=atmo_filter")
onclose(user, "atmo_filter")
return
if (src.temp)
dat = text("<TT>[]</TT><BR><BR><A href='?src=\ref[];temp=1'>Clear Screen</A>", src.temp, src)
//else
// src.on != src.on
*/
user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_filter")
onclose(user, "atmo_filter")
return
obj/machinery/water/trinary/filter/Topic(href, href_list) // -- TLE
if(..())
return
usr.machine = src
src.add_fingerprint(usr)
if (href_list["temp"])
src.temp = null
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
if(href_list["power"])
on=!on
if(href_list["add"])
var/list/choices = new()
for(var/T in typesof(/datum/reagent) - /datum/reagent)
var/datum/reagent/R = new T()
choices += R.id
var/choice = input("Choose Reagent", name) in choices
filter_types += choice
if(href_list["remove"])
filter_types -= href_list["remove"]
src.update_icon()
src.updateUsrDialog()
/*
for(var/mob/M in viewers(1, src))
if ((M.client && M.machine == src))
src.attack_hand(M)
*/
return

View File

@@ -0,0 +1,148 @@
obj/machinery/water/trinary/mixer
icon = 'mixer.dmi'
icon_state = "intact_off"
density = 1
name = "Liquid mixer"
req_access = list(access_atmospherics)
var/on = 0
var/target_pressure = ONE_ATMOSPHERE
var/node1_concentration = 0.5
var/node2_concentration = 0.5
//node 3 is the outlet, nodes 1 & 2 are intakes
update_icon()
if(node2 && node3 && node1)
icon_state = "intact_[on?("on"):("off")]"
else
icon_state = "intact_off"
on = 0
return
New()
..()
r3.maximum_volume = 500
process()
..()
if(!on)
return 0
var/output_starting_pressure = return_pressure3()
if(output_starting_pressure >= target_pressure)
//No need to mix if target is already full!
return 1
//Calculate necessary moles to transfer using PV=nRT
var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_vol1 = (node1_concentration*pressure_delta) * r1.maximum_volume / max_pressure
var/transfer_vol2 = (node2_concentration*pressure_delta) * r2.maximum_volume / max_pressure
var/r1_vol = r1.total_volume
var/r2_vol = r2.total_volume
if((r1_vol < transfer_vol1) || (r2_vol < transfer_vol2))
if(!transfer_vol1 || !transfer_vol2) return
var/ratio = min(r1_vol/transfer_vol1, r2_vol/transfer_vol2)
transfer_vol1 *= ratio
transfer_vol2 *= ratio
//Actually transfer the gas
if(transfer_vol1 > 0)
r1.trans_to(r3, transfer_vol1)
if(transfer_vol2 > 0)
r2.trans_to(r3, transfer_vol2)
if(network1 && transfer_vol1)
network1.update = 1
if(network2 && transfer_vol2)
network2.update = 1
if(network3)
network3.update = 1
else if(r3.total_volume > 0) // leak out 1,2->3
mingle_dc3_with_turf()
return 1
attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/env_air = loc.return_air()
if ((return_pressure3()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
add_fingerprint(user)
return 1
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe(loc, make_from=src)
del(src)
attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
user << "\red Access denied."
return
usr.machine = src
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output pressure: </b>
[target_pressure]kPa | <a href='?src=\ref[src];set_press=1'>Change</a>
<br>
<b>Node 1 Concentration:</b>
<a href='?src=\ref[src];node1_c=-0.1'><b>-</b></a>
<a href='?src=\ref[src];node1_c=-0.01'>-</a>
[node1_concentration]([node1_concentration*100]%)
<a href='?src=\ref[src];node1_c=0.01'><b>+</b></a>
<a href='?src=\ref[src];node1_c=0.1'>+</a>
<br>
<b>Node 2 Concentration:</b>
<a href='?src=\ref[src];node2_c=-0.1'><b>-</b></a>
<a href='?src=\ref[src];node2_c=-0.01'>-</a>
[node2_concentration]([node2_concentration*100]%)
<a href='?src=\ref[src];node2_c=0.01'><b>+</b></a>
<a href='?src=\ref[src];node2_c=0.1'>+</a>
"}
user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_mixer")
onclose(user, "atmo_mixer")
return
Topic(href,href_list)
if(href_list["power"])
on = !on
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
if(href_list["node1_c"])
var/value = text2num(href_list["node1_c"])
src.node1_concentration = max(0, min(1, src.node1_concentration + value))
src.node2_concentration = max(0, min(1, src.node2_concentration - value))
if(href_list["node2_c"])
var/value = text2num(href_list["node2_c"])
src.node2_concentration = max(0, min(1, src.node2_concentration + value))
src.node1_concentration = max(0, min(1, src.node1_concentration - value))
src.update_icon()
src.updateUsrDialog()
return

View File

@@ -0,0 +1,337 @@
obj/machinery/water/tvalve
icon = 'valve.dmi'
icon_state = "tvalve0"
name = "manual switching water valve"
desc = "A pipe valve"
dir = SOUTH
initialize_directions = SOUTH|NORTH|WEST
var/state = 0 // 0 = go straight, 1 = go to side
// like a trinary component, node1 is input, node2 is side output, node3 is straight output
var/obj/machinery/water/node1
var/obj/machinery/water/node2
var/obj/machinery/water/node3
var/datum/water/pipe_network/network_node1
var/datum/water/pipe_network/network_node2
var/datum/water/pipe_network/network_node3
update_icon(animation)
if(animation)
flick("tvalve[src.state][!src.state]",src)
else
icon_state = "tvalve[state]"
New()
switch(dir)
if(NORTH)
initialize_directions = SOUTH|NORTH|EAST
if(SOUTH)
initialize_directions = NORTH|SOUTH|WEST
if(EAST)
initialize_directions = WEST|EAST|SOUTH
if(WEST)
initialize_directions = EAST|WEST|NORTH
..()
network_expand(datum/water/pipe_network/new_network, obj/machinery/water/pipe/reference)
if(reference == node1)
network_node1 = new_network
if(state)
network_node2 = new_network
else
network_node3 = new_network
else if(reference == node2)
network_node2 = new_network
if(state)
network_node1 = new_network
else if(reference == node3)
network_node3 = new_network
if(!state)
network_node1 = new_network
if(new_network.normal_members.Find(src))
return 0
new_network.normal_members += src
if(state)
if(reference == node1)
if(node2)
return node2.network_expand(new_network, src)
else if(reference == node2)
if(node1)
return node1.network_expand(new_network, src)
else
if(reference == node1)
if(node3)
return node3.network_expand(new_network, src)
else if(reference == node3)
if(node1)
return node1.network_expand(new_network, src)
return null
Del()
loc = null
if(node1)
node1.disconnect(src)
del(network_node1)
if(node2)
node2.disconnect(src)
del(network_node2)
if(node3)
node3.disconnect(src)
del(network_node3)
node1 = null
node2 = null
node3 = null
..()
proc/go_to_side()
if(state) return 0
state = 1
update_icon()
if(network_node1)
del(network_node1)
if(network_node3)
del(network_node3)
build_network()
if(network_node1&&network_node2)
network_node1.merge(network_node2)
network_node2 = network_node1
if(network_node1)
network_node1.update = 1
else if(network_node2)
network_node2.update = 1
return 1
proc/go_straight()
if(!state)
return 0
state = 0
update_icon()
if(network_node1)
del(network_node1)
if(network_node2)
del(network_node2)
build_network()
if(network_node1&&network_node3)
network_node1.merge(network_node3)
network_node3 = network_node1
if(network_node1)
network_node1.update = 1
else if(network_node3)
network_node3.update = 1
return 1
attack_ai(mob/user as mob)
return
attack_paw(mob/user as mob)
return attack_hand(user)
attack_hand(mob/user as mob)
src.add_fingerprint(usr)
update_icon(1)
sleep(10)
if (src.state)
src.go_straight()
else
src.go_to_side()
process()
..()
machines.Remove(src)
if(!node1)
if(state && node2)
mingle_dc_with_turf(turn(dir,180), network_node2) // leak 2->1
else if(!state && node3)
mingle_dc_with_turf(turn(dir,180), network_node3) // leak 3->1
else
if(state && node2)
mingle_dc_with_turf(turn(dir,-90), network_node1) // leak 1->2
else if(!state && node3)
mingle_dc_with_turf(dir, network_node1) // leak 1->3
// if it's disconnected on both ends, do nothing
return
initialize()
var/node1_dir
var/node2_dir
var/node3_dir
node1_dir = turn(dir, 180)
node2_dir = turn(dir, -90)
node3_dir = dir
for(var/obj/machinery/water/target in get_step(src,node1_dir))
if(target.initialize_directions & get_dir(target,src))
node1 = target
break
for(var/obj/machinery/water/target in get_step(src,node2_dir))
if(target.initialize_directions & get_dir(target,src))
node2 = target
break
for(var/obj/machinery/water/target in get_step(src,node3_dir))
if(target.initialize_directions & get_dir(target,src))
node3 = target
break
build_network()
if(!network_node1 && node1)
network_node1 = new /datum/water/pipe_network()
network_node1.normal_members += src
network_node1.build_network(node1, src)
if(!network_node2 && node2)
network_node2 = new /datum/water/pipe_network()
network_node2.normal_members += src
network_node2.build_network(node2, src)
if(!network_node3 && node3)
network_node3 = new /datum/water/pipe_network()
network_node3.normal_members += src
network_node3.build_network(node3, src)
return_network(obj/machinery/water/reference)
build_network()
if(reference==node1)
return network_node1
if(reference==node2)
return network_node2
if(reference==node3)
return network_node3
return null
reassign_network(datum/water/pipe_network/old_network, datum/water/pipe_network/new_network)
if(network_node1 == old_network)
network_node1 = new_network
if(network_node2 == old_network)
network_node2 = new_network
if(network_node3 == old_network)
network_node3 = new_network
return 1
return_network_reagents(datum/water/pipe_network/reference)
return null
disconnect(obj/machinery/water/reference)
if(reference==node1)
del(network_node1)
node1 = null
else if(reference==node2)
del(network_node2)
node2 = null
else if(reference==node3)
del(network_node3)
node2 = null
return null
digital // can be controlled by AI
name = "digital switching valve"
desc = "A digitally controlled valve."
icon = 'digital_valve.dmi'
attack_ai(mob/user as mob)
return src.attack_hand(user)
attack_hand(mob/user as mob)
if(!src.allowed(user))
user << "\red Access denied."
return
..()
//Radio remote control
proc
set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
var/frequency = 0
var/id = null
var/datum/radio_frequency/radio_connection
initialize()
..()
if(frequency)
set_frequency(frequency)
receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != id))
return 0
switch(signal.data["command"])
if("valve_open")
if(!state)
go_to_side()
if("valve_close")
if(state)
go_straight()
if("valve_toggle")
if(state)
go_straight()
else
go_to_side()
proc/return_pressure()
return network_node1.return_pressure_transient()
attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if (istype(src, /obj/machinery/water/tvalve/digital))
user << "\red You cannot unwrench this [src], it's too complicated."
return 1
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/env_air = loc.return_air()
if ((return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
add_fingerprint(user)
return 1
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe(loc, make_from=src)
del(src)

View File

@@ -0,0 +1,105 @@
#define SPRINKLER_VOLUME_PER_SPLASH 3
/obj/machinery/water/unary/sprinkler
name = "fire sprinkler"
icon = 'water_fixtures.dmi'
icon_state = "sprinkler0"
layer = 5
max_volume = 100
max_pressure = ONE_ATMOSPHERE
var/on = 0
temperature_expose(datum/gas_mixture/air, temperature, volume)
on = temperature > T0C+200 ? 50 : 0
update_icon()
update_icon()
icon_state = "sprinkler[(on || stat) > 0]"
process()
// make broken sprinkler stay on forever
if((!stat && !on) || reagents.total_volume < SPRINKLER_VOLUME_PER_SPLASH)
return
if(on > 0)
on--
// from extinguisher
/*var/direction = turn(dir, 180)
var/turf/T = get_turf(loc)
var/turf/T1 = get_step(T,turn(direction, 90))
var/turf/T2 = get_step(T,turn(direction, -90))
for(var/i = 1 to 5)
T2 = get_step(T2,direction)
var/list/the_targets = block(T1, T2)*/ // 3x3 grid in front of sprinkler
var/list/the_targets = view(5, src.loc)
if(the_targets.len == 0)
return
for(var/a=0, a<round(reagents.total_volume/SPRINKLER_VOLUME_PER_SPLASH), a++)
spawn(0)
var/obj/effect/effect/water/W = new /obj/effect/effect/water(get_turf(src))
var/turf/my_target = get_turf(pick(the_targets))
var/datum/reagents/R = new/datum/reagents(SPRINKLER_VOLUME_PER_SPLASH)
if(!W) return
W.reagents = R
R.my_atom = W
if(!W || !src) return
reagents.trans_to(W,SPRINKLER_VOLUME_PER_SPLASH)
for(var/b=0, b<7, b++)
step_towards(W,my_target)
if(!W) return
W.reagents.reaction(get_turf(W))
for(var/atom/atm in get_turf(W))
if(!W) return
W.reagents.reaction(atm)
if(W.loc == my_target) break
if(network)
network.update = 1
attack_paw(mob/user as mob)
attack_hand(user)
attack_hand(mob/user as mob)
if(user.a_intent != "help" && (stat & BROKEN) == 0)
stat |= BROKEN
update_icon()
user.visible_message("\red [user] smashes \the [src]!",
"\red You smash \the [src]!",
"You hear a clang sound.")
attackby(obj/item/weapon/wrench/W, mob/user as mob)
if(istype(W))
if((stat & BROKEN) == BROKEN)
stat &= ~BROKEN
update_icon()
user.visible_message("\blue [user] wrenches \the [src] back closed.", \
"\blue You wrench \the [src] back closed.", \
"You hear a wrenching sound.")
else
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/env_air = loc.return_air()
if ((return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
add_fingerprint(user)
return 1
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe(loc, make_from=src)
del(src)
else
..()
#undef SPRINKLER_VOLUME_PER_SPLASH

View File

@@ -0,0 +1,89 @@
/obj/machinery/water/unary
dir = SOUTH
initialize_directions = SOUTH
var/obj/machinery/water/node
var/datum/water/pipe_network/network
var/max_volume = 400
var/max_pressure = 3 * ONE_ATMOSPHERE
New()
..()
initialize_directions = dir
reagents = new(max_volume)
reagents.my_atom = src
proc/return_pressure()
return reagents.total_volume / reagents.maximum_volume * max_pressure
// Housekeeping and pipe network stuff below
network_expand(datum/water/pipe_network/new_network, obj/machinery/water/pipe/reference)
if(reference == node)
network = new_network
if(new_network.normal_members.Find(src))
return 0
new_network.normal_members += src
return null
Del()
loc = null
if(node)
node.disconnect(src)
del(network)
node = null
..()
initialize()
if(node) return
var/node_connect = dir
for(var/obj/machinery/water/target in get_step(src,node_connect))
if(target.initialize_directions & get_dir(target,src))
node = target
break
update_icon()
build_network()
if(!network && node)
network = new /datum/water/pipe_network()
network.normal_members += src
network.build_network(node, src)
return_network(obj/machinery/water/reference)
build_network()
if(reference==node)
return network
return null
reassign_network(datum/water/pipe_network/old_network, datum/water/pipe_network/new_network)
if(network == old_network)
network = new_network
return 1
return_network_reagents(datum/water/pipe_network/reference)
var/list/results = list()
if(network == reference)
results += reagents
return results
disconnect(obj/machinery/water/reference)
if(reference==node)
del(network)
node = null
return null

View File

@@ -0,0 +1,320 @@
obj/machinery/water/valve
icon = 'valve.dmi'
icon_state = "valve0"
name = "manual water valve"
desc = "A pipe valve"
dir = SOUTH
initialize_directions = SOUTH|NORTH
var/open = 0
var/obj/machinery/water/node1
var/obj/machinery/water/node2
var/datum/water/pipe_network/network_node1
var/datum/water/pipe_network/network_node2
update_icon(animation)
if(animation)
flick("valve[src.open][!src.open]",src)
else
icon_state = "valve[open]"
New()
switch(dir)
if(NORTH || SOUTH)
initialize_directions = NORTH|SOUTH
if(EAST || WEST)
initialize_directions = EAST|WEST
..()
network_expand(datum/water/pipe_network/new_network, obj/machinery/water/pipe/reference)
if(reference == node1)
network_node1 = new_network
if(open)
network_node2 = new_network
else if(reference == node2)
network_node2 = new_network
if(open)
network_node1 = new_network
if(new_network.normal_members.Find(src))
return 0
new_network.normal_members += src
if(open)
if(reference == node1)
if(node2)
return node2.network_expand(new_network, src)
else if(reference == node2)
if(node1)
return node1.network_expand(new_network, src)
return null
Del()
loc = null
if(node1)
node1.disconnect(src)
del(network_node1)
if(node2)
node2.disconnect(src)
del(network_node2)
node1 = null
node2 = null
..()
proc/open()
if(open) return 0
open = 1
update_icon()
if(network_node1&&network_node2)
network_node1.merge(network_node2)
network_node2 = network_node1
if(network_node1)
network_node1.update = 1
else if(network_node2)
network_node2.update = 1
return 1
proc/close()
if(!open)
return 0
open = 0
update_icon()
if(network_node1)
del(network_node1)
if(network_node2)
del(network_node2)
build_network()
return 1
proc/normalize_dir()
if(dir==3)
dir = 1
else if(dir==12)
dir = 4
attack_ai(mob/user as mob)
return
attack_paw(mob/user as mob)
return attack_hand(user)
attack_hand(mob/user as mob)
src.add_fingerprint(usr)
update_icon(1)
sleep(10)
if (src.open)
src.close()
else
src.open()
process()
..()
machines.Remove(src)
if(open && (!node1 || !node2))
var/n2dir = (dir & (NORTH|SOUTH)) ? SOUTH : WEST
if(node1 && !node2)
mingle_dc_with_turf(n2dir, network_node1) // leak 1->2
else if(!node1 && node2)
mingle_dc_with_turf(turn(n2dir,180), network_node2) // leak 2->1
// if it's disconnected on both ends, or closed, do nothing
return
initialize()
normalize_dir()
var/node1_dir
var/node2_dir
for(var/direction in cardinal)
if(direction&initialize_directions)
if (!node1_dir)
node1_dir = direction
else if (!node2_dir)
node2_dir = direction
for(var/obj/machinery/water/target in get_step(src,node1_dir))
if(target.initialize_directions & get_dir(target,src))
node1 = target
break
for(var/obj/machinery/water/target in get_step(src,node2_dir))
if(target.initialize_directions & get_dir(target,src))
node2 = target
break
/*
var/connect_directions
switch(dir)
if(NORTH)
connect_directions = NORTH|SOUTH
if(SOUTH)
connect_directions = NORTH|SOUTH
if(EAST)
connect_directions = EAST|WEST
if(WEST)
connect_directions = EAST|WEST
else
connect_directions = dir
for(var/direction in cardinal)
if(direction&connect_directions)
for(var/obj/machinery/atmospherics/target in get_step(src,direction))
if(target.initialize_directions & get_dir(target,src))
connect_directions &= ~direction
node1 = target
break
if(node1)
break
for(var/direction in cardinal)
if(direction&connect_directions)
for(var/obj/machinery/atmospherics/target in get_step(src,direction))
if(target.initialize_directions & get_dir(target,src))
node2 = target
break
if(node1)
break
*/
build_network()
if(!network_node1 && node1)
network_node1 = new /datum/water/pipe_network()
network_node1.normal_members += src
network_node1.build_network(node1, src)
if(!network_node2 && node2)
network_node2 = new /datum/water/pipe_network()
network_node2.normal_members += src
network_node2.build_network(node2, src)
return_network(obj/machinery/water/reference)
build_network()
if(reference==node1)
return network_node1
if(reference==node2)
return network_node2
return null
reassign_network(datum/water/pipe_network/old_network, datum/water/pipe_network/new_network)
if(network_node1 == old_network)
network_node1 = new_network
if(network_node2 == old_network)
network_node2 = new_network
return 1
return_network_reagents(datum/water/pipe_network/reference)
return null
disconnect(obj/machinery/water/reference)
if(reference==node1)
del(network_node1)
node1 = null
else if(reference==node2)
del(network_node2)
node2 = null
return null
digital // can be controlled by AI
name = "digital water valve"
desc = "A digitally controlled valve."
icon = 'digital_valve.dmi'
attack_ai(mob/user as mob)
return src.attack_hand(user)
attack_hand(mob/user as mob)
if(!src.allowed(user))
user << "\red Access denied."
return
..()
//Radio remote control
proc
set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA)
var/frequency = 0
var/id = null
var/datum/radio_frequency/radio_connection
initialize()
..()
if(frequency)
set_frequency(frequency)
receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != id))
return 0
switch(signal.data["command"])
if("valve_open")
if(!open)
open()
if("valve_close")
if(open)
close()
if("valve_toggle")
if(open)
close()
else
open()
proc/return_pressure()
return network_node1.return_pressure_transient()
attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if (istype(src, /obj/machinery/water/valve/digital))
user << "\red You cannot unwrench this [src], it's too complicated."
return 1
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/env_air = loc.return_air()
if ((return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
add_fingerprint(user)
return 1
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe(loc, make_from=src)
del(src)

View File

@@ -0,0 +1,207 @@
/obj/machinery/water/glass_connector
icon = 'water_glass_connector.dmi'
icon_state = "intact"
name = "Beaker Connection"
desc = "For connecting portables devices related to reagents."
dir = SOUTH
initialize_directions = SOUTH
density = 1
var/obj/item/weapon/reagent_containers/glass/connected_device
var/obj/machinery/water/node
var/datum/water/pipe_network/network
New()
initialize_directions = dir
..()
update_icon()
if(node)
icon_state = "[node.level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]intact"
dir = get_dir(src, node)
else
icon_state = "exposed"
overlays = new()
if(connected_device)
overlays += "inserted"
if(connected_device.reagents.total_volume)
var/obj/effect/overlay = new/obj
overlay.icon = 'water_glass_connector.dmi'
overlay.icon_state = "window"
var/list/rgbcolor = list(0,0,0)
var/finalcolor
for(var/datum/reagent/re in connected_device.reagents.reagent_list) // natural color mixing bullshit/algorithm
if(!finalcolor)
rgbcolor = GetColors(re.color)
finalcolor = re.color
else
var/newcolor[3]
var/prergbcolor[3]
prergbcolor = rgbcolor
newcolor = GetColors(re.color)
rgbcolor[1] = (prergbcolor[1]+newcolor[1])/2
rgbcolor[2] = (prergbcolor[2]+newcolor[2])/2
rgbcolor[3] = (prergbcolor[3]+newcolor[3])/2
finalcolor = rgb(rgbcolor[1], rgbcolor[2], rgbcolor[3])
// This isn't a perfect color mixing system, the more reagents that are inside,
// the darker it gets until it becomes absolutely pitch black! I dunno, maybe
// that's pretty realistic? I don't do a whole lot of color-mixing anyway.
// If you add brighter colors to it it'll eventually get lighter, though.
overlay.icon += finalcolor
overlays += overlay
on_reagent_change(var/mob/user)
update_icon()
process()
..()
if(!connected_device)
return
if(network)
network.update = 1
return 1
// Housekeeping and pipe network stuff below
network_expand(datum/water/pipe_network/new_network, obj/machinery/water/pipe/reference)
if(reference == node)
network = new_network
if(new_network.normal_members.Find(src))
return 0
new_network.normal_members += src
return null
Del()
loc = null
if(connected_device)
connected_device.loc = src.loc
if(node)
node.disconnect(src)
del(network)
node = null
..()
initialize()
if(node) return
var/node_connect = dir
for(var/obj/machinery/water/target in get_step(src,node_connect))
if(target.initialize_directions & get_dir(target,src))
node = target
break
update_icon()
build_network()
if(!network && node)
network = new /datum/water/pipe_network()
network.normal_members += src
network.build_network(node, src)
return_network(obj/machinery/water/reference)
build_network()
if(reference==node)
return network
if(reference==connected_device)
return network
return null
reassign_network(datum/water/pipe_network/old_network, datum/water/pipe_network/new_network)
if(network == old_network)
network = new_network
return 1
return_network_reagents(datum/water/pipe_network/reference)
var/list/results = list()
if(connected_device)
results += connected_device.reagents
return results
disconnect(obj/machinery/water/reference)
if(reference==node)
del(network)
node = null
return null
proc/update_connection(inserting)
if(inserting)
if(network && !network.reagents.Find(connected_device.reagents))
network.reagents += connected_device.reagents
connected_device.reagents.my_atom = src
network.update = 1
else
if(network && network.reagents.Find(connected_device.reagents))
network.reagents -= connected_device.reagents
connected_device.reagents.my_atom = connected_device
attack_hand(mob/user as mob)
if (connected_device)
var/obj/item/weapon/reagent_containers/glass/B = connected_device
B.loc = src.loc
update_connection(0)
connected_device = null
update_icon()
else
..()
proc/return_pressure()
return network.return_pressure_transient()
attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
if(connected_device)
user << "\red You cannot unwrench this [src], remove [connected_device] first."
return 1
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/env_air = loc.return_air()
if ((return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
add_fingerprint(user)
return 1
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe(loc, make_from=src)
del(src)
else if(istype(W, /obj/item/weapon/reagent_containers/glass))
if(connected_device)
user << "\red You cannot insert this [src], remove [connected_device] first."
return 1
connected_device = W
update_connection(1)
user.drop_item()
W.loc = src
update_icon()
user << "\blue You add \the [W] to \the [src]."
else
return ..()

View File

@@ -0,0 +1,158 @@
/obj/machinery/water/portables_connector
icon = 'portables_connector.dmi'
icon_state = "intact"
name = "Water Connector Port"
desc = "For connecting reagent dispensers, such as water tanks."
dir = SOUTH
initialize_directions = SOUTH
var/obj/structure/reagent_dispensers/connected_device
var/obj/machinery/water/node
var/datum/water/pipe_network/network
var/on = 0
level = 0
New()
initialize_directions = dir
..()
update_icon()
if(node)
icon_state = "[level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]intact"
dir = get_dir(src, node)
else
icon_state = "exposed"
return
hide(var/i) //to make the little pipe section invisible, the icon changes.
if(node)
icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]intact"
dir = get_dir(src, node)
else
icon_state = "exposed"
process()
..()
if(!on)
return
if(!connected_device)
on = 0
return
if(network)
network.update = 1
return 1
// Housekeeping and pipe network stuff below
network_expand(datum/water/pipe_network/new_network, obj/machinery/water/pipe/reference)
if(reference == node)
network = new_network
if(new_network.normal_members.Find(src))
return 0
new_network.normal_members += src
return null
Del()
loc = null
if(connected_device)
connected_device.disconnect()
if(node)
node.disconnect(src)
del(network)
node = null
..()
initialize()
if(node) return
var/node_connect = dir
for(var/obj/machinery/water/target in get_step(src,node_connect))
if(target.initialize_directions & get_dir(target,src))
node = target
break
update_icon()
build_network()
if(!network && node)
network = new /datum/water/pipe_network()
network.normal_members += src
network.build_network(node, src)
return_network(obj/machinery/water/reference)
build_network()
if(reference==node)
return network
if(reference==connected_device)
return network
return null
reassign_network(datum/water/pipe_network/old_network, datum/water/pipe_network/new_network)
if(network == old_network)
network = new_network
return 1
return_network_reagents(datum/water/pipe_network/reference)
var/list/results = list()
if(connected_device)
results += connected_device.reagents
return results
disconnect(obj/machinery/water/reference)
if(reference==node)
del(network)
node = null
return null
proc/return_pressure()
return network.return_pressure_transient()
attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if (connected_device)
user << "\red You cannot unwrench this [src], dettach [connected_device] first."
return 1
if (locate(/obj/structure/reagent_dispensers, src.loc))
return 1
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/env_air = loc.return_air()
if ((return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
add_fingerprint(user)
return 1
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe(loc, make_from=src)
del(src)

View File

@@ -0,0 +1,433 @@
/obj/machinery/pipedispenser/water
name = "Water Pipe Dispenser"
/obj/machinery/pipedispenser/water/attack_hand(user as mob)
if(..())
return
var/dat = {"
<b>Regular pipes:</b><BR>
<A href='?src=\ref[src];wmake=0;dir=1'>Pipe</A><BR>
<A href='?src=\ref[src];wmake=1;dir=5'>Bent Pipe</A><BR>
<A href='?src=\ref[src];wmake=3;dir=1'>Manifold</A><BR>
<A href='?src=\ref[src];wmake=5;dir=1'>Manual Valve</A><BR>
<b>Devices:</b><BR>
<A href='?src=\ref[src];wmake=2;dir=1'>Beaker Connection</A><BR>
<A href='?src=\ref[src];wmake=9;dir=1'>Portables Connection</A><BR>
<A href='?src=\ref[src];wmake=6;dir=1'>Water Pump</A><BR>
<A href='?src=\ref[src];wmakemeter=1'>Water Meter</A><BR>
<A href='?src=\ref[src];wmake=8;dir=1'>Water Filter</A><BR>
<A href='?src=\ref[src];wmake=7;dir=1'>Fixture Connection</A><BR>
<A href='?src=\ref[src];wmake=4;dir=1'>Sprinkler</A><BR>
"}
user << browse("<HEAD><TITLE>[src]</TITLE></HEAD><TT>[dat]</TT>", "window=pipedispenser")
return
/obj/machinery/pipedispenser/water/Topic(href, href_list)
if(..())
return
if(unwrenched)
usr << browse(null, "window=pipedispenser")
return
usr.machine = src
src.add_fingerprint(usr)
if(href_list["wmake"])
if(!wait)
var/p_type = text2num(href_list["wmake"])
var/p_dir = text2num(href_list["dir"])
var/obj/item/water_pipe/P = new (/*usr.loc*/ src.loc, pipe_type=p_type, dir=p_dir)
P.update()
wait = 1
spawn(10)
wait = 0
if(href_list["makemeter"])
if(!wait)
new /obj/item/water_pipe_meter(/*usr.loc*/ src.loc)
wait = 1
spawn(15)
wait = 0
return
#define PIPE_SIMPLE_STRAIGHT 0
#define PIPE_SIMPLE_BENT 1
#define PIPE_GLASS_CONNECTOR 2
#define PIPE_MANIFOLD 3
#define PIPE_SPRINKLER 4
#define PIPE_MVALVE 5
#define PIPE_PUMP 6
#define PIPE_FIXTURE 7
#define PIPE_FILTER 8
#define PIPE_CONNECTOR 9
/obj/item/water_pipe
name = "water pipe"
desc = "A pipe"
var/pipe_type = 0
//var/pipe_dir = 0
var/pipename
icon = 'water_pipe_item.dmi'
icon_state = "simple"
item_state = "buildpipe"
flags = TABLEPASS|FPRINT
w_class = 4
level = 2
/obj/item/water_pipe/New(var/loc, var/pipe_type as num, var/dir as num, var/obj/machinery/water/make_from = null)
..()
if (make_from)
src.dir = make_from.dir
src.pipename = make_from.name
var/is_bent
if (make_from.initialize_directions in list(NORTH|SOUTH, WEST|EAST))
is_bent = 0
else
is_bent = 1
if(istype(make_from, /obj/machinery/water/pipe/simple))
src.pipe_type = PIPE_SIMPLE_STRAIGHT + is_bent
else if(istype(make_from, /obj/machinery/water/glass_connector))
src.pipe_type = PIPE_GLASS_CONNECTOR
else if(istype(make_from, /obj/machinery/water/portables_connector))
src.pipe_type = PIPE_CONNECTOR
else if(istype(make_from, /obj/machinery/water/pipe/manifold))
src.pipe_type = PIPE_MANIFOLD
else if(istype(make_from, /obj/machinery/water/unary/sprinkler))
src.pipe_type = PIPE_SPRINKLER
else if(istype(make_from, /obj/machinery/water/valve))
src.pipe_type = PIPE_MVALVE
else if(istype(make_from, /obj/machinery/water/binary/pump))
src.pipe_type = PIPE_PUMP
else if(istype(make_from, /obj/machinery/water/binary/fixture))
src.pipe_type = PIPE_FIXTURE
else if(istype(make_from, /obj/machinery/water/trinary/filter))
src.pipe_type = PIPE_FILTER
else
src.pipe_type = pipe_type
src.dir = dir
//src.pipe_dir = get_pipe_dir()
update()
src.pixel_x = rand(-5, 5)
src.pixel_y = rand(-5, 5)
//update the name and icon of the pipe item depending on the type
/obj/item/water_pipe/proc/update()
var/list/nlist = list( \
"pipe", \
"bent pipe", \
"glass connector", \
"manifold", \
"sprinkler", \
"mvalve", \
"pump", \
"fixture connection", \
"liquid filter", \
"connector", \
)
name = nlist[pipe_type+1] + " fitting"
var/list/islist = list( \
"simple", \
"simple", \
"gconnector", \
"manifold", \
"sprinkler", \
"mvalve", \
"pump", \
"fixture", \
"filter", \
"connector", \
)
icon_state = islist[pipe_type + 1]
//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
// rotate the pipe item clockwise
/obj/item/water_pipe/verb/rotate()
set category = "Object"
set name = "Rotate Pipe"
set src in view(1)
if ( usr.stat || usr.restrained() )
return
src.dir = turn(src.dir, -90)
if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_MVALVE))
if(dir==2)
dir = 1
else if(dir==8)
dir = 4
//src.pipe_dir = get_pipe_dir()
return
/obj/item/water_pipe/Move()
..()
if ((pipe_type in list (PIPE_SIMPLE_BENT)) \
&& (src.dir in cardinal))
src.dir = src.dir|turn(src.dir, 90)
else if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_MVALVE))
if(dir==2)
dir = 1
else if(dir==8)
dir = 4
return
// returns all pipe's endpoints
/obj/item/water_pipe/proc/get_pipe_dir()
if (!dir)
return 0
var/flip = turn(dir, 180)
var/cw = turn(dir, -90)
var/acw = turn(dir, 90)
switch(pipe_type)
if( PIPE_SIMPLE_STRAIGHT, \
PIPE_PUMP ,\
PIPE_MVALVE, \
PIPE_FIXTURE \
)
return dir|flip
if(PIPE_SIMPLE_BENT)
return dir //dir|acw
if(PIPE_GLASS_CONNECTOR, PIPE_CONNECTOR, PIPE_SPRINKLER)
return dir
if(PIPE_MANIFOLD)
return flip|cw|acw
if(PIPE_FILTER)
return dir|flip|cw
return 0
/obj/item/water_pipe/proc/get_pdir() //endpoints for regular pipes
return get_pipe_dir()
/obj/item/water_pipe/attack_self(mob/user as mob)
return rotate()
/obj/item/water_pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
..()
//*
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if (!isturf(src.loc))
return 1
if (pipe_type in list (PIPE_SIMPLE_STRAIGHT, PIPE_MVALVE))
if(dir==2)
dir = 1
else if(dir==8)
dir = 4
var/pipe_dir = get_pipe_dir()
for(var/obj/machinery/water/M in src.loc)
if(M.initialize_directions & pipe_dir) // matches at least one direction on either type of pipe
user << "\red There is already a pipe at that location."
return 1
// no conflicts found
var/pipefailtext = "\red There's nothing to connect this pipe section to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)"
switch(pipe_type)
if(PIPE_SIMPLE_STRAIGHT, PIPE_SIMPLE_BENT)
var/obj/machinery/water/pipe/simple/P = new( src.loc )
P.dir = src.dir
P.initialize_directions = pipe_dir
var/turf/T = P.loc
P.level = T.intact ? 2 : 1
P.initialize()
if (!P)
usr << pipefailtext
return 1
P.build_network()
if (P.node1)
P.node1.initialize()
P.node1.build_network()
if (P.node2)
P.node2.initialize()
P.node2.build_network()
if(PIPE_GLASS_CONNECTOR) // glass connector
var/obj/machinery/water/glass_connector/C = new( src.loc )
C.dir = dir
C.initialize_directions = pipe_dir
if (pipename)
C.name = pipename
C.initialize()
C.build_network()
if (C.node)
C.node.initialize()
C.node.build_network()
if(PIPE_CONNECTOR) // portables connector
var/obj/machinery/water/portables_connector/C = new( src.loc )
C.dir = dir
C.initialize_directions = pipe_dir
if (pipename)
C.name = pipename
var/turf/T = C.loc
C.level = T.intact ? 2 : 1
C.initialize()
C.build_network()
if (C.node)
C.node.initialize()
C.node.build_network()
if(PIPE_MANIFOLD) //manifold
var/obj/machinery/water/pipe/manifold/M = new( src.loc )
M.dir = dir
M.initialize_directions = pipe_dir
//M.New()
var/turf/T = M.loc
M.level = T.intact ? 2 : 1
M.initialize()
if (!M)
usr << "There's nothing to connect this manifold to! (with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)"
return 1
M.build_network()
if (M.node1)
M.node1.initialize()
M.node1.build_network()
if (M.node2)
M.node2.initialize()
M.node2.build_network()
if (M.node3)
M.node3.initialize()
M.node3.build_network()
if(PIPE_SPRINKLER) //sprinkler
var/obj/machinery/water/unary/sprinkler/V = new( src.loc )
V.dir = dir
V.initialize_directions = pipe_dir
if (pipename)
V.name = pipename
var/turf/T = V.loc
V.level = T.intact ? 2 : 1
V.initialize()
V.build_network()
if (V.node)
V.node.initialize()
V.node.build_network()
if(PIPE_FIXTURE) //fixture connection
var/obj/machinery/water/binary/fixture/V = new( src.loc )
V.dir = dir
V.initialize_directions = pipe_dir
if (pipename)
V.name = pipename
var/turf/T = V.loc
V.level = T.intact ? 2 : 1
V.initialize()
V.build_network()
if (V.node1)
V.node1.initialize()
V.node1.build_network()
if (V.node2)
V.node2.initialize()
V.node2.build_network()
if(PIPE_MVALVE) //manual valve
var/obj/machinery/water/valve/V = new( src.loc)
V.dir = dir
V.initialize_directions = pipe_dir
if (pipename)
V.name = pipename
var/turf/T = V.loc
V.level = T.intact ? 2 : 1
V.initialize()
V.build_network()
if (V.node1)
// world << "[V.node1.name] is connected to valve, forcing it to update its nodes."
V.node1.initialize()
V.node1.build_network()
if (V.node2)
// world << "[V.node2.name] is connected to valve, forcing it to update its nodes."
V.node2.initialize()
V.node2.build_network()
if(PIPE_PUMP) //gas pump
var/obj/machinery/water/binary/pump/P = new(src.loc)
P.dir = dir
P.initialize_directions = pipe_dir
if (pipename)
P.name = pipename
var/turf/T = P.loc
P.level = T.intact ? 2 : 1
P.initialize()
P.build_network()
if (P.node1)
P.node1.initialize()
P.node1.build_network()
if (P.node2)
P.node2.initialize()
P.node2.build_network()
if(PIPE_FILTER) //liquid filter
var/obj/machinery/water/trinary/filter/P = new(src.loc)
P.dir = dir
P.initialize_directions = pipe_dir
if (pipename)
P.name = pipename
var/turf/T = P.loc
P.level = T.intact ? 2 : 1
P.initialize()
P.build_network()
if (P.node1)
P.node1.initialize()
P.node1.build_network()
if (P.node2)
P.node2.initialize()
P.node2.build_network()
if (P.node3)
P.node3.initialize()
P.node3.build_network()
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user.visible_message( \
"[user] fastens the [src].", \
"\blue You have fastened the [src].", \
"You hear ratchet.")
del(src) // remove the pipe item
return
//TODO: DEFERRED
// ensure that setterm() is called for a newly connected pipeline
/obj/item/water_pipe_meter
name = "water meter"
desc = "A meter that can be laid on water pipes"
icon = 'water_pipe_item.dmi'
icon_state = "meter"
item_state = "buildpipe"
flags = TABLEPASS|FPRINT
w_class = 4
/obj/item/water_pipe_meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
..()
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if(!locate(/obj/machinery/water/pipe, src.loc))
user << "\red You need to fasten it to a pipe"
return 1
new/obj/machinery/water_meter( src.loc )
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You have fastened the meter to the pipe"
del(src)
#undef PIPE_SIMPLE_STRAIGHT
#undef PIPE_SIMPLE_BENT
#undef PIPE_GLASS_CONNECTOR
#undef PIPE_MANIFOLD
#undef PIPE_SPRINKLER
#undef PIPE_MVALVE
#undef PIPE_PUMP
#undef PIPE_FIXTURE
#undef PIPE_FILTER
#undef PIPE_CONNECTOR

View File

@@ -0,0 +1,69 @@
/*
You'll notice this is the atmospherics system,
but with reagents instead gas mixtures.
Quick overview:
Pipes combine to form pipelines
Pipelines and other water objects combine to form pipe_networks
Note: A single pipe_network represents a completely open space
Pipes -> Pipelines
Pipelines + Other Objects -> Pipe network
*/
obj/machinery/water
anchored = 1
use_power = 0
idle_power_usage = 0
active_power_usage = 0
power_channel = ENVIRON
var/nodealert = 0
var/initialize_directions = 0
var/color
process()
build_network()
..()
proc
network_expand(datum/water/pipe_network/new_network, obj/machinery/water/pipe/reference)
// Check to see if should be added to network. Add self if so and adjust variables appropriately.
// Note don't forget to have neighbors look as well!
return null
build_network()
// Called to build a network from this node
return null
return_network(obj/machinery/water/reference)
// Returns pipe_network associated with connection to reference
// Notes: should create network if necessary
// Should never return null
return null
reassign_network(datum/water/pipe_network/old_network, datum/water/pipe_network/new_network)
// Used when two pipe_networks are combining
return_network_reagents(datum/water/pipe_network/reference)
// Return a list of reagents(s) in the object
// associated with reference pipe_network for use in rebuilding the networks gases list
// Is permitted to return null
disconnect(obj/machinery/water/reference)
mingle_dc_with_turf(D, datum/water/pipe_network/net)
// 250 being a pipe opening volume
mingle_outflow_with_turf(get_turf(src), \
net.reagents_transient.total_volume / net.reagents_transient.maximum_volume * 250, \
D, network = net)
update_icon()
return null

View File

@@ -0,0 +1,121 @@
/obj/machinery/water_meter
name = "water meter"
desc = "It measures water flow."
icon = 'meter.dmi'
icon_state = "meterX"
var/obj/machinery/water/pipe/target = null
anchored = 1.0
var/frequency = 0
var/id
use_power = 1
idle_power_usage = 2
active_power_usage = 4
/obj/machinery/water_meter/New()
..()
target = locate(/obj/machinery/water/pipe) in loc
return 1
/obj/machinery/water_meter/initialize()
if (!target)
target = locate(/obj/machinery/water/pipe) in loc
/obj/machinery/water_meter/process()
if(!target)
icon_state = "meterX"
return 0
if(stat & (BROKEN|NOPOWER))
icon_state = "meter0"
return 0
use_power(5)
if(!target || !target.parent)
icon_state = "meterX"
return 0
var/datum/water/pipeline/pl = target.parent
var/pressure = pl.return_pressure() / target.max_pressure * 60*ONE_ATMOSPHERE
if(pressure <= 0.15*ONE_ATMOSPHERE)
icon_state = "meter0"
else if(pressure <= 1.8*ONE_ATMOSPHERE)
var/val = round(pressure/(ONE_ATMOSPHERE*0.3) + 0.5)
icon_state = "meter1_[val]"
else if(pressure <= 30*ONE_ATMOSPHERE)
var/val = round(pressure/(ONE_ATMOSPHERE*5)-0.35) + 1
icon_state = "meter2_[val]"
else if(pressure <= 59*ONE_ATMOSPHERE)
var/val = round(pressure/(ONE_ATMOSPHERE*5) - 6) + 1
icon_state = "meter3_[val]"
else
icon_state = "meter4"
if(frequency)
var/datum/radio_frequency/radio_connection = radio_controller.return_frequency(frequency)
if(!radio_connection) return
var/datum/signal/signal = new
signal.source = src
signal.transmission_method = 1
signal.data = list(
"tag" = id,
"device" = "AM",
"pressure" = round(pl.return_pressure()),
"sigtype" = "status"
)
radio_connection.post_signal(src, signal)
/obj/machinery/water_meter/examine()
set src in view(3)
var/t = "A gas flow meter. "
if (target)
if(target.parent)
var/datum/water/pipeline/pl = target.parent
var/pressure = pl.return_pressure()
t += "The pressure gauge reads [round(pressure, 0.01)] kPa"
else
t += "The sensor error light is blinking."
else
t += "The connect error light is blinking."
usr << t
/obj/machinery/water_meter/attack_hand(mob/user as mob)
if(stat & (NOPOWER|BROKEN))
return 1
var/t = null
if (get_dist(usr, src) <= 3 || istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/dead))
if (target)
if(target.parent)
var/datum/water/pipeline/pl = target.parent
var/pressure = pl.return_pressure()
t = "<B>Pressure:</B> [round(pressure, 0.01)] kPa"
else
t = "\red <B>Results: Sensor Error!</B>"
else
t = "\red <B>Results: Connection Error!</B>"
else
usr << "\blue <B>You are too far away.</B>"
usr << t
return 1
/obj/machinery/water_meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe_meter(src.loc)
del(src)

View File

@@ -0,0 +1,200 @@
var/global/list/datum/water/pipe_network/water_pipe_networks = list()
/datum/water/pipe_network
var/list/datum/reagents/reagents = list() //All of the gas_mixtures continuously connected in this network
var/list/obj/machinery/water/normal_members = list()
var/list/datum/water/pipeline/line_members = list()
//membership roster to go through for updates and what not
var/update = 1
var/datum/reagents/reagents_transient = null
var/max_pressure_transient = 3*ONE_ATMOSPHERE
New()
reagents_transient = new()
..()
proc/process()
//Equalize gases amongst pipe if called for
if(update)
update = 0
reconcile_reagents()
// release pipe leaks
var/dirs
for(var/datum/water/pipeline/P in line_members)
for(var/obj/machinery/water/pipe/E in P.edges)
dirs = E.initialize_directions
for(var/C in E.pipeline_expansion())
if(C) // a connection, remove dir from possibilities
dirs &= ~(get_dir(E, C))
if(dirs > 0) // there was a disconnect, release half of volume
P.mingle_with_turf(get_turf(E), \
P.reagents.total_volume / P.reagents.maximum_volume * E.max_volume / 2, \
dirs)
proc/build_network(obj/machinery/water/start_normal, obj/machinery/water/reference)
//Purpose: Generate membership roster
//Notes: Assuming that members will add themselves to appropriate roster in network_expand()
if(!start_normal)
del(src)
start_normal.network_expand(src, reference)
update_network_reagents()
if((normal_members.len>0)||(line_members.len>0))
water_pipe_networks += src
else
del(src)
proc/merge(datum/water/pipe_network/giver)
if(giver==src) return 0
normal_members -= giver.normal_members
normal_members += giver.normal_members
line_members -= giver.line_members
line_members += giver.line_members
for(var/obj/machinery/water/normal_member in giver.normal_members)
normal_member.reassign_network(giver, src)
for(var/datum/water/pipeline/line_member in giver.line_members)
line_member.network = src
del(giver)
update_network_reagents()
return 1
proc/update_network_reagents()
//Go through membership roster and make sure reagents is up to date
reagents = list()
for(var/obj/machinery/water/normal_member in normal_members)
var/result = normal_member.return_network_reagents(src)
if(result) reagents += result
for(var/datum/water/pipeline/line_member in line_members)
reagents += line_member.reagents
proc/reconcile_reagents()
//Perfectly equalize all reagent members instantly
reagents_transient = new(0)
reagents_transient.my_atom = new/obj()
for(var/datum/reagents/R in reagents)
// add in each reagents
reagents_transient.maximum_volume += R.maximum_volume
R.copy_to(reagents_transient, R.total_volume)
if(reagents_transient.total_volume > 0)
update = 1
//Update individual reagents by volume ratio
for(var/datum/reagents/R in reagents)
R.clear_reagents()
for(var/datum/reagent/re in reagents_transient.reagent_list)
R.add_reagent(re.id, re.volume \
* R.maximum_volume \
/ reagents_transient.maximum_volume)
return 1
proc/return_pressure_transient()
return reagents_transient.total_volume / reagents_transient.maximum_volume * max_pressure_transient
proc/mingle_outflow_with_turf(turf/simulated/target, mingle_volume, dir = 0, datum/water/pipeline/pipeline = null, datum/water/pipe_network/network = null, datum/reagents/reagents = null, pressure = 0)
if(pipeline)
network = pipeline.network
if(!reagents)
reagents = pipeline.reagents
if(!pressure)
pressure = pipeline.return_pressure()
else
if(!reagents)
reagents = network.reagents_transient
if(!pressure)
pressure = network.return_pressure_transient()
mingle_volume = min(mingle_volume, reagents.total_volume)
var/num_spots = round(pressure / 10)
if(mingle_volume < num_spots)
return
var/datum/reagents/mingle = new(mingle_volume)
mingle.my_atom = target
reagents.trans_to(mingle, mingle_volume)
var/turf/T1
var/turf/T2
if(dir == 0)
T1 = get_step(target, NORTH)
T1 = get_step(T1, EAST)
T2 = get_step(target, SOUTH)
T2 = get_step(T2, WEST)
else
T1 = get_step(target, turn(dir, -90))
T1 = get_step(T1, dir)
T2 = get_step(target, turn(dir, 90))
for(var/i = 1 to 5)
T2 = get_step(T2, dir)
var/box = block(T1, T2)
for(var/i = 1 to num_spots)
spawn(0)
var/obj/effect/effect/water/W = new /obj/effect/effect/water(get_turf(target))
var/turf/my_target = pick(box)
var/datum/reagents/R = new(mingle_volume/num_spots)
if(!W) return
W.reagents = R
R.my_atom = W
if(!W || !src) return
mingle.trans_to(W,mingle_volume/num_spots)
for(var/b=0, b<5, b++)
step_towards(W,my_target)
if(!W) return
W.reagents.reaction(get_turf(W))
for(var/atom/atm in get_turf(W))
if(!W) return
W.reagents.reaction(atm)
if(W.loc == my_target) break
if(network)
network.update = 1
proc/equalize_reagents(var/list/datum/reagents/reagents)
//Perfectly equalize all reagent members instantly
//Calculate totals from individual components
var/datum/reagents/reagents_transient = new(0)
reagents_transient.my_atom = new/obj()
for(var/datum/reagents/R in reagents)
// add in each reagent
reagents_transient.maximum_volume += R.maximum_volume
R.copy_to(reagents_transient, R.total_volume)
//Allow reagents to react
reagents_transient.handle_reactions()
if(reagents_transient.total_volume > 0)
//Update individual reagents by volume ratio
for(var/datum/reagents/R in reagents)
R.clear_reagents()
for(var/datum/reagent/re in reagents_transient.reagent_list)
R.add_reagent(re.id, re.volume \
* R.maximum_volume \
/ reagents_transient.maximum_volume)
return 1

View File

@@ -0,0 +1,127 @@
datum/water/pipeline
var/datum/reagents/reagents
var/max_pressure
var/list/obj/machinery/water/pipe/members
var/list/obj/machinery/water/pipe/edges //Used for building networks
var/datum/water/pipe_network/network
var/alert_pressure = 0
Del()
if(network)
del(network)
if(reagents && reagents.total_volume)
temporarily_store_reagents()
del(reagents)
..()
proc/process()//This use to be called called from the pipe networks
//Check to see if pressure is within acceptable limits
var/pressure = return_pressure()
if(pressure > alert_pressure)
for(var/obj/machinery/water/pipe/member in members)
if(!member.check_pressure(pressure))
break //Only delete 1 pipe per process
//Allow for reactions
//air.react() //Should be handled by pipe_network now
proc/temporarily_store_reagents()
//Update individual gas_mixtures by volume ratio
for(var/obj/machinery/water/pipe/member in members)
member.reagents_temporary = new(member.max_volume)
member.reagents_temporary.my_atom = member
for(var/datum/reagent/re in reagents.reagent_list)
re.volume = \
reagents.get_reagent_amount(re.id) \
* member.max_volume \
/ reagents.maximum_volume
proc/build_pipeline(obj/machinery/water/pipe/base)
var/list/possible_expansions = list(base)
members = list(base)
edges = list()
var/volume = base.max_volume
base.parent = src
alert_pressure = base.alert_pressure
if(base.reagents_temporary)
reagents = base.reagents_temporary
base.reagents_temporary = null
else
reagents = new(base.max_volume)
reagents.my_atom = base
max_pressure = base.max_pressure
var/PT = 1
while(possible_expansions.len>0)
for(var/obj/machinery/water/pipe/borderline in possible_expansions)
var/list/result = borderline.pipeline_expansion()
var/edge_check = result.len
if(result.len>0)
for(var/obj/machinery/water/pipe/item in result)
if(!members.Find(item))
members += item
possible_expansions += item
volume += item.max_volume
max_pressure += item.max_pressure
PT++
item.parent = src
alert_pressure = min(alert_pressure, item.alert_pressure)
if(item.reagents_temporary)
item.reagents_temporary.copy_to(reagents, item.reagents_temporary.total_volume)
edge_check--
if(edge_check>0)
edges += borderline
possible_expansions -= borderline
reagents.maximum_volume = volume
max_pressure /= PT
proc/network_expand(datum/water/pipe_network/new_network, obj/machinery/water/pipe/reference)
if(new_network.line_members.Find(src))
return 0
new_network.line_members += src
network = new_network
for(var/obj/machinery/water/pipe/edge in edges)
for(var/obj/machinery/water/result in edge.pipeline_expansion())
if(!istype(result,/obj/machinery/water/pipe) && (result!=reference))
result.network_expand(new_network, edge)
return 1
proc/return_network(obj/machinery/water/reference)
if(!network)
network = new /datum/water/pipe_network()
network.build_network(src, null)
//technically passing these parameters should not be allowed
//however pipe_network.build_network(..) and pipeline.network_extend(...)
// were setup to properly handle this case
return network
proc/return_pressure()
return reagents.total_volume / reagents.maximum_volume * max_pressure
proc/mingle_with_turf(turf/simulated/target, mingle_volume, dir = 0)
// dump all of section's volume
mingle_outflow_with_turf(target, mingle_volume, dir, pipeline=src)

View File

@@ -0,0 +1,961 @@
obj/machinery/water/pipe
var/datum/reagents/reagents_temporary //used when reconstructing a pipeline that broke
var/datum/water/pipeline/parent
var/max_volume = 0
var/max_pressure = 3 * ONE_ATMOSPHERE
var/force = 20
layer = 2.3 //under water pipes with their 2.4
var/alert_pressure = 2.5*ONE_ATMOSPHERE
//minimum pressure before check_pressure(...) should be called
New()
..()
proc/pipeline_expansion()
return null
proc/check_pressure(pressure)
//Return 1 if parent should continue checking other pipes
//Return null if parent should stop checking other pipes. Recall: del(src) will by default return null
return 1
proc/return_reagents()
if(!parent)
parent = new /datum/water/pipeline()
parent.build_pipeline(src)
return parent.reagents
build_network()
if(!parent)
parent = new /datum/water/pipeline()
parent.build_pipeline(src)
return parent.return_network()
network_expand(datum/water/pipe_network/new_network, obj/machinery/water/pipe/reference)
if(!parent)
parent = new /datum/water/pipeline()
parent.build_pipeline(src)
return parent.network_expand(new_network, reference)
return_network(obj/machinery/water/reference)
if(!parent)
parent = new /datum/water/pipeline()
parent.build_pipeline(src)
return parent.return_network(reference)
Del()
var/turf/simulated/target = get_turf(loc)
if(istype(target) && parent)
parent.mingle_with_turf(target, \
parent.reagents.total_volume / parent.reagents.maximum_volume * max_volume)
del(parent)
..()
simple
icon = 'pipes.dmi'
icon_state = "intact-f"
name = "pipe"
desc = "A one meter section of regular pipe"
max_volume = 500
dir = SOUTH
initialize_directions = SOUTH|NORTH
var/obj/machinery/water/node1
var/obj/machinery/water/node2
var/burst_pressure = 2.8*ONE_ATMOSPHERE
var/fatigue_pressure = 2.5*ONE_ATMOSPHERE
level = 1
New()
..()
switch(dir)
if(SOUTH || NORTH)
initialize_directions = SOUTH|NORTH
if(EAST || WEST)
initialize_directions = EAST|WEST
if(NORTHEAST)
initialize_directions = NORTH|EAST
if(NORTHWEST)
initialize_directions = NORTH|WEST
if(SOUTHEAST)
initialize_directions = SOUTH|EAST
if(SOUTHWEST)
initialize_directions = SOUTH|WEST
hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
process()
if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle
..()
else
machines.Remove(src)
/*if(!node1)
parent.mingle_with_turf(loc, volume)
if(!nodealert)
//world << "Missing node from [src] at [src.x],[src.y],[src.z]"
nodealert = 1
else if(!node2)
parent.mingle_with_turf(loc, volume)
if(!nodealert)
//world << "Missing node from [src] at [src.x],[src.y],[src.z]"
nodealert = 1
else if (nodealert)
nodealert = 0
else if(parent)
var/environment_temperature = 0
if(istype(loc, /turf/simulated/))
if(loc:blocks_air)
environment_temperature = loc:temperature
else
var/datum/gas_mixture/environment = loc.return_air()
environment_temperature = environment.temperature
else
environment_temperature = loc:temperature
var/datum/gas_mixture/pipe_air = return_air()
if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference)
parent.temperature_interact(loc, volume, thermal_conductivity)
*/ //Screw you heat lag
check_pressure(pressure)
var/datum/gas_mixture/environment = loc.return_air()
var/pressure_difference = pressure - environment.return_pressure()
if(pressure_difference > burst_pressure)
burst()
else if(pressure_difference > fatigue_pressure)
//TODO: leak to turf, doing pfshhhhh
if(prob(5))
burst()
else return 1
proc/burst()
src.visible_message("\red \bold [src] bursts!");
playsound(src.loc, 'bang.ogg', 25, 1)
var/obj/effect/effect/water/W = new(get_turf(src))
W.reagents = reagents
W.reagents.my_atom = W
if(!W) return
W.reagents.reaction(get_turf(W))
for(var/atom/atm in get_turf(W))
if(!W) return
W.reagents.reaction(atm)
sleep(1)
del(src)
proc/normalize_dir()
if(dir==3)
dir = 1
else if(dir==12)
dir = 4
Del()
if(node1)
node1.disconnect(src)
if(node2)
node2.disconnect(src)
..()
pipeline_expansion()
return list(node1, node2)
update_icon()
if(node1&&node2)
var/C = ""
switch(color)
if ("red") C = "-r"
if ("blue") C = "-b"
if ("cyan") C = "-c"
if ("green") C = "-g"
if ("yellow") C = "-y"
if ("purple") C = "-p"
icon_state = "intact[C][invisibility ? "-f" : "" ]"
//var/node1_direction = get_dir(src, node1)
//var/node2_direction = get_dir(src, node2)
//dir = node1_direction|node2_direction
else
if(!node1&&!node2)
del(src) //TODO: silent deleting looks weird
var/have_node1 = node1?1:0
var/have_node2 = node2?1:0
icon_state = "exposed[have_node1][have_node2][invisibility ? "-f" : "" ]"
initialize()
normalize_dir()
var/node1_dir
var/node2_dir
for(var/direction in cardinal)
if(direction&initialize_directions)
if (!node1_dir)
node1_dir = direction
else if (!node2_dir)
node2_dir = direction
for(var/obj/machinery/water/target in get_step(src,node1_dir))
if(target.initialize_directions & get_dir(target,src))
node1 = target
break
for(var/obj/machinery/water/target in get_step(src,node2_dir))
if(target.initialize_directions & get_dir(target,src))
node2 = target
break
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
update_icon()
//update_icon()
disconnect(obj/machinery/water/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/water/pipe))
del(parent)
node1 = null
if(reference == node2)
if(istype(node2, /obj/machinery/water/pipe))
del(parent)
node2 = null
update_icon()
return null
simple/drainage
name="Drainage pipe"
color="yellow"
icon_state = ""
simple/drainage_waste
name="Drainage waste pipe"
color="green"
icon_state = ""
simple/supply
name="Water supply pipe"
color="cyan"
icon_state = ""
New()
..()
reagents_temporary = new(max_volume)
reagents_temporary.my_atom = src
reagents_temporary.add_reagent("water", max_volume / 3)
simple/general
name="Water pipe"
color=""
icon_state = ""
simple/drainage/visible
level = 2
icon_state = "intact-y"
simple/drainage/hidden
level = 1
icon_state = "intact-y-f"
simple/drainage_waste/visible
level = 2
icon_state = "intact-g"
simple/drainage_waste/hidden
level = 1
icon_state = "intact-g-f"
simple/supply/visible
level = 2
icon_state = "intact-c"
simple/supply/hidden
level = 1
icon_state = "intact-c-f"
simple/general/visible
level = 2
icon_state = "intact"
simple/general/hidden
level = 1
icon_state = "intact-f"
tank
icon = 'pipe_tank.dmi'
icon_state = "intact"
name = "Pressure Tank"
desc = "A large vessel containing pressurized liquid."
max_volume = 23000
max_pressure = 4*ONE_ATMOSPHERE
dir = SOUTH
initialize_directions = SOUTH
density = 1
var/obj/machinery/water/node1
New()
initialize_directions = dir
reagents_temporary = new(max_volume)
reagents_temporary.my_atom = src
..()
process()
if(!parent)
..()
else
machines.Remove(src)
/* if(!node1)
parent.mingle_with_turf(loc, 200)
if(!nodealert)
//world << "Missing node from [src] at [src.x],[src.y],[src.z]"
nodealert = 1
else if (nodealert)
nodealert = 0
*/
water
name = "Pressure Tank (Water)"
icon = 'blue_water_tank.dmi'
New()
..()
reagents_temporary.add_reagent("water", max_volume * 0.95)
sugar_water
name = "Pressure Tank (Sugar Water)"
New()
..()
reagents_temporary.add_reagent("water", max_volume * 0.475)
reagents_temporary.add_reagent("sugar", max_volume * 0.475)
blue_paint
name = "Pressure Tank (Blue Paint)"
icon = 'blue_pipe_tank.dmi'
New()
..()
reagents_temporary.add_reagent("paint_blue", max_volume * 0.95)
Del()
if(node1)
node1.disconnect(src)
..()
pipeline_expansion()
return list(node1)
update_icon()
if(node1)
icon_state = "intact"
dir = get_dir(src, node1)
else
icon_state = "exposed"
initialize()
var/connect_direction = dir
for(var/obj/machinery/water/target in get_step(src,connect_direction))
if(target.initialize_directions & get_dir(target,src))
node1 = target
break
update_icon()
disconnect(obj/machinery/water/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/water/pipe))
del(parent)
node1 = null
update_icon()
return null
/* currently pointless because reagents can't just sit on a turf (currently)
drain
icon = 'pipe_vent.dmi'
icon_state = "intact"
name = "Drain"
desc = "A large drain"
level = 1
max_volume = 200
dir = SOUTH
initialize_directions = SOUTH
var/build_killswitch = 1
var/obj/machinery/water/node1
New()
initialize_directions = dir
..()
process()
if(!parent)
if(build_killswitch <= 0)
machines.Remove(src)
else
build_killswitch--
..()
return
else
var/pressure = parent.return_pressure()
var/datum/gas_mixture/env_air = loc.return_air()
if(env_air.return_pressure() > pressure)
parent.mingle_with_turf(loc, 200)
/*
if(!node1)
if(!nodealert)
//world << "Missing node from [src] at [src.x],[src.y],[src.z]"
nodealert = 1
else if (nodealert)
nodealert = 0
*/
Del()
if(node1)
node1.disconnect(src)
..()
pipeline_expansion()
return list(node1)
update_icon()
if(node1)
icon_state = "intact"
dir = get_dir(src, node1)
else
icon_state = "exposed"
initialize()
var/connect_direction = dir
for(var/obj/machinery/water/target in get_step(src,connect_direction))
if(target.initialize_directions & get_dir(target,src))
node1 = target
break
update_icon()
disconnect(obj/machinery/water/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/water/pipe))
del(parent)
node1 = null
update_icon()
return null
hide(var/i) //to make the little pipe section invisible, the icon changes.
if(node1)
icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]intact"
dir = get_dir(src, node1)
else
icon_state = "exposed"
*/
manifold
icon = 'pipe_manifold.dmi'
icon_state = "manifold-f"
name = "pipe manifold"
desc = "A liquid manifold composed of regular pipes"
max_volume = 750
dir = SOUTH
initialize_directions = EAST|NORTH|WEST
var/obj/machinery/water/node1
var/obj/machinery/water/node2
var/obj/machinery/water/node3
level = 1
New()
..()
switch(dir)
if(NORTH)
initialize_directions = EAST|SOUTH|WEST
if(SOUTH)
initialize_directions = WEST|NORTH|EAST
if(EAST)
initialize_directions = SOUTH|WEST|NORTH
if(WEST)
initialize_directions = NORTH|EAST|SOUTH
hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
pipeline_expansion()
return list(node1, node2, node3)
process()
if(!parent)
..()
else
machines.Remove(src)
/*
if(!node1)
parent.mingle_with_turf(loc, 70)
if(!nodealert)
//world << "Missing node from [src] at [src.x],[src.y],[src.z]"
nodealert = 1
else if(!node2)
parent.mingle_with_turf(loc, 70)
if(!nodealert)
//world << "Missing node from [src] at [src.x],[src.y],[src.z]"
nodealert = 1
else if(!node3)
parent.mingle_with_turf(loc, 70)
if(!nodealert)
//world << "Missing node from [src] at [src.x],[src.y],[src.z]"
nodealert = 1
else if (nodealert)
nodealert = 0
*/
Del()
if(node1)
node1.disconnect(src)
if(node2)
node2.disconnect(src)
if(node3)
node3.disconnect(src)
..()
disconnect(obj/machinery/water/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/water/pipe))
del(parent)
node1 = null
if(reference == node2)
if(istype(node2, /obj/machinery/water/pipe))
del(parent)
node2 = null
if(reference == node3)
if(istype(node3, /obj/machinery/water/pipe))
del(parent)
node3 = null
update_icon()
..()
update_icon()
if(node1&&node2&&node3)
var/C = ""
switch(color)
if ("red") C = "-r"
if ("blue") C = "-b"
if ("cyan") C = "-c"
if ("green") C = "-g"
if ("yellow") C = "-y"
if ("purple") C = "-p"
icon_state = "manifold[C][invisibility ? "-f" : ""]"
else
var/connected = 0
var/unconnected = 0
var/connect_directions = (NORTH|SOUTH|EAST|WEST)&(~dir)
if(node1)
connected |= get_dir(src, node1)
if(node2)
connected |= get_dir(src, node2)
if(node3)
connected |= get_dir(src, node3)
unconnected = (~connected)&(connect_directions)
icon_state = "manifold_[connected]_[unconnected]"
if(!connected)
del(src)
return
initialize()
var/connect_directions = (NORTH|SOUTH|EAST|WEST)&(~dir)
for(var/direction in cardinal)
if(direction&connect_directions)
for(var/obj/machinery/water/target in get_step(src,direction))
if(target.initialize_directions & get_dir(target,src))
node1 = target
connect_directions &= ~direction
break
if (node1)
break
for(var/direction in cardinal)
if(direction&connect_directions)
for(var/obj/machinery/water/target in get_step(src,direction))
if(target.initialize_directions & get_dir(target,src))
node2 = target
connect_directions &= ~direction
break
if (node2)
break
for(var/direction in cardinal)
if(direction&connect_directions)
for(var/obj/machinery/water/target in get_step(src,direction))
if(target.initialize_directions & get_dir(target,src))
node3 = target
connect_directions &= ~direction
break
if (node3)
break
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
//update_icon()
update_icon()
manifold/drainage
name="Drainage pipe"
color="yellow"
icon_state = ""
manifold/drainage_waste
name="Drainage waste pipe"
color="green"
icon_state = ""
manifold/supply
name="Water supply pipe"
color="cyan"
icon_state = ""
New()
..()
reagents_temporary = new(max_volume)
reagents_temporary.my_atom = src
reagents_temporary.add_reagent("water", max_volume / 3)
manifold/general
name="Water pipe"
color="gray"
icon_state = ""
manifold/drainage/visible
level = 2
icon_state = "manifold-y"
manifold/drainage/hidden
level = 1
icon_state = "manifold-y-f"
manifold/drainage_waste/visible
level = 2
icon_state = "manifold-g"
manifold/drainage_waste/hidden
level = 1
icon_state = "manifold-g-f"
manifold/supply/visible
level = 2
icon_state = "manifold-c"
manifold/supply/hidden
level = 1
icon_state = "manifold-c-f"
manifold/general/visible
level = 2
icon_state = "manifold"
manifold/general/hidden
level = 1
icon_state = "manifold-f"
manifold4w
icon = 'pipe_manifold.dmi'
icon_state = "manifold4w-f"
name = "4-way pipe manifold"
desc = "A liquid manifold composed of regular pipes"
max_volume = 1000
dir = SOUTH
initialize_directions = EAST|NORTH|WEST|SOUTH
var/obj/machinery/water/node1
var/obj/machinery/water/node2
var/obj/machinery/water/node3
var/obj/machinery/water/node4
level = 1
hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
pipeline_expansion()
return list(node1, node2, node3, node4)
process()
if(!parent)
..()
else
machines.Remove(src)
/*
if(!node1)
parent.mingle_with_turf(loc, 70)
if(!nodealert)
//world << "Missing node from [src] at [src.x],[src.y],[src.z]"
nodealert = 1
else if(!node2)
parent.mingle_with_turf(loc, 70)
if(!nodealert)
//world << "Missing node from [src] at [src.x],[src.y],[src.z]"
nodealert = 1
else if(!node3)
parent.mingle_with_turf(loc, 70)
if(!nodealert)
//world << "Missing node from [src] at [src.x],[src.y],[src.z]"
nodealert = 1
else if (nodealert)
nodealert = 0
*/
Del()
if(node1)
node1.disconnect(src)
if(node2)
node2.disconnect(src)
if(node3)
node3.disconnect(src)
if(node4)
node4.disconnect(src)
..()
disconnect(obj/machinery/water/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/water/pipe))
del(parent)
node1 = null
if(reference == node2)
if(istype(node2, /obj/machinery/water/pipe))
del(parent)
node2 = null
if(reference == node3)
if(istype(node3, /obj/machinery/water/pipe))
del(parent)
node3 = null
if(reference == node4)
if(istype(node4, /obj/machinery/water/pipe))
del(parent)
node3 = null
update_icon()
..()
update_icon()
overlays = new()
if(node1&&node2&&node3&&node4)
var/C = ""
switch(color)
if ("red") C = "-r"
if ("blue") C = "-b"
if ("cyan") C = "-c"
if ("green") C = "-g"
if ("yellow") C = "-y"
if ("purple") C = "-p"
icon_state = "manifold4w[C][invisibility ? "-f" : ""]"
else
icon_state = "manifold4w_ex"
var/icon/con = new/icon('pipe_manifold.dmi',"manifold4w_con")
if(node1)
overlays += new/image(con,dir=1)
if(node2)
overlays += new/image(con,dir=2)
if(node3)
overlays += new/image(con,dir=4)
if(node4)
overlays += new/image(con,dir=8)
if(!node1 && !node2 && !node3 && !node4)
del(src)
return
initialize()
for(var/obj/machinery/water/target in get_step(src,1))
if(target.initialize_directions & get_dir(target,src))
node1 = target
break
for(var/obj/machinery/water/target in get_step(src,2))
if(target.initialize_directions & get_dir(target,src))
node2 = target
break
for(var/obj/machinery/water/target in get_step(src,4))
if(target.initialize_directions & get_dir(target,src))
node3 = target
break
for(var/obj/machinery/water/target in get_step(src,8))
if(target.initialize_directions & get_dir(target,src))
node4 = target
break
var/turf/T = src.loc // hide if turf is not intact
hide(T.intact)
//update_icon()
update_icon()
manifold4w/drainage
name="Drainage pipe"
color="yellow"
icon_state = ""
manifold4w/drainage_waste
name="Drainage waste pipe"
color="green"
icon_state = ""
manifold4w/supply
name="Water supply pipe"
color="cyan"
icon_state = ""
New()
..()
reagents_temporary = new(max_volume)
reagents_temporary.my_atom = src
reagents_temporary.add_reagent("water", max_volume / 3)
manifold4w/general
name="Water pipe"
color="gray"
icon_state = ""
manifold4w/drainage/visible
level = 2
icon_state = "manifold4w-y"
manifold4w/drainage/hidden
level = 1
icon_state = "manifold4w-y-f"
manifold4w/drainage_waste/visible
level = 2
icon_state = "manifold4w-g"
manifold4w/drainage_waste/hidden
level = 1
icon_state = "manifold4w-g-f"
manifold4w/supply/visible
level = 2
icon_state = "manifold4w-c"
manifold4w/supply/hidden
level = 1
icon_state = "manifold4w-c-f"
manifold4w/general/visible
level = 2
icon_state = "manifold4w"
manifold4w/general/hidden
level = 1
icon_state = "manifold4w-f"
obj/machinery/water/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (istype(src, /obj/machinery/water/pipe/tank))
return ..()
if (istype(W, /obj/item/device/pda)) // allow reagent scanner to work
return
//if (istype(src, /obj/machinery/water/pipe/drain))
// return ..()
if (!istype(W, /obj/item/weapon/wrench))
return ..()
var/turf/T = src.loc
if (level==1 && isturf(T) && T.intact)
user << "\red You must remove the plating first."
return 1
var/datum/gas_mixture/env_air = loc.return_air()
if ((parent.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
user << "\red You cannot unwrench this [src], it too exerted due to internal pressure."
add_fingerprint(user)
return 1
playsound(src.loc, 'Ratchet.ogg', 50, 1)
user << "\blue You begin to unfasten \the [src]..."
if (do_after(user, 40))
user.visible_message( \
"[user] unfastens \the [src].", \
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/water_pipe(loc, make_from=src)
for (var/obj/machinery/water_meter/meter in T)
if (meter.target == src)
new /obj/item/water_pipe_meter(T)
del(meter)
del(src)