mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
/tg/ Plumbing on yogs
This commit is contained in:
7
code/__DEFINES/plumbing.dm
Normal file
7
code/__DEFINES/plumbing.dm
Normal file
@@ -0,0 +1,7 @@
|
||||
#define FIRST_DUCT_LAYER 1
|
||||
#define SECOND_DUCT_LAYER 2
|
||||
#define THIRD_DUCT_LAYER 4
|
||||
#define FOURTH_DUCT_LAYER 8
|
||||
#define FIFTH_DUCT_LAYER 16
|
||||
|
||||
#define DUCT_LAYER_DEFAULT THIRD_DUCT_LAYER
|
||||
5
code/controllers/subsystem/processing/fluids.dm
Normal file
5
code/controllers/subsystem/processing/fluids.dm
Normal file
@@ -0,0 +1,5 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(fluids)
|
||||
name = "Fluids"
|
||||
wait = 20
|
||||
stat_tag = "FD" //its actually Fluid Ducts
|
||||
flags = SS_NO_INIT | SS_TICKER
|
||||
173
code/datums/components/plumbing/plumbing.dm
Normal file
173
code/datums/components/plumbing/plumbing.dm
Normal file
@@ -0,0 +1,173 @@
|
||||
/datum/component/plumbing
|
||||
var/list/datum/ductnet/ducts = list() //Index with "1" = /datum/ductnet/theductpointingnorth etc. "1" being the num2text from NORTH define
|
||||
var/datum/reagents/reagents
|
||||
var/use_overlays = TRUE //TRUE if we wanna add proper pipe outless under our parent object
|
||||
var/list/image/ducterlays //We can't just cut all of the parents' overlays, so we'll track them here
|
||||
|
||||
var/supply_connects //directions in wich we act as a supplier
|
||||
var/demand_connects //direction in wich we act as a demander
|
||||
|
||||
var/active = FALSE //FALSE to pretty much just not exist in the plumbing world so we can be moved, TRUE to go plumbo mode
|
||||
var/turn_connects = TRUE
|
||||
|
||||
/datum/component/plumbing/Initialize(start=TRUE, _turn_connects=TRUE) //turn_connects for wheter or not we spin with the object to change our pipes
|
||||
if(parent && !ismovableatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
var/atom/movable/AM = parent
|
||||
if(!AM.reagents)
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
reagents = AM.reagents
|
||||
turn_connects = _turn_connects
|
||||
|
||||
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED,COMSIG_PARENT_PREQDELETED), .proc/disable)
|
||||
|
||||
if(start)
|
||||
start()
|
||||
|
||||
if(use_overlays)
|
||||
create_overlays()
|
||||
|
||||
/datum/component/plumbing/process()
|
||||
if(!demand_connects || !reagents)
|
||||
STOP_PROCESSING(SSfluids, src)
|
||||
return
|
||||
if(reagents.total_volume < reagents.maximum_volume)
|
||||
for(var/D in GLOB.cardinals)
|
||||
if(D & demand_connects)
|
||||
send_request(D)
|
||||
|
||||
/datum/component/plumbing/proc/can_add(datum/ductnet/D, dir)
|
||||
if(!active)
|
||||
return
|
||||
if(!dir || !D)
|
||||
return FALSE
|
||||
if(num2text(dir) in ducts)
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/component/plumbing/proc/send_request(dir) //this should usually be overwritten when dealing with custom pipes
|
||||
process_request(amount = 10, reagent = null, dir = dir)
|
||||
|
||||
/datum/component/plumbing/proc/process_request(amount, reagent, dir)
|
||||
var/list/valid_suppliers = list()
|
||||
var/datum/ductnet/net
|
||||
if(!ducts.Find(num2text(dir)))
|
||||
return
|
||||
net = ducts[num2text(dir)]
|
||||
for(var/A in net.suppliers)
|
||||
var/datum/component/plumbing/supplier = A
|
||||
if(supplier.can_give(amount, reagent))
|
||||
valid_suppliers += supplier
|
||||
for(var/A in valid_suppliers)
|
||||
var/datum/component/plumbing/give = A
|
||||
give.transfer_to(src, amount / valid_suppliers.len, reagent)
|
||||
|
||||
/datum/component/plumbing/proc/can_give(amount, reagent)
|
||||
if(!reagents || amount <= 0)
|
||||
return
|
||||
|
||||
if(reagent) //only asked for one type of reagent
|
||||
if(reagent in reagents.reagent_list)
|
||||
return TRUE
|
||||
else if(reagents.total_volume > 0) //take whatever
|
||||
return TRUE
|
||||
|
||||
/datum/component/plumbing/proc/transfer_to(datum/component/plumbing/target, amount, reagent)
|
||||
if(!reagents || !target || !target.reagents)
|
||||
return FALSE
|
||||
if(reagent)
|
||||
reagents.trans_id_to(target.reagents, reagent, amount)
|
||||
else
|
||||
reagents.trans_to(target.reagents, amount)
|
||||
|
||||
/datum/component/plumbing/proc/create_overlays()
|
||||
var/atom/movable/AM = parent
|
||||
for(var/image/I in ducterlays)
|
||||
AM.overlays.Remove(I)
|
||||
qdel(I)
|
||||
ducterlays = list()
|
||||
for(var/D in GLOB.cardinals)
|
||||
var/color
|
||||
var/direction
|
||||
if(D & demand_connects)
|
||||
color = "red" //red because red is mean and it takes
|
||||
else if(D & supply_connects)
|
||||
color = "blue" //blue is nice and gives
|
||||
else
|
||||
continue
|
||||
var/image/I
|
||||
if(turn_connects)
|
||||
switch(D)
|
||||
if(NORTH)
|
||||
direction = "north"
|
||||
if(SOUTH)
|
||||
direction = "south"
|
||||
if(EAST)
|
||||
direction = "east"
|
||||
if(WEST)
|
||||
direction = "west"
|
||||
I = image('icons/obj/plumbing/plumbers.dmi', "[direction]-[color]", layer = AM.layer - 1)
|
||||
else
|
||||
I = image('icons/obj/plumbing/plumbers.dmi', color, layer = AM.layer - 1) //color is not color as in the var, it's just the name
|
||||
I.dir = D
|
||||
AM.add_overlay(I)
|
||||
ducterlays += I
|
||||
|
||||
/datum/component/plumbing/proc/disable() //we stop acting like a plumbing thing and disconnect if we are, so we can safely be moved and stuff
|
||||
if(!active)
|
||||
return
|
||||
STOP_PROCESSING(SSfluids, src)
|
||||
for(var/A in ducts)
|
||||
var/datum/ductnet/D = ducts[A]
|
||||
D.remove_plumber(src)
|
||||
|
||||
active = FALSE
|
||||
|
||||
/datum/component/plumbing/proc/start() //settle wherever we are, and start behaving like a piece of plumbing
|
||||
if(active)
|
||||
return
|
||||
update_dir()
|
||||
active = TRUE
|
||||
|
||||
if(demand_connects)
|
||||
START_PROCESSING(SSfluids, src)
|
||||
|
||||
for(var/D in GLOB.cardinals)
|
||||
if(D & (demand_connects + supply_connects))
|
||||
for(var/obj/machinery/duct/duct in get_step(parent, D))
|
||||
var/turned_dir = turn(D, 180)
|
||||
if(turned_dir & duct.connects)
|
||||
duct.attempt_connect()
|
||||
|
||||
//TODO: Let plumbers directly plumb into one another without ducts if placed adjacent to each other
|
||||
|
||||
/datum/component/plumbing/proc/update_dir() //note that this is only called when we settle down. If someone wants it to fucking spin while connected to something go actually knock yourself out
|
||||
if(!turn_connects)
|
||||
return
|
||||
var/atom/movable/AM = parent
|
||||
var/new_demand_connects
|
||||
var/new_supply_connects
|
||||
var/new_dir = AM.dir
|
||||
var/angle = 180 - dir2angle(new_dir)
|
||||
if(new_dir == SOUTH)
|
||||
demand_connects = initial(demand_connects)
|
||||
supply_connects = initial(supply_connects)
|
||||
else
|
||||
for(var/D in GLOB.cardinals)
|
||||
if(D & initial(demand_connects))
|
||||
new_demand_connects += turn(D, angle)
|
||||
if(D & initial(supply_connects))
|
||||
new_supply_connects += turn(D, angle)
|
||||
demand_connects = new_demand_connects
|
||||
supply_connects = new_supply_connects
|
||||
|
||||
/datum/component/plumbing/simple_demand
|
||||
demand_connects = NORTH
|
||||
|
||||
/datum/component/plumbing/simple_supply
|
||||
supply_connects = NORTH
|
||||
|
||||
/datum/component/plumbing/tank
|
||||
demand_connects = WEST
|
||||
supply_connects = EAST
|
||||
60
code/datums/ductnet.dm
Normal file
60
code/datums/ductnet.dm
Normal file
@@ -0,0 +1,60 @@
|
||||
/datum/ductnet
|
||||
var/list/suppliers = list()
|
||||
var/list/demanders = list()
|
||||
var/list/obj/machinery/duct/ducts = list()
|
||||
|
||||
var/capacity
|
||||
|
||||
/datum/ductnet/proc/add_duct(obj/machinery/duct/D)
|
||||
if(!D || D in ducts)
|
||||
return
|
||||
ducts += D
|
||||
D.duct = src
|
||||
|
||||
/datum/ductnet/proc/remove_duct(obj/machinery/duct/ducting)
|
||||
destroy_network(FALSE)
|
||||
for(var/A in ducting.neighbours)
|
||||
var/obj/machinery/duct/D = A
|
||||
D.attempt_connect() //we destroyed the network, so now we tell the disconnected ducts neighbours they can start making a new ductnet
|
||||
qdel(src)
|
||||
|
||||
/datum/ductnet/proc/add_plumber(datum/component/plumbing/P, dir)
|
||||
if(!P.can_add(src, dir))
|
||||
return
|
||||
P.ducts[num2text(dir)] = src
|
||||
if(dir & P.supply_connects)
|
||||
suppliers += P
|
||||
else if(dir & P.demand_connects)
|
||||
demanders += P
|
||||
|
||||
/datum/ductnet/proc/remove_plumber(datum/component/plumbing/P)
|
||||
suppliers.Remove(P) //we're probably only in one of these, but Remove() is inherently sane so this is fine
|
||||
demanders.Remove(P)
|
||||
|
||||
for(var/dir in P.ducts)
|
||||
if(P.ducts[dir] == src)
|
||||
P.ducts -= dir
|
||||
|
||||
/datum/ductnet/proc/assimilate(datum/ductnet/D)
|
||||
ducts.Add(D.ducts)
|
||||
suppliers.Add(D.suppliers)
|
||||
demanders.Add(D.demanders)
|
||||
for(var/A in D.suppliers + D.demanders)
|
||||
var/datum/component/plumbing/P = A
|
||||
for(var/s in P.ducts)
|
||||
if(P.ducts[s] != D)
|
||||
continue
|
||||
P.ducts[s] = src //all your ducts are belong to us
|
||||
for(var/A in D.ducts)
|
||||
var/obj/machinery/duct/M = A
|
||||
M.duct = src //forget your old master
|
||||
qdel(D)
|
||||
|
||||
/datum/ductnet/proc/destroy_network(delete=TRUE)
|
||||
for(var/A in suppliers + demanders)
|
||||
remove_plumber(A)
|
||||
for(var/A in ducts)
|
||||
var/obj/machinery/duct/D = A
|
||||
D.duct = null
|
||||
if(delete) //I don't want code to run with qdeleted objects because that can never be good, so keep this in-case the ductnet has some business left to attend to before commiting suicide
|
||||
qdel(src)
|
||||
72
code/game/objects/structures/lavaland/geyser.dm
Normal file
72
code/game/objects/structures/lavaland/geyser.dm
Normal file
@@ -0,0 +1,72 @@
|
||||
//If you look at the "geyser_soup" overlay icon_state, you'll see that the first frame has 25 ticks.
|
||||
//That's because the first 18~ ticks are completely skipped for some ungodly weird fucking byond reason
|
||||
|
||||
/obj/structure/geyser
|
||||
name = "geyser"
|
||||
icon = 'icons/obj/lavaland/terrain.dmi'
|
||||
icon_state = "geyser"
|
||||
anchored = TRUE
|
||||
|
||||
var/erupting_state = null //set to null to get it greyscaled from "[icon_state]_soup". Not very usable with the whole random thing, but more types can be added if you change the spawn prob
|
||||
var/activated = FALSE //whether we are active and generating chems
|
||||
var/reagent_id = /datum/reagent/oil
|
||||
var/potency = 2 //how much reagents we add every process (2 seconds)
|
||||
var/max_volume = 500
|
||||
var/start_volume = 50
|
||||
|
||||
/obj/structure/geyser/proc/start_chemming()
|
||||
activated = TRUE
|
||||
create_reagents(max_volume, DRAINABLE)
|
||||
reagents.add_reagent(reagent_id, start_volume)
|
||||
START_PROCESSING(SSfluids, src) //It's main function is to be plumbed, so use SSfluids
|
||||
if(erupting_state)
|
||||
icon_state = erupting_state
|
||||
else
|
||||
var/mutable_appearance/I = mutable_appearance('icons/obj/lavaland/terrain.dmi', "[icon_state]_soup")
|
||||
I.color = mix_color_from_reagents(reagents.reagent_list)
|
||||
add_overlay(I)
|
||||
|
||||
/obj/structure/geyser/process()
|
||||
if(activated && reagents.total_volume <= reagents.maximum_volume) //this is also evaluated in add_reagent, but from my understanding proc calls are expensive and should be avoided in continous
|
||||
reagents.add_reagent(reagent_id, potency) //processes
|
||||
|
||||
/obj/structure/geyser/plunger_act(obj/item/plunger/P, mob/living/user, _reinforced)
|
||||
if(!_reinforced)
|
||||
to_chat(user, "<span class='warning'>The [P.name] isn't strong enough!</span>")
|
||||
return
|
||||
if(activated)
|
||||
to_chat(user, "<span class'warning'>The [name] is already active!")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You start vigorously plunging [src]!")
|
||||
if(do_after(user, 50*P.plunge_mod, target = src) && !activated)
|
||||
start_chemming()
|
||||
|
||||
/obj/structure/geyser/random
|
||||
erupting_state = null
|
||||
var/list/options = list(/datum/reagent/oil = 2, /datum/reagent/clf3 = 1) //fucking add more
|
||||
|
||||
/obj/structure/geyser/random/Initialize()
|
||||
. = ..()
|
||||
reagent_id = pickweight(options)
|
||||
|
||||
/obj/item/plunger
|
||||
name = "plunger"
|
||||
desc = "It's a plunger for plunging."
|
||||
icon = 'icons/obj/watercloset.dmi'
|
||||
icon_state = "plunger"
|
||||
|
||||
var/plunge_mod = 1 //time*plunge_mod = total time we take to plunge an object
|
||||
var/reinforced = FALSE //whether we do heavy duty stuff like geysers
|
||||
|
||||
/obj/item/plunger/attack_obj(obj/O, mob/living/user)
|
||||
if(!O.plunger_act(src, user, reinforced))
|
||||
return ..()
|
||||
|
||||
/obj/item/plunger/reinforced
|
||||
name = "reinforced plunger"
|
||||
desc = " It's an M. 7 Reinforced Plunger<65> for heavy duty plunging."
|
||||
icon_state = "reinforced_plunger"
|
||||
|
||||
reinforced = TRUE
|
||||
plunge_mod = 0.8
|
||||
279
code/modules/plumbing/ducts.dm
Normal file
279
code/modules/plumbing/ducts.dm
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
All the important duct code:
|
||||
/code/datums/components/plumbing/plumbing.dm
|
||||
/code/datums/ductnet.dm
|
||||
*/
|
||||
/obj/machinery/duct
|
||||
name = "fluid duct"
|
||||
icon = 'icons/obj/plumbing/fluid_ducts.dmi'
|
||||
icon_state = "nduct"
|
||||
|
||||
var/connects
|
||||
var/dumb = FALSE //set to TRUE to disable smart cable behaviour
|
||||
var/lock_connects = FALSE //wheter we allow our connects to be changed after initialization or not
|
||||
var/datum/ductnet/duct
|
||||
var/capacity = 10
|
||||
|
||||
var/duct_color = null
|
||||
var/ignore_colors = FALSE //TRUE to ignore colors, so yeah we also connect with other colors without issue
|
||||
var/duct_layer = DUCT_LAYER_DEFAULT //1,2,4,8,16
|
||||
var/lock_layers = FALSE //whether we allow our layers to be altered
|
||||
var/color_to_color_support = TRUE //TRUE to let colors connect when forced with a wrench, false to just not do that at all
|
||||
|
||||
var/active = TRUE //wheter to even bother with plumbing code or not
|
||||
var/list/neighbours = list() //track ducts we're connected to. Mainly for ducts we connect to that we normally wouldn't, like different layers and colors, for when we regenerate the ducts
|
||||
|
||||
/obj/machinery/duct/Initialize(mapload, no_anchor, color_of_duct, layer_of_duct = DUCT_LAYER_DEFAULT, force_connects)
|
||||
. = ..()
|
||||
if(no_anchor)
|
||||
active = FALSE
|
||||
anchored = FALSE
|
||||
else if(!can_anchor())
|
||||
CRASH("Overlapping ducts detected")
|
||||
qdel(src)
|
||||
if(force_connects)
|
||||
connects = force_connects //skip change_connects() because we're still initializing and we need to set our connects at one point
|
||||
if(!lock_layers)
|
||||
duct_layer = layer_of_duct
|
||||
if(!ignore_colors)
|
||||
duct_color = color_of_duct
|
||||
if(duct_color)
|
||||
add_atom_colour(duct_color, FIXED_COLOUR_PRIORITY)
|
||||
handle_layer()
|
||||
for(var/obj/machinery/duct/D in loc)
|
||||
if(D == src)
|
||||
continue
|
||||
if(D.duct_layer & duct_layer)
|
||||
qdel(src) //replace with dropping or something
|
||||
if(active)
|
||||
attempt_connect()
|
||||
|
||||
/obj/machinery/duct/proc/attempt_connect()
|
||||
reset_connects(0) //All connects are gathered here again eitherway, we might aswell reset it so they properly update when reconnecting
|
||||
|
||||
for(var/D in GLOB.cardinals)
|
||||
if(dumb && !(D & connects))
|
||||
continue
|
||||
for(var/atom/movable/AM in get_step(src, D))
|
||||
if(connect_network(AM, D))
|
||||
add_connects(D)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/duct/proc/connect_network(atom/movable/AM, direction, ignore_color)
|
||||
if(istype(AM, /obj/machinery/duct))
|
||||
return connect_duct(AM, direction, ignore_color)
|
||||
|
||||
var/plumber = AM.GetComponent(/datum/component/plumbing)
|
||||
if(!plumber)
|
||||
return
|
||||
connect_plumber(plumber, direction)
|
||||
|
||||
/obj/machinery/duct/proc/connect_duct(obj/machinery/duct/D, direction, ignore_color)
|
||||
var/opposite_dir = turn(direction, 180)
|
||||
if(!active || !D.active)
|
||||
return
|
||||
|
||||
if(!dumb && D.dumb && !(opposite_dir & D.connects))
|
||||
return
|
||||
if(dumb && D.dumb && !(connects & D.connects)) //we eliminated a few more scenario in attempt connect
|
||||
return
|
||||
|
||||
if((duct == D.duct) && duct)//check if we're not just comparing two null values
|
||||
add_neighbour(D)
|
||||
|
||||
D.add_connects(opposite_dir)
|
||||
D.update_icon()
|
||||
return TRUE //tell the current pipe to also update it's sprite
|
||||
if(!(D in neighbours)) //we cool
|
||||
if((duct_color != D.duct_color) && !(ignore_colors || D.ignore_colors))
|
||||
return
|
||||
if(!(duct_layer & D.duct_layer))
|
||||
return
|
||||
|
||||
if(D.duct)
|
||||
if(duct)
|
||||
duct.assimilate(D.duct)
|
||||
else
|
||||
D.duct.add_duct(src)
|
||||
else
|
||||
if(duct)
|
||||
duct.add_duct(D)
|
||||
else
|
||||
create_duct()
|
||||
duct.add_duct(D)
|
||||
add_neighbour(D)
|
||||
D.attempt_connect()//tell our buddy its time to pass on the torch of connecting to pipes. This shouldn't ever infinitely loop since it only works on pipes that havent been inductrinated
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/duct/proc/connect_plumber(datum/component/plumbing/P, direction)
|
||||
var/opposite_dir = turn(direction, 180)
|
||||
if(duct_layer != DUCT_LAYER_DEFAULT) //plumbing devices don't support multilayering. 3 is the default layer so we only use that. We can change this later
|
||||
return
|
||||
var/comp_directions = P.supply_connects + P.demand_connects //they should never, ever have supply and demand connects overlap or catastrophic failure
|
||||
if(opposite_dir & comp_directions)
|
||||
if(duct)
|
||||
duct.add_plumber(P, opposite_dir)
|
||||
else
|
||||
create_duct()
|
||||
duct.add_plumber(P, opposite_dir)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/duct/proc/disconnect_duct()
|
||||
anchored = FALSE
|
||||
active = FALSE
|
||||
if(duct)
|
||||
duct.remove_duct(src)
|
||||
lose_neighbours()
|
||||
reset_connects(0)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/duct/proc/create_duct()
|
||||
duct = new()
|
||||
duct.add_duct(src)
|
||||
|
||||
/obj/machinery/duct/proc/add_neighbour(obj/machinery/duct/D)
|
||||
if(!(D in neighbours))
|
||||
neighbours += D
|
||||
if(!(src in D.neighbours))
|
||||
D.neighbours += src
|
||||
|
||||
/obj/machinery/duct/proc/lose_neighbours()
|
||||
for(var/A in neighbours)
|
||||
var/obj/machinery/duct/D = A
|
||||
D.neighbours.Remove(src)
|
||||
neighbours = list()
|
||||
|
||||
/obj/machinery/duct/proc/add_connects(new_connects) //make this a define to cut proc calls?
|
||||
if(!lock_connects)
|
||||
connects |= new_connects
|
||||
|
||||
/obj/machinery/duct/proc/reset_connects()
|
||||
if(!lock_connects)
|
||||
connects = 0
|
||||
|
||||
/obj/machinery/duct/proc/get_adjacent_ducts()
|
||||
var/list/adjacents = list()
|
||||
for(var/A in GLOB.cardinals)
|
||||
if(A & connects)
|
||||
for(var/obj/machinery/duct/D in get_step(src, A))
|
||||
if((turn(A, 180) & D.connects) && D.active)
|
||||
adjacents += D
|
||||
return adjacents
|
||||
|
||||
/obj/machinery/duct/update_icon() //setting connects isnt a parameter because sometimes we make more than one change, overwrite it completely or just add it to the bitfield
|
||||
var/temp_icon = initial(icon_state)
|
||||
for(var/D in GLOB.cardinals)
|
||||
if(D & connects)
|
||||
if(D == NORTH)
|
||||
temp_icon += "_n"
|
||||
if(D == SOUTH)
|
||||
temp_icon += "_s"
|
||||
if(D == EAST)
|
||||
temp_icon += "_e"
|
||||
if(D == WEST)
|
||||
temp_icon += "_w"
|
||||
icon_state = temp_icon
|
||||
|
||||
/obj/machinery/duct/proc/handle_layer()
|
||||
var/offset
|
||||
switch(duct_layer)//it's a bitfield, but it's fine because it only works when there's one layer, and multiple layers should be handled differently
|
||||
if(FIRST_DUCT_LAYER)
|
||||
offset = -10
|
||||
if(SECOND_DUCT_LAYER)
|
||||
offset = -5
|
||||
if(THIRD_DUCT_LAYER)
|
||||
offset = 0
|
||||
if(FOURTH_DUCT_LAYER)
|
||||
offset = 5
|
||||
if(FIFTH_DUCT_LAYER)
|
||||
offset = 10
|
||||
pixel_x = offset
|
||||
pixel_y = offset
|
||||
|
||||
|
||||
/obj/machinery/duct/wrench_act(mob/living/user, obj/item/I) //I can also be the RPD
|
||||
add_fingerprint(user)
|
||||
I.play_tool_sound(src)
|
||||
if(anchored)
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"<span class='notice'>You unfasten \the [src].</span>", \
|
||||
"<span class='italics'>You hear ratcheting.</span>")
|
||||
disconnect_duct()
|
||||
else if(can_anchor())
|
||||
anchored = TRUE
|
||||
active = TRUE
|
||||
user.visible_message( \
|
||||
"[user] fastens \the [src].", \
|
||||
"<span class='notice'>You fasten \the [src].</span>", \
|
||||
"<span class='italics'>You hear ratcheting.</span>")
|
||||
attempt_connect()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/duct/proc/can_anchor(turf/T)
|
||||
if(!T)
|
||||
T = get_turf(src)
|
||||
for(var/obj/machinery/duct/D in T)
|
||||
if(!anchored)
|
||||
continue
|
||||
for(var/A in GLOB.cardinals)
|
||||
if(A & connects && A & D.connects)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/duct/doMove(destination)
|
||||
. = ..()
|
||||
disconnect_duct()
|
||||
anchored = FALSE
|
||||
|
||||
/obj/machinery/duct/Destroy()
|
||||
disconnect_duct()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/duct/MouseDrop_T(atom/A, mob/living/user)
|
||||
if(!istype(A, /obj/machinery/duct))
|
||||
return
|
||||
var/obj/machinery/duct/D = A
|
||||
var/obj/item/I = user.get_active_held_item()
|
||||
if(I?.tool_behaviour != TOOL_WRENCH)
|
||||
to_chat(user, "<span class='warning'>You need to be holding a wrench in your active hand to do that!</span>")
|
||||
return
|
||||
if(get_dist(src, D) != 1)
|
||||
return
|
||||
var/direction = get_dir(src, D)
|
||||
if(!(direction in GLOB.cardinals))
|
||||
return
|
||||
connect_network(D, direction, TRUE)
|
||||
add_connects(direction)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/duct/multilayered
|
||||
name = "duct layer-manifold"
|
||||
icon = 'icons/obj/2x2.dmi'
|
||||
icon_state = "multiduct"
|
||||
|
||||
|
||||
color_to_color_support = FALSE
|
||||
duct_layer = FIRST_DUCT_LAYER + SECOND_DUCT_LAYER + THIRD_DUCT_LAYER + FOURTH_DUCT_LAYER + FIFTH_DUCT_LAYER
|
||||
|
||||
lock_connects = TRUE
|
||||
lock_layers = TRUE
|
||||
ignore_colors = TRUE
|
||||
dumb = TRUE
|
||||
|
||||
|
||||
/obj/machinery/duct/multilayered/update_icon()
|
||||
icon_state = initial(icon_state)
|
||||
if((connects & NORTH) || (connects & SOUTH))
|
||||
icon_state += "_vertical"
|
||||
pixel_x = -15
|
||||
pixel_y = -15
|
||||
else
|
||||
icon_state += "_horizontal"
|
||||
pixel_x = -10
|
||||
pixel_y = -12
|
||||
|
||||
/obj/machinery/duct/multilayered/connect_duct(obj/machinery/duct/D, direction, ignore_color)
|
||||
if(istype(D, /obj/machinery/duct/multilayered)) //don't connect to other multilayered stuff because honestly it shouldnt be done and I dont wanna deal with it
|
||||
return
|
||||
return ..()
|
||||
74
code/modules/plumbing/plumbers/pumps.dm
Normal file
74
code/modules/plumbing/plumbers/pumps.dm
Normal file
@@ -0,0 +1,74 @@
|
||||
/obj/machinery/power/liquid_pump
|
||||
name = "liquid pump"
|
||||
desc = "Pump up those sweet liquids from under the surface."
|
||||
icon = 'icons/obj/plumbing/plumbers.dmi'
|
||||
icon_state = "pump"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 1000
|
||||
|
||||
var/powered = FALSE
|
||||
var/pump_power = 2 //units we pump per process (2 seconds)
|
||||
|
||||
var/obj/structure/geyser/geyser
|
||||
var/volume = 200
|
||||
|
||||
|
||||
/obj/machinery/power/liquid_pump/Initialize()
|
||||
create_reagents(volume)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/liquid_pump/ComponentInitialize()
|
||||
AddComponent(/datum/component/plumbing/simple_supply)
|
||||
|
||||
/obj/machinery/power/liquid_pump/wrench_act(mob/living/user, obj/item/I)
|
||||
default_unfasten_wrench(user, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/liquid_pump/default_unfasten_wrench(mob/user, obj/item/I, time = 20)
|
||||
. = ..()
|
||||
if(. == SUCCESSFUL_UNFASTEN)
|
||||
toggle_active()
|
||||
|
||||
/obj/machinery/power/liquid_pump/proc/toggle_active(mob/user, obj/item/I) //we split this in a seperate proc so we can also deactivate if we got no geyser under us
|
||||
geyser = null
|
||||
if(user)
|
||||
user.visible_message("<span class='notice'>[user.name] [anchored ? "fasten" : "unfasten"] [src]</span>", \
|
||||
"<span class='notice'>You [anchored ? "fasten" : "unfasten"] [src]</span>")
|
||||
var/datum/component/plumbing/P = GetComponent(/datum/component/plumbing)
|
||||
if(anchored)
|
||||
P.start()
|
||||
connect_to_network()
|
||||
else
|
||||
P.disable()
|
||||
disconnect_from_network()
|
||||
|
||||
/obj/machinery/power/liquid_pump/process()
|
||||
if(!anchored)
|
||||
return
|
||||
if(!geyser)
|
||||
for(var/obj/structure/geyser/G in loc.contents)
|
||||
geyser = G
|
||||
if(!geyser) //we didnt find one, abort
|
||||
toggle_active()
|
||||
anchored = FALSE
|
||||
visible_message("<span class='warning'>The [name] makes a sad beep!</span>")
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50)
|
||||
return
|
||||
|
||||
if(avail(active_power_usage))
|
||||
if(!powered) //we werent powered before this tick so update our sprite
|
||||
powered = TRUE
|
||||
icon_state = "[initial(icon_state)]-on"
|
||||
add_load(active_power_usage)
|
||||
pump()
|
||||
else if(powered) //we were powered, but now we arent
|
||||
powered = FALSE
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/machinery/power/liquid_pump/proc/pump()
|
||||
if(!geyser || !geyser.reagents)
|
||||
return
|
||||
geyser.reagents.trans_to(src, pump_power)
|
||||
BIN
icons/obj/lavaland/terrain.dmi
Normal file
BIN
icons/obj/lavaland/terrain.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 771 B |
BIN
icons/obj/plumbing/fluid_ducts.dmi
Normal file
BIN
icons/obj/plumbing/fluid_ducts.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
icons/obj/plumbing/plumbers.dmi
Normal file
BIN
icons/obj/plumbing/plumbers.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Reference in New Issue
Block a user