[MIRROR] Massive plumbing layer/placement improvements [MDB IGNORE] (#14172)

* Massive plumbing layer/placement improvements (#66602)

* Massive duct improvements

* last minute fixes/additions to plumbing layer fixes

* letter, loop, and early return fixes

* early continues

* color comments

* reaction chamber colors

* rcd tweaks

* Update code/datums/components/plumbing/reaction_chamber.dm

* Update code/datums/components/plumbing/reaction_chamber.dm

* Update code/datums/components/plumbing/_plumbing.dm

* Update code/datums/components/plumbing/_plumbing.dm

* remove unused var, better duct restacking

Co-authored-by: ShizCalev <ShizCalev@ users.noreply.github.com>

* Massive plumbing layer/placement improvements

Co-authored-by: Tastyfish <crazychris32@gmail.com>
Co-authored-by: ShizCalev <ShizCalev@ users.noreply.github.com>
This commit is contained in:
SkyratBot
2022-06-07 17:43:09 -07:00
committed by GitHub
co-authored by ShizCalev Tastyfish
parent f018dd9a9e
commit 4369049809
11 changed files with 417 additions and 268 deletions
+1
View File
@@ -58,6 +58,7 @@
#define GAS_PIPE_VISIBLE_LAYER 2.47 //layer = initial(layer) + piping_layer / 1000 in atmospherics/update_icon() to determine order of pipe overlap
#define GAS_FILTER_LAYER 2.48
#define GAS_PUMP_LAYER 2.49
#define PLUMBING_PIPE_VISIBILE_LAYER 2.495//layer = initial(layer) + ducting_layer / 3333 in atmospherics/handle_layer() to determine order of duct overlap
#define LOW_OBJ_LAYER 2.5
///catwalk overlay of /turf/open/floor/catwalk_floor
#define CATWALK_LAYER 2.51
+26
View File
@@ -7,3 +7,29 @@
#define DUCT_LAYER_DEFAULT THIRD_DUCT_LAYER
#define MACHINE_REAGENT_TRANSFER 10 //the default max plumbing machinery transfers
/// List of plumbing layers as name => bitflag
GLOBAL_LIST_INIT(plumbing_layers, list(
"First Layer" = FIRST_DUCT_LAYER,
"Second Layer" = SECOND_DUCT_LAYER,
"Default Layer" = THIRD_DUCT_LAYER,
"Fourth Layer" = FOURTH_DUCT_LAYER,
"Fifth Layer" = FIFTH_DUCT_LAYER,
))
/// Reverse of plumbing_layers, as "[bitflag]" => name
GLOBAL_LIST_INIT(plumbing_layer_names, list(
"[FIRST_DUCT_LAYER]" = "First Layer",
"[SECOND_DUCT_LAYER]" = "Second Layer",
"[THIRD_DUCT_LAYER]" = "Default Layer",
"[FOURTH_DUCT_LAYER]" = "Fourth Layer",
"[FIFTH_DUCT_LAYER]" = "Fifth Layer",
))
/// Name of omni color
#define DUCT_COLOR_OMNI "omni"
/// Cached radial menu options for plumbing RCD color picker
GLOBAL_LIST_EMPTY(plumbing_color_menu_options)
/// Cached radial menu options for plumbing RCD layer picker
GLOBAL_LIST_EMPTY(plumbing_layer_menu_options)
+78 -86
View File
@@ -22,10 +22,10 @@
var/recipient_reagents_holder
///How do we apply the new reagents to the receiver? Generally doesn't matter, but some stuff, like people, does care if its injected or whatevs
var/methods
///What color is our demand connect? Also it's not auto-colored so you'll have to make new sprites if its anything other than red, blue, yellow or green
var/demand_color = "red"
///What color is our supply connect? Also, refrain from pointlessly using non-standard colors unless it's really funny or something
var/supply_color = "blue"
///What color is our demand connect?
var/demand_color = COLOR_RED
///What color is our supply connect?
var/supply_color = COLOR_BLUE
///turn_connects is for wheter or not we spin with the object to change our pipes
/datum/component/plumbing/Initialize(start=TRUE, _ducting_layer, _turn_connects=TRUE, datum/reagents/custom_receiver)
@@ -35,14 +35,14 @@
if(_ducting_layer)
ducting_layer = _ducting_layer
var/atom/movable/AM = parent
if(!AM.reagents && !custom_receiver)
var/atom/movable/parent_movable = parent
if(!parent_movable.reagents && !custom_receiver)
return COMPONENT_INCOMPATIBLE
reagents = AM.reagents
reagents = parent_movable.reagents
turn_connects = _turn_connects
set_recipient_reagents_holder(custom_receiver ? custom_receiver : AM.reagents)
set_recipient_reagents_holder(custom_receiver ? custom_receiver : parent_movable.reagents)
if(start)
//We're registering here because I need to check whether we start active or not, and this is just easier
@@ -76,10 +76,10 @@
send_request(D)
///Can we be added to the ductnet?
/datum/component/plumbing/proc/can_add(datum/ductnet/D, dir)
/datum/component/plumbing/proc/can_add(datum/ductnet/ductnet, dir)
if(!active)
return
if(!dir || !D)
if(!dir || !ductnet)
return FALSE
if(num2text(dir) in ducts)
return FALSE
@@ -97,15 +97,13 @@
if(!ducts.Find(num2text(dir)))
return
net = ducts[num2text(dir)]
for(var/A in net.suppliers)
var/datum/component/plumbing/supplier = A
for(var/datum/component/plumbing/supplier as anything in net.suppliers)
if(supplier.can_give(amount, reagent, net))
valid_suppliers += supplier
// Need to ask for each in turn very carefully, making sure we get the total volume. This is to avoid a division that would always round down and become 0
var/targetVolume = reagents.total_volume + amount
var/suppliersLeft = valid_suppliers.len
for(var/A in valid_suppliers)
var/datum/component/plumbing/give = A
for(var/datum/component/plumbing/give as anything in valid_suppliers)
var/currentRequest = (targetVolume - reagents.total_volume) / suppliersLeft
give.transfer_to(src, currentRequest, reagent, net)
suppliersLeft--
@@ -116,9 +114,8 @@
return
if(reagent) //only asked for one type of reagent
for(var/A in reagents.reagent_list)
var/datum/reagent/R = A
if(R.type == reagent)
for(var/datum/reagent/contained_reagent as anything in reagents.reagent_list)
if(contained_reagent.type == reagent)
return TRUE
else if(reagents.total_volume > 0) //take whatever
return TRUE
@@ -133,7 +130,7 @@
reagents.trans_to(target.recipient_reagents_holder, amount, round_robin = TRUE, methods = methods)//we deal with alot of precise calculations so we round_robin=TRUE. Otherwise we get floating point errors, 1 != 1 and 2.5 + 2.5 = 6
///We create our luxurious piping overlays/underlays, to indicate where we do what. only called once if use_overlays = TRUE in Initialize()
/datum/component/plumbing/proc/create_overlays(atom/movable/AM, list/overlays)
/datum/component/plumbing/proc/create_overlays(atom/movable/parent_movable, list/overlays)
SIGNAL_HANDLER
if(tile_covered || !use_overlays)
@@ -158,39 +155,30 @@
var/duct_y = offset
for(var/D in GLOB.cardinals)
for(var/direction in GLOB.cardinals)
var/color
var/direction
if(D & initial(demand_connects))
if(direction & initial(demand_connects))
color = demand_color
else if(D & initial(supply_connects))
else if(direction & initial(supply_connects))
color = supply_color
else
continue
var/image/I
switch(D)
if(NORTH)
direction = "north"
if(SOUTH)
direction = "south"
if(EAST)
direction = "east"
if(WEST)
direction = "west"
var/direction_text = dir2text(direction)
var/duct_layer = PLUMBING_PIPE_VISIBILE_LAYER + ducting_layer * 0.0003
var/image/overlay
if(turn_connects)
I = image('icons/obj/plumbing/connects.dmi', "[direction]-[color]", layer = AM.layer - 1)
overlay = image('icons/obj/plumbing/connects.dmi', "[direction_text]-[ducting_layer]", layer = duct_layer)
else
I = image('icons/obj/plumbing/connects.dmi', "[direction]-[color]-s", layer = AM.layer - 1) //color is not color as in the var, it's just the name of the icon_state
I.dir = D
overlay = image('icons/obj/plumbing/connects.dmi', "[direction_text]-[ducting_layer]-s", layer = duct_layer)
overlay.dir = direction
I.pixel_x = duct_x
I.pixel_y = duct_y
overlay.color = color
overlay.pixel_x = duct_x
overlay.pixel_y = duct_y
overlays += I
overlays += overlay
///we stop acting like a plumbing thing and disconnect if we are, so we can safely be moved and stuff
/datum/component/plumbing/proc/disable()
@@ -201,19 +189,21 @@
STOP_PROCESSING(SSplumbing, src)
for(var/A in ducts)
var/datum/ductnet/D = ducts[A]
D.remove_plumber(src)
for(var/duct_dir in ducts)
var/datum/ductnet/duct = ducts[duct_dir]
duct.remove_plumber(src)
active = FALSE
for(var/D in GLOB.cardinals)
if(D & (demand_connects | supply_connects))
for(var/obj/machinery/duct/duct in get_step(parent, D))
if(duct.duct_layer == ducting_layer)
duct.remove_connects(turn(D, 180))
duct.neighbours.Remove(parent)
duct.update_appearance()
for(var/direction in GLOB.cardinals)
if(!(direction & (demand_connects | supply_connects)))
continue
for(var/obj/machinery/duct/duct in get_step(parent, direction))
if(!(duct.duct_layer & ducting_layer))
continue
duct.remove_connects(turn(direction, 180))
duct.neighbours.Remove(parent)
duct.update_appearance()
///settle wherever we are, and start behaving like a piece of plumbing
/datum/component/plumbing/proc/enable(obj/object, datum/component/component)
@@ -225,29 +215,32 @@
update_dir()
active = TRUE
var/atom/movable/AM = parent
for(var/obj/machinery/duct/D in AM.loc) //Destroy any ducts under us. Ducts also self-destruct if placed under a plumbing machine. machines disable when they get moved
if(D.anchored) //that should cover everything
D.disconnect_duct()
var/atom/movable/parent_movable = parent
// Destroy any ducts under us on the same layer.
// Ducts also self-destruct if placed under a plumbing machine.
// Machines disable when they get moved
for(var/obj/machinery/duct/duct in parent_movable.loc)
if(duct.anchored && (duct.duct_layer & ducting_layer))
duct.disconnect_duct()
if(demand_connects)
START_PROCESSING(SSplumbing, src)
for(var/D in GLOB.cardinals)
for(var/direction in GLOB.cardinals)
if(!(direction & (demand_connects | supply_connects)))
continue
for(var/atom/movable/found_atom in get_step(parent, direction))
if(istype(found_atom, /obj/machinery/duct))
var/obj/machinery/duct/duct = found_atom
duct.attempt_connect()
continue
if(D & (demand_connects | supply_connects))
for(var/atom/movable/A in get_step(parent, D))
if(istype(A, /obj/machinery/duct))
var/obj/machinery/duct/duct = A
duct.attempt_connect()
else
for(var/datum/component/plumbing/plumber as anything in A.GetComponents(/datum/component/plumbing))
if(plumber.ducting_layer == ducting_layer)
direct_connect(plumber, D)
for(var/datum/component/plumbing/plumber as anything in found_atom.GetComponents(/datum/component/plumbing))
if(plumber.ducting_layer & ducting_layer)
direct_connect(plumber, direction)
/// Toggle our machinery on or off. This is called by a hook from default_unfasten_wrench with anchored as only param, so we dont have to copypaste this on every object that can move
/datum/component/plumbing/proc/toggle_active(obj/O, new_state)
/datum/component/plumbing/proc/toggle_active(obj/parent_obj, new_state)
SIGNAL_HANDLER
if(new_state)
enable()
@@ -271,45 +264,44 @@
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)
for(var/direction in GLOB.cardinals)
if(direction & initial(demand_connects))
new_demand_connects += turn(direction, angle)
if(direction & initial(supply_connects))
new_supply_connects += turn(direction, angle)
demand_connects = new_demand_connects
supply_connects = new_supply_connects
///Give the direction of a pipe, and it'll return wich direction it originally was when it's object pointed SOUTH
/datum/component/plumbing/proc/get_original_direction(dir)
var/atom/movable/AM = parent
return turn(dir, dir2angle(AM.dir) - 180)
var/atom/movable/parent_movable = parent
return turn(dir, dir2angle(parent_movable.dir) - 180)
//special case in-case we want to connect directly with another machine without a duct
/datum/component/plumbing/proc/direct_connect(datum/component/plumbing/P, dir)
if(!P.active)
/datum/component/plumbing/proc/direct_connect(datum/component/plumbing/plumbing, dir)
if(!plumbing.active)
return
var/opposite_dir = turn(dir, 180)
if(P.demand_connects & opposite_dir && supply_connects & dir || P.supply_connects & opposite_dir && demand_connects & dir) //make sure we arent connecting two supplies or demands
if(plumbing.demand_connects & opposite_dir && supply_connects & dir || plumbing.supply_connects & opposite_dir && demand_connects & dir) //make sure we arent connecting two supplies or demands
var/datum/ductnet/net = new()
net.add_plumber(src, dir)
net.add_plumber(P, opposite_dir)
net.add_plumber(plumbing, opposite_dir)
/datum/component/plumbing/proc/hide(atom/movable/AM, should_hide)
/datum/component/plumbing/proc/hide(atom/movable/parent_obj, should_hide)
SIGNAL_HANDLER
tile_covered = should_hide
AM.update_appearance()
parent_obj.update_appearance()
/datum/component/plumbing/proc/change_ducting_layer(obj/caller, obj/O, new_layer = DUCT_LAYER_DEFAULT)
/datum/component/plumbing/proc/change_ducting_layer(obj/caller, obj/changer, new_layer = DUCT_LAYER_DEFAULT)
SIGNAL_HANDLER
ducting_layer = new_layer
if(ismovable(parent))
var/atom/movable/AM = parent
AM.update_appearance()
var/atom/movable/parent_movable = parent
parent_movable.update_appearance()
if(O)
playsound(O, 'sound/items/ratchet.ogg', 10, TRUE) //sound
if(changer)
playsound(changer, 'sound/items/ratchet.ogg', 10, TRUE) //sound
//quickly disconnect and reconnect the network.
if(active)
@@ -348,7 +340,7 @@
demand_connects = NORTH
supply_connects = SOUTH
/datum/component/plumbing/manifold/change_ducting_layer(obj/caller, obj/O, new_layer)
/datum/component/plumbing/manifold/change_ducting_layer(obj/caller, obj/changer, new_layer)
return
#define READY 2
@@ -40,7 +40,7 @@
///Special connect that we currently use for reaction chambers. Being used so we can keep certain inputs separate, like into a special internal acid container
/datum/component/plumbing/acidic_input
demand_connects = WEST
demand_color = "yellow"
demand_color = COLOR_YELLOW
ducting_layer = SECOND_DUCT_LAYER
@@ -50,7 +50,7 @@
///Special connect that we currently use for reaction chambers. Being used so we can keep certain inputs separate, like into a special internal base container
/datum/component/plumbing/alkaline_input
demand_connects = EAST
demand_color = "green"
demand_color = COLOR_VIBRANT_LIME
ducting_layer = FOURTH_DUCT_LAYER
+183 -61
View File
@@ -87,7 +87,7 @@ RLD
upgrade |= rcd_up.upgrade
if((rcd_up.upgrade & RCD_UPGRADE_SILO_LINK) && !silo_mats)
silo_mats = AddComponent(/datum/component/remote_materials, "RCD", FALSE, FALSE)
playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
qdel(rcd_up)
/// Inserts matter into the RCD allowing it to build
@@ -105,7 +105,7 @@ RLD
if(R.ammoamt <= 0)
qdel(R)
matter += load
playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
loaded = TRUE
else if(istype(O, /obj/item/stack))
loaded = loadwithsheets(O, user)
@@ -124,17 +124,17 @@ RLD
var/amount_to_use = min(S.amount, maxsheets)
S.use(amount_to_use)
matter += value*amount_to_use
playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
to_chat(user, span_notice("You insert [amount_to_use] [S.name] sheets into [src]. "))
return TRUE
to_chat(user, span_warning("You can't insert any more [S.name] sheets into [src]!"))
return FALSE
/obj/item/construction/proc/activate()
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, TRUE)
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
/obj/item/construction/attack_self(mob/user)
playsound(src.loc, 'sound/effects/pop.ogg', 50, FALSE)
playsound(loc, 'sound/effects/pop.ogg', 50, FALSE)
if(prob(20))
spark_system.start()
@@ -358,7 +358,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
T.rcd_act(user, src, RCD_FLOORWALL)
useResource(16, user)
activate()
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
playsound(loc, 'sound/machines/click.ogg', 50, 1)
user.gib()
return MANUAL_SUICIDE
@@ -709,7 +709,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
if(rcd_results["mode"] == RCD_MACHINE || rcd_results["mode"] == RCD_COMPUTER || rcd_results["mode"] == RCD_FURNISHING)
var/turf/target_turf = get_turf(A)
if(target_turf.is_blocked_turf(exclude_mobs = TRUE))
playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
qdel(rcd_effect)
return FALSE
if(!do_after(user, delay, target = A))
@@ -724,7 +724,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
rcd_effect.end_animation()
useResource(rcd_results["cost"], user)
activate()
playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
return TRUE
/obj/item/construction/rcd/Initialize(mapload)
@@ -1046,7 +1046,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
if(checkResource(deconcost, user))
to_chat(user, span_notice("You start deconstructing [A]..."))
user.Beam(A,icon_state="light_beam", time = 15)
playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
if(do_after(user, decondelay, target = A))
if(!useResource(deconcost, user))
return FALSE
@@ -1060,8 +1060,8 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
if(checkResource(floorcost, user))
to_chat(user, span_notice("You start building a wall light..."))
user.Beam(A,icon_state="light_beam", time = 15)
playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, FALSE)
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
playsound(loc, 'sound/effects/light_flicker.ogg', 50, FALSE)
if(do_after(user, floordelay, target = A))
if(!istype(W))
return FALSE
@@ -1075,7 +1075,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
candidates += C
if(!candidates.len)
to_chat(user, span_warning("Valid target not found..."))
playsound(src.loc, 'sound/misc/compiler-failure.ogg', 30, TRUE)
playsound(loc, 'sound/misc/compiler-failure.ogg', 30, TRUE)
return FALSE
for(var/turf/open/O in candidates)
if(istype(O))
@@ -1106,8 +1106,8 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
if(checkResource(floorcost, user))
to_chat(user, span_notice("You start building a floor light..."))
user.Beam(A,icon_state="light_beam", time = 15)
playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, TRUE)
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
playsound(loc, 'sound/effects/light_flicker.ogg', 50, TRUE)
if(do_after(user, floordelay, target = A))
if(!istype(F))
return FALSE
@@ -1170,44 +1170,69 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
var/list/machinery_data = list("cost" = list())
///This list that holds all the plumbing design types the plumberer can construct. Its purpose is to make it easy to make new plumberer subtypes with a different selection of machines.
var/list/plumbing_design_types
///Possible layers to pick from
var/static/list/layers = list("Second Layer" = SECOND_DUCT_LAYER, "Default Layer" = DUCT_LAYER_DEFAULT, "Fourth Layer" = FOURTH_DUCT_LAYER)
///Current selected layer
var/current_layer = "Default Layer"
///Current selected color, for ducts
var/current_color = "omni"
/obj/item/construction/plumbing/Initialize(mapload)
. = ..()
set_plumbing_designs()
/obj/item/construction/plumbing/examine(mob/user)
. = ..()
. += span_notice("Alt-Click to change layer and duct color.")
/obj/item/construction/plumbing/equipped(mob/user, slot, initial)
. = ..()
if(slot == ITEM_SLOT_HANDS)
RegisterSignal(user, COMSIG_MOUSE_SCROLL_ON, .proc/mouse_wheeled)
else
UnregisterSignal(user, COMSIG_MOUSE_SCROLL_ON)
/obj/item/construction/plumbing/dropped(mob/user, silent)
UnregisterSignal(user, COMSIG_MOUSE_SCROLL_ON)
return ..()
/obj/item/construction/plumbing/cyborg_unequip(mob/user)
UnregisterSignal(user, COMSIG_MOUSE_SCROLL_ON)
return ..()
/obj/item/construction/plumbing/attack_self(mob/user)
..()
if(!choices.len)
for(var/A in plumbing_design_types)
var/obj/machinery/plumbing/M = A
for(var/obj/machinery/plumbing/plumbing_type as anything in plumbing_design_types)
choices += list(initial(plumbing_type.name) = image(initial(plumbing_type.icon), icon_state = initial(plumbing_type.icon_state)))
name_to_type[initial(plumbing_type.name)] = plumbing_type
machinery_data["cost"][plumbing_type] = plumbing_design_types[plumbing_type]
choices += list(initial(M.name) = image(icon = initial(M.icon), icon_state = initial(M.icon_state)))
name_to_type[initial(M.name)] = M
machinery_data["cost"][A] = plumbing_design_types[A]
// Update duct icon
var/image/duct_image = choices["fluid duct"]
duct_image.color = current_color
var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
if(!check_menu(user))
if(!choice || !check_menu(user))
return
blueprint = name_to_type[choice]
playsound(src, 'sound/effects/pop.ogg', 50, FALSE)
to_chat(user, span_notice("You change [name]s blueprint to '[choice]'."))
///Set the list of designs this plumbing rcd can make
/**
* Set the list of designs this plumbing rcd can make
*/
/obj/item/construction/plumbing/proc/set_plumbing_designs()
plumbing_design_types = list(
// Note that the list MUST include fluid ducts.
/obj/machinery/duct = 1,
/obj/machinery/plumbing/input = 5,
/obj/machinery/plumbing/output = 5,
/obj/machinery/plumbing/tank = 20,
/obj/machinery/plumbing/synthesizer = 15,
/obj/machinery/plumbing/reaction_chamber = 15,
/obj/machinery/plumbing/buffer = 10,
/obj/machinery/plumbing/layer_manifold = 5,
//Above are the most common machinery which is shown on the first cycle. Keep new additions below THIS line, unless they're probably gonna be needed alot
/obj/machinery/plumbing/layer_manifold = 5,
/obj/machinery/plumbing/pill_press = 20,
/obj/machinery/plumbing/acclimator = 10,
/obj/machinery/plumbing/bottler = 50,
@@ -1223,56 +1248,152 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
)
///pretty much rcd_create, but named differently to make myself feel less bad for copypasting from a sibling-type
/obj/item/construction/plumbing/proc/create_machine(atom/A, mob/user)
if(!machinery_data || !isopenturf(A))
/obj/item/construction/plumbing/proc/create_machine(atom/destination, mob/user)
if(!machinery_data || !isopenturf(destination))
return FALSE
if(!canPlace(destination))
var/obj/blueprint_type = blueprint
to_chat(user, span_notice("There is something blocking you from placing a [initial(blueprint_type.name)] there."))
return
if(checkResource(machinery_data["cost"][blueprint], user) && blueprint)
//"cost" is relative to delay at a rate of 10 matter/second (1matter/decisecond) rather than playing with 2 different variables since everyone set it to this rate anyways.
if(do_after(user, machinery_data["cost"][blueprint], target = A))
if(checkResource(machinery_data["cost"][blueprint], user) && canPlace(A))
if(do_after(user, machinery_data["cost"][blueprint], target = destination))
if(checkResource(machinery_data["cost"][blueprint], user) && canPlace(destination))
useResource(machinery_data["cost"][blueprint], user)
activate()
playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
new blueprint (A, FALSE, layers[current_layer])
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
if(ispath(blueprint, /obj/machinery/duct))
var/is_omni = current_color == DUCT_COLOR_OMNI
new blueprint(destination, FALSE, GLOB.pipe_paint_colors[current_color], GLOB.plumbing_layers[current_layer], null, is_omni)
else
new blueprint(destination, FALSE, GLOB.plumbing_layers[current_layer])
return TRUE
/obj/item/construction/plumbing/proc/canPlace(turf/T)
if(!isopenturf(T))
/obj/item/construction/plumbing/proc/canPlace(turf/destination)
if(!isopenturf(destination))
return FALSE
. = TRUE
for(var/obj/O in T.contents)
if(O.density) //let's not built ontop of dense stuff, like big machines and other obstacles, it kills my immershion
var/obj/blueprint_template = blueprint
var/layer_id = GLOB.plumbing_layers[current_layer]
for(var/obj/content_obj in destination.contents)
// Let's not built ontop of dense stuff, if this is also dense.
if(initial(blueprint_template.density) && content_obj.density)
return FALSE
/obj/item/construction/plumbing/afterattack(atom/A, mob/user, proximity)
// Ducts can overlap other plumbing objects IF the layers are different
// make sure plumbling isn't overlapping.
for(var/datum/component/plumbing/plumber as anything in content_obj.GetComponents(/datum/component/plumbing))
if(plumber.ducting_layer & layer_id)
return FALSE
if(istype(content_obj, /obj/machinery/duct))
// Make sure ducts aren't overlapping.
var/obj/machinery/duct/duct_machine = content_obj
if(duct_machine.duct_layer & layer_id)
return FALSE
/obj/item/construction/plumbing/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!prox_check(proximity))
return
if(istype(A, /obj/machinery/plumbing))
var/obj/machinery/plumbing/P = A
if(P.anchored)
to_chat(user, span_warning("The [P.name] needs to be unanchored!"))
if(istype(target, /obj/machinery/plumbing))
var/obj/machinery/machine_target = target
if(machine_target.anchored)
to_chat(user, span_warning("The [target.name] needs to be unanchored!"))
return
if(do_after(user, 20, target = P))
P.deconstruct() //Let's not substract matter
if(do_after(user, 20, target = target))
machine_target.deconstruct() //Let's not substract matter
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE) //this is just such a great sound effect
else
create_machine(A, user)
create_machine(target, user)
/obj/item/construction/plumbing/AltClick(mob/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
// give a menu to pick layers or colors
var/list/options_menu = list(
"Current Layer" = image('icons/hud/radial.dmi', icon_state = "plumbing_layer[GLOB.plumbing_layers[current_layer]]"),
"Current Color" = image('icons/hud/radial.dmi', icon_state = current_color),
)
playsound(loc, 'sound/effects/pop.ogg', 50, FALSE)
var/choice = show_radial_menu(user, src, options_menu, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
if(!check_menu(user))
return
//this is just cycling options through a list
var/current_loc = layers.Find(current_layer) + 1
switch(choice)
if("Current Layer")
choose_layer_menu(user)
if("Current Color")
choose_color_menu(user)
if(current_loc > layers.len)
current_loc = 1
/**
* Choose the current layer via radial menu.
*
* Arguments:
* * user - current user.
*/
/obj/item/construction/plumbing/proc/choose_layer_menu(mob/user)
if(!GLOB.plumbing_layer_menu_options.len)
for(var/layer_name in GLOB.plumbing_layers)
GLOB.plumbing_layer_menu_options += list((layer_name) = image('icons/hud/radial.dmi', icon_state = "plumbing_layer[GLOB.plumbing_layers[layer_name]]"))
//We want the key (the define), not the index (the string)
current_layer = layers[current_loc]
to_chat(user, span_notice("You switch [src] to [current_layer]."))
playsound(loc, 'sound/effects/pop.ogg', 50, FALSE)
var/new_layer = show_radial_menu(user, src, GLOB.plumbing_layer_menu_options, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
if(!new_layer || !check_menu(user))
return
current_layer = new_layer
to_chat(user, span_notice("You set the layer to [new_layer]."))
/**
* Choose the current color via radial menu.
*
* Arguments:
* * user - current user.
*/
/obj/item/construction/plumbing/proc/choose_color_menu(mob/user)
if(!GLOB.plumbing_color_menu_options.len)
for(var/color_name in GLOB.pipe_paint_colors)
GLOB.plumbing_color_menu_options += list((color_name) = image('icons/hud/radial.dmi', icon_state = color_name))
playsound(loc, 'sound/effects/pop.ogg', 50, FALSE)
var/new_color = show_radial_menu(user, src, GLOB.plumbing_color_menu_options, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
if(!new_color || !check_menu(user))
return
current_color = new_color
to_chat(user, span_notice("You set the color to [new_color]."))
/**
* Choose layer via mouse wheel, like an RPD
*
* Arguments:
* * source - the user
* * A - the atom being selected, unused.
* * delta_x - X scroll delta
* * delta_y - Y scroll delta
*/
/obj/item/construction/plumbing/proc/mouse_wheeled(mob/source, atom/A, delta_x, delta_y, params)
SIGNAL_HANDLER
if(source.incapacitated(IGNORE_RESTRAINTS|IGNORE_STASIS))
return
if(delta_y == 0)
return
if(delta_y < 0)
var/current_loc = GLOB.plumbing_layers.Find(current_layer) + 1
if(current_loc > GLOB.plumbing_layers.len)
current_loc = 1
current_layer = GLOB.plumbing_layers[current_loc]
else
var/current_loc = GLOB.plumbing_layers.Find(current_layer) - 1
if(current_loc < 1)
current_loc = GLOB.plumbing_layers.len
current_layer = GLOB.plumbing_layers[current_loc]
to_chat(source, span_notice("You set the layer to [current_layer]."))
/obj/item/construction/plumbing/research
name = "research plumbing constructor"
@@ -1285,17 +1406,18 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window())
/obj/item/construction/plumbing/research/set_plumbing_designs()
plumbing_design_types = list(
/obj/machinery/plumbing/input = 5,
/obj/machinery/plumbing/output = 5,
/obj/machinery/plumbing/tank = 20,
/obj/machinery/plumbing/acclimator = 10,
/obj/machinery/plumbing/filter = 5,
/obj/machinery/plumbing/grinder_chemical = 30,
/obj/machinery/plumbing/reaction_chamber = 15,
/obj/machinery/plumbing/splitter = 5,
/obj/machinery/plumbing/disposer = 10,
/obj/machinery/plumbing/growing_vat = 20
)
/obj/machinery/duct = 1,
/obj/machinery/plumbing/input = 5,
/obj/machinery/plumbing/output = 5,
/obj/machinery/plumbing/tank = 20,
/obj/machinery/plumbing/acclimator = 10,
/obj/machinery/plumbing/filter = 5,
/obj/machinery/plumbing/reaction_chamber = 15,
/obj/machinery/plumbing/grinder_chemical = 30,
/obj/machinery/plumbing/splitter = 5,
/obj/machinery/plumbing/disposer = 10,
/obj/machinery/plumbing/growing_vat = 20
)
/obj/item/rcd_upgrade
@@ -139,9 +139,6 @@
///What layer we set it to
var/target_layer = DUCT_LAYER_DEFAULT
///Assoc list for possible layers
var/list/layers = list("Second Layer" = SECOND_DUCT_LAYER, "Default Layer" = DUCT_LAYER_DEFAULT, "Fourth Layer" = FOURTH_DUCT_LAYER)
/obj/item/plunger/attack_atom(obj/O, mob/living/user, params)
if(layer_mode)
SEND_SIGNAL(O, COMSIG_MOVABLE_CHANGE_DUCT_LAYER, O, target_layer)
@@ -178,10 +175,10 @@
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
return
var/new_layer = tgui_input_list(user, "Select a layer", "Layer", layers)
var/new_layer = tgui_input_list(user, "Select a layer", "Layer", GLOB.plumbing_layers)
if(isnull(new_layer))
return
target_layer = layers[new_layer]
target_layer = GLOB.plumbing_layers[new_layer]
///A faster reinforced plunger
/obj/item/plunger/reinforced
+123 -113
View File
@@ -7,6 +7,7 @@ All the important duct code:
name = "fluid duct"
icon = 'icons/obj/plumbing/fluid_ducts.dmi'
icon_state = "nduct"
layer = PLUMBING_PIPE_VISIBILE_LAYER
use_power = NO_POWER_USE
@@ -22,7 +23,7 @@ All the important duct code:
var/capacity = 10
///the color of our duct
var/duct_color = null
var/duct_color = COLOR_VERY_LIGHT_GRAY
///TRUE to ignore colors, so yeah we also connect with other colors without issue
var/ignore_colors = FALSE
///1,2,4,8,16
@@ -35,122 +36,113 @@ All the important duct code:
var/active = TRUE
///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
var/list/neighbours = list()
///wheter we just unanchored or drop whatever is in the variable. either is safe
///what stack to drop when disconnected. Must be /obj/item/stack/ducts or a subtype
var/drop_on_wrench = /obj/item/stack/ducts
/obj/machinery/duct/Initialize(mapload, no_anchor, color_of_duct = "#ffffff", layer_of_duct = DUCT_LAYER_DEFAULT, force_connects)
/obj/machinery/duct/Initialize(mapload, no_anchor, color_of_duct = null, layer_of_duct = null, force_connects, force_ignore_colors)
. = ..()
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 && layer_of_duct)
duct_layer = layer_of_duct
if(force_ignore_colors)
ignore_colors = force_ignore_colors
if(!ignore_colors && color_of_duct)
duct_color = color_of_duct
if(duct_color)
add_atom_colour(duct_color, FIXED_COLOUR_PRIORITY)
if(no_anchor)
active = FALSE
set_anchored(FALSE)
else if(!can_anchor())
qdel(src)
CRASH("Overlapping ducts detected")
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)
if(mapload)
log_mapping("Overlapping ducts detected at [AREACOORD(src)], unanchoring one.")
// Note that qdeling automatically drops a duct stack
return INITIALIZE_HINT_QDEL
handle_layer()
for(var/obj/machinery/duct/D in loc)
if(D == src)
continue
if(D.duct_layer & duct_layer)
return INITIALIZE_HINT_QDEL //If we have company, end it all
attempt_connect()
AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE)
///start looking around us for stuff to connect to
/obj/machinery/duct/proc/attempt_connect()
for(var/atom/movable/AM in loc)
for(var/datum/component/plumbing/plumber as anything in AM.GetComponents(/datum/component/plumbing))
if(plumber.active)
disconnect_duct() //let's not built under plumbing machinery
return
for(var/D in GLOB.cardinals)
if(dumb && !(D & connects))
for(var/direction in GLOB.cardinals)
if(dumb && !(direction & connects))
continue
for(var/atom/movable/AM in get_step(src, D))
if(connect_network(AM, D))
add_connects(D)
for(var/atom/movable/duct_candidate in get_step(src, direction))
if(connect_network(duct_candidate, direction))
add_connects(direction)
update_appearance()
///see if whatever we found can be connected to
/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)
/obj/machinery/duct/proc/connect_network(atom/movable/plumbable, direction)
if(istype(plumbable, /obj/machinery/duct))
return connect_duct(plumbable, direction)
for(var/datum/component/plumbing/plumber as anything in AM.GetComponents(/datum/component/plumbing))
for(var/datum/component/plumbing/plumber as anything in plumbable.GetComponents(/datum/component/plumbing))
. += connect_plumber(plumber, direction) //so that if one is true, all is true. beautiful.
///connect to a duct
/obj/machinery/duct/proc/connect_duct(obj/machinery/duct/D, direction, ignore_color)
/obj/machinery/duct/proc/connect_duct(obj/machinery/duct/other, direction)
var/opposite_dir = turn(direction, 180)
if(!active || !D.active)
if(!active || !other.active)
return
if(!dumb && D.dumb && !(opposite_dir & D.connects))
if(!dumb && other.dumb && !(opposite_dir & other.connects))
return
if(dumb && D.dumb && !(connects & D.connects)) //we eliminated a few more scenarios in attempt connect
if(dumb && other.dumb && !(connects & other.connects)) //we eliminated a few more scenarios in attempt connect
return
if((duct == D.duct) && duct)//check if we're not just comparing two null values
add_neighbour(D, direction)
if((duct == other.duct) && duct)//check if we're not just comparing two null values
add_neighbour(other, direction)
D.add_connects(opposite_dir)
D.update_appearance()
other.add_connects(opposite_dir)
other.update_appearance()
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))
if(!(other in neighbours)) //we cool
if((duct_color != other.duct_color) && !(ignore_colors || other.ignore_colors))
return
if(!(duct_layer & D.duct_layer))
if(!(duct_layer & other.duct_layer))
return
if(D.duct)
if(other.duct)
if(duct)
duct.assimilate(D.duct)
duct.assimilate(other.duct)
else
D.duct.add_duct(src)
other.duct.add_duct(src)
else
if(duct)
duct.add_duct(D)
duct.add_duct(other)
else
create_duct()
duct.add_duct(D)
duct.add_duct(other)
add_neighbour(D, direction)
add_neighbour(other, direction)
//Delegate to timer subsystem so its handled the next tick and doesnt cause byond to mistake it for an infinite loop and kill the game
addtimer(CALLBACK(D, .proc/attempt_connect))
addtimer(CALLBACK(other, .proc/attempt_connect))
return TRUE
///connect to a plumbing object
/obj/machinery/duct/proc/connect_plumber(datum/component/plumbing/P, direction)
/obj/machinery/duct/proc/connect_plumber(datum/component/plumbing/plumbing, direction)
var/opposite_dir = turn(direction, 180)
if(duct_layer != P.ducting_layer)
if(!(duct_layer & plumbing.ducting_layer))
return FALSE
if(!P.active)
if(!plumbing.active)
return
var/comp_directions = P.supply_connects + P.demand_connects //they should never, ever have supply and demand connects overlap or catastrophic failure
var/comp_directions = plumbing.supply_connects + plumbing.demand_connects //they should never, ever have supply and demand connects overlap or catastrophic failure
if(opposite_dir & comp_directions)
if(!duct)
create_duct()
if(duct.add_plumber(P, opposite_dir))
neighbours[P.parent] = direction
if(duct.add_plumber(plumbing, opposite_dir))
neighbours[plumbing.parent] = direction
return TRUE
///we disconnect ourself from our neighbours. we also destroy our ductnet and tell our neighbours to make a new one
@@ -164,9 +156,12 @@ All the important duct code:
reset_connects(0)
update_appearance()
if(ispath(drop_on_wrench))
new drop_on_wrench(drop_location())
var/obj/item/stack/ducts/duct_stack = new drop_on_wrench(drop_location())
duct_stack.duct_color = GLOB.pipe_color_name[duct_color] || DUCT_COLOR_OMNI
duct_stack.duct_layer = GLOB.plumbing_layer_names["[duct_layer]"] || GLOB.plumbing_layer_names["[DUCT_LAYER_DEFAULT]"]
duct_stack.add_atom_colour(duct_color, FIXED_COLOUR_PRIORITY)
drop_on_wrench = null
if(!QDELETED(src))
if(!QDELING(src))
qdel(src)
///Special proc to draw a new connect frame based on neighbours. not the norm so we can support multiple duct kinds
@@ -184,16 +179,17 @@ All the important duct code:
duct.add_duct(src)
///add a duct as neighbour. this means we're connected and will connect again if we ever regenerate
/obj/machinery/duct/proc/add_neighbour(obj/machinery/duct/D, direction)
if(!(D in neighbours))
neighbours[D] = direction
if(!(src in D.neighbours))
D.neighbours[src] = turn(direction, 180)
/obj/machinery/duct/proc/add_neighbour(obj/machinery/duct/other, direction)
if(!(other in neighbours))
neighbours[other] = direction
if(!(src in other.neighbours))
other.neighbours[src] = turn(direction, 180)
///remove all our neighbours, and remove us from our neighbours aswell
/obj/machinery/duct/proc/lose_neighbours()
for(var/obj/machinery/duct/D in neighbours)
D.neighbours.Remove(src)
for(var/obj/machinery/duct/other in neighbours)
other.neighbours.Remove(src)
other.generate_connects()
neighbours = list()
///add a connect direction
@@ -214,24 +210,24 @@ All the important duct code:
///get a list of the ducts we can connect to if we are dumb
/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
for(var/direction in GLOB.cardinals)
if(direction & connects)
for(var/obj/machinery/duct/other in get_step(src, direction))
if((turn(direction, 180) & other.connects) && other.active)
adjacents += other
return adjacents
/obj/machinery/duct/update_icon_state()
var/temp_icon = initial(icon_state)
for(var/D in GLOB.cardinals)
if(D & connects)
if(D == NORTH)
for(var/direction in GLOB.cardinals)
switch(direction & connects)
if(NORTH)
temp_icon += "_n"
if(D == SOUTH)
if(SOUTH)
temp_icon += "_s"
if(D == EAST)
if(EAST)
temp_icon += "_e"
if(D == WEST)
if(WEST)
temp_icon += "_w"
icon_state = temp_icon
return ..()
@@ -239,7 +235,8 @@ All the important duct code:
///update the layer we are on
/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
//it's a bitfield, but it's fine because ducts themselves are only on one layer
switch(duct_layer)
if(FIRST_DUCT_LAYER)
offset = -10
if(SECOND_DUCT_LAYER)
@@ -253,6 +250,7 @@ All the important duct code:
pixel_x = offset
pixel_y = offset
layer = initial(layer) + duct_layer * 0.0003
/obj/machinery/duct/set_anchored(anchorvalue)
. = ..()
@@ -264,10 +262,10 @@ All the important duct code:
else
disconnect_duct(TRUE)
/obj/machinery/duct/wrench_act(mob/living/user, obj/item/I) //I can also be the RPD
/obj/machinery/duct/wrench_act(mob/living/user, obj/item/wrench) //I can also be the RPD
..()
add_fingerprint(user)
I.play_tool_sound(src)
wrench.play_tool_sound(src)
if(anchored || can_anchor())
set_anchored(!anchored)
user.visible_message( \
@@ -277,14 +275,15 @@ All the important duct code:
return TRUE
///collection of all the sanity checks to prevent us from stacking ducts that shouldn't be stacked
/obj/machinery/duct/proc/can_anchor(turf/T)
if(!T)
T = get_turf(src)
for(var/obj/machinery/duct/D in T)
if(!anchored || D == src)
continue
for(var/A in GLOB.cardinals)
if(A & connects && A & D.connects)
/obj/machinery/duct/proc/can_anchor(turf/destination)
if(!destination)
destination = get_turf(src)
for(var/obj/machinery/duct/other in destination)
if(other.anchored && other != src && (duct_layer & other.duct_layer))
return FALSE
for(var/obj/machinery/machine in destination)
for(var/datum/component/plumbing/plumber as anything in machine.GetComponents(/datum/component/plumbing))
if(plumber.ducting_layer & duct_layer)
return FALSE
return TRUE
@@ -297,26 +296,29 @@ All the important duct code:
disconnect_duct()
return ..()
/obj/machinery/duct/MouseDrop_T(atom/A, mob/living/user)
if(!istype(A, /obj/machinery/duct))
/obj/machinery/duct/MouseDrop_T(atom/drag_source, mob/living/user)
if(!istype(drag_source, /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_warning("You need to be holding a wrench in your active hand to do that!"))
var/obj/machinery/duct/other = drag_source
if(get_dist(src, other) != 1)
return
if(get_dist(src, D) != 1)
return
var/direction = get_dir(src, D)
var/direction = get_dir(src, other)
if(!(direction in GLOB.cardinals))
return
if(duct_layer != D.duct_layer)
if(!(duct_layer & other.duct_layer))
to_chat(user, span_warning("The ducts must be on the same layer to connect them!"))
return
var/obj/item/held_item = user.get_active_held_item()
if(held_item?.tool_behaviour != TOOL_WRENCH)
to_chat(user, span_warning("You need to be holding a wrench in your active hand to do that!"))
return
add_connects(direction) //the connect of the other duct is handled in connect_network, but do this here for the parent duct because it's not necessary in normal cases
add_neighbour(D, direction)
connect_network(D, direction, TRUE)
add_neighbour(other, direction)
connect_network(other, direction)
update_appearance()
held_item.play_tool_sound(src)
to_chat(user, span_notice("You connect the two plumbing ducts."))
/obj/item/stack/ducts
name = "stack of duct"
@@ -330,22 +332,21 @@ All the important duct code:
max_amount = 50
item_flags = NOBLUDGEON
merge_type = /obj/item/stack/ducts
matter_amount = 1
///Color of our duct
var/duct_color = "omni"
///Default layer of our duct
var/duct_layer = "Default Layer"
///Assoc index with all the available layers. yes five might be a bit much. Colors uses a global by the way
var/list/layers = list("Second Layer" = SECOND_DUCT_LAYER, "Default Layer" = DUCT_LAYER_DEFAULT, "Fourth Layer" = FOURTH_DUCT_LAYER)
/obj/item/stack/ducts/examine(mob/user)
. = ..()
. += span_notice("It's current color and layer are [duct_color] and [duct_layer]. Use in-hand to change.")
/obj/item/stack/ducts/attack_self(mob/user)
var/new_layer = tgui_input_list(user, "Select a layer", "Layer", layers)
var/new_layer = tgui_input_list(user, "Select a layer", "Layer", GLOB.plumbing_layers, duct_layer)
if(new_layer)
duct_layer = new_layer
var/new_color = tgui_input_list(user, "Select a color", "Color", GLOB.pipe_paint_colors)
var/new_color = tgui_input_list(user, "Select a color", "Color", GLOB.pipe_paint_colors, duct_color)
if(new_color)
duct_color = new_color
add_atom_colour(GLOB.pipe_paint_colors[new_color], FIXED_COLOUR_PRIORITY)
@@ -355,16 +356,25 @@ All the important duct code:
if(!proximity)
return
if(istype(target, /obj/machinery/duct))
var/obj/machinery/duct/D = target
if(!D.anchored)
add(1)
qdel(D)
var/obj/machinery/duct/duct = target
if(duct.anchored)
to_chat(user, span_warning("The duct must be unanchored before it can be picked up."))
return
// Turn into a duct stack and then merge to the in-hand stack.
var/obj/item/stack/ducts/stack = new(duct.loc, 1, FALSE)
qdel(duct)
if(stack.can_merge(src))
stack.merge(src)
return
check_attach_turf(target)
/obj/item/stack/ducts/proc/check_attach_turf(atom/target)
if(istype(target, /turf/open) && use(1))
if(isopenturf(target) && use(1))
var/turf/open/open_turf = target
new /obj/machinery/duct(open_turf, FALSE, GLOB.pipe_paint_colors[duct_color], layers[duct_layer])
var/is_omni = duct_color == DUCT_COLOR_OMNI
new /obj/machinery/duct(open_turf, FALSE, GLOB.pipe_paint_colors[duct_color], GLOB.plumbing_layers[duct_layer], null, is_omni)
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE)
/obj/item/stack/ducts/fifty
@@ -14,7 +14,6 @@
var/buffer = 50
///Flags for reagents, like INJECTABLE, TRANSPARENT bla bla everything thats in DEFINES/reagents.dm
var/reagent_flags = TRANSPARENT
///wheter we partake in rcd construction or not
/obj/machinery/plumbing/Initialize(mapload, bolt = TRUE)
. = ..()
@@ -98,6 +97,8 @@
/obj/machinery/plumbing/layer_manifold/Initialize(mapload, bolt, layer)
. = ..()
AddComponent(/datum/component/plumbing/manifold, bolt, FIRST_DUCT_LAYER)
AddComponent(/datum/component/plumbing/manifold, bolt, SECOND_DUCT_LAYER)
AddComponent(/datum/component/plumbing/manifold, bolt, THIRD_DUCT_LAYER)
AddComponent(/datum/component/plumbing/manifold, bolt, FOURTH_DUCT_LAYER)
AddComponent(/datum/component/plumbing/manifold, bolt, FIFTH_DUCT_LAYER)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 973 B

After

Width:  |  Height:  |  Size: 900 B