mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-02-04 13:20:15 +00:00
Ensures observers use Process_Incorpmove() despite being dead, while disallowing the once living from doing the same. Ensures incorporeal creatures denied moving unto holy ground don't keep calling more movement code.
516 lines
13 KiB
Plaintext
516 lines
13 KiB
Plaintext
/mob/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
|
if(air_group || (height==0)) return 1
|
|
|
|
if(ismob(mover))
|
|
var/mob/moving_mob = mover
|
|
if ((other_mobs && moving_mob.other_mobs))
|
|
return 1
|
|
return (!mover.density || !density || lying)
|
|
else
|
|
return (!mover.density || !density || lying)
|
|
return
|
|
|
|
|
|
/client/North()
|
|
..()
|
|
|
|
|
|
/client/South()
|
|
..()
|
|
|
|
|
|
/client/West()
|
|
..()
|
|
|
|
|
|
/client/East()
|
|
..()
|
|
|
|
|
|
/client/Northeast()
|
|
swap_hand()
|
|
return
|
|
|
|
|
|
/client/Southeast()
|
|
attack_self()
|
|
return
|
|
|
|
|
|
/client/Southwest()
|
|
if(iscarbon(usr))
|
|
var/mob/living/carbon/C = usr
|
|
C.toggle_throw_mode()
|
|
else
|
|
usr << "\red This mob type cannot throw items."
|
|
return
|
|
|
|
|
|
/client/Northwest()
|
|
if(iscarbon(usr))
|
|
var/mob/living/carbon/C = usr
|
|
if(!C.get_active_hand())
|
|
usr << "\red You have nothing to drop in your hand."
|
|
return
|
|
drop_item()
|
|
else
|
|
usr << "\red This mob type cannot drop items."
|
|
return
|
|
|
|
//This gets called when you press the delete button.
|
|
/client/verb/delete_key_pressed()
|
|
set hidden = 1
|
|
|
|
if(!usr.pulling)
|
|
usr << "\blue You are not pulling anything."
|
|
return
|
|
usr.stop_pulling()
|
|
|
|
/client/verb/swap_hand()
|
|
set hidden = 1
|
|
if(istype(mob, /mob/living/carbon))
|
|
mob:swap_hand()
|
|
if(istype(mob,/mob/living/silicon/robot))
|
|
var/mob/living/silicon/robot/R = mob
|
|
R.cycle_modules()
|
|
return
|
|
|
|
|
|
|
|
/client/verb/attack_self()
|
|
set hidden = 1
|
|
if(mob)
|
|
mob.mode()
|
|
return
|
|
|
|
|
|
/client/verb/toggle_throw_mode()
|
|
set hidden = 1
|
|
if(!istype(mob, /mob/living/carbon))
|
|
return
|
|
if (!mob.stat && isturf(mob.loc) && !mob.restrained())
|
|
mob:toggle_throw_mode()
|
|
else
|
|
return
|
|
|
|
|
|
/client/verb/drop_item()
|
|
set hidden = 1
|
|
if(!isrobot(mob) && mob.stat == CONSCIOUS && isturf(mob.loc))
|
|
return mob.drop_item()
|
|
return
|
|
|
|
|
|
/client/Center()
|
|
/* No 3D movement in 2D spessman game. dir 16 is Z Up
|
|
if (isobj(mob.loc))
|
|
var/obj/O = mob.loc
|
|
if (mob.canmove)
|
|
return O.relaymove(mob, 16)
|
|
*/
|
|
return
|
|
|
|
//This proc should never be overridden elsewhere at /atom/movable to keep directions sane.
|
|
/atom/movable/Move(newloc, direct)
|
|
if (direct & (direct - 1))
|
|
if (direct & 1)
|
|
if (direct & 4)
|
|
if (step(src, NORTH))
|
|
step(src, EAST)
|
|
else
|
|
if (step(src, EAST))
|
|
step(src, NORTH)
|
|
else
|
|
if (direct & 8)
|
|
if (step(src, NORTH))
|
|
step(src, WEST)
|
|
else
|
|
if (step(src, WEST))
|
|
step(src, NORTH)
|
|
else
|
|
if (direct & 2)
|
|
if (direct & 4)
|
|
if (step(src, SOUTH))
|
|
step(src, EAST)
|
|
else
|
|
if (step(src, EAST))
|
|
step(src, SOUTH)
|
|
else
|
|
if (direct & 8)
|
|
if (step(src, SOUTH))
|
|
step(src, WEST)
|
|
else
|
|
if (step(src, WEST))
|
|
step(src, SOUTH)
|
|
else
|
|
var/atom/A = src.loc
|
|
|
|
var/olddir = dir //we can't override this without sacrificing the rest of movable/New()
|
|
. = ..()
|
|
if(direct != olddir)
|
|
dir = olddir
|
|
set_dir(direct)
|
|
|
|
src.move_speed = world.time - src.l_move_time
|
|
src.l_move_time = world.time
|
|
src.m_flag = 1
|
|
if ((A != src.loc && A && A.z == src.z))
|
|
src.last_move = get_dir(A, src.loc)
|
|
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.dir = direct
|
|
else
|
|
mob.control_object.loc = get_step(mob.control_object,direct)
|
|
return
|
|
|
|
|
|
/client/Move(n, direct)
|
|
if(!mob)
|
|
return // Moved here to avoid nullrefs below
|
|
|
|
if(mob.control_object) Move_object(direct)
|
|
|
|
if(mob.incorporeal_move && isobserver(mob))
|
|
Process_Incorpmove(direct)
|
|
return
|
|
|
|
if(moving) return 0
|
|
|
|
if(world.time < move_delay) return
|
|
|
|
if(locate(/obj/effect/stop/, mob.loc))
|
|
for(var/obj/effect/stop/S in mob.loc)
|
|
if(S.victim == mob)
|
|
return
|
|
|
|
if(mob.stat==2)
|
|
mob.ghostize()
|
|
return
|
|
|
|
// handle possible Eye movement
|
|
if(mob.eyeobj)
|
|
return mob.EyeMove(n,direct)
|
|
|
|
if(mob.monkeyizing) return//This is sota the goto stop mobs from moving var
|
|
|
|
if(isliving(mob))
|
|
var/mob/living/L = mob
|
|
if(L.incorporeal_move)//Move though walls
|
|
Process_Incorpmove(direct)
|
|
return
|
|
if(mob.client)
|
|
if(mob.client.view != world.view) // If mob moves while zoomed in with device, unzoom them.
|
|
for(var/obj/item/item in mob.contents)
|
|
if(item.zoom)
|
|
item.zoom()
|
|
break
|
|
/*
|
|
if(locate(/obj/item/weapon/gun/energy/sniperrifle, mob.contents)) // If mob moves while zoomed in with sniper rifle, unzoom them.
|
|
var/obj/item/weapon/gun/energy/sniperrifle/s = locate() in mob
|
|
if(s.zoom)
|
|
s.zoom()
|
|
if(locate(/obj/item/device/binoculars, mob.contents)) // If mob moves while zoomed in with binoculars, unzoom them.
|
|
var/obj/item/device/binoculars/b = locate() in mob
|
|
if(b.zoom)
|
|
b.zoom()
|
|
*/
|
|
|
|
if(Process_Grab()) return
|
|
|
|
|
|
if(!mob.canmove)
|
|
return
|
|
|
|
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
|
|
// if(!mob.Process_Spacemove(0)) return 0
|
|
|
|
if(!mob.lastarea)
|
|
mob.lastarea = get_area(mob.loc)
|
|
|
|
if((istype(mob.loc, /turf/space)) || (mob.lastarea.has_gravity == 0))
|
|
if(!mob.Process_Spacemove(0)) return 0
|
|
|
|
|
|
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(isturf(mob.loc))
|
|
|
|
if(mob.restrained())//Why being pulled while cuffed prevents you from moving
|
|
for(var/mob/M in range(mob, 1))
|
|
if(M.pulling == mob)
|
|
if(!M.restrained() && M.stat == 0 && M.canmove && mob.Adjacent(M))
|
|
src << "\blue You're restrained! You can't move!"
|
|
return 0
|
|
else
|
|
M.stop_pulling()
|
|
|
|
if(mob.pinned.len)
|
|
src << "\blue You're pinned to a wall by [mob.pinned[1]]!"
|
|
return 0
|
|
|
|
move_delay = world.time//set move delay
|
|
mob.last_move_intent = world.time + 10
|
|
switch(mob.m_intent)
|
|
if("run")
|
|
if(mob.drowsyness > 0)
|
|
move_delay += 6
|
|
move_delay += 1+config.run_speed
|
|
if("walk")
|
|
move_delay += 7+config.walk_speed
|
|
move_delay += mob.movement_delay()
|
|
|
|
var/tickcomp = 0 //moved this out here so we can use it for vehicles
|
|
if(config.Tickcomp)
|
|
// move_delay -= 1.3 //~added to the tickcomp calculation below
|
|
tickcomp = ((1/(world.tick_lag))*1.3) - 1.3
|
|
move_delay = move_delay + tickcomp
|
|
|
|
if(istype(mob.buckled, /obj/vehicle))
|
|
//manually set move_delay for vehicles so we don't inherit any mob movement penalties
|
|
//specific vehicle move delays are set in code\modules\vehicles\vehicle.dm
|
|
move_delay = world.time + tickcomp
|
|
//drunk driving
|
|
if(mob.confused)
|
|
direct = pick(cardinal)
|
|
return mob.buckled.relaymove(mob,direct)
|
|
|
|
if(istype(mob.machine, /obj/machinery))
|
|
if(mob.machine.relaymove(mob,direct))
|
|
return
|
|
|
|
if(mob.pulledby || mob.buckled) // Wheelchair driving!
|
|
if(istype(mob.loc, /turf/space))
|
|
return // No wheelchair driving in space
|
|
if(istype(mob.pulledby, /obj/structure/bed/chair/wheelchair))
|
|
return mob.pulledby.relaymove(mob, direct)
|
|
else if(istype(mob.buckled, /obj/structure/bed/chair/wheelchair))
|
|
if(ishuman(mob.buckled))
|
|
var/mob/living/carbon/human/driver = mob.buckled
|
|
var/obj/item/organ/external/l_hand = driver.get_organ("l_hand")
|
|
var/obj/item/organ/external/r_hand = driver.get_organ("r_hand")
|
|
if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED)))
|
|
return // No hands to drive your chair? Tough luck!
|
|
//drunk wheelchair driving
|
|
if(mob.confused)
|
|
direct = pick(cardinal)
|
|
move_delay += 2
|
|
return mob.buckled.relaymove(mob,direct)
|
|
|
|
//We are now going to move
|
|
moving = 1
|
|
//Something with pulling things
|
|
if(locate(/obj/item/weapon/grab, mob))
|
|
move_delay = max(move_delay, world.time + 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/T = mob.loc
|
|
. = ..()
|
|
if (isturf(M.loc))
|
|
var/diag = get_dir(mob, M)
|
|
if ((diag - 1) & diag)
|
|
else
|
|
diag = null
|
|
if ((get_dist(mob, M) > 1 || diag))
|
|
step(M, get_dir(M.loc, T))
|
|
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 )
|
|
step(M, direct)
|
|
return
|
|
spawn( 1 )
|
|
M.other_mobs = null
|
|
M.animate_movement = 2
|
|
return
|
|
|
|
else if(mob.confused)
|
|
step(mob, pick(cardinal))
|
|
else
|
|
. = mob.SelfMove(n, direct)
|
|
|
|
moving = 0
|
|
|
|
return .
|
|
|
|
return
|
|
|
|
/mob/proc/SelfMove(turf/n, direct)
|
|
return Move(n, direct)
|
|
|
|
|
|
///Process_Grab()
|
|
///Called by client/Move()
|
|
///Checks to see if you are grabbing anything and if moving will affect your grab.
|
|
/client/proc/Process_Grab()
|
|
for(var/obj/item/weapon/grab/G in list(mob.l_hand, mob.r_hand))
|
|
if(G.state == GRAB_KILL) //no wandering across the station/asteroid while choking someone
|
|
mob.visible_message("<span class='warning'>[mob] lost \his tight grip on [G.affecting]'s neck!</span>")
|
|
G.hud.icon_state = "disarm/kill"
|
|
G.state = GRAB_NECK
|
|
|
|
///Process_Incorpmove
|
|
///Called by client/Move()
|
|
///Allows mobs to run though walls
|
|
/client/proc/Process_Incorpmove(direct)
|
|
var/turf/mobloc = get_turf(mob)
|
|
|
|
switch(mob.incorporeal_move)
|
|
if(1)
|
|
var/turf/T = get_step(mob, direct)
|
|
if(mob.check_holy(T))
|
|
mob << "<span class='warning'>You cannot get past holy grounds while you are in this plane of existence!</span>"
|
|
return
|
|
else
|
|
mob.loc = get_step(mob, direct)
|
|
mob.dir = direct
|
|
if(2)
|
|
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
|
|
mob.loc = locate(locx,locy,mobloc.z)
|
|
spawn(0)
|
|
var/limit = 2//For only two trailing shadows.
|
|
for(var/turf/T in getline(mobloc, mob.loc))
|
|
spawn(0)
|
|
anim(T,mob,'icons/mob/mob.dmi',,"shadow",,mob.dir)
|
|
limit--
|
|
if(limit<=0) break
|
|
else
|
|
spawn(0)
|
|
anim(mobloc,mob,'icons/mob/mob.dmi',,"shadow",,mob.dir)
|
|
mob.loc = get_step(mob, direct)
|
|
mob.dir = direct
|
|
// Crossed is always a bit iffy
|
|
for(var/obj/S in mob.loc)
|
|
if(istype(S,/obj/effect/step_trigger) || istype(S,/obj/effect/beam))
|
|
S.Crossed(mob)
|
|
|
|
var/area/A = get_area_master(mob)
|
|
if(A)
|
|
A.Entered(mob)
|
|
if(isturf(mob.loc))
|
|
var/turf/T = mob.loc
|
|
T.Entered(mob)
|
|
mob.Post_Incorpmove()
|
|
return 1
|
|
|
|
/mob/proc/Post_Incorpmove()
|
|
return
|
|
|
|
///Process_Spacemove
|
|
///Called by /client/Move()
|
|
///For moving in space
|
|
///Return 1 for movement 0 for none
|
|
/mob/proc/Process_Spacemove(var/check_drift = 0)
|
|
|
|
if(!Check_Dense_Object()) //Nothing to push off of so end here
|
|
make_floating(1)
|
|
return 0
|
|
|
|
if(istype(src,/mob/living/carbon/human/))
|
|
var/mob/living/carbon/human/H = src
|
|
if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)) //magboots + dense_object = no floaty effect
|
|
make_floating(0)
|
|
else
|
|
make_floating(1)
|
|
else
|
|
make_floating(1)
|
|
|
|
if(restrained()) //Check to see if we can do things
|
|
return 0
|
|
|
|
//Check to see if we slipped
|
|
if(prob(Process_Spaceslipping(5)))
|
|
src << "\blue <B>You slipped!</B>"
|
|
src.inertia_dir = src.last_move
|
|
step(src, src.inertia_dir)
|
|
return 0
|
|
//If not then we can reset inertia and move
|
|
inertia_dir = 0
|
|
return 1
|
|
|
|
/mob/proc/Check_Dense_Object() //checks for anything to push off in the vicinity. also handles magboots on gravity-less floors tiles
|
|
|
|
var/dense_object = 0
|
|
for(var/turf/turf in oview(1,src))
|
|
if(istype(turf,/turf/space))
|
|
continue
|
|
|
|
if(istype(turf,/turf/simulated/floor)) // Floors don't count if they don't have gravity
|
|
var/area/A = turf.loc
|
|
if(istype(A) && A.has_gravity == 0)
|
|
var/can_walk = 0
|
|
|
|
if(ishuman(src)) // Only humans can wear magboots, so we give them a chance to.
|
|
var/mob/living/carbon/human/H = src
|
|
if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP))
|
|
can_walk = 1
|
|
|
|
if(!can_walk)
|
|
continue
|
|
|
|
dense_object++
|
|
break
|
|
|
|
if(!dense_object && (locate(/obj/structure/lattice) in oview(1, src)))
|
|
dense_object++
|
|
|
|
//Lastly attempt to locate any dense objects we could push off of
|
|
//TODO: If we implement objects drifing in space this needs to really push them
|
|
//Due to a few issues only anchored and dense objects will now work.
|
|
if(!dense_object)
|
|
for(var/obj/O in oview(1, src))
|
|
if((O) && (O.density) && (O.anchored))
|
|
dense_object++
|
|
break
|
|
|
|
return dense_object
|
|
|
|
|
|
/mob/proc/Process_Spaceslipping(var/prob_slip = 5)
|
|
//Setup slipage
|
|
//If knocked out we might just hit it and stop. This makes it possible to get dead bodies and such.
|
|
if(stat)
|
|
prob_slip = 0 // Changing this to zero to make it line up with the comment.
|
|
|
|
prob_slip = round(prob_slip)
|
|
return(prob_slip)
|