package onlinefrontlines.game; import java.util.*; import java.sql.SQLException; /** * Settings for a unit type * * @author jorrit * * Copyright (C) 2009-2013 Jorrit Rouwe * * This file is part of Online Frontlines. * * Online Frontlines 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 3 of the License, or * (at your option) any later version. * * Online Frontlines 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 Online Frontlines. If not, see <http://www.gnu.org/licenses/>. */ public final class UnitConfig { /** * Id for the unit type */ public int id = -1; /** * Name of the unit type */ public String name; /** * Class of the unit */ public UnitClass unitClass = UnitClass.none; /** * Image number for the unit */ public int imageNumber = -1; /** * Maximum amount of armour when unit is spawned */ public int maxArmour = 0; /** * Maps unit class to attack strength */ public final HashMap<UnitClass, UnitStrengthProperties> strengthProperties = new HashMap<UnitClass,UnitStrengthProperties>(); /** * Maximum amount of ammo when unit is spawned / recharged */ public int maxAmmo = 0; /** * Amount of tiles the unit can look */ public int visionRange = 0; /** * Amount of movement points that the unit has at the start of every turn */ public int movementPoints = 0; /** * Amount of actions unit can perform (move = 1 action, attack = 1 action) */ public int actions = 0; /** * Maps TerrainConfig.id to movement cost for this terrain type */ public final HashMap<Integer, UnitMovementCostProperties> movementCostProperties = new HashMap<Integer, UnitMovementCostProperties>(); /** * Gives TerrainConfig.id's for terrains that this unit can be set up on */ public final ArrayList<Integer> unitSetupOn = new ArrayList<Integer>(); /** * Gives TerrainConfig.id's for terrains that this unit must be next to (only if non empty) */ public final ArrayList<Integer> unitSetupNextTo = new ArrayList<Integer>(); /** * Number of units this unit can contain */ public int containerMaxUnits = 0; /** * List of units this unit can contain */ public ArrayList<Integer> containerUnitIds = new ArrayList<Integer>(); /** * Percentage of armour that is restored every turn for units contained in this unit (0-100) */ public int containerArmourPercentagePerTurn = 0; /** * Percentage of ammo that is restored every turn for units contained in this unit (0-100) */ public int containerAmmoPercentagePerTurn = 0; /** * If this unit can be transformed, this is the id of the unit it can transform to */ public int transformableToUnitId = 0; /** * If this unit transforms in a container */ public TransformableType transformableType = TransformableType.none; /** * Number of victory points associated with this unit */ public int victoryPoints; /** * Description for the unit */ public String description; /** * If this unit is a base or not */ public boolean isBase; /** * Victory category (if all units from one category are destroyed the opponent wins, possible values 0-31) */ public int victoryCategory; /** * If unit is equal or closer to this range it will be detected by the enemy (show up as a ?) */ public int beDetectedRange; /** * Static access to all units */ static public ArrayList<UnitConfig> allUnits = new ArrayList<UnitConfig>(); /** * Maps UnitConfig.id to UnitConfig */ static public HashMap<Integer, UnitConfig> allUnitsMap = new HashMap<Integer, UnitConfig>(); /** * Reference to the unknown UnitConfig */ static public UnitConfig unknownUnit; /** * Load all units from the database * * @throws SQLException */ static public void loadAll() throws SQLException { allUnitsMap.clear(); allUnits = UnitConfigDAO.loadAllUnits(); unknownUnit = null; for (UnitConfig u : allUnits) { if (u.name.equalsIgnoreCase("unknown")) unknownUnit = u; allUnitsMap.put(u.id, u); } } /** * Remove all loaded units */ static public void unloadAll() { allUnitsMap.clear(); allUnits.clear(); unknownUnit = null; } /** * Unit id */ public int getId() { return id; } /** * Unit name */ public String getName() { return name; } /** * Max unit armour */ public int getMaxArmour() { return maxArmour; } /** * Max unit ammo */ public int getMaxAmmo() { return maxAmmo; } /** * Vision range */ public int getVisionRange() { return visionRange; } /** * Movement points */ public int getMovementPoints() { return movementPoints; } /** * Actions */ public int getActions() { return actions; } /** * Max contained units */ public int getContainerMaxUnits() { return containerMaxUnits; } /** * Get container unit ids as string */ public String getContainerUnitIdsStringValue() { if (containerUnitIds.size() == 0) return ""; StringBuilder rv = new StringBuilder(); rv.append(containerUnitIds.get(0)); for (int i = 1; i < containerUnitIds.size(); ++i) { rv.append(','); rv.append(containerUnitIds.get(i)); } return rv.toString(); } /** * Amount of armour contained units gain per turn */ public int getContainerArmourPercentagePerTurn() { return containerArmourPercentagePerTurn; } /** * Amount of ammo contained units gain per turn */ public int getContainerAmmoPercentagePerTurn() { return containerAmmoPercentagePerTurn; } /** * Victory points */ public int getVictoryPoints() { return victoryPoints; } /** * Description for the unit */ public String getDescription() { return description; } /** * If this unit is a base or not */ public boolean getIsBase() { return isBase; } /** * Victory category */ public int getVictoryCategory() { return victoryCategory; } /** * Range where unit is detected */ public int getBeDetectedRange() { return beDetectedRange; } /* * Image number for the unit */ public int getImageNumber() { return imageNumber; } /** * Convert unit class to integer and return it */ public int getUnitClassIntValue() { return UnitClass.toInt(unitClass); } /** * Convert unit class to string and return it */ public String getUnitClassStringValue() { return unitClass.toString(); } /** * Get all strength properties */ public Collection<UnitStrengthProperties> getAllStrengthProperties() { return strengthProperties.values(); } /** * Get strength vs land */ public UnitStrengthProperties getStrengthVsLand() { return strengthProperties.get(UnitClass.land); } /** * Get strength vs air */ public UnitStrengthProperties getStrengthVsAir() { return strengthProperties.get(UnitClass.air); } /** * Get strength vs water */ public UnitStrengthProperties getStrengthVsWater() { return strengthProperties.get(UnitClass.water); } /** * Get strength vs land units as a string */ public String getStrengthVsLandStringValue() { UnitStrengthProperties result = strengthProperties.get(UnitClass.land); return result != null? result.toString() : "X"; } /** * Get strength vs water units as a string */ public String getStrengthVsWaterStringValue() { UnitStrengthProperties result = strengthProperties.get(UnitClass.water); return result != null? result.toString() : "X"; } /** * Get strength vs air units as a string */ public String getStrengthVsAirStringValue() { UnitStrengthProperties result = strengthProperties.get(UnitClass.air); return result != null? result.toString() : "X"; } /** * Get all movement costs */ public Collection<UnitMovementCostProperties> getAllMovementCostProperties() { return movementCostProperties.values(); } /** * Set up on string list */ public String getUnitSetupOnStringValue() { if (unitSetupOn.size() == 0) return ""; StringBuilder rv = new StringBuilder(); rv.append(unitSetupOn.get(0)); for (int i = 1; i < unitSetupOn.size(); ++i) { rv.append(','); rv.append(unitSetupOn.get(i)); } return rv.toString(); } /** * Set up next to string list */ public String getUnitSetupNextToStringValue() { if (unitSetupNextTo.size() == 0) return ""; StringBuilder rv = new StringBuilder(); rv.append(unitSetupNextTo.get(0)); for (int i = 1; i < unitSetupNextTo.size(); ++i) { rv.append(','); rv.append(unitSetupNextTo.get(i)); } return rv.toString(); } /** * If this unit transforms in a container */ public int getTransformableTypeIntValue() { return TransformableType.toInt(transformableType); } /** * If this unit transforms in a container */ public String getTransformableTypeStringValue() { return transformableType.toString(); } /** * If this unit can be transformed, this is the id of the unit it can transform to */ public int getTransformableToUnitId() { return transformableToUnitId; } /** * Get strength properties */ public UnitStrengthProperties getStrengthProperties(UnitClass unitClass) { UnitStrengthProperties sp = strengthProperties.get(unitClass); if (sp != null) return sp; else return new UnitStrengthProperties(unitClass, 0, 0, 0); } /** * Set strength properties * * @param sp Strength properties */ public void setStrengthProperties(UnitStrengthProperties sp) { strengthProperties.remove(sp.enemyUnitClass); if (sp.attackRange > 0 && (sp.maxStrengthWithAmmo > 0 || sp.maxStrengthWithoutAmmo > 0)) strengthProperties.put(sp.enemyUnitClass, sp); } /** * Get minimum movement cost per tile */ public int getMinimumMovementCost() { int smallest = Integer.MAX_VALUE; for (UnitMovementCostProperties cost : movementCostProperties.values()) if (cost.movementCost < smallest) smallest = cost.movementCost; return smallest; } /** * Get max amount of tiles this unit can move */ public int getMaxMovement() { return movementPoints / getMinimumMovementCost(); } /** * Get movement cost for specific terrain */ public int getMovementCost(TerrainConfig terrain) { if (movementCostProperties.get(terrain.id) != null) return movementCostProperties.get(terrain.id).movementCost; else return movementPoints + 1; } /** * Set movement cost for specific terrain * * @param terrainId Terrain type id * @param movementCost Movement cost */ public void setMovementCost(UnitMovementCostProperties umc) { assert(umc.movementCost > 0); movementCostProperties.remove(umc.terrainId); if (umc.movementCost <= movementPoints) movementCostProperties.put(umc.terrainId, umc); } /** * Check if the unit can move on a specific type of terrain */ public boolean canMoveOn(TerrainConfig terrain) { return movementCostProperties.get(terrain.id) != null; } }