diff --git a/beestation.dme b/beestation.dme index 0eba7be95547f..01cc550d0e2cf 100644 --- a/beestation.dme +++ b/beestation.dme @@ -825,6 +825,7 @@ #include "code\datums\elements\light_blocking.dm" #include "code\datums\elements\mechanical_repair.dm" #include "code\datums\elements\mirage_border.dm" +#include "code\datums\elements\movetype_handler.dm" #include "code\datums\elements\obj_regen.dm" #include "code\datums\elements\openspace_item_click_handler.dm" #include "code\datums\elements\pet_bonus.dm" diff --git a/code/__DEFINES/dcs/signals/signals_movable.dm b/code/__DEFINES/dcs/signals/signals_movable.dm index 077ef19d0b78d..f89b79dad4d27 100644 --- a/code/__DEFINES/dcs/signals/signals_movable.dm +++ b/code/__DEFINES/dcs/signals/signals_movable.dm @@ -63,3 +63,12 @@ #define COMSIG_STORAGE_ENTERED "storage_entered" ///from base of atom/movable/on_exit_storage(): (datum/component/storage/concrete/master_storage) #define COMSIG_STORAGE_EXITED "storage_exited" + +// /datum/element/movetype_handler signals +/// Called when the floating anim has to be temporarily stopped and restarted later: (timer) +#define COMSIG_PAUSE_FLOATING_ANIM "pause_floating_anim" +/// From base of datum/element/movetype_handler/on_movement_type_trait_gain: (flag) +#define COMSIG_MOVETYPE_FLAG_ENABLED "movetype_flag_enabled" +/// From base of datum/element/movetype_handler/on_movement_type_trait_loss: (flag) +#define COMSIG_MOVETYPE_FLAG_DISABLED "movetype_flag_disabled" + diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 5f17209e041d1..338abf737e3ab 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -523,3 +523,18 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Trait for psyphoza, flag for examine logic #define TRAIT_PSYCHIC_SENSE "psychic_sense" + +///Movement type traits for movables. See elements/movetype_handler.dm +#define TRAIT_MOVE_GROUND "move_ground" +#define TRAIT_MOVE_FLYING "move_flying" +#define TRAIT_MOVE_VENTCRAWLING "move_ventcrawling" +#define TRAIT_MOVE_FLOATING "move_floating" +#define TRAIT_MOVE_PHASING "move_phasing" +/// Disables the floating animation. See above. +#define TRAIT_NO_FLOATING_ANIM "no-floating-animation" + +#define VENTCRAWLING_TRAIT "ventcrawling" +#define SPECIES_FLIGHT_TRAIT "species-flight" +#define NO_GRAVITY_TRAIT "no-gravity" +#define LIFECANDLE_TRAIT "lifecandle" +#define LEAPER_BUBBLE_TRAIT "leaper-bubble" diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index de8e170d4db26..bd77f0b85bb23 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -139,6 +139,13 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_DOOR_PRYER" = TRAIT_DOOR_PRYER, "TRAIT_FISH_SAFE_STORAGE" = TRAIT_FISH_SAFE_STORAGE, "TRAIT_FISH_CASE_COMPATIBILE" = TRAIT_FISH_CASE_COMPATIBILE + ), + /atom/movable = list( + "TRAIT_MOVE_GROUND" = TRAIT_MOVE_GROUND, + "TRAIT_MOVE_FLYING" = TRAIT_MOVE_FLYING, + "TRAIT_MOVE_VENTCRAWLING" = TRAIT_MOVE_VENTCRAWLING, + "TRAIT_MOVE_FLOATING" = TRAIT_MOVE_FLOATING, + "TRAIT_MOVE_PHASING" = TRAIT_MOVE_PHASING ) )) @@ -151,3 +158,25 @@ GLOBAL_LIST(trait_name_map) for(var/tname in GLOB.traits_by_type[key]) var/val = GLOB.traits_by_type[key][tname] .[val] = tname + + +GLOBAL_LIST_INIT(movement_type_trait_to_flag, list( + TRAIT_MOVE_GROUND = GROUND, + TRAIT_MOVE_FLYING = FLYING, + TRAIT_MOVE_VENTCRAWLING = VENTCRAWLING, + TRAIT_MOVE_FLOATING = FLOATING, + TRAIT_MOVE_PHASING = PHASING + )) + +GLOBAL_LIST_INIT(movement_type_addtrait_signals, set_movement_type_addtrait_signals()) +GLOBAL_LIST_INIT(movement_type_removetrait_signals, set_movement_type_removetrait_signals()) + +/proc/set_movement_type_addtrait_signals(signal_prefix) + . = list() + for(var/trait in GLOB.movement_type_trait_to_flag) + . += SIGNAL_ADDTRAIT(trait) + +/proc/set_movement_type_removetrait_signals(signal_prefix) + . = list() + for(var/trait in GLOB.movement_type_trait_to_flag) + . += SIGNAL_REMOVETRAIT(trait) diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm index 4c0b708a0be17..b884e4ab248b9 100644 --- a/code/datums/components/caltrop.dm +++ b/code/datums/components/caltrop.dm @@ -55,7 +55,7 @@ if(!(flags & CALTROP_BYPASS_SHOES) && (H.shoes || feetCover)) return - if((H.movement_type & FLYING) || (H.body_position == LYING_DOWN)|| H.buckled) + if((H.movement_type & (FLYING|FLOATING)) || (H.body_position == LYING_DOWN)|| H.buckled) return var/damage = rand(min_damage, max_damage) diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm index 2838e70c19450..f0423eab57bbd 100644 --- a/code/datums/components/chasm.dm +++ b/code/datums/components/chasm.dm @@ -69,7 +69,7 @@ return FALSE if(!isliving(AM) && !isobj(AM)) return FALSE - if(is_type_in_typecache(AM, forbidden_types) || AM.throwing || (AM.movement_type & FLOATING)) + if(is_type_in_typecache(AM, forbidden_types) || AM.throwing || (AM.movement_type & (FLOATING|FLYING))) return FALSE //Flies right over the chasm if(ismob(AM)) @@ -78,8 +78,6 @@ var/mob/buckled_to = M.buckled if((!ismob(M.buckled) || (buckled_to.buckled != M)) && !droppable(M.buckled)) return FALSE - if(M.is_flying()) - return FALSE if(ishuman(AM)) var/mob/living/carbon/human/H = AM if(istype(H.belt, /obj/item/wormhole_jaunter)) diff --git a/code/datums/elements/movetype_handler.dm b/code/datums/elements/movetype_handler.dm new file mode 100644 index 0000000000000..4c3cdec336e14 --- /dev/null +++ b/code/datums/elements/movetype_handler.dm @@ -0,0 +1,107 @@ +/** + * An element that enables and disables movetype bitflags as movetype traits are added and removed. + * It also handles the +2/-2 pixel y anim loop typical of mobs possessing the FLYING or FLOATING movetypes. + * This element is necessary for the TRAIT_MOVE_ traits to work correctly. So make sure to include it when + * manipulating those traits on non-living movables. + */ +/datum/element/movetype_handler + element_flags = ELEMENT_DETACH + + var/list/attached_atoms = list() + var/list/paused_floating_anim_atoms = list() + +/datum/element/movetype_handler/Attach(datum/target) + . = ..() + if(!ismovable(target)) + return ELEMENT_INCOMPATIBLE + if(attached_atoms[target]) //Already attached. + return + + var/atom/movable/movable_target = target + RegisterSignals(movable_target, GLOB.movement_type_addtrait_signals, .proc/on_movement_type_trait_gain) + RegisterSignals(movable_target, GLOB.movement_type_removetrait_signals, .proc/on_movement_type_trait_loss) + RegisterSignal(movable_target, SIGNAL_ADDTRAIT(TRAIT_NO_FLOATING_ANIM), .proc/on_no_floating_anim_trait_gain) + RegisterSignal(movable_target, SIGNAL_REMOVETRAIT(TRAIT_NO_FLOATING_ANIM), .proc/on_no_floating_anim_trait_loss) + RegisterSignal(movable_target, COMSIG_PAUSE_FLOATING_ANIM, .proc/pause_floating_anim) + attached_atoms[movable_target] = TRUE + + if(movable_target.movement_type & (FLOATING|FLYING) && !HAS_TRAIT(movable_target, TRAIT_NO_FLOATING_ANIM)) + float(movable_target) + +/datum/element/movetype_handler/Detach(datum/source) + UnregisterSignal(source, GLOB.movement_type_addtrait_signals) + UnregisterSignal(source, GLOB.movement_type_removetrait_signals) + UnregisterSignal(source, SIGNAL_ADDTRAIT(TRAIT_NO_FLOATING_ANIM)) + UnregisterSignal(source, SIGNAL_REMOVETRAIT(TRAIT_NO_FLOATING_ANIM)) + UnregisterSignal(source, COMSIG_PAUSE_FLOATING_ANIM) + attached_atoms -= source + paused_floating_anim_atoms -= source + stop_floating(source) + return ..() + +/// Called when a movement type trait is added to the movable. Enables the relative bitflag. +/datum/element/movetype_handler/proc/on_movement_type_trait_gain(atom/movable/source, trait) + SIGNAL_HANDLER + var/flag = GLOB.movement_type_trait_to_flag[trait] + if(source.movement_type & flag) + return + if(!(source.movement_type & (FLOATING|FLYING)) && (trait == TRAIT_MOVE_FLYING || trait == TRAIT_MOVE_FLOATING) && !paused_floating_anim_atoms[source] && !HAS_TRAIT(source, TRAIT_NO_FLOATING_ANIM)) + float(source) + source.movement_type |= flag + SEND_SIGNAL(source, COMSIG_MOVETYPE_FLAG_ENABLED, flag) + +/// Called when a movement type trait is removed from the movable. Disables the relative bitflag if it wasn't there in the compile-time bitfield. +/datum/element/movetype_handler/proc/on_movement_type_trait_loss(atom/movable/source, trait) + SIGNAL_HANDLER + var/flag = GLOB.movement_type_trait_to_flag[trait] + if(initial(source.movement_type) & flag) + return + source.movement_type &= ~flag + if((trait == TRAIT_MOVE_FLYING || trait == TRAIT_MOVE_FLOATING) && !(source.movement_type & (FLOATING|FLYING))) + stop_floating(source) + SEND_SIGNAL(source, COMSIG_MOVETYPE_FLAG_DISABLED, flag) + +/// Called when the TRAIT_NO_FLOATING_ANIM trait is added to the movable. Stops it from bobbing up and down. +/datum/element/movetype_handler/proc/on_no_floating_anim_trait_gain(atom/movable/source, trait) + SIGNAL_HANDLER + stop_floating(source) + +/// Called when the TRAIT_NO_FLOATING_ANIM trait is removed from the mob. Restarts the bobbing animation. +/datum/element/movetype_handler/proc/on_no_floating_anim_trait_loss(atom/movable/source, trait) + SIGNAL_HANDLER + if(source.movement_type & (FLOATING|FLYING) && !paused_floating_anim_atoms[source]) + float(source) + +///Pauses the floating animation for the duration of the timer... plus [tickrate - (world.time + timer) % tickrate] to be precise. +/datum/element/movetype_handler/proc/pause_floating_anim(atom/movable/source, timer) + SIGNAL_HANDLER + if(paused_floating_anim_atoms[source] < world.time + timer) + stop_floating(source) + if(!length(paused_floating_anim_atoms)) + START_PROCESSING(SSdcs, src) //1 second tickrate. + paused_floating_anim_atoms[source] = world.time + timer + +/datum/element/movetype_handler/process() + for(var/_paused in paused_floating_anim_atoms) + var/atom/movable/paused = _paused + if(!paused) + paused_floating_anim_atoms -= paused + else if(paused_floating_anim_atoms[paused] < world.time) + if(paused.movement_type & (FLOATING|FLYING) && !HAS_TRAIT(paused, TRAIT_NO_FLOATING_ANIM)) + float(paused) + paused_floating_anim_atoms -= paused + if(!length(paused_floating_anim_atoms)) + STOP_PROCESSING(SSdcs, src) + +///Floats the movable up and down. Not a comsig proc. +/datum/element/movetype_handler/proc/float(atom/movable/target) + animate(target, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + animate(pixel_y = -2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) + +/// Stops the above. Also not a comsig proc. +/datum/element/movetype_handler/proc/stop_floating(atom/movable/target) + var/final_pixel_y = target.base_pixel_y + if(isliving(target)) //Living mobs also have a 'body_position_pixel_y_offset' variable that has to be taken into account here. + var/mob/living/living_target = target + final_pixel_y += living_target.body_position_pixel_y_offset + animate(target, pixel_y = final_pixel_y, time = 1 SECONDS) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index ef28dc34e9189..0b5be56586805 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -38,8 +38,13 @@ var/datum/movement_packet/move_packet var/list/acted_explosions //for explosion dodging var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm - ///In case you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc. Should only be changed through setMovetype() + /** + * In case you have multiple types, you automatically use the most useful one. + * IE: Skating on ice, flippers on water, flying over chasm/space, etc. + * I reccomend you use the movetype_handler system and not modify this directly, especially for living mobs. + */ var/movement_type = GROUND + var/atom/movable/pulling var/grab_state = 0 var/throwforce = 0 @@ -665,14 +670,6 @@ Moved(oldloc, NONE, TRUE) -///Proc to modify the movement_type and hook behavior associated with it changing. -/atom/movable/proc/setMovetype(newval) - if(movement_type == newval) - return - . = movement_type - movement_type = newval - - //Called whenever an object moves and by mobs when they attempt to move themselves through space //And when an object or action applies a force on src, see newtonian_move() below //Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting @@ -908,8 +905,8 @@ var/matrix/initial_transform = matrix(transform) var/matrix/rotated_transform = transform.Turn(rand(13,17) * turn_dir) - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform=rotated_transform, time = 1, easing=BACK_EASING|EASE_IN) - animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform=initial_transform, time = 2, easing=SINE_EASING) + animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform=rotated_transform, time = 1, easing=BACK_EASING|EASE_IN, flags = ANIMATION_PARALLEL) + animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform=initial_transform, time = 2, easing=SINE_EASING, flags = ANIMATION_PARALLEL) /atom/movable/proc/do_item_attack_animation(atom/A, visual_effect_icon, obj/item/used_item) var/image/I @@ -1008,17 +1005,6 @@ acted_explosions += ex_id return TRUE -//TODO: Better floating -/atom/movable/proc/float(on) - if(throwing) - return - if(on && !(movement_type & FLOATING)) - animate(src, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) - animate(pixel_y = -2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) - setMovetype(movement_type | FLOATING) - else if (!on && (movement_type & FLOATING)) - animate(src, pixel_y = base_pixel_y, time = 10) - setMovetype(movement_type & ~FLOATING) /* Language procs * Unless you are doing something very specific, these are the ones you want to use. */ diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 72188002f4287..c67151e3a4ccc 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -108,6 +108,10 @@ if (!check_loc && M.loc != loc) M.forceMove(loc) + if(anchored) + ADD_TRAIT(M, TRAIT_NO_FLOATING_ANIM, BUCKLED_TRAIT) + if(!length(buckled_mobs)) + RegisterSignal(src, COMSIG_MOVABLE_SET_ANCHORED, .proc/on_set_anchored) M.set_buckled(src) M.setDir(dir) buckled_mobs |= M @@ -153,10 +157,25 @@ buckled_mob.clear_alert("buckled") //buckled_mob.set_glide_size(DELAY_TO_GLIDE_SIZE(buckled_mob.total_multiplicative_slowdown())) buckled_mobs -= buckled_mob + if(anchored) + REMOVE_TRAIT(buckled_mob, TRAIT_NO_FLOATING_ANIM, BUCKLED_TRAIT) + if(!length(buckled_mobs)) + UnregisterSignal(src, COMSIG_MOVABLE_SET_ANCHORED, .proc/on_set_anchored) SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force) post_unbuckle_mob(.) +/atom/movable/proc/on_set_anchored(atom/movable/source, anchorvalue) + SIGNAL_HANDLER + for(var/_buckled_mob in buckled_mobs) + if(!_buckled_mob) + continue + var/mob/living/buckled_mob = _buckled_mob + if(anchored) + ADD_TRAIT(buckled_mob, TRAIT_NO_FLOATING_ANIM, BUCKLED_TRAIT) + else + REMOVE_TRAIT(buckled_mob, TRAIT_NO_FLOATING_ANIM, BUCKLED_TRAIT) + /atom/movable/proc/unbuckle_all_mobs(force=FALSE) if(!has_buckled_mobs()) diff --git a/code/game/objects/structures/life_candle.dm b/code/game/objects/structures/life_candle.dm index 83a562ace450b..40a7079e5a7de 100644 --- a/code/game/objects/structures/life_candle.dm +++ b/code/game/objects/structures/life_candle.dm @@ -24,6 +24,10 @@ var/respawn_time = 50 var/respawn_sound = 'sound/magic/staff_animation.ogg' +/obj/structure/life_candle/ComponentInitialize() + . = ..() + AddElement(/datum/element/movetype_handler) + /obj/structure/life_candle/attack_hand(mob/user) . = ..() if(.) @@ -33,12 +37,15 @@ if(user.mind in linked_minds) user.visible_message("[user] reaches out and pinches the flame of [src].", "You sever the connection between yourself and [src].") linked_minds -= user.mind + if(!linked_minds.len) + REMOVE_TRAIT(src, TRAIT_MOVE_FLOATING, LIFECANDLE_TRAIT) else user.visible_message("[user] touches [src]. It seems to respond to [user.p_their()] presence!", "You create a connection between you and [src].") linked_minds |= user.mind + if(!linked_minds.len) + ADD_TRAIT(src, TRAIT_MOVE_FLOATING, LIFECANDLE_TRAIT) update_icon() - float(linked_minds.len) if(linked_minds.len) START_PROCESSING(SSobj, src) set_light(lit_luminosity) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index c77f6d58ce261..b4cac583e2998 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1213,6 +1213,8 @@ Traitors and the like can also be revived with the previous role mostly intact. var/source = "adminabuse" switch(add_or_remove) if("Add") //Not doing source choosing here intentionally to make this bit faster to use, you can always vv it. + if(GLOB.movement_type_trait_to_flag[chosen_trait]) //include the required element. + D.AddElement(/datum/element/movetype_handler) ADD_TRAIT(D,chosen_trait,source) if("Remove") var/specific = input("All or specific source ?", "Trait Remove/Add") as null|anything in list("All","Specific") diff --git a/code/modules/antagonists/blob/blob_mobs.dm b/code/modules/antagonists/blob/blob_mobs.dm index d2e8650552041..7007f73a83b67 100644 --- a/code/modules/antagonists/blob/blob_mobs.dm +++ b/code/modules/antagonists/blob/blob_mobs.dm @@ -107,7 +107,7 @@ attack_verb_continuous = "hits" attack_verb_simple = "hit" attack_sound = 'sound/weapons/genhit1.ogg' - movement_type = FLYING + is_flying_animal = TRUE del_on_death = TRUE deathmessage = "explodes into a cloud of gas!" gold_core_spawnable = HOSTILE_SPAWN diff --git a/code/modules/antagonists/clock_cult/mobs/clockwork_marauder.dm b/code/modules/antagonists/clock_cult/mobs/clockwork_marauder.dm index 3e0490b4b8b51..de535c8d1b666 100644 --- a/code/modules/antagonists/clock_cult/mobs/clockwork_marauder.dm +++ b/code/modules/antagonists/clock_cult/mobs/clockwork_marauder.dm @@ -16,7 +16,7 @@ GLOBAL_LIST_EMPTY(clockwork_marauders) 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 maxbodytemp = INFINITY - movement_type = FLYING + is_flying_animal = TRUE move_resist = MOVE_FORCE_OVERPOWERING mob_size = MOB_SIZE_LARGE pass_flags = PASSTABLE diff --git a/code/modules/antagonists/clock_cult/mobs/eminence.dm b/code/modules/antagonists/clock_cult/mobs/eminence.dm index 5dbc2d84ff6ce..da36f6bc44349 100644 --- a/code/modules/antagonists/clock_cult/mobs/eminence.dm +++ b/code/modules/antagonists/clock_cult/mobs/eminence.dm @@ -24,7 +24,7 @@ status_flags = 0 wander = FALSE density = FALSE - movement_type = FLYING + is_flying_animal = TRUE move_resist = MOVE_FORCE_OVERPOWERING mob_size = MOB_SIZE_TINY pass_flags = PASSTABLE | PASSGRILLE | PASSMOB diff --git a/code/modules/antagonists/clock_cult/traps/receivers/skewer.dm b/code/modules/antagonists/clock_cult/traps/receivers/skewer.dm index d951eb4e22e5f..d9d66ea55c9f4 100644 --- a/code/modules/antagonists/clock_cult/traps/receivers/skewer.dm +++ b/code/modules/antagonists/clock_cult/traps/receivers/skewer.dm @@ -27,7 +27,7 @@ var/target_stabbed = FALSE density = TRUE for(var/mob/living/M in get_turf(src)) - if(M.incorporeal_move || M.is_flying()) + if(M.incorporeal_move || M.movement_type & (FLOATING|FLYING)) continue if(buckle_mob(M, TRUE)) target_stabbed = TRUE diff --git a/code/modules/antagonists/clock_cult/traps/senders/pressure_sensor.dm b/code/modules/antagonists/clock_cult/traps/senders/pressure_sensor.dm index 159afb8ace32e..e4b55981a9328 100644 --- a/code/modules/antagonists/clock_cult/traps/senders/pressure_sensor.dm +++ b/code/modules/antagonists/clock_cult/traps/senders/pressure_sensor.dm @@ -34,7 +34,7 @@ if(istype(M)) if(is_servant_of_ratvar(M)) return - if(M.incorporeal_move || M.is_flying()) + if(M.incorporeal_move || M.movement_type & (FLOATING|FLYING)) return else return diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index 4dcd3d8d278b0..eabcfff265400 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -43,7 +43,7 @@ status_flags = 0 wander = FALSE density = FALSE - movement_type = FLYING + is_flying_animal = TRUE move_resist = MOVE_FORCE_OVERPOWERING mob_size = MOB_SIZE_TINY pass_flags = PASSTABLE | PASSMOB diff --git a/code/modules/holoparasite/_holoparasite.dm b/code/modules/holoparasite/_holoparasite.dm index 30c7e5f0eb9bf..1872d2191de10 100644 --- a/code/modules/holoparasite/_holoparasite.dm +++ b/code/modules/holoparasite/_holoparasite.dm @@ -25,7 +25,7 @@ GLOBAL_LIST_EMPTY_TYPED(holoparasites, /mob/living/simple_animal/hostile/holopar light_on = FALSE a_intent = INTENT_HARM stop_automated_movement = TRUE - movement_type = FLYING // Immunity to chasms and landmines, etc. + is_flying_animal = TRUE // Immunity to chasms and landmines, etc. attack_sound = "punch" 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 diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm index 2b01cd25a1ddd..5d06cca10e6b6 100644 --- a/code/modules/mining/equipment/wormhole_jaunter.dm +++ b/code/modules/mining/equipment/wormhole_jaunter.dm @@ -50,7 +50,7 @@ try_move_adjacent(J) else user.Paralyze(2 SECONDS, TRUE, TRUE) //Ignore stun immunity here, for their own good - user.setMovetype(user.movement_type | FLOATING) //Prevents falling into chasm during delay, automatically removed upon movement + ADD_TRAIT(user, TRAIT_MOVE_FLOATING, "jaunter") //Prevents falling into chasm during delay, automatically removed upon movement addtimer(CALLBACK(J, TYPE_PROC_REF(/atom, attackby), null, user), 1 SECONDS) //Forcibly teleport them away from the chasm after a brief dramatic delay playsound(src,'sound/effects/sparks4.ogg',50,1) qdel(src) diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index e853c16df621a..2101a9406c67f 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -140,7 +140,6 @@ icon = initial(icon) icon_state = icon_living density = initial(density) - setMovetype(initial(movement_type)) /mob/living/basic/proc/melee_attack(atom/target) src.face_atom(target) diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index 1b024ec6aa2b5..96cb3c54cc149 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -87,8 +87,3 @@ if(leaping) //check that toggles out of leaping mode if the alien gets hit or otherwise interrupted leaping = FALSE update_icons() - -/mob/living/carbon/alien/humanoid/float(on) - if(leaping) - return - return ..() diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm index 33b556e736336..dcf4439f0018a 100644 --- a/code/modules/mob/living/carbon/carbon_movement.dm +++ b/code/modules/mob/living/carbon/carbon_movement.dm @@ -56,17 +56,17 @@ if(!usable_legs && !(movement_type & (FLYING | FLOATING))) ADD_TRAIT(src, TRAIT_IMMOBILIZED, LACKING_LOCOMOTION_APPENDAGES_TRAIT) +/mob/living/carbon/on_movement_type_flag_enabled(datum/source, flag) + var/old_movetype = movement_type + . = ..() + if(flag & (FLYING | FLOATING) && !(old_movetype & (FLYING | FLOATING))) + remove_movespeed_modifier(/datum/movespeed_modifier/limbless) + REMOVE_TRAIT(src, TRAIT_FLOORED, LACKING_LOCOMOTION_APPENDAGES_TRAIT) + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, LACKING_LOCOMOTION_APPENDAGES_TRAIT) -/mob/living/carbon/setMovetype(newval) +/mob/living/carbon/on_movement_type_flag_disabled(datum/source, flag) . = ..() - if(isnull(.)) - return - if(!(. & (FLYING | FLOATING))) - if(movement_type & (FLYING | FLOATING)) //From not flying to flying. - remove_movespeed_modifier(/datum/movespeed_modifier/limbless) - REMOVE_TRAIT(src, TRAIT_FLOORED, LACKING_LOCOMOTION_APPENDAGES_TRAIT) - REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, LACKING_LOCOMOTION_APPENDAGES_TRAIT) - else if(!(movement_type & (FLYING | FLOATING))) //From flying to no longer flying. + if(flag & (FLYING | FLOATING) && !(movement_type & (FLYING | FLOATING))) var/limbless_slowdown = 0 if(usable_legs < default_num_legs) limbless_slowdown += (default_num_legs - usable_legs) * 3 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 7372fb37f1ef1..090928d713575 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -811,11 +811,6 @@ /mob/living/carbon/human/can_hold_items() return TRUE -/mob/living/carbon/human/update_gravity(has_gravity,override = 0) - if(dna && dna.species) //prevents a runtime while a human is being monkeyfied - override = dna.species.override_float - ..() - /mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0) if(blood && (NOBLOOD in dna.species.species_traits)) if(message) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 8874bad02caff..ec07a513434e7 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -101,7 +101,6 @@ GLOBAL_LIST_EMPTY(features_by_species) var/obj/item/organ/liver/mutantliver var/obj/item/organ/stomach/mutantstomach - var/override_float = FALSE //Bitflag that controls what in game ways can select this species as a spawnable source //Think magic mirror and pride mirror, slime extract, ERT etc, see defines @@ -2346,19 +2345,17 @@ GLOBAL_LIST_EMPTY(features_by_species) //UNSAFE PROC, should only be called through the Activate or other sources that check for CanFly /datum/species/proc/toggle_flight(mob/living/carbon/human/H) - if(!(H.movement_type & FLYING)) + if(!HAS_TRAIT_FROM(H, TRAIT_MOVE_FLYING, SPECIES_FLIGHT_TRAIT)) stunmod *= 2 speedmod -= 0.35 - H.setMovetype(H.movement_type | FLYING) - override_float = TRUE + ADD_TRAIT(H, TRAIT_MOVE_FLYING, SPECIES_FLIGHT_TRAIT) H.pass_flags |= PASSTABLE if(("wings" in H.dna.species.mutant_bodyparts) || ("moth_wings" in H.dna.species.mutant_bodyparts)) H.Togglewings() else stunmod *= 0.5 speedmod += 0.35 - H.setMovetype(H.movement_type & ~FLYING) - override_float = FALSE + REMOVE_TRAIT(H, TRAIT_MOVE_FLYING, SPECIES_FLIGHT_TRAIT) H.pass_flags &= ~PASSTABLE if(("wingsopen" in H.dna.species.mutant_bodyparts) || ("moth_wingsopen" in H.dna.species.mutant_bodyparts)) H.Togglewings() diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm index 505201504141c..a02ae4866236f 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/update_icons.dm @@ -21,8 +21,8 @@ resize = RESIZE_DEFAULT_SIZE if(changed) + SEND_SIGNAL(src, COMSIG_PAUSE_FLOATING_ANIM, 0.3 SECONDS) animate(src, transform = ntransform, time = (lying_prev == 0 || lying_angle == 0) ? 2 : 0, pixel_y = final_pixel_y, dir = final_dir, easing = (EASE_IN|EASE_OUT)) - setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life(). UPDATE_OO_IF_PRESENT /mob/living/carbon diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm index 108570a584da3..87efcb9654173 100644 --- a/code/modules/mob/living/init_signals.dm +++ b/code/modules/mob/living/init_signals.dm @@ -38,6 +38,9 @@ SIGNAL_REMOVETRAIT(TRAIT_NODEATH), ), PROC_REF(update_succumb_action)) + RegisterSignal(src, COMSIG_MOVETYPE_FLAG_ENABLED, .proc/on_movement_type_flag_enabled) + RegisterSignal(src, COMSIG_MOVETYPE_FLAG_DISABLED, .proc/on_movement_type_flag_disabled) + ///Called when TRAIT_KNOCKEDOUT is added to the mob. /mob/living/proc/on_knockedout_trait_gain(datum/source) SIGNAL_HANDLER @@ -173,3 +176,13 @@ throw_alert("succumb", /atom/movable/screen/alert/succumb) else clear_alert("succumb") + +///From [element/movetype_handler/on_movement_type_trait_gain()] +/mob/living/proc/on_movement_type_flag_enabled(datum/source, trait) + SIGNAL_HANDLER + update_movespeed(FALSE) + +///From [element/movetype_handler/on_movement_type_trait_loss()] +/mob/living/proc/on_movement_type_flag_disabled(datum/source, trait) + SIGNAL_HANDLER + update_movespeed(FALSE) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index f3e618c29e544..b98d460e29a1f 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -7,9 +7,6 @@ SEND_SIGNAL(src, COMSIG_LIVING_LIFE, delta_time, times_fired) - if((movement_type & FLYING) && !(movement_type & FLOATING)) //TODO: Better floating - float(on = TRUE) - if (notransform) return if(!loc) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index caf4b857864ca..6b0b1c9268d8b 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -25,6 +25,10 @@ //color correction RegisterSignal(src, COMSIG_MOVABLE_ENTERED_AREA, PROC_REF(apply_color_correction)) +/mob/living/ComponentInitialize() + . = ..() + AddElement(/datum/element/movetype_handler) + /mob/living/prepare_huds() ..() prepare_data_huds() @@ -932,10 +936,11 @@ /mob/living/proc/get_visible_name() return name -/mob/living/update_gravity(has_gravity, override) +/mob/living/update_gravity(has_gravity) . = ..() if(!SSticker.HasRoundStarted()) return + var/was_weightless = alerts["gravity"] && istype(alerts["gravity"], /atom/movable/screen/alert/weightless) if(has_gravity) if(has_gravity == 1) clear_alert("gravity") @@ -944,24 +949,12 @@ throw_alert("gravity", /atom/movable/screen/alert/veryhighgravity) else throw_alert("gravity", /atom/movable/screen/alert/highgravity) + if(was_weightless) + REMOVE_TRAIT(src, TRAIT_MOVE_FLOATING, NO_GRAVITY_TRAIT) else throw_alert("gravity", /atom/movable/screen/alert/weightless) - if(!override && !is_flying()) - float(!has_gravity) - -/mob/living/float(on) - if(throwing) - return - var/fixed = 0 - if(anchored || (buckled && buckled.anchored)) - fixed = 1 - if(on && !(movement_type & FLOATING) && !fixed) - animate(src, pixel_y = base_pixel_y + 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) - animate(pixel_y = base_pixel_y - 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE) - setMovetype(movement_type | FLOATING) - else if(((!on || fixed) && (movement_type & FLOATING))) - animate(src, pixel_y = base_pixel_y + body_position_pixel_y_offset, time = 1 SECONDS) - setMovetype(movement_type & ~FLOATING) + if(!was_weightless) + ADD_TRAIT(src, TRAIT_MOVE_FLOATING, NO_GRAVITY_TRAIT) // The src mob is trying to strip an item from someone // Override if a certain type of mob should be behave differently when stripping items (can't, for example) @@ -1030,7 +1023,7 @@ var/matrix/reset_matrix = matrix() reset_matrix.Turn(-5) // Offset animation - animate(src, time = 1, pixel_x = rand(-2, 2), pixel_y = rand(-1, 1), easing = ELASTIC_EASING, flags = ANIMATION_RELATIVE) + animate(src, time = 1, pixel_x = rand(-2, 2), pixel_y = rand(-1, 1), easing = ELASTIC_EASING, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL) for (var/i in 1 to 4) var/dx = rand(-4, 2) var/dy = rand(-4, 2) @@ -1048,11 +1041,8 @@ var/amplitude = min(4, (jitteriness/100) + 1) var/pixel_x_diff = rand(-amplitude, amplitude) var/pixel_y_diff = rand(-amplitude/3, amplitude/3) - var/final_pixel_x = base_pixel_x + body_position_pixel_x_offset - var/final_pixel_y = base_pixel_y + body_position_pixel_y_offset - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6) - animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2) - setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life(). + animate(src, pixel_x = pixel_x_diff, pixel_y = pixel_y_diff , time = 2, loop = 6, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL) + animate(pixel_x = -pixel_x_diff , pixel_y = -pixel_y_diff , time = 2, flags = ANIMATION_RELATIVE) /mob/living/proc/get_temperature(datum/gas_mixture/environment) var/loc_temp = environment ? environment.return_temperature() : T0C diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index a34ecf210817b..3e02d5a4e4875 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -450,7 +450,6 @@ if(!used_item) used_item = get_active_held_item() ..() - setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement. /mob/living/extrapolator_act(mob/living/user, obj/item/extrapolator/extrapolator, dry_run = FALSE) . = ..() diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 0517752446447..fff6e77656b29 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -27,7 +27,7 @@ maxbodytemp = INFINITY healable = 0 faction = list("cult") - movement_type = FLYING + is_flying_animal = TRUE pressure_resistance = 100 unique_name = 1 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 fe890e42c6f3e..841c87de1c948 100644 --- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm +++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm @@ -17,7 +17,7 @@ friendly_verb_continuous = "nudges" friendly_verb_simple = "nudge" density = FALSE - movement_type = FLYING + is_flying_animal = TRUE pass_flags = PASSTABLE | PASSMOB ventcrawler = VENTCRAWLER_ALWAYS mob_size = MOB_SIZE_TINY diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index f83fc638d85e9..57fecbb17cdd1 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -44,7 +44,7 @@ density = FALSE mob_size = MOB_SIZE_TINY mob_biotypes = list(MOB_ORGANIC, MOB_BUG) - movement_type = FLYING + is_flying_animal = TRUE gold_core_spawnable = HOSTILE_SPAWN search_objects = 1 //have to find those plant trays! ventcrawler = VENTCRAWLER_ALWAYS diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index a88869e9eedac..b6679739954fb 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -38,7 +38,7 @@ minbodytemp = 0 maxbodytemp = 1500 faction = list("carp") - movement_type = FLYING + is_flying_animal = TRUE pressure_resistance = 200 gold_core_spawnable = HOSTILE_SPAWN diff --git a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm index 38eff231950a5..152b4e66c8109 100644 --- a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm +++ b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm @@ -23,7 +23,7 @@ attack_verb_continuous = "blinks at" attack_verb_simple = "blink at" attack_sound = 'sound/weapons/pierce.ogg' - movement_type = FLYING + is_flying_animal = TRUE faction = list("spooky") del_on_death = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index e12c6e9011f98..185508e1af543 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -81,13 +81,17 @@ /obj/structure/leaper_bubble/Initialize(mapload) . = ..() - float(on = TRUE) QDEL_IN(src, 100) var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_entered), ) AddElement(/datum/element/connect_loc, loc_connections) +/obj/structure/leaper_bubble/ComponentInitialize() + . = ..() + AddElement(/datum/element/movetype_handler) + ADD_TRAIT(src, TRAIT_MOVE_FLOATING, LEAPER_BUBBLE_TRAIT) + /obj/structure/leaper_bubble/Destroy() new /obj/effect/temp_visual/leaper_projectile_impact(get_turf(src)) playsound(src,'sound/effects/snap.ogg',50, 1, -1) 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 1ae92cf7d81dc..fb555e75d5c83 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -58,6 +58,10 @@ Difficulty: Very Hard small_sprite_type = /datum/action/small_sprite/megafauna/colossus var/invulnerable_finale = FALSE +/mob/living/simple_animal/hostile/megafauna/colossus/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, ROUNDSTART_TRAIT) //we don't want this guy to float, messes up his animations. + /datum/action/innate/megafauna_attack/spiral_attack name = "Spiral Shots" icon_icon = 'icons/mob/actions/actions_items.dmi' @@ -709,7 +713,7 @@ GLOBAL_DATUM(blackbox, /obj/machinery/smartfridge/black_box) friendly_verb_continuous = "mends" friendly_verb_simple = "mend" density = FALSE - movement_type = FLYING + is_flying_animal = TRUE pass_flags = PASSTABLE | PASSGRILLE | PASSMOB ventcrawler = VENTCRAWLER_ALWAYS mob_size = MOB_SIZE_TINY @@ -724,7 +728,6 @@ GLOBAL_DATUM(blackbox, /obj/machinery/smartfridge/black_box) faction = list("neutral") del_on_death = TRUE unsuitable_atmos_damage = 0 - movement_type = FLYING minbodytemp = 0 maxbodytemp = 1500 obj_damage = 0 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 90b948f3e0d15..8cfeb02215ed7 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -12,7 +12,7 @@ light_range = 3 faction = list("mining", "boss") weather_immunities = list("lava","ash") - movement_type = FLYING + is_flying_animal = TRUE robust_searching = TRUE ranged_ignores_vision = TRUE stat_attack = HARD_CRIT diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index 2617d977807f9..a7731786fb78a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -79,7 +79,7 @@ speak_emote = list("telepathically cries") attack_sound = 'sound/weapons/bladeslice.ogg' stat_attack = HARD_CRIT - movement_type = FLYING + is_flying_animal = TRUE robust_searching = 1 crusher_loot = /obj/item/crusher_trophy/watcher_wing loot = list() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm index a2d214b92fa6d..483fad157364a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm @@ -6,7 +6,7 @@ icon_living = "curseblob" icon_aggro = "curseblob" mob_biotypes = list(MOB_SPIRIT) - movement_type = FLYING + is_flying_animal = TRUE move_to_delay = 5 vision_range = 20 aggro_vision_range = 20 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm index 1f2e7a54654fb..6f0bdfcf37f7e 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/herald.dm @@ -195,7 +195,7 @@ icon_state = "herald_mirror" deathmessage = "shatters violently!" deathsound = 'sound/effects/glassbr1.ogg' - movement_type = FLYING + is_flying_animal = TRUE del_on_death = TRUE is_mirror = TRUE var/mob/living/simple_animal/hostile/asteroid/elite/herald/my_master = null diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index f0af72f7c10dc..674fba7ba4458 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -72,7 +72,7 @@ speed = 3 maxHealth = 1 health = 1 - movement_type = FLYING + is_flying_animal = TRUE melee_damage = 2 attack_verb_continuous = "slashes" attack_verb_simple = "slash" 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 2e7f3ee0990d8..73c3c5bc50c8b 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm @@ -27,7 +27,7 @@ environment_smash = ENVIRONMENT_SMASH_NONE ventcrawler = VENTCRAWLER_ALWAYS mob_size = MOB_SIZE_TINY - movement_type = FLYING + is_flying_animal = TRUE speak_emote = list("squeaks") var/max_co2 = 0 //to be removed once metastation map no longer use those for Sgt Araneus var/min_oxy = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm index f5149af8826f2..597842e87db3a 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm @@ -30,7 +30,7 @@ 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 maxbodytemp = 1500 - movement_type = FLYING + is_flying_animal = TRUE pressure_resistance = 300 gold_core_spawnable = NO_SPAWN //too spooky for science var/ghost_hair_style diff --git a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm index 661717fe758a5..327937ca85e11 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm @@ -55,7 +55,7 @@ maxbodytemp = 1500 faction = list("carp") pressure_resistance = 200 - movement_type = FLYING | FLOATING // fly so you can move without gravity, float so no animation applies + is_flying_animal = TRUE | FLOATING // fly so you can move without gravity, float so no animation applies /// How much endlag using Wing Gust should apply. Each use of wing gust increments this, and it decreases over time. var/tiredness = 0 /// A multiplier to how much each use of wing gust should add to the tiredness variable. Set to 5 if the current rift is destroyed. diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 19ff51965dd2b..dcc80d8464af9 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -292,7 +292,7 @@ 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 - movement_type = FLYING + is_flying_animal = TRUE limb_destroyer = TRUE speak_emote = list("states") bubble_icon = "syndibot" diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index fb9041a2c67f3..6b88ae9f0c990 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -67,7 +67,7 @@ friendly_verb_continuous = "grooms" friendly_verb_simple = "groom" mob_size = MOB_SIZE_SMALL - movement_type = FLYING + is_flying_animal = TRUE gold_core_spawnable = FRIENDLY_SPAWN chat_color = "#A6E398" mobchatspan = "curator" diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index 8bc330969caaf..fc0933635fbed 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -30,7 +30,7 @@ status_flags = 0 faction = list("cult") status_flags = CANPUSH - movement_type = FLYING + is_flying_animal = TRUE loot = list(/obj/item/ectoplasm) del_on_death = TRUE initial_language_holder = /datum/language_holder/construct diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 89fab3bd63b31..bc89221e8e418 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -99,6 +99,9 @@ var/dextrous = FALSE //If the creature has, and can use, hands var/dextrous_hud_type = /datum/hud/dextrous + ///If the creature should have an innate TRAIT_MOVE_FLYING trait added on init that is also toggled off/on on death/revival. + var/is_flying_animal = FALSE + var/AIStatus = AI_ON //The Status of our AI, can be changed via toggle_ai(togglestatus) to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players) var/can_have_ai = TRUE //once we have become sentient, we can never go back @@ -141,6 +144,8 @@ . = ..() if(dextrous) AddComponent(/datum/component/personal_crafting) + if(is_flying_animal) + ADD_TRAIT(src, TRAIT_MOVE_FLYING, ROUNDSTART_TRAIT) if(discovery_points) AddComponent(/datum/component/discoverable, discovery_points, get_discover_id = CALLBACK(src, PROC_REF(get_discovery_id))) @@ -159,6 +164,16 @@ return ..() +/mob/living/simple_animal/vv_edit_var(var_name, var_value) + . = ..() + switch(var_name) + if(NAMEOF(src, is_flying_animal)) + if(stat != DEAD) + if(!is_flying_animal) + REMOVE_TRAIT(src, TRAIT_MOVE_FLYING, ROUNDSTART_TRAIT) + else + ADD_TRAIT(src, TRAIT_MOVE_FLYING, ROUNDSTART_TRAIT) + /mob/living/simple_animal/examine(mob/user) . = ..() if(stat == DEAD) @@ -379,7 +394,6 @@ new i(loc) /mob/living/simple_animal/death(gibbed) - movement_type &= ~FLYING if(nest) nest.spawned_mobs -= src nest = null @@ -396,6 +410,8 @@ del_on_death = FALSE qdel(src) else + if(is_flying_animal) + REMOVE_TRAIT(src, TRAIT_MOVE_FLYING, ROUNDSTART_TRAIT) health = 0 icon_state = icon_dead if(flip_on_death) @@ -437,7 +453,8 @@ icon = initial(icon) icon_state = icon_living density = initial(density) - setMovetype(initial(movement_type)) + if(is_flying_animal) + ADD_TRAIT(src, TRAIT_MOVE_FLYING, ROUNDSTART_TRAIT) /mob/living/simple_animal/proc/make_babies() // <3 <3 <3 set waitfor = 0 diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index 0fd5f65ae1d0e..34a30f59b160a 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -102,7 +102,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list( A.pipe_vision_img.plane = ABOVE_HUD_PLANE client.images += A.pipe_vision_img pipes_shown += A.pipe_vision_img - setMovetype(movement_type | VENTCRAWLING) + ADD_TRAIT(src, TRAIT_MOVE_VENTCRAWLING, VENTCRAWLING_TRAIT) /mob/living/proc/remove_ventcrawl() @@ -110,7 +110,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list( for(var/image/current_image in pipes_shown) client.images -= current_image pipes_shown.len = 0 - setMovetype(movement_type & ~VENTCRAWLING) + REMOVE_TRAIT(src, TRAIT_MOVE_VENTCRAWLING, VENTCRAWLING_TRAIT) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index db43fd25105f0..b272ad7106b3e 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1249,12 +1249,6 @@ /mob/proc/set_nutrition(var/change) //Seriously fuck you oldcoders. nutrition = max(0, change) -/mob/setMovetype(newval) //Set the movement type of the mob and update it's movespeed - . = ..() - if(isnull(.)) - return - update_movespeed(FALSE) - /mob/proc/update_equipment_speed_mods() var/speedies = equipped_speed_mods() if(!speedies) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index f9c46bdedf7c4..209d811c6726c 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -520,13 +520,6 @@ message_admins("No ghosts were willing to take control of [ADMIN_LOOKUPFLW(M)])") return FALSE -///Is the mob a flying mob -/mob/proc/is_flying(mob/M = src) - if(M.movement_type & FLYING) - return 1 - else - return 0 - ///Clicks a random nearby mob with the source from this mob /mob/proc/click_random_mob() var/list/nearby_mobs = list() diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index eca93f0723ede..5edb0bbf147ad 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -182,7 +182,7 @@ var/turf/T = get_turf(owner) if(!T) // No more runtimes from being stuck in nullspace. return 0 - if(owner.is_flying() && owner.has_gravity()) + if((owner.movement_type & (FLOATING|FLYING)) && owner.has_gravity()) return 0 // Priority 1: use air from environment. var/datum/gas_mixture/environment = T.return_air()