Mapping helpers

This commit is contained in:
kevinz000
2020-01-15 18:22:43 -07:00
parent 8c50b578b4
commit c5b95ff5d0
9 changed files with 642 additions and 349 deletions
@@ -0,0 +1,38 @@
//Builds networks like power cables/atmos lines/etc
//Just a holder parent type for now..
/obj/effect/network_builder
/// set var to true to not del on lateload
var/custom_spawned = FALSE
/// what directions we know connections are in
var/list/network_directions
/obj/effect/network_builder/Initialize(mapload)
. = ..()
var/conflict = check_duplicates()
if(conflict)
stack_trace("WARNING: [type] network building helper found check_duplicates() conflict [conflict] in its location.!")
return INITIALIZE_HINT_QDEL
if(!mapload)
if(GLOB.Debug2)
custom_spawned = TRUE
return INITIALIZE_HINT_NORMAL
else
return INITIALIZE_HINT_QDEL
return INITIALIZE_HINT_LATELOAD
/// How this works: On LateInitialize, detect all directions that this should be applicable to, and do what it needs to do, and then inform all network builders in said directions that it's been around since it won't be around afterwards.
/obj/effect/network_builder/LateInitialize()
scan_directions()
build_network()
if(!custom_spawned)
qdel(src)
/obj/effect/network_builder/proc/check_duplicates()
CRASH("Base abstract network builder tried to check duplicates.")
/obj/effect/network_builder/proc/scan_directions()
CRASH("Base abstract network builder tried to scan directions.")
/obj/effect/network_builder/proc/build_network()
CRASH("Base abstract network builder tried to build network.")
@@ -0,0 +1,159 @@
#define NO_KNOT 0
#define KNOT_AUTO 1
#define KNOT_FORCED 2
/* Automatically places pipes on init based on any pipes connecting to it and adjacent helpers. Only supports cardinals.
* Conflicts with ANY PIPE ON ITS LAYER, as well as atmos network build helpers on the same layer, as well as any pipe on all layers. Do those manually.
*/
/obj/effect/network_builder/atmos_pipe
name = "atmos pipe autobuilder"
icon_state = "atmospipebuilder"
/// Layer to put our pipes on
var/pipe_layer = PIPING_LAYER_DEFAULT
/// Color to set our pipes to
var/pipe_color
/// Whether or not pipes we make are visible
var/visible_pipes = FALSE
color = null
/obj/effect/network_builder/atmos_pipe/check_duplicates()
for(var/obj/effect/network_builder/atmos_pipe/other in loc)
if(other.pipe_layer == pipe_layer)
return other
for(var/obj/machinery/atmospherics/A in loc)
if(A.pipe_flags & PIPING_ALL_LAYER)
return A
if(A.pipe_layer == pipe_layer)
return A
return FALSE
/// Scans directions, sets network_directions to have every direction that we can link to. If there's another power cable builder detected, make sure they know we're here by adding us to their cable directions list before we're deleted.
/obj/effect/network_builder/atmos_pipe/scan_directions()
var/turf/T
for(var/i in GLOB.cardinal)
if(i in network_directions)
continue //we're already set, that means another builder set us.
T = get_step(loc, i)
if(!T)
continue
var/found = FALSE
for(var/obj/effect/network_builder/atmos_pipe/other in T)
if(other.pipe_layer == pipe_layer)
network_directions += i
LAZYADD(other.network_directions, turn(i, 180))
found = TRUE
break
if(found)
continue
for(var/obj/machinery/atmospherics/A in T)
if((A.pipe_layer == pipe_layer) && (A.initialize_directions & i))
network_directions += i
break
return network_directions
/// Directions should only ever have cardinals.
/obj/effect/network_builder/atmos_pipe/build_network(list/directions = pipe_directions)
if(!length(directions) <= 1)
return
var/obj/machinery/atmospherics/pipe/built
switch(length(directions))
if(2) //straight pipe
built = new /obj/machinery/atmospherics/simple(loc)
built.setDir(directions[1] | directions[2])
if(3) //manifold
var/list/missing = directions ^ GLOB.cardinal
missing = missing[1]
built = new /obj/machinery/atmospherics/pipe/manifold(loc)
built.setDir(missing)
if(4) //4 way manifold
built = new /obj/machinery/atmospherics/pipe/manifold4w(loc)
built.SetInitDirections()
built.on_construction(pipe_color, piping_layer)
/obj/item/pipe/wrench_act(mob/living/user, obj/item/wrench/W)
if(!isturf(loc))
return TRUE
add_fingerprint(user)
var/obj/machinery/atmospherics/fakeA = pipe_type
var/flags = initial(fakeA.pipe_flags)
for(var/obj/machinery/atmospherics/M in loc)
if((M.pipe_flags & flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers.
to_chat(user, "<span class='warning'>Something is hogging the tile!</span>")
return TRUE
if((M.piping_layer != piping_layer) && !((M.pipe_flags | flags) & PIPING_ALL_LAYER)) //don't continue if either pipe goes across all layers
continue
if(M.GetInitDirections() & SSair.get_init_dirs(pipe_type, fixed_dir())) // matches at least one direction on either type of pipe
to_chat(user, "<span class='warning'>There is already a pipe at that location!</span>")
return TRUE
// no conflicts found
var/obj/machinery/atmospherics/A = new pipe_type(loc)
build_pipe(A)
A.on_construction(color, piping_layer)
transfer_fingerprints_to(A)
W.play_tool_sound(src)
user.visible_message( \
"[user] fastens \the [src].", \
"<span class='notice'>You fasten \the [src].</span>", \
"<span class='italics'>You hear ratcheting.</span>")
qdel(src)
/obj/item/pipe/proc/build_pipe(obj/machinery/atmospherics/A)
A.setDir(fixed_dir())
A.SetInitDirections()
if(pipename)
A.name = pipename
if(A.on)
// Certain pre-mapped subtypes are on by default, we want to preserve
// every other aspect of these subtypes (name, pre-set filters, etc.)
// but they shouldn't turn on automatically when wrenched.
A.on = FALSE
/obj/effect/network_builder/atmos_pipe/proc/spawn_wires(list/directions)
if(!length(directions))
return
else if(length(directions) == 1)
var/knot = (knot == KNOT_FORCED) || ((knot == KNOT_AUTO) && should_auto_knot())
if(knot)
var/dir = directions[1]
new /obj/structure/cable(loc, cable_color, NONE, directions[1])
else
if(knot == KNOT_FORCED)
for(var/d in directions)
new /obj/structure/cable(loc, cable_color, NONE, d)
else
var/knot = (knot == KNOT_FORCED) || ((knot == KNOT_AUTO) && should_auto_knot())
var/dirs = length(directions)
for(var/i in dirs)
var/li = i - 1
if(li < 1)
li = dirs + li
new /obj/structure/cable(loc, cable_color, directions[i], directions[li])
if(knot)
new /obj/structure/cable(loc, cable_color, NONE, directions[i])
knot = FALSE
/obj/effect/network_builder/atmos_pipe/distro
name = "distro line autobuilder"
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y
pipe_color = rgb(130,43,255)
color = rgb(130,43,255)
/obj/effect/network_builder/atmos_pipe/scrubbers
name = "scrubbers line autobuilder"
piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y
pipe_color = rgb(255,0,0)
color = rgb(255,0,0)
@@ -0,0 +1,97 @@
#define NO_KNOT 0
#define KNOT_AUTO 1
#define KNOT_FORCED 2
/// Automatically links on init to power cables and other cable builder helpers. Only supports cardinals.
/obj/effect/network_builder/power_cable
name = "power line autobuilder"
icon_state = "powerlinebuilder"
/// Whether or not we forcefully make a knot
var/knot = NO_KNOT
/// cable color as from GLOB.cable_colors
var/cable_color = "red"
color = "ff0000"
/obj/effect/network_builder/power_cable/check_duplicates()
return (locate(/obj/structure/cable) in loc) || (locate(/obj/effect/network_builder/power_cable) in loc)
/// Scans directions, sets network_directions to have every direction that we can link to. If there's another power cable builder detected, make sure they know we're here by adding us to their cable directions list before we're deleted.
/obj/effect/network_builder/power_cable/scan_directions()
var/turf/T
for(var/i in GLOB.cardinal)
if(i in network_directions)
continue //we're already set, that means another builder set us.
T = get_step(loc, i)
if(!T)
continue
var/obj/effect/network_builder/power_cable/other = locate() in T
if(other)
network_directions += i
LAZYADD(other.network_directions, turn(i, 180))
continue
for(var/obj/structure/cable/C in T)
if(C.d1 == turn(i, 180) || C.d2 == turn(i, 180))
network_directions += i
continue
return network_directions
/// Directions should only ever have cardinals.
/obj/effect/network_builder/power_cable/build_network(list/directions = network_directions)
if(!length(directions))
return
else if(length(directions) == 1)
var/knot = (knot == KNOT_FORCED) || ((knot == KNOT_AUTO) && should_auto_knot())
if(knot)
var/dir = directions[1]
new /obj/structure/cable(loc, cable_color, NONE, directions[1])
else
if(knot == KNOT_FORCED)
for(var/d in directions)
new /obj/structure/cable(loc, cable_color, NONE, d)
else
var/knot = (knot == KNOT_FORCED) || ((knot == KNOT_AUTO) && should_auto_knot())
var/dirs = length(directions)
for(var/i in dirs)
var/li = i - 1
if(li < 1)
li = dirs + li
new /obj/structure/cable(loc, cable_color, directions[i], directions[li])
if(knot)
new /obj/structure/cable(loc, cable_color, NONE, directions[i])
knot = FALSE
/obj/effect/network_builder/power_cable/proc/should_auto_knot()
return (locate(/obj/machinery/terminal) in loc)
/obj/effect/network_buidler/power_cable/knot
icon_state = "powerlinebuilderknot"
knot = KNOT_FORCED
/obj/effect/network_builder/power_cable/auto
icon_state = "powerlinebuilderauto"
knot = KNOT_AUTO
#define AUTODEF_COLOR(hex, enum) \
/obj/effect/network_builder/power_cable/##enum \
color = #hex \
cable_color = #enum \
/obj/effect/network_builder/power_cable/knot/##enum \
color = #hex \
cable_color = #enum \
/obj/effect/network_builder/power_cable/auto/##enum \
color = #hex \
cable_color = #enum
AUTODEF_COLOR("#ff0000", "red")
AUTODEF_COLOR("#ffffff", "white")
AUTODEF_COLOR("#00ffff", "cyan")
AUTODEF_COLOR("#ff8000", "orange")
AUTODEF_COLOR("#ff3cc8", "pink")
AUTODEF_COLOR("#1919c8", "blue")
AUTODEF_COLOR("#00aa00", "green")
AUTODEF_COLOR("#ffff00", "yellow")
#undef AUTODEF_COLOR