📄 physicalcalculator.java
字号:
l_dmg + r_dmg, (l_dmg + r_dmg) / 2.0); if (breach < Math.min(breach_a, 1.5)) { best_brush = PhysicalOption.BRUSH_BOTH; final_dmg = BrushOffAttackAction.getDamageFor(entity, BrushOffAttackAction.LEFT); final_dmg += BrushOffAttackAction.getDamageFor(entity, BrushOffAttackAction.RIGHT); } } // Construct and return Physical option if (best_brush != PhysicalOption.NONE) { return new PhysicalOption(entity, best_pod, final_dmg, best_brush, null); } } } } for (Enumeration e = game.getEntities(); e.hasMoreElements();) { Entity target = (Entity) e.nextElement(); if (target.equals(entity)) continue; if (!target.isEnemyOf(entity)) continue; if (target.getPosition() == null) continue; if (Compute.effectiveDistance(game, entity, target) > 1) continue; PhysicalOption one = getBestPhysicalAttack(entity, target, game); if (one != null) { if (best == null || one.expectedDmg > best.expectedDmg) { best = one; } } } if (best == null) best = new PhysicalOption(entity); return best; } static PhysicalOption getBestPhysicalAttack(Entity from, Entity to, IGame game) { double bestDmg = 0.0; double dmg; int damage; int target_arc; int location_table; int bestType = PhysicalOption.NONE; Mounted bestClub = null; // Infantry and tanks can't conduct any of these attacks if (from instanceof Infantry || from instanceof Tank) { return null; } // Find arc the attack comes in target_arc = CEntity.getThreatHitArc(to.getPosition(), to.getFacing(), from.getPosition()); // Check for punches // If the target is a Mech, must determine if punch lands on the punch, kick, or full table if (to instanceof Mech) { if (!to.isProne()) { location_table = ToHitData.HIT_PUNCH; if (to.getElevation() == from.getElevation() + 1) { location_table = ToHitData.HIT_KICK; } } else { location_table = ToHitData.HIT_NORMAL; } } else { location_table = ToHitData.HIT_NORMAL; } ToHitData odds = PunchAttackAction.toHit(game, from.getId(), to, PunchAttackAction.LEFT); if (odds.getValue() != ToHitData.IMPOSSIBLE) { damage = PunchAttackAction.getDamageFor(from, PunchAttackAction.LEFT); bestDmg = Compute.oddsAbove(odds.getValue()) / 100.0 * damage; // Adjust damage for targets armor bestType = PhysicalOption.PUNCH_LEFT; bestDmg *= punchThroughMod(to, location_table, target_arc, bestDmg, bestDmg); } odds = PunchAttackAction.toHit(game, from.getId(), to, PunchAttackAction.RIGHT); if (odds.getValue() != ToHitData.IMPOSSIBLE) { damage = PunchAttackAction.getDamageFor(from, PunchAttackAction.RIGHT); dmg = Compute.oddsAbove(odds.getValue()) / 100.0 * damage; // Adjust damage for targets armor dmg *= punchThroughMod(to, location_table, target_arc, dmg, dmg); if (dmg > bestDmg) { bestType = PhysicalOption.PUNCH_RIGHT; bestDmg = dmg; } } // Check for a double punch odds = PunchAttackAction.toHit(game, from.getId(), to, PunchAttackAction.LEFT); ToHitData odds_a = PunchAttackAction.toHit(game, from.getId(), to, PunchAttackAction.RIGHT); if (odds.getValue() != ToHitData.IMPOSSIBLE && odds_a.getValue() != ToHitData.IMPOSSIBLE) { damage = PunchAttackAction.getDamageFor(from, PunchAttackAction.LEFT); dmg = Compute.oddsAbove(odds.getValue()) / 100.0 * damage; double dmg_a = Compute.oddsAbove(odds_a.getValue()) / 100.0 * damage; dmg += dmg_a; dmg *= punchThroughMod(to, location_table, target_arc, dmg, dmg / 2.0); if (dmg > bestDmg) { bestType = PhysicalOption.PUNCH_BOTH; bestDmg = dmg; } } // Check for a kick // If the target is a Mech, must determine if it lands on the kick or punch table if (to instanceof Mech) { location_table = ToHitData.HIT_KICK; if (!to.isProne()) { if (to.getElevation() == from.getElevation() - 1) { location_table = ToHitData.HIT_PUNCH; } } else { location_table = ToHitData.HIT_NORMAL; } } else { location_table = ToHitData.HIT_NORMAL; } dmg = getExpectedKickDamage(from, to, game, location_table, target_arc, KickAttackAction.LEFT); if (dmg > bestDmg) { bestType = PhysicalOption.KICK_LEFT; bestDmg = dmg; } dmg = getExpectedKickDamage(from, to, game, location_table, target_arc, KickAttackAction.RIGHT); if (dmg > bestDmg) { bestType = PhysicalOption.KICK_RIGHT; bestDmg = dmg; } // Check for mounted club-type weapon or carried improvised club for (Mounted club : from.getClubs()) { // If the target is a Mech, must determine if it hits full body, punch, or kick table if (to instanceof Mech) { location_table = ToHitData.HIT_NORMAL; if (to.getElevation() == from.getElevation() - 1 && !to.isProne()) { location_table = ToHitData.HIT_PUNCH; } if (to.getElevation() == from.getElevation() + 1 && !to.isProne()) { location_table = ToHitData.HIT_KICK; } } else { location_table = ToHitData.HIT_NORMAL; } odds = ClubAttackAction.toHit(game, from.getId(), to, club); if (odds.getValue() != ToHitData.IMPOSSIBLE) { damage = ClubAttackAction.getDamageFor(from, club); dmg = Compute.oddsAbove(odds.getValue()) / 100.0 * damage; // Adjust damage for targets armor dmg *= punchThroughMod(to, location_table, target_arc, dmg, dmg); // Some types of clubs, such as the mace, require a piloting check on a missed attack // Calculate self damage in the same manner as a missed kick if (dmg > bestDmg) { bestType = PhysicalOption.USE_CLUB; bestDmg = dmg; bestClub = club; } } } // Check for a push attack odds = PushAttackAction.toHit(game, from.getId(), to); if (odds.getValue() != ToHitData.IMPOSSIBLE) { int elev_diff; double breach; boolean water_landing = false; dmg = 0.0; int disp_dir = from.getPosition().direction(to.getPosition()); Coords disp_c = to.getPosition().translated(disp_dir); // If the displacement hex is a valid one if (Compute.isValidDisplacement(game, to.getId(), to.getPosition(), disp_c)) { // If the displacement hex is not on the map, credit damage // against full target armor if (!game.getBoard().contains(disp_c)) { dmg = to.getTotalArmor() * Compute.oddsAbove(odds.getValue()) / 100.0; } if (game.getBoard().contains(disp_c)) { // Find the elevation difference elev_diff = game.getBoard().getHex(to.getPosition()).getElevation(); elev_diff -= game.getBoard().getHex(disp_c).getElevation(); if (elev_diff < 0) { elev_diff = 0; } // Set a flag if the displacement hex has water if (game.getBoard().getHex(disp_c).containsTerrain(Terrains.WATER)) { water_landing = true; } // Get the base damage from target falling, multiplied by the elevation difference dmg = calculateFallingDamage(Compute.oddsAbove(odds.getValue()) / 100.0, to) * (1.0 + elev_diff); // Calculate breach factor of falling damage breach = punchThroughMod(to, ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT, dmg, Math.min(dmg, 5.0)); // If breach factor is > 1 and displacement hex has water if (breach > 1 && water_landing) { breach *= 2.0; } // Modify damage to reflect how bad it is for target to be prone if (to.getWalkMP() > 0) { dmg = dmg * Math.sqrt(1.0 / to.getWalkMP() + to.getJumpMP()); } else { dmg *= Math.max(1.0, Math.sqrt(to.getJumpMP())); } // Modify damage by breach factor dmg *= breach; } } // If the displacement hex is not valid if (!Compute.isValidDisplacement(game, to.getId(), to.getPosition(), disp_c)) { // Set a flag if the displacement hex has water if (game.getBoard().getHex(to.getPosition()).containsTerrain(Terrains.WATER)) { water_landing = true; } // Get falling in place dmg = calculateFallingDamage(Compute.oddsAbove(odds.getValue()) / 100.0, to); // Calculate breach factor of falling damage breach = punchThroughMod(to, ToHitData.HIT_NORMAL, ToHitData.SIDE_FRONT, dmg, Math.min(dmg, 5.0)); // If breach factor is > 1 and target hex is in water if (breach > 1 && water_landing) { breach *= 2.0; } // Modify damage to reflect how bad it is for target to be prone if (to.getWalkMP() > 0) { dmg = dmg * Math.sqrt(1.0 / to.getWalkMP() + to.getJumpMP()); } else { dmg = dmg * Math.max(1.0, Math.sqrt(to.getJumpMP())); } // Modify damage by breach factor dmg *= breach; } // If damage is better than best damage if (dmg > bestDmg) { bestType = PhysicalOption.PUSH_ATTACK; bestDmg = dmg; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -