mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 19:44:09 +01:00
Some grab fixes.. (#17895)
* Some grab fixes.. * A tradeoff in jank * Address review comments * .. and a small comment
This commit is contained in:
@@ -540,25 +540,12 @@
|
||||
if(restrained())
|
||||
stop_pulling()
|
||||
|
||||
var/turf/T = loc
|
||||
var/turf/old_loc = loc
|
||||
. = ..()
|
||||
if(.)
|
||||
step_count++
|
||||
|
||||
if(pulling && pulling == pullee) // we were pulling a thing and didn't lose it during our move.
|
||||
if(pulling.anchored)
|
||||
stop_pulling()
|
||||
return
|
||||
|
||||
var/pull_dir = get_dir(src, pulling)
|
||||
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) // puller and pullee more than one tile away or in diagonal position
|
||||
if(isliving(pulling))
|
||||
var/mob/living/M = pulling
|
||||
if(M.lying && !M.buckled && (prob(M.getBruteLoss() * 200 / M.maxHealth)))
|
||||
M.makeTrail(T)
|
||||
pulling.Move(T, get_dir(pulling, T), movetime) // the pullee tries to reach our previous position
|
||||
if(pulling && get_dist(src, pulling) > 1) // the pullee couldn't keep up
|
||||
stop_pulling()
|
||||
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()
|
||||
@@ -566,6 +553,67 @@
|
||||
if(s_active && !(s_active in contents) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
|
||||
s_active.close(src)
|
||||
|
||||
/mob/living/proc/pull_pulled(turf/dest, atom/movable/pullee, movetime)
|
||||
if(pulling && pulling == pullee) // we were pulling a thing and didn't lose it during our move.
|
||||
if(pulling.anchored)
|
||||
stop_pulling()
|
||||
return
|
||||
|
||||
var/pull_dir = get_dir(src, pulling)
|
||||
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) // puller and pullee more than one tile away or in diagonal position
|
||||
if(isliving(pulling))
|
||||
var/mob/living/M = pulling
|
||||
if(M.lying && !M.buckled && (prob(M.getBruteLoss() * 200 / M.maxHealth)))
|
||||
M.makeTrail(dest)
|
||||
pulling.Move(dest, get_dir(pulling, dest), movetime) // the pullee tries to reach our previous position
|
||||
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
|
||||
// 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)
|
||||
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()
|
||||
|
||||
|
||||
/mob/living/proc/makeTrail(turf/T)
|
||||
if(!has_gravity(src))
|
||||
return
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
var/last_log = 0
|
||||
var/obj/machinery/machine = null
|
||||
var/other_mobs = null
|
||||
var/currently_grab_pulled = null /// only set while the move is ongoing, to prevent shuffling between pullees
|
||||
var/memory = ""
|
||||
var/next_move = null
|
||||
var/notransform = null //Carbon
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
return TRUE
|
||||
if(ismob(mover))
|
||||
var/mob/moving_mob = mover
|
||||
if((other_mobs && moving_mob.other_mobs))
|
||||
return TRUE
|
||||
if((currently_grab_pulled && moving_mob.currently_grab_pulled))
|
||||
return FALSE
|
||||
if(mover in buckled_mobs)
|
||||
return TRUE
|
||||
return (!mover.density || !density || lying)
|
||||
@@ -131,50 +131,23 @@
|
||||
|
||||
delay = TICKS2DS(-round(-(DS2TICKS(delay)))) //Rounded to the next tick in equivalent ds
|
||||
|
||||
|
||||
if(locate(/obj/item/grab, mob))
|
||||
delay += 7
|
||||
var/list/L = mob.ret_grab()
|
||||
if(istype(L, /list))
|
||||
if(L.len == 2)
|
||||
L -= mob
|
||||
var/mob/M = L[1]
|
||||
if(M)
|
||||
if((get_dist(mob, M) <= 1 || M.loc == mob.loc))
|
||||
var/turf/prev_loc = mob.loc
|
||||
. = mob.SelfMove(n, direct, delay)
|
||||
if(M && isturf(M.loc)) // Mob may get deleted during parent call
|
||||
var/diag = get_dir(mob, M)
|
||||
if((diag - 1) & diag)
|
||||
else
|
||||
diag = null
|
||||
if((get_dist(mob, M) > 1 || diag))
|
||||
M.Move(prev_loc, get_dir(M.loc, prev_loc), delay)
|
||||
else
|
||||
for(var/mob/M in L)
|
||||
M.other_mobs = 1
|
||||
if(mob != M)
|
||||
M.animate_movement = 3
|
||||
for(var/mob/M in L)
|
||||
spawn(0)
|
||||
M.Move(get_step(M,direct), direct, delay)
|
||||
spawn(1)
|
||||
M.other_mobs = null
|
||||
M.animate_movement = 2
|
||||
|
||||
else
|
||||
var/mob/living/L = mob
|
||||
if(L)
|
||||
var/newdir = NONE
|
||||
var/confusion = L.get_confusion()
|
||||
if(confusion > CONFUSION_MAX)
|
||||
newdir = pick(GLOB.alldirs)
|
||||
else if(prob(confusion * CONFUSION_HEAVY_COEFFICIENT))
|
||||
newdir = angle2dir(dir2angle(direct) + pick(90, -90))
|
||||
else if(prob(confusion * CONFUSION_LIGHT_COEFFICIENT))
|
||||
newdir = angle2dir(dir2angle(direct) + pick(45, -45))
|
||||
if(newdir)
|
||||
direct = newdir
|
||||
n = get_step(mob, direct)
|
||||
var/mob/living/living_mob = mob
|
||||
if(istype(living_mob))
|
||||
var/newdir = NONE
|
||||
var/confusion = living_mob.get_confusion()
|
||||
if(confusion > CONFUSION_MAX)
|
||||
newdir = pick(GLOB.alldirs)
|
||||
else if(prob(confusion * CONFUSION_HEAVY_COEFFICIENT))
|
||||
newdir = angle2dir(dir2angle(direct) + pick(90, -90))
|
||||
else if(prob(confusion * CONFUSION_LIGHT_COEFFICIENT))
|
||||
newdir = angle2dir(dir2angle(direct) + pick(45, -45))
|
||||
if(newdir)
|
||||
direct = newdir
|
||||
n = get_step(mob, direct)
|
||||
|
||||
var/prev_pulling_loc = null
|
||||
if(mob.pulling)
|
||||
@@ -198,13 +171,6 @@
|
||||
else
|
||||
mob.setDir(direct)
|
||||
|
||||
for(var/obj/item/grab/G in mob)
|
||||
if(G.state == GRAB_NECK)
|
||||
mob.setDir(angle2dir((dir2angle(direct) + 202.5) % 365))
|
||||
G.adjust_position()
|
||||
for(var/obj/item/grab/G in mob.grabbed_by)
|
||||
G.adjust_position()
|
||||
|
||||
moving = 0
|
||||
if(mob && .)
|
||||
if(mob.throwing)
|
||||
|
||||
Reference in New Issue
Block a user