⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compute.java

📁 MegaMek is a networked Java clone of BattleTech, a turn-based sci-fi boardgame for 2+ players. Fight
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
         */        if (((prevStepIsOnPavement && movementType == IEntityMovementType.MOVE_RUN)                 || (srcHex.containsTerrain(Terrains.ICE)) && movementType != IEntityMovementType.MOVE_JUMP)                 && isTurning && !isInfantry) {            return true;        }        // If we entering or leaving a building, all non-infantry        // need to make a piloting check to avoid damage.        // TODO: allow entities to occupy different levels of buildings.        if ((srcElevation < srcHex.terrainLevel(Terrains.BLDG_ELEV) || destElevation < destHex                .terrainLevel(Terrains.BLDG_ELEV))                && !(entity instanceof Infantry)) {            return true;        }        // check sideslips        if (entity instanceof VTOL) {            if (isTurning                    && ((movementType == IEntityMovementType.MOVE_RUN) || (movementType == IEntityMovementType.MOVE_VTOL_RUN)))                return true;        }        return false;    }    /**     * Can the defending unit be displaced from the source to the destination?     */    public static boolean isValidDisplacement(IGame game, int entityId,            Coords src, int direction) {        return isValidDisplacement(game, entityId, src, src                .translated(direction));    }    /**     * Can the defending unit be displaced from the source to the destination?     */    public static boolean isValidDisplacement(IGame game, int entityId,            Coords src, Coords dest) {        final Entity entity = game.getEntity(entityId);        final IHex srcHex = game.getBoard().getHex(src);        final IHex destHex = game.getBoard().getHex(dest);        final ArrayList<Coords> intervening = Coords.intervening(src, dest);        final int direction = src.direction(dest);        // arguments valid?        if (entity == null) {            throw new IllegalArgumentException("Entity invalid.");        }        // an easy check        if (!game.getBoard().contains(dest)) {            if (game.getOptions().booleanOption("push_off_board")) {                return true;            }			return false;        }        // can't be displaced into prohibited terrain        // unless we're displacing a tracked or wheeled vee into water        if (entity.isHexProhibited(destHex)                && !(entity instanceof Tank                        && destHex.containsTerrain(Terrains.WATER) && (entity.movementMode == IEntityMovementMode.TRACKED || entity.movementMode == IEntityMovementMode.WHEELED))) {            return false;        }        // can't go up more levels than normally possible        for (Coords c : intervening) {            final IHex hex = game.getBoard().getHex(c);            int change = entity.elevationOccupied(hex)                    - entity.elevationOccupied(srcHex);            if (change > entity.getMaxElevationChange()) {                return false;            }        }        // if there's an entity in the way, can they be displaced in that        // direction?        Entity inTheWay = stackingViolation(game, entityId, dest);        if (inTheWay != null) {            return isValidDisplacement(game, inTheWay.getId(), inTheWay                    .getPosition(), direction);        }        // okay, that's about all the checks        return true;    }    /**     * Gets a valid displacement, from the hexes around src, as close to the     * original direction as is possible.     *      * @return valid displacement coords, or null if none     */    public static Coords getValidDisplacement(IGame game, int entityId,            Coords src, int direction) {        // check the surrounding hexes, nearest to the original direction first        int[] offsets = { 0, 1, 5, 2, 4, 3 };        for (int i = 0; i < offsets.length; i++) {            Coords dest = src.translated((direction + offsets[i]) % 6);            if (isValidDisplacement(game, entityId, src, dest)) {                return dest;            }        }        // have fun being insta-killed!        return null;    }    /**     * Gets a preferred displacement. Right now this picks the surrounding hex     * with the highest elevation that is a valid displacement.     *      * @return valid displacement coords, or null if none     */    public static Coords getPreferredDisplacement(IGame game, int entityId,            Coords src, int direction) {        final Entity entity = game.getEntity(entityId);        int highestElev = Integer.MIN_VALUE;        Coords highest = null;        // check the surrounding hexes, nearest to the original direction first        int[] offsets = { 0, 1, 5, 2, 4, 3 };        for (int i = 0; i < offsets.length; i++) {            Coords dest = src.translated((direction + offsets[i]) % 6);            if (isValidDisplacement(game, entityId, src, dest)                    && game.getBoard().contains(dest)) {                IHex hex = game.getBoard().getHex(dest);                int elevation = entity.elevationOccupied(hex);                if (elevation > highestElev) {                    highestElev = elevation;                    highest = dest;                }                // preferably, go to same elevation                if (elevation == entity.getElevation()) {                    return dest;                }            }        }        return highest;    }    /**     * Gets a hex to displace a missed charge to. Picks left or right, first     * preferring higher hexes, then randomly, or returns the base hex if     * they're impassible.     */    public static Coords getMissedChargeDisplacement(IGame game, int entityId,            Coords src, int direction) {        Coords first = src.translated((direction + 1) % 6);        Coords second = src.translated((direction + 5) % 6);        IHex firstHex = game.getBoard().getHex(first);        IHex secondHex = game.getBoard().getHex(second);        Entity entity = game.getEntity(entityId);        if (firstHex == null || secondHex == null) {            // leave it, will be handled        } else if (entity.elevationOccupied(firstHex) > entity                .elevationOccupied(secondHex)) {            // leave it        } else if (entity.elevationOccupied(firstHex) < entity                .elevationOccupied(secondHex)) {            // switch            Coords temp = first;            first = second;            second = temp;        } else if (Compute.d6() > 3) {            // switch randomly            Coords temp = first;            first = second;            second = temp;        }        if (isValidDisplacement(game, entityId, src, src.direction(first))                && game.getBoard().contains(first)) {            return first;        } else if (isValidDisplacement(game, entityId, src, src                .direction(second))                && game.getBoard().contains(second)) {            return second;        } else {            return src;        }    }    /**     * Finds the best spotter for the attacker. The best spotter is the one with     * the lowest attack modifiers, of course. LOS modifiers and movement are     * considered.     */    public static Entity findSpotter(IGame game, Entity attacker,            Targetable target) {        Entity spotter = null;        int taggedBy = -1;        if (target instanceof Entity) {            taggedBy = ((Entity)target).getTaggedBy();        }        ToHitData bestMods = new ToHitData(ToHitData.IMPOSSIBLE, "");        for (java.util.Enumeration i = game.getEntities(); i.hasMoreElements();) {            Entity other = (Entity) i.nextElement();            if ( (other.isSpotting() || taggedBy == other.getId() )                 && !attacker.isEnemyOf(other)) {                // what are this guy's mods to the attack?                LosEffects los = LosEffects.calculateLos(game, other.getId(),                                                         target);                ToHitData mods = los.losModifiers(game);                los.setTargetCover(LosEffects.COVER_NONE);                mods.append(getAttackerMovementModifier(game, other.getId()));                // is this guy a better spotter?                if (spotter == null || mods.getValue() < bestMods.getValue()) {                    spotter = other;                    bestMods = mods;                }            }        }        return spotter;    }    public static ToHitData getImmobileMod(Targetable target) {        return getImmobileMod(target, Mech.LOC_NONE, IAimingModes.AIM_MODE_NONE);    }    public static ToHitData getImmobileMod(Targetable target, int aimingAt,            int aimingMode) {        if (target.isImmobile()) {            if (target instanceof Mech &&                aimingAt == Mech.LOC_HEAD &&                aimingMode == IAimingModes.AIM_MODE_IMMOBILE) {                return new ToHitData(3, "aiming at head");            }            return new ToHitData(-4, "target immobile");        }        return null;    }    /**     * Determines the to-hit modifier due to range for an attack with the     * specified parameters. Includes minimum range, infantry 0-range mods, and     * target stealth mods. Accounts for friendly C3 units.     *      * @return the modifiers     */    public static ToHitData getRangeMods(IGame game, Entity ae, int weaponId,            Targetable target) {        Mounted weapon = ae.getEquipment(weaponId);        WeaponType wtype = (WeaponType) weapon.getType();        int[] weaponRanges = wtype.getRanges();        boolean isAttackerInfantry = (ae instanceof Infantry);        boolean isWeaponInfantry = wtype.hasFlag(WeaponType.F_INFANTRY);        boolean isLRMInfantry = isWeaponInfantry                && wtype.getAmmoType() == AmmoType.T_LRM;        boolean isIndirect = ((wtype.getAmmoType() == AmmoType.T_LRM)                || (wtype.getAmmoType() == AmmoType.T_EXLRM)                || (wtype.getAmmoType() == AmmoType.T_TBOLT5)                 || (wtype.getAmmoType() == AmmoType.T_TBOLT10)                || (wtype.getAmmoType() == AmmoType.T_TBOLT15)                || (wtype.getAmmoType() == AmmoType.T_TBOLT20)                || (wtype.getAmmoType() == AmmoType.T_LRM_TORPEDO))                && weapon.curMode().equals("Indirect");        boolean useExtremeRange = game.getOptions().booleanOption(                "maxtech_range");        ToHitData mods = new ToHitData();        // modify the ranges for ATM missile systems based on the ammo selected        // TODO: this is not the right place to hardcode these        if (wtype.getAmmoType() == AmmoType.T_ATM) {            AmmoType atype = (AmmoType) weapon.getLinked().getType();            if ((atype.getAmmoType() == AmmoType.T_ATM)                    && atype.getMunitionType() == AmmoType.M_EXTENDED_RANGE) {                weaponRanges = new int[] { 4, 9, 18, 27, 36 };            } else if ((atype.getAmmoType() == AmmoType.T_ATM)                    && atype.getMunitionType() == AmmoType.M_HIGH_EXPLOSIVE) {                weaponRanges = new int[] { 0, 3, 6, 9, 12 };            }        }        //        // modifiy the ranges for PPCs when field inhibitors are turned off        // TODO: See above, it should be coded elsewhere...        //        if (wtype.getName().equals("Particle Cannon")) {            if (game.getOptions().booleanOption("maxtech_ppc_inhibitors")) {                if (weapon.curMode().equals("Field Inhibitor OFF")) {                    weaponRanges[0] = 0;                }            }        }                //Hotloaded weapons        if ( weapon.isHotLoaded()                 && game.getOptions().booleanOption("maxtech_hotload") )            weaponRanges[RangeType.RANGE_MINIMUM] = 0;                // is water involved?        IHex attHex = game.getBoard().getHex(ae.getPosition());        IHex targHex = game.getBoard().getHex(target.getPosition());        int targTop = 0;        int targBottom = 0;        if (target != null) {            targTop = target.absHeight();            targBottom = target.getElevation();        }        boolean targetInPartialWater = false;        boolean targetUnderwater = false;        boolean weaponUnderwater = (ae.getLocationStatus(weapon.getLocation()) == ILocationExposureStatus.WET);        if (targHex.containsTerrain(Terrains.WATER) && targBottom < 0) {            if (targTop >= 0)                targetInPartialWater = true;            else                targetUnderwater = true;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -