From eb32b0e45c7c0be3bffb4aaff06fb5b8f4c99c10 Mon Sep 17 00:00:00 2001 From: Uristqwerty Date: Sun, 17 Mar 2013 20:59:36 -0400 Subject: [PATCH] Automatic tube state, tries to connect two tubes. Less precise, but faster to lay out when mapping. --- code/game/objects/structures/transit_tubes.dm | 141 +++++++++++++++++- icons/obj/pipes/transit_tube.dmi | Bin 9235 -> 9791 bytes 2 files changed, 135 insertions(+), 6 deletions(-) diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm index 711305dabad..433e306285a 100644 --- a/code/game/objects/structures/transit_tubes.dm +++ b/code/game/objects/structures/transit_tubes.dm @@ -13,6 +13,12 @@ var/exit_delay = 2 var/enter_delay = 1 + // alldirs in global.dm is the same list of directions, but since + // the specific order matters to get a usable icon_state, it is + // copied here so that, in the unlikely case that alldirs is changed, + // this continues to work. + var/global/list/tube_dir_list = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) + // A place where tube pods stop, and people can get in or out. // Mappers: use "Generate Instances from Directions" for this @@ -86,8 +92,12 @@ obj/structure/ex_act(severity) /obj/structure/transit_tube/New(loc) ..(loc) - if(tube_dirs == null) - init_dirs() + // Spawn here to allow in-game procs to set the icon_state + // first, and so that the rest of the map loads before in-map + // auto tubes try to generate. + spawn(1) + if(tube_dirs == null) + init_dirs() @@ -421,10 +431,16 @@ obj/structure/ex_act(severity) // variations. Additionally, as a separate proc, sub-types // can handle it more intelligently. /obj/structure/transit_tube/proc/init_dirs() - tube_dirs = parse_dirs(icon_state) + if(icon_state == "auto") + // Additional delay, for map loading. + spawn(1) + init_dirs_automatic() - if(copytext(icon_state, 1, 3) == "D-" || findtextEx(icon_state, "Pass")) - density = 0 + else + tube_dirs = parse_dirs(icon_state) + + if(copytext(icon_state, 1, 3) == "D-" || findtextEx(icon_state, "Pass")) + density = 0 @@ -435,6 +451,94 @@ obj/structure/ex_act(severity) +// Initialize dirs by searching for tubes that do/might connect +// on nearby turfs. Create corner pieces if nessecary. +// Pick two directions, preferring tubes that already connect +// to loc, or other auto tubes if there aren't enough connections. +/obj/structure/transit_tube/proc/init_dirs_automatic() + var/list/connected = list() + var/list/connected_auto = list() + + for(var/direction in tube_dir_list) + var/location = get_step(loc, direction) + for(var/obj/structure/transit_tube/tube in location) + if(tube.directions() == null && tube.icon_state == "auto") + connected_auto += direction + break + + else if(turn(direction, 180) in tube.directions()) + connected += direction + break + + connected += connected_auto + + tube_dirs = select_automatic_dirs(connected) + + if(length(tube_dirs) == 2 && tube_dir_list.Find(tube_dirs[1]) > tube_dir_list.Find(tube_dirs[2])) + tube_dirs.Swap(1, 2) + + generate_automatic_corners(tube_dirs) + select_automatic_icon_state(tube_dirs) + + + +// Given a list of directions, look a pair that forms a 180 or +// 135 degree angle, and return a list containing the pair. +// If none exist, return list(connected[1], turn(connected[1], 180) +/obj/structure/transit_tube/proc/select_automatic_dirs(connected) + if(length(connected) < 1) + return list() + + for(var/i = 1, i <= length(connected), i++) + for(var/j = i + 1, j <= length(connected), j++) + var/d1 = connected[i] + var/d2 = connected[j] + + if(d1 == turn(d2, 135) || d1 == turn(d2, 180) || d1 == turn(d2, 225)) + return list(d1, d2) + + return list(connected[1], turn(connected[1], 180)) + + + +/obj/structure/transit_tube/proc/select_automatic_icon_state(directions) + if(length(directions) == 2) + icon_state = "[dir2text_short(directions[1])]-[dir2text_short(directions[2])]" + + + +// Look for diagonal directions, generate the decorative corners in each. +/obj/structure/transit_tube/proc/generate_automatic_corners(directions) + for(var/direction in directions) + if(direction == 5 || direction == 6 || direction == 9 || direction == 10) + if(direction & NORTH) + create_automatic_decorative_corner(get_step(loc, NORTH), direction ^ 3) + + else + create_automatic_decorative_corner(get_step(loc, SOUTH), direction ^ 3) + + if(direction & EAST) + create_automatic_decorative_corner(get_step(loc, EAST), direction ^ 12) + + else + create_automatic_decorative_corner(get_step(loc, WEST), direction ^ 12) + + + +// Generate a corner, if one doesn't exist for the direction on the turf. +/obj/structure/transit_tube/proc/create_automatic_decorative_corner(location, direction) + var/state = "D-[dir2text_short(direction)]" + + for(var/obj/structure/transit_tube/tube in location) + if(tube.icon_state == state) + return + + var/obj/structure/transit_tube/tube = new(location) + tube.icon_state = state + tube.init_dirs() + + + // Uses a list() to cache return values. Since they should // never be edited directly, all tubes with a certain // icon_state can just reference the same list. In theory, @@ -491,4 +595,29 @@ obj/structure/ex_act(severity) if("SOUTHWEST", "SW") return 10 else - return 0 \ No newline at end of file + return 0 + + + +// A copy of dir2text, which returns the short one or two letter +// directions used in tube icon states. +/obj/structure/transit_tube/proc/dir2text_short(direction) + switch(direction) + if(1) + return "N" + if(2) + return "S" + if(4) + return "E" + if(8) + return "W" + if(5) + return "NE" + if(6) + return "SE" + if(9) + return "NW" + if(10) + return "SW" + else + return diff --git a/icons/obj/pipes/transit_tube.dmi b/icons/obj/pipes/transit_tube.dmi index c1bbf75f6be35efb609e2ad9f1d9bb0313c08ef1..45b2abc3c3efe0aa6dcd7924c99095df6377a408 100644 GIT binary patch literal 9791 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 DDPuq}