mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-15 09:03:23 +01:00
Movements outside grab range stops grab, grab pull refactor (#21956)
* grab target move signal checker * moved grab proc into grab class, changed pulling grabbed person handling into signals from assailant, added movetime to SEND_SIGNAL on COMSIG_MOVABLE_MOVED as 4-th argument * refactor p1 * changed pull_grabbed proc, removed unused variable * Empty-Commit * Update code/modules/mob/mob_grab.dm Co-authored-by: Farie82 <farie82@users.noreply.github.com> * neck grab facing back works again * directionals on move again * fixed direction works again * glide speed good now, flips working again * death * fixing neck grab issue * Update code/modules/mob/mob_grab.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> * Update code/modules/mob/mob_grab.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> * dead code gone * I HATE DIAGONAL MOVEMENT * signal handlers added * pull support, best pull turfs only today --------- Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> Co-authored-by: Farie82 <farie82@users.noreply.github.com> Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
This commit is contained in:
@@ -577,7 +577,6 @@
|
||||
if(.)
|
||||
step_count++
|
||||
pull_pulled(old_loc, pullee, movetime)
|
||||
pull_grabbed(old_loc, direct, movetime)
|
||||
|
||||
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //seperated from our puller and not in the middle of a diagonal move
|
||||
pulledby.stop_pulling()
|
||||
@@ -601,61 +600,6 @@
|
||||
if(pulling && get_dist(src, pulling) > 1) // the pullee couldn't keep up
|
||||
stop_pulling()
|
||||
|
||||
/mob/living/proc/pull_grabbed(turf/old_turf, direct, movetime)
|
||||
if(!Adjacent(old_turf))
|
||||
return
|
||||
// We might not actually be grab pulled, but we are pretending that we are, so as to
|
||||
// hackily work around issues arising from mutual grabs.
|
||||
var/old_being_pulled = currently_grab_pulled
|
||||
currently_grab_pulled = TRUE
|
||||
// yes, this is four distinct `for` loops. No, they can't be merged.
|
||||
var/list/grabbing = list()
|
||||
for(var/mob/M in ret_grab())
|
||||
if(src == M)
|
||||
continue
|
||||
if(M.currently_grab_pulled)
|
||||
// Being already pulled by something else up the call stack.
|
||||
continue
|
||||
grabbing |= M
|
||||
for(var/mob/M in grabbing)
|
||||
M.currently_grab_pulled = TRUE
|
||||
M.animate_movement = SYNC_STEPS
|
||||
for(var/i in 1 to length(grabbing))
|
||||
var/mob/M = grabbing[i]
|
||||
if(QDELETED(M)) // old code warned me that M could go missing during a move, so I'm cargo-culting it here
|
||||
continue
|
||||
// compile a list of turfs we can maybe move them towards
|
||||
// importantly, this should happen before actually trying to move them to either of those
|
||||
// otherwise they can be moved twice (since `Move` returns TRUE only if it managed to
|
||||
// *fully* move where you wanted it to; it can still move partially and return FALSE)
|
||||
var/possible_dest = list()
|
||||
for(var/turf/dest in orange(src, 1))
|
||||
if(dest.Adjacent(M))
|
||||
possible_dest |= dest
|
||||
if(i == 1) // at least one of them should try to trail behind us, for aesthetics purposes
|
||||
if(M.Move(old_turf, get_dir(M, old_turf), movetime))
|
||||
continue
|
||||
// By this time the `old_turf` is definitely occupied by something immovable.
|
||||
// So try to move them into some other adjacent turf, in a believable way
|
||||
if(Adjacent(M))
|
||||
continue // they are already adjacent
|
||||
for(var/turf/dest in possible_dest)
|
||||
if(M.Move(dest, get_dir(M, dest), movetime))
|
||||
break
|
||||
for(var/mob/M in grabbing)
|
||||
M.currently_grab_pulled = null
|
||||
M.animate_movement = SLIDE_STEPS
|
||||
|
||||
for(var/obj/item/grab/G in src)
|
||||
if(G.state == GRAB_NECK)
|
||||
setDir(angle2dir((dir2angle(direct) + 202.5) % 365))
|
||||
G.adjust_position()
|
||||
for(var/obj/item/grab/G in grabbed_by)
|
||||
G.adjust_position()
|
||||
|
||||
currently_grab_pulled = old_being_pulled
|
||||
|
||||
|
||||
/mob/living/proc/makeTrail(turf/turf_to_trail_on)
|
||||
if(!has_gravity(src))
|
||||
return
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
return
|
||||
|
||||
affecting.grabbed_by += src
|
||||
RegisterSignal(affecting, COMSIG_MOVABLE_MOVED, PROC_REF(grab_moved))
|
||||
RegisterSignal(assailant, COMSIG_MOVABLE_MOVED, PROC_REF(pull_grabbed))
|
||||
|
||||
hud = new /obj/screen/grab(src)
|
||||
hud.icon_state = "reinforce"
|
||||
@@ -62,6 +64,92 @@
|
||||
clean_grabbed_by(assailant, affecting)
|
||||
adjust_position()
|
||||
|
||||
/obj/item/grab/Destroy()
|
||||
if(affecting)
|
||||
UnregisterSignal(affecting, COMSIG_MOVABLE_MOVED)
|
||||
if(!affecting.buckled)
|
||||
affecting.pixel_x = 0
|
||||
affecting.pixel_y = 0 //used to be an animate, not quick enough for qdel'ing
|
||||
affecting.layer = initial(affecting.layer)
|
||||
affecting.grabbed_by -= src
|
||||
affecting = null
|
||||
if(assailant)
|
||||
UnregisterSignal(assailant, COMSIG_MOVABLE_MOVED)
|
||||
if(assailant.client)
|
||||
assailant.client.screen -= hud
|
||||
assailant = null
|
||||
QDEL_NULL(hud)
|
||||
return ..()
|
||||
|
||||
/obj/item/grab/proc/pull_grabbed(mob/user, turf/old_turf, direct, forced)
|
||||
SIGNAL_HANDLER
|
||||
if(assailant.moving_diagonally == FIRST_DIAG_STEP) //we dont want to do anything in the middle of diagonal step
|
||||
return
|
||||
if(!assailant.Adjacent(old_turf))
|
||||
qdel(src)
|
||||
return
|
||||
var/list/grab_states_not_moving = list(GRAB_KILL, GRAB_NECK) //states of grab when we dont need affecting to be moved by himself
|
||||
var/assailant_glide_speed = TICKS2DS(world.icon_size / assailant.glide_size)
|
||||
if(state in grab_states_not_moving)
|
||||
affecting.glide_for(assailant_glide_speed)
|
||||
else if(get_turf(affecting) != old_turf)
|
||||
var/possible_dest = list()
|
||||
var/list/mobs_do_not_move = list() // those are mobs we shouldnt move while we're going to new position
|
||||
var/list/dest_1_sort = list() // just better dest to be picked first
|
||||
var/list/dest_2_sort = list()
|
||||
if(old_turf.Adjacent(affecting))
|
||||
possible_dest |= old_turf
|
||||
for(var/turf/dest in orange(1, assailant))
|
||||
if(assailant.loc == dest) // orange(1) is broken and returning central turf
|
||||
continue
|
||||
if(!dest.Adjacent(affecting))
|
||||
continue
|
||||
if(dest.Adjacent(old_turf))
|
||||
dest_1_sort |= dest
|
||||
continue
|
||||
dest_2_sort |= dest
|
||||
possible_dest |= dest_1_sort
|
||||
possible_dest |= dest_2_sort
|
||||
if(istype(assailant.l_hand, /obj/item/grab))
|
||||
var/obj/item/grab/grab = assailant.l_hand
|
||||
mobs_do_not_move |= grab.affecting
|
||||
if(istype(assailant.r_hand, /obj/item/grab))
|
||||
var/obj/item/grab/grab = assailant.r_hand
|
||||
mobs_do_not_move |= grab.affecting
|
||||
mobs_do_not_move |= assailant
|
||||
mobs_do_not_move -= affecting
|
||||
if(assailant.pulling)
|
||||
possible_dest -= old_turf // pull code just WANTS THAT old_loc and wont allow anyone else in it
|
||||
mobs_do_not_move |= assailant.pulling
|
||||
for(var/mob/mob as anything in mobs_do_not_move)
|
||||
possible_dest -= get_turf(mob)
|
||||
affecting.grab_do_not_move = mobs_do_not_move
|
||||
var/success_move = FALSE
|
||||
for(var/turf/dest as anything in possible_dest)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(get_turf(affecting) == dest)
|
||||
success_move = TRUE
|
||||
continue
|
||||
if(affecting.Move(dest, get_dir(affecting, dest), assailant_glide_speed))
|
||||
success_move = TRUE
|
||||
break
|
||||
continue
|
||||
affecting.grab_do_not_move = initial(affecting.grab_do_not_move)
|
||||
if(!success_move)
|
||||
qdel(src)
|
||||
return
|
||||
if(state == GRAB_NECK)
|
||||
assailant.setDir(turn(direct, 180))
|
||||
adjust_position()
|
||||
|
||||
/obj/item/grab/proc/grab_moved()
|
||||
SIGNAL_HANDLER
|
||||
if(affecting.moving_diagonally == FIRST_DIAG_STEP) //we dont want to do anything in the middle of diagonal step
|
||||
return
|
||||
if(!assailant.Adjacent(affecting))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grab/proc/clean_grabbed_by(mob/user, mob/victim) //Cleans up any nulls in the grabbed_by list.
|
||||
if(istype(user))
|
||||
|
||||
@@ -169,11 +257,6 @@
|
||||
return
|
||||
if(!assailant.Adjacent(affecting)) // To prevent teleportation via grab
|
||||
return
|
||||
if(IS_HORIZONTAL(affecting) && state != GRAB_KILL)
|
||||
animate(affecting, pixel_x = 0, pixel_y = 0, 5, 1, LINEAR_EASING)
|
||||
return //KJK
|
||||
/* if(force_down) //THIS GOES ABOVE THE RETURN LABELED KJK
|
||||
affecting.setDir(SOUTH)*///This shows how you can apply special directions based on a variable. //face up
|
||||
|
||||
var/shift = 0
|
||||
var/adir = get_dir(assailant, affecting)
|
||||
@@ -417,22 +500,6 @@
|
||||
|
||||
return EAT_TIME_FAT //if it doesn't fit into the above, it's probably a fat guy, take EAT_TIME_FAT to do it
|
||||
|
||||
/obj/item/grab/Destroy()
|
||||
if(affecting)
|
||||
if(!affecting.buckled)
|
||||
affecting.pixel_x = 0
|
||||
affecting.pixel_y = 0 //used to be an animate, not quick enough for qdel'ing
|
||||
affecting.layer = initial(affecting.layer)
|
||||
affecting.grabbed_by -= src
|
||||
affecting = null
|
||||
if(assailant)
|
||||
if(assailant.client)
|
||||
assailant.client.screen -= hud
|
||||
assailant = null
|
||||
QDEL_NULL(hud)
|
||||
return ..()
|
||||
|
||||
|
||||
#undef EAT_TIME_XENO
|
||||
#undef EAT_TIME_FAT
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
return TRUE
|
||||
if(ismob(mover))
|
||||
var/mob/moving_mob = mover
|
||||
if((currently_grab_pulled && moving_mob.currently_grab_pulled))
|
||||
return FALSE
|
||||
if(src in moving_mob.grab_do_not_move)
|
||||
return TRUE
|
||||
if(mover in buckled_mobs)
|
||||
return TRUE
|
||||
return (!mover.density || !density || horizontal)
|
||||
@@ -180,8 +180,6 @@
|
||||
|
||||
if(prev_pulling_loc && mob.pulling?.face_while_pulling && (mob.pulling.loc != prev_pulling_loc))
|
||||
mob.setDir(get_dir(mob, mob.pulling)) // Face welding tanks and stuff when pulling
|
||||
else
|
||||
mob.setDir(direct)
|
||||
|
||||
moving = 0
|
||||
if(mob && .)
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
var/last_log = 0
|
||||
var/obj/machinery/machine = null
|
||||
var/currently_grab_pulled = null /// only set while the move is ongoing, to prevent shuffling between pullees
|
||||
var/list/grab_do_not_move = list() /// other mobs we wont move when we're grab pulled. Not empty only when being grab pulled
|
||||
var/memory = ""
|
||||
var/notransform = FALSE //Carbon
|
||||
/// True for left hand active, otherwise for right hand active
|
||||
|
||||
Reference in New Issue
Block a user