btmux/autom4te.cache/
btmux/doc/.svn/
btmux/event/.svn/
btmux/game/.svn/
btmux/game/bin/.svn/
btmux/game/data/.svn/
btmux/game/logs/.svn/
btmux/game/maps/
btmux/game/maps/.svn/
btmux/game/maps/.svn/prop-base/
btmux/game/maps/.svn/props/
btmux/game/maps/.svn/text-base/
btmux/game/maps/.svn/wcprops/
btmux/game/mechs/
btmux/game/mechs/.svn/
btmux/game/mechs/.svn/prop-base/
btmux/game/mechs/.svn/props/
btmux/game/mechs/.svn/text-base/
btmux/game/mechs/.svn/wcprops/
btmux/game/text/.svn/
btmux/include/.svn/
btmux/misc/
btmux/misc/.svn/
btmux/misc/.svn/prop-base/
btmux/misc/.svn/props/
btmux/misc/.svn/text-base/
btmux/misc/.svn/wcprops/
btmux/python/
btmux/python/.svn/
btmux/python/.svn/prop-base/
btmux/python/.svn/props/
btmux/python/.svn/text-base/
btmux/python/.svn/wcprops/
btmux/src/.svn/prop-base/
btmux/src/.svn/props/
btmux/src/.svn/text-base/
btmux/src/.svn/wcprops/
btmux/src/hcode/.svn/
btmux/src/hcode/btech/
btmux/src/hcode/btech/.svn/
btmux/src/hcode/btech/.svn/prop-base/
btmux/src/hcode/btech/.svn/props/
btmux/src/hcode/btech/.svn/text-base/
btmux/src/hcode/btech/.svn/wcprops/
btmux/src/hcode/include/.svn/
/*
 * $Id: mech.update.c,v 1.4 2005/08/10 14:09:34 av1-op Exp $
 *
 * Author: Markus Stenberg <fingon@iki.fi>
 *
 *  Copyright (c) 1997 Markus Stenberg
 *  Copyright (c) 1998-2002 Thomas Wouters
 *  Copyright (c) 2000-2002 Cord Awtry
 *  Copyright (c) 1999-2005 Kevin Stevens
 *       All rights reserved
 *
 * Last modified: Tue Jul 21 00:16:07 1998 fingon
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/file.h>

#include "mech.h"
#include "failures.h"
#include "mech.events.h"
#include "mech.ice.h"
#include "p.mech.ecm.h"
#include "p.mech.tag.h"
#include "p.mech.combat.h"
#include "p.mech.combat.misc.h"
#include "p.mech.damage.h"
#include "p.mech.fire.h"
#include "p.mech.startup.h"
#include "p.mech.utils.h"
#include "p.mech.update.h"
#include "p.btechstats.h"
#include "p.mech.physical.h"
#include "p.bsuit.h"
#include "p.mine.h"
#include "p.mech.lite.h"
#include "p.mech.pickup.h"

extern int arc_override;

int fiery_death(MECH * mech)
{
    if (MechTerrain(mech) == FIRE) {
        if (is_aero(mech))
            return 0;
        if (MechMove(mech) == MOVE_VTOL)
            return 0;
        if (Destroyed(mech))
            return 0;

        /* Cause various things */
        /* MWs _die_ */
        if (MechType(mech) == CLASS_MW) {
            mech_notify(mech, MECHALL, "You feel tad bit too warm..");
            mech_notify(mech, MECHALL, "You faint.");
            DestroyMech(mech, mech, 0);
            return 1;
        }

        /* Tanks may die */
        return 0;		/* Dumb idea */
        heat_effect(NULL, mech, 0, 0);
        if (Destroyed(mech))
            return 1;
    }
    return 0;
}

int bridge_w_elevation(MECH * mech)
{
    return -1;
}

void bridge_set_elevation(MECH * mech)
{
    if (MechZ(mech) < (MechUpperElevation(mech) - MoveMod(mech))) {
	if (Overwater(mech))
	    MechZ(mech) = 0;
	else
	    MechZ(mech) = bridge_w_elevation(mech);
	return;
    }
    MechZ(mech) = MechUpperElevation(mech);
}

int DSOkToNotify(MECH * mech)
{
    if (DSLastMsg(mech) > muxevent_tick ||
	(muxevent_tick - DSLastMsg(mech)) >= DS_SPAM_TIME) {
	DSLastMsg(mech) = muxevent_tick;
	return 1;
    }
    return 0;
}

enum {
    JUMP, WALK_WALL, WALK_DROP, HIT_UNDER_BRIDGE, WALK_BACK
};

int collision_check(MECH * mech, int mode, int le, int lt)
{
    int e;
    MAP *mech_map = getMap(mech->mapindex);

    if (Overwater(mech) && le < 0)
	le = 0;
    e = MechElevation(mech);
    if (MechRTerrain(mech) == ICE)
	if (le >= 0)
	    e = 0;
    if (le < (MechUpperElevation(mech) - MoveMod(mech)) && lt == BRIDGE) {
	if (Overwater(mech))
	    le = 0;
	else
	    le = bridge_w_elevation(mech);
    }
    if (e < 0 && Overwater(mech))
	e = 0;
    switch (mode) {
    case JUMP:
	if (MechRTerrain(mech) == BRIDGE) {
	    if (MechZ(mech) < 0)
		return 1;
	    if (MechZ(mech) == (e - 1))
		return 1;
	    return 0;
	} else
	    return (MechZ(mech) < e);
    case WALK_DROP:
	return (le - e) > MoveMod(mech);
    case WALK_WALL:
	if ((MechMove(mech) == MOVE_HOVER) &&
	    (MechRTerrain(mech) == BRIDGE) && (((lt == ICE) ||
		    (lt == WATER)) || ((le == 0) && (lt == BRIDGE)))) {
	    return 0;
	} else {
	    return (e - le) > MoveMod(mech);
	}
	case WALK_BACK:
		if (MechMove(mech) != MOVE_TRACK && MechType(mech) != CLASS_VTOL)
	    return (MechSpeed(mech) < 0 ? abs((le - e)) : 0);
    case HIT_UNDER_BRIDGE:	/* Hovers only... tho it should be fixed for foils and hulls too */
	if ((lt == BRIDGE) && (MechRTerrain(mech) == BRIDGE) && (le == 0)
	    && (Elevation(mech_map, MechLastX(mech), MechLastY(mech)) != 0)
	    && (Elevation(mech_map, MechX(mech), MechY(mech)) == 1))
	    return 1;
	else
	    return 0;
    }
    return 0;
}

void CheckNavalHeight(MECH * mech, int oz);

void move_mech(MECH * mech)
{
    float newx = 0.0, newy = 0.0, dax, day;
    float xy_charge_dist, xscale;
    float jump_pos;

#ifdef ODDJUMP
    float rjump_pos, midmod;
#endif
    int x, y, upd_z = 0;
    int last_z = 0;
    MECH *target;
    MAP *mech_map;
    int oi, oz;
    int iced = 0;

    /* Buffer for printing messages so we don't use the tprintf
     * function anymore */
    char message_buffer[MBUF_SIZE];

    oz = MechZ(mech);
    mech_map = getMap(mech->mapindex);

    if (!mech_map && MechPilot(mech) >= 0)
        mech_map = ValidMap(MechPilot(mech), mech->mapindex);

    /* Unit is not on a map so don't need to move it - instead
     * reset its values and shut it down */
    if (!mech_map) {

        mech_notify(mech, MECHALL,
                "You are on an invalid map! Map index reset!");
        MechCocoon(mech) = 0;

        if (Jumping(mech))
            mech_land(MechPilot(mech), (void *) mech, "");

        mech_shutdown(MechPilot(mech), (void *) mech, "");

        snprintf(message_buffer, MBUF_SIZE, "move_mech:invalid map:Mech: %d Index: %d",
                mech->mynum, mech->mapindex);
        SendError(message_buffer);
        mech->mapindex = -1;
        return;
    }

    /* Is the unit on a valid spot on the map */
    if (MechX(mech) < 0 || MechX(mech) >= mech_map->map_width ||
            MechLastX(mech) < 0 || MechLastX(mech) >= mech_map->map_width ||
            MechY(mech) < 0 || MechY(mech) >= mech_map->map_height ||
            MechLastY(mech) < 0 || MechLastY(mech) >= mech_map->map_height) {

        mech_notify(mech, MECHALL,
                "You are at an invalid map location! Map index reset!");
        MechCocoon(mech) = 0;

        if (Jumping(mech))
            mech_land(MechPilot(mech), (void *) mech, "");

        mech_shutdown(MechPilot(mech), (void *) mech, "");

        snprintf(message_buffer, MBUF_SIZE, "move_mech:invalid map:Mech: %d Index: %d",
                mech->mynum, mech->mapindex);
        SendError(message_buffer);

        mech->mapindex = -1;
        return;
    }

    /* Is the unit charging - and if so have they been charging to long */
    if (mudconf.btech_newcharge && MechChargeTarget(mech) > 0) {
        if (MechChargeTimer(mech)++ > CHARGE_TIMER_LIMIT) {
            mech_notify(mech, MECHALL, "Charge timed out, charge reset.");
            MechChargeTarget(mech) = -1;
            MechChargeTimer(mech) = 0;
            MechChargeDistance(mech) = 0;
        }
    }

    /*! \todo {now that I think about it maybe make a single block
     * of code to check for jumping BEFORE anything else.} */

    /* Check the move type of the unit */
    switch (MechMove(mech)) {
        case MOVE_BIPED:
        case MOVE_QUAD:

            /* Biped/Quad Jumping */
            if (Jumping(mech)) {
                MarkForLOSUpdate(mech);
                FindComponents(JumpSpeed(mech, mech_map) * MOVE_MOD * MAPMOVEMOD(mech_map),
                        MechJumpHeading(mech), &newx, &newy);
                MechFX(mech) += newx;
                MechFY(mech) += newy;
                jump_pos = length_hypotenuse((MechFX(mech) - MechStartFX(mech)),
                        (MechFY(mech) - MechStartFY(mech)));

                /*! \todo {Not sure what ODDJUMP is but need to figure it out, possibly
                 * make this a mudconf parameter} */
#ifndef ODDJUMP
                MechFZ(mech) = ((4 * JumpSpeedMP(mech, mech_map) * ZSCALE)
                        / (MechJumpLength(mech) * MechJumpLength(mech))) *
                    jump_pos * (MechJumpLength(mech) - jump_pos) +
                    MechStartFZ(mech) + jump_pos * (MechEndFZ(mech)
                            - MechStartFZ(mech)) / (MechJumpLength(mech) * HEXLEVEL);
#else
                rjump_pos = MechJumpLength(mech) - jump_pos;
                if (rjump_pos < 0.0)
                    rjump_pos = 0.0;

                /* New flight path: Make a direct line from the origin to
                   destination, and imagine a 1-x^4 in relation to the 0 as
                   the line. y=1 = JumpTop offset, x=0 = middle of path,
                   x=-1 = beginning, x=1 = end */
                midmod = jump_pos / MechJumpLength(mech);
                midmod = (midmod - 0.5) * 2;
                if (MechJumpTop(mech) >= (1 + JumpSpeedMP(mech, mech_map))) {
                    midmod = (1.0 - (midmod * midmod)) * MechJumpTop(mech);
                } else {
                    midmod = (1.0 - (midmod * midmod * midmod * midmod)) *
                        MechJumpTop(mech);
                }

                MechFZ(mech) = (rjump_pos * MechStartFZ(mech) +
                        jump_pos * MechEndFZ(mech)) / MechJumpLength(mech) +
                    midmod * ZSCALE;
#endif

                MechZ(mech) = (int) (MechFZ(mech) / ZSCALE + 0.5);

#ifdef JUMPDEBUG
                snprintf(message_buffer, MBUF_SIZE,
                        "#%d: %d, %d, %d (%d, %d, %d)",
                        mech->mynum, MechX(mech), MechY(mech), MechZ(mech),
                        (int) MechFX(mech), (int) MechFY(mech),
                        (int) MechFZ(mech));
                SendDebug(message_buffer);
#endif

                /* The famous jumping on bridge collision code */
                /*! \todo {possibly turn the bridge collision code into
                 * a mudconf parameter} */
                if (MechRTerrain(mech) == BRIDGE &&
                        collision_check(mech, JUMP, 0, 0) && MechZ(mech) > 0) {

                    mech_notify(mech, MECHALL,
                            "CRASH!! You crash at the bridge!");
                    MechLOSBroadcast(mech, "crashes into the bridge!");
                    MechFalls(mech, 1, 0);
                    return;
                }

                /* Is the jumping unit in its target hex */
                if ((MechX(mech) == MechGoingX(mech)) &&
                        (MechY(mech) == MechGoingY(mech))) {

                    /*Ok.. in the hex. but no instant landings anymore, laddie */
                    /*Range to point of origin is larger than whole jump's length */
                    MapCoordToRealCoord(MechX(mech), MechY(mech), &dax, &day);

                    /*! \todo {Another instance of that crazy ODDJUMP stuff} */
                    /* Basicly checking to see if the unit is in the hex,
                     * the ODDJUMP code looks for the exact center */
#ifdef ODDJUMP
                    if (length_hypotenuse(dax - MechStartFX(mech), 
                                day - MechStartFY(mech)) <=
                            length_hypotenuse(MechFX(mech) - MechStartFX(mech),
                                MechFY(mech) - MechStartFY(mech))) {

                        LandMech(mech);
                        MechFX(mech) = (float) dax;
                        MechFY(mech) = (float) day;
                    }
#else
                    LandMech(mech);
                    MechFX(mech) = (float) dax;
                    MechFY(mech) = (float) day;
#endif
                }

                /* Are we landing on ice */
                if (MechRTerrain(mech) == ICE) {
                    if (oz < -1 && MechZ(mech) >= -1)
                        break_thru_ice(mech);
                    else if (oz >= -1 && MechZ(mech) < -1)
                        drop_thru_ice(mech);
                }

            } else if (fabs(MechSpeed(mech)) > 0.0) {

                /* Ok not jumping but we're moving */
                FindComponents(MechSpeed(mech) * MOVE_MOD *
                        MAPMOVEMOD(mech_map), MechLateral(mech) + MechFacing(mech),
                        &newx, &newy);
                MechFX(mech) += newx;
                MechFY(mech) += newy;

                upd_z = 1;

                /* If we're charging record distance traveled */
                if (MechChargeTarget(mech) > 0 && mudconf.btech_newcharge) {
                    xscale = 1.0 / SCALEMAP;
                    xscale = xscale * xscale;
                    xy_charge_dist = sqrt(xscale * newx * newx + YSCALE2 * newy * newy);
                    MechChargeDistance(mech) += xy_charge_dist;
                }

            } else {

                /* Ok not moving or jumping so don't need to calc a new x,y,z */
                return;
            }
            break;

        case MOVE_TRACK:
        case MOVE_WHEEL:

            /*! \todo {Put the tank JJ code here - for tracked/wheeled} */

            /* Is the tank moving? */
            if (fabs(MechSpeed(mech)) > 0.0) {

                /*! \todo {Possibly put in a mudconf parameter for this since
                 * I think the LATERAL command could check for it} */
#ifndef BT_MOVEMENT_MODES
                FindComponents(MechSpeed(mech) * MOVE_MOD *
                        MAPMOVEMOD(mech_map), MechFacing(mech), &newx, &newy);
#else
                FindComponents(MechSpeed(mech) * MOVE_MOD *
                        MAPMOVEMOD(mech_map), MechLateral(mech) + MechFacing(mech), 
                        &newx, &newy);
#endif
                MechFX(mech) += newx;
                MechFY(mech) += newy;
                upd_z = 1;

                /* If we're charging record the distance traveled */
                if (MechChargeTarget(mech) > 0 && mudconf.btech_newcharge) {
                    xscale = 1.0 / SCALEMAP;
                    xscale = xscale * xscale;
                    xy_charge_dist = sqrt(xscale * newx * newx + YSCALE2 * newy * newy);
                    MechChargeDistance(mech) += xy_charge_dist;
                }

            } else {

                /* Ok not moving or jumping so don't need to calc a new x,y,z */
                return;
            }
            break;

        case MOVE_HOVER:

            /* If we're moving update position */
            if (fabs(MechSpeed(mech)) > 0.0) {

                /*! \todo {Check the todo before this one, mudconf parameter maybe?} */
#ifndef BT_MOVEMENT_MODES
                FindComponents(MechSpeed(mech) * MOVE_MOD *
                        MAPMOVEMOD(mech_map), MechFacing(mech), &newx, &newy);
#else
                FindComponents(MechSpeed(mech) * MOVE_MOD *
                        MAPMOVEMOD(mech_map), MechLateral(mech) + MechFacing(mech), 
                        &newx, &newy);
#endif
                MechFX(mech) += newx;
                MechFY(mech) += newy;
                upd_z = 1;

                /* Record the charge distance */
                if (MechChargeTarget(mech) > 0 && mudconf.btech_newcharge) {
                    xscale = 1.0 / SCALEMAP;
                    xscale = xscale * xscale;
                    xy_charge_dist = sqrt(xscale * newx * newx + YSCALE2 * newy * newy);
                    MechChargeDistance(mech) += xy_charge_dist;
                }

            } else {

                /* Ok not moving or jumping so don't need to calc a new x,y,z */
                return;
            }
            break;

        case MOVE_VTOL:

            /* If we're landed we're not moving */
            if (Landed(mech))
                return;

            /* Use the same code as subs below */
            /*! \todo {VTOLS not able to lateral, nor can subs right now} */

        case MOVE_SUB:

            MarkForLOSUpdate(mech);
            FindComponents(MechSpeed(mech) * MOVE_MOD * MAPMOVEMOD(mech_map),
                    MechFacing(mech), &newx, &newy);
            MechFX(mech) += newx;
            MechFY(mech) += newy;
            MechFZ(mech) += MechVerticalSpeed(mech) * MOVE_MOD;
            MechZ(mech) = MechFZ(mech) / ZSCALE;
            break;

        case MOVE_FLY:

            /* Ok we're in the air */
            if (!Landed(mech)) {

                MarkForLOSUpdate(mech);
                MechFX(mech) += MechStartFX(mech) * MOVE_MOD;
                MechFY(mech) += MechStartFY(mech) * MOVE_MOD;
                MechFZ(mech) += MechStartFZ(mech) * MOVE_MOD;
                MechZ(mech) = MechFZ(mech) / ZSCALE;

                /*! \todo {Need to rewrite this for aerodyne DSes unless they're
                 * set as large aeros which i'm not sure but either way its
                 * probably not good} */
                if (IsDS(mech)) {

                    /* Fun messages to emit to the pilot */
                    if (MechZ(mech) < 10 && oz >= 10)
                        DS_LandWarning(mech, 1);
                    else if (MechZ(mech) < 50 && oz >= 50)
                        DS_LandWarning(mech, 0);
                    else if (MechZ(mech) < 100 && oz >= 100) {

                        if (abs(MechDesiredAngle(mech)) != 90) {
                            if (DSOkToNotify(mech)) {
                                mech_notify(mech, MECHALL, "As the craft enters "
                                        "the lower atmosphere, it's nose rises up "
                                        "for a clean landing..");
                                snprintf(message_buffer, MBUF_SIZE,
                                        "starts descending towards %d, %d..",
                                        MechX(mech), MechY(mech));
                                MechLOSBroadcast(mech, message_buffer);
                            } else {
                                mech_notify(mech, MECHALL, "Due to low altitude, "
                                        "climbing angle set to 90 degrees.");
                            }
                            MechDesiredAngle(mech) = 90;
                        }
                        MechStartFX(mech) = 0.0;
                        MechStartFY(mech) = 0.0;
                        DS_LandWarning(mech, -1);
                    }
                }

            } else {

                /* Ok we're rolling around on the ground */
                if (!(fabs(MechSpeed(mech)) > 0.0))
                    return;

                FindComponents(MechSpeed(mech) * MOVE_MOD *
                        MAPMOVEMOD(mech_map), MechFacing(mech), &newx, &newy);
                MechFX(mech) += newx;
                MechFY(mech) += newy;
                upd_z = 1;
            }
            break;

        case MOVE_HULL:
        case MOVE_FOIL:

            if (fabs(MechSpeed(mech)) > 0.0) {

                FindComponents(MechSpeed(mech) * MOVE_MOD *
                        MAPMOVEMOD(mech_map), MechFacing(mech), &newx, &newy);
                MechFX(mech) += newx;
                MechFY(mech) += newy;
                MechZ(mech) = 0;
                MechFZ(mech) = 0.0;

            } else {

                /* Not moving so no need to update x,y,z and other stuff */
                return;
            }
            break;
    }

    /* We've already updated the floating x,y values, now to update the hex
     * x,y values + both the Z values */
    MechLastX(mech) = MechX(mech);
    MechLastY(mech) = MechY(mech);
    last_z = MechZ(mech);

    RealCoordToMapCoord(&MechX(mech), &MechY(mech), MechFX(mech),
            MechFY(mech));

    /*! \todo {Its the ODDJUMP guy again, whats it for?} */
    /* Checking to make sure we didn't jump PAST our target hex */
#ifdef ODDJUMP
    if (Jumping(mech) && MechLastX(mech) == MechGoingX(mech) &&
            MechLastY(mech) == MechGoingY(mech) &&
            (MechX(mech) != MechLastX(mech) ||
             MechY(mech) != MechLastY(mech))) {

        LandMech(mech);
        MechFX(mech) -= newx;
        MechFY(mech) -= newy;
        MechFZ(mech) = MechEndFZ(mech);
        MechX(mech) = MechGoingX(mech);
        MechY(mech) = MechGoingY(mech);
        MapCoordToRealCoord(MechX(mech), MechY(mech), &MechFX(mech),
                &MechFY(mech));
        MechZ(mech) = MechFZ(mech) / ZSCALE;
    }
#endif

    /* Store the current map index */
    oi = mech->mapindex;
    
    /* Did we hit mapedge? */
    CheckEdgeOfMap(mech);

    /* Did our mapindex change? - like did we run out a hangar? */
    if (mech->mapindex != oi)
        mech_map = getMap(mech->mapindex);

    /* We left a hangar and/or moved to a new hex */
    if (oi != mech->mapindex || MechLastX(mech) != MechX(mech) ||
            MechLastY(mech) != MechY(mech)) {

        /* Either the mech or the map is bad */
        if (!mech || !mech_map) {

            snprintf(message_buffer, MBUF_SIZE,
                    "Invalide pointer (%s) in move_mech()",
                    (!mech ? "mech" : !mech_map ? "mech_map" : "weird...."));
            SendError(message_buffer);

            if (mech) {

                /* Bad Map */
                mech_notify(mech, MECHALL, "You are on an invalid map! Map index reset!");
                MechCocoon(mech) = 0;

                if (Jumping(mech))
                    mech_land(MechPilot(mech), (void *) mech, "");

                mech_shutdown(MechPilot(mech), (void *) mech, "");
                snprintf(message_buffer, MBUF_SIZE,
                        "move_mech:invalid map:Mech: %d Index: %d",
                        mech->mynum, mech->mapindex);
                SendError(message_buffer);
                mech->mapindex = -1;
            }
            return;
        }

        /* We've moved from our hex so break our cover */
        if (MechCritStatus(mech) & HIDDEN) {
            mech_notify(mech, MECHALL, "You move too much and break your cover!");
            MechLOSBroadcast(mech, "breaks from its cover.");
            MechCritStatus(mech) &= ~(HIDDEN);
        }

        StopHiding(mech);

        x = MechX(mech);
        y = MechY(mech);
        MechTerrain(mech) = GetTerrain(mech_map, x, y);
        MechElev(mech) = GetElev(mech_map, x, y);

        /* Update our Z values */
        if (upd_z) {

            /* Chance of breaking through ICE */
            if (MechRTerrain(mech) == ICE) {
                if (oz < -1 && MechZ(mech) >= -1)
                    break_thru_ice(mech);
                else if (MechZ(mech) == 0)
                    if (possibly_drop_thru_ice(mech))
                        iced = 1;
            }

            /* Check for bridges and basic elevation changes */
            DropSetElevation(mech, 0);

            /* To fix certain slide-under-ice-effect for _mechs_ */
            if (MechType(mech) == CLASS_MECH && MechRTerrain(mech) == ICE
                    && oz == -1 && MechZ(mech) == -1) {

                MechZ(mech) = 0;
                MechFZ(mech) = MechZ(mech) * ZSCALE;
            }
        }

        if (!iced)
            NewHexEntered(mech, mech_map, newx, newy, last_z);

        if (MechX(mech) == x && MechY(mech) == y) {

            MarkForLOSUpdate(mech);
            MechFloods(mech);
            water_extinguish_inferno(mech);
            steppable_base_check(mech, x, y);

            /* Pilot XP */
            if (In_Character(mech->mynum)) {
                MechHexes(mech)++;
                if (!(MechHexes(mech) % PIL_XP_EVERY_N_STEPS))
                    if (RGotPilot(mech))
                        AccumulatePilXP(MechPilot(mech), mech, 1, 0);
            }

            /* Check for stacking */
            domino_space(mech, 0);
        }
    }

    /* If aero/vtol make sure we're not rubbing against the ground or trees */
    if ((MechMove(mech) == MOVE_VTOL || is_aero(mech)) && !Landed(mech))
        CheckVTOLHeight(mech);
    
    /* If we're a boat make sure we've not run a ground */
    if (MechType(mech) == CLASS_VEH_NAVAL)
        CheckNavalHeight(mech, oz);
   
    /* We're charging lets do some damage */
    if (MechChargeTarget(mech) != -1) {

        /* Valid target? */
        target = getMech(MechChargeTarget(mech));
        if (target) {

            if (FaMechRange(mech, target) < CHARGE_DIST_TRIGGER) {
                ChargeMech(mech, target);
                MechChargeTarget(mech) = -1;
                MechChargeTimer(mech) = 0;
                MechChargeDistance(mech) = 0;
            }

        } else {
            mech_notify(mech, MECHPILOT, "Invalid CHARGE target!");
            MechChargeTarget(mech) = -1;
            MechChargeDistance(mech) = 0;
            MechChargeTimer(mech) = 0;
        }
    }

    /* If we're towing something update its position with us */
    if (MechCarrying(mech) > 0) {
        target = getMech(MechCarrying(mech));
        if (target && target->mapindex == mech->mapindex) {
            MirrorPosition(mech, target, 0);
            SetRFacing(target, MechRFacing(mech));
        }
    }

    /* If a bsuit has swarmed a target update its
     * position in relation to its target */
    BSuitMirrorSwarmedTarget(mech_map, mech);

    /* This is really for killing MechWarriors 
     * actual heat code is checked with UpdateHeat */
    fiery_death(mech);
}

void CheckNavalHeight(MECH * mech, int oz)
{
    if (MechRTerrain(mech) != WATER && MechRTerrain(mech) != ICE &&
	MechRTerrain(mech) != BRIDGE) {
	MechSpeed(mech) = 0.0;
	MechVerticalSpeed(mech) = 0;
	MechDesiredSpeed(mech) = 0.0;
	SetFacing(mech, 0);
	MechDesiredFacing(mech) = 0;
	return;
    }
    if (!oz && MechZ(mech) && MechElev(mech) > 1) {
	MarkForLOSUpdate(mech);
	MechZ(mech) = 0;
	MechLOSBroadcast(mech, "dives!");
	MechZ(mech) = -1;
    }
    if (MechFZ(mech) > 0.0) {
	if (MechVerticalSpeed(mech) > 0 && !MechZ(mech) && oz < 0) {
	    mech_notify(mech, MECHALL,
		"Your sub has reached surface and stops rising.");
	    MechLOSBroadcast(mech, tprintf("surfaces at %d,%d!",
		    MechX(mech), MechY(mech)));
	    /* Possible show-up message? */
	}
	MechZ(mech) = 0;
	MechFZ(mech) = 0.0;
	if (MechVerticalSpeed(mech) > 0)
	    MechVerticalSpeed(mech) = 0;
	return;
    }
    if (MechZ(mech) <= (MechLowerElevation(mech))) {
	MechZ(mech) = MIN(0, MechLowerElevation(mech) + 1);
	if (MechElevation(mech) > 0)
	    SendError(tprintf
		("Oddity: #%d managed to wind up on '%c' (%d elev.)",
		    mech->mynum, MechTerrain(mech), MechElev(mech)));
	MechFZ(mech) = ((5.0 * MechZ(mech) - 4) * ZSCALE) / 5.0;
	if (MechMove(mech) == MOVE_SUB) {
	    if (MechVerticalSpeed(mech) < 0) {
		MechVerticalSpeed(mech) = 0;
		mech_notify(mech, MECHALL,
		    "The sub has reached bottom and stops diving.");
	    }
#if 0
	    else
		mech_notify(mech, MECHALL, "The sub has reached bottom.");
#endif
	}
    }
}

void CheckVTOLHeight(MECH * mech)
{
    if (InWater(mech) && MechZ(mech) <= 0) {
	mech_notify(mech, MECHALL,
	    "You crash your vehicle into the water!!");
	mech_notify(mech, MECHALL,
	    "Water pours into the cockpit....gulp!");
	MechLOSBroadcast(mech, "splashes into the water!");
	DestroyAndDump(mech);
	return;
    }
    if (MechZ(mech) >= MechElevation(mech))
	return;
    if (MechRTerrain(mech) == BRIDGE)
	if (MechZ(mech) != (MechElevation(mech) - 1))
	    return;
    aero_land(MechPilot(mech), mech, "");
    if (Landed(mech))
	return;
    mech_notify(mech, MECHALL,
	"CRASH!! You smash your toy into the ground!!");
    MechLOSBroadcast(mech, "crashes into the ground!");
    MechFalls(mech, 1 + fabs(MechVerticalSpeed(mech) / MP1), 0);

/*   mech_notify (mech, MECHALL, "Your vehicle is inoperable."); */
    MechZ(mech) = MechElevation(mech);
    MechFZ(mech) = ZSCALE * MechZ(mech);
    MechSpeed(mech) = 0.0;
    MechVerticalSpeed(mech) = 0.0;
    MechStatus(mech) |= LANDED;

/*   DestroyMech (mech, mech); */
}

void UpdateHeading(MECH * mech)
{
    int offset;
    int normangle;
    int mw_mod = 1;
    float maxspeed, omaxspeed;
    MAP *mech_map;

    if (MechFacing(mech) == MechDesiredFacing(mech))
	return;
    maxspeed = MMaxSpeed(mech);
    if (is_aero(mech))
	maxspeed = maxspeed * ACCEL_MOD;
    if ((MechHeat(mech) >= 9.) &&
	(MechSpecials(mech) & TRIPLE_MYOMER_TECH))
	maxspeed += 1.5 * MP1;
    omaxspeed = maxspeed;
    normangle = MechRFacing(mech) - SHO2FSIM(MechDesiredFacing(mech));
    if (MechType(mech) == CLASS_MW || MechType(mech) == CLASS_BSUIT)
	mw_mod = 60;
    else if (MechIsQuad(mech))
	mw_mod = 2;
    if (mudconf.btech_fasaturn) {
#define FASA_TURN_MOD 3/2
	if (Jumping(mech))
	    offset = 2 * SHO2FSIM(1) * 2 * 360 * FASA_TURN_MOD / 60;
	else {
	    float ts = MechSpeed(mech);

	    if (ts < 0) {
		maxspeed = maxspeed * 2.0 / 3.0;
		ts = -ts;
	    }
	    if (ts > maxspeed || maxspeed < 0.1)	/* kludge */
		offset = 0;
	    else {
		offset = SHO2FSIM(1) * 2 * 360 * FASA_TURN_MOD / 60 * (maxspeed - ts) * (omaxspeed / maxspeed) * mw_mod * MP_PER_KPH / 6;	/* hmm. */
	    }
	}
    } else {
	if (Jumping(mech)) {
	    mech_map = FindObjectsData(mech->mapindex);
	    offset =
		SHO2FSIM(1) * 6 * JumpSpeedMP(mech, mech_map) * mw_mod;
	} else if (fabs(MechSpeed(mech)) < 1.0)
	    offset = SHO2FSIM(1) * 3 * maxspeed * MP_PER_KPH * mw_mod;
	else {
	    offset = SHO2FSIM(1) * 2 * maxspeed * MP_PER_KPH * mw_mod;
	    if ((SHO2FSIM(abs(normangle)) > offset) &&
		IsRunning(MechSpeed(mech), maxspeed)) {
		if (MechSpeed(mech) > maxspeed)
		    offset -= offset / 2 * maxspeed / MechSpeed(mech);
		else
		    offset -=
			offset / 2 * (3.0 * MechSpeed(mech) / maxspeed -
			2.0);
	    }
	}
    }
    /*   offset = offset * 2 * MOVE_MOD; - Twice as fast as this;dunno why - */
    offset = offset * MOVE_MOD;
#ifdef BT_MOVEMENT_MODES
    if(GetTurnMode(mech) && HasBoolAdvantage(MechPilot(mech), "maneuvering_ace"))
         offset = (offset * 3 ) /2 ;
    if (MechStatus2(mech) & (SPRINTING|EVADING) && !HasBoolAdvantage(MechPilot(mech), "maneuvering_ace")) {
	if (HasBoolAdvantage(MechPilot(mech), "speed_demon"))
	    offset = (offset * 2) / 3;
	else
	    offset = (offset / 2);
    }
#endif
    if (normangle < 0)
	normangle += SHO2FSIM(360);
    if (IsDS(mech) && offset >= SHO2FSIM(10))
	offset = SHO2FSIM(10);
    if (normangle > SHO2FSIM(180)) {
	AddRFacing(mech, offset);
	if (MechFacing(mech) >= 360)
	    AddFacing(mech, -360);
	normangle += offset;
	if (normangle >= SHO2FSIM(360))
	    SetRFacing(mech, SHO2FSIM(MechDesiredFacing(mech)));
    } else {
	AddRFacing(mech, -offset);
	if (MechRFacing(mech) < 0)
	    AddFacing(mech, 360);
	normangle -= offset;
	if (normangle < 0)
	    SetRFacing(mech, SHO2FSIM(MechDesiredFacing(mech)));
    }
    MechCritStatus(mech) |= CHEAD;
    MarkForLOSUpdate(mech);
}

/* MPs lost for heat need to go off walking speed, not off total speed */
#define DECREASE_HEAT(spd) \
tempspeed *= (ceil((rint((maxspeed / 1.5) / MP1) - (spd/MP1) ) * 1.5) * MP1) / maxspeed

#define DECREASE_OLD(spd) \
tempspeed *= (maxspeed - (spd)) / maxspeed
#define INCREASE_OLD(spd) DECREASE_OLD(-(spd))

#define DECREASE_NEW(spd) \
tempspeed *= MP1 / (MP1 + spd)
#define INCREASE_NEW(spd) \
tempspeed *= (MP1 + spd/2) / MP1

#define DECREASE(s) DECREASE_NEW(s)
#define INCREASE(s) INCREASE_NEW(s)

/* If you want to simulate _OLDs, you have to add 1MP in some cases (eww) */

float terrain_speed(MECH * mech, float tempspeed, float maxspeed,
    int terrain, int elev)
{
    switch (terrain) {
    case SNOW:
    case ROUGH:
	DECREASE(MP1);
	break;
    case MOUNTAINS:
	DECREASE(MP2);
	break;
    case LIGHT_FOREST:
	if (MechType(mech) != CLASS_BSUIT)
	    DECREASE(MP1);
	break;
    case HEAVY_FOREST:
	if (MechType(mech) != CLASS_BSUIT)
	    DECREASE(MP2);
	break;
    case BRIDGE:
    case ROAD:
	/* Ground units (wheeled and tracked) get +1 MP moving on paved surface */
#ifndef BT_MOVEMENT_MODES
	if (MechMove(mech) == MOVE_TRACK || MechMove(mech) == MOVE_WHEEL)
#else
	if (!(MechStatus2(mech) & SPRINTING) &&
		(MechMove(mech) == MOVE_TRACK || MechMove(mech) == MOVE_WHEEL))
#endif
	    INCREASE_OLD(MP1);
    case ICE:
	if (MechZ(mech) >= 0)
	    break;
	/* FALLTHRU */
	/* if he's under the ice/bridge, treat as water. */
    case WATER:
	if (MechIsBiped(mech) || MechIsQuad(mech)) {
	    if (elev <= -2)
		DECREASE(MP3);
	    else if (elev == -1)
		DECREASE(MP1);
	}
	break;
    }
    return tempspeed;
}

void UpdateSpeed(MECH * mech)
{
    float acc, tempspeed, maxspeed;
    MECH *target;

    if (!(!Fallen(mech) && !Jumping(mech) && (MechMaxSpeed(mech) > 0.0)))
	return;
    tempspeed = fabs(MechDesiredSpeed(mech));
    maxspeed = MMaxSpeed(mech);
    if (maxspeed < 0.0)
	maxspeed = 0.0;

    if ((MechStatus(mech) & MASC_ENABLED) &&
	(MechStatus(mech) & SCHARGE_ENABLED))
	maxspeed = ceil((rint(maxspeed / 1.5) / MP1) * 2.5) * MP1;
    else if (MechStatus(mech) & MASC_ENABLED)
	maxspeed = (4. / 3.) * maxspeed;
    else if (MechStatus(mech) & SCHARGE_ENABLED)
	maxspeed = (4. / 3.) * maxspeed;

    if (MechSpecials(mech) & TRIPLE_MYOMER_TECH) {
	if (MechHeat(mech) >= 9.)
	    maxspeed =
		ceil((rint((MMaxSpeed(mech) / 1.5) / MP1) +
		    1) * 1.5) * MP1;
	/* maxspeed *= ((maxspeed + 1.5 * MP1) / maxspeed); */
	if (MechDesiredSpeed(mech) >= maxspeed)
	    MechDesiredSpeed(mech) = maxspeed;
    }

    if (MechHeat(mech) >= 5.) {

/*  if ((MechHeat(mech) >= 9.) && (MechSpecials(mech) & TRIPLE_MYOMER_TECH)) {
      tempspeed *= ((maxspeed + 1.5 * MP1) / maxspeed);
  }
*/
	if (MechHeat(mech) >= 25.)
	    DECREASE_HEAT(MP5);
	else if (MechHeat(mech) >= 20.)
	    DECREASE_HEAT(MP4);
	else if (MechHeat(mech) >= 15.)
	    DECREASE_HEAT(MP3);
	else if (MechHeat(mech) >= 10.)
	    DECREASE_HEAT(MP2);
	else if (!((MechSpecials(mech) & TRIPLE_MYOMER_TECH) &&
		MechHeat(mech) >= 9))
	    DECREASE_HEAT(MP1);
    }
    if (MechType(mech) != CLASS_MW && MechMove(mech) != MOVE_VTOL &&
	(MechMove(mech) != MOVE_FLY || Landed(mech)))
	tempspeed =
	    terrain_speed(mech, tempspeed, maxspeed, MechRTerrain(mech),
	    MechElevation(mech));
    if (MechCritStatus(mech) & CHEAD) {
	if (mudconf.btech_slowdown == 2) {
	    /* _New_ slowdown based on facing vs desired difference */
	    int dif = MechFacing(mech) - MechDesiredFacing(mech);

	    if (dif < 0)
		dif = -dif;
	    if (dif > 180)
		dif = 360 - dif;
	    if (dif) {
		dif = (dif - 1) / 30;
		dif = (dif + 2);	/* whee */
		/* dif = 2 to 7 */
		tempspeed = tempspeed * (10 - dif) / 10;
	    }
	} else if (mudconf.btech_slowdown == 1) {
	    if (MechFacing(mech) != MechDesiredFacing(mech))
		tempspeed = tempspeed * 2.0 / 3.0;
	    else
		tempspeed = tempspeed * 3.0 / 4.0;
	}
#ifdef BT_MOVEMENT_MODES
	if ((Sprinting(mech) || Evading(mech)) && !(HasBoolAdvantage(MechPilot(mech), "speed_demon") || HasBoolAdvantage(MechPilot(mech), "maneuvering_ace")))
	    tempspeed = (tempspeed * 2) / 3;
#endif
	MechCritStatus(mech) &= ~CHEAD;
    }
    if (MechIsQuad(mech) && MechLateral(mech))
	DECREASE_OLD(MP1);	/* In truth 1 MP */
#ifdef BT_MOVEMENT_MODES
    else if (MechLateral(mech)) {
	if (HasBoolAdvantage(MechPilot(mech), "maneuvering_ace"))
	    DECREASE_OLD(MP2);
	else
	    DECREASE_OLD(MP3);
    }
#endif
    if (tempspeed <= 0.0)
	tempspeed = 0.0;
    if (MechDesiredSpeed(mech) < 0.)
	tempspeed = -tempspeed;

/*    if (MechSpecials(mech) & TRIPLE_MYOMER_TECH)
        {
        if (MechHeat(mech) >= 9.)
            maxspeed *= ((maxspeed + 1.5 * MP1) / maxspeed);
  if (MechDesiredSpeed(mech) >= maxspeed)
    MechDesiredSpeed(mech) = maxspeed;
        }
*/

    if (tempspeed != MechSpeed(mech)) {
	if (MechIsQuad(mech))
	    acc = maxspeed / 10.;
	else
	    acc = maxspeed / 20.;
	if (HasBoolAdvantage(MechPilot(mech), "speed_demon"))
	    acc *= 1.25;

	if (tempspeed < MechSpeed(mech)) {
	    /* Decelerating */
	    MechSpeed(mech) -= acc;
	    if (tempspeed > MechSpeed(mech))
		MechSpeed(mech) = tempspeed;
	} else {
	    /* Accelerating */
	    MechSpeed(mech) += acc;
	    if (tempspeed < MechSpeed(mech))
		MechSpeed(mech) = tempspeed;
	}
    }
    if (MechCarrying(mech) > 0) {
	target = getMech(MechCarrying(mech));
	if (target)
	    MechSpeed(target) = MechSpeed(mech);
    }
}




int OverheatMods(MECH * mech)
{
    int returnValue;

    if (MechHeat(mech) >= 24.) {
	/* +4 to fire... */
	returnValue = 4;
    } else if (MechHeat(mech) >= 17.) {
	/* +3 to fire... */
	returnValue = 3;
    } else if (MechHeat(mech) >= 13.) {
	/* +2 to fire... */
	returnValue = 2;
    } else if (MechHeat(mech) >= 8.) {
	/* +1 to fire... */
	returnValue = 1;
    } else {
	returnValue = 0;
    }
    return (returnValue);
}

void ammo_explosion(MECH * attacker, MECH * mech, int ammoloc,
    int ammocritnum, int damage)
{
    if (MechType(mech) == CLASS_MW) {
	mech_notify(mech, MECHALL, "Your weapon's ammo explodes!");
	MechLOSBroadcast(mech, "'s weapon's ammo explodes!");
    } else {
	mech_notify(mech, MECHALL, "Ammunition explosion!");
	if (GetPartAmmoMode(mech, ammoloc, ammocritnum) & INFERNO_MODE)
	    MechLOSBroadcast(mech,
		"is suddenly enveloped by a brilliant fireball!");
	else
	    MechLOSBroadcast(mech, "has an internal ammo explosion!");
    }
    DestroyPart(mech, ammoloc, ammocritnum);
    if (!attacker)
	return;
    if (GetPartAmmoMode(mech, ammoloc, ammocritnum) & INFERNO_MODE) {
	Inferno_Hit(mech, mech, damage / 4, 0);
	damage = damage / 2;
    }
    if (MechType(mech) == CLASS_BSUIT)
	DamageMech(mech, attacker, 0, -1, ammoloc, 0, 0, damage, 0, -1, 0,
	    -1, 0, 0);
    else
	DamageMech(mech, attacker, 0, -1, ammoloc, 0, 0, -1, damage, -1, 0,
	    -1, 0, 0);

    if (MechType(mech) != CLASS_BSUIT) {
	mech_notify(mech, MECHPILOT,
	    "You take personal injury from the ammunition explosion!");
	if (HasBoolAdvantage(MechPilot(mech), "pain_resistance"))
	    headhitmwdamage(mech, 1);
	else
	headhitmwdamage(mech, 2);
    }
}

void HandleOverheat(MECH * mech)
{
    int avoided = 0;
    MAP *mech_map;

    if (MechHeat(mech) < 14.)
	return;
    /* Has it been a TURN already ? */
    if ((MechHeatLast(mech) + TURN) > muxevent_tick)
	return;
    MechHeatLast(mech) = muxevent_tick;
#ifdef BT_EXILE_MW3STATS
  if (!isPlayer(MechPilot(mech))) {
#endif
    if (MechHeat(mech) >= 30.) {
	/* Shutdown */
    } else if (MechHeat(mech) >= 26.) {
	/* Shutdown avoid on 10+ */
	if (Roll() >= 10)
	    avoided = 1;
    } else if (MechHeat(mech) >= 22.) {
	/* Shutdown avoid on 8+ */
	if (Roll() >= 8)
	    avoided = 1;
    } else if (MechHeat(mech) >= 18.) {
	/* Shutdown avoid on 6+ */
	if (Roll() >= 6)
	    avoided = 1;
    } else if (MechHeat(mech) >= 14.) {
	/* Shutdown avoid on 4+ */
	if (Roll() >= 4)
	    avoided = 1;
    }
#ifdef BT_EXILE_MW3STATS
  } else {
    mech_notify(mech, MECHALL, "You franticly attempt to override the shutdown process!");
    avoided = char_getskillsuccess(MechPilot(mech), "computer", (MechHeat(mech) >= 30. ? 8 : MechHeat(mech) >= 26. ? 6 : MechHeat(mech) >= 22. ? 4 : MechHeat(mech) >=18. ? 2 : 0), 1);
    if (avoided)
        AccumulateComputerXP(MechPilot(mech), mech, 1);
  }
#endif
    if (!(avoided) && Started(mech)) {
	if (MechStatus(mech) & STARTED)
	    mech_notify(mech, MECHALL, "%ci%crReactor shutting down...%c");
	if (Jumping(mech) || OODing(mech) || (is_aero(mech) &&
		!Landed(mech))) {
	    mech_notify(mech, MECHALL, "%chYou fall from the sky!!!!!%c");
	    MechLOSBroadcast(mech, "falls from the sky!");
	    mech_map = getMap(mech->mapindex);
	    MechFalls(mech, JumpSpeedMP(mech, mech_map), 0);
	    domino_space(mech, 2);
	} else
	    MechLOSBroadcast(mech, "stops in mid-motion!");
	Shutdown(mech);
	StopMoving(mech);
	StopStand(mech);
    }
    avoided = 0;
    /* Ammo */
    if (MechHeat(mech) >= 19.) {
	if (MechHeat(mech) >= 28.) {
	    /* Ammo explosion (Avoid 8+) */
	    if (Roll() >= 8)
		avoided = 1;
	} else if (MechHeat(mech) >= 23.) {
	    /* Ammo explosion (Avoid 6+) */
	    if (Roll() >= 6)
		avoided = 1;
	} else if (MechHeat(mech) >= 19.) {
	    /* Ammo explosion (Avoid 4+) */
	    if (Roll() >= 4)
		avoided = 1;
	}
	if (!(avoided)) {
	    int ammoloc, ammocritnum, damage;

	    damage = FindDestructiveAmmo(mech, &ammoloc, &ammocritnum);
	    if (damage) {
		/* BOOM! */
		/* That's going to hurt... */
		ammo_explosion(mech, mech, ammoloc, ammocritnum, damage);
	    } else
		mech_notify(mech, MECHALL,
		    "You have no ammunition, lucky you!");
	}
    }
}

static int EnableSomeHS(MECH * mech)
{
    int numsinks = HS_Efficiency(mech);
    numsinks = MIN(numsinks, MechDisabledHS(mech));
    if (!numsinks)
	return 0;
    MechDisabledHS(mech) -= numsinks;
    MechMinusHeat(mech) += numsinks;	/* We dont check for water and such after enabling them, only the next tic. */
#ifdef HEATCUTOFF_DEBUG
    mech_notify(mech, MECHALL,
	tprintf("%%cg%d heatsink%s kick%s into action.%%c", numsinks,
	    numsinks == 1 ? "" : "s", numsinks == 1 ? "s" : ""));
#endif
    return numsinks;
}

static int DisableSomeHS(MECH * mech)
{
    int numsinks = HS_Efficiency(mech);
    numsinks = MIN(numsinks, MechActiveNumsinks(mech));
    if (!numsinks)
	return 0;
    MechDisabledHS(mech) += numsinks;
    MechMinusHeat(mech) -= numsinks;	/* Submerged heatsinks silently still dissipate some heat */
#ifdef HEATCUTOFF_DEBUG
    mech_notify(mech, MECHALL,
	tprintf("%%cy%d heatsink%s hum%s into silence.%%c", numsinks,
	    numsinks == 1 ? "" : "s", numsinks == 1 ? "s" : ""));
#endif
    return numsinks;
}

void UpdateHeat(MECH * mech)
{
    int legsinks;
    float maxspeed;
    float intheat;
    float inheat;
    MAP *map;

    if (MechType(mech) != CLASS_MECH && MechType(mech) != CLASS_AERO)
	return;
    inheat = MechHeat(mech);
    maxspeed = MMaxSpeed(mech);
    MechPlusHeat(mech) = 0.;
    if (MechTerrain(mech) == FIRE && MechType(mech) == CLASS_MECH)
	MechPlusHeat(mech) += 5.;
    if (fabs(MechSpeed(mech)) > 0.0) {
#ifndef BT_MOVEMENT_MODES
	if (IsRunning(MechDesiredSpeed(mech), maxspeed))
	    MechPlusHeat(mech) += 2.;
#else
	if (Sprinting(mech) || Evading(mech))
	    MechPlusHeat(mech) += 3.;
	else if (IsRunning(MechDesiredSpeed(mech), maxspeed))
	    MechPlusHeat(mech) += 2.;
#endif
	else
	    MechPlusHeat(mech) += 1.;
    }
    if (Jumping(mech))
	MechPlusHeat(mech) +=
	    (MechJumpSpeed(mech) * MP_PER_KPH >
	    3.) ? MechJumpSpeed(mech) * MP_PER_KPH : 3.;

    if (Started(mech))
	MechPlusHeat(mech) += (float) MechEngineHeat(mech);

    if (StealthArmorActive(mech))
	MechPlusHeat(mech) += 10;

    if (NullSigSysActive(mech))
	MechPlusHeat(mech) += 10;

    intheat = MechPlusHeat(mech);

    MechPlusHeat(mech) += MechWeapHeat(mech);

    /* ADD Water effects here */
    if (InWater(mech) && MechZ(mech) <= -1) {
	legsinks = FindLegHeatSinks(mech);
	legsinks = (legsinks > 4) ? 4 : legsinks;
	if (MechZ(mech) == -1 && !Fallen(mech)) {
	    MechMinusHeat(mech) = MIN(2 * MechActiveNumsinks(mech),
	    	legsinks + MechActiveNumsinks(mech));
	} else {
	    MechMinusHeat(mech) = MIN(2 * MechActiveNumsinks(mech),
	    	6 + MechActiveNumsinks(mech));
	}
    } else {
	MechMinusHeat(mech) = (float) (MechActiveNumsinks(mech));
    }
    if (Jellied(mech)) {
	MechMinusHeat(mech) = MechMinusHeat(mech) - 6;
	if (MechMinusHeat(mech) < 0)
	    MechMinusHeat(mech) = 0;
    }
    if (InSpecial(mech))
	if ((map = FindObjectsData(mech->mapindex)))
	    if (MapUnderSpecialRules(map))
		if (MapTemperature(map) < -30 || MapTemperature(map) > 50) {
		    if (MapTemperature(map) < -30)
			MechMinusHeat(mech) +=
			    (-30 - MapTemperature(map) + 9) / 10;
		    else
			MechMinusHeat(mech) -=
			    (MapTemperature(map) - 50 + 9) / 10;
		}

    /* Handle heat cutoff now */
    /* En/DisableSomeHS() take care of MechMinusHeat also. */
    if (Heatcutoff(mech)) {
	float overheat = MechPlusHeat(mech) - MechMinusHeat(mech);

	if (overheat >= 9. + HS_Efficiency(mech))
	    EnableSomeHS(mech);
	else if (overheat < 9.)
	    DisableSomeHS(mech);
    } else if (MechDisabledHS(mech))
	EnableSomeHS(mech);

    MechHeat(mech) = MechPlusHeat(mech) - MechMinusHeat(mech);

    /* No lowering of heat if heat is under 9 */
    MechWeapHeat(mech) -=
	(MechMinusHeat(mech) - intheat) / WEAPON_RECYCLE_TIME;
    if (MechWeapHeat(mech) < 0.0)
	MechWeapHeat(mech) = 0.0;


    if (MechHeat(mech) < 0.0)
	MechHeat(mech) = 0.0;

    if ((muxevent_tick % TURN) == 0)
	if (MechCritStatus(mech) & LIFE_SUPPORT_DESTROYED ||
	    (MechHeat(mech) > 30. && Number(0, 1) == 0)) {
	    if (MechHeat(mech) > 25.) {
		mech_notify(mech, MECHPILOT,
		    "You take personal injury from heat!!");
		headhitmwdamage(mech,
		    MechCritStatus(mech) & LIFE_SUPPORT_DESTROYED ? 2 : 1);
	    } else if (MechHeat(mech) >= 15.) {
		mech_notify(mech, MECHPILOT,
		    "You take personal injury from heat!!");
		headhitmwdamage(mech, 1);
	    }
	}
    if (MechHeat(mech) >= 19) {
	if (inheat < 19) {
	    mech_notify(mech, MECHALL,
		"%ch%cr=====================================");
	    mech_notify(mech, MECHALL,
		"Your Excess Heat indicator turns RED!");
	    mech_notify(mech, MECHALL,
		"=====================================%c");
	}
    } else if (MechHeat(mech) >= 14) {
	if (inheat >= 19 || inheat < 14) {
	    mech_notify(mech, MECHALL,
		"%ch%cy=======================================");
	    mech_notify(mech, MECHALL,
		"Your Excess Heat indicator turns YELLOW");
	    mech_notify(mech, MECHALL,
		"=======================================%c");
	}
    } else {
	if (inheat >= 14) {
	    mech_notify(mech, MECHALL,
		"%cg======================================");
	    mech_notify(mech, MECHALL,
		"Your Excess Heat indicator turns GREEN");
	    mech_notify(mech, MECHALL,
		"======================================%c");
	}
    }
    HandleOverheat(mech);
}

int recycle_weaponry(MECH * mech)
{

    int loop;
    int count, i;
    int crit[MAX_WEAPS_SECTION];
    unsigned char weaptype[MAX_WEAPS_SECTION];
    unsigned char weapdata[MAX_WEAPS_SECTION];
    char location[20];

    int diff = (muxevent_tick - MechLWRT(mech));
    int lowest = 0;

    if (diff < 1) {
	if (diff < 0)
	    MechLWRT(mech) = muxevent_tick;
	return 1;
    }
    MechLWRT(mech) = muxevent_tick;

    if (!Started(mech) || Destroyed(mech))
	return 0;

    arc_override = 1;
    for (loop = 0; loop < NUM_SECTIONS; loop++) {
	count = FindWeapons(mech, loop, weaptype, weapdata, crit);
	for (i = 0; i < count; i++) {
	    if (WpnIsRecycling(mech, loop, crit[i])) {
		if (diff >= GetPartData(mech, loop, crit[i])) {
		    GetPartData(mech, loop, crit[i]) = 0;
		    mech_notify(mech, MECHSTARTED,
			tprintf(MechType(mech) ==
			    CLASS_MW ?
			    "%%cgYou are ready to attack again with %s.%%c"
			    : PartTempNuke(mech, loop,
				crit[i]) !=
			    0 ? "%%cg%s is operational again.%%c" :
			    (GetPartFireMode(mech, loop,
				    crit[i]) & ROCKET_FIRED) ? "" :
			    "%%cg%s finished recycling.%%c",
			    &MechWeapons[weaptype[i]].name[3]));
		    SetPartTempNuke(mech, loop, crit[i], 0);
		} else {
		    if (PartTempNuke(mech, loop,
			    crit[i]) != FAIL_DESTROYED) {
			GetPartData(mech, loop, crit[i]) -= diff;
			if (GetPartData(mech, loop, crit[i]) < lowest ||
			    !lowest)
			    lowest = GetPartData(mech, loop, crit[i]);
		    }
		}
	    }
	}

    /* Cycle a section */
    if (MechSections(mech)[loop].recycle &&
            ((MechType(mech) == CLASS_MECH) 
             || (MechType(mech) == CLASS_BSUIT)
             || (MechType(mech) == CLASS_VEH_GROUND)
             || (MechType(mech) == CLASS_VTOL))) {

        /* Is the section finished cycling or do we deincrement it */
        if (diff >= MechSections(mech)[loop].recycle &&
                !SectIsDestroyed(mech, loop)) {
            
            MechSections(mech)[loop].recycle = 0;
            ArmorStringFromIndex(loop, location, MechType(mech),
                    MechMove(mech));

            mech_notify(mech, MECHSTARTED,
                    tprintf("%%cg%s%s has finished its previous action.%%c",
                        MechType(mech) == CLASS_BSUIT ? "" : "Your ",
                        location));

        } else {

            MechSections(mech)[loop].recycle -= diff;
            if (MechSections(mech)[loop].recycle < lowest || !lowest)
                lowest = MechSections(mech)[loop].recycle;

        }

    }

    }
    arc_override = 0;
    return lowest;
}

int SkidMod(float Speed)
{
    if (Speed < 2.1)
	return -1;
    if (Speed < 4.1)
	return 0;
    if (Speed < 7.1)
	return 1;
    if (Speed < 10.1)
	return 2;
    return 4;
}

/*
 * Move the unit back to its previous location because of cliff or something
 */
void move_unit_back(MECH *mech, float deltax, float deltay, int lastelevation, 
        int ot, int le) {

    MechFX(mech) -= deltax;
    MechFY(mech) -= deltay;
    MechX(mech) = MechLastX(mech);
    MechY(mech) = MechLastY(mech);
    MechZ(mech) = lastelevation;
    MechFZ(mech) = MechZ(mech) * ZSCALE;
    MechTerrain(mech) = ot;
    MechElev(mech) = le;

}

/*
 * Check to see what happens to the unit now that its entered a new hex
 */
void NewHexEntered(MECH * mech, MAP * mech_map, float deltax, float deltay,
        int last_z)
{
    int elevation, lastelevation;
    int oldterrain;
    int ot, le, ed, done = 0, tt, avoidbth;
    int isunder = 0;
    float f;

    /* Recording the old elevation and terrain */
    /*! \todo {Wasn't lastelevation passed as an argument 'last_z' ?} */
    ot = oldterrain = GetTerrain(mech_map, MechLastX(mech), MechLastY(mech));

    if ((MechMove(mech) == MOVE_HOVER) &&
            (oldterrain == WATER || oldterrain == ICE ||
             ((oldterrain == BRIDGE) && (last_z == 0)))) {
        
        le = lastelevation = elevation = 0;

    } else {

        le = lastelevation = Elevation(mech_map, MechLastX(mech), MechLastY(mech));
        elevation = MechElevation(mech);

        if (MechMove(mech) == MOVE_HOVER && elevation < 0)
            elevation = 0;

        if (ot == ICE && MechZ(mech) >= 0) {
            le = lastelevation = 0;
        }

        if (MechZ(mech) < le)
            le = MechZ(mech);
    }

    switch (MechMove(mech)) {
        case MOVE_BIPED:
        case MOVE_QUAD:

            if (Jumping(mech)) {

                if (MechRTerrain(mech) == WATER)
                    return;

#define MOVE_BACK \
                MechFX(mech) -= deltax;\
                MechFY(mech) -= deltay;\
                MechX(mech) = MechLastX(mech);\
                MechY(mech) = MechLastY(mech);\
                MechZ(mech) = lastelevation;\
                MechFZ(mech) = MechZ(mech) * ZSCALE;\
                MechTerrain(mech) = ot;\
                MechElev(mech) = le;

                /* Did we hit something while jumping */
                if (collision_check(mech, JUMP, 0, 0)) {

                    ed = MAX(1, 1 + MechZ(mech) - Elevation(mech_map,
                                MechX(mech), MechY(mech)));
                    move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                    mech_notify(mech, MECHALL,
                            "%chYou attempt to jump over elevation that is too high!!%c");
                    if (RGotPilot(mech) && 
                            MadePilotSkillRoll(mech, (int) (MechFZ(mech)) / ZSCALE / 3)) {

                        mech_notify(mech, MECHALL, "%chYou land safely.%c");
                        LandMech(mech);

                    } else {

                        mech_notify(mech, MECHALL,
                                "%chYou crash into the obstacle and fall from the sky!!!!!%c");
                        MechLOSBroadcast(mech,
                                "crashes into an obstacle and falls from the sky!");
                        MechFalls(mech, ed, 0);
                        domino_space(mech, 2);
                    }
                }
                return;
            }

            /* Walked into a wall silly */
            if (collision_check(mech, WALK_WALL, lastelevation, oldterrain)) {

                move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                mech_notify(mech, MECHALL,
                        "You attempt to climb a hill too steep for you.");

                if (MechPilot(mech) == -1 || (!mudconf.btech_skidcliff &&
                            MadePilotSkillRoll(mech, 
                                (int) (fabs((MechSpeed(mech)) + MP1) / MP1) / 3))
                        || (mudconf.btech_skidcliff && MadePilotSkillRoll(mech,
                                SkidMod(fabs(MechSpeed(mech)) / MP1)))) {

                    mech_notify(mech, MECHALL,
                            "You manage to stop before crashing.");
                    MechLOSBroadcast(mech, "stops suddenly to avoid a cliff!");

                } else {

                    mech_notify(mech, MECHALL,
                            "You run headlong into the cliff and fall down!!");
                    MechLOSBroadcast(mech,
                            "runs headlong into a cliff and falls down!");
                    if (!mudconf.btech_skidcliff)
                        MechFalls(mech, (int) (1 + (MechSpeed(mech)) * MP_PER_KPH) / 4, 0);
                    else
                        MechFalls(mech, 1, 0);
                }
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                MechZ(mech) = lastelevation;
                return;

            } else if (collision_check(mech, WALK_DROP, lastelevation,
                        oldterrain)) {

                /* Walked off a cliff ... */
                mech_notify(mech, MECHALL,
                        "You notice a large drop in front of you");
                avoidbth = mudconf.btech_skidcliff ?
                    SkidMod(fabs(MechSpeed(mech)) / MP1) :
                        ((fabs((MechSpeed(mech)) + MP1) / MP1) / 3);

                if (MechPilot(mech) == -1 || (!MechAutoFall(mech) &&
                            MadePilotSkillRoll(mech, avoidbth))) {

                    mech_notify(mech, MECHALL,
                            "You manage to stop before falling off.");
                    MechLOSBroadcast(mech,
                            "stops suddenly to avoid falling off a cliff!");
                    move_unit_back(mech, deltax, deltay, lastelevation, ot, le);

                } else {

                    mech_notify(mech, MECHALL,
                            "You run off the cliff and fall to the ground below.");
                    MechLOSBroadcast(mech,
                            "runs off a cliff and falls to the ground below!");
                    MechFalls(mech, lastelevation - elevation, 0);
                    MechDesiredSpeed(mech) = 0;
                    MechSpeed(mech) = 0;
                }
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;

            } else if (mudconf.btech_roll_on_backwalk && 
                    (MechSpeed(mech) < 0) && 
                    (collision_check(mech, WALK_BACK, lastelevation, oldterrain))) {

                mech_printf(mech, MECHALL, "You notice a %s behind you!",
                        (elevation > lastelevation ? "small incline" : "small drop"));

                if (MechPilot(mech) == -1
                        || (MadePilotSkillRoll(mech, 
                                collision_check(mech, WALK_BACK, lastelevation, oldterrain) 
                                - 1))) {

                    mech_notify(mech, MECHALL, "You manage to overcome the obstacle.");

                } else {

                    mech_printf(mech, MECHALL, "%s",
                            (elevation > lastelevation ?
                             "You stumble on your rear and fall down." :
                             "You fall on your rear off the small incline."));

                    /*! \todo {Get rid of this tprintf} */
                    MechLOSBroadcast(mech, tprintf("%s",(elevation > lastelevation ?
                                    "falls on it's back walking up an incline." : 
                                    "falls off the back of a small incline.")));
                    MechFalls(mech, abs(lastelevation - elevation), 1);
                    MechDesiredSpeed(mech) = 0;
                    MechSpeed(mech) = 0;
                    if (elevation > lastelevation) {
                        move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                    }
                }
                return;
            } 

            /* Slow the unit if its made an elevation change */
            le = elevation - lastelevation;
            le = (le < 0) ? -le : le;
            if (MechZ(mech) != elevation)
                le = 0;
            if (le > 0) {
                deltax = (le == 1) ? MP1 : MP2;
                if (MechSpeed(mech) > 0) {
                    MechSpeed(mech) -= deltax;
                    if (MechSpeed(mech) < 0)
                        MechSpeed(mech) = 0;
                } else if (MechSpeed(mech) < 0) {
                    MechSpeed(mech) += deltax;
                    if (MechSpeed(mech) > 0)
                        MechSpeed(mech) = 0;
                }
            }
            
            if (MechType(mech) == CLASS_BSUIT) {

                /* Are they in water, also make sure it affects them */
                if (!(MechSpecials2(mech) & WATERPROOF_TECH) &&
                        (MechRTerrain(mech) == WATER ||
                         (MechRTerrain(mech) == BRIDGE &&
                          (lastelevation < (elevation - 1)))) &&
                        elevation < 0) {

                    mech_notify(mech, MECHALL,
                            "You notice a body of water in front of you");

                    if (MechPilot(mech) == -1 ||
                            MadePilotSkillRoll(mech,
                                (int) (fabs((MechSpeed(mech)) + MP1) / MP1) / 3)) {

                        mech_notify(mech, MECHALL,
                                "You manage to stop before falling in.");
                        MechLOSBroadcast(mech,
                                "stops suddenly to avoid going for a swim!");
                    } else {

                        mech_notify(mech, MECHALL,
                                "You trip at the edge of the water and plunge in...");
                        MechFloods(mech);
                        return;
                    }
                    move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                    MechDesiredSpeed(mech) = 0;
                    MechSpeed(mech) = 0;
                    return;
                }

            } else if (!(MechSpecials2(mech) & WATERPROOF_TECH) &&
                    ((MechRTerrain(mech) == WATER && MechZ(mech) < 0) ||
                     (MechRTerrain(mech) == BRIDGE && MechZ(mech) < 0) ||
                     (MechRTerrain(mech) == ICE && MechZ(mech) < 0) ||
                     MechRTerrain(mech) == HIGHWATER) &&
                    MechType(mech) != CLASS_MW) {

                int skillmod, dammod;
                MechDesiredSpeed(mech) = MIN(MechDesiredSpeed(mech),
                        WalkingSpeed(MMaxSpeed(mech)));
#ifdef BT_MOVEMENT_MODES
                if (MechStatus2(mech) & SPRINTING) {
                    MechStatus2(mech) &= ~SPRINTING;
                    MechLOSBroadcast(mech, "breaks out of its sprint as it enters water!");
                    mech_notify(mech, MECHALL, "You lose your sprinting momentum as you "
                            "enter water!");
                    MECHEVENT(mech, EVENT_MOVEMODE, mech_movemode_event, TURN, 
                            MODE_OFF|MODE_SPRINT);
                }
#endif
                if (IsRunning(MechSpeed(mech), MMaxSpeed(mech))) {
                    mech_notify(mech, MECHPILOT,
                            "You struggle to keep control as you run into the water!");
                    skillmod = 2;
                    dammod = 2;
                } else {
                    mech_notify(mech, MECHPILOT, "You use your piloting skill "
                            "to maneuver through the water.");
                    skillmod = 0;
                    dammod = 0;
                }
                skillmod += (MechRTerrain(mech) == HIGHWATER ? -2 :
                        MechRTerrain(mech) == BRIDGE ? bridge_w_elevation(mech) :
                        MechElev(mech) > 3 ? 1 : (MechElev(mech) - 2));

                if (!MadePilotSkillRoll(mech, skillmod)) {
                    mech_notify(mech, MECHALL,
                            "You slip in the water and fall down");
                    MechLOSBroadcast(mech,
                            "slips in the water and falls down!");
                    MechFalls(mech, 1, dammod);
                    done = 1;
                }
            }
            break;

        case MOVE_TRACK:

            if (collision_check(mech, WALK_WALL, lastelevation, oldterrain)) {
                mech_notify(mech, MECHALL,
                        "You attempt to climb a hill too steep for you.");

                if (MechPilot(mech) == -1 || (!mudconf.btech_skidcliff && 
                            MadePilotSkillRoll(mech, 
                                (int) (fabs((MechSpeed(mech)) + MP1) / MP1) / 3))
                        || (mudconf.btech_skidcliff &&
                            MadePilotSkillRoll(mech,
                                SkidMod(fabs(MechSpeed(mech)) / MP1)))) {

                    mech_notify(mech, MECHALL,
                            "You manage to stop before crashing.");
                    MechLOSBroadcast(mech, "stops suddenly to avoid a cliff!");

                } else {
                    
                    if (!mudconf.btech_skidcliff) {
                        mech_notify(mech, MECHALL, "You smash into a cliff!!");
                        MechLOSBroadcast(mech, "crashes to a cliff!");
                        MechFalls(mech, (int) (MechSpeed(mech) * MP_PER_KPH / 4), 0);
                    } else {
                        mech_notify(mech, MECHALL,
                                "You skid to a violent halt!!");
                        MechLOSBroadcast(mech, "goes into a skid!");
                        MechFalls(mech, 0, 0);
                    }
                }
                move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;

            } else if (collision_check(mech, WALK_DROP, lastelevation,
                        oldterrain)) {

                mech_notify(mech, MECHALL,
                        "You notice a large drop in front of you");
                avoidbth = mudconf.btech_skidcliff ?
                    SkidMod(fabs(MechSpeed(mech)) / MP1) :
                        ((fabs((MechSpeed(mech)) + MP1) / MP1) / 3);
                if (MechPilot(mech) == -1 || (!MechAutoFall(mech) &&
                            MadePilotSkillRoll(mech, avoidbth))) {
                    mech_notify(mech, MECHALL,
                            "You manage to stop before falling off.");
                    MechLOSBroadcast(mech,
                            "stops suddenly to avoid falling off a cliff!");
                } else {
                    mech_notify(mech, MECHALL,
                            "You drive off the cliff and fall to the ground below.");
                    MechLOSBroadcast(mech,
                            "drives off a cliff and falls to the ground below.");
                    MechFalls(mech, lastelevation - elevation, 0);
                    domino_space(mech, 2);

                    if (MechRTerrain(mech) == WATER && 
                            !(MechSpecials2(mech) & WATERPROOF_TECH)) {

                        mech_notify(mech, MECHALL,
                                "You drive into the water and your vehicle becomes inoperable.");
                        Destroy(mech);
                    }

                    return;
                }
                move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;

            } else if (mudconf.btech_roll_on_backwalk && (MechSpeed(mech) < 0) && 
                    (collision_check(mech, WALK_BACK, lastelevation, oldterrain))) {

                mech_printf(mech, MECHALL, "You notice a %s behind you!",
                        (elevation > lastelevation ? "small incline" : "small drop"));

                if (MechPilot(mech) == -1 || (MadePilotSkillRoll(mech, 
                                collision_check(mech, WALK_BACK, lastelevation, oldterrain) 
                                - 1))) {

                    mech_notify(mech, MECHALL, "You manage to overcome the obstacle.");
                } else {
                    mech_printf(mech, MECHALL, "%s",
                            (elevation > lastelevation ?
                             "You stumble on your rear and fall down." :
                             "You fall on your rear off the small incline."));
                    MechLOSBroadcast(mech, tprintf("%s",(elevation > lastelevation
                                    ? "falls on it's back walking up an incline." : 
                                    "falls off the back of a small incline.")));
                    MechFalls(mech, abs(lastelevation - elevation), 1);
                    MechDesiredSpeed(mech) = 0;
                    MechSpeed(mech) = 0;
                    if (elevation > lastelevation) {
                        move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                    }
                }
                return;
            }


            if (!(MechSpecials2(mech) & WATERPROOF_TECH) &&
                    (MechRTerrain(mech) == WATER || 
                     (MechRTerrain(mech) == BRIDGE && (lastelevation < (elevation - 1)))) &&
                    elevation < 0) {

                mech_notify(mech, MECHALL,
                        "You notice a body of water in front of you");
                if (MechPilot(mech) == -1 ||
                        MadePilotSkillRoll(mech,
                            (int) (fabs((MechSpeed(mech)) + MP1) / MP1) / 3)) {
                    mech_notify(mech, MECHALL,
                            "You manage to stop before falling in.");
                    MechLOSBroadcast(mech,
                            "stops suddenly to avoid driving into the water!");
                } else {
                    mech_notify(mech, MECHALL,
                            "You drive into the water and your vehicle becomes inoperable.");
                    Destroy(mech);
                    return;
                }
                move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;
            }

            /* New terrain restrictions */
            if (mudconf.btech_newterrain) {
                tt = MechRTerrain(mech);
                if ((tt == HEAVY_FOREST) && fabs(MechSpeed(mech)) > MP1) {

#if 0
                    mech_notify(mech, MECHALL,
                            "You cruise at a bunch of trees!");
#endif
                    mech_notify(mech, MECHALL,
                            "You try to dodge the larger trees..");

                    if (MechPilot(mech) == -1 || MadePilotSkillRoll(mech,
                                (int) (fabs(MechSpeed(mech)) / MP1 / 6))) {

                        mech_notify(mech, MECHALL, "You manage to dodge 'em!");
                    } else {
                        mech_notify(mech, MECHALL,
                                "You swerve, but not enough! This'll hurt!");
                        MechLOSBroadcast(mech, "cruises headlong at a tree!");
                        f = fabs(MechSpeed(mech));
                        MechSpeed(mech) = MechSpeed(mech) / 2.0;
                        MechFalls(mech, MAX(1, (int) sqrt(f / MP1 / 2)), 0);
                    }
                }
            }

            /* Slow them if they made an elevation change */
            le = elevation - lastelevation;
            le = (le < 0) ? -le : le;
            if (le > 0) {
                deltax = (le == 1) ? MP2 : MP3;
                if (MechSpeed(mech) > 0) {
                    MechSpeed(mech) -= deltax;
                    if (MechSpeed(mech) < 0)
                        MechSpeed(mech) = 0;
                } else if (MechSpeed(mech) < 0) {
                    MechSpeed(mech) += deltax;
                    if (MechSpeed(mech) > 0)
                        MechSpeed(mech) = 0;
                }
            }
            break;

        case MOVE_WHEEL:

            /* Cliff ! */
            if (collision_check(mech, WALK_WALL, lastelevation, oldterrain)) {

                mech_notify(mech, MECHALL,
                        "You attempt to climb a hill too steep for you.");

                if (MechPilot(mech) == -1 || (!mudconf.btech_skidcliff &&
                            MadePilotSkillRoll(mech,
                                (int) (fabs((MechSpeed(mech)) + MP1) / MP1) / 3))
                        || (mudconf.btech_skidcliff && MadePilotSkillRoll(mech,
                                SkidMod(fabs(MechSpeed(mech)) / MP1)))) {

                    mech_notify(mech, MECHALL,
                            "You manage to stop before crashing.");
                    MechLOSBroadcast(mech, "stops suddenly to avoid a cliff!");

                } else {

                    if (!mudconf.btech_skidcliff) {
                        mech_notify(mech, MECHALL, "You smash into a cliff!!");
                        MechLOSBroadcast(mech, "crashes to a cliff!");
                        MechFalls(mech, (int) (MechSpeed(mech) * MP_PER_KPH / 4), 0);
                    } else {
                        mech_notify(mech, MECHALL,
                                "You skid to a violent halt!");
                        MechLOSBroadcast(mech, "skids to a halt!");
                        MechFalls(mech, 0, 0);
                    }
                }

                move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;

            } else if (collision_check(mech, WALK_DROP, lastelevation,
                        oldterrain)) {

                mech_notify(mech, MECHALL,
                        "You notice a large drop in front of you");
                avoidbth = mudconf.btech_skidcliff ?
                    SkidMod(fabs(MechSpeed(mech)) / MP1) :
                        ((fabs((MechSpeed(mech)) + MP1) / MP1) / 3);

                if (MechPilot(mech) == -1 || (!MechAutoFall(mech) &&
                            MadePilotSkillRoll(mech, avoidbth))) {

                    mech_notify(mech, MECHALL,
                            "You manage to stop before falling off.");
                    MechLOSBroadcast(mech,
                            "stops suddenly to avoid driving off a cliff!");
                } else {
                    mech_notify(mech, MECHALL,
                            "You drive off the cliff and fall to the ground below.");
                    MechLOSBroadcast(mech,
                            "drives off a cliff and falls to the ground below.");
                    MechFalls(mech, lastelevation - elevation, 0);
                    domino_space(mech, 2);

                    if (MechRTerrain(mech) == WATER &&
                            !(MechSpecials2(mech) & WATERPROOF_TECH)) {

                        mech_notify(mech, MECHALL,
                                "You drive into the water and your vehicle becomes inoperable.");
                        Destroy(mech);
                    }

                    return;
                }
                move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;

            }  else if (mudconf.btech_roll_on_backwalk && 
                    (MechSpeed(mech) < 0) && 
                    (collision_check(mech, WALK_BACK, lastelevation, oldterrain))) {

                mech_printf(mech, MECHALL, "You notice a %s behind you!",
                        (elevation > lastelevation ? "small incline" : "small drop"));

                if (MechPilot(mech) == -1 || (MadePilotSkillRoll(mech,
                                collision_check(mech, WALK_BACK, lastelevation, oldterrain) 
                                - 1))) {
                    mech_notify(mech, MECHALL,
                            "You manage to overcome the obstacle.");
                } else {
                    mech_printf(mech, MECHALL, "%s",
                            (elevation > lastelevation ?
                             "You stumble on your rear and fall down." :
                             "You fall on your rear off the small incline."));
                    MechLOSBroadcast(mech,
                            tprintf("%s",(elevation > lastelevation ? 
                                    "falls on it's back walking up an incline." :
                                    "falls off the back of a small incline.")));
                    MechFalls(mech, abs(lastelevation - elevation), 1);
                    MechDesiredSpeed(mech) = 0;
                    MechSpeed(mech) = 0;
                    if (elevation > lastelevation) {
                        move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                    }
                }
                return;
            }

            if (!(MechSpecials2(mech) & WATERPROOF_TECH) &&
                    (MechRTerrain(mech) == WATER || 
                     (MechRTerrain(mech) == BRIDGE && (lastelevation < (elevation - 1)))) &&
                    elevation < 0) {

                mech_notify(mech, MECHALL,
                        "You notice a body of water in front of you");

                if (MechPilot(mech) == -1 ||
                        MadePilotSkillRoll(mech,
                            (int) (fabs((MechSpeed(mech)) + MP1) / MP1) / 3)) {

                    mech_notify(mech, MECHALL,
                            "You manage to stop before falling in.");
                    MechLOSBroadcast(mech,
                            "stops suddenly to driving into the water!");
                } else {
                    mech_notify(mech, MECHALL,
                            "You drive into the water and your vehicle becomes inoperable.");
                    Destroy(mech);
                    return;
                }
                move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;
            }

            /* New terrain restrictions */
            if (mudconf.btech_newterrain) {
                tt = MechRTerrain(mech);
                if ((tt == HEAVY_FOREST || tt == LIGHT_FOREST) &&
                        fabs(MechSpeed(mech)) > MP1) {

#if 0
                    mech_notify(mech, MECHALL,
                            "You cruise at a bunch of trees!");
#endif
                    mech_notify(mech, MECHALL,
                            "You try to dodge the larger trees..");
                    if (MechPilot(mech) == -1 ||
                            MadePilotSkillRoll(mech,
                                (tt == HEAVY_FOREST ? 3 : 0) +
                                (fabs(MechSpeed(mech)) / MP1 / 6))) {

                        mech_notify(mech, MECHALL, "You manage to dodge 'em!");

                    } else {
                        mech_notify(mech, MECHALL,
                                "You swerve, but not enough! This'll hurt!");
                        MechLOSBroadcast(mech, "cruises headlong at a tree!");
                        f = fabs(MechSpeed(mech));
                        MechSpeed(mech) = MechSpeed(mech) / 2.0;
                        MechFalls(mech, MAX(1, (int) sqrt(f / MP1 / 2)), 0);
                    }

                } else if ((tt == ROUGH) && fabs(MechSpeed(mech)) > MP1) {
#if 0
                    mech_notify(mech, MECHALL,
                            "You cruise at some rough terrain!");
#endif
                    mech_notify(mech, MECHALL, "You try to avoid the rocks..");
                    if (MechPilot(mech) == -1 || MadePilotSkillRoll(mech,
                                (int) (fabs(MechSpeed(mech)) / MP1 / 6))) {
                        mech_notify(mech, MECHALL, "You manage to dodge 'em!");
                    } else {
                        mech_notify(mech, MECHALL,
                                "You swerve, but not enough! This'll hurt!");
                        MechLOSBroadcast(mech, "cruises headlong at a rock!");
                        f = fabs(MechSpeed(mech));
                        MechSpeed(mech) = MechSpeed(mech) / 2.0;
                        MechFalls(mech, MAX(1, (int) sqrt(f / MP1 / 2)), 0);
                    }
                }
            }

            /* Slow them down if they change elevations */
            le = elevation - lastelevation;
            le = (le < 0) ? -le : le;
            if (le > 0) {
                deltax = (le == 1) ? MP2 : MP3;
                if (MechSpeed(mech) > 0) {
                    MechSpeed(mech) -= deltax;
                    if (MechSpeed(mech) < 0)
                        MechSpeed(mech) = 0;
                } else if (MechSpeed(mech) < 0) {
                    MechSpeed(mech) += deltax;
                    if (MechSpeed(mech) > 0)
                        MechSpeed(mech) = 0;
                }
            }
            break;

        case MOVE_HULL:
        case MOVE_FOIL:
        case MOVE_SUB:

            if ((MechRTerrain(mech) != WATER && MechRTerrain(mech) != BRIDGE)
                    || abs(MechElev(mech)) < (abs(MechZ(mech)) + (MechMove(mech) ==
                            MOVE_FOIL ? -1 : 0))) {
                /* Run aground */
                MechElev(mech) = le;
                MechTerrain(mech) = ot;
                mech_notify(mech, MECHALL,
                        "You attempt to get too close with ground!");
                if (MechPilot(mech) == -1 ||
                        MadePilotSkillRoll(mech,
                            (int) (fabs((MechSpeed(mech)) + MP1) / MP1) / 3)) {
                    mech_notify(mech, MECHALL,
                            "You manage to stop before crashing.");
                    MechLOSBroadcast(mech,
                            "stops suddenly to avoid running aground!");
                    move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                } else {
                    mech_notify(mech, MECHALL, "You smash into the ground!!");
                    MechLOSBroadcast(mech, "smashes aground!");
                    MechFalls(mech, (int) (MechSpeed(mech) * MP_PER_KPH / 4),
                            0);
                }
                MechSpeed(mech) = 0;
                MechDesiredSpeed(mech) = 0;
                MechVerticalSpeed(mech) = 0;
                return;
            }
            if (elevation > 0)
                elevation = 0;
            break;

        case MOVE_HOVER:

            if (collision_check(mech, WALK_WALL, lastelevation, oldterrain)) {
                MechElev(mech) = le;
                MechTerrain(mech) = ot;
                mech_notify(mech, MECHALL,
                        "You attempt to climb a hill too steep for you.");
                if (MechPilot(mech) == -1 || (!mudconf.btech_skidcliff &&
                            MadePilotSkillRoll(mech, 
                                (int) (fabs((MechSpeed(mech)) + MP1) / MP1) / 3))
                        || (mudconf.btech_skidcliff && MadePilotSkillRoll(mech,
                                SkidMod(fabs(MechSpeed(mech)) / MP1)))) {

                    mech_notify(mech, MECHALL,
                            "You manage to stop before crashing.");
                    MechLOSBroadcast(mech, "stops suddenly to avoid a cliff!");

                } else {

                    if (!mudconf.btech_skidcliff) {
                        mech_notify(mech, MECHALL, "You smash into a cliff!!");
                        MechLOSBroadcast(mech, "smashes into a cliff!");
                        MechFalls(mech,
                                (int) (MechSpeed(mech) * MP_PER_KPH / 4), 0);
                    } else {
                        mech_notify(mech, MECHALL,
                                "You skid to a violent halt!");
                        MechLOSBroadcast(mech, "Skids to a halt!");
                        MechFalls(mech, 0, 0);
                    }
                }
                move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;

            } else if (collision_check(mech, WALK_DROP, lastelevation,
                        oldterrain)) {

                mech_notify(mech, MECHALL,
                        "You notice a large drop in front of you");

                avoidbth = mudconf.btech_skidcliff ?
                    SkidMod(fabs(MechSpeed(mech)) / MP1) :
                        ((fabs((MechSpeed(mech)) + MP1) / MP1) / 3);

                if (MechPilot(mech) == -1 || (!MechAutoFall(mech) &&
                            MadePilotSkillRoll(mech, avoidbth))) {

                    mech_notify(mech, MECHALL,
                            "You manage to stop before falling off.");
                    MechLOSBroadcast(mech,
                            "stops suddenly to avoid falling off a cliff!");

                } else {

                    mech_notify(mech, MECHALL,
                            "You drive off the cliff and fall to the ground below.");
                    MechLOSBroadcast(mech,
                            "drives off a cliff and falls to the ground below.");
                    MechFalls(mech, lastelevation - elevation, 0);
                    return;
                }

                move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;

            } else if (collision_check(mech, HIT_UNDER_BRIDGE, lastelevation,
                        oldterrain)) {

                mech_notify(mech, MECHALL,
                        "You notice the underside of the bridge in front of you!");

                if (MechPilot(mech) == -1 || (!mudconf.btech_skidcliff &&
                            MadePilotSkillRoll(mech,
                                (int) (fabs((MechSpeed(mech)) + MP1) / MP1) / 3))
                        || (mudconf.btech_skidcliff &&
                            MadePilotSkillRoll(mech,
                                SkidMod(fabs(MechSpeed(mech)) / MP1)))) {

                    mech_notify(mech, MECHALL,
                            "You manage to stop before slamming into the bridge.");
                    MechLOSBroadcast(mech,
                            "stops suddenly to avoid slamming in the bridge!");
                } else {
                    mech_notify(mech, MECHALL,
                            "You drive right into the underside of the bridge.");
                    MechLOSBroadcast(mech,
                            "drives right into the underside of the bridge.");
                    MechFalls(mech, 1, 0);
                }
                move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;

            }  else if (mudconf.btech_roll_on_backwalk && 
                    (MechSpeed(mech) < 0) &&
                    (collision_check(mech, WALK_BACK, lastelevation, oldterrain)) && !isunder) {

                mech_printf(mech, MECHALL, "You notice a %s behind you!",
                        (elevation > lastelevation ? "small incline" : "small drop"));
                
                if (MechPilot(mech) == -1 || (MadePilotSkillRoll(mech,
                                collision_check(mech, WALK_BACK, lastelevation, oldterrain) 
                                - 1))) {

                    mech_notify(mech, MECHALL,
                            "You manage to overcome the obstacle.");

                } else {

                    mech_printf(mech, MECHALL, "%s",
                            (elevation > lastelevation ?
                             "You stumble on your rear and fall down." :
                             "You fall on your rear off the small incline."));
                    MechLOSBroadcast(mech,
                            tprintf("%s",(elevation > lastelevation ? 
                                    "falls on it's back walking up an incline." :
                                    "falls off the back of a small incline.")));
                    MechFalls(mech, abs(lastelevation - elevation), 1);
                    MechDesiredSpeed(mech) = 0;
                    MechSpeed(mech) = 0;
                    if (elevation > lastelevation) {
                        move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                    }
                }
                return;
            }

            tt = MechRTerrain(mech);
            if ((tt == HEAVY_FOREST || tt == LIGHT_FOREST) &&
                    fabs(MechSpeed(mech)) > MP1) {
#if 0
                mech_notify(mech, MECHALL, "You cruise at a bunch of trees!");
#endif
                mech_notify(mech, MECHALL,
                        "You try to dodge the larger trees..");

                if (MechPilot(mech) == -1 ||
                        MadePilotSkillRoll(mech,
                            (tt == HEAVY_FOREST ? 3 : 0) +
                            (fabs(MechSpeed(mech)) / MP1 / 6))) {

                    mech_notify(mech, MECHALL, "You manage to dodge 'em!");

                } else {
                    mech_notify(mech, MECHALL,
                            "You swerve, but not enough! This'll hurt!");
                    MechLOSBroadcast(mech, "cruises headlong at a tree!");
                    f = fabs(MechSpeed(mech));
                    MechSpeed(mech) = MechSpeed(mech) / 2.0;
                    MechFalls(mech, MAX(1, (int) sqrt(f / MP1 / 2)), 0);
                }
            }

            /* Slow the unit down if its made an elevation change */
            le = elevation - lastelevation;
            le = (le < 0) ? -le : le;
            if (le > 0) {
                deltax = (le == 1) ? MP2 : MP3;
                if (MechSpeed(mech) > 0) {
                    MechSpeed(mech) -= deltax;
                    if (MechSpeed(mech) < 0)
                        MechSpeed(mech) = 0;
                } else if (MechSpeed(mech) < 0) {
                    MechSpeed(mech) += deltax;
                    if (MechSpeed(mech) > 0)
                        MechSpeed(mech) = 0;
                }
            }
            break;

        case MOVE_VTOL:
        case MOVE_FLY:

            if (Landed(mech) && MechRTerrain(mech) != ROAD &&
                    MechRTerrain(mech) != BRIDGE && MechRTerrain(mech) != GRASSLAND
                    && MechRTerrain(mech) != BUILDING) {

                mech_notify(mech, MECHALL,
                        "You go where no flying thing has ever gone before..");
                if (RGotPilot(mech) && MadePilotSkillRoll(mech, 5)) {
                    mech_notify(mech, MECHALL, "You stop in time!");
                    move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                } else {
                    mech_notify(mech, MECHALL,
                            "Eww.. You've a bad feeling about this.");
                    MechLOSBroadcast(mech, "crashes!");
                    MechFalls(mech, 1, 0);
                }
                MechDesiredSpeed(mech) = 0;
                MechSpeed(mech) = 0;
                return;

            }  else if (Landed(mech) && mudconf.btech_roll_on_backwalk && 
                    (MechSpeed(mech) < 0) && 
                    (collision_check(mech, WALK_BACK, lastelevation, oldterrain))) {

                mech_printf(mech, MECHALL, "You notice a %s behind you!",
                        (elevation > lastelevation ? "small incline" : "small drop"));

                if (MechPilot(mech) == -1 || (MadePilotSkillRoll(mech, 
                                collision_check(mech, WALK_BACK, lastelevation, oldterrain) 
                                - 1))) {

                    mech_notify(mech, MECHALL, "You manage to overcome the obstacle.");

                } else { 

                    mech_printf(mech, MECHALL, "%s", (elevation > lastelevation ?
                                "You stumble on your rear and fall down." :
                                "You fall on your rear off the small incline."));
                    MechLOSBroadcast(mech, tprintf("%s",(elevation > lastelevation ? 
                                    "falls on it's back walking up an incline." : 
                                    "falls off the back of a small incline.")));
                    MechFalls(mech, (abs(lastelevation - elevation) + 1000), 1);
                    MechDesiredSpeed(mech) = 0;
                    MechSpeed(mech) = 0;
                    if (elevation > lastelevation) {
                        move_unit_back(mech, deltax, deltay, lastelevation, ot, le);
                    } 
                }
                return;
            }

            if (MechRTerrain(mech) == WATER)
                return;

            if (MechRTerrain(mech) == LIGHT_FOREST ||
                    MechRTerrain(mech) == HEAVY_FOREST)
                elevation = MechElevation(mech) + 2;
            else
                elevation = MechElevation(mech);

            if (collision_check(mech, JUMP, 0, 0)) {
                MechFX(mech) -= deltax;
                MechFY(mech) -= deltay;
                MechX(mech) = MechLastX(mech);
                MechY(mech) = MechLastY(mech);
                MechZ(mech) = lastelevation;
                MechFZ(mech) = MechZ(mech) * ZSCALE;
                MechElev(mech) = le;
                MechTerrain(mech) = ot;
                mech_notify(mech, MECHALL,
                        "You attempt to fly over elevation that is too high!!");

                if (MechPilot(mech) == -1 || (MadePilotSkillRoll(mech,
                                (int) (MechFZ(mech) / ZSCALE / 3)) &&
                            (ot == GRASSLAND || ot == ROAD || ot == BUILDING))) {

                    mech_notify(mech, MECHALL, "You land safely.");
                    MechStatus(mech) |= LANDED;
                    MechSpeed(mech) = 0.0;
                    MechVerticalSpeed(mech) = 0.0;

                } else {
                    mech_notify(mech, MECHALL,
                            "You crash into the obstacle and fall from the sky!!!!!");
                    MechLOSBroadcast(mech,
                            "crashes into an obstacle and falls from the sky!");
                    MechFalls(mech, MechsElevation(mech) + 1, 0);
                    domino_space(mech, 2);
                }
            }
            break;
    }

    if (!done) {
        possible_mine_poof(mech, MINE_STEP);
        if (mudconf.btech_fasaadvvhlfire &&
                (MechType(mech) == CLASS_VEH_GROUND) &&
                (MechTerrain(mech) == FIRE))
            checkVehicleInFire(mech, 1);
    }
}

void CheckDamage(MECH * wounded)
{
    /* should be called from UpdatePilotSkillRolls */
    /* this is so that a roll will be made only when the mech takes damage */
    int now = muxevent_tick % TURN;
    int staggerLevel = 0;
    int headingChange = 0;

    if (mudconf.btech_newstagger) {
	if (StaggerDamage(wounded) <= 0)
	    return;

	staggerLevel = StaggerLevel(wounded);

	if (Fallen(wounded) || (MechType(wounded) != CLASS_MECH)) {
	    if (CheckingStaggerDamage(wounded) ||
		(StaggerDamage(wounded) > 0))
		StopStaggerCheck(wounded);

	    return;
	}

	if (!CheckingStaggerDamage(wounded)) {
	    if ((Jumping(wounded) && (staggerLevel < 1)) ||
		!Jumping(wounded))
		StartStaggerCheck(wounded);
	}

	if (staggerLevel < 1) {
	    return;
	}

	SendDebug(tprintf("For %d. StaggerDamage: %d. StaggerLevel: %d.",
		wounded->mynum, StaggerDamage(wounded),
		StaggerLevel(wounded)));

	if (LastStaggerNotify(wounded) < staggerLevel) {
	    LastStaggerNotify(wounded) = staggerLevel;

	    if (Jumping(wounded) || OODing(wounded)) {
		switch (staggerLevel) {
		case 1:
		    mech_notify(wounded, MECHALL,
			"%cy%chThe damage causes you to spin a little in your flight path.%cn");
		    headingChange = 15;
		    break;

		case 2:
		    mech_notify(wounded, MECHALL,
			"%crThe damage spins you but you maintain your flight!%cn");
		    MechLOSBroadcast(wounded,
			"turns slightly from the damage!");
		    headingChange = 45;
		    break;

		default:
		    mech_notify(wounded, MECHALL,
			"%cr%chThe damage causes you to spin completely around!%cn");
		    MechLOSBroadcast(wounded,
			"spins around from the damage!");
		    headingChange = 180;
		    break;
		}

		SetFacing(wounded,
		    AcceptableDegree(MechFacing(wounded) +
			headingChange) * ((Roll() >= 6) ? 1 : -1));
	    } else {
		switch (staggerLevel) {
		case 1:
		    mech_notify(wounded, MECHALL,
			"%cy%chThe damage causes you to stagger a little.%cn");
		    break;

		case 2:
		    mech_notify(wounded, MECHALL,
			"%crThe damage causes you to stagger even more!%cn");
		    MechLOSBroadcast(wounded,
			"starts to stagger from the damage!");
		    break;

		default:
		    mech_notify(wounded, MECHALL,
			"%cr%chThe damage causes you to stagger violently while attempting to keep your footing!%cn");
		    MechLOSBroadcast(wounded,
			"staggers back and forth attempting to keep its footing!");
		    break;
		}
	    }
	}
    } else {
	if (!IsDS(wounded) && MechTurnDamage(wounded) >= 20 &&
	    (!MechStaggeredLastTurn(wounded) ||
		MechStaggerStamp(wounded) == now)) {

	    if (!Jumping(wounded) && !Fallen(wounded) && !OODing(wounded)) {
		mech_notify(wounded, MECHALL,
		    "You stagger from the damage!");
		if (!MadePilotSkillRoll(wounded, 1)) {
		    mech_notify(wounded, MECHALL,
			"You fall over from all the damage!!");
		    MechLOSBroadcast(wounded,
			"falls down, staggered by the damage!");
		    MechFalls(wounded, 1, 0);
		}
	    }
	    MechTurnDamage(wounded) = 0;
	    SetMechStaggerStamp(wounded, now);
	    return;
	}
	if ((MechStaggeredLastTurn(wounded) &&
		MechStaggerStamp(wounded) == now) ||
	    (!MechStaggeredLastTurn(wounded) && !now)) {
	    MechTurnDamage(wounded) = 0;
	    SetMechStaggerStamp(wounded, -1);
	}
    }
}

void UpdatePilotSkillRolls(MECH * mech)
{
    int makeroll = 0, grav = 0;
    float maxspeed;

    if (((muxevent_tick % TURN) == 0) && !Fallen(mech) && !Jumping(mech) &&
	!OODing(mech))
	/* do this once a turn (30 secs), only if mech is standing */
    {
	maxspeed = MMaxSpeed(mech);

	if (!Started(mech))
	    makeroll = 4;

	if ((MechHeat(mech) >= 9.) &&
	    (MechSpecials(mech) & TRIPLE_MYOMER_TECH))
	    maxspeed =
		ceil((rint((MMaxSpeed(mech) / 1.5) / MP1) +
		    1) * 1.5) * MP1;
	/* maxspeed += 1.5 * MP1; */
#ifndef BT_MOVEMENT_MODES
	if (InSpecial(mech) && InGravity(mech))
#else
	if (InSpecial(mech) && InGravity(mech) && !MoveModeChange(mech))
#endif
	    if (MechSpeed(mech) > MechMaxSpeed(mech) &&
		MechType(mech) == CLASS_MECH) {
		grav = 1;
		makeroll = 1;
	    }
	if (IsRunning(MechSpeed(mech), maxspeed) &&
	    ((MechCritStatus(mech) & GYRO_DAMAGED) ||
		(MechCritStatus(mech) & HIP_DAMAGED)))
	    makeroll = 1;

	if (makeroll) {
	    if (!MadePilotSkillRoll(mech, (makeroll - 1))) {
		if (grav) {
		    int dam = (MechSpeed(mech) - MechMaxSpeed(mech)) / MP1 + 1;
		    mech_notify(mech, MECHALL,
			"Your legs take some damage!");
		    if (MechIsQuad(mech)) {
			if (!SectIsDestroyed(mech, LARM))
			    DamageMech(mech, mech, 0, -1, LARM, 0, 0, 0,
				dam, 0, 0, -1, 0, 1);
			if (!SectIsDestroyed(mech, RARM))
			    DamageMech(mech, mech, 0, -1, RARM, 0, 0, 0,
			    	dam, 0, 0, -1, 0, 1);

		    }
		    if (!SectIsDestroyed(mech, LLEG))
			DamageMech(mech, mech, 0, -1, LLEG, 0, 0, 0,
			    dam, 0, 0, -1, 0, 1);
		    if (!SectIsDestroyed(mech, RLEG))
			DamageMech(mech, mech, 0, -1, RLEG, 0, 0, 0,
			    dam, 0, 0, -1, 0, 1);
		} else {
		    mech_notify(mech, MECHALL,
			"Your damaged mech falls as you try to run");
		    MechLOSBroadcast(mech, "falls down.");
		    MechFalls(mech, 1, 0);
		}
	    }
	}
    }
    if (MechType(mech) == CLASS_MECH)
	CheckDamage(mech);
    else
	MechTurnDamage(mech) = 0;
    if ((muxevent_tick % TURN) == 0) {
	if (Started(mech) && MechMove(mech) != MOVE_NONE)
	    CheckGenericFail(mech, -1, NULL, NULL);
    }
}

void updateAutoturnTurret(MECH * mech)
{
    MECH *target;
    int bearing;
    float fx, fy;

    if (!Started(mech) || Uncon(mech) || Blinded(mech))
	return;

    if ((MechTankCritStatus(mech) & TURRET_JAMMED) ||
	(MechTankCritStatus(mech) & TURRET_LOCKED))
	return;

    if (!GetSectInt(mech, TURRET))
	return;

    if (MechTarget(mech) == -1 && (MechTargY(mech) == -1 ||
	    MechTargX(mech) == -1))
	return;

    if (MechTarget(mech) != -1) {
	target = getMech(MechTarget(mech));
	fx = MechFX(target);
	fy = MechFY(target);
    } else {
	MapCoordToRealCoord(MechTargX(mech), MechTargY(mech), &fx, &fy);
    }

    bearing =
	AcceptableDegree(FindBearing(MechFX(mech), MechFY(mech), fx,
	    fy) - MechFacing(mech));
    MechTurretFacing(mech) = bearing;
    MarkForLOSUpdate(mech);
}

/* This function is called once every second for every mech in the game */
void mech_update(dbref key, void *data)
{
    MECH *mech = (MECH *) data;

    if (!mech)
	return;
    MechStatus(mech) &= ~FIRED;
    if (is_aero(mech)) {
	aero_update(mech);
	return;
    }
    if (Started(mech) || Uncon(mech))
	UpdatePilotSkillRolls(mech);
    if (Started(mech) || MechPlusHeat(mech) > 0.1)
	UpdateHeat(mech);
    if (Started(mech))
	MechVisMod(mech) =
	    BOUNDED(0, MechVisMod(mech) + Number(-40, 40), 100);
    checkECM(mech);
    checkTAG(mech);
    end_lite_check(mech);

    if (MechStatus2(mech) & AUTOTURN_TURRET)
	updateAutoturnTurret(mech);
}