User Tools

Site Tools


combatmath

Combat Math

Below is a code excerpt for combat loss calculations (ALPHA-release). The getCombatLoss(…) function is called twice once for us and once for the opponent to calculate loss for each piece. Notes on variables used:

  • piece(): that's us.
  • opponent: the opponent piece we are combating.
  • distance: the distance between attacker and defender (e.g. 1 for swordsman or 2 for archer).
  • CompPos: contains the position information for a piece on the map (i.e. which tile it is on).
  • CompArm: contains the armament for a piece (parts of it are listed below).
  • Spec: contains the specifications for a piece that are the same for pieces of the same type.
  • Combat: The combat type/modality, e.g. “melee” (swordsman), “mounted” (horseman, war elephant) or “ranged” (spearman).
  • CombatBonus: the combat bonus [1, infinite) against a certain combat modality for a piece where 100 is the default. For example a spearman could have a combat bonus 125 against mounted/horsemen (rather strong) and 50 against melee/swordsmen (rather weak).

// we call this twice once for us & once for the opponent to calculate loss for each
public int getCombatLoss(Piece opponent, ArenaTile tile, int distance) {
  // the strength loss when fighting the opponent (1x)
  if (opponent.getCompArm().canAttack(piece(), distance)) {
    // find our bonus against their troop type & their bonus agains our troop type!
    boolean countHosted = piece().getCompPos().getLocation().distance(tile.getLocation()) <= getSpec().getRangeAttack();
    int bonus = getCombatBoni(tile, opponent.getCompArm().getSpec().getCombat(), countHosted);
    int bonusOpponent = opponent.getCompArm().getCombatBoni(tile, getSpec().getCombat(), false);
    int total = bonus + bonusOpponent;
 
    // calculate percentage loss, e.g. 70-30, 50-50, 10-80! (totaling to 100)
    int loss;
    if (total > 0) {
      loss = (100 * bonusOpponent) / total;
    }
    else {
      // both have 0, so let's divide 50-50!
      loss = 50;
    }
 
    // apply offense and defense!
    if (hasDefense()) {
      // apply our defense effect: reduced loss!
      int effect = getDefenseEffect();
      loss = loss * (100 - effect) / 100;
    }
    if (opponent.getCompArm().hasOffense()) {
      // apply the opponent's offense effect: increased loss!
      int effect = opponent.getCompArm().getOffenseEffect();
      loss = loss * (100 + effect) / 100;
    }
 
    // and return total strength loss!
    return loss;
  }
  else {
    // we have 0 loss as the opponent cannot fight back
    return 0;
  }
}
 
// the combat bonus for the given combat modality/specs
private int getCombatBoni(ArenaTile tile, Combat combat, boolean countHosted) {
  Piece piece = piece();
 
  // base bonus against combat modality
  int bonus = 100 + getSpec().getCombatBonus(combat);
 
  // apply strength
  int strength = (100 * getStrength()) / getStrengthMax();
  if (piece.hasCompBin()) {
    for (int i = 0; i < piece.getCompBin().getHostedCount(); i++) {
      Piece hosted = piece.getCompBin().getHosted(i);
      if (hosted.hasCompArm()) {
        strength += (piece.getCompBin().getSpec().getDefenseMod() * hosted.getCompArm().getStrength()) / hosted.getCompArm().getStrengthMax();
      }
    }
  }
  bonus = (bonus * strength) / 100;  
 
  // apply modifier for being hosted
  if ((countHosted) && (piece.getCompPos().hasPositionHost())) {
    Piece host = piece.getCompPos().getPositionHost();
    bonus = (bonus * host.getCompBin().getSpec().getOffenseMod()) / 100;
  }
 
  // apply experience
  if (piece.hasCompMov()) {
    bonus = (bonus * piece.getCompMov().getExperience()) / 100;
  }
 
  // apply attrition
  if (piece.hasCompMov()) {
    bonus = (bonus * (100 - piece.getCompMov().getAttrition())) / 100;
  }
 
  // apply happiness
  if (piece.hasCompCiv()) {
    bonus = (bonus * piece.getCompCiv().getHappiness()) / 100;
  }
 
  // apply weather effect (additive)
  if (tile.getWeather().hasPrecipitation()) {
    bonus += (bonus * getSpec().getWeatherEffect()) / 100;
  }
 
  // apply terrain effect (additive)
  Nature nature = tile.getNature();
  if (nature != null) {
    switch (nature) {
      case FLORA_PINES: 
      case FLORA_PALMS: {  
        // half the terrain effect!
        bonus += (bonus * getSpec().getTerrainEffect() / 2) / 100;
        break;
      }
      case FLORA_PINESDENSE: 
      case FLORA_PALMSDENSE: {  
        // full terrain effect!
        bonus += (bonus * getSpec().getTerrainEffect()) / 100;
        break;
      }
      default: 
        // we ignore other nature types, a.k.a. no effect!
    }
  }
 
  // and return the bonus...
  return bonus;
}

combatmath.txt · Last modified: 2014-02-19 09:56 (external edit)