diff --git a/code/__HELPERS/paths/path.dm b/code/__HELPERS/paths/path.dm
index 706bd6e4cf2..5e33353c005 100644
--- a/code/__HELPERS/paths/path.dm
+++ b/code/__HELPERS/paths/path.dm
@@ -359,7 +359,7 @@
src.can_ventcrawl = living_construct.ventcrawler == VENTCRAWLER_ALWAYS || living_construct.ventcrawler == VENTCRAWLER_NUDE
src.mob_size = living_construct.mob_size
src.incorporeal_move = living_construct.incorporeal_move
- is_flying = living_construct.flying
+ is_flying = HAS_TRAIT(living_construct, TRAIT_FLYING)
if(iscameramob(construct_from))
src.camera_type = construct_from.type
src.is_bot = isbot(construct_from)
diff --git a/code/__HELPERS/trait_helpers.dm b/code/__HELPERS/trait_helpers.dm
index 241da8e9fcb..beea1ae000f 100644
--- a/code/__HELPERS/trait_helpers.dm
+++ b/code/__HELPERS/trait_helpers.dm
@@ -237,6 +237,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_NPC_ZOMBIE "npc_zombie" // A trait for checking if a zombie should act like an NPC and attack
#define TRAIT_ABSTRACT_HANDS "abstract_hands" // Mobs with this trait can only pick up abstract items.
#define TRAIT_LANGUAGE_LOCKED "language_locked" // cant add/remove languages until removed (excludes babel because fuck everything i guess)
+#define TRAIT_FLYING "flying"
//***** MIND TRAITS *****/
#define TRAIT_HOLY "is_holy" // The mob is holy in regards to religion
@@ -412,3 +413,12 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
//***** EFFECT TRAITS *****//
// Causes the effect to go through a teleporter instead of being deleted by it.
#define TRAIT_EFFECT_CAN_TELEPORT "trait_effect_can_teleport"
+
+//***** PROC WRAPPERS *****//
+/// Proc wrapper of add_trait. You should only use this for callback. Otherwise, use the macro.
+/proc/callback_add_trait(datum/target, trait, source)
+ ADD_TRAIT(target, trait, source)
+
+/// Proc wrapper of remove_trait. You should only use this for callback. Otherwise, use the macro.
+/proc/callback_remove_trait(datum/target, trait, source)
+ REMOVE_TRAIT(target, trait, source)
diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm
index bca3cc8056a..de94b8dfe93 100644
--- a/code/datums/components/caltrop.dm
+++ b/code/datums/components/caltrop.dm
@@ -65,7 +65,7 @@
if(bypass_shoes && ((H?.shoes?.flags & THICKMATERIAL) || (H?.wear_suit?.flags & THICKMATERIAL)))
return
- if(H.flying || H.floating || H.buckled)
+ if(HAS_TRAIT(H, TRAIT_FLYING) || H.floating || H.buckled)
return
if(IS_HORIZONTAL(H) && HAS_TRAIT(H, TRAIT_CONTORTED_BODY))
diff --git a/code/datums/components/footstep.dm b/code/datums/components/footstep.dm
index 5903c1b669d..1784f8f05fa 100644
--- a/code/datums/components/footstep.dm
+++ b/code/datums/components/footstep.dm
@@ -53,7 +53,7 @@
return
var/mob/living/LM = parent
- if(!T.footstep || !(LM.mobility_flags & MOBILITY_MOVE) || LM.buckled || LM.throwing || LM.flying || istype(LM.loc, /obj/machinery/atmospherics))
+ if(!T.footstep || !(LM.mobility_flags & MOBILITY_MOVE) || LM.buckled || LM.throwing || HAS_TRAIT(LM, TRAIT_FLYING) || istype(LM.loc, /obj/machinery/atmospherics))
return
steps++
diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm
index 4488c8dcb83..bc7b0e05f8a 100644
--- a/code/datums/components/slippery.dm
+++ b/code/datums/components/slippery.dm
@@ -51,7 +51,7 @@
Additionally calls the parent's `after_slip()` proc on the `victim`.
*/
/datum/component/slippery/proc/Slip(datum/source, mob/living/carbon/human/victim)
- if(istype(victim) && !victim.flying)
+ if(istype(victim) && !HAS_TRAIT(victim, TRAIT_FLYING))
var/atom/movable/owner = parent
if(!isturf(owner.loc))
return
diff --git a/code/datums/components/squeak.dm b/code/datums/components/squeak.dm
index 908ab5130f9..47a94d7e69d 100644
--- a/code/datums/components/squeak.dm
+++ b/code/datums/components/squeak.dm
@@ -78,7 +78,7 @@
return
if(ismob(crossing))
var/mob/M = crossing
- if(M.flying)
+ if(HAS_TRAIT(M, TRAIT_FLYING))
return
if(isliving(crossing))
var/mob/living/L = M
@@ -94,7 +94,7 @@
return
if(ismob(source))
var/mob/M = source
- if(M.flying)
+ if(HAS_TRAIT(M, TRAIT_FLYING))
return
if(isliving(source))
var/mob/living/L = M
diff --git a/code/datums/weather/weather_types/floor_is_lava.dm b/code/datums/weather/weather_types/floor_is_lava.dm
index 0233e0aee71..6cb2202593f 100644
--- a/code/datums/weather/weather_types/floor_is_lava.dm
+++ b/code/datums/weather/weather_types/floor_is_lava.dm
@@ -35,7 +35,7 @@
return
if(!L.client) //Only sentient people are going along with it!
return
- if(L.flying)
+ if(HAS_TRAIT(L, TRAIT_FLYING))
return
L.adjustFireLoss(3)
diff --git a/code/game/dna/mutations/mutation_powers.dm b/code/game/dna/mutations/mutation_powers.dm
index 9cdd0861b68..75efba0c78a 100644
--- a/code/game/dna/mutations/mutation_powers.dm
+++ b/code/game/dna/mutations/mutation_powers.dm
@@ -542,10 +542,9 @@
"You hear the flexing of powerful muscles and suddenly a crash as a body hits the floor.")
return FALSE
var/prevLayer = user.layer
- var/prevFlying = user.flying
user.layer = 9
- user.flying = TRUE
+ ADD_TRAIT(user, TRAIT_FLYING, "leap")
for(var/i in 1 to leap_distance)
var/turf/hit_turf = get_step(user, user.dir)
var/atom/hit_atom = get_blocking_atom(hit_turf)
@@ -560,7 +559,7 @@
user.pixel_y -= 8
sleep(1)
- user.flying = prevFlying
+ REMOVE_TRAIT(user, TRAIT_FLYING, "leap")
user.pixel_y = 0 // In case leap was varedited to be longer or shorter
if(HAS_TRAIT(user, TRAIT_FAT) && prob(66))
diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm
index a306b41eb32..d0a50fc3ee1 100644
--- a/code/game/gamemodes/miniantags/guardian/guardian.dm
+++ b/code/game/gamemodes/miniantags/guardian/guardian.dm
@@ -16,7 +16,6 @@
a_intent = INTENT_HARM
can_change_intents = FALSE
stop_automated_movement = TRUE
- flying = TRUE
attack_sound = 'sound/weapons/punch1.ogg'
minbodytemp = 0
maxbodytemp = INFINITY
@@ -31,6 +30,7 @@
AIStatus = AI_OFF
butcher_results = list(/obj/item/food/ectoplasm = 1)
hud_type = /datum/hud/guardian
+ initial_traits = list(TRAIT_FLYING)
var/summoned = FALSE
var/cooldown = 0
var/damage_transfer = 1 //how much damage from each attack we transfer to the owner
diff --git a/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm b/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm
index e05efa0c74a..904a3f5b6de 100644
--- a/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm
+++ b/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm
@@ -36,7 +36,6 @@
maxHealth = 50
health = 50
speed = -0.5
- flying = TRUE
mob_size = MOB_SIZE_TINY
density = FALSE
del_on_death = TRUE
@@ -53,6 +52,7 @@
// this makes the demon able to speak through holopads, due to the overriden say, PD cannot speak normally regardless
universal_speak = TRUE
loot = list(/obj/item/organ/internal/heart/demon/pulse)
+ initial_traits = list(TRAIT_FLYING)
/// List of sounds that is picked from when the demon speaks.
var/list/speech_sounds = list("sound/voice/pdvoice1.ogg", "sound/voice/pdvoice2.ogg", "sound/voice/pdvoice3.ogg")
diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm
index 7fd74c37372..904cc49d3b0 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant.dm
@@ -31,11 +31,11 @@
status_flags = 0
wander = FALSE
density = FALSE
- flying = TRUE
move_resist = INFINITY
mob_size = MOB_SIZE_TINY
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
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)
+ initial_traits = list(TRAIT_FLYING)
/// The revenant's idle icon
var/icon_idle = "revenant_idle"
diff --git a/code/game/gamemodes/wizard/magic_tarot.dm b/code/game/gamemodes/wizard/magic_tarot.dm
index 1bf82da346d..992ddf86336 100644
--- a/code/game/gamemodes/wizard/magic_tarot.dm
+++ b/code/game/gamemodes/wizard/magic_tarot.dm
@@ -475,10 +475,10 @@
card_icon = "the_hanged_man"
/datum/tarot/the_hanged_man/activate(mob/living/target)
- if(target.flying)
+ if(HAS_TRAIT(target, TRAIT_FLYING))
return
- target.flying = TRUE
- addtimer(VARSET_CALLBACK(target, flying, FALSE), 60 SECONDS)
+ ADD_TRAIT(target, TRAIT_FLYING, "tarot")
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(callback_remove_trait), target, TRAIT_FLYING, "tarot"), 60 SECONDS)
/datum/tarot/death
name = "XIII - Death"
diff --git a/code/game/objects/effects/alien_acid.dm b/code/game/objects/effects/alien_acid.dm
index 86c1c0c2c73..afc114502d5 100644
--- a/code/game/objects/effects/alien_acid.dm
+++ b/code/game/objects/effects/alien_acid.dm
@@ -53,7 +53,7 @@
/obj/effect/acid/Crossed(AM as mob|obj)
if(isliving(AM))
var/mob/living/L = AM
- if(L.flying)
+ if(HAS_TRAIT(L, TRAIT_FLYING))
return
if(L.m_intent != MOVE_INTENT_WALK && prob(40))
var/acid_used = min(acid_level * 0.05, 20)
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index 08b657be0ed..756be876e05 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -16,7 +16,7 @@
var/mob/living/M = AM
if(faction && (faction in M.faction))
return
- if(M.flying)
+ if(HAS_TRAIT(M, TRAIT_FLYING))
return
triggermine(M)
diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm
index f816d7c8dd5..593c5bdee7d 100644
--- a/code/game/objects/items/weapons/legcuffs.dm
+++ b/code/game/objects/items/weapons/legcuffs.dm
@@ -102,7 +102,7 @@
return ..()
var/mob/living/L = AM
- if((iscarbon(AM) || isanimal(AM)) && !L.flying)
+ if((iscarbon(AM) || isanimal(AM)) && HAS_TRAIT(L, TRAIT_FLYING))
spring_trap(AM)
if(ishuman(AM))
diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm
index ce0a5893285..7f25b42f760 100644
--- a/code/game/objects/items/weapons/shards.dm
+++ b/code/game/objects/items/weapons/shards.dm
@@ -72,7 +72,7 @@
/obj/item/shard/Crossed(mob/living/L, oldloc)
if(istype(L) && has_gravity(loc))
- if(L.incorporeal_move || L.flying || L.floating)
+ if(L.incorporeal_move || HAS_TRAIT(L, TRAIT_FLYING) || L.floating)
return
playsound(loc, 'sound/effects/glass_step.ogg', 50, TRUE)
return ..()
diff --git a/code/game/objects/items/weapons/staff.dm b/code/game/objects/items/weapons/staff.dm
index 255b2d4cfe1..8da6c38f2d7 100644
--- a/code/game/objects/items/weapons/staff.dm
+++ b/code/game/objects/items/weapons/staff.dm
@@ -34,7 +34,7 @@
user.update_inv_l_hand()
user.update_inv_r_hand()
if(iswizard(user))
- user.flying = TRUE
+ ADD_TRAIT(user, TRAIT_FLYING, "broomstick")
user.say("QUID 'ITCH")
animate(user, pixel_y = pixel_y + 10 , time = 10, loop = 1, easing = SINE_EASING)
to_chat(user, "You hold [src] between your legs.")
@@ -44,6 +44,7 @@
user.update_inv_l_hand()
user.update_inv_r_hand()
if(iswizard(user))
+ REMOVE_TRAIT(user, TRAIT_FLYING, "broomstick")
animate(user, pixel_y = pixel_y + 10 , time = 1, loop = 1)
animate(user, pixel_y = pixel_y, time = 10, loop = 1, easing = SINE_EASING)
animate(user)
@@ -58,8 +59,7 @@
..()
/obj/item/staff/broom/dropped(mob/user)
- if(iswizard(user) && user.flying)
- user.flying = FALSE
+ REMOVE_TRAIT(user, TRAIT_FLYING, "broomstick")
..()
/obj/item/staff/broom/horsebroom
diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm
index 37e590e40c3..437fa7ddc6e 100644
--- a/code/game/objects/structures/railings.dm
+++ b/code/game/objects/structures/railings.dm
@@ -106,7 +106,7 @@
return TRUE
if(ismob(mover))
var/mob/living/M = mover
- if(M.flying || (istype(M) && IS_HORIZONTAL(M) && HAS_TRAIT(M, TRAIT_CONTORTED_BODY)))
+ if(HAS_TRAIT(M, TRAIT_FLYING) || (istype(M) && IS_HORIZONTAL(M) && HAS_TRAIT(M, TRAIT_CONTORTED_BODY)))
return TRUE
if(mover.throwing)
return TRUE
@@ -133,7 +133,7 @@
if(isprojectile(O))
return TRUE
if(istype(M))
- if(M.flying || M.floating || (IS_HORIZONTAL(M) && HAS_TRAIT(M, TRAIT_CONTORTED_BODY)))
+ if(HAS_TRAIT(M, TRAIT_FLYING) || M.floating || (IS_HORIZONTAL(M) && HAS_TRAIT(M, TRAIT_CONTORTED_BODY)))
return TRUE
if(O.throwing)
return TRUE
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 42723b2d039..60ec516c939 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -140,7 +140,7 @@
if(istype(mover,/obj/item/projectile))
return (check_cover(mover,target))
var/mob/living/living_mover = mover
- if(istype(living_mover) && (living_mover.flying || (IS_HORIZONTAL(living_mover) && HAS_TRAIT(living_mover, TRAIT_CONTORTED_BODY))))
+ if(istype(living_mover) && (HAS_TRAIT(living_mover, TRAIT_FLYING) || (IS_HORIZONTAL(living_mover) && HAS_TRAIT(living_mover, TRAIT_CONTORTED_BODY))))
return TRUE
if(istype(mover) && mover.checkpass(PASSTABLE))
return TRUE
@@ -484,7 +484,7 @@
if(!isliving(AM))
return
var/mob/living/L = AM
- if(L.incorporeal_move || L.flying || L.floating)
+ if(L.incorporeal_move || HAS_TRAIT(L, TRAIT_FLYING) || L.floating)
return
// Don't break if they're just flying past
diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm
index 53cf6694f5e..303e8d5b6ef 100644
--- a/code/game/turfs/simulated.dm
+++ b/code/game/turfs/simulated.dm
@@ -124,7 +124,7 @@
if(IS_HORIZONTAL(M))
return 1
- if(M.flying)
+ if(HAS_TRAIT(M, TRAIT_FLYING))
return ..()
switch(src.wet)
diff --git a/code/game/turfs/simulated/floor/chasm.dm b/code/game/turfs/simulated/floor/chasm.dm
index 61be5dd4a8b..86e26e198ed 100644
--- a/code/game/turfs/simulated/floor/chasm.dm
+++ b/code/game/turfs/simulated/floor/chasm.dm
@@ -130,7 +130,7 @@
//Flies right over the chasm
if(isliving(AM))
var/mob/living/M = AM
- if(M.flying || M.floating)
+ if(HAS_TRAIT(M, TRAIT_FLYING) || M.floating)
return FALSE
if(istype(M.buckled, /obj/tgvehicle/scooter/skateboard/hoverboard))
return FALSE
@@ -273,10 +273,10 @@
playsound(ourturf, 'sound/effects/bang.ogg', 50, TRUE)
ourturf.visible_message("[escapee] busts through [ourturf], leaping out of the chasm below!")
ourturf.ChangeTurf(ourturf.baseturf)
- escapee.flying = TRUE
+ ADD_TRAIT(escapee, TRAIT_FLYING, "chasm_escape")
escapee.forceMove(ourturf)
escapee.throw_at(get_edge_target_turf(ourturf, pick(GLOB.alldirs)), rand(2, 10), rand(2, 10))
- escapee.flying = FALSE
+ REMOVE_TRAIT(escapee, TRAIT_FLYING, "chasm_escape")
escapee.Sleeping(20 SECONDS)
/turf/simulated/floor/chasm/straight_down/lava_land_surface/normal_air
diff --git a/code/game/turfs/simulated/floor/lava.dm b/code/game/turfs/simulated/floor/lava.dm
index d28d298fa55..2eab0b2fb0d 100644
--- a/code/game/turfs/simulated/floor/lava.dm
+++ b/code/game/turfs/simulated/floor/lava.dm
@@ -96,7 +96,7 @@
else if(isliving(thing))
. = TRUE
var/mob/living/L = thing
- if(L.flying)
+ if(HAS_TRAIT(L, TRAIT_FLYING))
continue //YOU'RE FLYING OVER IT
var/buckle_check = L.buckling
if(!buckle_check)
@@ -221,7 +221,7 @@
continue
. = TRUE
var/mob/living/burn_living = thing
- if(burn_living.flying)
+ if(HAS_TRAIT(burn_living, TRAIT_FLYING))
continue //YOU'RE FLYING OVER IT
var/buckle_check = burn_living.buckling
if(!buckle_check)
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index c89d736091d..3d445c09ede 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -341,11 +341,8 @@
return
var/atom/target = get_edge_target_turf(user, user.dir) //gets the user's direction
- var/do_callback = FALSE
- if(!user.flying)
- user.flying = TRUE
- do_callback = TRUE
- if(user.throw_at(target, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE, callback = do_callback ? VARSET_CALLBACK(user, flying, FALSE) : null))
+ ADD_TRAIT(user, TRAIT_FLYING, "gravity_boots")
+ if(user.throw_at(target, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE, callback = CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(callback_remove_trait), user, TRAIT_FLYING, "gravity_boots")))
playsound(src, 'sound/effects/stealthoff.ogg', 50, TRUE, 1)
user.visible_message("[usr] dashes forward into the air!")
recharging_time = world.time + recharging_rate
diff --git a/code/modules/clothing/shoes/misc_shoes.dm b/code/modules/clothing/shoes/misc_shoes.dm
index 5c66cd8382d..a40b0bba0c2 100644
--- a/code/modules/clothing/shoes/misc_shoes.dm
+++ b/code/modules/clothing/shoes/misc_shoes.dm
@@ -472,11 +472,8 @@
return
var/atom/target = get_edge_target_turf(user, user.dir) //gets the user's direction
- var/do_callback = FALSE
- if(!user.flying)
- user.flying = TRUE
- do_callback = TRUE
- if(user.throw_at(target, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE, callback = do_callback ? VARSET_CALLBACK(user, flying, FALSE) : null))
+ ADD_TRAIT(user, TRAIT_FLYING, "bhop_shoes")
+ if(user.throw_at(target, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE, callback = CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(callback_remove_trait), user, TRAIT_FLYING, "bhop_shoes")))
playsound(src, 'sound/effects/stealthoff.ogg', 50, TRUE, 1)
user.visible_message("[usr] dashes forward into the air!")
recharging_time = world.time + recharging_rate
diff --git a/code/modules/events/blob/blob_mobs.dm b/code/modules/events/blob/blob_mobs.dm
index ab4beb39ab5..8640bbbd4e3 100644
--- a/code/modules/events/blob/blob_mobs.dm
+++ b/code/modules/events/blob/blob_mobs.dm
@@ -67,7 +67,7 @@
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
attacktext = "hits"
attack_sound = 'sound/weapons/genhit1.ogg'
- flying = TRUE
+ initial_traits = list(TRAIT_FLYING)
speak_emote = list("pulses")
var/obj/structure/blob/factory/factory = null
var/list/human_overlays = list()
diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm
index f47f059515e..def0e5c7c20 100644
--- a/code/modules/mining/lavaland/loot/colossus_loot.dm
+++ b/code/modules/mining/lavaland/loot/colossus_loot.dm
@@ -261,7 +261,7 @@
harm_intent_damage = 1
friendly = "mends"
density = FALSE
- flying = TRUE
+ initial_traits = list(TRAIT_FLYING)
obj_damage = 0
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
ventcrawler = VENTCRAWLER_ALWAYS
diff --git a/code/modules/mob/living/carbon/carbon_procs.dm b/code/modules/mob/living/carbon/carbon_procs.dm
index f276e626313..6c31a070b01 100644
--- a/code/modules/mob/living/carbon/carbon_procs.dm
+++ b/code/modules/mob/living/carbon/carbon_procs.dm
@@ -1048,7 +1048,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/carbon/proc/slip(description, knockdown, tilesSlipped, walkSafely, slipAny, slipVerb = "slip")
- if(flying || buckled || (walkSafely && m_intent == MOVE_INTENT_WALK))
+ if(HAS_TRAIT(src, TRAIT_FLYING) || buckled || (walkSafely && m_intent == MOVE_INTENT_WALK))
return FALSE
if(IS_HORIZONTAL(src) && !tilesSlipped)
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index 69a4db2e47a..263b8f947df 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -293,7 +293,7 @@
if(HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN))
ignoreslow = TRUE
- var/flight = H.flying //Check for flight and flying items
+ var/flight = HAS_TRAIT(H, TRAIT_FLYING) //Check for flight and flying items
ADD_SLOWDOWN(speed_mod)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index af5aa80a835..22b318ff3b2 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -9,6 +9,9 @@
if(advanced_bullet_dodge_chance)
RegisterSignal(src, COMSIG_ATOM_PREHIT, PROC_REF(advanced_bullet_dodge))
+ for(var/initial_trait in initial_traits)
+ ADD_TRAIT(src, initial_trait, INNATE_TRAIT)
+
// Used to determine the forces dependend on the mob size
// Will only change the force if the force was not set in the mob type itself
/mob/living/proc/determine_move_and_pull_forces()
@@ -824,7 +827,7 @@
clear_alert("weightless")
else
throw_alert("weightless", /atom/movable/screen/alert/weightless)
- if(!flying)
+ if(!HAS_TRAIT(src, TRAIT_FLYING))
float(!has_gravity)
/mob/living/proc/float(on)
@@ -1112,7 +1115,7 @@
return ..()
/mob/living/hit_by_thrown_mob(mob/living/C, datum/thrownthing/throwingdatum, damage, mob_hurt, self_hurt)
- if(C == src || flying || !density)
+ if(C == src || HAS_TRAIT(src, TRAIT_FLYING) || !density)
return
playsound(src, 'sound/weapons/punch1.ogg', 50, 1)
if(mob_hurt)
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 2661102fef4..56427c70ef2 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -105,6 +105,9 @@
///This variable is the chance for a mob to automatically dodge a bullet. Useful for admins, and applied to some mobs by default, such as the malfunctioning drone mobs.
var/advanced_bullet_dodge_chance = 0
+ /// List of traits that should be applied on Initialize
+ var/list/initial_traits = list()
+
/*
Taste Vars
*/
diff --git a/code/modules/mob/living/living_life.dm b/code/modules/mob/living/living_life.dm
index afba51de5a4..ebd0c6781e5 100644
--- a/code/modules/mob/living/living_life.dm
+++ b/code/modules/mob/living/living_life.dm
@@ -2,7 +2,7 @@
set waitfor = FALSE
set invisibility = 0
- if(flying && !floating) //TODO: Better floating
+ if(HAS_TRAIT(src, TRAIT_FLYING) && !floating) //TODO: Better floating
float(TRUE)
if(client || registered_z) // This is a temporary error tracker to make sure we've caught everything
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index cdb8d9cb000..906518cb941 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -18,7 +18,6 @@
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
faction = list("cult")
- flying = TRUE
pressure_resistance = 100
universal_speak = TRUE
AIStatus = AI_OFF //normal constructs don't have AI
diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm
index ba878cd423e..e928fd850a8 100644
--- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm
+++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm
@@ -16,17 +16,13 @@
harm_intent_damage = 1
friendly = "nudges"
density = FALSE
- flying = TRUE
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
ventcrawler = VENTCRAWLER_ALWAYS
mob_size = MOB_SIZE_TINY
mob_biotypes = MOB_ORGANIC | MOB_BUG
butcher_results = list(/obj/item/food/meat = 0)
gold_core_spawnable = FRIENDLY_SPAWN
-
-/mob/living/simple_animal/butterfly/Initialize(mapload) //Not the poor butterfly!
- . = ..()
- ADD_TRAIT(src, TRAIT_EDIBLE_BUG, "edible_bug")
+ initial_traits = list(TRAIT_FLYING, TRAIT_EDIBLE_BUG)
/mob/living/simple_animal/butterfly/New()
..()
diff --git a/code/modules/mob/living/simple_animal/hostile/bat.dm b/code/modules/mob/living/simple_animal/hostile/bat.dm
index 1604aab392e..b51af42343d 100644
--- a/code/modules/mob/living/simple_animal/hostile/bat.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bat.dm
@@ -17,7 +17,6 @@
maxHealth = 20
health = 20
mob_size = MOB_SIZE_TINY
- flying = TRUE
harm_intent_damage = 8
melee_damage_lower = 10
melee_damage_upper = 10
@@ -35,6 +34,8 @@
faction = list("scarybat")
gold_core_spawnable = HOSTILE_SPAWN
+ initial_traits = list(TRAIT_FLYING)
+
/mob/living/simple_animal/hostile/scarybat/Initialize(mapload, mob/living/L)
. = ..()
if(istype(L))
diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm
index 5d05c17c5eb..dd9b7433f8f 100644
--- a/code/modules/mob/living/simple_animal/hostile/bees.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bees.dm
@@ -34,7 +34,6 @@
density = FALSE
mob_size = MOB_SIZE_TINY
mob_biotypes = MOB_ORGANIC | MOB_BUG
- flying = TRUE
gold_core_spawnable = HOSTILE_SPAWN
search_objects = TRUE //have to find those plant trays!
@@ -43,6 +42,8 @@
minbodytemp = 0
del_on_death = TRUE
+ initial_traits = list(TRAIT_FLYING)
+
var/datum/reagent/beegent = null //hehe, beegent
var/obj/structure/beebox/beehome = null
var/idle = 0
diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm
index 2f402fbe444..ff1588298fe 100644
--- a/code/modules/mob/living/simple_animal/hostile/carp.dm
+++ b/code/modules/mob/living/simple_animal/hostile/carp.dm
@@ -34,10 +34,11 @@
minbodytemp = 0
maxbodytemp = 1500
faction = list("carp")
- flying = TRUE
pressure_resistance = 200
gold_core_spawnable = HOSTILE_SPAWN
+ initial_traits = list(TRAIT_FLYING, TRAIT_SHOCKIMMUNE)
+
var/random_color = TRUE //if the carp uses random coloring
var/rarechance = 1 //chance for rare color variant
@@ -63,7 +64,6 @@
/mob/living/simple_animal/hostile/carp/Initialize(mapload)
. = ..()
- ADD_TRAIT(src, TRAIT_SHOCKIMMUNE, SPECIES_TRAIT)
carp_randomify(rarechance)
update_icons()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/ancient_robot.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/ancient_robot.dm
index 75b18ec3ea1..07def89e330 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/ancient_robot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/ancient_robot.dm
@@ -631,7 +631,6 @@ Difficulty: Hard
weather_immunities = list("lava","ash")
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
- flying = TRUE
check_friendly_fire = 1
ranged = TRUE
projectilesound = 'sound/weapons/gunshots/gunshot.ogg'
@@ -652,6 +651,7 @@ Difficulty: Hard
ranged_ignores_vision = TRUE
stat_attack = UNCONSCIOUS
maxbodytemp = INFINITY
+ initial_traits = list(TRAIT_FLYING)
var/range = 3
var/mob/living/simple_animal/hostile/megafauna/ancient_robot/core = null
var/fake_max_hp = 300
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
index ad8b1f7becb..400e87cc01d 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
@@ -30,7 +30,6 @@ Difficulty: Medium
icon = 'icons/mob/lavaland/blood_drunk.dmi'
mob_biotypes = MOB_ORGANIC | MOB_HUMANOID
light_color = "#E4C7C5"
- flying = FALSE
speak_emote = list("roars")
speed = 3
move_to_delay = 3
@@ -61,6 +60,8 @@ Difficulty: Medium
/datum/action/innate/megafauna_attack/kinetic_accelerator,
/datum/action/innate/megafauna_attack/transform_weapon)
+ initial_traits = list() // Don't want to inherit flight from parent type /megafauna/
+
/obj/item/gps/internal/miner
icon_state = null
gpstag = "Resonant Signal"
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index 18739b9e6ea..29f5fb08039 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -11,7 +11,6 @@
light_range = 3
faction = list("mining", "boss")
weather_immunities = list("lava","ash")
- flying = TRUE
robust_searching = TRUE
ranged_ignores_vision = TRUE
stat_attack = DEAD
@@ -29,6 +28,7 @@
flags_2 = IMMUNE_TO_SHUTTLECRUSH_2
mouse_opacity = MOUSE_OPACITY_ICON
dodging = FALSE // This needs to be false until someone fixes megafauna pathing so they dont lag-switch teleport at you (09-15-2023)
+ initial_traits = list(TRAIT_FLYING)
var/list/crusher_loot
var/medal_type
var/score_type = BOSS_SCORE
diff --git a/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm
index 5fd8f200321..f5514b40fbc 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining/basilisk.dm
@@ -81,11 +81,11 @@
speak_emote = list("telepathically cries")
attack_sound = 'sound/weapons/bladeslice.ogg'
stat_attack = UNCONSCIOUS
- flying = TRUE
robust_searching = TRUE
crusher_loot = /obj/item/crusher_trophy/watcher_wing
loot = list()
butcher_results = list(/obj/item/stack/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1)
+ initial_traits = list(TRAIT_FLYING)
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/magmawing
name = "magmawing watcher"
diff --git a/code/modules/mob/living/simple_animal/hostile/mining/elites/herald.dm b/code/modules/mob/living/simple_animal/hostile/mining/elites/herald.dm
index 6b2611e196e..395e32f4157 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining/elites/herald.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining/elites/herald.dm
@@ -209,8 +209,8 @@
del_on_death = TRUE
is_mirror = TRUE
move_resist = MOVE_FORCE_OVERPOWERING // no dragging your mirror around
- flying = TRUE
var/mob/living/simple_animal/hostile/asteroid/elite/herald/my_master = null
+ initial_traits = list(TRAIT_FLYING)
/mob/living/simple_animal/hostile/asteroid/elite/herald/mirror/Initialize(mapload)
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
index 02f2d897d5e..a16ab19c136 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
@@ -74,7 +74,6 @@
speed = 3
maxHealth = 1
health = 1
- flying = TRUE
harm_intent_damage = 5
melee_damage_lower = 2
melee_damage_upper = 2
@@ -87,13 +86,13 @@
pass_flags = PASSTABLE | PASSMOB
density = FALSE
del_on_death = TRUE
+ initial_traits = list(TRAIT_FLYING)
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Initialize(mapload)
. = ..()
addtimer(CALLBACK(src, PROC_REF(death)), 100)
AddComponent(/datum/component/swarming)
-
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood
name = "blood brood"
desc = "A living string of blood and alien materials."
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm
index eafb92e7dab..c9696fd0879 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm
@@ -24,7 +24,7 @@
attack_sound = 'sound/weapons/bite.ogg'
speak_emote = list("gnashes")
faction = list("carp")
- flying = TRUE
+ initial_traits = list(TRAIT_FLYING)
var/carp_color = "carp" //holder for icon set
var/static/list/carp_colors = list(\
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm
index 1b9db4ba39a..da8df5e98d7 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm
@@ -29,13 +29,14 @@
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
- flying = TRUE
pressure_resistance = 300
gold_core_spawnable = NO_SPAWN //too spooky for science
faction = list("undead") // did I mention ghost
loot = list(/obj/item/food/ectoplasm)
del_on_death = TRUE
+ initial_traits = list(TRAIT_FLYING)
+
/mob/living/simple_animal/hostile/retaliate/ghost/Process_Spacemove(check_drift = 0)
return 1
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm b/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm
index c4a887baf23..3021c468cbd 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate_mobs.dm
@@ -411,12 +411,13 @@
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_size = MOB_SIZE_TINY
- flying = TRUE
bubble_icon = "syndibot"
gold_core_spawnable = HOSTILE_SPAWN
del_on_death = TRUE
deathmessage = "is smashed into pieces!"
+ initial_traits = list(TRAIT_FLYING)
+
/mob/living/simple_animal/hostile/viscerator/Initialize(mapload)
. = ..()
AddComponent(/datum/component/swarming)
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 3d34ba45718..4968aabfb45 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -84,7 +84,7 @@
//Parrots are kleptomaniacs. This variable ... stores the item a parrot is holding.
var/obj/item/held_item = null
- flying = TRUE
+ initial_traits = list(TRAIT_FLYING)
gold_core_spawnable = FRIENDLY_SPAWN
/mob/living/simple_animal/parrot/New()
diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm
index 54cd08666f0..8129b49d1c8 100644
--- a/code/modules/mob/living/simple_animal/shade.dm
+++ b/code/modules/mob/living/simple_animal/shade.dm
@@ -27,10 +27,10 @@
universal_speak = TRUE
faction = list("cult")
status_flags = CANPUSH
- flying = TRUE
loot = list(/obj/item/food/ectoplasm)
del_on_death = TRUE
deathmessage = "lets out a contented sigh as their form unwinds."
+ initial_traits = list(TRAIT_FLYING, TRAIT_SHOCKIMMUNE)
var/holy = FALSE
/mob/living/simple_animal/shade/attackby(obj/item/O, mob/user) //Marker -Agouri
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index b819db355e0..8ce7b533a7d 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -194,7 +194,7 @@
return
/*
- * String associated list returns a cached list.
+ * String associated list returns a cached list.
* This is like a static list to pass into the element below.
*/
atmos_requirements = string_assoc_list(atmos_requirements)
@@ -354,7 +354,8 @@
icon = initial(icon)
icon_state = icon_living
density = initial(density)
- flying = initial(flying)
+ if(TRAIT_FLYING in initial_traits)
+ ADD_TRAIT(src, TRAIT_FLYING, INNATE_TRAIT)
if(collar_type)
collar_type = "[initial(collar_type)]"
regenerate_icons()
@@ -364,7 +365,7 @@
. = ..()
if(!.)
return FALSE
- flying = FALSE
+ REMOVE_TRAIT(src, TRAIT_FLYING, INNATE_TRAIT)
walk(src, 0)
if(nest)
nest.spawned_mobs -= src
diff --git a/code/modules/mob/mob_vars.dm b/code/modules/mob/mob_vars.dm
index eb1416b550b..ba6fbbbb7ef 100644
--- a/code/modules/mob/mob_vars.dm
+++ b/code/modules/mob/mob_vars.dm
@@ -63,7 +63,6 @@
var/timeofdeath = 0 //Living
var/bodytemperature = 310.055 //98.7 F
- var/flying = FALSE
var/nutrition = NUTRITION_LEVEL_FED + 50 //Carbon
var/satiety = 0 //Carbon
var/hunger_drain = HUNGER_FACTOR // how quickly the mob gets hungry; largely utilized by species.
diff --git a/code/modules/power/lights.dm b/code/modules/power/lights.dm
index 0728db514bc..74780dc48b7 100644
--- a/code/modules/power/lights.dm
+++ b/code/modules/power/lights.dm
@@ -907,7 +907,7 @@
/obj/item/light/Crossed(mob/living/L)
if(istype(L) && has_gravity(loc))
- if(L.incorporeal_move || L.flying || L.floating)
+ if(L.incorporeal_move || HAS_TRAIT(L, TRAIT_FLYING) || L.floating)
return
playsound(loc, 'sound/effects/glass_step.ogg', 50, TRUE)
if(status == LIGHT_BURNED || status == LIGHT_OK)
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index ff2a5af0b70..73b40012795 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -185,7 +185,7 @@
if(!istype(H) || !H.reagents || HAS_TRAIT(H, TRAIT_PIERCEIMMUNE) || ismachineperson(H))
return
- if(H.floating || H.flying || H.buckled)
+ if(H.floating || HAS_TRAIT(H, TRAIT_FLYING) || H.buckled)
return
if(!IS_HORIZONTAL(H) && (H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET))))