From 3afe3391987fc7fb79ddd5c231b1d7fa910037f9 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 24 Apr 2017 17:43:37 -0500 Subject: [PATCH] Fixes bugs with shuttles breaking pipes, wires and disposals --- code/game/mecha/equipment/tools/work_tools.dm | 4 +- .../atmospherics/machinery/atmosmachinery.dm | 69 ++++++++++++++++--- .../binary_devices/binary_devices.dm | 8 +-- .../trinary_devices/trinary_devices.dm | 5 +- .../machinery/pipes/heat_exchange/junction.dm | 8 +-- code/modules/power/cable.dm | 63 +++++++++++++++-- code/modules/recycling/disposal-structures.dm | 10 +++ code/modules/shuttle/on_move.dm | 24 +++---- code/modules/shuttle/shuttle.dm | 22 +++++- 9 files changed, 166 insertions(+), 47 deletions(-) diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm index e7e8379095..8a78bad45a 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -409,13 +409,13 @@ NC.cableColor("red") NC.d1 = 0 NC.d2 = fdirn - NC.updateicon() + NC.update_icon() var/datum/powernet/PN if(last_piece && last_piece.d2 != chassis.dir) last_piece.d1 = min(last_piece.d2, chassis.dir) last_piece.d2 = max(last_piece.d2, chassis.dir) - last_piece.updateicon() + last_piece.update_icon() PN = last_piece.powernet if(!PN) diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 6044b6a1a4..a838f53da7 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -60,19 +60,24 @@ Pipelines + Other Objects -> Pipe network N.disconnect(src) NODE_I = null +/obj/machinery/atmospherics/proc/getNodeConnects() + var/list/node_connects = list() + node_connects.len = device_type + + for(DEVICE_TYPE_LOOP) + for(var/D in GLOB.cardinal) + if(D & GetInitDirections()) + if(D in node_connects) + continue + node_connects[I] = D + break + return node_connects + + //this is called just after the air controller sets up turfs /obj/machinery/atmospherics/proc/atmosinit(var/list/node_connects) if(!node_connects) //for pipes where order of nodes doesn't matter - node_connects = list() - node_connects.len = device_type - - for(DEVICE_TYPE_LOOP) - for(var/D in GLOB.cardinal) - if(D & GetInitDirections()) - if(D in node_connects) - continue - node_connects[I] = D - break + node_connects = getNodeConnects() for(DEVICE_TYPE_LOOP) for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[I])) @@ -288,3 +293,47 @@ Pipelines + Other Objects -> Pipe network //Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it. /obj/machinery/atmospherics/proc/can_see_pipes() return 1 + +//Properly updates pipes on shuttle movement +/obj/machinery/atmospherics/shuttleRotate(rotation) + var/list/real_node_connect = getNodeConnects() + for(DEVICE_TYPE_LOOP) + real_node_connect[I] = angle2dir(rotation+dir2angle(real_node_connect[I])) + + ..() + SetInitDirections() + var/list/supposed_node_connect = getNodeConnects() + var/list/nodes_copy = nodes.Copy() + + for(DEVICE_TYPE_LOOP) + var/new_pos = supposed_node_connect.Find(real_node_connect[I]) + nodes[new_pos] = nodes_copy[I] + +/obj/machinery/atmospherics/afterShuttleMove() + ..() + var/missing_nodes = FALSE + for(DEVICE_TYPE_LOOP) + if(src.nodes[I]) + var/obj/machinery/atmospherics/node = src.nodes[I] + var/connected = FALSE + for(var/D in GLOB.cardinal) + if(node in get_step(src, D)) + connected = TRUE + break + + if(!connected) + nullifyNode(I) + + if(!src.nodes[I]) + missing_nodes = TRUE + + if(missing_nodes) + atmosinit() + for(var/obj/machinery/atmospherics/A in pipeline_expansion()) + A.atmosinit() + if(A.returnPipenet()) + A.addMember(src) + build_network() + else + // atmosinit() calls update_icon(), so we don't need to call it + update_icon() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm b/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm index 6b838d991c..0e9ad562de 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm @@ -26,9 +26,5 @@ Iconnery Housekeeping and pipe network stuff */ -/obj/machinery/atmospherics/components/binary/atmosinit() - var/node2_connect = dir - var/node1_connect = turn(dir, 180) - - var/list/node_connects = list(node1_connect, node2_connect) - ..(node_connects) \ No newline at end of file +/obj/machinery/atmospherics/components/binary/getNodeConnects() + return list(turn(dir, 180), dir) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm b/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm index 8b0adfd91c..ad9d80efc4 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm @@ -22,7 +22,7 @@ Housekeeping and pipe network stuff */ -/obj/machinery/atmospherics/components/trinary/atmosinit() +/obj/machinery/atmospherics/components/trinary/getNodeConnects() //Mixer: //1 and 2 is input @@ -43,5 +43,4 @@ Housekeeping and pipe network stuff node1_connect = turn(node1_connect, 180) node3_connect = turn(node3_connect, 180) - var/list/node_connects = list(node1_connect, node2_connect, node3_connect) - ..(node_connects) \ No newline at end of file + return list(node1_connect, node2_connect, node3_connect) \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm index 0cba512ec6..49c911b858 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm @@ -29,12 +29,8 @@ initialize_directions = EAST initialize_directions_he = WEST -/obj/machinery/atmospherics/pipe/heat_exchanging/junction/atmosinit() - var/node2_connect = dir - var/node1_connect = turn(dir, 180) - var/list/node_connects = list(node1_connect, node2_connect) - - ..(node_connects) +/obj/machinery/atmospherics/pipe/heat_exchanging/junction/getNodeConnects() + return list(turn(dir, 180), dir) /obj/machinery/atmospherics/pipe/heat_exchanging/junction/can_be_node(obj/machinery/atmospherics/target, iteration) var/init_dir diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 6ac6ff8e2f..b5b6165699 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -108,9 +108,9 @@ By design, d1 is the smallest direction and d2 is the highest if(level == 1 && isturf(loc)) invisibility = i ? INVISIBILITY_MAXIMUM : 0 - updateicon() + update_icon() -/obj/structure/cable/proc/updateicon() +/obj/structure/cable/update_icon() if(invisibility) icon_state = "[d1]-[d2]-f" else @@ -429,6 +429,59 @@ By design, d1 is the smallest direction and d2 is the highest if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to P.disconnect_from_network() //remove from current network +// Ugly procs that ensure proper separation and reconnection of wires on shuttle movement/rotation +/obj/structure/cable/beforeShuttleMove(turf/T1, rotation) + var/on_edge = FALSE + var/A = get_area(src) + + for(var/D in GLOB.alldirs) + if(A != get_area(get_step(src, D))) + on_edge = TRUE + break + + if(on_edge && powernet) + var/tmp_loc = loc + cut_cable_from_powernet() + loc = tmp_loc + +/obj/structure/cable/afterShuttleMove() + var/on_edge = FALSE + var/A = get_area(src) + + for(var/D in GLOB.alldirs) + if(A != get_area(get_step(src, D))) + on_edge = TRUE + break + + if(on_edge) + var/datum/powernet/PN = new() + PN.add_cable(src) + + mergeConnectedNetworks(d1) //merge the powernet with adjacents powernets + mergeConnectedNetworks(d2) + mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets + + if(d1 & (d1 - 1))// if the cable is layed diagonally, check the others 2 possible directions + mergeDiagonalsNetworks(d1) + if(d2 & (d2 - 1)) + mergeDiagonalsNetworks(d2) + +/obj/structure/cable/shuttleRotate(rotation) + //..() is not called because wires are not supposed to have a non-default direction + //Rotate connections + if(d1) + d1 = angle2dir(rotation+dir2angle(d1)) + if(d2) + d2 = angle2dir(rotation+dir2angle(d2)) + + //d1 should be less than d2 for cable icons to work + if(d1 > d2) + var/temp = d1 + d1 = d2 + d2 = temp + update_icon() + + /////////////////////////////////////////////// // The cable coil object, used for laying cable /////////////////////////////////////////////// @@ -584,7 +637,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai C.d1 = 0 //it's a O-X node cable C.d2 = dirn C.add_fingerprint(user) - C.updateicon() + C.update_icon() //create a new powernet with the cable, if needed it will be merged later var/datum/powernet/PN = new() @@ -650,7 +703,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai NC.d1 = 0 NC.d2 = fdirn NC.add_fingerprint() - NC.updateicon() + NC.update_icon() //create a new powernet with the cable, if needed it will be merged later var/datum/powernet/newPN = new() @@ -699,7 +752,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai C.update_stored(2, item_color) C.add_fingerprint() - C.updateicon() + C.update_icon() C.mergeConnectedNetworks(C.d1) //merge the powernets... diff --git a/code/modules/recycling/disposal-structures.dm b/code/modules/recycling/disposal-structures.dm index a823b4a62e..531af92238 100644 --- a/code/modules/recycling/disposal-structures.dm +++ b/code/modules/recycling/disposal-structures.dm @@ -340,6 +340,16 @@ if(current_size >= STAGE_FIVE) deconstruct() +//Fixes dpdir on shuttle rotation +/obj/structure/disposalpipe/shuttleRotate(rotation) + ..() + var/new_dpdir = 0 + for(var/D in GLOB.cardinal) + if(dpdir & D) + new_dpdir = new_dpdir | angle2dir(rotation+dir2angle(D)) + dpdir = new_dpdir + + // *** TEST verb //client/verb/dispstop() // for(var/obj/structure/disposalholder/H in world) diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 2f80291a0e..756fad25b3 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -1,3 +1,8 @@ +// Called before shuttle starts moving atoms. +/atom/movable/proc/beforeShuttleMove(turf/T1, rotation) + return + +// Called when shuttle attempts to move an atom. /atom/movable/proc/onShuttleMove(turf/T1, rotation) if(rotation) shuttleRotate(rotation) @@ -6,25 +11,16 @@ update_parallax_contents() return 1 +// Called after all of the atoms on shuttle are moved. +/atom/movable/proc/afterShuttleMove() + return + + /obj/onShuttleMove() if(invisibility >= INVISIBILITY_ABSTRACT) return 0 . = ..() -/obj/machinery/atmospherics/onShuttleMove() - . = ..() - for(DEVICE_TYPE_LOOP) - if(get_area(nodes[I]) != get_area(src)) - nullifyNode(I) - -#define DIR_CHECK_TURF_AREA(X) (get_area(get_ranged_target_turf(src, X, 1)) != A) -/obj/structure/cable/onShuttleMove() - . = ..() - var/A = get_area(src) - //cut cables on the edge - if(DIR_CHECK_TURF_AREA(NORTH) || DIR_CHECK_TURF_AREA(SOUTH) || DIR_CHECK_TURF_AREA(EAST) || DIR_CHECK_TURF_AREA(WEST)) - cut_cable_from_powernet() -#undef DIR_CHECK_TURF_AREA /atom/movable/light/onShuttleMove() return 0 diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index a271ddfe41..94d10392cc 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -481,6 +481,21 @@ //move or squish anything in the way ship at destination roadkill(L0, L1, S1.dir) + + for(var/i in 1 to L0.len) + var/turf/T0 = L0[i] + if(!T0) + continue + var/turf/T1 = L1[i] + if(!T1) + continue + if(T0.type == T0.baseturf) + continue + for(var/atom/movable/AM in T0) + AM.beforeShuttleMove(T1, rotation) + + var/list/moved_atoms = list() + for(var/i in 1 to L0.len) var/turf/T0 = L0[i] if(!T0) @@ -502,7 +517,8 @@ //move mobile to new location for(var/atom/movable/AM in T0) - AM.onShuttleMove(T1, rotation) + if(AM.onShuttleMove(T1, rotation)) + moved_atoms += AM if(rotation) T1.shuttleRotate(rotation) @@ -517,6 +533,10 @@ T0.CalculateAdjacentTurfs() SSair.add_to_active(T0,1) + for(var/am in moved_atoms) + var/atom/movable/AM = am + AM.afterShuttleMove() + check_poddoors() S1.last_dock_time = world.time