diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 51a5fb3ece..2a375a38ae 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -536,3 +536,7 @@
#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
+
+// /datum/element/ventcrawling signals
+#define COMSIG_HANDLE_VENTCRAWL "handle_ventcrawl" //when atom with ventcrawling element attempts to ventcrawl
+#define COMSIG_CHECK_VENTCRAWL "check_ventcrawl" //to check an atom's ventcrawling element tier (if applicable)
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 153a82ad5e..6604120d27 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -29,9 +29,10 @@
#define MOB_SIZE_LARGE 3
// Ventcrawling defines
-#define VENTCRAWLER_NONE 0
-#define VENTCRAWLER_NUDE 1
-#define VENTCRAWLER_ALWAYS 2
+#define VENTCRAWLER_NONE 0
+#define VENTCRAWLER_NUDE 1
+#define VENTCRAWLER_IMPLANT 2
+#define VENTCRAWLER_ALWAYS 3
// Bloodcrawling defines
#define BLOODCRAWL 1
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index 44775ed031..8dca59ea94 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -121,7 +121,7 @@
add_monkey(affected_mob.mind)
if(ishuman(affected_mob))
var/mob/living/carbon/monkey/M = affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
- M.ventcrawler = VENTCRAWLER_ALWAYS
+ M.AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/datum/disease/transformation/jungle_fever/stage_act()
diff --git a/code/datums/elements/ventcrawling.dm b/code/datums/elements/ventcrawling.dm
new file mode 100644
index 0000000000..f1429b94fd
--- /dev/null
+++ b/code/datums/elements/ventcrawling.dm
@@ -0,0 +1,31 @@
+/datum/element/ventcrawling
+ element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
+ id_arg_index = 2
+ var/tier
+
+/datum/element/ventcrawling/Attach(datum/target, duration = 0, given_tier = VENTCRAWLER_NUDE)
+ . = ..()
+
+ src.tier = given_tier
+
+ RegisterSignal(target, COMSIG_HANDLE_VENTCRAWL, .proc/handle_ventcrawl)
+ RegisterSignal(target, COMSIG_CHECK_VENTCRAWL, .proc/check_ventcrawl)
+ to_chat(target, "You can ventcrawl! Use alt+click on vents to quickly travel about the station.")
+
+ if(duration!=0)
+ addtimer(CALLBACK(src, .proc/Detach, target), duration)
+
+/datum/element/ventcrawling/Detach(datum/target)
+ . = ..()
+
+ UnregisterSignal(target, COMSIG_HANDLE_VENTCRAWL)
+
+/datum/element/ventcrawling/proc/handle_ventcrawl(datum/target,atom/A)
+ var/mob/living/person = target
+ if(!istype(person))
+ return FALSE
+
+ person.handle_ventcrawl(A,tier)
+
+/datum/element/ventcrawling/proc/check_ventcrawl()
+ return tier
diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm
index a07e9a26d5..ff8287d77b 100644
--- a/code/game/objects/structures/plasticflaps.dm
+++ b/code/game/objects/structures/plasticflaps.dm
@@ -62,7 +62,7 @@
return 1
var/mob/living/M = caller
- if(!M.ventcrawler && M.mob_size != MOB_SIZE_TINY)
+ if(!(SEND_SIGNAL(M, COMSIG_CHECK_VENTCRAWL)) && M.mob_size != MOB_SIZE_TINY)
return 0
var/atom/movable/M = caller
if(M && M.pulling)
@@ -91,7 +91,7 @@
return 1
if(M.buckled && istype(M.buckled, /mob/living/simple_animal/bot/mulebot)) // mulebot passenger gets a free pass.
return 1
- if(!M.lying && !M.ventcrawler && M.mob_size != MOB_SIZE_TINY) //If your not laying down, or a ventcrawler or a small creature, no pass.
+ if(!M.lying && !(SEND_SIGNAL(M, COMSIG_CHECK_VENTCRAWL)) && M.mob_size != MOB_SIZE_TINY) //If your not laying down, or a ventcrawler or a small creature, no pass.
return 0
return ..()
diff --git a/code/modules/antagonists/abductor/equipment/glands/ventcrawl.dm b/code/modules/antagonists/abductor/equipment/glands/ventcrawl.dm
index 8ac083f68b..a0ee2a9bc3 100644
--- a/code/modules/antagonists/abductor/equipment/glands/ventcrawl.dm
+++ b/code/modules/antagonists/abductor/equipment/glands/ventcrawl.dm
@@ -9,4 +9,4 @@
/obj/item/organ/heart/gland/ventcrawling/activate()
to_chat(owner, "You feel very stretchy.")
- owner.ventcrawler = VENTCRAWLER_ALWAYS
+ owner.AddElement(/datum/element/ventcrawling, duration = mind_control_duration, given_tier = VENTCRAWLER_ALWAYS)
diff --git a/code/modules/antagonists/devil/true_devil/_true_devil.dm b/code/modules/antagonists/devil/true_devil/_true_devil.dm
index 293b1de3dc..069080170e 100644
--- a/code/modules/antagonists/devil/true_devil/_true_devil.dm
+++ b/code/modules/antagonists/devil/true_devil/_true_devil.dm
@@ -11,7 +11,6 @@
gender = NEUTER
health = 350
maxHealth = 350
- ventcrawler = VENTCRAWLER_NONE
density = TRUE
pass_flags = 0
sight = (SEE_TURFS | SEE_OBJS)
diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm
index e91feda006..00a2039ac2 100644
--- a/code/modules/antagonists/morph/morph.dm
+++ b/code/modules/antagonists/morph/morph.dm
@@ -15,7 +15,6 @@
stop_automated_movement = 1
status_flags = CANPUSH
pass_flags = PASSTABLE
- ventcrawler = VENTCRAWLER_ALWAYS
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxHealth = 150
@@ -51,6 +50,10 @@
You can attack any item or dead creature to consume it - creatures will fully restore your health. \
Finally, you can restore yourself to your original form while morphed by shift-clicking yourself."
+/mob/living/simple_animal/hostile/morph/Initialize()
+ . = ..()
+ src.AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/hostile/morph/examine(mob/user)
if(morphed)
. = form.examine(user)
diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm
index 7444905b89..fb8f4c5f07 100644
--- a/code/modules/antagonists/swarmer/swarmer.dm
+++ b/code/modules/antagonists/swarmer/swarmer.dm
@@ -93,7 +93,6 @@
AIStatus = AI_OFF
pass_flags = PASSTABLE
mob_size = MOB_SIZE_TINY
- ventcrawler = VENTCRAWLER_ALWAYS
ranged = 1
projectiletype = /obj/item/projectile/beam/disabler
ranged_cooldown_time = 20
@@ -112,6 +111,7 @@
remove_verb(src, /mob/living/verb/pulled)
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.add_to_hud(src)
+ src.AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/hostile/swarmer/med_hud_set_health()
var/image/holder = hud_list[DIAG_HUD]
diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm
index 25e4084524..7f4a8cd794 100644
--- a/code/modules/atmospherics/machinery/atmosmachinery.dm
+++ b/code/modules/atmospherics/machinery/atmosmachinery.dm
@@ -44,7 +44,7 @@
. = ..()
if(is_type_in_list(src, GLOB.ventcrawl_machinery) && isliving(user))
var/mob/living/L = user
- if(L.ventcrawler)
+ if(SEND_SIGNAL(L, COMSIG_CHECK_VENTCRAWL))
. += "Alt-click to crawl through it."
/obj/machinery/atmospherics/New(loc, process = TRUE, setdir)
@@ -318,7 +318,7 @@
/obj/machinery/atmospherics/AltClick(mob/living/L)
if(is_type_in_typecache(src, GLOB.ventcrawl_machinery))
- return L.handle_ventcrawl(src)
+ return SEND_SIGNAL(L, COMSIG_HANDLE_VENTCRAWL, src)
return ..()
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index e7ad67d240..e8c78c668c 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -4,7 +4,6 @@
gender = FEMALE //All xenos are girls!!
dna = null
faction = list(ROLE_ALIEN)
- ventcrawler = VENTCRAWLER_ALWAYS
sight = SEE_MOBS
see_in_dark = 4
verb_say = "hisses"
@@ -40,6 +39,8 @@
create_internal_organs()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
. = ..()
/mob/living/carbon/alien/create_internal_organs()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
index 1200220ce4..ba6ec19dcb 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
@@ -2,7 +2,6 @@
//Common stuffs for Praetorian and Queen
icon = 'icons/mob/alienqueen.dmi'
status_flags = 0
- ventcrawler = VENTCRAWLER_NONE //pull over that ass too fat
unique_name = 0
pixel_x = -16
bubble_icon = "alienroyal"
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index ff0287d7b9..858e3000fb 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -801,11 +801,11 @@
/datum/species/golem/plastic/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
- C.ventcrawler = VENTCRAWLER_NUDE
+ C.AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/datum/species/golem/plastic/on_species_loss(mob/living/carbon/C)
. = ..()
- C.ventcrawler = initial(C.ventcrawler)
+ C.RemoveElement(/datum/element/ventcrawling)
/datum/species/golem/bronze
name = "Bronze Golem"
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index 558fdc6594..2296b69762 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -169,7 +169,7 @@
if(istype(H, /mob/living/simple_animal))
var/mob/living/simple_animal/SA = H
if((human_caster.blood_volume <= (BLOOD_VOLUME_BAD*human_caster.blood_ratio)) || (ventcrawl_nude_only && length(human_caster.get_equipped_items(include_pockets = TRUE))))
- SA.ventcrawler = FALSE
+ SA.RemoveElement(/datum/element/ventcrawling)
if(transfer_name)
H.name = human_caster.name
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index 1f3e0a1b81..d49059f839 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -6,7 +6,6 @@
icon_state = ""
gender = NEUTER
pass_flags = PASSTABLE
- ventcrawler = VENTCRAWLER_NUDE
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1)
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/monkey
@@ -29,6 +28,8 @@
create_bodyparts()
create_internal_organs()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_NUDE)
+
. = ..()
if (cubespawned)
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 5621fab9c1..d96540d928 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -75,7 +75,6 @@
var/bloodcrawl = 0 //0 No blood crawling, BLOODCRAWL for bloodcrawling, BLOODCRAWL_EAT for crawling+mob devour
var/holder = null //The holder for blood crawling
- var/ventcrawler = 0 //0 No vent crawling, 1 vent crawling in the nude, 2 vent crawling always
var/limb_destroyer = 0 //1 Sets AI behavior that allows mobs to target and dismember limbs with their basic attack.
var/mob_size = MOB_SIZE_HUMAN
diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm
index 931f87eb7c..2b1c2de17a 100644
--- a/code/modules/mob/living/login.dm
+++ b/code/modules/mob/living/login.dm
@@ -17,10 +17,6 @@
if (isturf(T))
update_z(T.z)
- //Vents
- if(ventcrawler)
- to_chat(src, "You can ventcrawl! Use alt+click on vents to quickly travel about the station.")
-
if(ranged_ability)
ranged_ability.add_ranged_ability(src, "You currently have [ranged_ability] active!")
if((vore_flags & VORE_INIT) && !(vore_flags & VOREPREF_INIT)) //Vore's been initialized, voreprefs haven't. If this triggers then that means that voreprefs failed to load due to the client being missing.
diff --git a/code/modules/mob/living/simple_animal/friendly/bumbles.dm b/code/modules/mob/living/simple_animal/friendly/bumbles.dm
index 0debb7b98c..6ed6d03b68 100644
--- a/code/modules/mob/living/simple_animal/friendly/bumbles.dm
+++ b/code/modules/mob/living/simple_animal/friendly/bumbles.dm
@@ -20,7 +20,6 @@
density = FALSE
movement_type = FLYING
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
- ventcrawler = VENTCRAWLER_ALWAYS
mob_size = MOB_SIZE_TINY
mob_biotypes = MOB_ORGANIC|MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
@@ -35,6 +34,7 @@
/mob/living/simple_animal/pet/bumbles/Initialize()
. = ..()
add_verb(src, /mob/living/proc/lay_down)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/pet/bumbles/ComponentInitialize()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm
index bf4f45e283..1e6afd6044 100644
--- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm
+++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm
@@ -20,7 +20,6 @@
density = FALSE
movement_type = FLYING
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
- ventcrawler = VENTCRAWLER_ALWAYS
mob_size = MOB_SIZE_TINY
mob_biotypes = MOB_ORGANIC|MOB_BUG
gold_core_spawnable = FRIENDLY_SPAWN
@@ -33,6 +32,7 @@
. = ..()
var/newcolor = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/butterfly/bee_friendly()
return TRUE //treaty signed at the Beeneeva convention
diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm
index 71ae3b4c03..4594d27ecd 100644
--- a/code/modules/mob/living/simple_animal/friendly/cat.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cat.dm
@@ -14,7 +14,6 @@
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
- ventcrawler = VENTCRAWLER_ALWAYS
pass_flags = PASSTABLE
mob_size = MOB_SIZE_SMALL
mob_biotypes = MOB_ORGANIC|MOB_BEAST
@@ -40,6 +39,7 @@
/mob/living/simple_animal/pet/cat/Initialize()
. = ..()
add_verb(src, /mob/living/proc/lay_down)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/pet/cat/ComponentInitialize()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/friendly/cockroach.dm b/code/modules/mob/living/simple_animal/friendly/cockroach.dm
index 384fa8146f..67119139fc 100644
--- a/code/modules/mob/living/simple_animal/friendly/cockroach.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cockroach.dm
@@ -22,7 +22,6 @@
response_harm_simple = "splat"
speak_emote = list("chitters")
density = FALSE
- ventcrawler = VENTCRAWLER_ALWAYS
mob_size = MOB_SIZE_TINY
gold_core_spawnable = FRIENDLY_SPAWN
verb_say = "chitters"
@@ -32,6 +31,10 @@
var/squish_chance = 50
del_on_death = 1
+/mob/living/simple_animal/cockroach/Initialize()
+ . = ..()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/cockroach/death(gibbed)
if(SSticker.mode && SSticker.mode.station_was_nuked) //If the nuke is going off, then cockroaches are invincible. Keeps the nuke from killing them, cause cockroaches are immune to nukes.
return
diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm
index 7f3693f622..addbd493a5 100644
--- a/code/modules/mob/living/simple_animal/friendly/crab.dm
+++ b/code/modules/mob/living/simple_animal/friendly/crab.dm
@@ -21,12 +21,15 @@
stop_automated_movement = 1
friendly_verb_continuous = "pinches"
friendly_verb_simple = "pinch"
- ventcrawler = VENTCRAWLER_ALWAYS
mob_size = MOB_SIZE_TINY
var/obj/item/inventory_head
var/obj/item/inventory_mask
gold_core_spawnable = FRIENDLY_SPAWN
+/mob/living/simple_animal/crab/Initialize()
+ . = ..()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/crab/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index a8c0e7d207..e11facb4ba 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -28,7 +28,6 @@
unsuitable_atmos_damage = 0
wander = 0
speed = 0
- ventcrawler = VENTCRAWLER_ALWAYS
healable = 0
density = FALSE
pass_flags = PASSTABLE | PASSMOB
@@ -101,6 +100,8 @@
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.add_to_hud(src)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/drone/ComponentInitialize()
. = ..()
if(can_be_held)
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
index 55339a02fd..22dbdd3db7 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
@@ -114,7 +114,6 @@
harm_intent_damage = 5
density = TRUE
speed = 1
- ventcrawler = VENTCRAWLER_NONE
faction = list("neutral", "ratvar")
speak_emote = list("clanks", "clinks", "clunks", "clangs")
verb_ask = "requests"
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
index 54184310a8..0728484cea 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
@@ -110,7 +110,7 @@
to_chat(src, "Your onboard antivirus has initiated lockdown. Motor servos are impaired, ventilation access is denied, and your display reports that you are hacked to all nearby.")
hacked = TRUE
mind.special_role = "hacked drone"
- ventcrawler = VENTCRAWLER_NONE //Again, balance
+ RemoveElement(/datum/element/ventcrawling) // balance
speed = 1 //gotta go slow
message_admins("[src] ([src.key]) became a hacked drone hellbent on [clockwork ? "serving Ratvar" : "destroying the station"]!")
else
@@ -125,7 +125,7 @@
to_chat(src, "Having been restored, your onboard antivirus reports the all-clear and you are able to perform all actions again.")
hacked = FALSE
mind.special_role = null
- ventcrawler = initial(ventcrawler)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
speed = initial(speed)
if(is_servant_of_ratvar(src))
remove_servant_of_ratvar(src, TRUE)
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index 51e7ee6c03..81925d922f 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -241,7 +241,6 @@
attack_verb_simple = "kick"
health = 3
maxHealth = 3
- ventcrawler = VENTCRAWLER_ALWAYS
var/amount_grown = 0
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
@@ -253,6 +252,7 @@
. = ..()
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/chick/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
@@ -296,7 +296,6 @@
attack_verb_simple = "kick"
health = 15
maxHealth = 15
- ventcrawler = VENTCRAWLER_ALWAYS
var/eggsleft = 0
var/eggsFertile = TRUE
var/body_color
@@ -322,6 +321,8 @@
pixel_y = rand(0, 10)
++chicken_count
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/chicken/Destroy()
--chicken_count
return ..()
@@ -392,7 +393,6 @@
attack_verb_simple = "kick"
health = 25
maxHealth = 25
- ventcrawler = VENTCRAWLER_ALWAYS
var/eggsleft = 0
var/eggsFertile = TRUE
pass_flags = PASSTABLE | PASSMOB
@@ -412,6 +412,8 @@
. = ..()
++kiwi_count
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/kiwi/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
@@ -473,7 +475,6 @@
attack_verb_simple = "kick"
health = 10
maxHealth = 10
- ventcrawler = VENTCRAWLER_ALWAYS
var/amount_grown = 0
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
@@ -486,6 +487,8 @@
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/babyKiwi/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm
index b9ff99b677..fd0095bf87 100644
--- a/code/modules/mob/living/simple_animal/friendly/lizard.dm
+++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm
@@ -18,7 +18,6 @@
response_disarm_simple = "shoo"
response_harm_continuous = "stomps on"
response_harm_simple = "stomp on"
- ventcrawler = VENTCRAWLER_ALWAYS
density = FALSE
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
@@ -31,6 +30,7 @@
/mob/living/simple_animal/hostile/lizard/ComponentInitialize()
. = ..()
AddElement(/datum/element/mob_holder, worn_state = "lizard", inv_slots = ITEM_SLOT_HEAD) //you can hold lizards now.
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/hostile/lizard/CanAttack(atom/the_target)//Can we actually attack a possible target?
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 51c903ee16..8348af43fa 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -22,7 +22,6 @@
response_harm_continuous = "splats"
response_harm_simple = "splat"
density = FALSE
- ventcrawler = VENTCRAWLER_ALWAYS
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
mob_biotypes = MOB_ORGANIC|MOB_BEAST
@@ -40,6 +39,7 @@
icon_state = "mouse_[body_color]"
icon_living = "mouse_[body_color]"
icon_dead = "mouse_[body_color]_dead"
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/mouse/proc/splat()
src.health = 0
diff --git a/code/modules/mob/living/simple_animal/friendly/possum.dm b/code/modules/mob/living/simple_animal/friendly/possum.dm
index 71fdbd1465..5e7ed572e2 100644
--- a/code/modules/mob/living/simple_animal/friendly/possum.dm
+++ b/code/modules/mob/living/simple_animal/friendly/possum.dm
@@ -22,12 +22,15 @@
response_harm_continuous = "stamps on"
response_harm_simple = "stamp"
density = FALSE
- ventcrawler = VENTCRAWLER_ALWAYS
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_TINY
mob_biotypes = MOB_ORGANIC|MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
+/mob/living/simple_animal/opossum/Initialize()
+ . = ..()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/opossum/poppy
name = "Poppy the Safety Possum"
desc = "Safety first!"
diff --git a/code/modules/mob/living/simple_animal/friendly/snake.dm b/code/modules/mob/living/simple_animal/friendly/snake.dm
index 4d20b927a6..61c735c7c1 100644
--- a/code/modules/mob/living/simple_animal/friendly/snake.dm
+++ b/code/modules/mob/living/simple_animal/friendly/snake.dm
@@ -30,7 +30,6 @@
response_harm_continuous = "steps on"
response_harm_simple = "step on"
faction = list("hostile")
- ventcrawler = VENTCRAWLER_ALWAYS
density = FALSE
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
@@ -39,6 +38,9 @@
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
+/mob/living/simple_animal/hostile/retaliate/poison/snake/Initialize()
+ . = ..()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/hostile/retaliate/poison/snake/ListTargets(atom/the_target)
. = oview(vision_range, targets_from) //get list of things in vision range
diff --git a/code/modules/mob/living/simple_animal/hostile/banana_spider.dm b/code/modules/mob/living/simple_animal/hostile/banana_spider.dm
index 259c0bc721..a88593ed74 100644
--- a/code/modules/mob/living/simple_animal/hostile/banana_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/banana_spider.dm
@@ -22,7 +22,6 @@
speak_emote = list("chitters")
mouse_opacity = 2
density = TRUE
- ventcrawler = VENTCRAWLER_ALWAYS
verb_say = "chitters"
verb_ask = "chitters inquisitively"
verb_exclaim = "chitters loudly"
@@ -37,6 +36,8 @@
if(A)
notify_ghosts("A banana spider has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/banana_spider/attack_ghost(mob/user)
if(key) //please stop using src. without a good reason.
return
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index bde5a19518..609a6d9420 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -44,7 +44,6 @@
var/busy = SPIDER_IDLE
pass_flags = PASSTABLE
move_to_delay = 6
- ventcrawler = VENTCRAWLER_ALWAYS
attack_verb_continuous = "bites"
attack_verb_simple = "bite"
attack_sound = 'sound/weapons/bite.ogg'
@@ -63,6 +62,8 @@
lay_web = new
lay_web.Grant(src)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/hostile/poison/giant_spider/Destroy()
QDEL_NULL(lay_web)
return ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm
index 850beeb099..5e34d17bb2 100644
--- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm
+++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm
@@ -20,11 +20,14 @@
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
speak_emote = list("squeaks")
- ventcrawler = VENTCRAWLER_ALWAYS
var/datum/mind/origin
var/egg_lain = 0
gold_core_spawnable = NO_SPAWN //are you sure about this?? // CITADEL CHANGE, Yes.
+/mob/living/simple_animal/hostile/headcrab/Initialize()
+ . = ..()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/victim)
var/obj/item/organ/body_egg/changeling_egg/egg = new(victim)
egg.Insert(victim)
diff --git a/code/modules/mob/living/simple_animal/hostile/killertomato.dm b/code/modules/mob/living/simple_animal/hostile/killertomato.dm
index b86d5d87fc..d3d3dadd1e 100644
--- a/code/modules/mob/living/simple_animal/hostile/killertomato.dm
+++ b/code/modules/mob/living/simple_animal/hostile/killertomato.dm
@@ -22,10 +22,13 @@
attack_verb_continuous = "slams"
attack_verb_simple = "slam"
attack_sound = 'sound/weapons/punch1.ogg'
- ventcrawler = VENTCRAWLER_ALWAYS
faction = list("plants")
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 150
maxbodytemp = 500
gold_core_spawnable = HOSTILE_SPAWN
+
+/mob/living/simple_animal/hostile/killertomato/Initialize()
+ . = ..()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index fa3a59a6b9..a584d34995 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -620,7 +620,6 @@ Difficulty: Very Hard
density = FALSE
movement_type = FLYING
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
- ventcrawler = VENTCRAWLER_ALWAYS
mob_size = MOB_SIZE_TINY
gold_core_spawnable = HOSTILE_SPAWN
verb_say = "warps"
@@ -648,6 +647,7 @@ Difficulty: Very Hard
remove_verb(src, /mob/verb/me_verb)
var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
medsensor.add_hud_to(src)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/hostile/lightgeist/AttackingTarget()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
index 0ccc4525c7..e35220a920 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
@@ -27,7 +27,6 @@
friendly_verb_continuous = "pinches"
friendly_verb_simple = "pinch"
a_intent = INTENT_HELP
- ventcrawler = VENTCRAWLER_ALWAYS
gold_core_spawnable = FRIENDLY_SPAWN
stat_attack = UNCONSCIOUS
gender = NEUTER
@@ -50,6 +49,7 @@
/mob/living/simple_animal/hostile/asteroid/gutlunch/Initialize()
udder = new()
. = ..()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/hostile/asteroid/gutlunch/CanAttack(atom/the_target) // Gutlunch-specific version of CanAttack to handle stupid stat_exclusive = true crap so we don't have to do it for literally every single simple_animal/hostile except the two that spawn in lavaland
if(isturf(the_target) || !the_target || the_target.type == /atom/movable/lighting_object) // bail out on invalids
diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm
index 9101430ccc..f41746ea69 100644
--- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm
@@ -28,7 +28,6 @@
stat_attack = DEAD
mouse_opacity = MOUSE_OPACITY_ICON
speed = 1
- ventcrawler = VENTCRAWLER_ALWAYS
robust_searching = 1
unique_name = 1
speak_emote = list("squeaks")
@@ -41,6 +40,10 @@
var/static/mutable_appearance/cap_living //Where we store our cap icons so we dont generate them constantly to update our icon
var/static/mutable_appearance/cap_dead
+/mob/living/simple_animal/hostile/mushroom/Initialize()
+ . = ..()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/hostile/mushroom/examine(mob/user)
. = ..()
if(health >= maxHealth)
diff --git a/code/modules/mob/living/simple_animal/hostile/regalrat.dm b/code/modules/mob/living/simple_animal/hostile/regalrat.dm
index 77b2d4268a..77731f0ea4 100644
--- a/code/modules/mob/living/simple_animal/hostile/regalrat.dm
+++ b/code/modules/mob/living/simple_animal/hostile/regalrat.dm
@@ -23,7 +23,6 @@
attack_verb_continuous = "slashes"
attack_verb_simple = "slash"
attack_sound = 'sound/weapons/punch1.ogg'
- ventcrawler = VENTCRAWLER_ALWAYS
unique_name = TRUE
faction = list("rat")
var/datum/action/cooldown/coffer
@@ -42,6 +41,8 @@
key = C.key
notify_ghosts("All rise for the rat king, ascendant to the throne in \the [get_area(src)].", source = src, action = NOTIFY_ORBIT, flashwindow = FALSE)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/hostile/regalrat/handle_automated_action()
if(prob(20))
riot.Trigger()
@@ -175,7 +176,6 @@
health = 15
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1)
density = FALSE
- ventcrawler = VENTCRAWLER_ALWAYS
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
mob_biotypes = MOB_ORGANIC|MOB_BEAST
@@ -185,6 +185,7 @@
. = ..()
SSmobs.cheeserats += src
AddComponent(/datum/component/swarming)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/hostile/rat/Destroy()
SSmobs.cheeserats -= src
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm
index 9045ccef51..cb1ee6c6f6 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm
@@ -30,7 +30,6 @@
attack_sound = 'sound/weapons/bite.ogg'
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
- ventcrawler = VENTCRAWLER_ALWAYS
mob_size = MOB_SIZE_TINY
movement_type = FLYING
speak_emote = list("squeaks")
@@ -38,11 +37,14 @@
var/min_oxy = 0
var/max_tox = 0
-
//Space bats need no air to fly in.
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
+/mob/living/simple_animal/hostile/retaliate/bat/Initialize()
+ . = ..()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/hostile/retaliate/bat/secbat
name = "Security Bat"
icon_state = "secbat"
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
index dec2159dc0..96418686d3 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
@@ -137,7 +137,6 @@
emote_see = list("honks", "sweats", "jiggles", "contemplates its existence")
speak_chance = 5
dextrous = TRUE
- ventcrawler = VENTCRAWLER_ALWAYS
maxHealth = 140
health = 140
speed = -5
@@ -147,6 +146,10 @@
obj_damage = 5
loot = list(/obj/item/clothing/suit/hooded/bloated_human, /obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap)
+/mob/living/simple_animal/hostile/retaliate/clown/fleshclown/Initialize()
+ . = ..()
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/hostile/retaliate/clown/longface
name = "Longface"
desc = "Often found walking into the bar."
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm
index 8424a0a576..5953de72ad 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm
@@ -22,7 +22,6 @@
response_harm_continuous = "splats"
response_harm_simple = "splat"
density = FALSE
- ventcrawler = VENTCRAWLER_ALWAYS
faction = list("hostile")
attack_sound = 'sound/effects/reee.ogg'
butcher_results = list(/obj/item/reagent_containers/food/snacks/nugget = 1)
@@ -40,6 +39,7 @@
icon_living = "rare_frog"
icon_dead = "rare_frog_dead"
butcher_results = list(/obj/item/reagent_containers/food/snacks/nugget = 5)
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
/mob/living/simple_animal/hostile/retaliate/frog/Crossed(AM as mob|obj)
if(!stat && isliving(AM))
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 1f45e57718..d5b9fa5f68 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -4,7 +4,6 @@
icon_state = "grey baby slime"
pass_flags = PASSTABLE
mob_size = MOB_SIZE_SMALL
- ventcrawler = VENTCRAWLER_ALWAYS
gender = NEUTER
var/is_adult = 0
var/docile = 0
@@ -108,6 +107,8 @@
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_SLIME, 7.5)
set_nutrition(rand(650, 800))
+ AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
+
/mob/living/simple_animal/slime/Destroy()
for (var/A in actions)
var/datum/action/AC = A
diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm
index 4c00fd0033..06c75f9b8e 100644
--- a/code/modules/mob/living/ventcrawling.dm
+++ b/code/modules/mob/living/ventcrawling.dm
@@ -5,7 +5,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
//VENTCRAWLING
-/mob/living/proc/handle_ventcrawl(atom/A)
+/mob/living/proc/handle_ventcrawl(atom/A, ventcrawler)
if(!ventcrawler || !Adjacent(A))
return
. = TRUE //return value to stop the client from being shown the turf contents stat tab on alt-click.
@@ -59,10 +59,15 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
if(!client)
return
- if(iscarbon(src) && ventcrawler == VENTCRAWLER_NUDE)
- if(length(get_equipped_items(include_pockets = TRUE)) || get_num_held_items())
- to_chat(src, "You can't crawl around in the ventilation ducts with items!")
- return
+ if(iscarbon(src))
+ switch(ventcrawler)
+ if(VENTCRAWLER_NUDE)
+ if(length(get_equipped_items(include_pockets = TRUE)) || get_num_held_items())
+ to_chat(src, "You can't crawl around in the ventilation ducts with items!")
+ return
+ if(VENTCRAWLER_IMPLANT)
+ if(getBackSlot() || getBeltSlot() || get_num_held_items())
+ to_chat(src, "You can't crawl around in the ventilation ducts with what you have equipped!")
visible_message("[src] scrambles into the ventilation ducts!","You climb into the ventilation ducts.")
forceMove(vent_found)
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index b106005a15..ef3a053027 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -141,7 +141,7 @@
update_icon()
/obj/machinery/disposal/proc/can_stuff_mob_in(mob/living/target, mob/living/user, pushing = FALSE)
- if(!pushing && !iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves.
+ if(!pushing && !iscarbon(user) && !(SEND_SIGNAL(user, COMSIG_CHECK_VENTCRAWL))) //only carbon and ventcrawlers can climb into disposal by themselves.
if(iscyborg(user))
var/mob/living/silicon/robot/borg = user
if (!borg.module || !borg.module.canDispose)
diff --git a/tgstation.dme b/tgstation.dme
index bac0ffbdd3..4d4274bf54 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -609,6 +609,7 @@
#include "code\datums\elements\tactical.dm"
#include "code\datums\elements\update_icon_blocker.dm"
#include "code\datums\elements\update_icon_updates_onmob.dm"
+#include "code\datums\elements\ventcrawling.dm"
#include "code\datums\elements\wuv.dm"
#include "code\datums\helper_datums\events.dm"
#include "code\datums\helper_datums\getrev.dm"