940cd92824
Attempt 2 at fixing the remaining bugs with orbits Incorpmove had to be converted to forceMove() to make orbits able to tell when they move. They used loc setting before. This likely breaks some things but I couldn't find any particular issues. We should be overriding forceMove anyway for things that need to handle loc changes like that differently. fixes #40544 fixes #40522
368 lines
9.8 KiB
Plaintext
368 lines
9.8 KiB
Plaintext
/mob/CanPass(atom/movable/mover, turf/target)
|
|
if((mover.pass_flags & PASSMOB))
|
|
return TRUE
|
|
if(istype(mover, /obj/item/projectile) || mover.throwing)
|
|
return (!density || lying)
|
|
if(buckled == mover)
|
|
return TRUE
|
|
if(ismob(mover))
|
|
if (mover in buckled_mobs)
|
|
return TRUE
|
|
return (!mover.density || !density || lying)
|
|
|
|
//DO NOT USE THIS UNLESS YOU ABSOLUTELY HAVE TO. THIS IS BEING PHASED OUT FOR THE MOVESPEED MODIFICATION SYSTEM.
|
|
//See mob_movespeed.dm
|
|
/mob/proc/movement_delay() //update /living/movement_delay() if you change this
|
|
return cached_multiplicative_slowdown
|
|
|
|
/client/verb/drop_item()
|
|
set hidden = 1
|
|
if(!iscyborg(mob) && mob.stat == CONSCIOUS)
|
|
mob.dropItemToGround(mob.get_active_held_item())
|
|
return
|
|
|
|
/client/proc/Move_object(direct)
|
|
if(mob && mob.control_object)
|
|
if(mob.control_object.density)
|
|
step(mob.control_object,direct)
|
|
if(!mob.control_object)
|
|
return
|
|
mob.control_object.setDir(direct)
|
|
else
|
|
mob.control_object.forceMove(get_step(mob.control_object,direct))
|
|
|
|
#define MOVEMENT_DELAY_BUFFER 0.75
|
|
#define MOVEMENT_DELAY_BUFFER_DELTA 1.25
|
|
|
|
/client/Move(n, direct)
|
|
if(world.time < move_delay) //do not move anything ahead of this check please
|
|
return FALSE
|
|
else
|
|
next_move_dir_add = 0
|
|
next_move_dir_sub = 0
|
|
var/old_move_delay = move_delay
|
|
move_delay = world.time + world.tick_lag //this is here because Move() can now be called mutiple times per tick
|
|
if(!mob || !mob.loc)
|
|
return FALSE
|
|
if(!n || !direct)
|
|
return FALSE
|
|
if(mob.notransform)
|
|
return FALSE //This is sota the goto stop mobs from moving var
|
|
if(mob.control_object)
|
|
return Move_object(direct)
|
|
if(!isliving(mob))
|
|
return mob.Move(n, direct)
|
|
if(mob.stat == DEAD)
|
|
mob.ghostize()
|
|
return FALSE
|
|
if(mob.force_moving)
|
|
return FALSE
|
|
|
|
var/mob/living/L = mob //Already checked for isliving earlier
|
|
if(L.incorporeal_move) //Move though walls
|
|
Process_Incorpmove(direct)
|
|
return FALSE
|
|
|
|
if(mob.remote_control) //we're controlling something, our movement is relayed to it
|
|
return mob.remote_control.relaymove(mob, direct)
|
|
|
|
if(isAI(mob))
|
|
return AIMove(n,direct,mob)
|
|
|
|
if(Process_Grab()) //are we restrained by someone's grip?
|
|
return
|
|
|
|
if(mob.buckled) //if we're buckled to something, tell it we moved.
|
|
return mob.buckled.relaymove(mob, direct)
|
|
|
|
if(!mob.canmove)
|
|
return FALSE
|
|
|
|
if(isobj(mob.loc) || ismob(mob.loc)) //Inside an object, tell it we moved
|
|
var/atom/O = mob.loc
|
|
return O.relaymove(mob, direct)
|
|
|
|
if(!mob.Process_Spacemove(direct))
|
|
return FALSE
|
|
//We are now going to move
|
|
var/add_delay = mob.movement_delay()
|
|
if(old_move_delay + (add_delay*MOVEMENT_DELAY_BUFFER_DELTA) + MOVEMENT_DELAY_BUFFER > world.time)
|
|
move_delay = old_move_delay
|
|
else
|
|
move_delay = world.time
|
|
|
|
if(L.confused)
|
|
var/newdir = 0
|
|
if(L.confused > 40)
|
|
newdir = pick(GLOB.alldirs)
|
|
else if(prob(L.confused * 1.5))
|
|
newdir = angle2dir(dir2angle(direct) + pick(90, -90))
|
|
else if(prob(L.confused * 3))
|
|
newdir = angle2dir(dir2angle(direct) + pick(45, -45))
|
|
if(newdir)
|
|
direct = newdir
|
|
n = get_step(L, direct)
|
|
|
|
. = ..()
|
|
|
|
if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully
|
|
add_delay *= 2
|
|
move_delay += add_delay
|
|
if(.) // If mob is null here, we deserve the runtime
|
|
if(mob.throwing)
|
|
mob.throwing.finalize(FALSE)
|
|
|
|
var/atom/movable/P = mob.pulling
|
|
if(P && !ismob(P) && P.density)
|
|
mob.setDir(turn(mob.dir, 180))
|
|
|
|
///Process_Grab()
|
|
///Called by client/Move()
|
|
///Checks to see if you are being grabbed and if so attemps to break it
|
|
/client/proc/Process_Grab()
|
|
if(mob.pulledby)
|
|
if(mob.incapacitated(ignore_restraints = 1))
|
|
move_delay = world.time + 10
|
|
return TRUE
|
|
else if(mob.restrained(ignore_grab = 1))
|
|
move_delay = world.time + 10
|
|
to_chat(src, "<span class='warning'>You're restrained! You can't move!</span>")
|
|
return TRUE
|
|
else
|
|
return mob.resist_grab(1)
|
|
|
|
///Process_Incorpmove
|
|
///Called by client/Move()
|
|
///Allows mobs to run though walls
|
|
/client/proc/Process_Incorpmove(direct)
|
|
var/turf/mobloc = get_turf(mob)
|
|
if(!isliving(mob))
|
|
return
|
|
var/mob/living/L = mob
|
|
switch(L.incorporeal_move)
|
|
if(INCORPOREAL_MOVE_BASIC)
|
|
var/T = get_step(L,direct)
|
|
if(T)
|
|
L.forceMove(T)
|
|
L.setDir(direct)
|
|
if(INCORPOREAL_MOVE_SHADOW)
|
|
if(prob(50))
|
|
var/locx
|
|
var/locy
|
|
switch(direct)
|
|
if(NORTH)
|
|
locx = mobloc.x
|
|
locy = (mobloc.y+2)
|
|
if(locy>world.maxy)
|
|
return
|
|
if(SOUTH)
|
|
locx = mobloc.x
|
|
locy = (mobloc.y-2)
|
|
if(locy<1)
|
|
return
|
|
if(EAST)
|
|
locy = mobloc.y
|
|
locx = (mobloc.x+2)
|
|
if(locx>world.maxx)
|
|
return
|
|
if(WEST)
|
|
locy = mobloc.y
|
|
locx = (mobloc.x-2)
|
|
if(locx<1)
|
|
return
|
|
else
|
|
return
|
|
var/target = locate(locx,locy,mobloc.z)
|
|
if(target)
|
|
L.loc = target
|
|
var/limit = 2//For only two trailing shadows.
|
|
for(var/turf/T in getline(mobloc, L.loc))
|
|
new /obj/effect/temp_visual/dir_setting/ninja/shadow(T, L.dir)
|
|
limit--
|
|
if(limit<=0)
|
|
break
|
|
else
|
|
new /obj/effect/temp_visual/dir_setting/ninja/shadow(mobloc, L.dir)
|
|
var/T = get_step(L,direct)
|
|
if(T)
|
|
L.forceMove(T)
|
|
L.setDir(direct)
|
|
if(INCORPOREAL_MOVE_JAUNT) //Incorporeal move, but blocked by holy-watered tiles and salt piles.
|
|
var/turf/open/floor/stepTurf = get_step(L, direct)
|
|
if(stepTurf)
|
|
for(var/obj/effect/decal/cleanable/salt/S in stepTurf)
|
|
to_chat(L, "<span class='warning'>[S] bars your passage!</span>")
|
|
if(isrevenant(L))
|
|
var/mob/living/simple_animal/revenant/R = L
|
|
R.reveal(20)
|
|
R.stun(20)
|
|
return
|
|
if(stepTurf.flags_1 & NOJAUNT_1)
|
|
to_chat(L, "<span class='warning'>Some strange aura is blocking the way.</span>")
|
|
return
|
|
if (locate(/obj/effect/blessing, stepTurf))
|
|
to_chat(L, "<span class='warning'>Holy energies block your path!</span>")
|
|
return
|
|
|
|
L.forceMove(stepTurf)
|
|
L.setDir(direct)
|
|
return TRUE
|
|
|
|
|
|
///Process_Spacemove
|
|
///Called by /client/Move()
|
|
///For moving in space
|
|
///return TRUE for movement 0 for none
|
|
/mob/Process_Spacemove(movement_dir = 0)
|
|
if(spacewalk || ..())
|
|
return TRUE
|
|
var/atom/movable/backup = get_spacemove_backup()
|
|
if(backup)
|
|
if(istype(backup) && movement_dir && !backup.anchored)
|
|
if(backup.newtonian_move(turn(movement_dir, 180))) //You're pushing off something movable, so it moves
|
|
to_chat(src, "<span class='info'>You push off of [backup] to propel yourself.</span>")
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/mob/get_spacemove_backup()
|
|
for(var/A in orange(1, get_turf(src)))
|
|
if(isarea(A))
|
|
continue
|
|
else if(isturf(A))
|
|
var/turf/turf = A
|
|
if(isspaceturf(turf))
|
|
continue
|
|
if(!turf.density && !mob_negates_gravity())
|
|
continue
|
|
return A
|
|
else
|
|
var/atom/movable/AM = A
|
|
if(AM == buckled)
|
|
continue
|
|
if(ismob(AM))
|
|
var/mob/M = AM
|
|
if(M.buckled)
|
|
continue
|
|
if(!AM.CanPass(src) || AM.density)
|
|
if(AM.anchored)
|
|
return AM
|
|
if(pulling == AM)
|
|
continue
|
|
. = AM
|
|
|
|
/mob/proc/mob_has_gravity()
|
|
return has_gravity()
|
|
|
|
/mob/proc/mob_negates_gravity()
|
|
return FALSE
|
|
|
|
|
|
/mob/proc/slip(s_amount, w_amount, obj/O, lube)
|
|
return
|
|
|
|
/mob/proc/update_gravity()
|
|
return
|
|
|
|
//bodypart selection - Cyberboss
|
|
//8 toggles through head - eyes - mouth
|
|
//4: r-arm 5: chest 6: l-arm
|
|
//1: r-leg 2: groin 3: l-leg
|
|
|
|
/client/proc/check_has_body_select()
|
|
return mob && mob.hud_used && mob.hud_used.zone_select && istype(mob.hud_used.zone_select, /obj/screen/zone_sel)
|
|
|
|
/client/verb/body_toggle_head()
|
|
set name = "body-toggle-head"
|
|
set hidden = 1
|
|
|
|
if(!check_has_body_select())
|
|
return
|
|
|
|
var/next_in_line
|
|
switch(mob.zone_selected)
|
|
if(BODY_ZONE_HEAD)
|
|
next_in_line = BODY_ZONE_PRECISE_EYES
|
|
if(BODY_ZONE_PRECISE_EYES)
|
|
next_in_line = BODY_ZONE_PRECISE_MOUTH
|
|
else
|
|
next_in_line = BODY_ZONE_HEAD
|
|
|
|
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
|
selector.set_selected_zone(next_in_line, mob)
|
|
|
|
/client/verb/body_r_arm()
|
|
set name = "body-r-arm"
|
|
set hidden = 1
|
|
|
|
if(!check_has_body_select())
|
|
return
|
|
|
|
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
|
selector.set_selected_zone(BODY_ZONE_R_ARM, mob)
|
|
|
|
/client/verb/body_chest()
|
|
set name = "body-chest"
|
|
set hidden = 1
|
|
|
|
if(!check_has_body_select())
|
|
return
|
|
|
|
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
|
selector.set_selected_zone(BODY_ZONE_CHEST, mob)
|
|
|
|
/client/verb/body_l_arm()
|
|
set name = "body-l-arm"
|
|
set hidden = 1
|
|
|
|
if(!check_has_body_select())
|
|
return
|
|
|
|
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
|
selector.set_selected_zone(BODY_ZONE_L_ARM, mob)
|
|
|
|
/client/verb/body_r_leg()
|
|
set name = "body-r-leg"
|
|
set hidden = 1
|
|
|
|
if(!check_has_body_select())
|
|
return
|
|
|
|
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
|
selector.set_selected_zone(BODY_ZONE_R_LEG, mob)
|
|
|
|
/client/verb/body_groin()
|
|
set name = "body-groin"
|
|
set hidden = 1
|
|
|
|
if(!check_has_body_select())
|
|
return
|
|
|
|
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
|
selector.set_selected_zone(BODY_ZONE_PRECISE_GROIN, mob)
|
|
|
|
/client/verb/body_l_leg()
|
|
set name = "body-l-leg"
|
|
set hidden = 1
|
|
|
|
if(!check_has_body_select())
|
|
return
|
|
|
|
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
|
selector.set_selected_zone(BODY_ZONE_L_LEG, mob)
|
|
|
|
/client/verb/toggle_walk_run()
|
|
set name = "toggle-walk-run"
|
|
set hidden = TRUE
|
|
set instant = TRUE
|
|
if(mob)
|
|
mob.toggle_move_intent(usr)
|
|
|
|
/mob/proc/toggle_move_intent(mob/user)
|
|
if(m_intent == MOVE_INTENT_RUN)
|
|
m_intent = MOVE_INTENT_WALK
|
|
else
|
|
m_intent = MOVE_INTENT_RUN
|
|
if(hud_used && hud_used.static_inventory)
|
|
for(var/obj/screen/mov_intent/selector in hud_used.static_inventory)
|
|
selector.update_icon(src)
|