if (moveType == Entity.MOVE_WALK) { entity.heatBuildup += 1; } else if (moveType == Entity.MOVE_RUN) { entity.heatBuildup += 2; } else if (moveType == Entity.MOVE_JUMP) { entity.heatBuildup += Math.max(3, distance); }
    private void doEntityMovement(Packet c, int cn) {        final MovementData md = (MovementData)c.getObject(1);        // walk thru data, stopping when the mech is out of movement        final Entity entity = game.getEntity(c.getIntValue(0));	boolean infMoveMulti = game.getOptions().booleanOption("inf_move_multi");	boolean infMoveLast = game.getOptions().booleanOption("inf_move_last");                if (entity == null) {            // what causes this?  --Ben            return;        }                if (!entity.ready) {            // the entity has already moved, apparently            return;        }	// Check for potential cheating:	// If "inf_move_mutli" option is selected, and we're in the middle	// of a block of Infantry moves, entity had better be an Infantry	// platoon owned by the most recent player.	if ( infMoveMulti && turnInfMoved > 0 &&	     ( !(entity instanceof Infantry) ||	       entity.getOwnerId() != turnLastPlayerId ) ) {	    // Do something appropriately awful.	    // TODO: Implement me!!!	}        	// Check for potential cheating:	// If "inf_move_last" option is selected, player can't move	// a Mek or Vehicle after Infantry have started to move.	else if ( infMoveLast && turnInfMoved > 0 &&		  !(entity instanceof Infantry) ) {	    // Do something appropriately awful.	    // TODO: Implement me!!!	}	// check for fleeing        if (md.contains(MovementData.STEP_FLEE)) {            phaseReport.append("\n" + entity.getDisplayName()            + " flees the battlefield.\n");            game.moveToGraveyard(entity.getId());            send(createRemoveEntityPacket(entity.getId()));            return;        }                // check for MASC failure        if (entity instanceof Mech) {            if (((Mech)entity).checkForMASCFailure(phaseReport)) {                // no movement after that                return;            }        }                                // okay, proceed with movement calculations        Coords lastPos = entity.getPosition();        Coords curPos = entity.getPosition();        int curFacing = entity.getFacing();        int distance = 0;        int mpUsed = 0;        int moveType = Entity.MOVE_NONE;        int overallMoveType = Entity.MOVE_NONE;        boolean firstStep;        boolean wasProne;        boolean fellDuringMovement;	int prevFacing = curFacing;	Hex prevHex = null;	final boolean isInfantry = (entity instanceof Infantry);                Compute.compile(game, entity.getId(), md);                // get last step's movement type        for (final Enumeration i = md.getSteps(); i.hasMoreElements();) {            final MovementData.Step step = (MovementData.Step)i.nextElement();            if (step.getMovementType() == Entity.MOVE_ILLEGAL) {                break;            } else {                overallMoveType = step.getMovementType();            }        }                // iterate through steps        firstStep = true;        fellDuringMovement = false;        for (final Enumeration i = md.getSteps(); i.hasMoreElements();) {            final MovementData.Step step = (MovementData.Step)i.nextElement();            wasProne = entity.isProne();                        // stop for illegal movement            if (step.getMovementType() == Entity.MOVE_ILLEGAL) {                break;            }                        // check piloting skill for getting up            if (step.getType() == MovementData.STEP_GET_UP) {                entity.heatBuildup += 1;                entity.setProne(false);                wasProne = false;                doSkillCheckInPlace(entity, new PilotingRollData(entity.getId(), 0, "getting up"), true);            } else if (firstStep) {                // running with destroyed hip or gyro needs a check                if (overallMoveType == Entity.MOVE_RUN && !entity.isProne()                && (entity.getDestroyedCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_GYRO,Mech.LOC_CT) > 0                || entity.hasHipCrit())) {                    doSkillCheckInPlace(entity, new PilotingRollData(entity.getId(), 0, "running with damaged hip actuator or gyro"), false);                }                firstStep = false;            }                        // did the entity just fall?            if (!wasProne && entity.isProne()) {                moveType = step.getMovementType();                curFacing = entity.getFacing();                curPos = entity.getPosition();                mpUsed = step.getMpUsed();                fellDuringMovement = true;                break;            }                         if (step.getType() == MovementData.STEP_UNJAM_RAC) {                entity.setUnjammingRAC(true);                attacks.addElement(new UnjamAction(entity.getId()));                break;            }            // set most step parameters            moveType = step.getMovementType();            distance = step.getDistance();            mpUsed = step.getMpUsed();            // check for charge            if (step.getType() == MovementData.STEP_CHARGE) {                Entity target = step.getTarget( game );                ChargeAttackAction caa = new ChargeAttackAction(entity.getId(), target.getId(), target.getPosition());                entity.setDisplacementAttack(caa);                pendingCharges.addElement(caa);                break;            }                        // check for dfa            if (step.getType() == MovementData.STEP_DFA) {                Entity target = step.getTarget( game );                DfaAttackAction daa = new DfaAttackAction(entity.getId(), target.getId(), target.getPosition());                entity.setDisplacementAttack(daa);                pendingCharges.addElement(daa);                break;            }            // set last step parameters            curPos = step.getPosition();            curFacing = step.getFacing();            final Hex curHex = game.board.getHex(curPos);            // Check for skid.	    if ( moveType != Entity.MOVE_JUMP		 && prevHex != null		 && prevHex.contains(Terrain.PAVEMENT)		 && overallMoveType == Entity.MOVE_RUN		 && prevFacing != curFacing		 && !lastPos.equals(curPos)		 && !isInfantry ) {		// Have an entity-meaningful PSR message.		PilotingRollData psr = null;		if ( entity instanceof Mech ) {		    psr = new PilotingRollData			(entity.getId(), getMovementPSRModifier(distance),			 "running & turning on pavement", true);		} else {		    psr = new PilotingRollData			(entity.getId(), getMovementPSRModifier(distance),			 "reckless driving on pavement", true);		}		// Does the entity skid?		if ( !doSkillCheckWhileMoving(entity, lastPos, lastPos, psr) ){                    curPos = lastPos;		    Coords nextPos = curPos;		    Hex    nextHex = null;		    int    skidDistance = 0;		    Enumeration targets = null;		    Entity target = null;		    int    curElevation;		    int    nextElevation;		    // All charge damage is based upon                    // the pre-skid move distance.		    entity.delta_distance = distance-1;                    // BUG: all attacks against a skidding target are at +2,                    //          and are *NOT* based upon distance moved at all.                    // TODO: add Entity.MOVE_SKID constant and update the                    //          Compute#getTargetMovementModifier methods.		    // What is the first hex in the skid?		    nextPos = curPos.translated( prevFacing );		    nextHex = game.board.getHex( nextPos );		    // Move the entity a number hexes from curPos in the		    // prevFacing direction equal to half the distance moved                    // this turn (rounded up), unless something intervenes.		    for ( skidDistance = 0;                          skidDistance < (int) Math.ceil(entity.delta_distance / 2.0); 			  skidDistance++ ) {			// Is the next hex off the board?			if ( !game.board.contains(nextPos) ) {			    // Can the entity skid off the map?			    if ( game.getOptions().booleanOption("push_off_board") ) {				// Yup.  One dead entity.				game.moveToGraveyard(entity.getId());				send(createRemoveEntityPacket(entity.getId()));				phaseReport.append("*** " + entity.getDisplayName() + " has skidded off the field. ***\n");			    } else {				// Nope.  Update the report.				phaseReport.append( "   Can't skid off the field.\n" );			    }			    // Stay in the current hex and stop skidding.			    break;			}			// Can the skiding entity enter the hex?			if ( entity.isHexProhibited(nextHex) ) {			    // Update report.			    phaseReport.append( "   Can't skid into hex " + 						nextPos.getBoardNum() +						".\n" );			    // TODO: inflict any damage			    // Stay in the current hex and stop skidding.			    break;			}                        // BMRr pg. 22 - Can't skid uphill,                        //      but can skid downhill.			curElevation = game.board.getHex(curPos).floor();			nextElevation = nextHex.floor();                        // Hovercraft can "skid" over water.                        if ( entity instanceof Tank &&                             entity.getMovementType() ==                             Entity.MovementType.HOVER ) {                            Terrain land = game.board.getHex(curPos).                                getTerrain(Terrain.WATER);                            if ( land != null ) {                                curElevation += land.getLevel();                            }                            land = nextHex.getTerrain(Terrain.WATER);                            if ( land != null ) {                                nextElevation += land.getLevel();                            }                        }			if ( curElevation < nextElevation ) {			    phaseReport.append                                ( "   Can not skid uphill into hex " +                                  nextPos.getBoardNum() + ".\n" );			    // Stay in the current hex and stop skidding.			    break;			}			// Does the next hex contain an entities?			boolean stopTheSkid = false;			targets = game.getEntities( nextPos );			while ( targets.hasMoreElements() ) {			    target = (Entity) targets.nextElement();                            // TODO : allow ready targets to move out of way			    // TODO : Handle targets in buildings.			    // Mechs and vehicles get charged.			    if ( !(target instanceof Infantry) ) {				// Update report.				phaseReport.append( "   Skids into " +						    target.getShortName() +						    " in hex " +						    nextPos.getBoardNum() +						    "... " );				// Resolve a charge against the target.				ToHitData toHit = new ToHitData();				toHit.setHitTable( target.isProne() ? 						   ToHitData.HIT_NORMAL :						   ToHitData.HIT_KICK );				toHit.setSideTable				    (Compute.targetSideTable(entity, target));				resolveChargeDamage				    (entity, target, toHit, prevFacing);				// The skid ends here if the target lives.                                // TODO : do we keep skiding if the target                                //      is pushed off the board?                                if ( !target.isDoomed() &&                                     !target.isDestroyed() ) {                                    stopTheSkid = true;                                }			    }			    // Resolve "move-through" damage on infantry.			    else {				// Update report.				phaseReport.append( "   Skids through " +						    target.getShortName() +						    " in hex " +						    nextPos.getBoardNum() +						    "... " );				// Infantry don't have different				// tables for punches and kicks				HitData hit = target.rollHitLocation( ToHitData.HIT_NORMAL,								      Compute.targetSideTable(entity, target)								      );				// Damage equals tonnage, divided by 5.				phaseReport.append( damageEntity(target, hit, (int)Math.round(entity.getWeight()/5)) );				phaseReport.append( "\n" );			    } // End handle-infantry			    			    // Has the target been destroyed?			    if ( target.isDoomed() ) {				// Has the target taken a turn?				if ( target.ready ) {				    // Dead entities don't take turns.				    int targetOwnerId = target.getOwner().getId();				    for ( int loop = turnIndex + 1;					  loop < turns.size();					  loop++ ) {					// Is the loop-th turn for the 					// destroyed target's player?					if ( targetOwnerId == ( (GameTurn)turns.elementAt(loop) ).getPlayerNum() ) {					    // Yup. Remove the turn and stop looping.					    turns.removeElementAt( loop );					    break;					}				    } // Check the next turn				} // End target-still-to-move				// Yup.  Clean out the entity.				target.setDestroyed(true);				game.moveToGraveyard(target.getId());				send(createRemoveEntityPacket(target.getId()));			    }			    // Update the target's position,			    // unless it is off the game map.			    if ( !game.isInGraveyard(target) ) {				entityUpdate( target.getId() );			    }			} // End someone's-in-the-way			// Do we stay in the current hex and stop skidding?			if ( stopTheSkid ) {			    break;			}			// Did we skid into a building?                        // TODO : BMRr pg. 22, only count buildings that are                        //      higher than our starting terrain height.			if ( nextHex.contains(Terrain.BUILDING) ) {			    // Update report.			    phaseReport.append( "   Skids into building in hex " +						nextPos.getBoardNum() +						".\n" );			    // TODO : Damage the building and the skidding entity.			    // Skid into the building's hex and stop skidding.			    curPos = nextPos;			    entity.setPosition( curPos );			    break;			}			// Update the position and keep skidding.			curPos = nextPos;			entity.setPosition( curPos );			phaseReport.append( "   Skids into hex " + 					    curPos.getBoardNum() + ".\n" );			// Get the next hex in the skid?			nextPos = nextPos.translated( prevFacing );			nextHex = game.board.getHex( nextPos );		    } // Handle the next skid hex.		    // If the skidding entity violates stacking,		    // displace targets until it doesn't.		    curPos = entity.getPosition();		    target = Compute.stackingViolation			(game, entity.getId(), curPos);		    while (target != null) {			nextPos = Compute.getValidDisplacement			    (game, target.getId(),			     target.getPosition(), prevFacing);			// ASSUMPTION			// There should always be *somewhere* that			// the target can go... last skid hex if			// nothing else is available.			if ( null == nextPos ) {			    // But I don't trust the assumption fully.			    // Report the error and try to continue.			    System.err.println( "The skid of " +						entity.getShortName() +						" should displace " +						target.getShortName() +						" in hex " +						curPos.getBoardNum() +						" but there is nowhere to go."						);			    break;			}			phaseReport.append( "    " ); // indent displacement			doEntityDisplacement(target, curPos, nextPos, null);			target = Compute.stackingViolation( game, 							    entity.getId(), 							    curPos );		    }		    // Mechs suffer damage for every hex skidded.		    if ( entity instanceof Mech ) {			// Calculate one half falling damage times skid length.			int damage = skidDistance * (int) Math.ceil(Math.round(entity.getWeight() / 10.0) / 2.0);			// report skid damage			phaseReport.append("    " + entity.getDisplayName() + " suffers " + damage + " damage from the skid.");			// standard damage loop			// All skid damage is to the front.			while (damage > 0) {			    int cluster = Math.min(5, damage);			    HitData hit = entity.rollHitLocation(ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT);			    phaseReport.append(damageEntity(entity, hit, cluster));			    damage -= cluster;			}			phaseReport.append( "\n" );		    }		    // Clean up the entity if it has been destroyed.		    if ( entity.isDoomed() ) {			entity.setDestroyed(true);			game.moveToGraveyard(entity.getId());			send(createRemoveEntityPacket(entity.getId()));		    }		    // Let the player know the ordeal is over.		    phaseReport.append( "      Skid ends.\n" );		    // set entity parameters		    curFacing = entity.getFacing();		    curPos = entity.getPosition();		    entity.setSecondaryFacing( curFacing );		    mpUsed = entity.getRunMP(); // skid consumes all movement		    entity.moved = moveType;		    fellDuringMovement = true;		    break;		}            }            // check if we've moved into rubble            if (!lastPos.equals(curPos)            && step.getMovementType() != Entity.MOVE_JUMP            && curHex.levelOf(Terrain.RUBBLE) > 0) {                doSkillCheckWhileMoving(entity, lastPos, curPos, new PilotingRollData(entity.getId(), 0, "entering Rubble"));            }                        // check to see if we've moved OUT of fire and we are a mech            if (!lastPos.equals(curPos)            && step.getMovementType() != Entity.MOVE_JUMP            && game.board.getHex(lastPos).contains(Terrain.FIRE)) {                if (entity instanceof Mech) {                    entity.heatBuildup+=2;                    phaseReport.append("\n" + entity.getDisplayName()                    + " passes through a fire.  It will generate 2 more heat this round.\n");                }            }	                        // check to see if we've moved INTO fire and we are not a mech            if (!lastPos.equals(curPos)            && step.getMovementType() != Entity.MOVE_JUMP            && game.board.getHex(curPos).contains(Terrain.FIRE)) {                if (!(entity instanceof Mech)) {                    doFlamingDeath(entity);                }            }	            // check if we've moved into water            if (!lastPos.equals(curPos)            && step.getMovementType() != Entity.MOVE_JUMP            && curHex.levelOf(Terrain.WATER) > 0            && entity.getMovementType() != Entity.MovementType.HOVER) {                if (curHex.levelOf(Terrain.WATER) == 1) {                    doSkillCheckWhileMoving(entity, lastPos, curPos, new PilotingRollData(entity.getId(), -1, "entering Depth 1 Water"));                } else if (curHex.levelOf(Terrain.WATER) == 2) {                    doSkillCheckWhileMoving(entity, lastPos, curPos, new PilotingRollData(entity.getId(), 0, "entering Depth 2 Water"));                } else {                    doSkillCheckWhileMoving(entity, lastPos, curPos, new PilotingRollData(entity.getId(), 1, "entering Depth 3+ Water"));                }            }            // Handle loading units.            if ( step.getType() == MovementData.STEP_LOAD ) {                // Find the unit being loaded.                Entity loaded = null;                Enumeration entities = game.getEntities( curPos );                while ( entities.hasMoreElements() ) {                    // Is the other unit friendly and not the current entity?                    loaded = (Entity)entities.nextElement();                    if ( entity.getOwner() == loaded.getOwner() &&                         !entity.equals(loaded) ) {                        // The moving unit should be able to load the other                        // unit and the other should be able to have a turn.                        if ( !entity.canLoad(loaded) ||                             !loaded.isSelectable() ) {                            // Something is fishy in Denmark.                            System.err.println( entity.getShortName() +                                                " can not load " +                                                loaded.getShortName() );                            loaded = null;                        }                        else {                            // Have the deployed unit load the indicated unit.                            this.loadUnit( entity, loaded );                            // Stop looking.                            break;                        }                    } else {                        // Nope. Discard it.                        loaded = null;                    }                } // Handle the next entity in this hex.                // We were supposed to find someone to load.                if ( loaded == null ) {                    System.err.println( "Could not find unit for " +                                        entity.getShortName() +                                        " to load in " + curPos );                }            } // End STEP_LOAD            // Handle unloading units.            if ( step.getType() == MovementData.STEP_UNLOAD ) {                Entity unloaded = step.getTarget( game );                if ( !this.unloadUnit( entity, unloaded,                                       curPos, curFacing ) ) {                    System.err.println( "Error! Server was told to unload " +                                        unloaded.getShortName() +                                        " from " + entity.getShortName() +                                        " into " + curPos.getBoardNum() );                }            }            // did the entity just fall?            if (!wasProne && entity.isProne()) {                curFacing = entity.getFacing();                curPos = entity.getPosition();                mpUsed = step.getMpUsed();                fellDuringMovement = true;                break;            }                        // update lastPos, prevFacing & prevHex            lastPos = new Coords(curPos);            if (!curHex.equals(prevHex)) {                prevFacing = curFacing;            }            prevHex = curHex;        }                // set entity parameters        entity.setPosition(curPos);        entity.setFacing(curFacing);        entity.setSecondaryFacing(curFacing);        entity.delta_distance = distance;        entity.moved = moveType;        entity.mpUsed = mpUsed;                            // but the danger isn't over yet!  landing from a jump can be risky!        if (overallMoveType == Entity.MOVE_JUMP && !entity.isMakingDfa()) {            // check for damaged criticals            if (entity.getDestroyedCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_GYRO,Mech.LOC_CT) > 0 || entity.hasLegActuatorCrit()) {                doSkillCheckInPlace(entity, new PilotingRollData(entity.getId(), 0, "landing with damaged leg actuator or gyro"), false);            }            // jumped into water?            int waterLevel = game.board.getHex(curPos).levelOf(Terrain.WATER);            if (waterLevel == 1) {                doSkillCheckInPlace(entity, new PilotingRollData(entity.getId(), -1, "entering Depth 1 Water"), false);            } else if (waterLevel == 2) {                doSkillCheckInPlace(entity, new PilotingRollData(entity.getId(), 0, "entering Depth 2 Water"), false);            } else if (waterLevel >= 3) {                doSkillCheckInPlace(entity, new PilotingRollData(entity.getId(), 1, "entering Depth 3+ Water"), false);            }        }                // build up heat from movement        if (moveType == Entity.MOVE_WALK) {            entity.heatBuildup += 1;        } else if (moveType == Entity.MOVE_RUN) {            entity.heatBuildup += 2;        } else if (moveType == Entity.MOVE_JUMP) {            entity.heatBuildup += Math.max(3, distance);        }                // should we give another turn to the entity to keep moving?        if (fellDuringMovement && entity.mpUsed < entity.getRunMP() && entity.isSelectable()) {            entity.applyDamage();            entity.ready = true;            turns.insertElementAt(new GameTurn(entity.getOwner().getId(), entity.getId()), turnIndex);        } else {            entity.ready = false;        }                // Is the entity Infantry?        if ( entity instanceof Infantry ) {            // Increment the counter.            turnInfMoved++;            // Record the player moving the infantry.            turnLastPlayerId = entity.getOwnerId();            // Do infantry move in blocks?            if ( infMoveMulti ) {                // Are we at the end of a block?                if ( Game.INF_MOVE_MULTI == turnInfMoved ||                     !game.hasInfantry(turnLastPlayerId) ) {                                // Yup.  Reset the counter.                    turnInfMoved = 0;                }                else {                                // Nope.  Decrement the turn index.                    turnIndex--;                }            } // End inf_move_multi        } // End entity-is-infantry        // Update the entitiy's position,        // unless it is off the game map.        if ( !game.isInGraveyard(entity) ) {            entityUpdate( entity.getId() );        }                // if using double blind, update the player on new units he might see        if (doBlind()) {            send(entity.getOwner().getId(), createFilteredEntitiesPacket(entity.getOwner()));        }    }