📄 compute.java
字号:
} } // arm-mounted weapons have addidional trouble if (weapon.getLocation() == Mech.LOC_RARM || weapon.getLocation() == Mech.LOC_LARM) { if (l3ProneFiringArm == weapon.getLocation()) { return new ToHitData(ToHitData.IMPOSSIBLE, "Prone and propping up with this arm."); } int otherArm = weapon.getLocation() == Mech.LOC_RARM ? Mech.LOC_LARM : Mech.LOC_RARM; // check previous attacks for weapons fire from the other arm if (isFiringFromArmAlready(game, weaponId, attacker, otherArm)) { return new ToHitData(ToHitData.IMPOSSIBLE, "Prone and firing from other arm already."); } } // can't fire leg weapons if (weapon.getLocation() == Mech.LOC_LLEG || weapon.getLocation() == Mech.LOC_RLEG) { return new ToHitData(ToHitData.IMPOSSIBLE, "Can't fire leg-mounted weapons while prone."); } mods.addModifier(2, "attacker prone"); if (l3ProneFiringArm != Entity.LOC_NONE) { mods.addModifier(1, "attacker propping on single arm"); } } return mods; } /** * Checks to see if there is an attack previous to the one with this weapon * from the specified arm. * * @return true if there is a previous attack from this arm */ private static boolean isFiringFromArmAlready(IGame game, int weaponId, final Entity attacker, int armLoc) { int torsoLoc = Mech.getInnerLocation(armLoc); for (Enumeration i = game.getActions(); i.hasMoreElements();) { Object o = i.nextElement(); if (!(o instanceof WeaponAttackAction)) { continue; } WeaponAttackAction prevAttack = (WeaponAttackAction) o; // stop when we get to this weaponattack (does this always work?) if (prevAttack.getEntityId() == attacker.getId() && prevAttack.getWeaponId() == weaponId) { break; } if ( (prevAttack.getEntityId() == attacker.getId() && attacker.getEquipment(prevAttack.getWeaponId()) .getLocation() == armLoc) || (prevAttack.getEntityId() == attacker.getId() && attacker.getEquipment(prevAttack.getWeaponId()) .getLocation() == torsoLoc && attacker.getEquipment(prevAttack.getWeaponId()).isSplit())) { return true; } } return false; } /** * Adds any damage modifiers from arm critical hits or sensor damage. * * @return Any applicable damage modifiers */ public static ToHitData getDamageWeaponMods(Entity attacker, Mounted weapon) { ToHitData mods = new ToHitData(); if (attacker instanceof Protomech) { // Head criticals add to target number of all weapons. int hits = ((Protomech) attacker).getCritsHit(Protomech.LOC_HEAD); if (hits > 0) { mods.addModifier(hits, hits + " head critical(s)"); } // Arm mounted (and main gun) weapons get DRMs from arm crits. switch (weapon.getLocation()) { case Protomech.LOC_LARM: case Protomech.LOC_RARM: hits = ((Protomech) attacker).getCritsHit(weapon .getLocation()); if (hits > 0) { mods.addModifier(hits, hits + " arm critical(s)"); } break; case Protomech.LOC_MAINGUN: // Main gun is affected by crits in *both* arms. hits = ((Protomech) attacker) .getCritsHit(Protomech.LOC_LARM); hits += ((Protomech) attacker) .getCritsHit(Protomech.LOC_RARM); if (4 == hits) { mods.addModifier(ToHitData.IMPOSSIBLE, "Cannot fire main gun with no arms."); } else if (hits > 0) { mods.addModifier(hits, hits + " arm critical(s)"); } break; } } // End attacker-is-Protomech // Is the shoulder destroyed? else { // split weapons need to account for arm actuator hits, too // see bug 1363690 // we don't need to specifically check for weapons split between // torso and leg, because for those, the location stored in the // Mounted is the leg. int location = weapon.getLocation(); if (weapon.isSplit()) { switch (location) { case Mech.LOC_LT: location = Mech.LOC_LARM; break; case Mech.LOC_RT: location = Mech.LOC_RARM; break; default: } } if (attacker.getBadCriticals(CriticalSlot.TYPE_SYSTEM, Mech.ACTUATOR_SHOULDER, location) > 0) { mods.addModifier(4, "shoulder actuator destroyed"); } else { // no shoulder hits, add other arm hits int actuatorHits = 0; if (attacker.getBadCriticals(CriticalSlot.TYPE_SYSTEM, Mech.ACTUATOR_UPPER_ARM, location) > 0) { actuatorHits++; } if (attacker.getBadCriticals(CriticalSlot.TYPE_SYSTEM, Mech.ACTUATOR_LOWER_ARM, location) > 0) { actuatorHits++; } if (actuatorHits > 0) { mods.addModifier(actuatorHits, actuatorHits + " destroyed arm actuators"); } } } // sensors critical hit to attacker int sensorHits = attacker.getBadCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_SENSORS, Mech.LOC_HEAD); if ((attacker instanceof Mech) && ((Mech)attacker).getCockpitType() == Mech.COCKPIT_TORSO_MOUNTED) { sensorHits += attacker.getBadCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_SENSORS, Mech.LOC_CT); if (sensorHits > 1) { mods.addModifier(4, "attacker sensors badly damaged"); } else if (sensorHits > 0) { mods.addModifier(2, "attacker sensors damaged"); } } else if (sensorHits > 0) { mods.addModifier(2, "attacker sensors damaged"); } return mods; } /** * Determines if the current target is a secondary target, and if so, * returns the appropriate modifier. * * @return The secondary target modifier. * @author Ben */ public static ToHitData getSecondaryTargetMod(IGame game, Entity attacker, Targetable target) { return getSecondaryTargetMod(game, attacker, target, false); } public static ToHitData getSecondaryTargetMod(IGame game, Entity attacker, Targetable target, boolean isSwarm) { boolean curInFrontArc = isInArc(attacker.getPosition(), attacker .getSecondaryFacing(), target.getPosition(), ARC_FORWARD); int primaryTarget = Entity.NONE; for (Enumeration i = game.getActions(); i.hasMoreElements();) { Object o = i.nextElement(); if (!(o instanceof WeaponAttackAction)) { continue; } WeaponAttackAction prevAttack = (WeaponAttackAction) o; if (prevAttack.getEntityId() == attacker.getId()) { // first front arc target is our primary. // if first target is non-front, and either a later target or // the current one is in front, use that instead. Targetable pte = game.getTarget(prevAttack.getTargetType(), prevAttack.getTargetId()); // in double blind play, we might not have the target in our // local copy of the game. In that case, the sprite won't // have the correct to-hit number, but at least we don't crash if (pte == null) { continue; } // When targeting a stealthed Mech, you can _only_ target it, // not anything else (BMRr, pg. 147) if (pte instanceof Mech && ((Entity) pte).isStealthActive() && pte != target && !isSwarm) { return new ToHitData(ToHitData.IMPOSSIBLE, "When targeting a stealthed Mech, can not attack secondary targets"); } if (isInArc(attacker.getPosition(), attacker .getSecondaryFacing(), pte.getPosition(), ARC_FORWARD)) { primaryTarget = prevAttack.getTargetId(); break; } else if (primaryTarget == Entity.NONE && !curInFrontArc) { primaryTarget = prevAttack.getTargetId(); } } } if (primaryTarget == Entity.NONE || primaryTarget == target.getTargetId()) { // current target is primary target return null; // no modifier } // current target is secondary // Infantry can't attack secondary targets (BMRr, pg. 32). if (attacker instanceof Infantry) { return new ToHitData(ToHitData.IMPOSSIBLE, "Can't have multiple targets."); } // Stealthed Mechs can't be secondary targets (BMRr, pg. 147) if ((target instanceof Mech) && ((Entity) target).isStealthActive()) { return new ToHitData(ToHitData.IMPOSSIBLE, "Can't target Mech with active stealth armor as secondary target"); } if (curInFrontArc) { return new ToHitData(1, "secondary target modifier"); } return new ToHitData(2, "secondary target modifier"); } /** * Damage that a mech does with a accidental fall from above. */ public static int getAffaDamageFor(Entity entity) { return (int) entity.getWeight() / 10; } /** * Modifier to attacks due to attacker movement */ public static ToHitData getAttackerMovementModifier(IGame game, int entityId) { return getAttackerMovementModifier(game, entityId, game .getEntity(entityId).moved); } /** * Modifier to attacks due to attacker movement */ public static ToHitData getAttackerMovementModifier(IGame game, int entityId, int movement) { final Entity entity = game.getEntity(entityId); ToHitData toHit = new ToHitData(); // infantry aren't affected by their own movement, // unless it's flying Infantry (like the sylph) if (entity instanceof Infantry) { if (movement == IEntityMovementType.MOVE_VTOL_WALK || movement == IEntityMovementType.MOVE_VTOL_RUN) { toHit.addModifier(3, "attacker flew"); } return toHit; } if ( entity.getMovementMode() == IEntityMovementMode.BIPED_SWIM || entity.getMovementMode() == IEntityMovementMode.QUAD_SWIM ) return toHit; if (movement == IEntityMovementType.MOVE_WALK || movement == IEntityMovementType.MOVE_VTOL_WALK) { toHit.addModifier(1, "attacker walked"); } else if (movement == IEntityMovementType.MOVE_RUN || movement == IEntityMovementType.MOVE_VTOL_RUN || movement == IEntityMovementType.MOVE_SKID) { toHit.addModifier(2, "attacker ran"); } else if (movement == IEntityMovementType.MOVE_JUMP) { toHit.addModifier(3, "attacker jumped"); } return toHit; } /** * Modifier to attacks due to spotter movement */ public static ToHitData getSpotterMovementModifier(IGame game, int entityId) { return getSpotterMovementModifier(game, entityId, game .getEntity(entityId).moved); } /** * Modifier to attacks due to spotter movement */ public static ToHitData getSpotterMovementModifier(IGame game, int entityId, int movement) { ToHitData toHit = new ToHitData(); if (movement == IEntityMovementType.MOVE_WALK || movement == IEntityMovementType.MOVE_VTOL_WALK) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -