diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 03d308e34d6..aae96c38601 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -99,6 +99,9 @@ GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH, else return null +///Returns a single dir rotated by x degrees clockwise, adhering to the cardinal directions. +#define turn_cardinal(dir, rotation) ( angle2dir_cardinal ( dir2angle(dir) + rotation ) ) + //Returns the angle in english /proc/angle2text(degree) return dir2text(angle2dir(degree)) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 39d6fe7d2ea..abd481d525d 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -134,7 +134,7 @@ Buildable meters return ..() /obj/item/pipe/proc/make_from_existing(obj/machinery/atmospherics/make_from) - p_init_dir = make_from.initialize_directions + p_init_dir = make_from.get_init_directions() setDir(make_from.dir) pipename = make_from.name add_atom_colour(make_from.color, FIXED_COLOUR_PRIORITY) diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index ebb6b714850..820361b740e 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -272,9 +272,9 @@ for(var/Ddir in GLOB.cardinals) if(old_entered_dirs & Ddir) - entered_dirs |= angle2dir_cardinal(dir2angle(Ddir) + ang_change) + entered_dirs |= turn_cardinal(Ddir, ang_change) if(old_exited_dirs & Ddir) - exited_dirs |= angle2dir_cardinal(dir2angle(Ddir) + ang_change) + exited_dirs |= turn_cardinal(Ddir, ang_change) update_appearance() return ..() diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 186ef8ea9aa..f0b567a3482 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -26,7 +26,7 @@ ///Check if the object can be unwrenched var/can_unwrench = FALSE ///Bitflag of the initialized directions (NORTH | SOUTH | EAST | WEST) - var/initialize_directions = 0 + var/initialize_directions = NONE ///The color of the pipe var/pipe_color = COLOR_VERY_LIGHT_GRAY ///What layer the pipe is in (from 1 to 5, default 3) @@ -41,7 +41,7 @@ var/image/pipe_vision_img = null ///The type of the device (UNARY, BINARY, TRINARY, QUATERNARY) - var/device_type = 0 + var/device_type = NONE ///The lists of nodes that a pipe/device has, depends on the device_type var (from 1 to 4) var/list/obj/machinery/atmospherics/nodes @@ -257,8 +257,7 @@ * Return a list of the nodes that can connect to other machines, get called by atmos_init() */ /obj/machinery/atmospherics/proc/get_node_connects() - var/list/node_connects = list() - node_connects.len = device_type + var/list/node_connects[device_type] //empty list of size device_type var/init_directions = get_init_directions() for(var/i in 1 to device_type) diff --git a/code/modules/atmospherics/machinery/components/tank.dm b/code/modules/atmospherics/machinery/components/tank.dm index 6aa23f84e93..f025a3b6af7 100644 --- a/code/modules/atmospherics/machinery/components/tank.dm +++ b/code/modules/atmospherics/machinery/components/tank.dm @@ -31,6 +31,8 @@ ///The image showing the gases inside of the tank var/image/window + /// The open node directions of the tank, assuming that the tank is facing NORTH. + var/open_ports = NONE /// The volume of the gas mixture var/volume = 2500 //in liters /// The max pressure of the gas mixture before damaging the tank @@ -97,7 +99,8 @@ // Mapped in tanks should automatically connect to adjacent pipenets in the direction set in dir if(mapload) - initialize_directions = dir + set_portdir_relative(dir, TRUE) + set_init_directions() return INITIALIZE_HINT_LATELOAD @@ -151,28 +154,60 @@ refresh_window() /////////////////////////////////////////////////////////////////// -// Pipenet stuff +// Port stuff -/obj/machinery/atmospherics/components/tank/return_analyzable_air() - return air_contents +/** + * Enables/Disables a port direction in var/open_ports. \ + * Use this, then call set_init_directions() instead of setting initialize_directions directly \ + * This system exists because tanks not having all initialize_directions set correctly breaks shuttle rotations + */ +/obj/machinery/atmospherics/components/tank/proc/set_portdir_relative(relative_port_dir, enable) + ASSERT(!isnull(enable), "Did not receive argument enable") -/obj/machinery/atmospherics/components/tank/return_airs_for_reconcilation(datum/pipeline/requester) - . = ..() - if(!air_contents) - return - . += air_contents - -/obj/machinery/atmospherics/components/tank/return_pipenets_for_reconcilation(datum/pipeline/requester) - . = ..() - var/datum/merger/merge_group = GetMergeGroup(merger_id, merger_typecache) - for(var/obj/machinery/atmospherics/components/tank/tank as anything in merge_group.members) - . += tank.parents - -/obj/machinery/atmospherics/components/tank/proc/toggle_side_port(new_dir) - if(initialize_directions & new_dir) - initialize_directions &= ~new_dir + // Rotate the given dir so that it's relative to north + var/port_dir + if(dir == NORTH) // We're already facing north, no rotation needed + port_dir = relative_port_dir else - initialize_directions |= new_dir + var/offnorth_angle = dir2angle(dir) + port_dir = turn(relative_port_dir, offnorth_angle) + + if(enable) + open_ports |= port_dir + else + open_ports &= ~port_dir + +/** + * Toggles a port direction in var/open_ports \ + * Use this, then call set_init_directions() instead of setting initialize_directions directly \ + * This system exists because tanks not having all initialize_directions set correctly breaks shuttle rotations + */ +/obj/machinery/atmospherics/components/tank/proc/toggle_portdir_relative(relative_port_dir) + var/toggle = ((initialize_directions & relative_port_dir) ? FALSE : TRUE) + set_portdir_relative(relative_port_dir, toggle) + +/obj/machinery/atmospherics/components/tank/set_init_directions() + if(!open_ports) + initialize_directions = NONE + return + + //We're rotating open_ports relative to dir, and + //setting initialize_directions to that rotated dir + var/relative_port_dirs = NONE + var/dir_angle = dir2angle(dir) + for(var/cardinal in GLOB.cardinals) + var/current_dir = cardinal & open_ports + if(!current_dir) + continue + + var/rotated_dir = turn(current_dir, -dir_angle) + relative_port_dirs |= rotated_dir + + initialize_directions = relative_port_dirs + +/obj/machinery/atmospherics/components/tank/proc/toggle_side_port(port_dir) + toggle_portdir_relative(port_dir) + set_init_directions() for(var/i in 1 to length(nodes)) var/obj/machinery/atmospherics/components/node = nodes[i] @@ -195,6 +230,24 @@ update_parents() +/////////////////////////////////////////////////////////////////// +// Pipenet stuff + +/obj/machinery/atmospherics/components/tank/return_analyzable_air() + return air_contents + +/obj/machinery/atmospherics/components/tank/return_airs_for_reconcilation(datum/pipeline/requester) + . = ..() + if(!air_contents) + return + . += air_contents + +/obj/machinery/atmospherics/components/tank/return_pipenets_for_reconcilation(datum/pipeline/requester) + . = ..() + var/datum/merger/merge_group = GetMergeGroup(merger_id, merger_typecache) + for(var/obj/machinery/atmospherics/components/tank/tank as anything in merge_group.members) + . += tank.parents + /////////////////////////////////////////////////////////////////// // Merger handling diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index af7a9a4bf51..d7afd8461c0 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -248,11 +248,6 @@ All ShuttleMove procs go here . = ..() recharging_turf = get_step(loc, dir) -/obj/machinery/atmospherics/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) - . = ..() - if(pipe_vision_img) - pipe_vision_img.loc = loc - /obj/machinery/computer/auxiliary_base/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() if(is_mining_level(z)) //Avoids double logging and landing on other Z-levels due to badminnery @@ -260,6 +255,9 @@ All ShuttleMove procs go here /obj/machinery/atmospherics/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() + if(pipe_vision_img) + pipe_vision_img.loc = loc + var/missing_nodes = FALSE for(var/i in 1 to device_type) if(nodes[i]) diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm index 15af6db6a4f..7afd43a0d35 100644 --- a/code/modules/shuttle/shuttle_rotate.dm +++ b/code/modules/shuttle/shuttle_rotate.dm @@ -82,7 +82,11 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate /obj/machinery/atmospherics/shuttleRotate(rotation, params) var/list/real_node_connect = get_node_connects() for(var/i in 1 to device_type) - real_node_connect[i] = angle2dir(rotation+dir2angle(real_node_connect[i])) + var/node_dir = real_node_connect[i] + if(isnull(node_dir)) + continue + + real_node_connect[i] = turn(node_dir, -rotation) . = ..() set_init_directions() @@ -90,7 +94,11 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate var/list/nodes_copy = nodes.Copy() for(var/i in 1 to device_type) - var/new_pos = supposed_node_connect.Find(real_node_connect[i]) + var/node_dir = real_node_connect[i] + if(isnull(node_dir)) + continue + + var/new_pos = supposed_node_connect.Find(node_dir) nodes[new_pos] = nodes_copy[i] //prevents shuttles attempting to rotate this since it messes up sprites