Merge pull request #2171 from tigercat2000/muh_tg_spessmove

-tg- spacemove system
This commit is contained in:
Mark van Alphen
2015-09-26 05:07:32 +02:00
35 changed files with 276 additions and 588 deletions
+82 -13
View File
@@ -5,7 +5,6 @@
// var/elevation = 2 - not used anywhere
var/move_speed = 10
var/l_move_time = 1
var/m_flag = 1
var/throwing = 0
var/thrower
var/turf/throw_source = null
@@ -14,9 +13,10 @@
var/no_spin_thrown = 0 //set this to 1 if you don't want an item that you throw to spin, no matter what. -Fox
var/moved_recently = 0
var/mob/pulledby = null
var/inertia_dir = 0
var/area/areaMaster
var/auto_init = 1
/atom/movable/New()
@@ -35,7 +35,7 @@
pulledby = null
..()
return QDEL_HINT_QUEUE
/atom/movable/proc/initialize()
return
@@ -44,15 +44,53 @@
/atom/movable/proc/setLoc(var/T, var/teleported=0)
loc = T
/atom/movable/Move()
var/atom/A = src.loc
. = ..()
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
/atom/movable/Move(atom/newloc, direct = 0)
if(!loc || !newloc) return 0
var/atom/oldloc = loc
if(loc != newloc)
if (!(direct & (direct - 1))) //Cardinal move
. = ..()
else //Diagonal move, split it into cardinal moves
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)
if(!loc || (loc == oldloc && oldloc != newloc))
last_move = 0
return
src.move_speed = world.timeofday - src.l_move_time
src.l_move_time = world.timeofday
last_move = direct
spawn(5) // Causes space drifting. /tg/station has no concept of speed, we just use 5
if(loc && direct && last_move == direct)
if(loc == newloc) //Remove this check and people can accelerate. Not opening that can of worms just yet.
newtonian_move(last_move)
// Previously known as Crossed()
// This is automatically called when something enters your square
@@ -104,6 +142,37 @@
M.turf_collision(T, speed)
//Called whenever an object moves and by mobs when they attempt to move themselves through space
//And when an object or action applies a force on src, see newtonian_move() below
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm
//movement_dir == 0 when stopping or any dir when trying to move
/atom/movable/proc/Process_Spacemove(var/movement_dir = 0)
if(has_gravity(src))
return 1
if(pulledby)
return 1
if(locate(/obj/structure/lattice) in orange(1, get_turf(src))) //Not realistic but makes pushing things in space easier
return 1
return 0
/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity
if(!loc || Process_Spacemove(0))
inertia_dir = 0
return 0
inertia_dir = direction
if(!direction)
return 1
var/old_dir = dir
. = step(src, direction)
dir = old_dir
//decided whether a movable atom being thrown can pass through the turf it is in.
/atom/movable/proc/hit_check(var/speed)
if(src.throwing)
@@ -152,7 +221,7 @@
var/atom/step = get_step(src, dy)
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
break
src.Move(step)
src.Move(step, get_dir(loc, step))
hit_check(speed)
error += dist_x
dist_travelled++
+5 -35
View File
@@ -93,50 +93,20 @@
return
/obj/mecha/combat/marauder/relaymove(mob/user,direction)
if(user != src.occupant) //While not "realistic", this piece is player friendly.
user.loc = get_turf(src)
user << "You climb out from [src]"
return 0
if(!can_move)
return 0
if(zoom)
if(world.time - last_message > 20)
src.occupant_message("Unable to move while in zoom mode.")
last_message = world.time
return 0
if(connected_port)
if(world.time - last_message > 20)
src.occupant_message("Unable to move while connected to the air system port")
last_message = world.time
return 0
if(!thrusters && src.pr_inertial_movement.active())
return 0
if(state || !has_charge(step_energy_drain))
return 0
var/tmp_step_in = step_in
var/tmp_step_energy_drain = step_energy_drain
var/move_result = 0
if(internal_damage&MECHA_INT_CONTROL_LOST)
move_result = mechsteprand()
else if(src.dir!=direction)
move_result = mechturn(direction)
else
move_result = mechstep(direction)
if(move_result)
if(istype(src.loc, /turf/space))
if(!src.check_for_support())
src.pr_inertial_movement.start(list(src,direction))
if(thrusters)
src.pr_inertial_movement.set_process_args(list(src,direction))
tmp_step_energy_drain = step_energy_drain*2
return ..()
can_move = 0
spawn(tmp_step_in) can_move = 1
use_power(tmp_step_energy_drain)
/obj/mecha/combat/marauder/Process_Spacemove(var/movement_dir = 0)
if(..())
return 1
if(thrusters && movement_dir && use_power(step_energy_drain))
return 1
return 0
/obj/mecha/combat/marauder/verb/toggle_thrusters()
set category = "Exosuit Interface"
set name = "Toggle thrusters"
+10 -30
View File
@@ -59,7 +59,6 @@
var/list/internals_req_access = list(access_engine,access_robotics)//required access level to open cell compartment
var/datum/global_iterator/pr_int_temp_processor //normalizes internal air mixture temperature
var/datum/global_iterator/pr_inertial_movement //controls intertial movement in spesss
var/datum/global_iterator/pr_give_air //moves air from tank to cabin
var/datum/global_iterator/pr_internal_damage //processes internal damage
@@ -136,7 +135,6 @@
/obj/mecha/proc/add_iterators()
pr_int_temp_processor = new /datum/global_iterator/mecha_preserve_temp(list(src))
pr_inertial_movement = new /datum/global_iterator/mecha_intertial_movement(null,0)
pr_give_air = new /datum/global_iterator/mecha_tank_give_air(list(src))
pr_internal_damage = new /datum/global_iterator/mecha_internal_damage(list(src),0)
@@ -159,13 +157,6 @@
return 1
/obj/mecha/proc/check_for_support()
if(locate(/obj/structure/grille, orange(1, src)) || locate(/obj/structure/lattice, orange(1, src)) || locate(/turf/simulated, orange(1, src)) || locate(/turf/unsimulated, orange(1, src)))
return 1
else
return 0
/obj/mecha/examine(mob/user)
..(user)
var/integrity = health/initial(health)*100
@@ -289,11 +280,15 @@
//////// Movement procs ////////
//////////////////////////////////
/obj/mecha/Move()
/obj/mecha/Move(atom/newLoc, direct)
. = ..()
if(.)
events.fireEvent("onMove",get_turf(src))
return
/obj/mecha/Process_Spacemove(var/movement_dir = 0)
if(occupant)
return occupant.Process_Spacemove(movement_dir) //We'll just say you used the clamp to grab the wall
return ..()
/obj/mecha/relaymove(mob/user,direction)
if(user != src.occupant) //While not "realistic", this piece is player friendly.
@@ -316,7 +311,7 @@
/obj/mecha/proc/dyndomove(direction)
if(!can_move)
return 0
if(src.pr_inertial_movement.active())
if(!Process_Spacemove(direction))
return 0
if(!has_charge(step_energy_drain))
return 0
@@ -326,14 +321,9 @@
else if(src.dir!=direction)
move_result = mechturn(direction)
else
move_result = mechstep(direction)
move_result = mechstep(direction)
if(move_result)
can_move = 0
use_power(step_energy_drain)
if(istype(src.loc, /turf/space))
if(!src.check_for_support())
src.pr_inertial_movement.start(list(src,direction))
src.log_message("Movement control lost. Inertial movement started.")
if(mecha_do_after(step_in))
can_move = 1
return 1
@@ -1070,7 +1060,7 @@
connected_port = new_port
connected_port.connected_device = src
connected_port.parent.reconcile_air()
log_message("Connected to gas port.")
return 1
@@ -1082,7 +1072,7 @@
connected_port = null
src.log_message("Disconnected from gas port.")
return 1
/obj/mecha/portableConnectorReturnAir()
return internal_tank.return_air()
@@ -1881,16 +1871,6 @@
return stop()
return
/datum/global_iterator/mecha_intertial_movement //inertial movement in space
delay = 7
process(var/obj/mecha/mecha as obj,direction)
if(direction)
if(!step(mecha, direction)||mecha.check_for_support())
src.stop()
else
src.stop()
return
/datum/global_iterator/mecha_internal_damage // processing internal damage
+31 -41
View File
@@ -769,40 +769,35 @@ steam.start() -- spawns the effect
var/processing = 1
var/on = 1
set_up(atom/atom)
attach(atom)
oldposition = get_turf(atom)
/datum/effect/effect/system/ion_trail_follow/set_up(atom/atom)
attach(atom)
start()
if(!src.on)
src.on = 1
src.processing = 1
if(src.processing)
src.processing = 0
spawn(0)
var/turf/T = get_turf(src.holder)
if(T != src.oldposition)
if(istype(T, /turf/space))
var/obj/effect/effect/ion_trails/I = new /obj/effect/effect/ion_trails(src.oldposition)
src.oldposition = T
I.dir = src.holder.dir
flick("ion_fade", I)
I.icon_state = "blank"
spawn( 20 )
if(I) I.delete()
spawn(2)
if(src.on)
src.processing = 1
src.start()
else
spawn(2)
if(src.on)
src.processing = 1
src.start()
proc/stop()
/datum/effect/effect/system/ion_trail_follow/start() //Whoever is responsible for this abomination of code should become an hero
if(!src.on)
src.on = 1
src.processing = 1
if(src.processing)
src.processing = 0
src.on = 0
var/turf/T = get_turf(src.holder)
if(T != src.oldposition)
if(!has_gravity(T))
var/obj/effect/effect/ion_trails/I = new /obj/effect/effect/ion_trails(src.oldposition)
I.dir = src.holder.dir
flick("ion_fade", I)
I.icon_state = "blank"
spawn( 20 )
if(I)
I.delete()
src.oldposition = T
spawn(2)
if(src.on)
src.processing = 1
src.start()
/datum/effect/effect/system/ion_trail_follow/proc/stop()
src.processing = 0
src.on = 0
oldposition = null
/datum/effect/effect/system/ion_trail_follow/space_trail
var/turf/oldloc // secondary ion trail loc
@@ -850,15 +845,10 @@ steam.start() -- spawns the effect
spawn( 20 )
if(I) I.delete()
if(II) II.delete()
spawn(2)
if(src.on)
src.processing = 1
src.start()
else
spawn(2)
if(src.on)
src.processing = 1
src.start()
spawn(2)
if(src.on)
src.processing = 1
src.start()
currloc = T
+12 -14
View File
@@ -105,27 +105,29 @@
var/obj/B = usr.buckled
var/movementdirection = turn(direction,180)
if(C) C.propelled = 4
B.Move(get_step(usr,movementdirection), movementdirection)
step(B, movementdirection)
sleep(1)
B.Move(get_step(usr,movementdirection), movementdirection)
step(B, movementdirection)
if(C) C.propelled = 3
sleep(1)
B.Move(get_step(usr,movementdirection), movementdirection)
step(B, movementdirection)
sleep(1)
B.Move(get_step(usr,movementdirection), movementdirection)
step(B, movementdirection)
if(C) C.propelled = 2
sleep(2)
B.Move(get_step(usr,movementdirection), movementdirection)
step(B, movementdirection)
if(C) C.propelled = 1
sleep(2)
B.Move(get_step(usr,movementdirection), movementdirection)
step(B, movementdirection)
if(C) C.propelled = 0
sleep(3)
B.Move(get_step(usr,movementdirection), movementdirection)
step(B, movementdirection)
sleep(3)
B.Move(get_step(usr,movementdirection), movementdirection)
step(B, movementdirection)
sleep(3)
B.Move(get_step(usr,movementdirection), movementdirection)
step(B, movementdirection)
else user.newtonian_move(turn(direction, 180))
var/turf/T = get_turf(target)
var/turf/T1 = get_step(T,turn(direction, 90))
@@ -161,9 +163,5 @@
if(W.loc == my_target) break
sleep(2)
if(!has_gravity(user))
user.inertia_dir = get_dir(target, user)
step(user, user.inertia_dir)
else
return ..()
return ..()
+13 -134
View File
@@ -5,9 +5,8 @@
var/empstun = 0
var/health = 100
var/destroyed = 0
var/inertia_dir = 0
var/allowMove = 1
var/delay = 1
var/move_delay = 1
var/keytype = /obj/item/key
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread
/obj/structure/stool/bed/chair/cart/process()
@@ -48,96 +47,6 @@
if(istype(W, /obj/item/key))
user << "Hold [W] in one of your hands while you drive this [name]."
/obj/structure/stool/bed/chair/cart/proc/Process_Spacemove(var/check_drift = 0, mob/user)
//First check to see if we can do things
/*
if(istype(src,/mob/living/carbon))
if(src.l_hand && src.r_hand)
return 0
*/
var/dense_object = 0
if(!user)
for(var/turf/turf in oview(1,src))
if(istype(turf,/turf/space))
continue
/*
if((istype(turf,/turf/simulated/floor))
if(user)
if(user.lastarea.has_gravity == 0)
continue*/
/*
if(istype(turf,/turf/simulated/floor) && (src.flags & NOGRAV))
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
else
for(var/turf/turf in oview(1,user))
if(istype(turf,/turf/space))
continue
/*
if((istype(turf,/turf/simulated/floor))
if(user)
if(user.lastarea.has_gravity == 0)
continue*/
/*
if(istype(turf,/turf/simulated/floor) && (src.flags & NOGRAV))
continue
*/
dense_object++
break
if(!dense_object && (locate(/obj/structure/lattice) in oview(1, user)))
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, user))
if((O) && (O.density) && (O.anchored))
dense_object++
break
//Nothing to push off of so end here
if(!dense_object)
return 0
/* The cart has very grippy tires and or magnets to keep it from slipping when on a good surface
//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
/obj/structure/stool/bed/chair/cart/user_buckle_mob(mob/living/M, mob/user)
if(user.incapacitated()) //user can't move the mob on the janicart's turf if incapacitated
@@ -263,16 +172,12 @@
var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite
var/obj/item/weapon/storage/bag/trash/mybag = null
/obj/structure/stool/bed/chair/cart/janicart/New()
..()
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
/obj/structure/stool/bed/chair/cart/janicart/examine(mob/user)
if(!..(user, 1))
return
@@ -314,21 +219,15 @@
if(user)
user << "\red \the [src] is unresponsive."
return
if((istype(src.loc, /turf/space)))
if(!src.Process_Spacemove(0)) return
if(istype(user.l_hand, /obj/item/key) || istype(user.r_hand, /obj/item/key))
if(!allowMove)
if(istype(user.l_hand, keytype) || istype(user.r_hand, keytype))
if(!Process_Spacemove(direction) || !has_gravity(src.loc) || move_delay || !isturf(loc))
return
allowMove = 0
step(src, direction)
update_mob()
handle_rotation()
sleep(delay)
allowMove = 1
/*
if(istype(src.loc, /turf/space) && (!src.Process_Spacemove(0, user)))
var/turf/space/S = src.loc
S.Entered(src)*/
move_delay = 1
spawn(2)
move_delay = 0
else
user << "<span class='notice'>You'll need the keys in one of your hands to drive this pimpin' ride.</span>"
@@ -338,7 +237,7 @@
name = "ambulance"
icon = 'icons/obj/vehicles.dmi'
icon_state = "docwagon"
anchored = 1
anchored = 0
density = 1
/var/brightness = 4
/var/strobe = 0
@@ -351,39 +250,19 @@
if(user)
user << "\red \the [src] is unresponsive."
return
if((istype(src.loc, /turf/space)))
if(!src.Process_Spacemove(0)) return
if(istype(user.l_hand, /obj/item/key) || istype(user.r_hand, /obj/item/key))
if(!allowMove)
if(istype(user.l_hand, keytype) || istype(user.r_hand, keytype))
if(!Process_Spacemove(direction) || !has_gravity(src.loc) || move_delay || !isturf(loc))
return
allowMove = 0
step(src, direction)
// NEW PULLING CODE
if (istype(user.pulling, /obj/structure/stool/bed/roller))
var/turf/T = loc
step(user.pulling, get_dir(user.pulling.loc, T))
// END NEW PULLING CODE
update_mob()
handle_rotation()
sleep(delay)
allowMove = 1
/*
if(istype(src.loc, /turf/space) && (!src.Process_Spacemove(0, user)))
var/turf/space/S = src.loc
S.Entered(src)*/
move_delay = 1
spawn(2)
move_delay = 0
else
user << "<span class='notice'>You'll need the keys in one of your hands to drive this ambulance.</span>"
/obj/item/key
name = "key"
desc = "A keyring with a small steel key, and a pink fob reading \"Pussy Wagon\"."
@@ -36,9 +36,15 @@
if(!buckled_mob.Move(loc, direct))
loc = buckled_mob.loc //we gotta go back
last_move = buckled_mob.last_move
inertia_dir = last_move
buckled_mob.inertia_dir = last_move
. = 0
/obj/structure/stool/bed/Process_Spacemove(movement_dir = 0)
if(buckled_mob)
return buckled_mob.Process_Spacemove(movement_dir)
return ..()
/obj/structure/stool/bed/CanPass(atom/movable/mover, turf/target, height=1.5)
if(mover == buckled_mob)
return 1
@@ -14,6 +14,10 @@
handle_rotation()
return
/obj/structure/stool/bed/chair/Move(atom/newloc, direct)
..()
handle_rotation()
/obj/structure/stool/bed/chair/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
..()
if(istype(W, /obj/item/assembly/shock_kit))
@@ -25,6 +25,11 @@
return ..()
/obj/structure/transit_tube_pod/Process_Spacemove()
if(moving) //No drifting while moving in the tubes
return 1
else return ..()
/obj/structure/transit_tube_pod/proc/follow_tube(var/reverse_launch)
if(moving)
return
@@ -67,7 +72,7 @@
if(current_tube == null)
dir = next_dir
Move(get_step(loc, dir)) // Allow collisions when leaving the tubes.
Move(get_step(loc, dir), dir) // Allow collisions when leaving the tubes.
break
last_delay = current_tube.enter_delay(src, next_dir)
@@ -82,21 +87,6 @@
density = 1
// If the pod is no longer in a tube, move in a line until stopped or slowed to a halt.
// /turf/inertial_drift appears to only work on mobs, and re-implementing some of the
// logic allows a gradual slowdown and eventual stop when passing over non-space turfs.
if(!current_tube && last_delay <= 10)
do
sleep(last_delay)
if(!istype(loc, /turf/space))
last_delay++
if(last_delay > 10)
break
while(isturf(loc) && Move(get_step(loc, dir)))
moving = 0
+2 -4
View File
@@ -94,8 +94,6 @@
..()
if ((!(A) || src != A.loc)) return
inertial_drift(A)
if(transition)
if(A.z > MAX_Z) return //for away missions
@@ -121,8 +119,8 @@
L.pulling.loc = T
//now we're on the new z_level, proceed the space drifting
if ((A && A.loc))
A.loc.Entered(A)
sleep(0)//Let a diagonal move finish, if necessary
A.newtonian_move(A.inertia_dir)
/turf/space/proc/Sandbox_Spacemove(atom/movable/A as mob|obj)
var/cur_x
+1 -46
View File
@@ -109,12 +109,7 @@
var/mob/O = M
if(!O.lastarea)
O.lastarea = get_area(O.loc)
var/has_gravity = O.mob_has_gravity(src)
O.update_gravity(has_gravity)
if(!has_gravity)
inertial_drift(O)
else if(!istype(src, /turf/space))
O.inertia_dir = 0
O.update_gravity(O.mob_has_gravity(src))
var/loopsanity = 100
for(var/atom/A in range(1))
@@ -145,46 +140,6 @@
/turf/proc/return_siding_icon_state() //used for grass floors, which have siding.
return 0
/turf/proc/inertial_drift(atom/movable/A as mob|obj)
if(!(A.last_move)) return
if(istype(A, /obj/spacepod) && src.x > 2 && src.x < (world.maxx - 1) && src.y > 2 && src.y < (world.maxy-1))
var/obj/spacepod/SP = A
if(SP.Process_Spacemove(1))
SP.inertia_dir = 0
return
spawn(5)
if((SP && (SP.loc == src)))
if(SP.inertia_dir)
step(SP, SP.inertia_dir)
return
if(istype(A, /obj/structure/stool/bed/chair/cart/) && src.x > 2 && src.x < (world.maxx - 1) && src.y > 2 && src.y < (world.maxy-1))
var/obj/structure/stool/bed/chair/cart/JC = A //A bomb!
if(JC.Process_Spacemove(1))
JC.inertia_dir = 0
return
spawn(5)
if((JC && (JC.loc == src)))
if(JC.inertia_dir)
step(JC, JC.inertia_dir)
return
JC.inertia_dir = JC.last_move
step(JC, JC.inertia_dir)
if((istype(A, /mob/) && src.x > 2 && src.x < (world.maxx - 1) && src.y > 2 && src.y < (world.maxy-1)))
var/mob/M = A
if(M.Process_Spacemove(1))
M.inertia_dir = 0
return
spawn(5)
if((M && !(M.anchored) && !(M.pulledby) && (M.loc == src)))
if(M.inertia_dir)
step(M, M.inertia_dir)
return
M.inertia_dir = M.last_move
step(M, M.inertia_dir)
return
/turf/proc/levelupdate()
for(var/obj/O in src)
if(O.level == 1)
+9 -31
View File
@@ -29,7 +29,6 @@
var/datum/global_iterator/pr_give_air //moves air from tank to cabin
var/datum/effect/effect/system/ion_trail_follow/space_trail/ion_trail
var/inertia_dir = 0
var/hatch_open = 0
@@ -736,25 +735,6 @@ obj/spacepod/verb/toggleLights()
return stop()
return
/obj/spacepod/Move(NewLoc, Dir = 0, step_x = 0, step_y = 0)
..()
if(dir == 1 || dir == 4)
src.loc.Entered(src)
/obj/spacepod/proc/Process_Spacemove(var/check_drift = 0, mob/user)
var/dense_object = 0
if(!user)
for(var/direction in list(NORTH, NORTHEAST, EAST))
var/turf/cardinal = get_step(src, direction)
if(istype(cardinal, /turf/space))
continue
dense_object++
break
if(!dense_object)
return 0
inertia_dir = 0
return 1
/obj/spacepod/relaymove(mob/user, direction)
if(!CheckIfOccupant2(user))
handlerelaymove(user, direction)
@@ -764,26 +744,24 @@ obj/spacepod/verb/toggleLights()
if(battery && battery.charge >= 3 && health && empcounter == 0)
src.dir = direction
switch(direction)
if(1)
if(inertia_dir == 2)
if(NORTH)
if(inertia_dir == SOUTH)
inertia_dir = 0
moveship = 0
if(2)
if(inertia_dir == 1)
if(SOUTH)
if(inertia_dir == NORTH)
inertia_dir = 0
moveship = 0
if(4)
if(inertia_dir == 8)
if(EAST)
if(inertia_dir == WEST)
inertia_dir = 0
moveship = 0
if(8)
if(inertia_dir == 4)
if(WEST)
if(inertia_dir == EAST)
inertia_dir = 0
moveship = 0
if(moveship)
step(src, direction)
if(istype(src.loc, /turf/space))
inertia_dir = direction
Move(get_step(src, direction), direction)
else
if(!battery)
user << "<span class='warning'>No energy cell detected.</span>"