package rts.units;
import java.util.ArrayList;
import org.jdom.Element;
/**
* \brief All of the unit definitions
* @author Jeff Bernard
*
*/
public class UnitDefinitionManager {
// the definitions
// first listing is neutral army, so it's shifted player+1
public ArrayList<ArrayList<UnitDefinition> > resource_defs;
public ArrayList<ArrayList<UnitDefinition> > unit_defs;
public ArrayList<ArrayList<UnitDefinition> > building_defs;
public ArrayList<ArrayList<UnitUpgrade> > unit_upgrades;
public ArrayList<ArrayList<UnitUpgrade> > building_upgrades;
public ArrayList<Integer> resource_scores; /**< how many points each resource type gets you */
/**
* Loads the unit definitions from xml
* @param xmlRoot
*/
public UnitDefinitionManager(Element xmlRoot) {
resource_defs = new ArrayList<ArrayList<UnitDefinition> >();
unit_defs = new ArrayList<ArrayList<UnitDefinition> >();
building_defs = new ArrayList<ArrayList<UnitDefinition> >();
unit_upgrades = new ArrayList<ArrayList<UnitUpgrade> >();
building_upgrades = new ArrayList<ArrayList<UnitUpgrade> >();
resource_scores = new ArrayList<Integer>();
resource_defs.add(new ArrayList<UnitDefinition>());
unit_defs.add(new ArrayList<UnitDefinition>());
building_defs.add(new ArrayList<UnitDefinition>());
unit_upgrades.add(new ArrayList<UnitUpgrade>());
building_upgrades.add(new ArrayList<UnitUpgrade>());
Element resources = xmlRoot.getChild("resources");
Element units = xmlRoot.getChild("units");
Element buildings = xmlRoot.getChild("buildings");
Element upgrades = xmlRoot.getChild("upgrades");
// add resources
for (int i = 0; i < resources.getChildren().size(); i++) {
Element child = (Element)resources.getChildren().get(i);
if (child.getName().equalsIgnoreCase("resource")) {
UnitDefinition resource = new UnitDefinition();
resource.is_resources = true;
resource.harvest_speed = getInt(child, "harvest_time");
resource.harvest_amt = getInt(child, "harvest_amt");
resource.label = child.getAttributeValue("label");
resource.resources_type = resource_defs.get(0).size();
resource_defs.get(0).add(resource);
resource_scores.add(getInt(child, "score"));
}
}
// get unit definitions
for (int i = 0; i < units.getChildren().size(); i++) {
Element child = (Element)units.getChildren().get(i);
if (child.getName().equalsIgnoreCase("unit-def")) {
UnitDefinition unit = new UnitDefinition(resourceTypes());
unit.label = child.getAttributeValue("label");
for (int j = 0; j < child.getChildren().size(); j++) {
Element stat = (Element)child.getChildren().get(j);
if (stat.getName().equalsIgnoreCase("cost")) {
for (int k = 0; k < stat.getChildren().size(); k++) {
Element cost = (Element)stat.getChildren().get(k);
if (cost.getName().equalsIgnoreCase("resource")) {
int resourceType = getInt(cost, "type");
if (resourceType >= 0 && resourceType < resourceTypes()) {
unit.cost.set(resourceType, getInt(cost, "cost"));
}
}
}
} else if (stat.getName().equalsIgnoreCase("stats")) {
unit.hp = getInt(stat, "hp");
unit.vision = getInt(stat, "vision");
unit.attack_range = getInt(stat, "attack_range");
unit.attack_min = getInt(stat, "attack_min");
unit.attack_max = getInt(stat, "attack_max");
unit.attack_speed = getInt(stat, "attack_time");
unit.produce_speed = getInt(stat, "produce_time");
unit.move_speed = getInt(stat, "move_time");
unit.is_worker = Boolean.parseBoolean(stat.getAttributeValue("is_worker"));
unit.is_flying = Boolean.parseBoolean(stat.getAttributeValue("is_flying"));
unit.type = unit_defs.get(0).size();
}
}
unit_defs.get(0).add(unit);
}
}
// get building definitions
for (int i = 0; i < buildings.getChildren().size(); i++) {
Element child = (Element)buildings.getChildren().get(i);
if (child.getName().equalsIgnoreCase("building-def")) {
UnitDefinition building = new UnitDefinition(resourceTypes());
building.is_building = true;
building.label = child.getAttributeValue("label");
if (Boolean.parseBoolean(child.getAttributeValue("stockpile"))) {
building.is_stockpile_building = true;
}
for (int j = 0; j < child.getChildren().size(); j++) {
Element stat = (Element)child.getChildren().get(j);
if (stat.getName().equalsIgnoreCase("cost")) {
for (int k = 0; k < stat.getChildren().size(); k++) {
Element cost = (Element)stat.getChildren().get(k);
if (cost.getName().equalsIgnoreCase("resource")) {
int resourceType = getInt(cost, "type");
if (resourceType >= 0 && resourceType < resourceTypes()) {
building.cost.set(resourceType, getInt(cost, "cost"));
}
}
}
} else if (stat.getName().equalsIgnoreCase("stats")) {
building.hp = getInt(stat, "hp");
building.vision = getInt(stat, "vision");
building.produce_speed = getInt(stat, "produce_time");
building.type = building_defs.get(0).size();
} else if (stat.getName().equalsIgnoreCase("produce")) {
for (int k = 0; k < stat.getChildren().size(); k++) {
Element produce = (Element)stat.getChildren().get(k);
if (produce.getName().equalsIgnoreCase("unit")) {
int unitType = getInt(produce, "type");
if (unitType >= 0 && unitType < unit_defs.get(0).size()) {
building.produces.add(unitType);
}
}
}
}
}
building_defs.get(0).add(building);
}
}
// get upgrades
if (upgrades != null) {
for (int i = 0; i < upgrades.getChildren().size(); i++) {
Element child = (Element)upgrades.getChildren().get(i);
if (child.getName().equalsIgnoreCase("unit-upgrade")) {
// upgrade a unit
UnitDefinition changes = new UnitDefinition(resourceTypes());
ArrayList<Integer> cost = new ArrayList<Integer>();
for (int j = 0; j < resourceTypes(); j++) {
cost.add(0);
}
for (int j = 0; j < child.getChildren().size(); j++) {
Element stat = (Element)child.getChildren().get(j);
if (stat.getName().equalsIgnoreCase("cost")) {
for (int k = 0; k < stat.getChildren().size(); k++) {
Element resource_cost = (Element)stat.getChildren().get(k);
if (resource_cost.getName().equalsIgnoreCase("resource")) {
int resourceType = getInt(resource_cost, "type");
if (resourceType >= 0 && resourceType < resourceTypes()) {
cost.set(resourceType, getInt(resource_cost, "cost"));
}
}
}
} else if (stat.getName().equalsIgnoreCase("changes")) {
for (int k = 0; k < stat.getChildren().size(); k++) {
Element change = (Element)stat.getChildren().get(k);
if (change.getName().equalsIgnoreCase("stats")) {
changes.hp = getInt(change, "hp");
changes.vision = getInt(change, "vision");
changes.produce_speed = getInt(change, "produce_speed");
changes.attack_range = getInt(change, "attack_range");
changes.attack_min = getInt(change, "attack_min");
changes.attack_max = getInt(change, "attack_max");
changes.move_speed = getInt(change, "move_speed");
changes.attack_speed = getInt(change, "attack_speed");
} else if (change.getName().equalsIgnoreCase("cost")) {
for (int l = 0; l < stat.getChildren().size(); l++) {
Element resource_cost = (Element)stat.getChildren().get(k);
if (resource_cost.getName().equalsIgnoreCase("resource")) {
int resourceType = getInt(resource_cost, "type");
if (resourceType >= 0 && resourceType < resourceTypes()) {
changes.cost.set(resourceType, getInt(resource_cost, "cost"));
}
}
}
}
}
}
}
unit_upgrades.get(0).add(new UnitUpgrade(changes, cost, getInt(child, "time"), getInt(child, "type")));
} else if (child.getName().equalsIgnoreCase("building-upgrade")) {
// upgrade a building
UnitDefinition changes = new UnitDefinition(resourceTypes());
ArrayList<Integer> cost = new ArrayList<Integer>();
for (int j = 0; j < resourceTypes(); j++) {
cost.add(0);
}
for (int j = 0; j < child.getChildren().size(); j++) {
Element stat = (Element)child.getChildren().get(j);
if (stat.getName().equalsIgnoreCase("cost")) {
for (int k = 0; k < stat.getChildren().size(); k++) {
Element resource_cost = (Element)stat.getChildren().get(k);
if (resource_cost.getName().equalsIgnoreCase("resource")) {
int resourceType = getInt(resource_cost, "type");
if (resourceType >= 0 && resourceType < resourceTypes()) {
cost.set(resourceType, getInt(resource_cost, "cost"));
}
}
}
} else if (stat.getName().equalsIgnoreCase("changes")) {
for (int k = 0; k < stat.getChildren().size(); k++) {
Element change = (Element)stat.getChildren().get(k);
if (change.getName().equalsIgnoreCase("stats")) {
changes.hp = getInt(change, "hp");
changes.vision = getInt(change, "vision");
changes.produce_speed = getInt(change, "produce_speed");
} else if (change.getName().equalsIgnoreCase("cost")) {
for (int l = 0; l < stat.getChildren().size(); l++) {
Element resource_cost = (Element)stat.getChildren().get(k);
if (resource_cost.getName().equalsIgnoreCase("resource")) {
int resourceType = getInt(resource_cost, "type");
if (resourceType >= 0 && resourceType < resourceTypes()) {
changes.cost.set(resourceType, getInt(resource_cost, "cost"));
}
}
}
}
}
}
}
building_upgrades.get(0).add(new UnitUpgrade(changes, cost, getInt(child, "time"), getInt(child, "type")));
}
}
}
}
/**
* Returns how many resource types there are
* @return
*/
public int resourceTypes() {
return resource_defs.get(0).size();
}
/**
* Makes a new resource field
* @param units the unit list to add this to
* @param stats the stats list to add this to
* @param type
* @param player
* @param x
* @param y
* @param amount
*/
public void makeResource(ArrayList<Unit> units, ArrayList<UnitStats> stats, int type, int player, int x, int y, int amount) {
if (type >= 0 && type < resourceTypes()) {
UnitStats resource_stats = new UnitStats(player, x, y, resource_defs.get(player+1).get(type));
resource_stats.resources = amount;
Unit resource = new Unit(resource_stats);
units.add(resource);
stats.add(resource_stats);
}
}
/**
* Makes a new unit
* @param units
* @param stats
* @param type
* @param player
* @param x
* @param y
*/
public void makeUnit(ArrayList<Unit> units, ArrayList<UnitStats> stats, int type, int player, int x, int y) {
if (type >= 0 && type < unit_defs.get(player+1).size()) {
UnitStats unit_stats = new UnitStats(player, x, y, unit_defs.get(player+1).get(type));
Unit unit = new Unit(unit_stats);
units.add(unit);
stats.add(unit_stats);
} else {
System.out.println(type+" is not a valid unit type");
}
}
/**
* Makes a new building
* @param units
* @param stats
* @param type
* @param player
* @param x
* @param y
*/
public void makeBuilding(ArrayList<Unit> units, ArrayList<UnitStats> stats, int type, int player, int x, int y) {
if (type >= 0 && type < building_defs.get(player+1).size()) {
UnitStats unit_stats = new UnitStats(player, x, y, building_defs.get(player+1).get(type));
Unit unit = new Unit(unit_stats);
units.add(unit);
stats.add(unit_stats);
}
}
/**
* Sets the number of players
* @param players how many players there are
*/
public void setPlayers(int players) {
for (int i = 0; i < players; i++) {
resource_defs.add(new ArrayList<UnitDefinition>());
unit_defs.add(new ArrayList<UnitDefinition>());
building_defs.add(new ArrayList<UnitDefinition>());
unit_upgrades.add(new ArrayList<UnitUpgrade>());
building_upgrades.add(new ArrayList<UnitUpgrade>());
for (int j = 0; j < resource_defs.get(0).size(); j++) {
resource_defs.get(i+1).add(resource_defs.get(0).get(j).clone());
}
for (int j = 0; j < unit_defs.get(0).size(); j++) {
unit_defs.get(i+1).add(unit_defs.get(0).get(j).clone());
}
for (int j = 0; j < building_defs.get(0).size(); j++) {
building_defs.get(i+1).add(building_defs.get(0).get(j).clone());
}
for (int j = 0; j < unit_upgrades.get(0).size(); j++) {
unit_upgrades.get(i+1).add(unit_upgrades.get(0).get(j).clone());
}
for (int j = 0; j < building_upgrades.get(0).size(); j++) {
building_upgrades.get(i+1).add(unit_upgrades.get(0).get(j).clone());
}
}
}
/**
* gets an int from the xml
* @param e
* @param attr
* @return
*/
private int getInt(Element e, String attr) {
try {
return Integer.parseInt(e.getAttributeValue(attr));
} catch (NumberFormatException x) {
return 0;
}
}
/**
* Returns the score for a unit
* @param unit
* @return
*/
public int getScore(UnitStats unit) {
int score = 0;
for (int i = 0; i < unit.definition.cost.size(); i++) {
score += resource_scores.get(i)*unit.definition.cost.get(i);
}
return score;
}
/**
* Gets a copy of the unit definitions for the specified player
* @param player which player
* @return
*/
public ArrayList<UnitDefinition> getCopyOfUnits(int player) {
ArrayList<UnitDefinition> defs = new ArrayList<UnitDefinition>();
if (player >= 0 && player < unit_defs.size()) {
player++;
for (int i = 0; i < unit_defs.get(player).size(); i++) {
defs.add(unit_defs.get(player).get(i).clone());
}
}
return defs;
}
/**
* Gets a copy of the building definitions for the specified player
* @param player which player
* @return
*/
public ArrayList<UnitDefinition> getCopyOfBuildings(int player) {
ArrayList<UnitDefinition> defs = new ArrayList<UnitDefinition>();
if (player >= 0 && player < building_defs.size()) {
player++;
for (int i = 0; i < building_defs.get(player).size(); i++) {
defs.add(building_defs.get(player).get(i).clone());
}
}
return defs;
}
/**
* Executes a unit upgrade
* @param player
* @param upgrade_id
* @return
*/
public boolean upgrade(int player, int upgrade_id) {
player++;
if (player >= 0 && player < unit_upgrades.size()) {
for (int i = 0; i < unit_upgrades.get(player).size(); i++) {
UnitUpgrade upgrade = unit_upgrades.get(player).get(i);
if (upgrade.getID() == upgrade_id) {
upgrade.upgrade(unit_defs.get(player).get(upgrade.getUnit()));
unit_upgrades.get(player).remove(i);
return true;
}
}
for (int i = 0; i < building_upgrades.get(player).size(); i++) {
UnitUpgrade upgrade = building_upgrades.get(player).get(i);
if (upgrade.getID() == upgrade_id) {
upgrade.upgrade(building_defs.get(player).get(upgrade.getUnit()));
building_upgrades.get(player).remove(i);
return true;
}
}
}
return false;
}
private UnitDefinitionManager() {
}
/**
*
* @return
*/
public UnitDefinitionManager copy() {
UnitDefinitionManager u = new UnitDefinitionManager();
u.resource_defs = new ArrayList<ArrayList<UnitDefinition> >();
u.unit_defs = new ArrayList<ArrayList<UnitDefinition> >();
u.building_defs = new ArrayList<ArrayList<UnitDefinition> >();
u.unit_upgrades = new ArrayList<ArrayList<UnitUpgrade> >();
u.building_upgrades = new ArrayList<ArrayList<UnitUpgrade> >();
u.resource_scores = new ArrayList<Integer>();
for (int i = 0; i < resource_defs.size(); i++) {
u.resource_defs.add(new ArrayList<UnitDefinition>());
for (int j = 0; j < resource_defs.get(i).size(); j++) {
u.resource_defs.get(i).add(resource_defs.get(i).get(j).clone());
}
}
for (int i = 0; i < unit_defs.size(); i++) {
u.unit_defs.add(new ArrayList<UnitDefinition>());
for (int j = 0; j < unit_defs.get(i).size(); j++) {
u.unit_defs.get(i).add(unit_defs.get(i).get(j).clone());
}
}
for (int i = 0; i < building_defs.size(); i++) {
u.building_defs.add(new ArrayList<UnitDefinition>());
for (int j = 0; j < building_defs.get(i).size(); j++) {
u.building_defs.get(i).add(building_defs.get(i).get(j).clone());
}
}
for (int i = 0; i < unit_upgrades.size(); i++) {
u.unit_upgrades.add(new ArrayList<UnitUpgrade>());
for (int j = 0; j < unit_upgrades.get(i).size(); j++) {
u.unit_upgrades.get(i).add(unit_upgrades.get(i).get(j).clone());
}
}
for (int i = 0; i < building_upgrades.size(); i++) {
u.building_upgrades.add(new ArrayList<UnitUpgrade>());
for (int j = 0; j < building_upgrades.get(i).size(); j++) {
u.building_upgrades.get(i).add(building_upgrades.get(i).get(j).clone());
}
}
for (int i = 0; i < resource_scores.size(); i++) {
u.resource_scores.add(resource_scores.get(i));
}
return u;
}
}