diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm
index a1ed1bf3648..2444031a8c2 100644
--- a/code/ATMOSPHERICS/atmospherics.dm
+++ b/code/ATMOSPHERICS/atmospherics.dm
@@ -15,26 +15,38 @@ Pipelines + Other Objects -> Pipe network
active_power_usage = 0
power_channel = ENVIRON
var/nodealert = 0
-
- layer = 2.4 //under wires with their 2.44
+
+ layer = 2.4 //under wires with their 2.44
var/connect_types[] = list(1) //1=regular, 2=supply, 3=scrubber
var/connected_to = 1 //same as above, currently not used for anything
var/icon_connect_type = "" //"-supply" or "-scrubbers"
-
+
var/initialize_directions = 0
var/pipe_color
-
+
var/global/datum/pipe_icon_manager/icon_manager
+/obj/machinery/atmospherics/Destroy()
+ for(var/mob/living/M in src) //ventcrawling is serious business
+ M.remove_ventcrawl()
+ M.loc = src.loc
+ ..()
+
+// Find a connecting /obj/machinery/atmospherics in specified direction.
+/obj/machinery/atmospherics/proc/findConnecting(var/direction)
+ for(var/obj/machinery/atmospherics/target in get_step(src,direction))
+ if(target.initialize_directions & get_dir(target,src))
+ return target
+
/obj/machinery/atmospherics/New()
if(!icon_manager)
icon_manager = new()
-
+
if(!pipe_color)
pipe_color = color
color = null
-
+
if(!pipe_color_check(pipe_color))
pipe_color = null
..()
@@ -84,22 +96,22 @@ obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/a
if(list1[i] == list2[j])
var/n = list1[i]
return n
- return 0
-
+ return 0
+
/obj/machinery/atmospherics/proc/check_icon_cache(var/safety = 0)
if(!istype(icon_manager))
if(!safety) //to prevent infinite loops
icon_manager = new()
check_icon_cache(1)
return 0
-
+
return 1
/obj/machinery/atmospherics/proc/color_cache_name(var/obj/machinery/atmospherics/node)
//Don't use this for standard pipes
if(!istype(node))
return null
-
+
return node.pipe_color
/obj/machinery/atmospherics/process()
@@ -134,4 +146,31 @@ obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/a
/obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference)
/obj/machinery/atmospherics/update_icon()
- return null
\ No newline at end of file
+ return null
+
+#define VENT_SOUND_DELAY 30
+
+/obj/machinery/atmospherics/relaymove(mob/living/user, direction)
+ if(!(direction & initialize_directions)) //can't go in a way we aren't connecting to
+ return
+
+ var/obj/machinery/atmospherics/target_move = findConnecting(direction)
+ if(target_move)
+ if(is_type_in_list(target_move, ventcrawl_machinery))
+ user.remove_ventcrawl()
+ user.forceMove(target_move.loc) //handles entering and so on
+ user.visible_message("You hear something squeezing through the ducts.", "You climb out the ventilation system.")
+ else
+ user.loc = target_move
+ user.client.eye = target_move //if we don't do this, Byond only updates the eye every tick - required for smooth 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_list(src, ventcrawl_machinery)) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
+ user.remove_ventcrawl()
+ user.forceMove(src.loc)
+ user.visible_message("You hear something squeezing through the pipes.", "You climb out the ventilation system.")
+ user.canmove = 0
+ spawn(1)
+ user.canmove = 1
\ No newline at end of file
diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm
index d2092ce7e54..a96d5b1acd4 100644
--- a/code/ATMOSPHERICS/components/unary/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm
@@ -39,7 +39,7 @@
var/radio_filter_out
var/radio_filter_in
-
+
connect_types = list(1,2) //connects to regular and supply pipes
/obj/machinery/atmospherics/unary/vent_pump/on
@@ -80,7 +80,7 @@
return
overlays.Cut()
-
+
var/vent_icon = "vent"
var/turf/T = get_turf(src)
@@ -89,7 +89,7 @@
if(T.intact && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
vent_icon += "h"
-
+
if(welded)
vent_icon += "weld"
else if(!powered())
@@ -375,16 +375,3 @@
initial_loc.air_vent_names -= id_tag
..()
return
-
-/*
- Alt-click to ventcrawl - Monkeys, aliens, slimes and mice.
- This is a little buggy but somehow that just seems to plague ventcrawl.
- I am sorry, I don't know why.
-*/
-/obj/machinery/atmospherics/unary/vent_pump/AltClick(var/mob/living/ML)
- if(istype(ML))
- var/list/ventcrawl_verbs = list(/mob/living/carbon/monkey/verb/ventcrawl, /mob/living/carbon/alien/verb/alien_ventcrawl, /mob/living/carbon/slime/verb/ventcrawl,/mob/living/simple_animal/mouse/verb/ventcrawl)
- if(length(ML.verbs & ventcrawl_verbs)) // alien queens have this removed, an istype would be complicated
- ML.handle_ventcrawl(src)
- return
- ..()
diff --git a/code/_onclick/ventcrawl.dm b/code/_onclick/ventcrawl.dm
new file mode 100644
index 00000000000..f80b0933a71
--- /dev/null
+++ b/code/_onclick/ventcrawl.dm
@@ -0,0 +1,37 @@
+var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, /obj/machinery/atmospherics/unary/vent_scrubber)
+
+/mob/living/carbon/slime/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
+
+/mob/living/carbon/monkey/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
+
+/mob/living/simple_animal/borer/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
+
+/mob/living/simple_animal/mouse/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
+
+/mob/living/simple_animal/spiderbot/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
+
+/mob/living/carbon/alien/AltClickOn(var/atom/A)
+ if(is_type_in_list(A,ventcrawl_machinery))
+ src.ventcrawl(A)
+ return
+ ..(A)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/empress.dm b/code/modules/mob/living/carbon/alien/humanoid/empress.dm
index 867804f87c2..dd99aa3fe86 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/empress.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/empress.dm
@@ -47,7 +47,7 @@
real_name = src.name
verbs.Add(/mob/living/carbon/alien/humanoid/proc/corrosive_acid,/mob/living/carbon/alien/humanoid/proc/resin)
- verbs -= /mob/living/carbon/alien/verb/alien_ventcrawl
+ verbs -= /mob/living/carbon/alien/verb/ventcrawl
..()
/mob/living/carbon/alien/humanoid/empress
diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
index 2c4ba4a7e43..85f898640ab 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
@@ -24,7 +24,7 @@
real_name = src.name
verbs.Add(/mob/living/carbon/alien/humanoid/proc/corrosive_acid,/mob/living/carbon/alien/humanoid/proc/neurotoxin,/mob/living/carbon/alien/humanoid/proc/resin)
- verbs -= /mob/living/carbon/alien/verb/alien_ventcrawl
+ verbs -= /mob/living/carbon/alien/verb/ventcrawl
..()
diff --git a/code/modules/mob/living/carbon/alien/powers.dm b/code/modules/mob/living/carbon/alien/powers.dm
index 1af22f401eb..c735c43adf8 100644
--- a/code/modules/mob/living/carbon/alien/powers.dm
+++ b/code/modules/mob/living/carbon/alien/powers.dm
@@ -1,5 +1,5 @@
-/mob/living/carbon/alien/verb/alien_ventcrawl() // -- TLE
- set name = "Crawl through vent (alien)"
+/mob/living/carbon/alien/verb/ventcrawl(var/atom/pipe) // -- TLE
+ set name = "Crawl Through Vent(Alien)"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Alien"
- handle_ventcrawl()
\ No newline at end of file
+ handle_ventcrawl(pipe)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index c52ba708661..2a8f173eb2f 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -1,3 +1,6 @@
+mob/living
+ var/canEnterVentWith = "/obj/item/weapon/implant=0&/obj/item/clothing/mask/facehugger=0&/obj/item/device/radio/borg=0&/obj/machinery/camera=0"
+
/mob/living/carbon/Login()
..()
update_hud()
@@ -256,104 +259,80 @@
/mob/living/carbon/can_use_vents()
return
-/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn
- if(stat)
- src << "You must be conscious to do this!"
- return
- if(lying)
- src << "You can't vent crawl while you're stunned!"
- return
+/mob/living/proc/handle_ventcrawl(var/atom/clicked_on) // -- TLE -- Merged by Carn
+ diary << "[src] is ventcrawling."
+ if(!stat)
+ if(!lying)
- var/special_fail_msg = can_use_vents()
- if(special_fail_msg)
- src << "\red [special_fail_msg]"
- return
+/*
+ if(clicked_on)
+ world << "We start with [clicked_on], and [clicked_on.type]"
+*/
+ var/obj/machinery/atmospherics/unary/vent_found
+
+ if(clicked_on && Adjacent(clicked_on))
+ var/obj/machinery/atmospherics/unary/vent_pump/v = clicked_on
+ if(!istype(v) || !v.welded)
+ vent_found = clicked_on
+
+ if(!vent_found)
+ for(var/obj/machinery/atmospherics/machine in range(1,src))
+ if(is_type_in_list(machine, ventcrawl_machinery))
+ vent_found = machine
+
+ var/obj/machinery/atmospherics/unary/vent_pump/v = machine
+ if(istype(v) && v.welded)
+ vent_found = null
+
+ if(vent_found)
+ if(vent_found.network && (vent_found.network.normal_members.len || vent_found.network.line_members.len))
+
+ src << "You begin climbing into the ventilation system..."
+ if(!do_after(src, 45))
+ return
+
+ if(!client)
+ return
+
+ if(contents.len && !isrobot(src))
+ for(var/obj/item/carried_item in contents)//If the ventcrawler got on objects.
+ if(!(isInTypes(carried_item, canEnterVentWith)))
+ src << "You can't be carrying items or have items equipped when vent crawling!"
+ return
+
+ visible_message("[src] scrambles into the ventilation ducts!", "You climb into the ventilation system.")
+
+ loc = vent_found
+ add_ventcrawl(vent_found)
+
+ else
+ src << "This vent is not connected to anything."
+
+ else
+ src << "You must be standing on or beside an air vent to enter it."
+
+ else
+ src << "You can't vent crawl while you're stunned!"
- if(vent_found) // one was passed in, probably from vent/AltClick()
- if(vent_found.welded)
- src << "That vent is welded shut."
- return
- if(!vent_found.Adjacent(src))
- return // don't even acknowledge that
else
- for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
- if(!v.welded)
- if(v.Adjacent(src))
- vent_found = v
- if(!vent_found)
- src << "You'll need a non-welded vent to crawl into!"
- return
+ src << "You must be conscious to do this!"
+ return
- if(!vent_found.network || !vent_found.network.normal_members.len)
- src << "This vent is not connected to anything."
- return
+/mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/unary/starting_machine)
+ for(var/datum/pipeline/pipeline in starting_machine.network.line_members)
+ for(var/atom/A in (pipeline.members || pipeline.edges))
+ var/image/new_image = image(A, A.loc, dir = A.dir)
+ pipes_shown += new_image
+ client.images += new_image
- var/list/vents = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
- if(temp_vent.welded)
- continue
- if(temp_vent in loc)
- continue
- var/turf/T = get_turf(temp_vent)
+/mob/living/proc/remove_ventcrawl()
+ for(var/image/current_image in pipes_shown)
+ client.images -= current_image
- if(!T || T.z != loc.z)
- continue
+ pipes_shown.len = 0
- var/i = 1
- var/index = "[T.loc.name]\[[i]\]"
- while(index in vents)
- i++
- index = "[T.loc.name]\[[i]\]"
- vents[index] = temp_vent
- if(!vents.len)
- src << "\red There are no available vents to travel to, they could be welded."
- return
-
- var/obj/selection = input("Select a destination.", "Duct System") as null|anything in sortAssoc(vents)
- if(!selection) return
-
- if(!vent_found.Adjacent(src))
- src << "Never mind, you left."
- return
-
- if(!ignore_items)
- for(var/obj/item/carried_item in contents)//If the monkey got on objects.
- if( !istype(carried_item, /obj/item/weapon/implant) && !istype(carried_item, /obj/item/clothing/mask/facehugger) )//If it's not an implant or a facehugger
- src << "\red You can't be carrying items or have items equipped when vent crawling!"
- return
-
- if(isslime(src))
- var/mob/living/carbon/slime/S = src
- if(S.Victim)
- src << "\red You'll have to let [S.Victim] go or finish eating \him first."
- return
-
- var/obj/machinery/atmospherics/unary/vent_pump/target_vent = vents[selection]
- if(!target_vent)
- return
-
- for(var/mob/O in viewers(src, null))
- O.show_message(text("[src] scrambles into the ventillation ducts!"), 1)
- loc = target_vent
-
- var/travel_time = round(get_dist(loc, target_vent.loc) / 2)
-
- spawn(travel_time)
-
- if(!target_vent) return
- for(var/mob/O in hearers(target_vent,null))
- O.show_message("You hear something squeezing through the ventilation ducts.",2)
-
- sleep(travel_time)
-
- if(!target_vent) return
- if(target_vent.welded) //the vent can be welded while alien scrolled through the list or travelled.
- target_vent = vent_found //travel back. No additional time required.
- src << "\red The vent you were heading to appears to be welded."
- loc = target_vent.loc
- var/area/new_area = get_area(loc)
- if(new_area)
- new_area.Entered(src)
+ if(client)
+ client.eye = src
/mob/living/carbon/clean_blood()
. = ..()
diff --git a/code/modules/mob/living/carbon/metroid/powers.dm b/code/modules/mob/living/carbon/metroid/powers.dm
index bb7dcbe7bbc..23733bb9b87 100644
--- a/code/modules/mob/living/carbon/metroid/powers.dm
+++ b/code/modules/mob/living/carbon/metroid/powers.dm
@@ -104,7 +104,7 @@
adjustBruteLoss(-10)
adjustFireLoss(-10)
adjustCloneLoss(-10)
-
+
updatehealth()
if(Victim)
Victim.updatehealth()
@@ -227,9 +227,9 @@
else
src << "I am not old enough to reproduce yet..."
-/mob/living/carbon/slime/verb/ventcrawl()
+/mob/living/carbon/slime/verb/ventcrawl(var/atom/pipe)
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Slime"
if(Victim) return
- handle_ventcrawl()
\ No newline at end of file
+ handle_ventcrawl(pipe)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/monkey/powers.dm b/code/modules/mob/living/carbon/monkey/powers.dm
index e7c6937cda2..1ed34a6b73c 100644
--- a/code/modules/mob/living/carbon/monkey/powers.dm
+++ b/code/modules/mob/living/carbon/monkey/powers.dm
@@ -1,5 +1,5 @@
-/mob/living/carbon/monkey/verb/ventcrawl()
+/mob/living/carbon/monkey/verb/ventcrawl(var/atom/pipe)
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Monkey"
- handle_ventcrawl()
+ handle_ventcrawl(pipe)
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 5bda59435af..7c235b0349a 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -44,3 +44,6 @@
var/silent = null //Can't talk. Value goes down every life proc.
var/floating = 0
var/nightvision = 0
+
+ var/list/icon/pipes_shown = list()
+ var/last_played_vent
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/borer.dm b/code/modules/mob/living/simple_animal/borer.dm
index c0bdc6fe0eb..e9e80db0dd4 100644
--- a/code/modules/mob/living/simple_animal/borer.dm
+++ b/code/modules/mob/living/simple_animal/borer.dm
@@ -456,11 +456,11 @@ mob/living/simple_animal/borer/proc/detatch()
host_brain.real_name = M.real_name
host.status_flags |= PASSEMOTES
-/mob/living/simple_animal/borer/verb/ventcrawl()
+/mob/living/simple_animal/borer/verb/ventcrawl(var/atom/pipe)
set name = "Crawl through vent (borer)"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Alien"
- handle_ventcrawl()
+ handle_ventcrawl(pipe)
/mob/living/simple_animal/borer/can_use_vents()
return
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 76e9bcc276d..65b6447696e 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -70,58 +70,11 @@
client.time_died_as_mouse = world.time
//copy paste from alien/larva, if that func is updated please update this one also
-/mob/living/simple_animal/mouse/verb/ventcrawl()
+/mob/living/simple_animal/mouse/verb/ventcrawl(var/atom/pipe)
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Mouse"
-
-// if(!istype(V,/obj/machinery/atmoalter/siphs/fullairsiphon/air_vent))
-// return
-
- if(src.stat != CONSCIOUS) return
-
- var/obj/machinery/atmospherics/unary/vent_pump/vent_found
- var/welded = 0
- for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
- if(!v.welded)
- vent_found = v
- break
- else
- welded = 1
- if(vent_found)
- if(vent_found.network&&vent_found.network.normal_members.len)
- var/list/vents = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
- if(temp_vent.loc == loc)
- continue
- vents.Add(temp_vent)
- var/list/choices = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents)
- if(vent.loc.z != loc.z)
- continue
- var/atom/a = get_turf(vent)
- choices.Add(a.loc)
- var/turf/startloc = loc
- var/obj/selection = input("Select a destination.", "Duct System") in choices
- var/selection_position = choices.Find(selection)
- if(loc==startloc)
- var/obj/target_vent = vents[selection_position]
- if(target_vent)
- /*
- for(var/mob/O in oviewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("[src] scrambles into the ventillation ducts!"), 1)
- */
- loc = target_vent.loc
- else
- src << "\blue You need to remain still while entering a vent."
- else
- src << "\blue This vent is not connected to anything."
- else if(welded)
- src << "\red That vent is welded."
- else
- src << "\blue You must be standing on or beside an air vent to enter it."
- return
+ handle_ventcrawl(pipe)
//make mice fit under tables etc? this was hacky, and not working
/*
diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
index 4729438839e..195d2212436 100644
--- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
@@ -140,7 +140,7 @@
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with the [O]. ")
-
+
/mob/living/simple_animal/spiderbot/emag_act(user as mob)
if (emagged)
user << "\red [src] is already overloaded - better run."
@@ -219,51 +219,11 @@
return
//copy paste from alien/larva, if that func is updated please update this one also
-/mob/living/simple_animal/spiderbot/verb/ventcrawl()
+/mob/living/simple_animal/spiderbot/verb/ventcrawl(var/atom/pipe)
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Spiderbot"
-
-// if(!istype(V,/obj/machinery/atmoalter/siphs/fullairsiphon/air_vent))
-// return
- var/obj/machinery/atmospherics/unary/vent_pump/vent_found
- var/welded = 0
- for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
- if(!v.welded)
- vent_found = v
- break
- else
- welded = 1
- if(vent_found)
- if(vent_found.network&&vent_found.network.normal_members.len)
- var/list/vents = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
- if(temp_vent.loc == loc)
- continue
- vents.Add(temp_vent)
- var/list/choices = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents)
- if(vent.loc.z != loc.z)
- continue
- var/atom/a = get_turf(vent)
- choices.Add(a.loc)
- var/turf/startloc = loc
- var/obj/selection = input("Select a destination.", "Duct System") in choices
- var/selection_position = choices.Find(selection)
- if(loc==startloc)
- var/obj/target_vent = vents[selection_position]
- if(target_vent)
- loc = target_vent.loc
- else
- src << "\blue You need to remain still while entering a vent."
- else
- src << "\blue This vent is not connected to anything."
- else if(welded)
- src << "\red That vent is welded."
- else
- src << "\blue You must be standing on or beside an air vent to enter it."
- return
-
+ handle_ventcrawl(pipe)
//Cannibalized from the parrot mob. ~Zuhayr
/mob/living/simple_animal/spiderbot/verb/drop_held_item()
diff --git a/paradise.dme b/paradise.dme
index 47cb9cbd971..8460f9bd996 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -47,6 +47,7 @@
#include "code\_onclick\other_mobs.dm"
#include "code\_onclick\overmind.dm"
#include "code\_onclick\telekinesis.dm"
+#include "code\_onclick\ventcrawl.dm"
#include "code\_onclick\hud\_defines.dm"
#include "code\_onclick\hud\ai.dm"
#include "code\_onclick\hud\alien.dm"
diff --git a/sound/machines/ventcrawl.ogg b/sound/machines/ventcrawl.ogg
new file mode 100644
index 00000000000..2df8b5c8981
Binary files /dev/null and b/sound/machines/ventcrawl.ogg differ