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

📄 loseffects.java

📁 MegaMek is a networked Java clone of BattleTech, a turn-based sci-fi boardgame for 2+ players. Fight
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * MegaMek - Copyright (C) 2002-2003 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. *//* * LosEffects.java * * Created on October 14, 2002, 11:19 PM */package megamek.common;import java.util.ArrayList;/** * Keeps track of the cumulative effects of intervening terrain on LOS * * @author  Ben */public class LosEffects {        public static class AttackInfo {        public boolean attUnderWater;        public boolean attInWater;        public boolean attOnLand;        public boolean targetUnderWater;        public boolean targetInWater;        public boolean targetOnLand;        public boolean underWaterCombat;        public boolean targetEntity = true;        public boolean targetInfantry;        public boolean attOffBoard;        public Coords attackPos;        public Coords targetPos;        public int attackAbsHeight;        public int targetAbsHeight;        public int attackHeight;        public int targetHeight;        int minimumWaterDepth = -1;    }    //                                                  MAXTECH             BMR    public static final int COVER_NONE =        0;      //no cover          (none)    public static final int COVER_LOWLEFT =     0x1;    //25% cover         (partial)    public static final int COVER_LOWRIGHT =    0x2;    //25% cover         (partial)    public static final int COVER_LEFT =        0x4;    //vertical cover    (blocked)    public static final int COVER_RIGHT =       0x8;    //vertical cover    (blocked)    public static final int COVER_HORIZONTAL =  0x3;    //50% cover         (partial)    public static final int COVER_UPPER =       0xC;    //blocked           (blocked) - in case of future rule where only legs are exposed    public static final int COVER_FULL =        0xF;    //blocked           (blocked)    public static final int COVER_75LEFT =      0x7;    //75% cover         (blocked)    public static final int COVER_75RIGHT =     0xB;    //75% cover         (blocked)        boolean blocked = false;    boolean infProtected = false;    boolean hasLoS = true;    int lightWoods = 0;    int heavyWoods = 0;    int ultraWoods = 0;    int lightSmoke = 0;    int heavySmoke = 0; // heavySmoke is also standard for normal L2 smoke    int targetCover = COVER_NONE;  // that means partial cover    int attackerCover = COVER_NONE;  // ditto    Building thruBldg = null;    int minimumWaterDepth = -1;    /** Creates a new instance of LosEffects */    public LosEffects() {    }    public int getMinimumWaterDepth()    {        return minimumWaterDepth;    }    public void setMinimumWaterDepth(int inVal)    {        minimumWaterDepth = inVal;    }    public void add(LosEffects other) {        this.blocked |= other.blocked;        this.infProtected |= other.infProtected;        this.lightWoods += other.lightWoods;        this.heavyWoods += other.heavyWoods;        this.ultraWoods += other.ultraWoods;        this.lightSmoke += other.lightSmoke;        this.heavySmoke += other.heavySmoke;        this.targetCover |= other.targetCover;        this.attackerCover |= other.attackerCover;        if ( null != this.thruBldg &&             !this.thruBldg.equals(other.thruBldg) ) {            this.thruBldg = null;        }    }        public int getLightWoods() {        return lightWoods;    }        public int getHeavyWoods() {        return heavyWoods;    }        public int getUltraWoods() {        return ultraWoods;    }    public int getLightSmoke() {        return lightSmoke;    }        public int getHeavySmoke() {        return heavySmoke;    }    public boolean isBlocked() {        return blocked;    }    /** Getter for property targetCover.     * @return Value of property targetCover.     */    public boolean isTargetCover() {        return targetCover >= COVER_HORIZONTAL;    }        public int getTargetCover() {            return targetCover;    }        /** Setter for property targetCover.     * @param targetCover New value of property targetCover.     */    public void setTargetCover(int targetCover) {        this.targetCover = targetCover;    }    /** Getter for property attackerCover.     * @return Value of property attackerCover.     */    public boolean isAttackerCover() {        return attackerCover >= COVER_HORIZONTAL;    }        public int getAttackerCover() {        return attackerCover;    }        /** Setter for property attackerCover.     * @param attackerCover New value of property attackerCover.     */    public void setAttackerCover(int attackerCover) {        this.attackerCover = attackerCover;    }    /** Getter for property thruBldg.     * @return Value of property thruBldg.     */    public Building getThruBldg() {        return thruBldg;    }        /** Setter for property thruBldg.     * @param thruBldg New value of property thruBldg.     */    public void setThruBldg(Building thruBldg) {        this.thruBldg = thruBldg;    }        /**     * LOS check from ae to te.     */    public boolean canSee() {        return hasLoS;//!blocked && (lightWoods + lightSmoke) + ((heavyWoods + heavySmoke) * 2) < 3;    }    /**     * Returns a LosEffects object representing the LOS effects of interveing     * terrain between the attacker and target.     *     * Checks to see if the attacker and target are at an angle where the LOS     * line will pass between two hexes.  If so, calls losDivided, otherwise      * calls losStraight.     */    public static LosEffects calculateLos(IGame game, int attackerId, Targetable target) {        final Entity ae = game.getEntity(attackerId);                        // LOS fails if one of the entities is not deployed.        if (null == ae.getPosition() || null == target.getPosition() || ae.isOffBoard()) {            LosEffects los = new LosEffects();            los.blocked = true; // TODO: come up with a better "impossible"            los.hasLoS = false;            return los;        }                final AttackInfo ai = new AttackInfo();        ai.attackPos = ae.getPosition();        ai.targetPos = target.getPosition();        ai.targetEntity = target.getTargetType() == Targetable.TYPE_ENTITY;        ai.targetInfantry = target instanceof Infantry;        ai.attackHeight = ae.getHeight();        ai.targetHeight = target.getHeight();            IHex attHex = game.getBoard().getHex(ae.getPosition());        IHex targetHex = game.getBoard().getHex(target.getPosition());        int attEl = ae.absHeight() + attHex.getElevation();        int targEl;        if (target.getTargetType() == Targetable.TYPE_ENTITY                || target.getTargetType() == Targetable.TYPE_FUEL_TANK                || target.getTargetType() == Targetable.TYPE_FUEL_TANK_IGNITE                || target.getTargetType() == Targetable.TYPE_BUILDING                || target.getTargetType() == Targetable.TYPE_BLDG_IGNITE) {            targEl = target.absHeight() + targetHex.getElevation();        } else {            targEl = game.getBoard().getHex(target.getPosition()).surface();        }                ai.attackAbsHeight = attEl;        ai.targetAbsHeight = targEl;        boolean attOffBoard = ae.isOffBoard();        boolean attUnderWater;        boolean attInWater;        boolean attOnLand;        if (attOffBoard) {            attUnderWater = true;            attInWater = false;            attOnLand = true;        } else {            attUnderWater = attHex.containsTerrain(Terrains.WATER) &&                 attHex.depth() > 0 &&                 attEl < attHex.surface();            attInWater = attHex.containsTerrain(Terrains.WATER) &&                attHex.depth() > 0 &&                 attEl == attHex.surface();            attOnLand = !(attUnderWater || attInWater);        }                boolean targetOffBoard = !game.getBoard().contains(target.getPosition());        boolean targetUnderWater;        boolean targetInWater;        boolean targetOnLand;        if (targetOffBoard) {            targetUnderWater = true;            targetInWater = false;            targetOnLand = true;        } else {            targetUnderWater = targetHex.containsTerrain(Terrains.WATER) &&                 targetHex.depth() > 0 &&                 targEl < targetHex.surface();            targetInWater = targetHex.containsTerrain(Terrains.WATER) &&                targetHex.depth() > 0 &&                 targEl == targetHex.surface();            targetOnLand = !(targetUnderWater || targetInWater);        }                boolean underWaterCombat = targetUnderWater || attUnderWater;                ai.attUnderWater = attUnderWater;        ai.attInWater = attInWater;        ai.attOnLand = attOnLand;        ai.targetUnderWater = targetUnderWater;        ai.targetInWater = targetInWater;        ai.targetOnLand = targetOnLand;        ai.underWaterCombat = underWaterCombat;        ai.attOffBoard = attOffBoard;        // Handle minimum water depth.        // Applies to Torpedos.        if(ai.attOnLand || ai.targetOnLand)            ai.minimumWaterDepth = 0;        else if (ai.attInWater || ai.targetInWater)            ai.minimumWaterDepth = 1;        else if (ai.attUnderWater || ai.targetUnderWater)            ai.minimumWaterDepth = Math.min(attHex.terrainLevel(Terrains.WATER),                    targetHex.terrainLevel(Terrains.WATER));        LosEffects finalLoS = calculateLos(game, ai);        finalLoS.setMinimumWaterDepth(ai.minimumWaterDepth);        finalLoS.hasLoS = !finalLoS.blocked && (finalLoS.lightWoods + finalLoS.lightSmoke) + ((finalLoS.heavyWoods + finalLoS.heavySmoke) * 2) + (finalLoS.ultraWoods * 3) < 3;                /*         * Torren (MekWars)         * If LOS is blocked         * And the Attacker has BAP that is working         * i.e. not effect by ECM or destoyed/damaged/breached/Shutdown         * And the target is a Non-Infantry Unit         * And the target is not under water         * And the target is in range of the Attackers BAP         * Then remove the Block.         *          *  Note code was done with 2 version of BMR and maxtech rules from various user sources          *  anything that is wrong please let me know for feature refence.         *           *  This will not detect hidden units(not coded yet anyways)         *  This was designed for double blind.         *           *           */        final int probeRange = ae.getBAPRange();        if ( !finalLoS.canSee()&& ae.hasBAP()                 &&  ai.targetEntity                && !(ai.targetInfantry && !(target instanceof BattleArmor) && probeRange!=8)                && !ai.underWaterCombat                 && ae.getPosition().distance(ai.targetPos) <= probeRange                && !Compute.isAffectedByECM(ae, ae.getPosition(), ai.targetPos)                && !Compute.isAffectedByAngelECM(ae, ae.getPosition(), ai.targetPos)) {            Entity te = (Entity)target;            if(probeRange==8 || !(te.isStealthActive()))                finalLoS.hasLoS = true;        }        return finalLoS;    }    public static LosEffects calculateLos(IGame game, AttackInfo ai) {        if (ai.attOffBoard) {            LosEffects los = new LosEffects();            los.blocked = true;            los.hasLoS = false;            return los;        }        if (ai.attOnLand && ai.targetUnderWater ||            ai.attUnderWater && ai.targetOnLand) {            LosEffects los = new LosEffects();            los.blocked = true;            los.hasLoS = false;            return los;                     }        double degree = ai.attackPos.degree(ai.targetPos);        if (degree % 60 == 30) {            return LosEffects.losDivided(game, ai);        }		return LosEffects.losStraight(game, ai);    }    /**     * Returns ToHitData indicating the modifiers to fire for the specified     * LOS effects data.     */    public ToHitData losModifiers(IGame game) {        return losModifiers(game, 0);    }    public ToHitData losModifiers(IGame game, int eistatus) {        ToHitData modifiers = new ToHitData();        if (blocked) {            return new ToHitData(ToHitData.IMPOSSIBLE, "LOS blocked by terrain.");        }                if (infProtected) {            return new ToHitData(ToHitData.IMPOSSIBLE, "Infantry protected by building.");        }                if (ultraWoods >= 1 || lightWoods + (heavyWoods * 2) > 2) {            return new ToHitData(ToHitData.IMPOSSIBLE, "LOS blocked by woods.");        }        if (lightSmoke + (heavySmoke * 2) > 2) {            return new ToHitData(ToHitData.IMPOSSIBLE, "LOS blocked by smoke.");        }

⌨️ 快捷键说明

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