diff --git a/_maps/RandomRuins/SpaceRuins/caravanambush.dmm b/_maps/RandomRuins/SpaceRuins/caravanambush.dmm
index 2f395e4f1c4..58af9d49196 100644
--- a/_maps/RandomRuins/SpaceRuins/caravanambush.dmm
+++ b/_maps/RandomRuins/SpaceRuins/caravanambush.dmm
@@ -735,30 +735,10 @@
/area/ruin/powered)
"cu" = (
/obj/structure/closet/crate/secure/engineering,
-/obj/item/wrench{
- color = "#ff0000";
- desc = "A prototype of a new wrench design, allegedly the red color scheme makes it go faster.";
- name = "experimental wrench";
- toolspeed = 3
- },
-/obj/item/screwdriver{
- color = "#ff0000";
- desc = "A prototype of a new screwdriver design, allegedly the red color scheme makes it go faster.";
- name = "experimental screwdriver";
- toolspeed = 3
- },
-/obj/item/wirecutters{
- color = "#ff0000";
- desc = "A prototype of a new wirecutter design, allegedly the red color scheme makes it go faster.";
- name = "experimental wirecutters";
- toolspeed = 3
- },
-/obj/item/crowbar/red{
- color = "#ff0000";
- desc = "A prototype of a new crowbar design, allegedly the red color scheme makes it go faster.";
- name = "experimental crowbar";
- toolspeed = 3
- },
+/obj/item/wrench/caravan,
+/obj/item/screwdriver/caravan,
+/obj/item/wirecutters/caravan,
+/obj/item/crowbar/red/caravan,
/turf/open/floor/mineral/plastitanium,
/area/ruin/powered)
"cv" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 1abcb105e18..92e087ff055 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -3622,7 +3622,7 @@
min_oxy = 5;
name = "Sergeant Araneus";
real_name = "Sergeant Araneus";
- movement_type = GROUND
+ movement_type = 1;
response_help = "pets";
turns_per_move = 10;
voice_name = "unidentifiable voice"
diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm
index 383e4c8bcc2..1273b5e3de5 100644
--- a/code/__DEFINES/atmospherics.dm
+++ b/code/__DEFINES/atmospherics.dm
@@ -177,6 +177,19 @@
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
#define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300"
+//IF YOU EVER CHANGE THESE CHANGE SPRITES TO MATCH.
+#define PIPING_LAYER_MIN 1
+#define PIPING_LAYER_MAX 3
+#define PIPING_LAYER_DEFAULT 2
+#define PIPING_LAYER_P_X 5
+#define PIPING_LAYER_P_Y 5
+#define PIPING_LAYER_LCHANGE 0.05
+
+#define PIPING_ALL_LAYER 1 //intended to connect with all layers, check for all instead of just one.
+#define PIPING_ONE_PER_TURF 2 //can only be built if nothing else with this flag is on the tile already.
+#define PIPING_DEFAULT_LAYER_ONLY 4 //can only exist at PIPING_LAYER_DEFAULT
+#define PIPING_CARDINAL_AUTONORMALIZE 8 //north/south east/west doesn't matter, auto normalize on build.
+
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
#define ADD_GAS(gas_id, out_list)\
diff --git a/code/__DEFINES/pipe_construction.dm b/code/__DEFINES/pipe_construction.dm
index 2d15b8aed3e..403c9a061fb 100644
--- a/code/__DEFINES/pipe_construction.dm
+++ b/code/__DEFINES/pipe_construction.dm
@@ -7,24 +7,25 @@ Construction breaks otherwise
//Pipes
#define PIPE_SIMPLE /obj/machinery/atmospherics/pipe/simple
#define PIPE_MANIFOLD /obj/machinery/atmospherics/pipe/manifold
-#define PIPE_4WAYMANIFOLD /obj/machinery/atmospherics/pipe/manifold4w
+#define PIPE_4WAYMANIFOLD /obj/machinery/atmospherics/pipe/manifold4w
#define PIPE_HE /obj/machinery/atmospherics/pipe/heat_exchanging/simple
#define PIPE_HE_MANIFOLD /obj/machinery/atmospherics/pipe/heat_exchanging/manifold
#define PIPE_HE_4WAYMANIFOLD /obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w
#define PIPE_JUNCTION /obj/machinery/atmospherics/pipe/heat_exchanging/junction
-#define PIPE_BLUESPACE /obj/machinery/atmospherics/pipe/bluespace
+#define PIPE_LAYER_MANIFOLD /obj/machinery/atmospherics/pipe/layer_manifold
+#define PIPE_BLUESPACE /obj/machinery/atmospherics/pipe/bluespace
//Unary
#define PIPE_CONNECTOR /obj/machinery/atmospherics/components/unary/portables_connector
#define PIPE_UVENT /obj/machinery/atmospherics/components/unary/vent_pump
#define PIPE_SCRUBBER /obj/machinery/atmospherics/components/unary/vent_scrubber
#define PIPE_INJECTOR /obj/machinery/atmospherics/components/unary/outlet_injector
-#define PIPE_HEAT_EXCHANGE /obj/machinery/atmospherics/components/unary/heat_exchanger
+#define PIPE_HEAT_EXCHANGE /obj/machinery/atmospherics/components/unary/heat_exchanger
//Binary
#define PIPE_PUMP /obj/machinery/atmospherics/components/binary/pump
-#define PIPE_PASSIVE_GATE /obj/machinery/atmospherics/components/binary/passive_gate
-#define PIPE_VOLUME_PUMP /obj/machinery/atmospherics/components/binary/volume_pump
+#define PIPE_PASSIVE_GATE /obj/machinery/atmospherics/components/binary/passive_gate
+#define PIPE_VOLUME_PUMP /obj/machinery/atmospherics/components/binary/volume_pump
#define PIPE_MVALVE /obj/machinery/atmospherics/components/binary/valve
-#define PIPE_DVALVE /obj/machinery/atmospherics/components/binary/valve/digital
+#define PIPE_DVALVE /obj/machinery/atmospherics/components/binary/valve/digital
//Trinary
#define PIPE_GAS_FILTER /obj/machinery/atmospherics/components/trinary/filter
#define PIPE_GAS_MIXER /obj/machinery/atmospherics/components/trinary/mixer
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index b7b18578d91..c1c7390fd5a 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1229,6 +1229,9 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
/proc/stack_trace(msg)
CRASH(msg)
+/datum/proc/stack_trace(msg)
+ CRASH(msg)
+
//Key thing that stops lag. Cornerstone of performance in ss13, Just sitting here, in unsorted.dm.
//Increases delay as the server gets more overloaded,
diff --git a/code/_globalvars/lists/typecache.dm b/code/_globalvars/lists/typecache.dm
index 0a6cdeafea9..dfa99b67067 100644
--- a/code/_globalvars/lists/typecache.dm
+++ b/code/_globalvars/lists/typecache.dm
@@ -7,3 +7,5 @@ GLOBAL_LIST_INIT(typecache_mob, typecacheof(list(/mob)))
GLOBAL_LIST_INIT(typecache_living, typecacheof(list(/mob/living)))
+GLOBAL_LIST_INIT(typecache_machine_or_structure, typecacheof(list(/obj/machinery))|typecacheof(list(/obj/structure)))
+
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index e972eb5bbb6..987913ee188 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -426,7 +426,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
for(var/obj/machinery/door/D in GLOB.airlocks)
if(!(D.z in GLOB.station_z_levels))
continue
- INVOKE_ASYNC(D, /obj/machinery/door.proc/hostile_lockdown, src)
+ INVOKE_ASYNC(D, /obj/machinery/door.proc/hostile_lockdown, owner)
addtimer(CALLBACK(D, /obj/machinery/door.proc/disable_lockdown), 900)
var/obj/machinery/computer/communications/C = locate() in GLOB.machines
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index e56c8f75192..6c3eaf2c729 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -19,11 +19,13 @@ Buildable meters
item_state = "buildpipe"
w_class = WEIGHT_CLASS_NORMAL
level = 2
- var/flipped = 0
- var/is_bent = 0
+ var/flipped = FALSE
+ var/is_bent = FALSE
+ var/piping_layer = PIPING_LAYER_DEFAULT
var/static/list/pipe_types = list(
PIPE_SIMPLE, \
+ PIPE_LAYER_MANIFOLD, \
PIPE_MANIFOLD, \
PIPE_4WAYMANIFOLD, \
PIPE_HE, \
@@ -52,40 +54,58 @@ Buildable meters
..()
to_chat(user, "Alt-click to rotate it clockwise.")
-/obj/item/pipe/New(loc, pipe_type, dir, obj/machinery/atmospherics/make_from)
- ..()
+/obj/item/pipe/Initialize(mapload, _pipe_type, _dir, obj/machinery/atmospherics/make_from)
if(make_from)
- src.setDir(make_from.dir)
- src.pipename = make_from.name
+ setDir(make_from.dir)
+ pipename = make_from.name
add_atom_colour(make_from.color, FIXED_COLOUR_PRIORITY)
if(make_from.type in pipe_types)
- src.pipe_type = make_from.type
+ pipe_type = make_from.type
+ setPipingLayer(make_from.piping_layer)
else //make pipe_type a value we can work with
for(var/P in pipe_types)
if(istype(make_from, P))
- src.pipe_type = P
+ pipe_type = P
break
var/obj/machinery/atmospherics/components/trinary/triP = make_from
if(istype(triP) && triP.flipped)
- src.flipped = 1
- src.setDir(turn(src.dir, -45))
+ flipped = TRUE
+ setDir(turn(dir, -45))
else
- src.pipe_type = pipe_type
- src.setDir(dir)
+ pipe_type = _pipe_type
+ setDir(_dir)
- if(src.dir in GLOB.diagonals)
- is_bent = 1
+ if(_dir in GLOB.diagonals)
+ is_bent = TRUE
update()
- src.pixel_x = rand(-5, 5)
- src.pixel_y = rand(-5, 5)
+ pixel_x = rand(-5, 5)
+ pixel_y = rand(-5, 5)
+ return ..()
+
+/obj/item/pipe/dropped()
+ if(loc)
+ setPipingLayer(piping_layer)
+ return ..()
+
+/obj/item/pipe/proc/setPipingLayer(new_layer = PIPING_LAYER_DEFAULT)
+ var/obj/machinery/atmospherics/fakeA = get_pipe_cache(pipe_type)
+ var/nolayer = (fakeA.pipe_flags & PIPING_ALL_LAYER)
+ if(nolayer)
+ new_layer = PIPING_LAYER_DEFAULT
+ piping_layer = new_layer
+ if(pipe_type != PIPE_LAYER_MANIFOLD)
+ pixel_x = (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X
+ pixel_y = (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y
+ layer = initial(layer) + ((piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE)
//update the name and icon of the pipe item depending on the type
GLOBAL_LIST_INIT(pipeID2State, list(
"[PIPE_SIMPLE]" = "simple", \
"[PIPE_MANIFOLD]" = "manifold", \
+ "[PIPE_LAYER_MANIFOLD]" = "layer_manifold", \
"[PIPE_4WAYMANIFOLD]" = "manifold4w", \
"[PIPE_HE]" = "he", \
"[PIPE_HE_MANIFOLD]" = "he_manifold", \
@@ -114,6 +134,7 @@ GLOBAL_LIST_INIT(pipeID2State, list(
"[PIPE_SIMPLE]" = "pipe", \
"[PIPE_SIMPLE]_b" = "bent pipe", \
"[PIPE_MANIFOLD]" = "manifold", \
+ "[PIPE_LAYER_MANIFOLD]" = "layer manifold", \
"[PIPE_4WAYMANIFOLD]" = "4-way manifold", \
"[PIPE_HE]" = "h/e pipe", \
"[PIPE_HE]_b" = "bent h/e pipe", \
@@ -151,7 +172,7 @@ GLOBAL_LIST_INIT(pipeID2State, list(
if ( usr.stat || usr.restrained() || !usr.canmove )
return
- src.setDir(turn(src.dir, -90))
+ setDir(turn(dir, -90))
fixdir()
@@ -166,11 +187,11 @@ GLOBAL_LIST_INIT(pipeID2State, list(
return
if (pipe_type in list(PIPE_GAS_FILTER, PIPE_GAS_MIXER))
- src.setDir(turn(src.dir, flipped )? 45 : -45)
+ setDir(turn(dir, flipped )? 45 : -45)
flipped = !flipped
return
- src.setDir(turn(src.dir, -180))
+ setDir(turn(dir, -180))
fixdir()
@@ -199,7 +220,7 @@ GLOBAL_LIST_INIT(pipeID2State, list(
//Helper to clean up dir
/obj/item/pipe/proc/fixdir()
- if((pipe_type in list (PIPE_SIMPLE, PIPE_HE, PIPE_MVALVE, PIPE_DVALVE)) && !is_bent)
+ if((pipe_type in list (PIPE_SIMPLE, PIPE_HE, PIPE_MVALVE, PIPE_DVALVE, PIPE_LAYER_MANIFOLD)) && !is_bent)
if(dir==SOUTH)
setDir(NORTH)
else if(dir==WEST)
@@ -208,40 +229,54 @@ GLOBAL_LIST_INIT(pipeID2State, list(
/obj/item/pipe/attack_self(mob/user)
return rotate()
+/obj/item/pipe/proc/get_pipe_cache(type, direction)
+ var/static/list/obj/machinery/atmospherics/check_cache
+ if(!islist(check_cache))
+ check_cache = list()
+ if(!check_cache[type])
+ check_cache[type] = list()
+ if(!check_cache[type]["[direction]"])
+ check_cache[type]["[direction]"] = new type(null, null, direction)
+
+ return check_cache[type]["[direction]"]
+
/obj/item/pipe/attackby(obj/item/W, mob/user, params)
if (!istype(W, /obj/item/wrench))
return ..()
- if (!isturf(src.loc))
- return 1
-
+ if (!isturf(loc))
+ return TRUE
add_fingerprint(user)
fixdir()
if(pipe_type in list(PIPE_GAS_MIXER, PIPE_GAS_FILTER))
setDir(unflip(dir))
- var/obj/machinery/atmospherics/A = new pipe_type(src.loc)
- A.setDir(src.dir)
- A.SetInitDirections()
+ var/obj/machinery/atmospherics/fakeA = get_pipe_cache(pipe_type, dir)
- for(var/obj/machinery/atmospherics/M in src.loc)
- if(M == A) //we don't want to check to see if it interferes with itself
+ for(var/obj/machinery/atmospherics/M in loc)
+ if((M.pipe_flags & PIPING_ONE_PER_TURF) && (fakeA.pipe_flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers.
+ to_chat(user, "Something is hogging the tile!")
+ return TRUE
+ if((M.piping_layer != piping_layer) && !((M.pipe_flags & PIPING_ALL_LAYER) || (pipe_type == PIPE_LAYER_MANIFOLD)))
continue
- if(M.GetInitDirections() & A.GetInitDirections()) // matches at least one direction on either type of pipe
+ if(M.GetInitDirections() & fakeA.GetInitDirections()) // matches at least one direction on either type of pipe
to_chat(user, "There is already a pipe at that location!")
- qdel(A)
- return 1
+ return TRUE
// no conflicts found
+ var/obj/machinery/atmospherics/A = new pipe_type(loc)
+ A.setDir(dir)
+ A.SetInitDirections()
+
if(pipename)
A.name = pipename
var/obj/machinery/atmospherics/components/trinary/T = A
if(istype(T))
T.flipped = flipped
- A.on_construction(pipe_type, color)
+ A.on_construction(pipe_type, color, piping_layer)
- playsound(src.loc, W.usesound, 50, 1)
+ playsound(src, W.usesound, 50, 1)
user.visible_message( \
"[user] fastens \the [src].", \
"You fasten \the [src].", \
@@ -271,16 +306,33 @@ GLOBAL_LIST_INIT(pipeID2State, list(
icon_state = "meter"
item_state = "buildpipe"
w_class = WEIGHT_CLASS_BULKY
+ var/piping_layer = PIPING_LAYER_DEFAULT
-/obj/item/pipe_meter/attackby(obj/item/W, mob/user, params)
+/obj/item/pipe_meter/attackby(obj/item/I, mob/user, params)
..()
- if (!istype(W, /obj/item/wrench))
+ if (!istype(I, /obj/item/wrench))
return ..()
- if(!locate(/obj/machinery/atmospherics/pipe, src.loc))
+ var/obj/machinery/atmospherics/pipe/pipe
+ for(var/obj/machinery/atmospherics/pipe/P in loc)
+ if(P.piping_layer == piping_layer)
+ pipe = P
+ break
+ if(!pipe)
to_chat(user, "You need to fasten it to a pipe!")
- return 1
- new/obj/machinery/meter( src.loc )
- playsound(src.loc, W.usesound, 50, 1)
+ return TRUE
+ new /obj/machinery/meter(loc, piping_layer)
+ playsound(src, I.usesound, 50, 1)
to_chat(user, "You fasten the meter to the pipe.")
qdel(src)
+
+/obj/item/pipe_meter/dropped()
+ . = ..()
+ if(loc)
+ setAttachLayer(piping_layer)
+
+/obj/item/pipe_meter/proc/setAttachLayer(new_layer = PIPING_LAYER_DEFAULT)
+ piping_layer = new_layer
+ pixel_x = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X
+ pixel_y = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y
+
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 26559c5ef9f..911a81c2fce 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -6,18 +6,21 @@
density = TRUE
anchored = TRUE
var/wait = 0
+ var/piping_layer = PIPING_LAYER_DEFAULT
/obj/machinery/pipedispenser/attack_paw(mob/user)
- return src.attack_hand(user)
+ return attack_hand(user)
/obj/machinery/pipedispenser/attack_hand(mob/user)
if(..())
return 1
var/dat = {"
+PIPING LAYER: --[piping_layer]++
Pipes:
Pipe
Bent Pipe
Manifold
+Layer Manifold
4-Way Manifold
Manual Valve
Digital Valve
@@ -53,18 +56,23 @@
usr << browse(null, "window=pipedispenser")
return 1
usr.set_machine(src)
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
if(href_list["make"])
if(wait < world.time)
var/p_type = text2path(href_list["make"])
var/p_dir = text2num(href_list["dir"])
- var/obj/item/pipe/P = new (src.loc, pipe_type=p_type, dir=p_dir)
+ var/obj/item/pipe/P = new (loc, p_type, p_dir)
+ P.setPipingLayer(piping_layer)
P.add_fingerprint(usr)
wait = world.time + 10
if(href_list["makemeter"])
if(wait < world.time )
- new /obj/item/pipe_meter(src.loc)
+ new /obj/item/pipe_meter(loc)
wait = world.time + 15
+ if(href_list["layer_up"])
+ piping_layer = Clamp(++piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
+ if(href_list["layer_down"])
+ piping_layer = Clamp(--piping_layer, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
return
/obj/machinery/pipedispenser/attackby(obj/item/W, mob/user, params)
@@ -75,7 +83,7 @@
return
else if (istype(W, /obj/item/wrench))
if (!anchored && !isinspace())
- playsound(src.loc, W.usesound, 50, 1)
+ playsound(src, W.usesound, 50, 1)
to_chat(user, "You begin to fasten \the [src] to the floor...")
if (do_after(user, 40*W.toolspeed, target = src))
add_fingerprint(user)
@@ -88,7 +96,7 @@
if (usr.machine==src)
usr << browse(null, "window=pipedispenser")
else if(anchored)
- playsound(src.loc, W.usesound, 50, 1)
+ playsound(src, W.usesound, 50, 1)
to_chat(user, "You begin to unfasten \the [src] from the floor...")
if (do_after(user, 20*W.toolspeed, target = src))
add_fingerprint(user)
@@ -160,11 +168,11 @@ Nah
if(..())
return 1
usr.set_machine(src)
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
if(href_list["dmake"])
if(wait < world.time)
var/p_type = text2num(href_list["dmake"])
- var/obj/structure/disposalconstruct/C = new (src.loc,p_type)
+ var/obj/structure/disposalconstruct/C = new (loc,p_type)
if(!C.can_place())
to_chat(usr, "There's not enough room to build that here!")
@@ -211,7 +219,7 @@ Nah
if(..())
return 1
usr.set_machine(src)
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
if(wait < world.time)
if(href_list["tube"])
var/tube_type = text2num(href_list["tube"])
diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm
index 15abe72a524..0151b0e9e15 100644
--- a/code/game/objects/items/RPD.dm
+++ b/code/game/objects/items/RPD.dm
@@ -30,10 +30,10 @@ RPD
var/selected=0
/datum/pipe_info/New(pid,direction,dt)
- src.id=pid
- src.icon_state=GLOB.pipeID2State["[pid]"]
- src.dir = direction
- src.dirtype=dt
+ id=pid
+ icon_state=GLOB.pipeID2State["[pid]"]
+ dir = direction
+ dirtype=dt
/datum/pipe_info/proc/Render(dispenser,label)
return "
[label]"
@@ -67,10 +67,10 @@ GLOBAL_LIST_INIT(disposalpipeID2State, list(
icon_state = "meterX"
/datum/pipe_info/disposal/New(var/pid,var/dt)
- src.id=pid
- src.icon_state=GLOB.disposalpipeID2State[pid+1]
- src.dir = SOUTH
- src.dirtype=dt
+ id=pid
+ icon_state=GLOB.disposalpipeID2State[pid+1]
+ dir = SOUTH
+ dirtype=dt
if(pidDISP_END_CHUTE)
icon_state = "con[icon_state]"
@@ -80,13 +80,14 @@ GLOBAL_LIST_INIT(disposalpipeID2State, list(
//find these defines in code\game\machinery\pipe\consruction.dm
GLOBAL_LIST_INIT(RPD_recipes, list(
"Pipes" = list(
- "Pipe" = new /datum/pipe_info(PIPE_SIMPLE, 1, PIPE_BENDABLE),
- //"Bent Pipe" = new /datum/pipe_info(PIPE_SIMPLE, 5, PIPE_BENT),
- "Manifold" = new /datum/pipe_info(PIPE_MANIFOLD, 1, PIPE_TRINARY),
- "Manual Valve" = new /datum/pipe_info(PIPE_MVALVE, 1, PIPE_BINARY),
- "Digital Valve" = new /datum/pipe_info(PIPE_DVALVE, 1, PIPE_BINARY),
- "4-Way Manifold" = new /datum/pipe_info(PIPE_4WAYMANIFOLD, 1, PIPE_QUAD),
- "Bluespace Pipe" = new /datum/pipe_info(PIPE_BLUESPACE, 1, PIPE_UNARY),
+ "Pipe" = new /datum/pipe_info(PIPE_SIMPLE, 1, PIPE_BENDABLE),
+ //"Bent Pipe" = new /datum/pipe_info(PIPE_SIMPLE, 5, PIPE_BENT),
+ "Manifold" = new /datum/pipe_info(PIPE_MANIFOLD, 1, PIPE_TRINARY),
+ "Manual Valve" = new /datum/pipe_info(PIPE_MVALVE, 1, PIPE_BINARY),
+ "Digital Valve" = new /datum/pipe_info(PIPE_DVALVE, 1, PIPE_BINARY),
+ "4-Way Manifold" = new /datum/pipe_info(PIPE_4WAYMANIFOLD, 1, PIPE_QUAD),
+ "Layer Manifold" = new /datum/pipe_info(PIPE_LAYER_MANIFOLD, 1, PIPE_BINARY),
+ "Bluespace Pipe" = new /datum/pipe_info(PIPE_BLUESPACE, 1, PIPE_UNARY),
),
"Devices"=list(
"Connector" = new /datum/pipe_info(PIPE_CONNECTOR, 1, PIPE_UNARY),
@@ -153,6 +154,7 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
)
var/paint_color="grey"
var/screen = CATEGORY_ATMOS //Starts on the atmos tab.
+ var/piping_layer = PIPING_LAYER_DEFAULT
/obj/item/pipe_dispenser/New()
. = ..()
@@ -201,6 +203,14 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
dat += "Atmospherics Disposals
"
else if(screen == CATEGORY_DISPOSALS)
dat += "Atmospherics Disposals
"
+ var/generated_layer_list = ""
+ var/layers_total = PIPING_LAYER_MAX - PIPING_LAYER_MIN + 1
+ for(var/iter = PIPING_LAYER_MIN, iter <= layers_total, iter++)
+ if(iter == piping_layer)
+ generated_layer_list += "[iter]"
+ else
+ generated_layer_list += "[iter]"
+ dat += "Atmospherics Piping Layer: [generated_layer_list]
"
dat += ""
var/icon/preview=null
@@ -459,7 +469,7 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
usr << browse(null, "window=pipedispenser")
return
usr.set_machine(src)
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
if(href_list["screen"])
screen = text2num(href_list["screen"])
show_menu(usr)
@@ -469,11 +479,18 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
p_flipped = text2num(href_list["flipped"])
show_menu(usr)
+ if(href_list["setlayer"])
+ if(!isnum(href_list["setlayer"]))
+ piping_layer = text2num(href_list["setlayer"])
+ else
+ piping_layer = href_list["setlayer"]
+ show_menu(usr)
+
if(href_list["eatpipes"])
p_class = EATING_MODE
p_conntype=-1
p_dir=1
- src.spark_system.start()
+ spark_system.start()
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
show_menu(usr)
@@ -481,13 +498,13 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
p_class = PAINT_MODE
p_conntype = -1
p_dir = 1
- src.spark_system.start()
+ spark_system.start()
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
show_menu(usr)
if(href_list["set_color"])
paint_color = href_list["set_color"]
- src.spark_system.start()
+ spark_system.start()
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
show_menu(usr)
@@ -496,7 +513,7 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
p_dir = text2num(href_list["dir"])
p_conntype = text2num(href_list["type"])
p_class = ATMOS_MODE
- src.spark_system.start()
+ spark_system.start()
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
show_menu(usr)
@@ -504,7 +521,7 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
p_class = METER_MODE
p_conntype = -1
p_dir = 1
- src.spark_system.start()
+ spark_system.start()
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
show_menu(usr)
@@ -513,7 +530,7 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
p_conntype = text2num(href_list["type"])
p_dir = 1
p_class = DISPOSALS_MODE
- src.spark_system.start()
+ spark_system.start()
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
show_menu(usr)
@@ -522,10 +539,18 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
if(!user.IsAdvancedToolUser() || istype(A, /turf/open/space/transit))
return ..()
+ var/atmos_piping_mode = p_class == ATMOS_MODE || p_class == METER_MODE
+ var/temp_piping_layer
+ if(atmos_piping_mode)
+ if(istype(A, /obj/machinery/atmospherics))
+ var/obj/machinery/atmospherics/AM = A
+ temp_piping_layer = AM.piping_layer
+ A = get_turf(user)
+
//make sure what we're clicking is valid for the current mode
var/is_paintable = (p_class == PAINT_MODE && istype(A, /obj/machinery/atmospherics/pipe))
var/is_consumable = (p_class == EATING_MODE && (istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct)))
- var/can_make_pipe = ((p_class == ATMOS_MODE || p_class == METER_MODE || p_class == DISPOSALS_MODE) && isturf(A))
+ var/can_make_pipe = ((atmos_piping_mode || p_class == DISPOSALS_MODE) && isturf(A))
if(!is_paintable && !is_consumable && !can_make_pipe)
return ..()
@@ -540,10 +565,8 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
if(PAINT_MODE) //Paint pipes
var/obj/machinery/atmospherics/pipe/P = A
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- P.add_atom_colour(paint_colors[paint_color], FIXED_COLOUR_PRIORITY)
- P.pipe_color = paint_colors[paint_color]
+ P.paint(paint_colors[paint_color])
user.visible_message("[user] paints \the [P] [paint_color].","You paint \the [P] [paint_color].")
- P.update_node_icon()
return
if(EATING_MODE) //Eating pipes
@@ -558,21 +581,29 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A))
activate()
- var/obj/item/pipe/P = new (A, pipe_type=queued_p_type, dir=queued_p_dir)
+ var/obj/item/pipe/P = new(A, queued_p_type, queued_p_dir)
P.flipped = queued_p_flipped
P.update()
P.add_fingerprint(usr)
+ if(!isnull(temp_piping_layer))
+ P.setPipingLayer(temp_piping_layer)
+ else
+ P.setPipingLayer(piping_layer)
if(METER_MODE) //Making pipe meters
to_chat(user, "You start building a meter...")
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 2, target = A))
activate()
- new /obj/item/pipe_meter(A)
+ var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(A)
+ if(!isnull(temp_piping_layer))
+ PM.setAttachLayer(temp_piping_layer)
+ else
+ PM.setAttachLayer(piping_layer)
if(DISPOSALS_MODE) //Making disposals pipes
if(isclosedturf(A))
- to_chat(user, "[src]'s error light flickers; there's something in the way!")
+ to_chat(user, "\the [src]'s error light flickers; there's something in the way!")
return
to_chat(user, "You start building a disposals pipe...")
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index 4d8ae7f5391..215afcccd01 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -201,7 +201,7 @@
slot_flags = SLOT_BELT | SLOT_BACK
force = 40
throwforce = 10
- w_class = WEIGHT_CLASS_NORMAL
+ w_class = WEIGHT_CLASS_HUGE
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
block_chance = 50
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 646548bbcab..ad5f69672bc 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -7,8 +7,12 @@
damage_amount = run_obj_armor(damage_amount, damage_type, damage_flag, attack_dir)
if(damage_amount >= 0.1)
. = damage_amount
- obj_integrity = max(obj_integrity - damage_amount, 0)
+ var/old_integ = obj_integrity
+ obj_integrity = max(old_integ - damage_amount, 0)
if(obj_integrity <= 0)
+ var/int_fail = integrity_failure
+ if(int_fail && old_integ > int_fail)
+ obj_break(damage_flag)
obj_destruction(damage_flag)
else if(integrity_failure)
if(obj_integrity <= integrity_failure)
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 8ab9a4e6821..57037de4463 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -174,7 +174,7 @@
return
/turf/closed/wall/proc/try_clean(obj/item/W, mob/user, turf/T)
- if((user.a_intent != INTENT_HELP) || !damage_decals.len || !istype(W, /obj/item/weldingtool))
+ if((user.a_intent != INTENT_HELP) || !LAZYLEN(damage_decals) || !istype(W, /obj/item/weldingtool))
return FALSE
var/obj/item/weldingtool/WT = W
if(WT.remove_fuel(0, user))
diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm
index 6a2df72a485..aa4099caee9 100644
--- a/code/modules/atmospherics/machinery/atmosmachinery.dm
+++ b/code/modules/atmospherics/machinery/atmosmachinery.dm
@@ -25,6 +25,8 @@ Pipelines + Other Objects -> Pipe network
var/can_unwrench = 0
var/initialize_directions = 0
var/pipe_color
+ var/piping_layer = PIPING_LAYER_DEFAULT
+ var/pipe_flags = NONE
var/global/list/iconsetids = list()
var/global/list/pipeimages = list()
@@ -41,7 +43,11 @@ Pipelines + Other Objects -> Pipe network
if(L.ventcrawler)
to_chat(L, "Alt-click to crawl through it.")
-/obj/machinery/atmospherics/New(loc, process = TRUE)
+/obj/machinery/atmospherics/New(loc, process = TRUE, setdir)
+ if(!isnull(setdir))
+ setDir(setdir)
+ if(pipe_flags & PIPING_CARDINAL_AUTONORMALIZE)
+ normalize_cardinal_directions()
nodes = new(device_type)
if (!armor)
armor = list(melee = 25, bullet = 10, laser = 10, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 100, acid = 70)
@@ -63,6 +69,13 @@ Pipelines + Other Objects -> Pipe network
return ..()
//return QDEL_HINT_FINDREFERENCE
+/obj/machinery/atmospherics/proc/destroy_network()
+ return
+
+/obj/machinery/atmospherics/proc/build_network()
+ // Called to build a network from this node
+ return
+
/obj/machinery/atmospherics/proc/nullifyNode(I)
if(NODE_I)
var/obj/machinery/atmospherics/N = NODE_I
@@ -82,6 +95,11 @@ Pipelines + Other Objects -> Pipe network
break
return node_connects
+/obj/machinery/atmospherics/proc/normalize_cardinal_directions()
+ if(dir==SOUTH)
+ setDir(NORTH)
+ else if(dir==WEST)
+ setDir(EAST)
//this is called just after the air controller sets up turfs
/obj/machinery/atmospherics/proc/atmosinit(var/list/node_connects)
@@ -93,12 +111,37 @@ Pipelines + Other Objects -> Pipe network
if(can_be_node(target, I))
NODE_I = target
break
-
update_icon()
+/obj/machinery/atmospherics/proc/setPipingLayer(new_layer)
+ if(pipe_flags & PIPING_DEFAULT_LAYER_ONLY)
+ new_layer = PIPING_LAYER_DEFAULT
+ piping_layer = new_layer
+ pixel_x = (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X
+ pixel_y = (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y
+ layer = initial(layer) + ((piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE)
+
/obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target)
- if(target.initialize_directions & get_dir(target,src))
+ return connection_check(target, piping_layer)
+
+//Find a connecting /obj/machinery/atmospherics in specified direction
+/obj/machinery/atmospherics/proc/findConnecting(direction, prompted_layer)
+ for(var/obj/machinery/atmospherics/target in get_step(src, direction))
+ if(target.initialize_directions & get_dir(target,src))
+ if(connection_check(target, prompted_layer))
+ return target
+
+/obj/machinery/atmospherics/proc/connection_check(obj/machinery/atmospherics/target, given_layer)
+ if(isConnectable(target, given_layer) && target.isConnectable(src, given_layer) && (target.initialize_directions & get_dir(target,src)))
return TRUE
+ return FALSE
+
+/obj/machinery/atmospherics/proc/isConnectable(obj/machinery/atmospherics/target, given_layer)
+ if(isnull(given_layer))
+ given_layer = piping_layer
+ if((target.piping_layer == given_layer) || (target.pipe_flags & PIPING_ALL_LAYER))
+ return TRUE
+ return FALSE
/obj/machinery/atmospherics/proc/pipeline_expansion()
return nodes
@@ -121,14 +164,10 @@ Pipelines + Other Objects -> Pipe network
/obj/machinery/atmospherics/proc/replacePipenet()
return
-/obj/machinery/atmospherics/proc/build_network()
- // Called to build a network from this node
- return
-
/obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference)
if(istype(reference, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/P = reference
- qdel(P.parent)
+ P.destroy_network()
var/I = nodes.Find(reference)
NODE_I = null
update_icon()
@@ -137,12 +176,17 @@ Pipelines + Other Objects -> Pipe network
return
/obj/machinery/atmospherics/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/pipe)) //lets you autodrop
+ var/obj/item/pipe/pipe = W
+ if(user.dropItemToGround(pipe))
+ pipe.setPipingLayer(piping_layer) //align it with us
+ return TRUE
if(istype(W, /obj/item/wrench))
if(can_unwrench(user))
var/turf/T = get_turf(src)
if (level==1 && isturf(T) && T.intact)
to_chat(user, "You must remove the plating first!")
- return 1
+ return TRUE
var/datum/gas_mixture/int_air = return_air()
var/datum/gas_mixture/env_air = loc.return_air()
add_fingerprint(user)
@@ -150,7 +194,7 @@ Pipelines + Other Objects -> Pipe network
var/unsafe_wrenching = FALSE
var/internal_pressure = int_air.return_pressure()-env_air.return_pressure()
- playsound(src.loc, W.usesound, 50, 1)
+ playsound(src, W.usesound, 50, 1)
to_chat(user, "You begin to unfasten \the [src]...")
if (internal_pressure > 2*ONE_ATMOSPHERE)
to_chat(user, "As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?")
@@ -195,7 +239,8 @@ Pipelines + Other Objects -> Pipe network
/obj/machinery/atmospherics/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(can_unwrench)
- var/obj/item/pipe/stored = new(loc, make_from=src)
+ var/obj/item/pipe/stored = new(loc, piping_layer, dir, src)
+ stored.setPipingLayer(piping_layer)
if(!disassembled)
stored.obj_integrity = stored.max_integrity * 0.5
transfer_fingerprints_to(stored)
@@ -226,10 +271,11 @@ Pipelines + Other Objects -> Pipe network
if(unconnected & direction)
underlays += getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', "pipe_exposed", direction)
-/obj/machinery/atmospherics/on_construction(pipe_type, obj_color)
+/obj/machinery/atmospherics/on_construction(pipe_type, obj_color, set_layer)
if(can_unwrench)
add_atom_colour(obj_color, FIXED_COLOUR_PRIORITY)
pipe_color = obj_color
+ setPipingLayer(set_layer)
var/turf/T = get_turf(src)
level = T.intact ? 2 : 1
atmosinit()
@@ -239,18 +285,16 @@ Pipelines + Other Objects -> Pipe network
A.addMember(src)
build_network()
+/obj/machinery/atmospherics/Entered(atom/movable/AM)
+ if(istype(AM, /mob/living))
+ var/mob/living/L = AM
+ L.ventcrawl_layer = piping_layer
+ return ..()
+
/obj/machinery/atmospherics/singularity_pull(S, current_size)
- ..()
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
-
-
-//Find a connecting /obj/machinery/atmospherics in specified direction
-/obj/machinery/atmospherics/proc/findConnecting(direction)
- for(var/obj/machinery/atmospherics/target in get_step(src, direction))
- if(target.initialize_directions & get_dir(target,src))
- return target
-
+ return ..()
#define VENT_SOUND_DELAY 30
@@ -261,7 +305,7 @@ Pipelines + Other Objects -> Pipe network
if(user in buckled_mobs)// fixes buckle ventcrawl edgecase fuck bug
return
- var/obj/machinery/atmospherics/target_move = findConnecting(direction)
+ var/obj/machinery/atmospherics/target_move = findConnecting(direction, user.ventcrawl_layer)
if(target_move)
if(target_move.can_crawl_through())
if(is_type_in_typecache(target_move, GLOB.ventcrawl_machinery))
@@ -271,14 +315,14 @@ Pipelines + Other Objects -> Pipe network
var/list/pipenetdiff = returnPipenets() ^ target_move.returnPipenets()
if(pipenetdiff.len)
user.update_pipe_vision(target_move)
- user.loc = target_move
+ user.forceMove(target_move)
user.client.eye = target_move //Byond only updates the eye every tick, This smooths out the movement
if(world.time - user.last_played_vent > VENT_SOUND_DELAY)
user.last_played_vent = world.time
playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
else
if((direction & initialize_directions) || is_type_in_typecache(src, GLOB.ventcrawl_machinery) && can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
- user.forceMove(src.loc)
+ user.forceMove(loc)
user.visible_message("You hear something squeezing through the ducts...","You climb out the ventilation system.")
user.canmove = 0
spawn(1)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
index 45c48726d32..36462a3eb69 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
@@ -11,6 +11,7 @@
var/status = 0
var/last_pressure_delta = 0
+ pipe_flags = PIPING_ONE_PER_TURF
anchored = TRUE
density = TRUE
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 14495cd237f..8ba105fdb12 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm
@@ -5,6 +5,7 @@
use_power = IDLE_POWER_USE
device_type = TRINARY
layer = GAS_FILTER_LAYER
+ pipe_flags = PIPING_ONE_PER_TURF
var/flipped = FALSE
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index 9061cce8d9d..9b034b92f84 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -11,6 +11,7 @@
layer = ABOVE_WINDOW_LAYER
state_open = FALSE
circuit = /obj/item/circuitboard/machine/cryo_tube
+ pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
var/on = FALSE
var/autoeject = FALSE
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm
index e17a2f796cc..ee488890416 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm
@@ -8,6 +8,7 @@
use_power = NO_POWER_USE
level = 0
layer = GAS_FILTER_LAYER
+ pipe_flags = PIPING_ONE_PER_TURF
/obj/machinery/atmospherics/components/unary/portables_connector/New()
..()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
index ca60c9bf852..04f1068a000 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
@@ -9,6 +9,7 @@
density = TRUE
var/gas_type = 0
layer = ABOVE_WINDOW_LAYER
+ pipe_flags = PIPING_ONE_PER_TURF
/obj/machinery/atmospherics/components/unary/tank/New()
..()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
index dc482eda02e..d7bfe1ecb86 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
@@ -11,6 +11,7 @@
armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 80, acid = 30)
layer = OBJ_LAYER
circuit = /obj/item/circuitboard/machine/thermomachine
+ pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
var/on = FALSE
var/min_temperature = 0
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm
index a6ac9760e80..f629020d747 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm
@@ -3,6 +3,7 @@
dir = SOUTH
initialize_directions = SOUTH
device_type = UNARY
+ pipe_flags = PIPING_ONE_PER_TURF
/obj/machinery/atmospherics/components/unary/SetInitDirections()
initialize_directions = dir
diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm
index 124caa23bee..72946381626 100644
--- a/code/modules/atmospherics/machinery/other/meter.dm
+++ b/code/modules/atmospherics/machinery/other/meter.dm
@@ -13,19 +13,33 @@
active_power_usage = 4
max_integrity = 150
armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 40, acid = 0)
-
-
-/obj/machinery/meter/Initialize(mapload)
- . = ..()
- SSair.atmos_machinery += src
- if (!target)
- target = locate(/obj/machinery/atmospherics/pipe) in loc
+ var/target_layer = PIPING_LAYER_DEFAULT
/obj/machinery/meter/Destroy()
SSair.atmos_machinery -= src
- src.target = null
+ target = null
return ..()
+/obj/machinery/meter/Initialize(mapload, new_piping_layer)
+ if(!isnull(new_piping_layer))
+ target_layer = new_piping_layer
+ SSair.atmos_machinery += src
+ if(mapload && !target)
+ reattach_to_layer()
+ return ..()
+
+/obj/machinery/meter/proc/reattach_to_layer()
+ for(var/obj/machinery/atmospherics/pipe/pipe in loc)
+ if(pipe.piping_layer == target_layer)
+ target = pipe
+ setAttachLayer(pipe.piping_layer)
+ break
+
+/obj/machinery/meter/proc/setAttachLayer(var/new_layer)
+ target_layer = new_layer
+ pixel_x = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X
+ pixel_y = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y
+
/obj/machinery/meter/process_atmos()
if(!target)
icon_state = "meterX"
@@ -75,7 +89,7 @@
radio_connection.post_signal(src, signal)
/obj/machinery/meter/proc/status()
- if (src.target)
+ if (target)
var/datum/gas_mixture/environment = target.return_air()
if(environment)
. = "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)] K ([round(environment.temperature-T0C,0.01)]°C)."
@@ -91,23 +105,23 @@
/obj/machinery/meter/attackby(obj/item/W, mob/user, params)
if (istype(W, /obj/item/wrench))
- playsound(src.loc, W.usesound, 50, 1)
+ playsound(src, W.usesound, 50, 1)
to_chat(user, "You begin to unfasten \the [src]...")
if (do_after(user, 40*W.toolspeed, target = src))
user.visible_message( \
"[user] unfastens \the [src].", \
"You unfasten \the [src].", \
"You hear ratchet.")
- new /obj/item/pipe_meter(src.loc)
+ new /obj/item/pipe_meter(loc)
qdel(src)
else
return ..()
/obj/machinery/meter/attack_ai(mob/user)
- return src.attack_hand(user)
+ return attack_hand(user)
/obj/machinery/meter/attack_paw(mob/user)
- return src.attack_hand(user)
+ return attack_hand(user)
/obj/machinery/meter/attack_hand(mob/user)
@@ -129,4 +143,4 @@
/obj/machinery/meter/turf/Initialize()
. = ..()
- src.target = loc
+ target = loc
diff --git a/code/modules/atmospherics/machinery/pipes/bluespace_pipe.dm b/code/modules/atmospherics/machinery/pipes/bluespace_pipe.dm
index 476235d3d95..51e89950c18 100644
--- a/code/modules/atmospherics/machinery/pipes/bluespace_pipe.dm
+++ b/code/modules/atmospherics/machinery/pipes/bluespace_pipe.dm
@@ -29,7 +29,7 @@ GLOBAL_LIST_EMPTY(bluespace_pipes)
/obj/machinery/atmospherics/pipe/bluespace/pipeline_expansion()
return ..() + GLOB.bluespace_pipes - src
-/obj/machinery/atmospherics/components/pipe/bluespace/hide()
+/obj/machinery/atmospherics/pipe/bluespace/hide()
update_icon()
/obj/machinery/atmospherics/pipe/bluespace/update_icon(showpipe)
diff --git a/code/modules/atmospherics/machinery/pipes/layermanifold.dm b/code/modules/atmospherics/machinery/pipes/layermanifold.dm
new file mode 100644
index 00000000000..cc9ef366787
--- /dev/null
+++ b/code/modules/atmospherics/machinery/pipes/layermanifold.dm
@@ -0,0 +1,135 @@
+/obj/machinery/atmospherics/pipe/layer_manifold
+ name = "pipe-layer manifold"
+ icon = 'icons/obj/atmospherics/pipes/manifold.dmi'
+ icon_state = "manifoldlayer"
+ desc = "A special pipe to bridge pipe layers with."
+ dir = SOUTH
+ initialize_directions = NORTH|SOUTH
+ pipe_flags = PIPING_ALL_LAYER | PIPING_DEFAULT_LAYER_ONLY | PIPING_CARDINAL_AUTONORMALIZE
+ piping_layer = PIPING_LAYER_DEFAULT
+ device_type = 0
+ volume = 260
+ var/list/front_nodes
+ var/list/back_nodes
+
+/obj/machinery/atmospherics/pipe/layer_manifold/Initialize()
+ front_nodes = list()
+ back_nodes = list()
+ return ..()
+
+/obj/machinery/atmospherics/pipe/layer_manifold/Destroy()
+ nullifyAllNodes()
+ return ..()
+
+/obj/machinery/atmospherics/pipe/layer_manifold/proc/nullifyAllNodes()
+ var/list/obj/machinery/atmospherics/needs_nullifying = get_all_connected_nodes()
+ front_nodes = null
+ back_nodes = null
+ nodes = list()
+ for(var/obj/machinery/atmospherics/A in needs_nullifying)
+ A.disconnect(src)
+ A.build_network()
+
+/obj/machinery/atmospherics/pipe/layer_manifold/proc/get_all_connected_nodes()
+ var/list/obj/machinery/atmospherics/all_connected = list()
+ for(var/obj/machinery/atmospherics/I in front_nodes)
+ all_connected[I] = I
+ for(var/obj/machinery/atmospherics/I in back_nodes)
+ all_connected[I] = I
+ for(var/obj/machinery/atmospherics/I in nodes)
+ all_connected[I] = I
+ var/list/obj/machinery/atmospherics/returnlist = list()
+ for(var/obj/machinery/atmospherics/A in all_connected)
+ returnlist += all_connected[A]
+ return returnlist
+
+/obj/machinery/atmospherics/pipe/layer_manifold/update_icon() //HEAVILY WIP FOR UPDATE ICONS!!
+ layer = (initial(layer) + (PIPING_LAYER_MAX * PIPING_LAYER_LCHANGE)) //This is above everything else.
+ var/invis = invisibility ? "-f" : ""
+ icon_state = "[initial(icon_state)][invis]"
+ cut_overlays()
+ for(var/obj/machinery/atmospherics/A in front_nodes)
+ add_attached_image(A)
+ for(var/obj/machinery/atmospherics/A in back_nodes)
+ add_attached_image(A)
+
+/obj/machinery/atmospherics/pipe/layer_manifold/proc/add_attached_image(obj/machinery/atmospherics/A)
+ var/invis = A.invisibility ? "-f" : ""
+ if(istype(A, /obj/machinery/atmospherics/pipe/layer_manifold))
+ for(var/i = PIPING_LAYER_MIN, i <= PIPING_LAYER_MAX, i++)
+ var/image/I = getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full_layer_long[invis]", get_dir(src, A), A.pipe_color)
+ I.pixel_x = (i - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X
+ I.pixel_y = (i - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y
+ I.layer = layer - 0.01
+ add_overlay(I)
+ else
+ var/image/I = getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full_layer_long[invis]", get_dir(src, A), A.pipe_color)
+ I.pixel_x = A.pixel_x
+ I.pixel_y = A.pixel_y
+ I.layer = layer - 0.01
+ add_overlay(I)
+
+/obj/machinery/atmospherics/pipe/layer_manifold/SetInitDirections()
+ switch(dir)
+ if(NORTH || SOUTH)
+ initialize_directions = NORTH|SOUTH
+ if(EAST || WEST)
+ initialize_directions = EAST|WEST
+
+/obj/machinery/atmospherics/pipe/layer_manifold/isConnectable(obj/machinery/atmospherics/target, given_layer)
+ if(!given_layer)
+ return TRUE
+ . = ..()
+
+/obj/machinery/atmospherics/pipe/layer_manifold/proc/findAllConnections()
+ front_nodes = list()
+ back_nodes = list()
+ var/list/new_nodes = list()
+ for(var/iter in PIPING_LAYER_MIN to PIPING_LAYER_MAX)
+ var/obj/machinery/atmospherics/foundfront = findConnecting(dir, iter)
+ var/obj/machinery/atmospherics/foundback = findConnecting(turn(dir, 180), iter)
+ front_nodes += foundfront
+ back_nodes += foundback
+ if(foundfront && !QDELETED(foundfront))
+ new_nodes += foundfront
+ if(foundback && !QDELETED(foundback))
+ new_nodes += foundback
+ update_icon()
+ return new_nodes
+
+/obj/machinery/atmospherics/pipe/layer_manifold/atmosinit()
+ normalize_cardinal_directions()
+ findAllConnections()
+ var/turf/T = loc // hide if turf is not intact
+ hide(T.intact)
+
+/obj/machinery/atmospherics/pipe/layer_manifold/setPipingLayer()
+ piping_layer = PIPING_LAYER_DEFAULT
+
+/obj/machinery/atmospherics/pipe/layer_manifold/pipeline_expansion()
+ return get_all_connected_nodes()
+
+/obj/machinery/atmospherics/pipe/layer_manifold/disconnect(obj/machinery/atmospherics/reference)
+ if(istype(reference, /obj/machinery/atmospherics/pipe))
+ var/obj/machinery/atmospherics/pipe/P = reference
+ P.destroy_network()
+ while(reference in get_all_connected_nodes())
+ if(reference in nodes)
+ var/I = nodes.Find(reference)
+ NODE_I = null
+ if(reference in front_nodes)
+ var/I = front_nodes.Find(reference)
+ front_nodes[I] = null
+ if(reference in back_nodes)
+ var/I = back_nodes.Find(reference)
+ back_nodes[I] = null
+ update_icon()
+
+/obj/machinery/atmospherics/pipe/layer_manifold/relaymove(mob/living/user, dir)
+ if(initialize_directions & dir)
+ return ..()
+ if((NORTH|EAST) & dir)
+ user.ventcrawl_layer = Clamp(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
+ if((SOUTH|WEST) & dir)
+ user.ventcrawl_layer = Clamp(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX)
+ to_chat(user, "You align yourself with the [user.ventcrawl_layer]\th output.")
diff --git a/code/modules/atmospherics/machinery/pipes/manifold.dm b/code/modules/atmospherics/machinery/pipes/manifold.dm
index b5788fa1cc2..5be4b63d885 100644
--- a/code/modules/atmospherics/machinery/pipes/manifold.dm
+++ b/code/modules/atmospherics/machinery/pipes/manifold.dm
@@ -125,7 +125,7 @@
/obj/machinery/atmospherics/pipe/manifold/orange/hidden
level = PIPE_HIDDEN_LEVEL
-
+
/obj/machinery/atmospherics/pipe/manifold/purple
pipe_color=rgb(128,0,182)
color=rgb(128,0,182)
diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm
index 49383a74cbd..cc01e6c4bdb 100644
--- a/code/modules/atmospherics/machinery/pipes/pipes.dm
+++ b/code/modules/atmospherics/machinery/pipes/pipes.dm
@@ -24,6 +24,14 @@
if(oldN)
oldN.build_network()
+/obj/machinery/atmospherics/pipe/destroy_network()
+ QDEL_NULL(parent)
+
+/obj/machinery/atmospherics/pipe/build_network()
+ if(QDELETED(parent))
+ parent = new
+ parent.build_pipeline(src)
+
/obj/machinery/atmospherics/pipe/update_icon() //overridden by manifolds
if(NODE1&&NODE2)
icon_state = "intact[invisibility ? "-f" : "" ]"
@@ -51,14 +59,13 @@
/obj/machinery/atmospherics/pipe/return_air()
return parent.air
-/obj/machinery/atmospherics/pipe/build_network()
- if(!parent)
- parent = new /datum/pipeline()
- parent.build_pipeline(src)
-
/obj/machinery/atmospherics/pipe/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/device/analyzer))
atmosanalyzer_scan(parent.air, user)
+ if(istype(W, /obj/item/pipe_meter))
+ var/obj/item/pipe_meter/meter = W
+ user.dropItemToGround(meter)
+ meter.setAttachLayer(piping_layer)
else
return ..()
@@ -81,9 +88,7 @@
qdel(meter)
. = ..()
- if(parent && !QDELETED(parent))
- qdel(parent)
- parent = null
+ QDEL_NULL(parent)
/obj/machinery/atmospherics/pipe/proc/update_node_icon()
for(DEVICE_TYPE_LOOP)
diff --git a/code/modules/atmospherics/machinery/pipes/simple.dm b/code/modules/atmospherics/machinery/pipes/simple.dm
index 5ac9ac31e6b..e8d82c611c0 100644
--- a/code/modules/atmospherics/machinery/pipes/simple.dm
+++ b/code/modules/atmospherics/machinery/pipes/simple.dm
@@ -12,10 +12,12 @@ The regular pipe you see everywhere, including bent ones.
dir = SOUTH
initialize_directions = SOUTH|NORTH
+ pipe_flags = PIPING_CARDINAL_AUTONORMALIZE
device_type = BINARY
/obj/machinery/atmospherics/pipe/simple/SetInitDirections()
+ normalize_cardinal_directions()
if(dir in GLOB.diagonals)
initialize_directions = dir
switch(dir)
@@ -24,20 +26,6 @@ The regular pipe you see everywhere, including bent ones.
if(EAST,WEST)
initialize_directions = EAST|WEST
-/obj/machinery/atmospherics/pipe/simple/atmosinit()
- normalize_dir()
- ..()
-
-/obj/machinery/atmospherics/pipe/simple/proc/normalize_dir()
- if(dir==SOUTH)
- setDir(NORTH)
- else if(dir==WEST)
- setDir(EAST)
-
-/obj/machinery/atmospherics/pipe/simple/update_icon()
- normalize_dir()
- ..()
-
//Colored pipes, use these for mapping
/obj/machinery/atmospherics/pipe/simple/general
diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
index 96a5b8e4894..cad15849917 100644
--- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
+++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
@@ -45,11 +45,11 @@
/obj/machinery/portable_atmospherics/proc/connect(obj/machinery/atmospherics/components/unary/portables_connector/new_port)
//Make sure not already connected to something else
if(connected_port || !new_port || new_port.connected_device)
- return 0
+ return FALSE
//Make sure are close enough for a valid connection
if(new_port.loc != get_turf(src))
- return 0
+ return TRUE
//Perform the connection
connected_port = new_port
@@ -58,7 +58,9 @@
connected_port_parent.reconcile_air()
anchored = TRUE //Prevent movement
- return 1
+ pixel_x = new_port.pixel_x
+ pixel_y = new_port.pixel_y
+ return TRUE
/obj/machinery/portable_atmospherics/Move()
. = ..()
@@ -67,11 +69,11 @@
/obj/machinery/portable_atmospherics/proc/disconnect()
if(!connected_port)
- return 0
+ return FALSE
anchored = FALSE
connected_port.connected_device = null
connected_port = null
- return 1
+ return TRUE
/obj/machinery/portable_atmospherics/portableConnectorReturnAir()
return air_contents
diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm
index c833309e2d7..3f2bceaa045 100644
--- a/code/modules/atmospherics/machinery/portable/pump.dm
+++ b/code/modules/atmospherics/machinery/portable/pump.dm
@@ -1,6 +1,6 @@
#define PUMP_OUT "out"
#define PUMP_IN "in"
-#define PUMP_MAX_PRESSURE (ONE_ATMOSPHERE * 30)
+#define PUMP_MAX_PRESSURE (ONE_ATMOSPHERE * 25)
#define PUMP_MIN_PRESSURE (ONE_ATMOSPHERE / 10)
#define PUMP_DEFAULT_PRESSURE (ONE_ATMOSPHERE)
diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm
index b92c3b38747..977bd60da1e 100644
--- a/code/modules/food_and_drinks/food/snacks_pie.dm
+++ b/code/modules/food_and_drinks/food/snacks_pie.dm
@@ -50,7 +50,9 @@
H.adjust_blurriness(1)
H.visible_message("[H] is creamed by [src]!", "You've been creamed by [src]!")
playsound(H, "desceration", 50, TRUE)
- H.add_overlay(creamoverlay)
+ if (!H.creamed) // one layer at a time
+ H.add_overlay(creamoverlay)
+ H.creamed = TRUE
qdel(src)
@@ -237,4 +239,4 @@
icon_state = "frostypie"
bonus_reagents = list("nutriment" = 4, "vitamin" = 6)
tastes = list("mint" = 1, "pie" = 1)
- foodtype = GRAIN | FRUIT | SUGAR
+ foodtype = GRAIN | FRUIT | SUGAR
\ No newline at end of file
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index a0b26718d55..5dd9627c2d1 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -913,6 +913,7 @@
///////////////////////////////////////////////////////////////////////////////
/obj/machinery/hydroponics/soil //Not actually hydroponics at all! Honk!
name = "soil"
+ desc = "A patch of dirt."
icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "soil"
circuit = null
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 18c431b319c..d76578b4bbd 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -691,10 +691,10 @@
/mob/living/carbon/human/wash_cream()
- //clean both to prevent a rare bug
- cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_lizard"))
- cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_human"))
-
+ if(creamed) //clean both to prevent a rare bug
+ cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_lizard"))
+ cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_human"))
+ creamed = FALSE
//Turns a mob black, flashes a skeleton overlay
//Just like a cartoon!
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 41c5b474e36..bc6890ef3be 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -46,3 +46,5 @@
can_buckle = TRUE
buckle_lying = FALSE
can_ride_typecache = list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot)
+
+ var/creamed = FALSE //to use with creampie overlays
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 16969bfb8d7..0e8b9f4de4c 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -225,10 +225,11 @@ There are several things that need to be remembered:
overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/eyes.dmi')
var/mutable_appearance/glasses_overlay = overlays_standing[GLASSES_LAYER]
- if(OFFSET_GLASSES in dna.species.offset_features)
- glasses_overlay.pixel_x += dna.species.offset_features[OFFSET_GLASSES][1]
- glasses_overlay.pixel_y += dna.species.offset_features[OFFSET_GLASSES][2]
- overlays_standing[GLASSES_LAYER] = glasses_overlay
+ if(glasses_overlay)
+ if(OFFSET_GLASSES in dna.species.offset_features)
+ glasses_overlay.pixel_x += dna.species.offset_features[OFFSET_GLASSES][1]
+ glasses_overlay.pixel_y += dna.species.offset_features[OFFSET_GLASSES][2]
+ overlays_standing[GLASSES_LAYER] = glasses_overlay
apply_overlay(GLASSES_LAYER)
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 2b9cf6b4374..3507063bbe9 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -143,3 +143,5 @@
var/list/can_ride_typecache = list()
var/list/mousemove_intercept_objects
+
+ var/ventcrawl_layer = PIPING_LAYER_DEFAULT
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index cb086b71156..9447b32daaa 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -6,8 +6,13 @@
/mob/living/carbon/isloyal()
for(var/obj/item/implant/mindshield/L in implants)
- return 1
+ return TRUE
+/mob/proc/lowest_buckled_mob()
+ . = src
+ if(buckled && ismob(buckled))
+ var/mob/Buckled = buckled
+ . = Buckled.lowest_buckled_mob()
/proc/check_zone(zone)
if(!zone)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 862547abe9a..8c6003ebf85 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -210,7 +210,7 @@
firing_burst = FALSE
return FALSE
if(!issilicon(user))
- if( iteration > 1 && !(user.is_holding(src))) //for burst firing
+ if(iteration > 1 && !(user.is_holding(src))) //for burst firing
firing_burst = FALSE
return FALSE
if(chambered && chambered.BB)
@@ -228,6 +228,8 @@
shoot_live_shot(user, 1, target, message)
else
shoot_live_shot(user, 0, target, message)
+ if (iteration >= burst_size)
+ firing_burst = FALSE
else
shoot_with_empty_chamber(user)
firing_burst = FALSE
@@ -252,8 +254,7 @@
if(burst_size > 1)
firing_burst = TRUE
for(var/i = 1 to burst_size)
- addtimer(CALLBACK(src, .proc/process_burst, user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), min(fire_delay * (i - 1), 0))
- firing_burst = FALSE
+ addtimer(CALLBACK(src, .proc/process_burst, user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), fire_delay * (i - 1))
else
if(chambered)
sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index f7357207da5..aaa3a3e6372 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -187,41 +187,42 @@
if(forcedodge)
loc = target_turf
return FALSE
- var/permutation = select_target(A,target_turf) // searches for return value, could be deleted after run so check A isn't null
+
+ var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null
if(permutation == -1 || forcedodge)// the bullet passes through a dense object!
loc = target_turf
if(A)
permutated.Add(A)
return FALSE
+ else
+ var/atom/alt = select_target(A)
+ if(alt)
+ if(!prehit(alt))
+ return FALSE
+ alt.bullet_act(src, def_zone)
qdel(src)
return TRUE
-/obj/item/projectile/proc/select_target(atom/A,target_turf)
- if((A && A.density && !(A.flags_1 & ON_BORDER_1)) && (istype(A,/obj/machinery) || isturf(A))) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile.
- var/list/mobs_list = list()
- var/list/machine_list = list()
- for(var/mob/living/L in target_turf)
- mobs_list += L
- for(var/obj/machinery/m in target_turf)
- if(m.density)
- machine_list += m
- var/permutationbackup
- if(isturf(A))
- permutationbackup = A.bullet_act(src, def_zone) // Just in case the turf can deflect bullets
- if(mobs_list.len || machine_list.len)
- var/atom/movable/selected_target
- if(mobs_list.Find(original) || machine_list.Find(original))
- selected_target = original
- else if(mobs_list.len)
- selected_target = pick(mobs_list)
- else
- selected_target = pick(machine_list)
- if(!prehit(selected_target))
- return FALSE
- return selected_target.bullet_act(src, def_zone)
- return permutationbackup
- else
- return A.bullet_act(src, def_zone)
+
+/obj/item/projectile/proc/select_target(atom/A) //Selects another target from a wall if we hit a wall.
+ if(!A || !A.density || (A.flags_1 & ON_BORDER_1) || ismob(A)) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs or machines/structures on that tile.
+ return
+ if(A == original || original in A)
+ return original
+ var/list/mob/possible_mobs = typecache_filter_list(A, GLOB.typecache_mob)
+ var/list/mob/mobs = list()
+ for(var/i in possible_mobs)
+ var/mob/M = i
+ if(M.lying)
+ continue
+ mobs += M
+ var/mob/M = safepick(mobs)
+ if(M)
+ return M.lowest_buckled_mob()
+ var/obj/O = safepick(typecache_filter_list(A, GLOB.typecache_machine_or_structure))
+ if(O)
+ return O
+ return A
/obj/item/projectile/proc/check_ricochet()
if(prob(ricochet_chance))
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index a184434039a..e88b8c454b2 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -814,7 +814,8 @@
M.jitteriness = 0
if(M.has_dna())
M.dna.remove_all_mutations()
- ..()
+ if(!QDELETED(M)) //We were a monkey, now a human
+ ..()
/datum/reagent/medicine/antihol
name = "Antihol"
diff --git a/code/modules/ruins/spaceruin_code/caravanambush.dm b/code/modules/ruins/spaceruin_code/caravanambush.dm
new file mode 100644
index 00000000000..8877a693cda
--- /dev/null
+++ b/code/modules/ruins/spaceruin_code/caravanambush.dm
@@ -0,0 +1,27 @@
+//caravan ambush
+
+/obj/item/wrench/caravan
+ color = "#ff0000"
+ desc = "A prototype of a new wrench design, allegedly the red color scheme makes it go faster."
+ name = "experimental wrench"
+ toolspeed = 0.3
+
+/obj/item/screwdriver/caravan
+ color = "#ff0000"
+ desc = "A prototype of a new screwdriver design, allegedly the red color scheme makes it go faster."
+ name = "experimental screwdriver"
+ toolspeed = 0.3
+ random_color = FALSE
+
+/obj/item/wirecutters/caravan
+ color = "#ff0000"
+ desc = "A prototype of a new wirecutter design, allegedly the red color scheme makes it go faster."
+ name = "experimental wirecutters"
+ toolspeed = 0.3
+ random_color = FALSE
+
+/obj/item/crowbar/red/caravan
+ color = "#ff0000"
+ desc = "A prototype of a new crowbar design, allegedly the red color scheme makes it go faster."
+ name = "experimental crowbar"
+ toolspeed = 0.3
diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm
index 61bfe3a2b52..d376fda48ad 100644
--- a/code/modules/shuttle/navigation_computer.dm
+++ b/code/modules/shuttle/navigation_computer.dm
@@ -80,7 +80,7 @@
return FALSE
var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj
if(!my_port)
- my_port = new /obj/docking_port/stationary
+ my_port = new /obj/docking_port/stationary()
my_port.name = shuttlePortName
my_port.id = shuttlePortId
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm
index 6f3c7c095f2..530e9a3ba4a 100644
--- a/code/modules/shuttle/on_move.dm
+++ b/code/modules/shuttle/on_move.dm
@@ -76,7 +76,7 @@ All ShuttleMove procs go here
return move_mode
// Called on atoms to move the atom to the new location
-/atom/movable/proc/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock)
+/atom/movable/proc/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
if(newT == oldT) // In case of in place shuttle rotation shenanigans.
return
@@ -268,7 +268,7 @@ All ShuttleMove procs go here
/************************************Mob move procs************************************/
-/mob/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock)
+/mob/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
if(!move_on_shuttle)
return
. = ..()
@@ -293,7 +293,7 @@ All ShuttleMove procs go here
if(movement_force["KNOCKDOWN"])
Knockdown(movement_force["KNOCKDOWN"])
-/mob/living/simple_animal/hostile/megafauna/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock)
+/mob/living/simple_animal/hostile/megafauna/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
. = ..()
message_admins("Megafauna [src] [ADMIN_FLW(src)] moved via shuttle from [ADMIN_COORDJMP(oldT)] to [ADMIN_COORDJMP(loc)]")
@@ -324,21 +324,20 @@ All ShuttleMove procs go here
/************************************Misc move procs************************************/
-/atom/movable/lighting_object/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock)
+/atom/movable/lighting_object/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
return FALSE
-/atom/movable/light/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock)
+/atom/movable/light/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
return FALSE
-/obj/docking_port/stationary/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock)
- if(old_dock == src) //Don't move the dock we're leaving
+/obj/docking_port/stationary/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
+ if(!moving_dock.can_move_docking_ports || (old_dock == src))
return FALSE
-
. = ..()
-/obj/docking_port/stationary/public_mining_dock/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock)
+/obj/docking_port/stationary/public_mining_dock/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
id = "mining_public" //It will not move with the base, but will become enabled as a docking point.
-/obj/effect/abstract/proximity_checker/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock)
+/obj/effect/abstract/proximity_checker/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock)
//timer so it only happens once
addtimer(CALLBACK(monitor, /datum/proximity_monitor/proc/SetRange, monitor.current_range, TRUE), 0, TIMER_UNIQUE)
\ No newline at end of file
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index d5ad26f57c4..3058e4bbb51 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -284,6 +284,7 @@
var/engine_coeff = 1 //current engine coeff
var/current_engines = 0 //current engine power
var/initial_engines = 0 //initial engine power
+ var/can_move_docking_ports = FALSE //if this shuttle can move docking ports other than the one it is docked at
/obj/docking_port/mobile/proc/register()
SSshuttle.mobile += src
@@ -600,7 +601,7 @@
var/atom/movable/moving_atom = thing
if(moving_atom.loc != oldT) //fix for multi-tile objects
continue
- moving_atom.onShuttleMove(newT, oldT, rotation, movement_force, movement_direction, old_dock)//atoms
+ moving_atom.onShuttleMove(newT, oldT, rotation, movement_force, movement_direction, old_dock, src)//atoms
moved_atoms += moving_atom
if(move_mode & MOVE_TURF)
oldT.onShuttleMove(newT, underlying_turf_type, underlying_baseturf_type, rotation, movement_force, movement_direction)//turfs
diff --git a/html/changelog.html b/html/changelog.html
index 3153ad068f3..0aebb90de35 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,41 @@
-->
+
17 October 2017
+
DaxDupont updated:
+
+ - Fancy boxes(ie: donut boxes) now show the proper content amount in the sprite and no longer go invisible when empty.
+
+
Mercenaryblue updated:
+
+ - when decapitated, banana-flavored cream no longer hovers where your head used to be.
+
+
More Robust Than You updated:
+
+ - EI NATH! now causes a flash of light
+
+
Naksu updated:
+
+ - Pinned notes will now show up on vault, abductor, centcom and large glass airlocks.
+ - Removed a misleading message when handling full stacks of sheets.
+ - Pre-filled glass bottles (uplink, medbay, botany) will now give visual feedback about how much stuff is left inside, and the color of contents will match an empty bottle being filled with the same reagent.
+ - Player-controlled "neutral" mobs such as minebots are now considered valid targets by clock cult's ocular wardens.
+
+
Xhuis updated:
+
+ - Cogged APCs can now be correctly unlocked with an ID card.
+
+
duncathan updated:
+
+ - Portable air pumps can output to a maximum of 25 atmospheres.
+
+
kevinz000 updated:
+
+ - Legacy projectiles have been removed. Instead, all projectiles are now PIXEL PROJECTILES!
+ - Reflectors can now be at any angle you want. Alt click them to set angle!
+ - Pipes can now be layered up to 3 layers.
+
+
15 October 2017
Armhulen updated:
@@ -961,29 +996,6 @@
- Nanotrasen redesigned the area power controllers!
- Thanks Xhuis for the contrast tweak on APCs
-
-
14 August 2017
-
Joan updated:
-
- - Ported CEV-Eris's APC sprites.
-
-
More Robust Than You updated:
-
- - Fixes a typo in the blobbernaut spawn text
-
-
WJohnston updated:
-
- - Adds an ore box and shuttle console to aux bases on all stations.
-
-
Xhuis updated:
-
- - The Resurrect Cultist rune now works as intended.
- - Cyborg energy swords now properly have an icon.
-
-
kingofkosmos updated:
-
- - Canisters don't flash red lights anymore when empty.
-
GoonStation 13 Development Team
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index b07de8b7626..9ad56ea61e4 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -13219,3 +13219,30 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- admin: Radiation pulses over 3000 are logged now
spessmenart:
- imageadd: The captains sabre no longer looks like a rapier.
+2017-10-17:
+ DaxDupont:
+ - bugfix: 'Fancy boxes(ie: donut boxes) now show the proper content amount in the
+ sprite and no longer go invisible when empty.'
+ Mercenaryblue:
+ - bugfix: when decapitated, banana-flavored cream no longer hovers where your head
+ used to be.
+ More Robust Than You:
+ - rscadd: EI NATH! now causes a flash of light
+ Naksu:
+ - bugfix: Pinned notes will now show up on vault, abductor, centcom and large glass
+ airlocks.
+ - spellcheck: Removed a misleading message when handling full stacks of sheets.
+ - bugfix: Pre-filled glass bottles (uplink, medbay, botany) will now give visual
+ feedback about how much stuff is left inside, and the color of contents will
+ match an empty bottle being filled with the same reagent.
+ - bugfix: Player-controlled "neutral" mobs such as minebots are now considered valid
+ targets by clock cult's ocular wardens.
+ Xhuis:
+ - bugfix: Cogged APCs can now be correctly unlocked with an ID card.
+ duncathan:
+ - tweak: Portable air pumps can output to a maximum of 25 atmospheres.
+ kevinz000:
+ - refactor: Legacy projectiles have been removed. Instead, all projectiles are now
+ PIXEL PROJECTILES!
+ - rscadd: Reflectors can now be at any angle you want. Alt click them to set angle!
+ - rscadd: Pipes can now be layered up to 3 layers.
diff --git a/html/changelogs/AutoChangeLog-pr-30599.yml b/html/changelogs/AutoChangeLog-pr-30599.yml
deleted file mode 100644
index 8efa7118156..00000000000
--- a/html/changelogs/AutoChangeLog-pr-30599.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - refactor: "Legacy projectiles have been removed. Instead, all projectiles are now PIXEL PROJECTILES!"
- - rscadd: "Reflectors can now be at any angle you want. Alt click them to set angle!"
diff --git a/html/changelogs/AutoChangeLog-pr-31673.yml b/html/changelogs/AutoChangeLog-pr-31673.yml
deleted file mode 100644
index 3d66b596aab..00000000000
--- a/html/changelogs/AutoChangeLog-pr-31673.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Xhuis"
-delete-after: True
-changes:
- - bugfix: "Cogged APCs can now be correctly unlocked with an ID card."
diff --git a/html/changelogs/AutoChangeLog-pr-31691.yml b/html/changelogs/AutoChangeLog-pr-31691.yml
deleted file mode 100644
index f2d49e07844..00000000000
--- a/html/changelogs/AutoChangeLog-pr-31691.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "More Robust Than You"
-delete-after: True
-changes:
- - rscadd: "EI NATH! now causes a flash of light"
diff --git a/html/changelogs/AutoChangeLog-pr-31699.yml b/html/changelogs/AutoChangeLog-pr-31699.yml
new file mode 100644
index 00000000000..6800b33f5c0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-31699.yml
@@ -0,0 +1,4 @@
+author: "Improvedname"
+delete-after: True
+changes:
+ - tweak: "Reverts katana's to its orginal size being huge"
diff --git a/html/changelogs/AutoChangeLog-pr-31741.yml b/html/changelogs/AutoChangeLog-pr-31741.yml
deleted file mode 100644
index d6d85367ea5..00000000000
--- a/html/changelogs/AutoChangeLog-pr-31741.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - bugfix: "Pinned notes will now show up on vault, abductor, centcom and large glass airlocks."
diff --git a/html/changelogs/AutoChangeLog-pr-31742.yml b/html/changelogs/AutoChangeLog-pr-31742.yml
deleted file mode 100644
index 0eed3012f9b..00000000000
--- a/html/changelogs/AutoChangeLog-pr-31742.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - spellcheck: "Removed a misleading message when handling full stacks of sheets."
diff --git a/html/changelogs/AutoChangeLog-pr-31747.yml b/html/changelogs/AutoChangeLog-pr-31747.yml
deleted file mode 100644
index 14e5bc93922..00000000000
--- a/html/changelogs/AutoChangeLog-pr-31747.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - bugfix: "Pre-filled glass bottles (uplink, medbay, botany) will now give visual feedback about how much stuff is left inside, and the color of contents will match an empty bottle being filled with the same reagent."
diff --git a/html/changelogs/AutoChangeLog-pr-31749.yml b/html/changelogs/AutoChangeLog-pr-31749.yml
deleted file mode 100644
index 84b20fc00d3..00000000000
--- a/html/changelogs/AutoChangeLog-pr-31749.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Mercenaryblue"
-delete-after: True
-changes:
- - bugfix: "when decapitated, banana-flavored cream no longer hovers where your head used to be."
diff --git a/html/changelogs/AutoChangeLog-pr-31750.yml b/html/changelogs/AutoChangeLog-pr-31750.yml
new file mode 100644
index 00000000000..0fda2ae9d13
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-31750.yml
@@ -0,0 +1,4 @@
+author: "Mercenaryblue"
+delete-after: True
+changes:
+ - balance: "it should be far easier to clean out your face from multiple cream pies."
diff --git a/html/changelogs/AutoChangeLog-pr-31757.yml b/html/changelogs/AutoChangeLog-pr-31757.yml
deleted file mode 100644
index 07b022ed296..00000000000
--- a/html/changelogs/AutoChangeLog-pr-31757.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - bugfix: "Player-controlled \"neutral\" mobs such as minebots are now considered valid targets by clock cult's ocular wardens."
diff --git a/html/changelogs/AutoChangeLog-pr-31765.yml b/html/changelogs/AutoChangeLog-pr-31765.yml
deleted file mode 100644
index cd6bfdeea09..00000000000
--- a/html/changelogs/AutoChangeLog-pr-31765.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "DaxDupont"
-delete-after: True
-changes:
- - bugfix: "Fancy boxes(ie: donut boxes) now show the proper content amount in the sprite and no longer go invisible when empty."
diff --git a/html/changelogs/AutoChangeLog-pr-31792.yml b/html/changelogs/AutoChangeLog-pr-31792.yml
new file mode 100644
index 00000000000..b9d1ba0556b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-31792.yml
@@ -0,0 +1,4 @@
+author: "ShizCalev"
+delete-after: True
+changes:
+ - bugfix: "The tools on the Caravan Ambush space ruin have had their speeds corrected."
diff --git a/html/changelogs/AutoChangeLog-pr-31800.yml b/html/changelogs/AutoChangeLog-pr-31800.yml
new file mode 100644
index 00000000000..fe4674e8bb9
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-31800.yml
@@ -0,0 +1,4 @@
+author: "DaxDupont"
+delete-after: True
+changes:
+ - bugfix: "Fixes automatic fire on guns."
diff --git a/icons/obj/atmospherics/pipes/manifold.dmi b/icons/obj/atmospherics/pipes/manifold.dmi
index 6fe285c74bc..3e4d218ca6b 100644
Binary files a/icons/obj/atmospherics/pipes/manifold.dmi and b/icons/obj/atmospherics/pipes/manifold.dmi differ
diff --git a/icons/obj/atmospherics/pipes/pipe_item.dmi b/icons/obj/atmospherics/pipes/pipe_item.dmi
index 7b9185aba02..d953fc4c890 100644
Binary files a/icons/obj/atmospherics/pipes/pipe_item.dmi and b/icons/obj/atmospherics/pipes/pipe_item.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index e5ee8cd66ea..09020db1f27 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1132,6 +1132,7 @@
#include "code\modules\atmospherics\machinery\other\miner.dm"
#include "code\modules\atmospherics\machinery\other\zvent.dm"
#include "code\modules\atmospherics\machinery\pipes\bluespace_pipe.dm"
+#include "code\modules\atmospherics\machinery\pipes\layermanifold.dm"
#include "code\modules\atmospherics\machinery\pipes\manifold.dm"
#include "code\modules\atmospherics\machinery\pipes\manifold4w.dm"
#include "code\modules\atmospherics\machinery\pipes\pipes.dm"
@@ -2074,6 +2075,7 @@
#include "code\modules\ruins\objects_and_mobs\sin_ruins.dm"
#include "code\modules\ruins\spaceruin_code\asteroid4.dm"
#include "code\modules\ruins\spaceruin_code\bigderelict1.dm"
+#include "code\modules\ruins\spaceruin_code\caravanambush.dm"
#include "code\modules\ruins\spaceruin_code\crashedclownship.dm"
#include "code\modules\ruins\spaceruin_code\crashedship.dm"
#include "code\modules\ruins\spaceruin_code\deepstorage.dm"