mob var move_dir = 0 next_move = 0 hotkey(name) if (src.use_movement_controller) var/datum/movement_controller/controller = src.use_movement_controller.get_movement_controller() if (controller) return controller.hotkey(src, name) return ..() keys_changed(keys, changed) if (src.use_movement_controller) var/datum/movement_controller/controller = src.use_movement_controller.get_movement_controller() if (controller) controller.keys_changed(src, keys, changed) return if (changed & (KEY_FORWARD|KEY_BACKWARD|KEY_RIGHT|KEY_LEFT)) var/move_x = 0 var/move_y = 0 if (keys & KEY_FORWARD) move_y += 1 if (keys & KEY_BACKWARD) move_y -= 1 if (keys & KEY_RIGHT) move_x += 1 if (keys & KEY_LEFT) move_x -= 1 if (move_x || move_y) src.move_dir = angle2dir(atan2(move_y, move_x)) src.attempt_move() else src.move_dir = 0 src.dir = src.move_dir if (changed & (KEY_THROW|KEY_PULL|KEY_POINT|KEY_EXAMINE|KEY_BOLT|KEY_OPEN|KEY_SHOCK)) // bleh src.update_cursor() process_move(keys) if (src.use_movement_controller) var/datum/movement_controller/controller = src.use_movement_controller.get_movement_controller() if (controller) return controller.process_move(src, keys) if (isdead(src) && !isobserver(src)) return if (src.next_move - world.time >= world.tick_lag / 10) return max(world.tick_lag, (src.next_move - world.time) - world.tick_lag / 10) if (src.move_dir) var/running = 0 var/mob/living/carbon/human/H = src if ((keys & KEY_RUN) && H.get_stamina() > STAMINA_SPRINT && H.getStatusDuration("staggered") < 1) running = 1 if (H.pushing && get_dir(H,H.pushing) != H.move_dir) //Stop pushing before calculating move_delay if we've changed direction H.pushing = 0 var/delay = max(src.movement_delay(get_step(src,src.move_dir), running), world.tick_lag) // don't divide by zero var/move_dir = src.move_dir if (move_dir & (move_dir-1)) delay *= 1.4 // actual sqrt(2) unsurprisingly resulted in rounding errors if (src.client && src.client.flying) var/glide = 32 / (running ? 0.5 : 1.5) * world.tick_lag if (!ticker || last_move_trigger + 10 <= ticker.round_elapsed_ticks) last_move_trigger = ticker.round_elapsed_ticks deliver_move_trigger(m_intent) src.glide_size = glide // dumb hack: some Move() code needs glide_size to be set early in order to adjust "following" objects src.animate_movement = SLIDE_STEPS src.set_loc(get_step(src.loc, move_dir)) src.dir = move_dir OnMove() src.glide_size = glide next_move = world.time + (running ? 0.5 : 1.5) return (running ? 0.5 : 1.5) if (src.canmove) if (src.restrained()) for(var/mob/M in range(src, 1)) if ((M.pulling == src && (!M.restrained() && isalive(M))) || src.grabbed_by.len) boutput(src, "You're restrained! You can't move!") return if ((prob(src.misstep_chance) || (src.traitHolder && prob(5) && src.traitHolder.hasTrait("leftfeet")) || (prob(DISORIENT_MISSTEP_CHANCE) && src.getStatusDuration("disorient")) )) move_dir = pick(turn(move_dir, 90),turn(move_dir, -90)) if (src.buckled && !istype(src.buckled, /obj/stool/chair)) src.buckled.relaymove(move_dir) else if (isturf(src.loc)) if (src.buckled && istype(src.buckled, /obj/stool/chair)) var/obj/stool/chair/C = src.buckled delay += C.buckle_move_delay //GriiiiIIIND for (var/obj/item/grab/G in src.equipped_list(check_for_magtractor = 0)) if (get_dist(src, G.affecting) > 1) qdel(G) for(var/grab in src.grabbed_by) var/obj/item/grab/G = grab if (get_dist(src, G.assailant) > 1) if (G.state > 1) delay += G.assailant.p_class qdel(G) var/turf/old_loc = src.loc //use commented bit if you wanna have world fps different from client. But its not perfect! var/glide = ((32 / delay) * world.tick_lag)// * (world.tick_lag / CLIENTSIDE_TICK_LAG_SMOOTH)) var/spacemove = 0 if (src.no_gravity || (old_loc.throw_unlimited && !src.is_spacefaring()) ) spacemove = 1 for (var/atom/A in oview(1,src)) if (A.stops_space_move) spacemove = 0 break if (spacemove) if (istype(src.back, /obj/item/tank/jetpack)) var/obj/item/tank/jetpack/J = src.back if(J.allow_thrust(0.01, src)) spacemove = 0 src.inertia_dir = 0 else if (ishuman(src)) var/mob/living/carbon/human/Hu = src // I hate doing this uuuugh if (istype(Hu.shoes, /obj/item/clothing/shoes/jetpack)) var/obj/item/clothing/shoes/jetpack/J = Hu.shoes if (J.allow_thrust(0.01, src)) spacemove = 0 src.inertia_dir = 0 else if (isrobot(src) || isghostdrone(src) || isshell(src)) if (src:jetpack) if (!src:jeton) spacemove = 0 src.inertia_dir = 0 if (!spacemove) // yes, this is dumb // also fuck it. var/obj/effects/ion_trails/I = unpool(/obj/effects/ion_trails) I.set_loc(src.loc) I.dir = src.dir flick("ion_fade", I) I.icon_state = "blank" I.pixel_x = src.pixel_x I.pixel_y = src.pixel_y SPAWN_DBG( 20 ) if (I && !I.disposed) pool(I) if (!spacemove) // buh // if the gameticker doesn't exist yet just work with no cooldown src.inertia_dir = 0 if (!ticker || last_move_trigger + 10 <= ticker.round_elapsed_ticks) last_move_trigger = ticker ? ticker.round_elapsed_ticks : 0 //Wire note: Fix for Cannot read null.round_elapsed_ticks deliver_move_trigger(m_intent) if (running) src.remove_stamina(STAMINA_COST_SPRINT) if (src.pulling) src.remove_stamina(STAMINA_COST_SPRINT-1) src.glide_size = glide // dumb hack: some Move() code needs glide_size to be set early in order to adjust "following" objects src.animate_movement = SLIDE_STEPS //if (src.client && src.client.flying) // src.set_loc(get_step(src.loc, move_dir)) // src.dir = move_dir //else src.pushing = 0 var/do_step = 1 //robust grab : don't even bother if we are in a chokehold. Assailant gets moved below. Makes the tile glide better without having a chain of step(src)->step(assailant)->step(me) for(var/grab in src.grabbed_by) var/obj/item/grab/G = grab if (G.state < GRAB_NECK) continue do_step = 0 break if (do_step) step(src, move_dir) OnMove() src.glide_size = glide // but Move will auto-set glide_size, so we need to override it again //robust grab : Assailant gets moved here (do_step shit). this is messy, i'm sorry, blame MBC if (!do_step || src.loc != old_loc) if (mob_flags & AT_GUNPOINT) //we do this check here because if we DID take a step, we aren't tight-grabbed and the gunpoint shot will be triggered by Mob/Move(). messy i know, fix later for(var/obj/item/grab/gunpoint/G in grabbed_by) G.shoot() for(var/grab in src.grabbed_by) var/obj/item/grab/G = grab if (G.state < GRAB_NECK) continue if (!isturf(G.assailant.loc) || G.assailant.anchored) return src.set_density(0) //assailant shouldn't be able to bump us here. Density is set to 0 by the grab stuff but *SAFETY!* step(G.assailant, move_dir) delay += G.assailant.p_class if (src.loc != old_loc) var/list/pulling = list() if (src.pulling) if (get_dist(old_loc, src.pulling) > 1 || src.pulling == src) // fucks sake src.pulling = null //hud.update_pulling() // FIXME else pulling += src.pulling for (var/obj/item/grab/G in src.equipped_list(check_for_magtractor = 0)) pulling += G.affecting for (var/atom/movable/A in pulling) if (get_dist(src, A) == 0) // if we're moving onto the same tile as what we're pulling, don't pull continue if (!isturf(A.loc) || A.anchored) return // whoops A.animate_movement = SYNC_STEPS A.glide_size = glide step(A, get_dir(A, old_loc)) A.glide_size = glide else if (src.loc) //ZeWaka: Fix for null.relaymove delay = src.loc.relaymove(src, move_dir, delay) //relaymove returns 1 if we dont want to override delay if (!delay) delay = 0.5 next_move = world.time + delay return delay