/** * Copyright (C) 2002-2012 The FreeCol Team * * This file is part of FreeCol. * * FreeCol 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. * * FreeCol 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. * * You should have received a copy of the GNU General Public License * along with FreeCol. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.freecol.common.model; import java.util.List; import java.util.Random; import java.util.Set; abstract public class CombatModel { public static enum CombatResult { // Special results that set the sense of the result. NO_RESULT, LOSE, WIN, // Specific actions AUTOEQUIP_UNIT, // Defending unit auto-arms BURN_MISSIONS, // Defending natives burn attackers missions CAPTURE_AUTOEQUIP, // Winner captures loser auto-equipment CAPTURE_COLONY, // Winning Europeans capture a colony CAPTURE_CONVERT, // Winning Europeans cause native to convert CAPTURE_EQUIP, // Winner captures loser equipment CAPTURE_UNIT, // Losing unit is captured DAMAGE_COLONY_SHIPS, // Ships in losing colony are damaged DAMAGE_SHIP_ATTACK, // Losing ship is damaged by normal attack DAMAGE_SHIP_BOMBARD, // Losing ship is damaged by bombardment DEMOTE_UNIT, // Losing unit is demoted DESTROY_COLONY, // Winning natives burn a colony DESTROY_SETTLEMENT, // Winner destroys a native settlement EVADE_ATTACK, // Defending ship evades normal attack EVADE_BOMBARD, // Defending ship evades bombardment LOOT_SHIP, // Losing ship is looted LOSE_AUTOEQUIP, // Losing unit auto-arms and loses the arms LOSE_EQUIP, // Losing unit loses some equipment PILLAGE_COLONY, // Winning natives pillage an undefended colony PROMOTE_UNIT, // Winning unit is promoted SINK_COLONY_SHIPS, // Ships in losing colony are sunk SINK_SHIP_ATTACK, // Losing ship is sunk by normal attack SINK_SHIP_BOMBARD, // Losing ship is sunk by bombardment SLAUGHTER_UNIT, // Losing unit is slaughtered } /** * Odds a particular outcome will occur in combat. */ public class CombatOdds { public static final float UNKNOWN_ODDS = -1.0f; public float win; public CombatOdds(float win) { this.win = win; } } /** * Empty constructor is sufficient. */ public CombatModel() {} /** * Is this just a measurement of offence power? * * @param attacker The attacker. * @param defender The defender. * @return True if no defender is provided. */ public boolean combatIsAttackMeasurement(FreeColGameObject attacker, FreeColGameObject defender) { return attacker instanceof Unit && defender == null; } /** * Is this just a measurement of defence power? * * @param attacker The attacker. * @param defender The defender. * @return True if no attacker is provided. */ public boolean combatIsDefenceMeasurement(FreeColGameObject attacker, FreeColGameObject defender) { return attacker == null && defender instanceof Unit; } /** * Is this combat a normal attack? * * @param attacker The attacker. * @param defender The defender. * @return True if the combat is a normal attack. */ public boolean combatIsAttack(FreeColGameObject attacker, FreeColGameObject defender) { return attacker instanceof Unit && defender instanceof Unit; } /** * Is this combat a attack on a settlement? These happen on the client * side only, for the purposes of the pre-combat display. In these cases * the actual defender unit is hidden from the attacker player, so * the defender is shown as the settlement itself. * * @param attacker The attacker. * @param defender The defender. * @return True if the combat is a client-side attack on a settlement. */ public boolean combatIsSettlementAttack(FreeColGameObject attacker, FreeColGameObject defender) { return attacker instanceof Unit && defender instanceof Settlement; } /** * Is this combat a bombardment? * * @param attacker The attacker. * @param defender The defender. * @return True if the combat is a bombardment. */ public boolean combatIsBombard(FreeColGameObject attacker, FreeColGameObject defender) { return attacker instanceof Settlement && defender instanceof Unit && ((Unit) defender).isNaval(); } /** * Could this attack be an amphibious operation? * * @param attacker The attacker. * @param defender The defender. * @return True if the attack is amphibious. */ public boolean combatIsAmphibious(FreeColGameObject attacker, FreeColGameObject defender) { return attacker instanceof Unit && ((Unit) attacker).getTile() != null && !((Unit) attacker).getTile().isLand() && defender instanceof Locatable && ((Locatable) defender).getTile() != null && ((Locatable) defender).getTile().isLand(); } /** * Calculates the chance of the outcomes of a combat. * * @param attacker The attacker. * @param defender The defender. * @return The <code>CombatOdds</code>. */ abstract public CombatOdds calculateCombatOdds(FreeColGameObject attacker, FreeColGameObject defender); /** * Get the offensive power of a attacker wrt a defender. * * Null can be passed for the defender when only the attacker * stats are required. * * @param attacker The attacker. * @param defender The defender. * @return The offensive power. */ abstract public float getOffencePower(FreeColGameObject attacker, FreeColGameObject defender); /** * Get the defensive power of a defender wrt an attacker. * * @param attacker The attacker. * @param defender The defender. * @return The defensive power. */ abstract public float getDefencePower(FreeColGameObject attacker, FreeColGameObject defender); /** * Collect all the offensive modifiers that apply to an attack. * * Null can be passed as the defender when only the attacker unit * stats are required. * * @param attacker The attacker. * @param defender The defender. * @return All the applicable offensive modifiers. */ abstract public Set<Modifier> getOffensiveModifiers(FreeColGameObject attacker, FreeColGameObject defender); /** * Collect all defensive modifiers that apply to a unit defending * against another. * * @param attacker The attacker. * @param defender The defender. * @return All the applicable defensive modifiers. */ abstract public Set<Modifier> getDefensiveModifiers(FreeColGameObject attacker, FreeColGameObject defender); /** * Generates a list of results of an attack. The first must be one * of NO_RESULT, LOSE or WIN. The rest can be any other CombatResult * suitable to the situation. * To be called by the server only. * * @param random A pseudo-random number source. * @param attacker The attacker. * @param defender The defender. * @return The results of the combat. */ abstract public List<CombatResult> generateAttackResult(Random random, FreeColGameObject attacker, FreeColGameObject defender); }