Files
Aurora.3/code/modules/mob/mob_movement.dm
NanakoAC 92ba70df81 Alcohol Tweaks (#530)
- bugfix: "Fixed dizziness effects on alcohol, psilocybin, and cryptobiolin taking a long to start up and sometimes never starting for low doses"
  - tweak: "Sip size from alcohol bottles is now the same as for glasses, which is half what it was"
  - tweak: "Rebalanced all alcoholic drinks with more believable alcohol values, and adjusted alcohol metabolism. Generally drinks are stronger but metabolise more slowly, pace yourself!"
  - rscadd: "Different species now have varying susceptibility to alcohol. Tajarans get drunk slightly faster, skrell are twice as fast as humans, unathi can drink more, and vaurca get drunk very slowly, but alcohol poisons them"
  - bugfix: "Dousing people in alcohol and setting them on fire, now only works with spirits and liqeurs stronger than 40% ABV, and the heat of the resulting fire is based on the strength"
2016-07-12 14:53:15 +03:00

505 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.forceMove(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==DEAD && isliving(mob))
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 && prob(20))
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.is_stump()) && (!r_hand || r_hand.is_stump()))
return // No hands to drive your chair? Tough luck!
//drunk wheelchair driving
if(mob.confused && prob(20))
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 && prob(20))
step(mob, pick(cardinal))
else
. = mob.SelfMove(n, direct)
for (var/obj/item/weapon/grab/G in mob)
if (G.state == GRAB_NECK)
mob.set_dir(reverse_dir[direct])
G.adjust_position()
for (var/obj/item/weapon/grab/G in mob.grabbed_by)
G.adjust_position()
moving = 0
return .
return
/mob/proc/SelfMove(turf/n, direct)
return Move(n, direct)
///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.forceMove(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.forceMove(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.forceMove(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
update_floating(0)
return 0
update_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
var/shoegrip
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)
if(shoegrip == null)
shoegrip = Check_Shoegrip() //Shoegrip is only ever checked when a zero-gravity floor is encountered to reduce load
if(!shoegrip)
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/Check_Shoegrip()
return 0
/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)