mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 12:41:09 +01:00
[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:
co-authored by
ShizCalev
Tastyfish
parent
f018dd9a9e
commit
4369049809
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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 |
Reference in New Issue
Block a user