📄 physicalcalculator.java
字号:
} // Conventional infantry in the open suffer double damage. if (to instanceof Infantry && !(to instanceof BattleArmor)) { IHex e_hex = game.getBoard().getHex(to.getPosition()); if (!e_hex.containsTerrain(Terrains.WOODS) && !e_hex.containsTerrain(Terrains.BUILDING)) { bestDmg *= 2.0; } } if (bestDmg > 0) { return new PhysicalOption(from, to, bestDmg, bestType, bestClub); } return null; } /** * Calculates the Falling damage after a successful To-Hit. * @param odds * @param ent The entity that is falling * @return */ private static double calculateFallingDamage(double odds, Entity ent) { double dmg = odds; dmg *= 1.0 - Compute.oddsAbove(ent.getBasePilotingRoll().getValue()) / 100.0; dmg *= ent.getWeight() * 0.1; return dmg; } private static double getExpectedKickDamage(Entity from, Entity to, IGame game, int locTable, int arc, int action) { double self_damage; double dmg; double coll_damage = 0.0; int damage; ToHitData odds = KickAttackAction.toHit(game, from.getId(), to, action); if (odds.getValue() == ToHitData.IMPOSSIBLE) { return 0.0; } // Calculate collateral damage, due to possible target fall if (to instanceof Mech) { coll_damage = calculateFallingDamage(Compute.oddsAbove(odds.getValue()) / 100.0, to); } damage = KickAttackAction.getDamageFor(from, action); dmg = Compute.oddsAbove(odds.getValue()) / 100.0 * damage; // Adjust damage for targets armor dmg *= punchThroughMod(to, locTable, arc, dmg, dmg); // Calculate self damage, due to possible fall from missing a kick self_damage = calculateFallingDamage(1.0 - Compute.oddsAbove(odds.getValue()) / 100.0, from); if (from.getWalkMP() > 0) { self_damage = self_damage * Math.sqrt(1.0 / from.getWalkMP() + from.getJumpMP()); } else { self_damage = self_damage * Math.sqrt(from.getJumpMP()); } // Add together damage values for comparison dmg = dmg + coll_damage - self_damage; return dmg; } /* * This checks to see if the damage will punch through armor anywhere in the * attacked arc. * damage argument is divided into hits, using the group argument (ie, group = 5.0 for LRM). * Each hit of group damage is checked against each location; if it penetrates increase the * multiplier to reflect potential for additional damage * Multiple passes are made with each hit being multiples of group damage to reflect shot * grouping; as each pass is made the increase to the multiplier is lowered due to the lower * chance of hitting the same location */ private static double punchThroughMod(Entity target, int hitTable, int hitSide, double damage, double group) { int[] armor_values = new int[8]; int max_index = 1; armor_values[0] = 0; // Set the final multiplier as 1.0 (no chance of penetrating armor) double final_multiplier = 1.0; // Set the base multiplier as 0.5 (good bonus for penetrating with a single hit) double base_multiplier = 0.5; if (damage <= 0.0 || group <= 0.0) return final_multiplier; // If the target is a Mech if (target instanceof Mech) { // Create vector of body locations with targets current armor values // Use hit table and direction to determine locations that are hit if (hitTable == ToHitData.HIT_NORMAL) { max_index = 7; armor_values[0] = target.getArmor(Mech.LOC_HEAD, false); if (hitSide != ToHitData.SIDE_FRONT) { armor_values[1] = target.getArmor(Mech.LOC_CT, true); } else { armor_values[1] = target.getArmor(Mech.LOC_CT, false); } if (hitSide != ToHitData.SIDE_FRONT) { armor_values[2] = target.getArmor(Mech.LOC_RT, true); } else { armor_values[2] = target.getArmor(Mech.LOC_RT, false); } if (hitSide != ToHitData.SIDE_FRONT) { armor_values[3] = target.getArmor(Mech.LOC_LT, true); } else { armor_values[3] = target.getArmor(Mech.LOC_LT, false); } armor_values[4] = target.getArmor(Mech.LOC_RARM, false); armor_values[5] = target.getArmor(Mech.LOC_LARM, false); armor_values[6] = target.getArmor(Mech.LOC_RLEG, false); armor_values[7] = target.getArmor(Mech.LOC_RLEG, false); } if (hitTable == ToHitData.HIT_PUNCH) { armor_values[0] = target.getArmor(Mech.LOC_HEAD, false); if (hitSide == ToHitData.SIDE_RIGHT) { max_index = 3; armor_values[1] = target.getArmor(Mech.LOC_CT, false); armor_values[2] = target.getArmor(Mech.LOC_RT, false); armor_values[3] = target.getArmor(Mech.LOC_RARM, false); } if (hitSide == ToHitData.SIDE_LEFT) { max_index = 3; armor_values[1] = target.getArmor(Mech.LOC_CT, false); armor_values[2] = target.getArmor(Mech.LOC_LT, false); armor_values[3] = target.getArmor(Mech.LOC_LARM, false); } if (hitSide == ToHitData.SIDE_FRONT) { max_index = 5; armor_values[1] = target.getArmor(Mech.LOC_CT, false); armor_values[2] = target.getArmor(Mech.LOC_RT, false); armor_values[3] = target.getArmor(Mech.LOC_LT, false); armor_values[4] = target.getArmor(Mech.LOC_RARM, false); armor_values[5] = target.getArmor(Mech.LOC_LARM, false); } if (hitSide == ToHitData.SIDE_REAR) { max_index = 5; armor_values[1] = target.getArmor(Mech.LOC_CT, true); armor_values[2] = target.getArmor(Mech.LOC_RT, true); armor_values[3] = target.getArmor(Mech.LOC_LT, true); armor_values[4] = target.getArmor(Mech.LOC_RARM, false); armor_values[5] = target.getArmor(Mech.LOC_LARM, false); } } if (hitTable == ToHitData.HIT_KICK) { max_index = -1; if (hitSide == ToHitData.SIDE_FRONT || hitSide == ToHitData.SIDE_REAR || hitSide == ToHitData.SIDE_RIGHT) { max_index++; armor_values[max_index] = target.getArmor(Mech.LOC_RLEG, false); } if (hitSide == ToHitData.SIDE_FRONT || hitSide == ToHitData.SIDE_REAR || hitSide == ToHitData.SIDE_LEFT) { max_index++; armor_values[max_index] = target.getArmor(Mech.LOC_LLEG, false); } } } // If the target is a ProtoMech if (target instanceof Protomech) { max_index = 6; // Create vector of body locations with targets current armor values // Create two high-armor dummy locations to represent the 'near miss' hit locations armor_values[0] = target.getArmor(Protomech.LOC_TORSO, false); armor_values[1] = target.getArmor(Protomech.LOC_LEG, false); armor_values[2] = target.getArmor(Protomech.LOC_RARM, false); armor_values[3] = target.getArmor(Protomech.LOC_LARM, false); armor_values[4] = target.getArmor(Protomech.LOC_HEAD, false); armor_values[5] = 100; armor_values[6] = 100; if (((Protomech) target).hasMainGun()) { max_index++; armor_values[max_index] = target.getArmor(Protomech.LOC_MAINGUN, false); } } // If the target is a vehicle if (target instanceof Tank) { // Create vector of armor locations max_index = 0; switch (hitSide) { case ToHitData.SIDE_FRONT: armor_values[0] = target.getArmor(Tank.LOC_FRONT); break; case ToHitData.SIDE_RIGHT: armor_values[0] = target.getArmor(Tank.LOC_RIGHT); break; case ToHitData.SIDE_LEFT: armor_values[0] = target.getArmor(Tank.LOC_LEFT); break; case ToHitData.SIDE_REAR: armor_values[0] = target.getArmor(Tank.LOC_REAR); break; } if (!((Tank) target).hasNoTurret()) { max_index++; armor_values[max_index] = target.getArmor(Tank.LOC_TURRET); } } // If the target is Battle Armor if (target instanceof BattleArmor) { // Create vector of armor of surviving troopers max_index = -1; for (int i = 1; i < ((BattleArmor) target).getShootingStrength(); i++) { if (target.getArmor(i) >= 0) { max_index++; armor_values[max_index] = target.getArmor(i); } } } // If the target is conventional infantry if (target instanceof Infantry && !(target instanceof BattleArmor)) { // Create a single element vector with total number of troopers max_index = 0; armor_values[0] = ((Infantry) target).getShootingStrength(); } double hit_total = 0; // While hit damage is less than total damage applied, increment by group value while (hit_total <= damage) { hit_total += group; for (int i = 0; i <= max_index; i++) { // If hit damage can penetrate location if (hit_total > armor_values[i]) { final_multiplier += base_multiplier; } } base_multiplier /= 2.0; } // Return final multiplier return final_multiplier; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -