📄 movestep.java
字号:
/* * MegaMek - * Copyright (C) 2000,2001,2002,2003,2004,2005 Ben Mazur (bmazur@sev.org) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA *//* * Created on Aug 28, 2003 */package megamek.common;import java.io.Serializable;import java.util.Enumeration;/** * A single step in the entity's movment. */public class MoveStep implements Serializable { private int type = 0; private int targetId = Entity.NONE; private int targetType = Targetable.TYPE_ENTITY; private Coords position; private int facing; private int mp; // this step private int mpUsed; // whole path private int heat; //this step private int totalHeat; private int distance; private int elevation=-999; private int mineToLay = -1; /** * This step's static movement type. Additional * steps in the path will not change this value. */ private int movementType; private boolean isProne; private boolean isHullDown; private boolean climbMode; private boolean danger; // keep psr private boolean pastDanger; private boolean isUsingMASC; private int targetNumberMASC; // psr // private boolean firstStep; // check if no previous private boolean isTurning; // method private boolean isUnloaded; private boolean hasEverUnloaded; private boolean prevStepOnPavement; // prev private boolean hasJustStood; private boolean thisStepBackwards; private boolean onlyPavement; // additive private boolean isPavementStep; private boolean isRunProhibited = false; private boolean isStackingViolation = false; private boolean isDiggingIn = false; private MovePath parent = null; /** * Flag that indicates that this step is into prohibited terrain. * <p/> * If the unit is jumping, this step is only invalid if it is the * end of the path. */ private boolean terrainInvalid = false; /** * Flag that indicates that this step's position is the end of a path. */ private boolean isEndPos = true; /** * Create a step of the given type. * * @param type - * should match one of the MovePath constants, but this is not * currently checked. */ public MoveStep(MovePath path, int type) { this.type = type; this.parent = path; if (type==MovePath.STEP_UNLOAD) { hasEverUnloaded=true; } else { hasEverUnloaded=false; } } /** * Create a step with the given target. * * @param type - * should match one of the MovePath constants, but this is not * currently checked. * @param target - * the <code>Targetable</code> that is the target of this * step. For example, the enemy being charged. */ public MoveStep(MovePath path, int type, Targetable target) { this(path, type); this.targetId = target.getTargetId(); this.targetType = target.getTargetType(); if (type==MovePath.STEP_UNLOAD) { hasEverUnloaded=true; } else { hasEverUnloaded=false; } } /** * Create a step with the given mine to lay. * * @param path * @param type - * should match one of the MovePath constants, but this is not * currently checked. * @param mineToLay - * the <code>int</code> that is the id of the mine * that should be laid in this step. */ public MoveStep(MovePath path, int type, int mineToLay) { this (path, type); this.mineToLay = mineToLay; } void setParent(MovePath path) { parent = path; } public String toString() { switch (type) { case MovePath.STEP_BACKWARDS : return "B"; case MovePath.STEP_CHARGE : return "Ch"; case MovePath.STEP_DFA : return "DFA"; case MovePath.STEP_FORWARDS : return "F"; case MovePath.STEP_GET_UP : return "Up"; case MovePath.STEP_GO_PRONE : return "Prone"; case MovePath.STEP_START_JUMP : return "StrJump"; case MovePath.STEP_TURN_LEFT : return "L"; case MovePath.STEP_TURN_RIGHT : return "R"; case MovePath.STEP_LATERAL_LEFT : return "ShL"; case MovePath.STEP_LATERAL_RIGHT : return "ShR"; case MovePath.STEP_LATERAL_LEFT_BACKWARDS : return "ShLB"; case MovePath.STEP_LATERAL_RIGHT_BACKWARDS : return "ShRB"; case MovePath.STEP_UNJAM_RAC : return "Unjam"; case MovePath.STEP_SEARCHLIGHT : return "SLight"; case MovePath.STEP_LOAD : return "Load"; case MovePath.STEP_UNLOAD : return "Unload"; case MovePath.STEP_EJECT : return "Eject"; case MovePath.STEP_UP : return "U"; case MovePath.STEP_DOWN : return "D"; case MovePath.STEP_HULL_DOWN : return "HullDown"; case MovePath.STEP_CLIMB_MODE_ON: return "CM+"; case MovePath.STEP_CLIMB_MODE_OFF: return "CM-"; default : return "???"; } } public int getType() { return type; } public MovePath getParent() { return parent; } /** * Set the target of the current step. * * @param target - * the <code>Targetable</code> that is the target of this * step. For example, the enemy being charged. If there is no * target, pass a <code>null</code> */ public void setTarget(Targetable target) { if (target == null) { this.targetId = Entity.NONE; this.targetType = Targetable.TYPE_ENTITY; } else { this.targetId = target.getTargetId(); this.targetType = target.getTargetType(); } } /** * Get the target of the current step. * * @param game - * The <code>Game</code> object. * @return The <code>Targetable</code> that is the target of this step. * For example, the enemy being charged. This value may be <code>null</code> */ public Targetable getTarget(IGame game) { if (this.targetId == Entity.NONE) { return null; } return game.getTarget(this.targetType, this.targetId); } /** * Helper for compile(), to deal with steps that move to a new hex. * @param game * @param entity * @param prev */ private void compileMove(final IGame game, final Entity entity, MoveStep prev) { IHex destHex = game.getBoard().getHex(getPosition()); // Check for pavement movement. if (Compute.canMoveOnPavement(game, prev.getPosition(), getPosition())) { setPavementStep(true); } else { setPavementStep(false); setOnlyPavement(false); } setHasJustStood(false); if (prev.isThisStepBackwards() != isThisStepBackwards()) { setDistance(0); //start over after shifting gears } addDistance(1); if (getType() == MovePath.STEP_DFA) { IHex hex = game.getBoard().getHex(getPosition()); setElevation(Math.max(0, hex.terrainLevel(Terrains.BLDG_ELEV))); // If we're DFA-ing, we want to be 1 above the level of the target. // However, if that puts us in the ground, we're instead 1 above the level of the hex right before the target. int otherEl = 0; IHex hex2 = game.getBoard().getHex(prev.getPosition()); otherEl = Math.max(0, hex2.terrainLevel(Terrains.BLDG_ELEV)); if (otherEl > getElevation()) setElevation(otherEl); setElevation(getElevation() + 1); } else if (parent.isJumping()) { IHex hex = game.getBoard().getHex(getPosition()); int maxElevation = entity.getJumpMP() + entity.getElevation() + game.getBoard().getHex(entity.getPosition()).surface() - hex.surface(); int building = hex.terrainLevel(Terrains.BLDG_ELEV); if (entity instanceof Infantry) { //infantry can jump into a building setElevation(Math.max(-hex.depth(), Math.min(building,maxElevation))); } else { setElevation(Math.max(-hex.depth(), building)); } if (climbMode() && maxElevation >= hex.terrainLevel(Terrains.BRIDGE_ELEV)) { setElevation(Math.max(getElevation(), hex.terrainLevel(Terrains.BRIDGE_ELEV))); } } else { setElevation(entity.calcElevation(game.getBoard().getHex(prev.getPosition()),game.getBoard().getHex(getPosition()),elevation, climbMode())); } calcMovementCostFor(game, prev.getPosition(), prev.getElevation()); // check for water if (!isPavementStep() && destHex.terrainLevel(Terrains.WATER) > 0 && !(destHex.containsTerrain(Terrains.ICE) && elevation >= 0) && !(destHex.terrainLevel(Terrains.BRIDGE_ELEV) == elevation) && entity.getMovementMode() != IEntityMovementMode.HOVER && entity.getMovementMode() != IEntityMovementMode.NAVAL && entity.getMovementMode() != IEntityMovementMode.HYDROFOIL && !(elevation == 0 && entity.getMovementMode() == IEntityMovementMode.SUBMARINE) //sub can't flank underwater && entity.getMovementMode() != IEntityMovementMode.VTOL) { setRunProhibited(true); } int magmaLevel = destHex.terrainLevel(Terrains.MAGMA); if(elevation > 0) { magmaLevel = 0; } // Check for fire or magma crust in the new hex. if (destHex.containsTerrain(Terrains.FIRE) || magmaLevel == 1) { heat = 2; totalHeat += 2; } // Check for liquid magma else if(magmaLevel == 2) { heat = 5; totalHeat += 5; } } /** * Compile the static move data for this step. * * @param game the <code>Game</code> being played. * @param entity the <code>Entity</code> taking this step. * @param prev the previous step in the path. */ protected void compile(final IGame game, final Entity entity, MoveStep prev) { final boolean isInfantry = entity instanceof Infantry; copy(game, prev); // Is this the first step? if (prev == null) { prev = new MoveStep(parent, MovePath.STEP_FORWARDS); prev.setFromEntity(entity, game); setFirstStep( prev.mpUsed == 0 ); // Bug 1519330 - its not a first step when continuing after a fall } switch (getType()) { case MovePath.STEP_UNLOAD : // Infantry in immobilized transporters get // a special "unload stranded" game turn. hasEverUnloaded=true; setMp(1); break; case MovePath.STEP_LOAD : setMp(1); break; case MovePath.STEP_TURN_LEFT : case MovePath.STEP_TURN_RIGHT : // Check for pavement movement. if (Compute.canMoveOnPavement(game, prev.getPosition(), getPosition())) { setPavementStep(true); } else { setPavementStep(false); setOnlyPavement(false); } // Infantry can turn for free. setMp( ( parent.isJumping() || isHasJustStood() || isInfantry ) ? 0 : 1 ); adjustFacing(getType()); break; case MovePath.STEP_BACKWARDS : moveInDir((getFacing() + 3) % 6); setThisStepBackwards(true); setRunProhibited(true); compileMove(game, entity, prev); break; case MovePath.STEP_FORWARDS : case MovePath.STEP_CHARGE : case MovePath.STEP_DFA : case MovePath.STEP_SWIM: // step forwards or backwards moveInDir(getFacing()); setThisStepBackwards(false); compileMove(game, entity, prev); break; case MovePath.STEP_LATERAL_LEFT_BACKWARDS : case MovePath.STEP_LATERAL_RIGHT_BACKWARDS : moveInDir( (MovePath .getAdjustedFacing( getFacing(), MovePath.turnForLateralShift(getType())) + 3) % 6); setThisStepBackwards(true); setRunProhibited(true); compileMove(game, entity, prev); setMp(getMp() + 1); //+1 for side step break; case MovePath.STEP_LATERAL_LEFT : case MovePath.STEP_LATERAL_RIGHT : moveInDir( MovePath.getAdjustedFacing( getFacing(), MovePath.turnForLateralShift(getType()))); setThisStepBackwards(false); compileMove(game, entity, prev); setMp(getMp() + 1); //+1 for side step break; case MovePath.STEP_GET_UP : // mechs with 1 MP are allowed to get up setMp(entity.getRunMP() == 1 ? 1 : 2); setHasJustStood(true);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -