mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-31 09:08:30 +01:00
[MIRROR] Refactors how movetypes are added and removed, No timers this time. (#2358)
* Refactors how movetypes are added and removed, No timers this time. (#55444) * Refactors how movetypes are added and removed, No timers this time. Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
@@ -887,6 +887,14 @@
|
||||
///from base of datum/component/two_handed/proc/unwield(mob/living/carbon/user): (/mob/user)
|
||||
#define COMSIG_TWOHANDED_UNWIELD "twohanded_unwield"
|
||||
|
||||
// /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"
|
||||
|
||||
// /datum/action signals
|
||||
|
||||
///from base of datum/action/proc/Trigger(): (datum/action)
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
target.status_traits = list(); \
|
||||
_L = target.status_traits; \
|
||||
_L[trait] = list(source); \
|
||||
SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait)); \
|
||||
SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait), trait); \
|
||||
} else { \
|
||||
_L = target.status_traits; \
|
||||
if (_L[trait]) { \
|
||||
_L[trait] |= list(source); \
|
||||
} else { \
|
||||
_L[trait] = list(source); \
|
||||
SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait)); \
|
||||
SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait), trait); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -37,7 +37,7 @@
|
||||
};\
|
||||
if (!length(_L[trait])) { \
|
||||
_L -= trait; \
|
||||
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(trait)); \
|
||||
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(trait), trait); \
|
||||
}; \
|
||||
if (!length(_L)) { \
|
||||
target.status_traits = null \
|
||||
@@ -53,7 +53,7 @@
|
||||
_L[_T] &= _S;\
|
||||
if (!length(_L[_T])) { \
|
||||
_L -= _T; \
|
||||
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(_T)); \
|
||||
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(_T), _T); \
|
||||
}; \
|
||||
};\
|
||||
if (!length(_L)) { \
|
||||
@@ -228,6 +228,15 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_KNOW_CYBORG_WIRES "know_cyborg_wires"
|
||||
#define TRAIT_KNOW_ENGI_WIRES "know_engi_wires"
|
||||
|
||||
///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"
|
||||
|
||||
//non-mob traits
|
||||
/// Used for limb-based paralysis, where replacing the limb will fix it.
|
||||
#define TRAIT_PARALYSIS "paralysis"
|
||||
@@ -369,6 +378,12 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define SLEEPING_CARP_TRAIT "sleeping_carp"
|
||||
#define MADE_UNCLONEABLE "made-uncloneable"
|
||||
#define TIMESTOP_TRAIT "timestop"
|
||||
#define LIFECANDLE_TRAIT "lifecandle"
|
||||
#define VENTCRAWLING_TRAIT "ventcrawling"
|
||||
#define SPECIES_FLIGHT_TRAIT "species-flight"
|
||||
#define FROSTMINER_ENRAGE_TRAIT "frostminer-enrage"
|
||||
#define NO_GRAVITY_TRAIT "no-gravity"
|
||||
#define LEAPER_BUBBLE_TRAIT "leaper-bubble"
|
||||
#define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a bad soundcloud rapper's name
|
||||
#define SKILLCHIP_TRAIT "skillchip"
|
||||
#define PULLED_WHILE_SOFTCRIT_TRAIT "pulled-while-softcrit"
|
||||
|
||||
@@ -167,6 +167,13 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
),
|
||||
/atom = list(
|
||||
"TRAIT_KEEP_TOGETHER" = TRAIT_KEEP_TOGETHER
|
||||
),
|
||||
/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
|
||||
)
|
||||
))
|
||||
|
||||
@@ -179,3 +186,24 @@ 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)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
return
|
||||
|
||||
//move these next two down a level if you add more mobs to this.
|
||||
if(H.is_flying() || H.is_floating()) //check if they are able to pass over us
|
||||
if(H.movement_type & (FLOATING|FLYING)) //check if they are able to pass over us
|
||||
return //gravity checking only our parent would prevent us from triggering they're using magboots / other gravity assisting items that would cause them to still touch us.
|
||||
if(H.buckled) //if they're buckled to something, that something should be checked instead.
|
||||
return
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/mob/victim = AM
|
||||
if(istype(victim) && !victim.is_flying() && victim.slip(knockdown_time, parent, lube_flags, paralyze_time, force_drop_items) && callback)
|
||||
if(istype(victim) && !(victim.movement_type & FLYING) && victim.slip(knockdown_time, parent, lube_flags, paralyze_time, force_drop_items) && callback)
|
||||
callback.Invoke(victim)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* 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
|
||||
RegisterSignal(movable_target, GLOB.movement_type_addtrait_signals, .proc/on_movement_type_trait_gain)
|
||||
RegisterSignal(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, list(
|
||||
GLOB.movement_type_addtrait_signals,
|
||||
GLOB.movement_type_removetrait_signals,
|
||||
SIGNAL_ADDTRAIT(TRAIT_NO_FLOATING_ANIM),
|
||||
SIGNAL_REMOVETRAIT(TRAIT_NO_FLOATING_ANIM),
|
||||
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|ANIMATION_PARALLEL)
|
||||
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)
|
||||
@@ -35,8 +35,14 @@
|
||||
var/list/client_mobs_in_contents // This contains all the client mobs within this container
|
||||
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
|
||||
@@ -594,15 +600,6 @@
|
||||
var/atom/movable/AM = item
|
||||
AM.onTransitZ(old_z,new_z)
|
||||
|
||||
|
||||
///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][/atom/movable/proc/newtonian_move]
|
||||
@@ -848,8 +845,8 @@
|
||||
|
||||
var/matrix/initial_transform = matrix(transform)
|
||||
var/matrix/rotated_transform = transform.Turn(15 * 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
|
||||
@@ -903,19 +900,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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
@@ -146,10 +150,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)
|
||||
|
||||
/**
|
||||
* Call [/atom/movable/proc/unbuckle_mob] for all buckled mobs
|
||||
*/
|
||||
|
||||
@@ -355,7 +355,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
|
||||
/obj/item/shard/Crossed(atom/movable/AM)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!(L.is_flying() || L.is_floating() || L.buckled))
|
||||
if(!(L.movement_type & (FLYING|FLOATING)) || L.buckled)
|
||||
playsound(src, 'sound/effects/glass_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 30 : 50, TRUE)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
return
|
||||
if(!isturf(user.loc))//You can't use jet in nowhere or from mecha/closet
|
||||
return
|
||||
if(!(user.is_flying() || user.is_floating()) || user.buckled)//You don't want use jet in gravity or while buckled.
|
||||
if(!(user.movement_type & FLOATING) || user.buckled)//You don't want use jet in gravity or while buckled.
|
||||
return
|
||||
if(user.pulledby)//You don't must use jet if someone pull you
|
||||
return
|
||||
|
||||
@@ -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("<span class='notice'>[user] reaches out and pinches the flame of [src].</span>", "<span class='warning'>You sever the connection between yourself and [src].</span>")
|
||||
linked_minds -= user.mind
|
||||
if(!linked_minds.len)
|
||||
REMOVE_TRAIT(src, TRAIT_MOVE_FLOATING, LIFECANDLE_TRAIT)
|
||||
else
|
||||
if(!linked_minds.len)
|
||||
ADD_TRAIT(src, TRAIT_MOVE_FLOATING, LIFECANDLE_TRAIT)
|
||||
user.visible_message("<span class='notice'>[user] touches [src]. It seems to respond to [user.p_their()] presence!</span>", "<span class='warning'>You create a connection between you and [src].</span>")
|
||||
linked_minds |= user.mind
|
||||
|
||||
update_icon()
|
||||
float(linked_minds.len)
|
||||
if(linked_minds.len)
|
||||
START_PROCESSING(SSobj, src)
|
||||
set_light(lit_luminosity)
|
||||
|
||||
@@ -1261,6 +1261,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")
|
||||
|
||||
@@ -105,7 +105,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 = NO_SPAWN //gold slime cores should only spawn the independent subtype
|
||||
|
||||
@@ -45,7 +45,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
|
||||
|
||||
@@ -376,7 +376,6 @@
|
||||
custom_premium_price = PAYCHECK_EASY * 1.6
|
||||
custom_price = PAYCHECK_EASY * 1.6
|
||||
|
||||
|
||||
/obj/item/clothing/shoes/kindle_kicks
|
||||
name = "Kindle Kicks"
|
||||
desc = "They'll sure kindle something in you, and it's not childhood nostalgia..."
|
||||
|
||||
@@ -86,9 +86,3 @@
|
||||
visible_message("<span class='danger'>[src] smashes into [hit_atom]!</span>", "<span class='alertalien'>[src] smashes into [hit_atom]!</span>")
|
||||
Paralyze(40, ignore_canstun = TRUE)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/float(on)
|
||||
if(leaping)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -529,7 +529,7 @@
|
||||
// Shake animation
|
||||
if (incapacitated())
|
||||
var/direction = prob(50) ? -1 : 1
|
||||
animate(src, pixel_x = pixel_x + SHAKE_ANIMATION_OFFSET * direction, time = 1, easing = QUAD_EASING | EASE_OUT)
|
||||
animate(src, pixel_x = pixel_x + SHAKE_ANIMATION_OFFSET * direction, time = 1, easing = QUAD_EASING | EASE_OUT, flags = ANIMATION_PARALLEL)
|
||||
animate(pixel_x = pixel_x - (SHAKE_ANIMATION_OFFSET * 2 * direction), time = 1)
|
||||
animate(pixel_x = pixel_x + SHAKE_ANIMATION_OFFSET * direction, time = 1, easing = QUAD_EASING | EASE_IN)
|
||||
|
||||
|
||||
@@ -59,17 +59,17 @@
|
||||
if(!usable_legs && !(movement_type & (FLYING | FLOATING)))
|
||||
ADD_TRAIT(src, TRAIT_IMMOBILIZED, LACKING_LOCOMOTION_APPENDAGES_TRAIT)
|
||||
|
||||
|
||||
/mob/living/carbon/setMovetype(newval)
|
||||
/mob/living/carbon/on_movement_type_flag_enabled(datum/source, flag)
|
||||
var/old_movetype = movement_type
|
||||
. = ..()
|
||||
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) && !(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/on_movement_type_flag_disabled(datum/source, flag)
|
||||
. = ..()
|
||||
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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
|
||||
sues//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
|
||||
/mob/living/carbon/update_transform()
|
||||
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
|
||||
var/final_pixel_y = pixel_y
|
||||
@@ -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().
|
||||
|
||||
/mob/living/carbon
|
||||
var/list/overlays_standing[TOTAL_LAYERS]
|
||||
|
||||
@@ -902,11 +902,6 @@
|
||||
/mob/living/carbon/human/is_literate()
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/update_gravity(has_gravity,override = 0)
|
||||
if(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 = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, harm = TRUE, force = FALSE, purge_ratio = 0.1)
|
||||
if(blood && (NOBLOOD in dna.species.species_traits) && !HAS_TRAIT(src, TRAIT_TOXINLOVER))
|
||||
if(message)
|
||||
|
||||
@@ -168,8 +168,6 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
var/obj/item/organ/appendix/mutantappendix = /obj/item/organ/appendix
|
||||
///Forces an item into this species' hands. Only an honorary mutantthing because this is not an organ and not loaded in the same way, you've been warned to do your research.
|
||||
var/obj/item/mutanthands
|
||||
///Allows the species to not give a single F about gravity. Used by wings.
|
||||
var/override_float = FALSE
|
||||
|
||||
///Bitflag that controls what in game ways something can select this species as a spawnable source, such as magic mirrors. See [mob defines][code/__DEFINES/mobs.dm] for possible sources.
|
||||
var/changesource_flags = NONE
|
||||
@@ -2080,18 +2078,18 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
|
||||
//UNSAFE PROC, should only be called through the Activate or other sources that check for CanFly
|
||||
/datum/species/proc/ToggleFlight(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_NO_FLOATING_ANIM, SPECIES_FLIGHT_TRAIT)
|
||||
ADD_TRAIT(H, TRAIT_MOVE_FLYING, SPECIES_FLIGHT_TRAIT)
|
||||
passtable_on(H, SPECIES_TRAIT)
|
||||
H.OpenWings()
|
||||
else
|
||||
stunmod *= 0.5
|
||||
speedmod += 0.35
|
||||
H.setMovetype(H.movement_type & ~FLYING)
|
||||
override_float = FALSE
|
||||
REMOVE_TRAIT(H, TRAIT_NO_FLOATING_ANIM, SPECIES_FLIGHT_TRAIT)
|
||||
REMOVE_TRAIT(H, TRAIT_MOVE_FLYING, SPECIES_FLIGHT_TRAIT)
|
||||
passtable_off(H, SPECIES_TRAIT)
|
||||
H.CloseWings()
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
SIGNAL_REMOVETRAIT(TRAIT_NODEATH),
|
||||
), .proc/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)
|
||||
@@ -180,3 +182,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)
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
/mob/living/proc/Life(times_fired)
|
||||
set waitfor = FALSE
|
||||
|
||||
if((movement_type & FLYING) && !(movement_type & FLOATING)) //TODO: Better floating
|
||||
float(on = TRUE)
|
||||
|
||||
if (client)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
faction += "[REF(src)]"
|
||||
GLOB.mob_living_list += src
|
||||
|
||||
/mob/living/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/movetype_handler)
|
||||
|
||||
/mob/living/prepare_huds()
|
||||
..()
|
||||
prepare_data_huds()
|
||||
@@ -942,10 +946,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")
|
||||
@@ -954,24 +959,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?.anchored))
|
||||
fixed = 1
|
||||
if(on && !(movement_type & FLOATING) && !fixed)
|
||||
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 || 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)
|
||||
@@ -1065,11 +1058,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.temperature : T0C
|
||||
|
||||
@@ -401,7 +401,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.
|
||||
|
||||
/**
|
||||
* Does a slap animation on an atom
|
||||
|
||||
@@ -26,7 +26,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
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
friendly_verb_continuous = "nudges"
|
||||
friendly_verb_simple = "nudge"
|
||||
density = FALSE
|
||||
movement_type = FLYING
|
||||
is_flying_animal = TRUE
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
mob_size = MOB_SIZE_TINY
|
||||
|
||||
@@ -25,7 +25,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
speed = 0
|
||||
a_intent = INTENT_HARM
|
||||
stop_automated_movement = 1
|
||||
movement_type = FLYING // Immunity to chasms and landmines, etc.
|
||||
is_flying_animal = TRUE // Immunity to chasms and landmines, etc.
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
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
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
density = FALSE
|
||||
mob_size = MOB_SIZE_TINY
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BUG
|
||||
movement_type = FLYING
|
||||
is_flying_animal = TRUE
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
search_objects = 1 //have to find those plant trays!
|
||||
can_be_held = TRUE
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 1500
|
||||
faction = list("carp")
|
||||
movement_type = FLYING
|
||||
is_flying_animal = TRUE
|
||||
pressure_resistance = 200
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
attack_verb_continuous = "blinks at"
|
||||
attack_verb_simple = "blink at"
|
||||
attack_sound = 'sound/weapons/pierce.ogg'
|
||||
movement_type = FLYING
|
||||
is_flying_animal = TRUE
|
||||
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
|
||||
|
||||
@@ -81,9 +81,13 @@
|
||||
|
||||
/obj/structure/leaper_bubble/Initialize()
|
||||
. = ..()
|
||||
INVOKE_ASYNC(src, /atom/movable.proc/float, TRUE)
|
||||
QDEL_IN(src, 100)
|
||||
|
||||
/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, TRUE, -1)
|
||||
|
||||
@@ -57,6 +57,10 @@
|
||||
/datum/action/innate/megafauna_attack/alternating_cardinals)
|
||||
small_sprite_type = /datum/action/small_sprite/megafauna/colossus
|
||||
|
||||
/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'
|
||||
@@ -250,14 +254,6 @@
|
||||
AT.pixel_y += random_y
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/colossus/float(on) //we don't want this guy to float, messes up his animations
|
||||
if(throwing)
|
||||
return
|
||||
if(on && !(movement_type & FLOATING))
|
||||
setMovetype(movement_type | FLOATING)
|
||||
else if(!on && (movement_type & FLOATING))
|
||||
setMovetype(movement_type & ~FLOATING)
|
||||
|
||||
/obj/projectile/colossus
|
||||
name ="death bolt"
|
||||
icon_state= "chronobolt"
|
||||
@@ -661,7 +657,7 @@
|
||||
friendly_verb_continuous = "taps"
|
||||
friendly_verb_simple = "tap"
|
||||
density = FALSE
|
||||
movement_type = FLYING
|
||||
is_flying_animal = TRUE
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
mob_size = MOB_SIZE_TINY
|
||||
|
||||
@@ -256,7 +256,7 @@ Difficulty: Extremely Hard
|
||||
for(var/mob/living/L in viewers(src))
|
||||
shake_camera(L, 3, 2)
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE)
|
||||
setMovetype(movement_type | FLYING)
|
||||
ADD_TRAIT(src, TRAIT_MOVE_FLYING, FROSTMINER_ENRAGE_TRAIT)
|
||||
enraging = FALSE
|
||||
adjustHealth(-maxHealth)
|
||||
|
||||
|
||||
@@ -11,7 +11,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 = DEAD
|
||||
|
||||
@@ -110,7 +110,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
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
icon_living = "curseblob"
|
||||
icon_aggro = "curseblob"
|
||||
mob_biotypes = MOB_SPIRIT
|
||||
movement_type = FLYING
|
||||
is_flying_animal = TRUE
|
||||
move_to_delay = 5
|
||||
vision_range = 20
|
||||
aggro_vision_range = 20
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
icon_aggro = "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
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
speed = 3
|
||||
maxHealth = 1
|
||||
health = 1
|
||||
movement_type = FLYING
|
||||
is_flying_animal = TRUE
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 2
|
||||
melee_damage_upper = 2
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
deathmessage = "fades as the energies that tied it to this world dissipate."
|
||||
deathsound = 'sound/magic/demon_dies.ogg'
|
||||
stat_attack = HARD_CRIT
|
||||
movement_type = FLYING
|
||||
is_flying_animal = TRUE
|
||||
robust_searching = TRUE
|
||||
footstep_type = FOOTSTEP_MOB_CLAW
|
||||
/// Distance the demon will teleport from the target
|
||||
|
||||
@@ -28,7 +28,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
|
||||
|
||||
@@ -28,7 +28,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
|
||||
light_system = MOVABLE_LIGHT
|
||||
|
||||
@@ -306,7 +306,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 = 1
|
||||
speak_emote = list("states")
|
||||
bubble_icon = "syndibot"
|
||||
|
||||
@@ -63,7 +63,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
|
||||
|
||||
var/parrot_damage_upper = 10
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
stop_automated_movement = 1
|
||||
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
|
||||
|
||||
@@ -128,6 +128,9 @@
|
||||
var/dextrous = FALSE
|
||||
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
|
||||
|
||||
///The Status of our AI, can be set 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/AIStatus = AI_ON
|
||||
///once we have become sentient, we can never go back.
|
||||
@@ -178,6 +181,8 @@
|
||||
if(dextrous)
|
||||
AddComponent(/datum/component/personal_crafting)
|
||||
ADD_TRAIT(src, TRAIT_ADVANCEDTOOLUSER, ROUNDSTART_TRAIT)
|
||||
if(is_flying_animal)
|
||||
ADD_TRAIT(src, TRAIT_MOVE_FLYING, ROUNDSTART_TRAIT)
|
||||
|
||||
if(speak)
|
||||
speak = string_list(speak)
|
||||
@@ -214,6 +219,15 @@
|
||||
|
||||
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/attackby(obj/item/O, mob/user, params)
|
||||
if(!is_type_in_list(O, food_type))
|
||||
@@ -449,7 +463,6 @@
|
||||
new i(loc)
|
||||
|
||||
/mob/living/simple_animal/death(gibbed)
|
||||
movement_type &= ~FLYING
|
||||
if(nest)
|
||||
nest.spawned_mobs -= src
|
||||
nest = null
|
||||
@@ -466,6 +479,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)
|
||||
@@ -499,7 +514,6 @@
|
||||
/mob/living/simple_animal/extinguish_mob()
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/revive(full_heal = FALSE, admin_revive = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
@@ -507,8 +521,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
|
||||
if(gender != FEMALE || stat || next_scan_time > world.time || !childtype || !animal_species || !SSticker.IsRoundInProgress())
|
||||
|
||||
@@ -93,15 +93,14 @@ 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()
|
||||
if(client)
|
||||
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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1289,14 +1289,6 @@
|
||||
/mob/proc/set_nutrition(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)
|
||||
|
||||
@@ -447,14 +447,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()
|
||||
return (movement_type & FLYING)
|
||||
|
||||
///Is the mob a floating mob
|
||||
/mob/proc/is_floating()
|
||||
return (movement_type & FLOATING)
|
||||
|
||||
///Clicks a random nearby mob with the source from this mob
|
||||
/mob/proc/click_random_mob()
|
||||
var/list/nearby_mobs = list()
|
||||
|
||||
@@ -940,7 +940,7 @@
|
||||
if(!isliving(AM))
|
||||
return
|
||||
var/mob/living/L = AM
|
||||
if(istype(L) && !(L.is_flying() || L.is_floating() || L.buckled))
|
||||
if(!(L.movement_type & (FLYING|FLOATING)) || L.buckled)
|
||||
playsound(src, 'sound/effects/glass_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 30 : 50, TRUE)
|
||||
if(status == LIGHT_BURNED || status == LIGHT_OK)
|
||||
shatter()
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
return
|
||||
if(!isturf(owner.loc))//You can't use jet in nowhere or in mecha/closet
|
||||
return
|
||||
if(!(owner.is_flying() || owner.is_floating()) || owner.buckled)//You don't want use jet in gravity or while buckled.
|
||||
if(!(owner.movement_type & FLOATING) || owner.buckled)//You don't want use jet in gravity or while buckled.
|
||||
return
|
||||
if(owner.pulledby)//You don't must use jet if someone pull you
|
||||
return
|
||||
|
||||
@@ -614,6 +614,7 @@
|
||||
#include "code\datums\elements\firestacker.dm"
|
||||
#include "code\datums\elements\forced_gravity.dm"
|
||||
#include "code\datums\elements\light_blocking.dm"
|
||||
#include "code\datums\elements\movetype_handler.dm"
|
||||
#include "code\datums\elements\obj_regen.dm"
|
||||
#include "code\datums\elements\point_of_interest.dm"
|
||||
#include "code\datums\elements\rad_insulation.dm"
|
||||
|
||||
Reference in New Issue
Block a user