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

📄 weaponattackaction.java

📁 MegaMek is a networked Java clone of BattleTech, a turn-based sci-fi boardgame for 2+ players. Fight
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * MegaMek - Copyright (C) 2000,2001,2002,2003,2004 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. */package megamek.common.actions;import java.util.Enumeration;import java.util.ArrayList;import megamek.common.AmmoType;import megamek.common.BattleArmor;import megamek.common.Compute;import megamek.common.CriticalSlot;import megamek.common.Entity;import megamek.common.EquipmentType;import megamek.common.GunEmplacement;import megamek.common.HexTarget;import megamek.common.IAimingModes;import megamek.common.IEntityMovementMode;import megamek.common.IEntityMovementType;import megamek.common.IGame;import megamek.common.IHex;import megamek.common.ILocationExposureStatus;import megamek.common.INarcPod;import megamek.common.Infantry;import megamek.common.LosEffects;import megamek.common.Mech;import megamek.common.MechWarrior;import megamek.common.MinefieldTarget;import megamek.common.Mounted;import megamek.common.Protomech;import megamek.common.RangeType;import megamek.common.Tank;import megamek.common.Targetable;import megamek.common.Terrains;import megamek.common.ToHitData;import megamek.common.WeaponType;import megamek.common.VTOL;import megamek.common.MiscType;/** * Represents intention to fire a weapon at the target. */public class WeaponAttackAction extends AbstractAttackAction {    private int weaponId;    private int ammoId = -1;    private int aimedLocation = Mech.LOC_NONE;    private int aimMode = IAimingModes.AIM_MODE_NONE;    private int otherAttackInfo = -1;   //     private boolean nemesisConfused;    private boolean swarmingMissiles;    private int oldTargetId = -1;        // equipment that affects this attack (AMS, ECM?, etc)    // only used server-side    private transient ArrayList vCounterEquipment;        // default to attacking an entity    public WeaponAttackAction(int entityId, int targetId, int weaponId) {        super(entityId, targetId);        this.weaponId = weaponId;    }        public WeaponAttackAction(int entityId, int targetType, int targetId, int weaponId) {        super(entityId, targetType, targetId);        this.weaponId = weaponId;    }        public int getWeaponId() {        return weaponId;    }        public int getAmmoId() {        return ammoId;    }        public int getAimedLocation() {        return aimedLocation;    }        public int getAimingMode() {        return aimMode;    }        public ArrayList getCounterEquipment() {        return vCounterEquipment;    }        public void setWeaponId(int weaponId) {        this.weaponId = weaponId;    }        public void setAmmoId(int ammoId) {        this.ammoId = ammoId;    }        public void setAimedLocation(int aimedLocation) {        this.aimedLocation = aimedLocation;    }        public void setAimingMode(int aimMode) {        this.aimMode = aimMode;    }        public void addCounterEquipment(Mounted m) {        if (vCounterEquipment == null) {            vCounterEquipment = new ArrayList();        }        vCounterEquipment.add(m);    }    public void setOtherAttackInfo(int newInfo) {        otherAttackInfo = newInfo;    }    public int getOtherAttackInfo() {        return otherAttackInfo;    }    public ToHitData toHit(IGame game) {        return WeaponAttackAction.toHit(game, getEntityId(),                           game.getTarget(getTargetType(), getTargetId()),                           getWeaponId(),                           getAimedLocation(),                           getAimingMode(), nemesisConfused, swarmingMissiles, game.getEntity(oldTargetId));    }    public static ToHitData toHit(IGame game, int attackerId, Targetable target, int weaponId) {        return WeaponAttackAction.toHit(game, attackerId, target, weaponId, Mech.LOC_NONE, IAimingModes.AIM_MODE_NONE, false, false, null);      }        public static ToHitData toHit(IGame game, int attackerId, Targetable target, int weaponId, int aimingAt, int aimingMode) {        return toHit(game, attackerId, target, weaponId, aimingAt, aimingMode, false, false, null);    }    /**     * To-hit number for attacker firing a weapon at the target.     */    private static ToHitData toHit(IGame game, int attackerId, Targetable target, int weaponId, int aimingAt, int aimingMode, boolean isNemesisConfused, boolean exchangeSwarmTarget, Entity oldTarget) {        final Entity ae = game.getEntity(attackerId);        final Mounted weapon = ae.getEquipment(weaponId);        final WeaponType wtype = (WeaponType)weapon.getType();        if (exchangeSwarmTarget) {            // Quick check, is the new target out of range for the weapon?            if(RangeType.rangeBracket(ae.getPosition().distance(target.getPosition()), wtype.getRanges(),                    game.getOptions().booleanOption("maxtech_range")) == RangeType.RANGE_OUT) {                return new ToHitData(ToHitData.AUTOMATIC_FAIL, "swarm target out of range");            }            // this is a swarm attack against a new target            // first, exchange old and new targets to get all mods            // as if firing against old target.            // at the end of this function, we remove target terrain            // and movement mods, and add those for the new target            Targetable tempTarget = target;            target = oldTarget;            oldTarget = (Entity)tempTarget;        }        Entity te = null;        if (target.getTargetType() == Targetable.TYPE_ENTITY) {            te = (Entity) target;        }        boolean isAttackerInfantry = ae instanceof Infantry;        boolean isWeaponInfantry = wtype.hasFlag(WeaponType.F_INFANTRY);        // 2003-01-02 BattleArmor MG and Small Lasers have unlimited ammo.        // 2002-09-16 Infantry weapons have unlimited ammo.        final boolean usesAmmo = wtype.getAmmoType() != AmmoType.T_NA &&            wtype.getAmmoType() != AmmoType.T_BA_MG &&            wtype.getAmmoType() != AmmoType.T_BA_SMALL_LASER &&            !isWeaponInfantry;        final Mounted ammo = usesAmmo ? weapon.getLinked() : null;        final AmmoType atype = ammo == null ? null : (AmmoType)ammo.getType();        final boolean targetInBuilding = Compute.isInBuilding( game, te );        boolean isIndirect = wtype.hasModes()            && weapon.curMode().equals("Indirect");        boolean isInferno =            atype != null && (atype.getAmmoType() == AmmoType.T_SRM || atype.getAmmoType() == AmmoType.T_BA_INFERNO) && atype.getMunitionType() == AmmoType.M_INFERNO ||                isWeaponInfantry && wtype.hasFlag(WeaponType.F_INFERNO);        boolean isArtilleryDirect= wtype.hasFlag(WeaponType.F_ARTILLERY) && game.getPhase() == IGame.PHASE_FIRING;        boolean isArtilleryIndirect = wtype.hasFlag(WeaponType.F_ARTILLERY) && (game.getPhase() == IGame.PHASE_TARGETING || game.getPhase() == IGame.PHASE_OFFBOARD);//hack, otherwise when actually resolves shot labeled impossible.        boolean isArtilleryFLAK = isArtilleryDirect &&                                  target.getTargetType() == Targetable.TYPE_ENTITY &&                                  te.getMovementMode() == IEntityMovementMode.VTOL &&                                  te.getElevation() > 0 &&                                  (usesAmmo && atype.getMunitionType() == AmmoType.M_STANDARD);        boolean isHaywireINarced = ae.isINarcedWith(INarcPod.HAYWIRE);        boolean isINarcGuided = false;        boolean isECMAffected = Compute.isAffectedByECM(ae, ae.getPosition(), target.getPosition());        boolean isTAG = wtype.hasFlag(WeaponType.F_TAG);        boolean isHoming = false;        if (te != null) {            if (te.isINarcedBy(ae.getOwner().getTeam()) &&                atype != null &&                (atype.getAmmoType() == AmmoType.T_LRM || atype.getAmmoType() == AmmoType.T_SRM) &&                atype.getMunitionType() == AmmoType.M_NARC_CAPABLE &&                (wtype.getAmmoType() == AmmoType.T_LRM ||                 wtype.getAmmoType() == AmmoType.T_SRM)) {                isINarcGuided = true;            }        }        int toSubtract = 0;        final int ttype = target.getTargetType();                ToHitData toHit = null;        String reason=null;                reason = toHitIsImpossible (game, ae, target, weapon, atype,                                    wtype, ttype, exchangeSwarmTarget,                                    usesAmmo, te, isTAG, isInferno,                                     isAttackerInfantry, isIndirect,                                    attackerId, weaponId, isArtilleryIndirect,                                    ammo, isArtilleryFLAK, targetInBuilding,                                    isArtilleryDirect);        if (reason!=null) {            return new ToHitData(ToHitData.IMPOSSIBLE, reason);        }        long munition = AmmoType.M_STANDARD;        if (atype != null) {            munition = atype.getMunitionType();        }        if (munition == AmmoType.M_HOMING) {            //target type checked later because its different for direct/indirect (BMRr p77 on board arrow IV)            isHoming = true;        }         int targEl;            if (te == null) {            targEl = game.getBoard().getHex(target.getPosition()).floor();        } else {            targEl = te.absHeight();        }            //TODO: mech making DFA could be higher if DFA target hex is higher        //      BMRr pg. 43, "attacking unit is considered to be in the air        //      above the hex, standing on an elevation 1 level higher than        //      the target hex or the elevation of the hex the attacker is        //      in, whichever is higher."            // if we're doing indirect fire, find a spotter        Entity spotter = null;        if (isIndirect) {            spotter = Compute.findSpotter(game, ae, target);        }            // EI system        // 0 if no EI (or switched off)        // 1 if no intervening light woods        // 2 if intervening light woods (because target in woods + intervening woods is only +1 total)        int eistatus=0;        // check LOS (indirect LOS is from the spotter)        LosEffects los;        ToHitData losMods;        if (!isIndirect) {            los = LosEffects.calculateLos(game, attackerId, target);            if(ae.hasActiveEiCockpit()) {                if(los.getLightWoods() > 0)                    eistatus = 2;                else                    eistatus = 1;            }                        losMods = los.losModifiers(game, eistatus);            if ((atype != null)                    && ((atype.getAmmoType() == AmmoType.T_LRM_TORPEDO)                    || (atype.getAmmoType() == AmmoType.T_SRM_TORPEDO))                    && (los.getMinimumWaterDepth() < 1)) {                return new ToHitData(ToHitData.IMPOSSIBLE, "Torpedos must follow water their entire LOS");            }        } else {            los = LosEffects.calculateLos(game, spotter.getId(), target);            // do not count attacker partial cover in indirect fire            los.setAttackerCover(LosEffects.COVER_NONE);            if(spotter.hasActiveEiCockpit()) {                if(los.getLightWoods() > 0)                    eistatus = 2;                else                    eistatus = 1;            }            losMods = los.losModifiers(game);        }        // Leg attacks, Swarm attacks, and        // Mine Launchers don't use gunnery.        if ( Infantry.LEG_ATTACK.equals( wtype.getInternalName() ) ) {            toHit = Compute.getLegAttackBaseToHit( ae, te );                // If the attacker has Assault claws, give a -1 modifier.            // We can stop looking when we find our first match.            for (Mounted mount : ae.getMisc()) {                EquipmentType equip = mount.getType();                if ( BattleArmor.ASSAULT_CLAW.equals                     (equip.getInternalName()) ) {                    toHit.addModifier( -1, "attacker has assault claws" );                    break;                }            }        } else if ( Infantry.SWARM_MEK.equals( wtype.getInternalName() ) ) {            toHit = Compute.getSwarmMekBaseToHit( ae, te );            // If the attacker has Assault claws, give a -1 modifier.            // We can stop looking when we find our first match.            for (Mounted mount : ae.getMisc()) {                EquipmentType equip = mount.getType();                if ( BattleArmor.ASSAULT_CLAW.equals                     (equip.getInternalName()) ) {                    toHit.addModifier( -1, "attacker has assault claws" );                    break;                }            }        } else if ( Infantry.STOP_SWARM.equals( wtype.getInternalName() ) ) {            // Can't stop if we're not swarming, otherwise automatic.            return new ToHitData( ToHitData.AUTOMATIC_SUCCESS,                                      "End swarm attack." );        }        else if ( BattleArmor.MINE_LAUNCHER.equals(wtype.getInternalName()) ) {            // Mine launchers can not hit infantry.            toHit = new ToHitData(8, "magnetic mine attack");        }        // Swarming infantry always hit their target, but

⌨️ 快捷键说明

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