mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 16:14:08 +01:00
61fb177584
## About The Pull Request When the `force_move()` component is applied, it registers two signals on the involved mob, to stop it moving, and a third one on the `move_loop` it's created. The signal on the created loop is there so that when the loop ends, the `force_move` component can delete itself and free the user. However, there are no checks for whether the `move_loop` was successfully created(which isn't the actual problem, although I have made it runtime there so it is easier to catch in the future). The issue is that when creating two identical moveloops, it cancels the creation of the loop, returning nothing even though there is a loop in effect. The fix was to return the existing loop in this scenario, because it's identical to what would have been made had there not been a loop already. ## Why It's Good For The Game fixes #96069 - Certain raptors transfer hits to their owners, and (this seems like an oversight in and of itself) piercing projectiles thus hit twice, which in the case of the honk staff does two slips, two `force_move`s, two loops, and triggers our identical loop problem. fixes #88352 - The issue report is vague and lacking in specific scenarios, but the mention of slipping again fixing it(which it does with this bug, as the new `force_move` component deletes the broken one) makes me pretty sure it's the same bug fixes #95994 - I'm not certain on this one because I don't know how the Parade works internally, but it seems likely that it could cause two slips on the same tile fixes #94515 - I'm just assuming this is the same bug based on it having the same symptoms ## Changelog 🆑 fix: Several ways you could become permanently immobile, primarily based around lube & other methods of slipping, have been fixed /🆑
41 lines
1.3 KiB
Plaintext
41 lines
1.3 KiB
Plaintext
///Forced directional movement, but with a twist
|
|
///Let's block pressure and client movements while doing it so we can't be interrupted
|
|
///Supports spinning on each move, for lube related reasons
|
|
/datum/component/force_move
|
|
|
|
/datum/component/force_move/Initialize(atom/target, spin)
|
|
if(!target || !ismob(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
var/mob/mob_parent = parent
|
|
var/dist = get_dist(mob_parent, target)
|
|
var/datum/move_loop/loop = GLOB.move_manager.move_towards(mob_parent, target, delay = 1, timeout = dist)
|
|
if(!loop)
|
|
return COMPONENT_INCOMPATIBLE
|
|
RegisterSignal(mob_parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(stop_move))
|
|
RegisterSignal(mob_parent, COMSIG_ATOM_PRE_PRESSURE_PUSH, PROC_REF(stop_pressure))
|
|
if(spin)
|
|
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(slip_spin))
|
|
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(loop_ended))
|
|
|
|
/datum/component/force_move/proc/stop_move(datum/source)
|
|
SIGNAL_HANDLER
|
|
return COMSIG_MOB_CLIENT_BLOCK_PRE_LIVING_MOVE
|
|
|
|
/datum/component/force_move/proc/stop_pressure(datum/source)
|
|
SIGNAL_HANDLER
|
|
return COMSIG_ATOM_BLOCKS_PRESSURE
|
|
|
|
/datum/component/force_move/proc/slip_spin(datum/source)
|
|
SIGNAL_HANDLER
|
|
var/mob/mob_parent = parent
|
|
mob_parent.spin(1, 1)
|
|
|
|
/datum/component/force_move/proc/loop_ended(datum/source)
|
|
SIGNAL_HANDLER
|
|
if(QDELETED(src))
|
|
return
|
|
qdel(src)
|
|
|
|
|