[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:
SkyratBot
2020-12-29 02:39:03 +00:00
committed by GitHub
co-authored by Ghom
parent b7f50181ca
commit 94ed7ed0f1
53 changed files with 302 additions and 150 deletions
+1 -1
View File
@@ -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
+1 -3
View File
@@ -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))
+1 -1
View File
@@ -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)
+109
View File
@@ -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)