|
|
|
|
@@ -81,6 +81,7 @@
|
|
|
|
|
|
|
|
|
|
//Called when we bump onto a mob
|
|
|
|
|
/mob/living/proc/MobBump(mob/M)
|
|
|
|
|
SEND_SIGNAL(src, COMSIG_LIVING_MOB_BUMP, M)
|
|
|
|
|
//Even if we don't push/swap places, we "touched" them, so spread fire
|
|
|
|
|
spreadFire(M)
|
|
|
|
|
|
|
|
|
|
@@ -88,6 +89,7 @@
|
|
|
|
|
return TRUE
|
|
|
|
|
|
|
|
|
|
var/they_can_move = TRUE
|
|
|
|
|
|
|
|
|
|
if(isliving(M))
|
|
|
|
|
var/mob/living/L = M
|
|
|
|
|
they_can_move = CHECK_MOBILITY(L, MOBILITY_MOVE)
|
|
|
|
|
@@ -105,16 +107,16 @@
|
|
|
|
|
//Should stop you pushing a restrained person out of the way
|
|
|
|
|
if(L.pulledby && L.pulledby != src && L.restrained())
|
|
|
|
|
if(!(world.time % 5))
|
|
|
|
|
to_chat(src, "<span class='warning'>[L] is restrained, you cannot push past.</span>")
|
|
|
|
|
return 1
|
|
|
|
|
to_chat(src, span_warning("[L] is restrained, you cannot push past."))
|
|
|
|
|
return TRUE
|
|
|
|
|
|
|
|
|
|
if(L.pulling)
|
|
|
|
|
if(ismob(L.pulling))
|
|
|
|
|
var/mob/P = L.pulling
|
|
|
|
|
if(P.restrained())
|
|
|
|
|
if(!(world.time % 5))
|
|
|
|
|
to_chat(src, "<span class='warning'>[L] is restraining [P], you cannot push past.</span>")
|
|
|
|
|
return 1
|
|
|
|
|
to_chat(src, span_warning("[L] is restraining [P], you cannot push past."))
|
|
|
|
|
return TRUE
|
|
|
|
|
|
|
|
|
|
//CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks or over prone bodies without a short delay
|
|
|
|
|
if(!CHECK_MOBILITY(src, MOBILITY_STAND))
|
|
|
|
|
@@ -142,7 +144,7 @@
|
|
|
|
|
//END OF CIT CHANGES
|
|
|
|
|
|
|
|
|
|
if(moving_diagonally)//no mob swap during diagonal moves.
|
|
|
|
|
return 1
|
|
|
|
|
return TRUE
|
|
|
|
|
|
|
|
|
|
if(!M.buckled && !M.has_buckled_mobs())
|
|
|
|
|
var/mob_swap = FALSE
|
|
|
|
|
@@ -151,7 +153,8 @@
|
|
|
|
|
if(!too_strong)
|
|
|
|
|
mob_swap = TRUE
|
|
|
|
|
else
|
|
|
|
|
if(M.pulledby == src && a_intent == INTENT_GRAB)
|
|
|
|
|
//You can swap with the person you are dragging on grab intent, and restrained people in most cases
|
|
|
|
|
if(M.pulledby == src && !too_strong)
|
|
|
|
|
mob_swap = TRUE
|
|
|
|
|
//restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller
|
|
|
|
|
else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP))
|
|
|
|
|
@@ -159,8 +162,8 @@
|
|
|
|
|
if(mob_swap)
|
|
|
|
|
//switch our position with M
|
|
|
|
|
if(loc && !loc.Adjacent(M.loc))
|
|
|
|
|
return 1
|
|
|
|
|
now_pushing = 1
|
|
|
|
|
return TRUE
|
|
|
|
|
now_pushing = TRUE
|
|
|
|
|
var/oldloc = loc
|
|
|
|
|
var/oldMloc = M.loc
|
|
|
|
|
|
|
|
|
|
@@ -180,27 +183,31 @@
|
|
|
|
|
if(!M_passmob)
|
|
|
|
|
M.pass_flags &= ~PASSMOB
|
|
|
|
|
|
|
|
|
|
now_pushing = 0
|
|
|
|
|
now_pushing = FALSE
|
|
|
|
|
|
|
|
|
|
if(!move_failed)
|
|
|
|
|
return 1
|
|
|
|
|
return TRUE
|
|
|
|
|
|
|
|
|
|
//okay, so we didn't switch. but should we push?
|
|
|
|
|
//not if he's not CANPUSH of course
|
|
|
|
|
if(!(M.status_flags & CANPUSH))
|
|
|
|
|
return 1
|
|
|
|
|
return TRUE
|
|
|
|
|
if(isliving(M))
|
|
|
|
|
var/mob/living/L = M
|
|
|
|
|
if(HAS_TRAIT(L, TRAIT_PUSHIMMUNE))
|
|
|
|
|
return 1
|
|
|
|
|
//If they're a human, and they're not in help intent, block pushing
|
|
|
|
|
if(ishuman(M) && (M.a_intent != INTENT_HELP))
|
|
|
|
|
return TRUE
|
|
|
|
|
return TRUE
|
|
|
|
|
if(M.a_intent != INTENT_HELP)
|
|
|
|
|
//If they're a human, and they're not in help intent, block pushing
|
|
|
|
|
if(ishuman(M))
|
|
|
|
|
return TRUE
|
|
|
|
|
//if they are a cyborg, and they're alive and not in help intent, block pushing
|
|
|
|
|
if(iscyborg(M) && M.stat != DEAD)
|
|
|
|
|
return TRUE
|
|
|
|
|
//anti-riot equipment is also anti-push
|
|
|
|
|
for(var/obj/item/I in M.held_items)
|
|
|
|
|
if(!istype(M, /obj/item/clothing))
|
|
|
|
|
if(prob(I.block_chance*2))
|
|
|
|
|
return 1
|
|
|
|
|
return TRUE
|
|
|
|
|
|
|
|
|
|
/mob/living/get_photo_description(obj/item/camera/camera)
|
|
|
|
|
var/list/mob_details = list()
|
|
|
|
|
@@ -231,21 +238,40 @@
|
|
|
|
|
if(!client && (mob_size < MOB_SIZE_SMALL))
|
|
|
|
|
return
|
|
|
|
|
now_pushing = TRUE
|
|
|
|
|
var/t = get_dir(src, AM)
|
|
|
|
|
SEND_SIGNAL(src, COMSIG_LIVING_PUSHING_MOVABLE, AM)
|
|
|
|
|
var/dir_to_target = get_dir(src, AM)
|
|
|
|
|
|
|
|
|
|
// If there's no dir_to_target then the player is on the same turf as the atom they're trying to push.
|
|
|
|
|
// This can happen when a player is stood on the same turf as a directional window. All attempts to push
|
|
|
|
|
// the window will fail as get_dir will return 0 and the player will be unable to move the window when
|
|
|
|
|
// it should be pushable.
|
|
|
|
|
// In this scenario, we will use the facing direction of the /mob/living attempting to push the atom as
|
|
|
|
|
// a fallback.
|
|
|
|
|
if(!dir_to_target)
|
|
|
|
|
dir_to_target = dir
|
|
|
|
|
|
|
|
|
|
var/push_anchored = FALSE
|
|
|
|
|
if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force)
|
|
|
|
|
if(move_crush(AM, move_force, t))
|
|
|
|
|
if(move_crush(AM, move_force, dir_to_target))
|
|
|
|
|
push_anchored = TRUE
|
|
|
|
|
if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally
|
|
|
|
|
if(force_push(AM, move_force, t, push_anchored))
|
|
|
|
|
if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally
|
|
|
|
|
if(force_push(AM, move_force, dir_to_target, push_anchored))
|
|
|
|
|
push_anchored = TRUE
|
|
|
|
|
if(ismob(AM))
|
|
|
|
|
var/mob/mob_to_push = AM
|
|
|
|
|
var/atom/movable/mob_buckle = mob_to_push.buckled
|
|
|
|
|
// If we can't pull them because of what they're buckled to, make sure we can push the thing they're buckled to instead.
|
|
|
|
|
// If neither are true, we're not pushing anymore.
|
|
|
|
|
if(mob_buckle && (mob_buckle.buckle_prevents_pull || (force < (mob_buckle.move_resist * MOVE_FORCE_PUSH_RATIO))))
|
|
|
|
|
now_pushing = FALSE
|
|
|
|
|
return
|
|
|
|
|
if((AM.anchored && !push_anchored) || (force < (AM.move_resist * MOVE_FORCE_PUSH_RATIO)))
|
|
|
|
|
now_pushing = FALSE
|
|
|
|
|
return
|
|
|
|
|
if (istype(AM, /obj/structure/window))
|
|
|
|
|
if(istype(AM, /obj/structure/window))
|
|
|
|
|
var/obj/structure/window/W = AM
|
|
|
|
|
if(W.fulltile)
|
|
|
|
|
for(var/obj/structure/window/win in get_step(W,t))
|
|
|
|
|
for(var/obj/structure/window/win in get_step(W, dir_to_target))
|
|
|
|
|
now_pushing = FALSE
|
|
|
|
|
return
|
|
|
|
|
if(pulling == AM)
|
|
|
|
|
@@ -253,8 +279,9 @@
|
|
|
|
|
var/current_dir
|
|
|
|
|
if(isliving(AM))
|
|
|
|
|
current_dir = AM.dir
|
|
|
|
|
if(step(AM, t) && Process_Spacemove(t))
|
|
|
|
|
step(src, t)
|
|
|
|
|
if(AM.Move(get_step(AM.loc, dir_to_target), dir_to_target, glide_size))
|
|
|
|
|
AM.add_fingerprint(src)
|
|
|
|
|
Move(get_step(loc, dir_to_target), dir_to_target)
|
|
|
|
|
if(current_dir)
|
|
|
|
|
AM.setDir(current_dir)
|
|
|
|
|
now_pushing = FALSE
|
|
|
|
|
|