[MIRROR] RPD UI ,bunch of pipe fixes & stack garbage collection [MDB IGNORE] (#19100)

* RPD UI  ,bunch of pipe fixes & stack garbage collection

* Update _machinery.dm

---------

Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
Co-authored-by: lessthanthree <83487515+lessthnthree@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-02-13 10:41:11 -08:00
committed by GitHub
co-authored by SyncIt21 lessthanthree
parent 43e3b37073
commit dfe6c614ae
8 changed files with 153 additions and 134 deletions
@@ -20,6 +20,8 @@
resistance_flags = FIRE_PROOF
max_integrity = 200
obj_flags = CAN_BE_HIT
armor_type = /datum/armor/machinery_atmospherics
///Check if the object can be unwrenched
var/can_unwrench = FALSE
///Bitflag of the initialized directions (NORTH | SOUTH | EAST | WEST)
@@ -154,6 +156,47 @@
node_machine.disconnect(src)
nodes[i] = null
/**
* Setter for device direction
*
* Set the direction to either SOUTH or WEST if the pipe_flag is set to PIPING_CARDINAL_AUTONORMALIZE, called in New(), used mostly by layer manifolds
*/
/obj/machinery/atmospherics/proc/normalize_cardinal_directions()
switch(dir)
if(SOUTH)
setDir(NORTH)
if(WEST)
setDir(EAST)
/**
* setter for pipe layers
*
* Set the layer of the pipe that the device has to a new_layer
* Arguments:
* * new_layer - the layer at which we want the piping_layer to be (1 to 5)
*/
/obj/machinery/atmospherics/proc/set_piping_layer(new_layer)
piping_layer = (pipe_flags & PIPING_DEFAULT_LAYER_ONLY) ? PIPING_LAYER_DEFAULT : new_layer
update_appearance()
/obj/machinery/atmospherics/update_icon()
. = ..()
update_layer()
/**
* Find a connecting /obj/machinery/atmospherics in specified direction, called by relaymove()
* used by ventcrawling mobs to check if they can move inside a pipe in a specific direction
* Arguments:
* * direction - the direction we are checking against
* * prompted_layer - the piping_layer we are inside
*/
/obj/machinery/atmospherics/proc/find_connecting(direction, prompted_layer)
for(var/obj/machinery/atmospherics/target in get_step_multiz(src, direction))
if(!(target.initialize_directions & get_dir(target,src)) && !istype(target, /obj/machinery/atmospherics/pipe/multiz))
continue
if(connection_check(target, prompted_layer))
return target
/**
* Getter for node_connects
*
@@ -175,18 +218,6 @@
return node_connects
/**
* Setter for device direction
*
* Set the direction to either SOUTH or WEST if the pipe_flag is set to PIPING_CARDINAL_AUTONORMALIZE, called in New(), used mostly by layer manifolds
*/
/obj/machinery/atmospherics/proc/normalize_cardinal_directions()
switch(dir)
if(SOUTH)
setDir(NORTH)
if(WEST)
setDir(EAST)
/**
* Initialize for atmos devices
*
@@ -200,50 +231,21 @@
for(var/i in 1 to device_type)
for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[i]))
if(can_be_node(target, i))
if(can_be_node(target))
nodes[i] = target
break
update_appearance()
/**
* setter for pipe layers
*
* Set the layer of the pipe that the device has to a new_layer
* Arguments:
* * new_layer - the layer at which we want the piping_layer to be (1 to 5)
*/
/obj/machinery/atmospherics/proc/set_piping_layer(new_layer)
piping_layer = (pipe_flags & PIPING_DEFAULT_LAYER_ONLY) ? PIPING_LAYER_DEFAULT : new_layer
update_appearance()
/obj/machinery/atmospherics/update_icon()
. = ..()
update_layer()
/**
* Check if a node can actually exists by connecting to another machine
* called on atmos_init()
* Arguments:
* * obj/machinery/atmospherics/target - the machine we are connecting to
* * iteration - the current node we are checking (from 1 to 4)
*/
/obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target, iteration)
/obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target)
return connection_check(target, piping_layer)
/**
* Find a connecting /obj/machinery/atmospherics in specified direction, called by relaymove()
* used by ventcrawling mobs to check if they can move inside a pipe in a specific direction
* Arguments:
* * direction - the direction we are checking against
* * prompted_layer - the piping_layer we are inside
*/
/obj/machinery/atmospherics/proc/find_connecting(direction, prompted_layer)
for(var/obj/machinery/atmospherics/target in get_step_multiz(src, direction))
if(!(target.initialize_directions & get_dir(target,src)) && !istype(target, /obj/machinery/atmospherics/pipe/multiz))
continue
if(connection_check(target, prompted_layer))
return target
/**
* Check the connection between two nodes
*
@@ -254,20 +256,15 @@
* * given_layer - the piping_layer we are checking
*/
/obj/machinery/atmospherics/proc/connection_check(obj/machinery/atmospherics/target, given_layer)
if(is_connectable(target, given_layer) && target.is_connectable(src, given_layer) && check_init_directions(target))
return TRUE
return FALSE
//if target is not multiz then we have to check if the target & src connect in the same direction
if(!istype(target, /obj/machinery/atmospherics/pipe/multiz) && !((initialize_directions & get_dir(src, target)) && (target.initialize_directions & get_dir(target, src))))
return FALSE
/**
* check if the initialized direction are the same on both sides (or if is a multiz adapter)
* returns TRUE or FALSE if the connection is possible or not
* Arguments:
* * obj/machinery/atmospherics/target - the machinery we want to connect to
*/
/obj/machinery/atmospherics/proc/check_init_directions(obj/machinery/atmospherics/target)
if((initialize_directions & get_dir(src, target) && target.initialize_directions & get_dir(target,src)) || istype(target, /obj/machinery/atmospherics/pipe/multiz))
return TRUE
return FALSE
//both target & src can't be connected either way
if(!is_connectable(target, given_layer) || !target.is_connectable(src, given_layer))
return FALSE
return TRUE
/**
* check if the piping layer and color are the same on both sides (grey can connect to all colors)
@@ -279,33 +276,20 @@
/obj/machinery/atmospherics/proc/is_connectable(obj/machinery/atmospherics/target, given_layer)
if(isnull(given_layer))
given_layer = piping_layer
if(check_connectable_layer(target, given_layer) && target.loc != loc && check_connectable_color(target))
return TRUE
return FALSE
/**
* check if the piping layer are the same on both sides or one of them has the PIPING_ALL_LAYER flag
* returns TRUE if one of the parameters is TRUE
* called by is_connectable()
* Arguments:
* * obj/machinery/atmospherics/target - the machinery we want to connect to
* * given_layer - the piping_layer we are connecting to
*/
/obj/machinery/atmospherics/proc/check_connectable_layer(obj/machinery/atmospherics/target, given_layer)
if(target.piping_layer == given_layer || target.pipe_flags & PIPING_ALL_LAYER)
return TRUE
return FALSE
// you cant place the machine on the same location as the target cause it blocks
if(target.loc == loc)
return FALSE
/**
* check if the color are the same on both sides or if one of the pipes are grey or have the PIPING_ALL_COLORS flag
* returns TRUE if one of the parameters is TRUE
* Arguments:
* * obj/machinery/atmospherics/target - the machinery we want to connect to
*/
/obj/machinery/atmospherics/proc/check_connectable_color(obj/machinery/atmospherics/target)
if(target.pipe_color == pipe_color || ((target.pipe_flags | pipe_flags) & PIPING_ALL_COLORS) || target.pipe_color == COLOR_VERY_LIGHT_GRAY || pipe_color == COLOR_VERY_LIGHT_GRAY)
return TRUE
return FALSE
//if the target is not in the same piping layer & it does not have the all layer connection flag[which allows it to be connected regardless of layer] then we are out
if(target.piping_layer != given_layer && !(target.pipe_flags & PIPING_ALL_LAYER))
return FALSE
//if the target does not have the same color and it does not have all color connection flag[which allows it to be connected regardless of color] & one of the pipes is not gray[allowing for connection regardless] then we are out
if(target.pipe_color != pipe_color && !((target.pipe_flags | pipe_flags) & PIPING_ALL_COLORS) && target.pipe_color != COLOR_VERY_LIGHT_GRAY && pipe_color != COLOR_VERY_LIGHT_GRAY)
return FALSE
return TRUE
/**
* Called on construction and when expanding the datum_pipeline, returns the nodes of the device
@@ -3,6 +3,7 @@
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold
icon = 'icons/obj/atmospherics/pipes/he-manifold.dmi'
icon_state = "manifold-3"
base_icon_state = "manifold"
name = "pipe manifold"
desc = "A manifold composed of regular pipes."
@@ -19,6 +20,9 @@
initialize_directions = ALL_CARDINALS
initialize_directions &= ~dir
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/update_pipe_icon()
icon_state = "[base_icon_state]-[piping_layer]"
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/update_overlays()
. = ..()
var/mutable_appearance/center = mutable_appearance(icon, "manifold_center")
@@ -3,6 +3,7 @@
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w
icon = 'icons/obj/atmospherics/pipes/he-manifold.dmi'
icon_state = "manifold4w-3"
base_icon_state = "manifold4w"
name = "4-way pipe manifold"
desc = "A manifold composed of heat-exchanging pipes."
@@ -17,6 +18,9 @@
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/set_init_directions()
initialize_directions = initial(initialize_directions)
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/update_pipe_icon()
icon_state = "[base_icon_state]-[piping_layer]"
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/update_overlays()
. = ..()
var/mutable_appearance/center = mutable_appearance(icon, "manifold4w_center")
@@ -12,40 +12,76 @@ GLOBAL_LIST_INIT(atmos_components, typecacheof(list(/obj/machinery/atmospherics)
pipe_state = "manifold4w"
///Current active connections
var/connections = NONE
///Was this pipe created during map load
var/map_loaded_pipe = FALSE
/obj/machinery/atmospherics/pipe/smart/Initialize(mapload)
map_loaded_pipe = mapload
return ..()
///helper function to append all directions into an single bit flag
/obj/machinery/atmospherics/pipe/smart/proc/append_directions(list/spanning_directions)
var/bit_flag = NONE
for(var/i in 1 to length(spanning_directions))
var/spanning_direction = spanning_directions[i]
if(!spanning_direction)
continue
bit_flag |= spanning_direction
return bit_flag
/obj/machinery/atmospherics/pipe/smart/update_pipe_icon()
icon = 'icons/obj/atmospherics/pipes/pipes_bitmask.dmi'
connections = NONE
//find all directions this pipe is connected with other nodes
connections = NONE
for(var/i in 1 to device_type)
if(!nodes[i])
continue
var/obj/machinery/atmospherics/node = nodes[i]
var/connected_dir = get_dir(src, node)
connections |= connected_dir
var/bitfield = CARDINAL_TO_FULLPIPES(connections)
dir = check_binary_direction(connections)
//set the correct direction for this node in case of binary directions
switch(connections)
if(EAST | WEST)
dir = EAST
if(SOUTH | NORTH)
dir = SOUTH
else
dir = connections
// If we dont have enough bits to make a proper sprite, add some shortpipe bits
//same as connections but used for spriting
var/sprite_bits = NONE
//the directions this pipe stretches out in e.g. T pipe is EAST,WEST & SOUTH, L pipe is NORTH,EAST & so on
var/list/spanning_directions = get_node_connects()
/**
*For pipes created during mapload we draw the pipes sprite only in directions where its connected to a machine
*so for example if an T shaped pipe is connected only in its EAST & WEST directions then only those ends are drawn
*but the SOUTH end is not drawn
*this will allow mappers to use whatever pipes but the end result has no visual clutter.
*This is actually just an bandage for lazy mappers using + pipes all over the place without carying about directions so hopefully when they map pipes correctly we can remove this
*/
if(map_loaded_pipe)
sprite_bits = connections
/**
* if pipe is connected in only one direction[e.g. after disconnecting its neighbour] then to avoid a broken sprite append the reverse direction of its one connected end.
* this wont work for L pipes because if one of its ends is broken then the opposite direction of any of its last connected end is invalid
* e.g. for an L pipe if the top[NORTH] end is broken the opposite of its one remaining connected end[i.e EAST END] is WEST but thats not an valid direction for this pipe
* so we have to again check one last time after this to make sure the pipe isnt broken
*/
if(ISSTUB(sprite_bits))
// & initialize_directions will yield 0 if the reversed direction is not valid
sprite_bits |= REVERSE_DIR(sprite_bits) & get_init_directions()
//if its still broken after the above patch then screw it we make the pipe an normal non mapload type and do the usual stuff with player created pipes
if(ISSTUB(sprite_bits))
sprite_bits = append_directions(spanning_directions)
/**
*for pipes created by players during the round we draw the pipe in all directions so they
*can visually see what ends are free.
*/
else
sprite_bits = append_directions(spanning_directions)
// Smart pipe icons differ from classic pipe icons in that we stop adding
// short pipe directions as soon as we find a valid sprite, rather than
// adding in all connectable directions.
// This prevents a lot of visual clutter, though it does make it harder to
// notice completely disconnected pipes.
if(ISSTUB(connections))
var/bits_to_add = NONE
if(connections != NONE)
bits_to_add |= REVERSE_DIR(connections) & initialize_directions
var/candidates = initialize_directions
var/shift = 0
// Note that candidates "should" never reach 0, as stub pipes are not allowed and break things
while (ISSTUB(connections | bits_to_add) && (candidates >> shift) != 0)
bits_to_add |= candidates & (1 << shift)
shift += 1
bitfield |= CARDINAL_TO_SHORTPIPES(bits_to_add)
icon_state = "[bitfield]_[piping_layer]"
icon_state = "[sprite_bits]_[piping_layer]"
/obj/machinery/atmospherics/pipe/smart/set_init_directions(init_dir)
if(init_dir)
@@ -53,28 +89,6 @@ GLOBAL_LIST_INIT(atmos_components, typecacheof(list(/obj/machinery/atmospherics)
else
initialize_directions = ALL_CARDINALS
/obj/machinery/atmospherics/pipe/smart/proc/check_binary_direction(direction)
switch(direction)
if(EAST|WEST)
return EAST
if(SOUTH|NORTH)
return SOUTH
else
return direction
/obj/machinery/atmospherics/pipe/smart/proc/check_manifold_direction(direction)
switch(direction)
if(NORTH|SOUTH|EAST)
return WEST
if(NORTH|SOUTH|WEST)
return EAST
if(NORTH|WEST|EAST)
return SOUTH
if(SOUTH|WEST|EAST)
return NORTH
else
return null
//mapping helpers
/obj/machinery/atmospherics/pipe/smart/simple
icon = 'icons/obj/atmospherics/pipes/simple.dmi'