Files
Bubberstation/code/datums/forced_movement.dm
SkyratBot c529b754fb [MIRROR] Fixes a bunch of callbacks that were being qdeleted, and code cleanup [MDB IGNORE] (#23319)
* Fixes a bunch of callbacks that were being qdeleted, and code cleanup (#77904)

## About The Pull Request

![image](https://github.com/tgstation/tgstation/assets/13398309/559eb50a-461c-4220-b628-55412baaffc3)

Continuing the work of
https://github.com/tgstation/tgstation/pull/77850.

it started with finding one that was being missed and causing a
runtime...then I noticed a whole lot more. While I was doing this I
found callbacks that weren't being nulled in `Destroy()`, so I added
that wherever I found these spots as well as some general code cleanup.

There were a lot more of these than I initially hoped to encounter so
I'm labeling it as a refactor.

## Why It's Good For The Game

Fixes lots of runtimes, improves code resiliency.

## Changelog

🆑
refactor: fixed a bunch of instances of callbacks being qdeleted and
cleaned up related code
/🆑

* Fixes a bunch of callbacks that were being qdeleted, and code cleanup

---------

Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
2023-08-25 19:06:07 -04:00

90 lines
2.4 KiB
Plaintext

//Just new and forget
//Depricated, use movement loops instead. Exists to support things that want to move more then 10 times a second
/datum/forced_movement
var/atom/movable/victim
var/atom/target
var/last_processed
var/steps_per_tick
var/allow_climbing
var/datum/callback/on_step
var/moved_at_all = FALSE
//as fast as ssfastprocess
/datum/forced_movement/New(atom/movable/_victim, atom/_target, _steps_per_tick = 0.5, _allow_climbing = FALSE, datum/callback/_on_step = null)
victim = _victim
target = _target
steps_per_tick = _steps_per_tick
allow_climbing = _allow_climbing
on_step = _on_step
. = ..()
if(_victim && _target && _steps_per_tick && !_victim.force_moving)
last_processed = world.time
_victim.force_moving = src
START_PROCESSING(SSfastprocess, src)
else
qdel(src) //if you want to overwrite the current forced movement, call qdel(victim.force_moving) before creating this
/datum/forced_movement/Destroy()
if(victim.force_moving == src)
victim.force_moving = null
if(moved_at_all)
victim.forceMove(victim.loc) //get the side effects of moving here that require us to currently not be force_moving aka reslipping on ice
STOP_PROCESSING(SSfastprocess, src)
victim = null
target = null
on_step = null
return ..()
//Todo: convert
/datum/forced_movement/process()
if(QDELETED(victim) || !victim.loc || QDELETED(target) || !target.loc)
qdel(src)
return
var/steps_to_take = round(steps_per_tick * (world.time - last_processed))
if(steps_to_take)
for(var/i in 1 to steps_to_take)
if(TryMove())
moved_at_all = TRUE
if(on_step)
on_step.InvokeAsync()
else
qdel(src)
return
last_processed = world.time
/datum/forced_movement/proc/TryMove(recursive = FALSE)
if(QDELETED(src)) //Our previous step caused deletion of this datum
return
var/atom/movable/vic = victim //sanic
var/atom/tar = target
if(!recursive)
. = step_towards(vic, tar)
//shit way for getting around corners
if(!.) //If stepping towards the target failed
if(tar.x > vic.x) //If we're going x, step x
if(step(vic, EAST))
. = TRUE
else if(tar.x < vic.x)
if(step(vic, WEST))
. = TRUE
if(!.) //If the x step failed, go y
if(tar.y > vic.y)
if(step(vic, NORTH))
. = TRUE
else if(tar.y < vic.y)
if(step(vic, SOUTH))
. = TRUE
if(!.) //If both failed, try again for some reason
if(recursive)
return FALSE
else
. = TryMove(TRUE)
. = . && (vic.loc != tar.loc)