[customwars] r745 committed - Change numeric to text for unit and city stats. Validate the stats. Al...

1 view
Skip to first unread message

codesite...@google.com

unread,
Mar 14, 2011, 10:18:54 AM3/14/11
to customwar...@googlegroups.com
Revision: 745
Author: ace....@gmail.com
Date: Mon Mar 14 07:18:14 2011
Log: Change numeric to text for unit and city stats. Validate the stats.
Allow units to be resupplied within a transport. Cleaner xml format in
units.xml. Give the gun boat unit a weapon.
http://code.google.com/p/customwars/source/detail?r=745

Added:
/trunk/v2/src/com/customwars/client/model/gameobject/TransportStats.java
Modified:
/trunk/v2/resources/res/plugin/dor/data/baseCities.xml
/trunk/v2/resources/res/plugin/dor/data/units.xml
/trunk/v2/resources/res/plugin/dor/data/weapons.xml
/trunk/v2/src/com/customwars/client/controller/UnitMenuBuilder.java
/trunk/v2/src/com/customwars/client/io/loading/ModelLoader.java
/trunk/v2/src/com/customwars/client/model/gameobject/City.java
/trunk/v2/src/com/customwars/client/model/gameobject/Unit.java
/trunk/v2/src/com/customwars/client/model/gameobject/UnitStats.java
/trunk/v2/src/com/customwars/client/model/map/Map.java
/trunk/v2/test/com/customwars/client/model/TestData.java
/trunk/v2/test/com/customwars/client/model/gameobject/CityTest.java
/trunk/v2/test/com/customwars/client/model/gameobject/UnitXStreamTest.java

=======================================
--- /dev/null
+++
/trunk/v2/src/com/customwars/client/model/gameobject/TransportStats.java
Mon Mar 14 07:18:14 2011
@@ -0,0 +1,74 @@
+package com.customwars.client.model.gameobject;
+
+import com.customwars.client.tools.Args;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Holds the unit ID's that a unit can transport. This object is immutable.
+ * APC example:
+ * transports={inf, mech}
+ * maxTransportCount=1
+ */
+public class TransportStats implements Serializable {
+ private List<String> transports; // Units that can be transported
(empty when this unit can't transport)
+ public final int maxTransportCount; // Amount of units that can be
transported
+
+ /**
+ * Create a NULL transport stats object
+ */
+ public TransportStats() {
+ transports = Collections.<String>emptyList();
+ maxTransportCount = 0;
+ }
+
+ public TransportStats(int maxTransportCount) {
+ this.transports = new ArrayList<String>();
+ this.maxTransportCount = maxTransportCount;
+ }
+
+ public void addAll(Iterable<String> transports) {
+ if (transports != null) {
+ for (String unitID : transports) {
+ add(unitID);
+ }
+ }
+ }
+
+ public void add(String unitID) {
+ transports.add(unitID);
+ }
+
+ public void init(UnitStats stats) {
+ transports = Args.createEmptyListIfNull(transports);
+ Args.validate(!transports.isEmpty() && maxTransportCount <= 0,
+ "Max transport count should be >0 for unit " + stats.getName());
+ }
+
+ public void validate(UnitStats stats) {
+ for (String unitName : transports) {
+ Args.validate(!UnitFactory.hasUnitForName(unitName),
+ "Illegal unit name " + unitName + " in transports stats for unit "
+ stats.getName());
+ }
+ }
+
+ public boolean canTransport() {
+ return !transports.isEmpty();
+ }
+
+ public boolean canTransport(String unitID) {
+ return transports.contains(unitID);
+ }
+
+ public List<String> getTransports() {
+ return Collections.unmodifiableList(transports);
+ }
+
+ @Override
+ public String toString() {
+ return "transports=" + transports + " max=" + maxTransportCount;
+ }
+}
=======================================
--- /trunk/v2/resources/res/plugin/dor/data/baseCities.xml Tue Aug 3
13:14:57 2010
+++ /trunk/v2/resources/res/plugin/dor/data/baseCities.xml Mon Mar 14
07:18:14 2011
@@ -28,9 +28,9 @@
</heals>
<healRate>2</healRate>
<canBeCaptureBy>
- <int>0</int>
- <int>1</int>
- <int>2</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
</canBeCaptureBy>
<maxCapCount>20</maxCapCount>
<description>They give you money and heal units inside
them.</description>
@@ -54,25 +54,25 @@
</heals>
<healRate>2</healRate>
<canBeCaptureBy>
- <int>0</int>
- <int>1</int>
- <int>2</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
</canBeCaptureBy>
<builds>
- <int>0</int>
- <int>1</int>
- <int>2</int>
- <int>3</int>
- <int>4</int>
- <int>5</int>
- <int>6</int>
- <int>7</int>
- <int>8</int>
- <int>9</int>
- <int>10</int>
- <int>11</int>
- <int>12</int>
- <int>13</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
+ <unitID>recon</unitID>
+ <unitID>flare</unitID>
+ <unitID>anti_air</unitID>
+ <unitID>light_tank</unitID>
+ <unitID>medium_tank</unitID>
+ <unitID>heavy_tank</unitID>
+ <unitID>artillery</unitID>
+ <unitID>anti_tank</unitID>
+ <unitID>rockets</unitID>
+ <unitID>missiles</unitID>
+ <unitID>apc</unitID>
</builds>
<maxCapCount>20</maxCapCount>
<description>Factories heal, provide supplies and can create new
ground units.</description>
@@ -96,16 +96,16 @@
</heals>
<healRate>2</healRate>
<canBeCaptureBy>
- <int>0</int>
- <int>1</int>
- <int>2</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
</canBeCaptureBy>
<builds>
- <int>14</int>
- <int>15</int>
- <int>17</int>
- <int>18</int>
- <int>19</int>
+ <unitID>jet</unitID>
+ <unitID>bomber</unitID>
+ <unitID>tcopter</unitID>
+ <unitID>bcopter</unitID>
+ <unitID>fighter</unitID>
</builds>
<maxCapCount>20</maxCapCount>
<description>empty</description>
@@ -129,17 +129,17 @@
</heals>
<healRate>2</healRate>
<canBeCaptureBy>
- <int>0</int>
- <int>1</int>
- <int>2</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
</canBeCaptureBy>
<builds>
- <int>20</int>
- <int>21</int>
- <int>22</int>
- <int>23</int>
- <int>24</int>
- <int>25</int>
+ <unitID>gun_boat</unitID>
+ <unitID>cruiser</unitID>
+ <unitID>sub</unitID>
+ <unitID>carrier</unitID>
+ <unitID>battleship</unitID>
+ <unitID>lander</unitID>
</builds>
<maxCapCount>20</maxCapCount>
<description></description>
@@ -163,9 +163,9 @@
</heals>
<healRate>2</healRate>
<canBeCaptureBy>
- <int>0</int>
- <int>1</int>
- <int>2</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
</canBeCaptureBy>
<maxCapCount>20</maxCapCount>
<description></description>
@@ -183,9 +183,9 @@
</moveCosts>
<vision>1</vision>
<canBeLaunchedBy>
- <int>0</int>
- <int>1</int>
- <int>2</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
</canBeLaunchedBy>

<maxCapCount>20</maxCapCount>
@@ -231,9 +231,9 @@
<vision>5</vision>

<canBeCaptureBy>
- <int>0</int>
- <int>1</int>
- <int>2</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
</canBeCaptureBy>
<maxCapCount>20</maxCapCount>
<description>Reveals 5 tiles around this city in all
directions.</description>
@@ -250,9 +250,9 @@
<int>127</int>
</moveCosts>
<canBeCaptureBy>
- <int>0</int>
- <int>1</int>
- <int>2</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
</canBeCaptureBy>
<maxCapCount>20</maxCapCount>
<description>A small airfield that can repair and resupply your air
units.</description>
@@ -269,9 +269,9 @@
<int>1</int>
</moveCosts>
<canBeCaptureBy>
- <int>0</int>
- <int>1</int>
- <int>2</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
</canBeCaptureBy>
<maxCapCount>20</maxCapCount>
<description>A small dock that can repair and resupply your
fleet.</description>
@@ -290,9 +290,9 @@
<vision>1</vision>

<canBeCaptureBy>
- <int>0</int>
- <int>1</int>
- <int>2</int>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
</canBeCaptureBy>
<maxCapCount>20</maxCapCount>
<description>Once captured, this structure boosts all unit's offense
by 5%</description>
=======================================
--- /trunk/v2/resources/res/plugin/dor/data/units.xml Sat Feb 19 10:43:56
2011
+++ /trunk/v2/resources/res/plugin/dor/data/units.xml Mon Mar 14 07:18:14
2011
@@ -1,9 +1,11 @@
<!DOCTYPE list [<!ELEMENT list (unit*)>

- <!ELEMENT unit (price, movement, vision,canHide?, canDive?,
canCapture?, canJoin?, canFlare?, canSupply?,
- canTransport?, maxTransportCount?, transports?,
transformTerrains?, buildCities?, buildUnits?, maxExperience?, maxHp,
supplyRange?,
- maxSupplies, suppliesPerTurn?, suppliesPerTurnWhenHidden?,
maxConstructionMaterial?,
- buildCities?, healRate?, armyBranch,movementType,
primaryWeaponName?, secondaryWeaponName?, description)>
+ <!ELEMENT unit (price, movement, vision,
+ canHide?, canDive?, canCapture?, canJoin?, canFlare?,
canLaunchUnit?,
+ transports?, transformTerrains?, buildCities?, buildUnits?,
supplyUnits?, supplyUnitsInTransport?,
+ maxExperience?, maxHp, supplyRange?, maxSupplies,
suppliesPerTurn?, suppliesPerTurnWhenHidden?,
+ maxConstructionMaterial?, healRate?,
+ armyBranch,movementType, primaryWeaponName?, secondaryWeaponName?,
description)>

<!ATTLIST unit name CDATA #REQUIRED>
<!ATTLIST unit unitID CDATA #REQUIRED>
@@ -19,22 +21,27 @@
<!ELEMENT canJoin (#PCDATA)>
<!ELEMENT canFlare (#PCDATA)>
<!ELEMENT canSupply (#PCDATA)>
+ <!ELEMENT canLaunchUnit (#PCDATA)>
<!ELEMENT canTransport (#PCDATA)>
- <!ELEMENT maxTransportCount (#PCDATA)>
- <!ELEMENT transports (int*)>
+
+ <!ELEMENT transports (unitID*)>
+ <!ATTLIST transports max CDATA #REQUIRED>
+
<!ELEMENT transformTerrains (entry*)>
<!ELEMENT buildCities (entry*)>
- <!ELEMENT buildUnits (int*)>
-
- <!ELEMENT entry (int+)>
- <!ELEMENT int (#PCDATA)>
+ <!ELEMENT buildUnits (unitID*)>
+ <!ELEMENT supplyUnitsInTransport (unitID*)>
+ <!ELEMENT supplyUnits (unitID*)>
+
+ <!ELEMENT entry (id+)>
+ <!ELEMENT id (#PCDATA)>
+ <!ELEMENT unitID (#PCDATA)>
+ <!ELEMENT minRange (#PCDATA)>
+ <!ELEMENT maxRange (#PCDATA)>

<!ELEMENT maxExperience (#PCDATA)>
<!ELEMENT maxHp (#PCDATA)>
<!ELEMENT supplyRange (minRange, maxRange)>
- <!ELEMENT minRange (#PCDATA)>
- <!ELEMENT maxRange (#PCDATA)>
-
<!ELEMENT maxSupplies (#PCDATA)>
<!ELEMENT suppliesPerTurn (#PCDATA)>
<!ELEMENT suppliesPerTurnWhenHidden (#PCDATA)>
@@ -294,43 +301,59 @@
<vision>1</vision>

<canJoin>true</canJoin>
- <canSupply>true</canSupply>
- <canTransport>true</canTransport>
- <maxTransportCount>1</maxTransportCount>
- <transports>
- <int>0</int>
- <int>1</int>
+ <transports max="1">
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
</transports>

- <maxExperience>3</maxExperience>
- <maxHp>100</maxHp>
- <supplyRange>
- <minRange>1</minRange>
- <maxRange>1</maxRange>
- </supplyRange>
- <maxSupplies>99</maxSupplies>
-
- <maxConstructionMaterial>1</maxConstructionMaterial>
<buildCities>
<entry>
- <int>18</int>
- <!-- Terrain -->
- <int>12</int>
- <!-- City -->
+ <id>plain</id>
+ <id>temp_airport</id>
</entry>
<entry>
- <int>65</int>
- <int>11</int>
- </entry>
- <entry>
- <int>0</int>
- <int>11</int>
+ <id>shoal</id>
+ <id>temp_port</id>
</entry>
</buildCities>

+ <supplyUnits>
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
+ <unitID>recon</unitID>
+ <unitID>flare</unitID>
+ <unitID>anti_air</unitID>
+ <unitID>light_tank</unitID>
+ <unitID>medium_tank</unitID>
+ <unitID>heavy_tank</unitID>
+ <unitID>artillery</unitID>
+ <unitID>anti_tank</unitID>
+ <unitID>rockets</unitID>
+ <unitID>missiles</unitID>
+ <unitID>apc</unitID>
+ <unitID>jet</unitID>
+ <unitID>bomber</unitID>
+ <unitID>sea_plane</unitID>
+ <unitID>fighter</unitID>
+ <unitID>bcopter</unitID>
+ <unitID>tcopter</unitID>
+ <unitID>gun_boat</unitID>
+ <unitID>cruiser</unitID>
+ <unitID>sub</unitID>
+ <unitID>carrier</unitID>
+ <unitID>battleship</unitID>
+ <unitID>lander</unitID>
+ </supplyUnits>
+
+ <maxExperience>3</maxExperience>
+ <maxHp>100</maxHp>
+ <maxSupplies>99</maxSupplies>
+ <maxConstructionMaterial>1</maxConstructionMaterial>
+
<armyBranch>LAND</armyBranch>
<movementType>&TREAD;</movementType>
- <description>Can transport 1 unit(Infantry or Mech) they also have the
ability to supply.</description>
+ <description>Can transport 1 unit(Infantry or Mech) can supply units,
can build temp properties.</description>
</unit>

<unit name="jet" unitID="14" imgRowID="14">
@@ -431,11 +454,9 @@

<canJoin>true</canJoin>

- <canTransport>true</canTransport>
- <maxTransportCount>1</maxTransportCount>
- <transports>
- <int>0</int>
- <int>1</int>
+ <transports max="1">
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
</transports>

<maxHp>100</maxHp>
@@ -453,11 +474,9 @@
<vision>2</vision>

<canJoin>true</canJoin>
- <canTransport>true</canTransport>
- <maxTransportCount>1</maxTransportCount>
- <transports>
- <int>0</int>
- <int>1</int>
+ <transports max="1">
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
</transports>

<maxExperience>3</maxExperience>
@@ -467,6 +486,7 @@

<armyBranch>NAVAL</armyBranch>
<movementType>&NAVAL;</movementType>
+ <primaryWeaponName>gunboat_anti_ship_missile</primaryWeaponName>
<description></description>
</unit>
<unit name="cruiser" unitID="21" imgRowID="21">
@@ -476,11 +496,9 @@

<canJoin>true</canJoin>

- <canTransport>true</canTransport>
- <maxTransportCount>2</maxTransportCount>
- <transports>
- <int>18</int>
- <int>19</int>
+ <transports max="2">
+ <unitID>tcopter</unitID>
+ <unitID>bcopter</unitID>
</transports>

<maxExperience>3</maxExperience>
@@ -522,17 +540,30 @@
<vision>4</vision>

<canJoin>true</canJoin>
-
- <canTransport>true</canTransport>
- <maxTransportCount>2</maxTransportCount>
- <transports>
- <int>&AIR;</int>
+ <canLaunchUnit>true</canLaunchUnit>
+
+ <transports max="2">
+ <unitID>jet</unitID>
+ <unitID>bomber</unitID>
+ <unitID>tcopter</unitID>
+ <unitID>bcopter</unitID>
+ <unitID>sea_plane</unitID>
+ <unitID>fighter</unitID>
</transports>

<buildUnits>
- <int>16</int>
+ <unitID>sea_plane</unitID>
</buildUnits>

+ <supplyUnitsInTransport>
+ <unitID>jet</unitID>
+ <unitID>bomber</unitID>
+ <unitID>tcopter</unitID>
+ <unitID>bcopter</unitID>
+ <unitID>sea_plane</unitID>
+ <unitID>fighter</unitID>
+ </supplyUnitsInTransport>
+
<maxExperience>3</maxExperience>
<maxHp>100</maxHp>
<maxSupplies>99</maxSupplies>
@@ -542,7 +573,7 @@
<armyBranch>NAVAL</armyBranch>
<movementType>&NAVAL;</movementType>

- <secondaryWeaponName>naval_anti_air_missle</secondaryWeaponName>
+ <primaryWeaponName>naval_anti_air_missle</primaryWeaponName>
<description>Can produce and carry 2 air units</description>
</unit>
<unit name="battleship" unitID="24" imgRowID="24">
@@ -569,23 +600,21 @@
<vision>1</vision>

<canJoin>true</canJoin>
- <canTransport>true</canTransport>
- <maxTransportCount>2</maxTransportCount>
- <transports>
- <int>0</int>
- <int>1</int>
- <int>2</int>
- <int>3</int>
- <int>4</int>
- <int>5</int>
- <int>6</int>
- <int>7</int>
- <int>8</int>
- <int>9</int>
- <int>18</int>
- <int>22</int>
- <int>23</int>
- <int>24</int>
+ <transports max="2">
+ <unitID>infantry</unitID>
+ <unitID>mech</unitID>
+ <unitID>bikes</unitID>
+ <unitID>recon</unitID>
+ <unitID>flare</unitID>
+ <unitID>anti_air</unitID>
+ <unitID>light_tank</unitID>
+ <unitID>medium_tank</unitID>
+ <unitID>heavy_tank</unitID>
+ <unitID>artillery</unitID>
+ <unitID>anti_tank</unitID>
+ <unitID>rockets</unitID>
+ <unitID>missiles</unitID>
+ <unitID>apc</unitID>
</transports>

<maxHp>100</maxHp>
=======================================
--- /trunk/v2/resources/res/plugin/dor/data/weapons.xml Fri Feb 18 16:18:45
2011
+++ /trunk/v2/resources/res/plugin/dor/data/weapons.xml Mon Mar 14 07:18:14
2011
@@ -157,7 +157,7 @@
<weapon name="naval_anti_air_missle">
<fireRange>
<minRange>1</minRange>
- <maxRange>2</maxRange>
+ <maxRange>1</maxRange>
</fireRange>
<attacks>
<armyBranch>AIR</armyBranch>
@@ -257,4 +257,15 @@
<maxAmmo>3</maxAmmo>
<description>Fires a flare that reveals fogged tiles.</description>
</weapon>
+ <weapon name="gunboat_anti_ship_missile">
+ <fireRange>
+ <minRange>1</minRange>
+ <maxRange>1</maxRange>
+ </fireRange>
+ <attacks>
+ <armyBranch>NAVAL</armyBranch>
+ </attacks>
+ <maxAmmo>1</maxAmmo>
+ <description></description>
+ </weapon>
</list>
=======================================
--- /trunk/v2/src/com/customwars/client/controller/UnitMenuBuilder.java Fri
Mar 11 12:34:14 2011
+++ /trunk/v2/src/com/customwars/client/controller/UnitMenuBuilder.java Mon
Mar 14 07:18:14 2011
@@ -190,7 +190,7 @@
}

if (canBuildUnit) {
- for (int unitID : unit.getStats().getUnitsThatCanBeBuild()) {
+ for (String unitID : unit.getStats().getUnitsThatCanBeBuild()) {
Unit unitThatCanBeBuild = UnitFactory.getUnit(unitID);
CWAction buildUnitAction =
ActionFactory.buildProduceUnitAction(unit, unitThatCanBeBuild, to);
String menuText = App.translate("build") + " - " +
App.translate(unitThatCanBeBuild.getStats().getName());
@@ -280,12 +280,12 @@
}

private Terrain getTransformToTerrain(Tile tile) {
- int transformID =
unit.getStats().getTransformTerrainFor(tile.getTerrain());
+ String transformID =
unit.getStats().getTransformTerrainFor(tile.getTerrain());
return TerrainFactory.getTerrain(transformID);
}

private City getCityThatCanBeBuildOn(Tile tile) {
- int cityID =
unit.getStats().getCityToBuildOnTerrain(tile.getTerrain());
+ String cityID =
unit.getStats().getCityToBuildOnTerrain(tile.getTerrain());
return CityFactory.getCity(cityID);
}

=======================================
--- /trunk/v2/src/com/customwars/client/io/loading/ModelLoader.java Mon May
24 11:10:40 2010
+++ /trunk/v2/src/com/customwars/client/io/loading/ModelLoader.java Mon Mar
14 07:18:14 2011
@@ -16,6 +16,7 @@
import com.customwars.client.model.gameobject.Terrain;
import com.customwars.client.model.gameobject.TerrainConnection;
import com.customwars.client.model.gameobject.TerrainFactory;
+import com.customwars.client.model.gameobject.TransportStats;
import com.customwars.client.model.gameobject.Unit;
import com.customwars.client.model.gameobject.UnitFactory;
import com.customwars.client.model.gameobject.UnitStats;
@@ -68,6 +69,7 @@
loadCities();
loadDamageTables();
loadCOs();
+ validateData();
}

private void loadTerrains() {
@@ -103,11 +105,22 @@

private void loadUnits() {
xStream.alias("unit", UnitStats.class);
- XStreamUtil.useReflectionFor(xStream, Unit.class);
+ XStreamUtil.useReflectionFor(xStream, UnitStats.class);
xStream.useAttributeFor(UnitStats.class, "unitID");
xStream.useAttributeFor(UnitStats.class, "imgRowID");
xStream.useAttributeFor(UnitStats.class, "name");
+ xStream.useAttributeFor(Range.class, "minRange");
+ xStream.useAttributeFor(Range.class, "maxRange");
+
+ xStream.aliasField("transports", UnitStats.class, "transportStats");
+ xStream.addImplicitCollection(TransportStats.class, "transports");
+ xStream.useAttributeFor(TransportStats.class, "maxTransportCount");
+ xStream.aliasAttribute("max", "maxTransportCount");
+
xStream.alias("supplyRange", Range.class);
+ xStream.alias("unitID", String.class);
+ xStream.alias("id", String.class);
+
InputStream unitStream =
ResourceLoader.getResourceAsStream(modelResPath + XML_DATA_UNITS_FILE);
Collection<UnitStats> unitStats = (Collection<UnitStats>)
XStreamUtil.readObject(xStream, unitStream);
UnitFactory.addUnits(unitStats);
@@ -121,6 +134,7 @@
xStream.useAttributeFor(Terrain.class, "type");
xStream.useAttributeFor(City.class, "imgRowID");
xStream.alias("armyBranch", ArmyBranch.class);
+ xStream.alias("unitID", String.class);
xStream.aliasField("connect", Terrain.class, "connection");

// Load Base Cities, they contain the city stats
@@ -166,4 +180,13 @@
COFactory.addCOStyles(CoStyles);
COFactory.addCOs(cos);
}
-}
+
+ private void validateData() {
+ for (Unit unit : UnitFactory.getAllUnits()) {
+ unit.getStats().validate();
+ }
+ for (City city : CityFactory.getBaseCities()) {
+ city.validate();
+ }
+ }
+}
=======================================
--- /trunk/v2/src/com/customwars/client/model/gameobject/City.java Sun Feb
20 02:59:11 2011
+++ /trunk/v2/src/com/customwars/client/model/gameobject/City.java Mon Mar
14 07:18:14 2011
@@ -31,14 +31,12 @@
* <p/>
* A City can fire a rocket once
* A City can be destroyed
- *
- * @author stefan
*/
public class City extends Terrain implements PropertyChangeListener,
TurnHandler, Locatable, Defender {
private List<ArmyBranch> heals; // The army branches this City can
heal(Empty list means it cannot heal)
- private List<Integer> canBeCaptureBy; // The unit ids this City can be
captured by(Empty list means it cannot be captured)
- private List<Integer> builds; // The unit ids this City can
build (Empty list means it cannot build)
- private List<Integer> canBeLaunchedBy;// The unit ids that can launch a
rocket from this city (Empty list means it cannot launch rockets)
+ private List<String> canBeCaptureBy; // The unit ids this City can be
captured by(Empty list means it cannot be captured)
+ private List<String> builds; // The unit ids this City can build
(Empty list means it cannot build)
+ private List<String> canBeLaunchedBy;// The unit ids that can launch a
rocket from this city (Empty list means it cannot launch rockets)
private final int maxCapCount;
private final int healRate; // Healing/repairs this city can give
to a Unit
private final int maxHp; // Maximum health points
@@ -55,13 +53,14 @@

public City(int id, int imgRowID, String type, String connectType,
String name, String description, int defenseBonus, int height,
List<Integer> moveCosts,
int vision, boolean hidden, List<Direction>
connectedDirections,
- List<ArmyBranch> heals, List<Integer> canBeCaptureBy,
List<Integer> builds, int maxCapCount, int healRate,
+ List<ArmyBranch> heals, List<String> canBeCaptureBy,
List<String> builds, List<String> canBeLaunchedBy, int maxCapCount, int
healRate,
int maxHp, boolean canProduceFunds) {
super(id, type, connectType, name, description, defenseBonus, height,
hidden, vision, moveCosts, connectedDirections, "");
this.imgRowID = imgRowID;
this.heals = heals;
this.canBeCaptureBy = canBeCaptureBy;
this.builds = builds;
+ this.canBeLaunchedBy = canBeLaunchedBy;
this.maxCapCount = maxCapCount;
this.healRate = healRate;
this.maxHp = maxHp;
@@ -73,7 +72,7 @@
* Create a city with the given ID all the other values are set to
default values
*/
public City(int id) {
- this(id, id, "", "", "dummy city", "", 0, 0, Arrays.asList(1), 0,
false, null, null, null, null, 0, 0, 0, true);
+ this(id, id, "", "", "dummy city", "", 0, 0, Arrays.asList(1), 0,
false, null, null, null, null, null, 0, 0, 0, true);
}

@Override
@@ -86,6 +85,25 @@
Args.validate(maxCapCount < 0, "maxCapcount should be positive");
Args.validate(maxHp < 0, "maxHP should be positive");
}
+
+ public void validate() {
+ for (String unitName : canBeCaptureBy) {
+ validateUnitName(unitName,
+ "Illegal unit name " + unitName + " in can be captured by");
+ }
+ for (String unitName : builds) {
+ validateUnitName(unitName,
+ "Illegal unit name " + unitName + " in builds");
+ }
+ for (String unitName : canBeLaunchedBy) {
+ validateUnitName(unitName,
+ "Illegal unit name " + unitName + " in can be launched");
+ }
+ }
+
+ private void validateUnitName(String unitName, String err) {
+ Args.validate(!UnitFactory.hasUnitForName(unitName), err);
+ }

public City(City otherCity) {
super(otherCity);
@@ -153,7 +171,6 @@
* the player that is owning the capturing unit will be the new owner of
this city
* <p/>
* Pre: canBeCapturedBy(unit) == true
- * Post: isCaptured() == true isCapturedBy(unit) == true
*
* @param capturer The Unit that will perform the capture action
*/
@@ -342,7 +359,7 @@
}

public boolean canBeCapturedBy(Unit unit) {
- return unit != null &&
canBeCaptureBy.contains(unit.getStats().getID()) &&
unit.getLocation().equals(location);
+ return unit != null &&
canBeCaptureBy.contains(unit.getStats().getName()) &&
unit.getLocation().equals(location);
}

public boolean canBeCaptured() {
@@ -353,7 +370,7 @@
* @return does this city has the ability to build the given unit
*/
public boolean canBuild(Unit unit) {
- return unit != null && builds.contains(unit.getStats().getID());
+ return unit != null && builds.contains(unit.getStats().getName());
}

/**
@@ -392,7 +409,7 @@
* @return if the unit can launch a rocket from this city
*/
public boolean canLaunchRocket(Unit unit) {
- return unit != null && canLaunchRocket() &&
canBeLaunchedBy.contains(unit.getStats().getID());
+ return unit != null && canLaunchRocket() &&
canBeLaunchedBy.contains(unit.getStats().getName());
}

/**
=======================================
--- /trunk/v2/src/com/customwars/client/model/gameobject/Unit.java Fri Mar
11 13:07:50 2011
+++ /trunk/v2/src/com/customwars/client/model/gameobject/Unit.java Mon Mar
14 07:18:14 2011
@@ -65,7 +65,7 @@
}

void init() {
- stats.validate();
+ stats.init();
transport = new LinkedList<Locatable>();
if (stats.canDive) dive();
unitState = UnitState.IDLE;
@@ -162,15 +162,15 @@
}

/**
- * If this unit is transporting units and it can build the unit in the
transport
+ * If this unit is transporting units and it can supply the unit in the
transport
* then supply and heal the units in the transport
*/
private void supplyUnitsInTransport() {
- if (stats.canTransport && !transport.isEmpty()) {
+ if (stats.canTransport() && !transport.isEmpty()) {
for (Locatable locatable : transport) {
Unit unit = (Unit) locatable;
- if (stats.canBuildUnit(unit)) {
- supply(unit);
+ if (stats.canSupplyUnitInTransport(unit)) {
+ supplyInTransport(unit);
unit.heal(stats.healRate);
}
}
@@ -330,18 +330,18 @@
public boolean canAdd(Locatable locatable) {
if (locatable instanceof Unit) {
Unit unit = (Unit) locatable;
- return canTransport(unit.getMovementType());
+ return canTransport(unit.stats.name);
} else {
return false;
}
}

- public boolean canTransport(int id) {
- return stats.canTransport && stats.canTransport(id)
&& !isTransportFull();
+ public boolean canTransport(String unitName) {
+ return stats.canTransport(unitName) && !isTransportFull();
}

private boolean isTransportFull() {
- return transport.size() >= stats.maxTransportCount;
+ return transport.size() >= stats.getMaxTransportCount();
}

/**
@@ -390,10 +390,17 @@
secondaryWeapon.restock();
}
}
+
+ public void supplyInTransport(Unit unit) {
+ if (canSupply(unit, true)) {
+ unit.resupply();
+ }
+ }

public void supply(Unit unit) {
- if (canSupply(unit))
+ if (canSupply(unit, false)) {
unit.resupply();
+ }
}

/**
@@ -402,11 +409,17 @@
* #2 Can we add supplies or ammo to one of the weapons of the unit
* #3 Is the supplier and the unit owned by the same player
*
- * @param unit the unit that is going to be supplied by this unit
+ * @param unit the unit that is going to be supplied by this unit
+ * @param inTransport true if only units in the transport should be
resupplied..
* @return Can this unit supply the given unit
*/
- public boolean canSupply(Unit unit) {
- return unit != null && stats.canSupply && !unit.hasMaxSupplies() &&
owner == unit.owner;
+ public boolean canSupply(Unit unit, boolean inTransport) {
+ if (unit == null) return false;
+ boolean canSupply = inTransport ?
stats.canSupplyUnitInTransport(unit) :
stats.canSupplyUnitAroundTransport(unit);
+ boolean needsSupplies = !unit.hasMaxSupplies();
+ boolean allied = owner.equals(unit.owner);
+
+ return canSupply && needsSupplies && allied;
}

/**
@@ -919,7 +932,7 @@
* @return Can this unit build units
*/
public boolean canBuildUnit() {
- return stats.canTransport && !isTransportFull();
+ return stats.canTransport() && !isTransportFull();
}

public boolean canHide() {
=======================================
--- /trunk/v2/src/com/customwars/client/model/gameobject/UnitStats.java Tue
Aug 3 13:14:57 2010
+++ /trunk/v2/src/com/customwars/client/model/gameobject/UnitStats.java Mon
Mar 14 07:18:14 2011
@@ -5,10 +5,10 @@
import com.customwars.client.model.map.path.DefaultMoveStrategy;
import com.customwars.client.model.map.path.MoveStrategy;
import com.customwars.client.tools.Args;
+import com.customwars.client.tools.StringUtil;

import java.io.Serializable;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;

@@ -16,6 +16,7 @@
* Immutable statistics of a Unit
*/
public class UnitStats implements Serializable {
+ private static final Range DEFAULT_SUPPLY_RANGE = new Range(1, 1);
final int unitID; // The unit Type ie(1->INF, 2->APC,...)
final int imgRowID; // The id, used to retrieve the images for this
unit
final String name; // Full name ie Infantry, Tank, ...
@@ -29,35 +30,36 @@
final int maxHp; // The value when this unit is 100% Healthy
Range supplyRange; // Range in which the unit can supply
final int maxSupplies; // The value when this unit has 100%
supplies
- final int maxTransportCount; // Amount of units that can be transported
final int suppliesPerTurn; // Amount of supplies that are subtracted
each turn from supplies
final int healRate; // Amount of healing that a transport can
give to units that can be build by that transport

final boolean canCapture; // Abilities
final boolean canDive;
- final boolean canSupply;
- final boolean canTransport;
final boolean canJoin;
final boolean canFlare;
final boolean canHide;
-
- private Map<Integer, Integer> transformTerrains; // Terrain Ids this
unit can transform to for a given TerrainId
- private Map<Integer, Integer> buildCities; // City Ids this unit
can build on given terrains
- private List<Integer> buildUnits; // Units that can be
build/healed
- private List<Integer> transports; // Units that can be
transported (empty when this unit can't transport)
+ final boolean canLaunchUnit;
+
+ private Map<String, String> transformTerrains; // Terrain Ids this unit
can transform to for a given TerrainId
+ private Map<String, String> buildCities; // City Ids this unit
can build on given terrains
+ private List<String> buildUnits; // Units that can be build
+ private List<String> supplyUnitsInTransport; // Units that can be
supplied and healed when within this transport(empty means no unit can be
supplied)
+ private List<String> supplyUnits; // Units that can be
supplied and healed around this unit(empty means no unit can be supplied)
final ArmyBranch armyBranch; // Naval, Ground, Air
final int movementType; // Inf, Mech, Tires, Tread,
Air, Naval ...

- private final String primaryWeaponName; // Weapons, "" means no
weapon
- private final String secondaryWeaponName;
+ private String primaryWeaponName; // Weapons, "" means no
weapon
+ private String secondaryWeaponName;
private final int suppliesPerTurnWhenHidden;
final int maxConstructionMaterial;
+ private TransportStats transportStats;

public UnitStats(int unitID, int imgRowID, String name, String
description,
int price, int movement, int vision, int maxExperience,
int maxHp, int maxSupplies, int maxTransportCount, int
suppliesPerTurn,
- boolean canCapture, boolean canDive, boolean canSupply,
boolean canTransport, boolean canJoin,
- boolean canFlare, boolean canHide, List<Integer>
transports,
+ boolean canCapture, boolean canDive, boolean canJoin,
+ boolean canFlare, boolean canHide, boolean
canLaunchUnit, List<String> transports,
+ List<String> supplyUnitsInTransport, List<String>
supplyUnits,
ArmyBranch armyBranch, int movementType, Range
supplyRange,
String primaryWeaponName, String secondaryWeaponName,
int healRate,
int suppliesPerTurnWhenHidden, int
maxConstructionMaterial) {
@@ -72,18 +74,18 @@

this.maxHp = maxHp;
this.maxSupplies = maxSupplies;
- this.maxTransportCount = maxTransportCount;
this.suppliesPerTurn = suppliesPerTurn;

this.canCapture = canCapture;
this.canDive = canDive;
- this.canSupply = canSupply;
- this.canTransport = canTransport;
this.canJoin = canJoin;
this.canFlare = canFlare;
this.canHide = canHide;
- this.transports = transports;
-
+ this.canLaunchUnit = canLaunchUnit;
+ this.transportStats = new TransportStats(maxTransportCount);
+ this.transportStats.addAll(transports);
+ this.supplyUnitsInTransport = supplyUnitsInTransport;
+ this.supplyUnits = supplyUnits;
this.armyBranch = armyBranch;
this.movementType = movementType;
this.supplyRange = supplyRange;
@@ -92,21 +94,68 @@
this.healRate = healRate;
this.suppliesPerTurnWhenHidden = suppliesPerTurnWhenHidden;
this.maxConstructionMaterial = maxConstructionMaterial;
- validate();
+ init();
}

- public void validate() {
- transports = Args.createEmptyListIfNull(transports);
- transformTerrains = transformTerrains == null ? new HashMap<Integer,
Integer>() : transformTerrains;
- buildCities = buildCities == null ? new HashMap<Integer, Integer>() :
buildCities;
+ public void init() {
+ if (transportStats == null) transportStats = new TransportStats();
+ transportStats.init(this);
+ transformTerrains = Args.createEmptyMapIfNull(transformTerrains);
+ buildCities = Args.createEmptyMapIfNull(buildCities);
buildUnits = Args.createEmptyListIfNull(buildUnits);
- supplyRange = supplyRange == null ? Range.ZERO_RANGE : supplyRange;
+ supplyUnitsInTransport =
Args.createEmptyListIfNull(supplyUnitsInTransport);
+ supplyUnits = Args.createEmptyListIfNull(supplyUnits);
+ if (primaryWeaponName == null) primaryWeaponName = "";
+ if (secondaryWeaponName == null) secondaryWeaponName = "";
+ if (moveStrategy == null) moveStrategy = new DefaultMoveStrategy();
Args.checkForNull(name, "please provide a name for unitID " + unitID);
- Args.checkForNull(description, "please provide a description for
unitID " + unitID);
+ Args.checkForNull(description, "please provide a description for
unit " + name);
Args.validate(suppliesPerTurn < 0, "supplies per turn should be
positive");
Args.validate(suppliesPerTurnWhenHidden < 0, "supplies per turn when
hidden should be positive");
- if (moveStrategy == null) moveStrategy = new DefaultMoveStrategy();
Args.validate(maxConstructionMaterial < 0, "Construction material must
be positive");
+ initSupplyRange();
+ }
+
+ private void initSupplyRange() {
+ boolean canSupply = !supplyUnits.isEmpty();
+ if (canSupply && supplyRange == null) {
+ supplyRange = DEFAULT_SUPPLY_RANGE; // Default to adjacent supply
range when no range has been given
+ } else {
+ supplyRange = supplyRange == null ? Range.ZERO_RANGE : supplyRange;
+ }
+ }
+
+ /**
+ * Validate ensures that String references to other objects are valid.
+ * This check cannot be done in the init() method because all resources
may not be loaded yet.
+ * Call this method when all objects have been loaded.
+ */
+ public void validate() {
+ transportStats.validate(this);
+
+ for (String unitName : buildUnits) {
+ Args.validate(!UnitFactory.hasUnitForName(unitName), "Illegal unit
name " + unitName + " in build unit stats");
+ }
+
+ for (Map.Entry<String, String> entry : buildCities.entrySet()) {
+ String terrainName = entry.getKey();
+ String cityName = entry.getValue();
+
Args.validate(!TerrainFactory.hasTerrainForName(terrainName), "Illegal
terrain " + terrainName + " in build cities stats");
+ Args.validate(!CityFactory.hasCityForName(cityName), "Illegal city "
+ cityName + " in build cities stats");
+ }
+
+ for (String unitName : supplyUnits) {
+ Args.validate(!UnitFactory.hasUnitForName(unitName), "Illegal unit "
+ unitName + " in supply units stats");
+ }
+
+ for (String unitName : supplyUnitsInTransport) {
+ Args.validate(!UnitFactory.hasUnitForName(unitName), "Illegal unit "
+ unitName + " in supply units in transport stats");
+ }
+
+ Args.validate(StringUtil.hasContent(primaryWeaponName)
&& !WeaponFactory.hasWeapon(primaryWeaponName),
+ "Illegal primary weapon " + primaryWeaponName + " for unit " + name);
+ Args.validate(StringUtil.hasContent(secondaryWeaponName)
&& !WeaponFactory.hasWeapon(secondaryWeaponName),
+ "Illegal secondary weapon " + secondaryWeaponName + " for unit " +
name);
}

public ArmyBranch getArmyBranch() {
@@ -166,7 +215,7 @@
}

public int getMaxTransportCount() {
- return maxTransportCount;
+ return transportStats.maxTransportCount;
}

public int getSuppliesPerTurn() {
@@ -180,64 +229,76 @@
public int getMovementType() {
return movementType;
}
-
- public boolean canSupply() {
- return canSupply;
- }

public boolean canHide() {
return canHide;
}
+
+ public boolean canLaunchUnit() {
+ return canLaunchUnit;
+ }

public boolean canCapture() {
return canCapture;
}

public boolean canTransformTerrain(Terrain terrain) {
- return transformTerrains.containsKey(terrain.getID());
+ return transformTerrains.containsKey(terrain.getName());
}

- public int getTransformTerrainFor(Terrain terrain) {
- return transformTerrains.get(terrain.getID());
- }
-
- public Map<Integer, Integer> getTransformTerrains() {
- return Collections.unmodifiableMap(transformTerrains);
+ public String getTransformTerrainFor(Terrain terrain) {
+ return transformTerrains.get(terrain.getName());
}

public boolean canTransport() {
- return canTransport;
+ return transportStats.canTransport();
}

- public boolean canTransport(int id) {
- return transports.contains(id);
+ public boolean canTransport(String unitID) {
+ return transportStats.canTransport(unitID);
}

- public List<Integer> getTransports() {
- return Collections.unmodifiableList(transports);
+ public List<String> getTransports() {
+ return transportStats.getTransports();
}

- public boolean canBuildCity(int id) {
+ public boolean canBuildCity(String id) {
return buildCities.containsKey(id);
}

public boolean canBuildCityOn(Terrain terrain) {
- return canBuildCity(terrain.getID());
+ return canBuildCity(terrain.getName());
}

- public int getCityToBuildOnTerrain(Terrain terrain) {
- return buildCities.get(terrain.getID());
+ public String getCityToBuildOnTerrain(Terrain terrain) {
+ return buildCities.get(terrain.getName());
}

public boolean canBuildUnit(Unit unit) {
- return canBuildUnit(unit.getStats().unitID);
+ return canBuildUnit(unit.getStats().name);
}

- public boolean canBuildUnit(int unitID) {
+ public boolean canBuildUnit(String unitID) {
return buildUnits.contains(unitID);
}

- public Iterable<Integer> getUnitsThatCanBeBuild() {
+ public boolean canSupplyUnitInTransport(Unit unit) {
+ return canSupplyUnitInTransport(unit.getStats().name);
+ }
+
+ public boolean canSupplyUnitInTransport(String unitID) {
+ return supplyUnitsInTransport.contains(unitID);
+ }
+
+ public boolean canSupplyUnitAroundTransport(Unit unit) {
+ return canSupplyUnitAroundTransport(unit.getStats().name);
+ }
+
+ public boolean canSupplyUnitAroundTransport(String unitID) {
+ return supplyUnits.contains(unitID);
+ }
+
+ public Iterable<String> getUnitsThatCanBeBuild() {
return Collections.unmodifiableList(buildUnits);
}

@@ -259,37 +320,41 @@

@Override
public String toString() {
- return "UnitStats{" +
- "unitID=" + unitID +
- ", imgRowID=" + imgRowID +
- ", name='" + name + '\'' +
- ", description='" + description + '\'' +
- ", price=" + price +
- ", movement=" + movement +
- ", vision=" + vision +
- ", maxExperience=" + maxExperience +
- ", maxHp=" + maxHp +
- ", supplyRange=" + supplyRange +
- ", maxSupplies=" + maxSupplies +
- ", maxTransportCount=" + maxTransportCount +
- ", maxConstructionMaterial=" + maxConstructionMaterial +
- ", suppliesPerTurn=" + suppliesPerTurn +
- ", suppliesPerTurnWhenHidden=" + suppliesPerTurnWhenHidden +
- ", canCapture=" + canCapture +
- ", canDive=" + canDive +
- ", canSupply=" + canSupply +
- ", canTransport=" + canTransport +
- ", canJoin=" + canJoin +
- ", canFlare=" + canFlare +
- ", canHide=" + canHide +
- ", transformTerrains=" + transformTerrains +
- ", buildCities=" + buildCities +
- ", buildUnits=" + buildUnits +
- ", transports=" + transports +
- ", armyBranch=" + armyBranch +
- ", movementType=" + movementType +
- ", primaryWeaponName='" + primaryWeaponName + '\'' +
- ", secondaryWeaponName='" + secondaryWeaponName + '\'' +
- '}';
+ final StringBuffer sb = new StringBuffer(100);
+ sb.append("UnitStats");
+ sb.append("{unitID=").append(unitID);
+ sb.append(", imgRowID=").append(imgRowID);
+ sb.append(", name='").append(name).append('\'');
+ sb.append(", description='").append(description).append('\'');
+ sb.append(", price=").append(price);
+ sb.append(", movement=").append(movement);
+ sb.append(", vision=").append(vision);
+ sb.append(", moveStrategy=").append(moveStrategy);
+ sb.append(", maxExperience=").append(maxExperience);
+ sb.append(", maxHp=").append(maxHp);
+ sb.append(", supplyRange=").append(supplyRange);
+ sb.append(", maxSupplies=").append(maxSupplies);
+ sb.append(", suppliesPerTurn=").append(suppliesPerTurn);
+ sb.append(", healRate=").append(healRate);
+ sb.append(", canCapture=").append(canCapture);
+ sb.append(", canDive=").append(canDive);
+ sb.append(", canJoin=").append(canJoin);
+ sb.append(", canFlare=").append(canFlare);
+ sb.append(", canHide=").append(canHide);
+ sb.append(", canLaunchUnit=").append(canLaunchUnit);
+ sb.append(", transformTerrains=").append(transformTerrains);
+ sb.append(", buildCities=").append(buildCities);
+ sb.append(", buildUnits=").append(buildUnits);
+ sb.append(", supplyUnitsInTransport=").append(supplyUnitsInTransport);
+ sb.append(", supplyUnits=").append(supplyUnits);
+ sb.append(", armyBranch=").append(armyBranch);
+ sb.append(", movementType=").append(movementType);
+ sb.append(",
primaryWeaponName='").append(primaryWeaponName).append('\'');
+ sb.append(",
secondaryWeaponName='").append(secondaryWeaponName).append('\'');
+ sb.append(",
suppliesPerTurnWhenHidden=").append(suppliesPerTurnWhenHidden);
+ sb.append(",
maxConstructionMaterial=").append(maxConstructionMaterial);
+ sb.append(", transportStats=").append(transportStats);
+ sb.append('}');
+ return sb.toString();
}
}
=======================================
--- /trunk/v2/src/com/customwars/client/model/map/Map.java Fri Mar 11
13:07:50 2011
+++ /trunk/v2/src/com/customwars/client/model/map/Map.java Mon Mar 14
07:18:14 2011
@@ -293,7 +293,7 @@
Unit unitInRange = getUnitOn(t);

if (unitInRange != null) {
- if (isUnitVisible(unitInRange) && supplier.canSupply(unitInRange))
{
+ if (isUnitVisible(unitInRange) && supplier.canSupply(unitInRange,
false)) {
units.add(unitInRange);
}
}
@@ -330,7 +330,11 @@

if (fight != null) {
if (fight.canUsePrimaryWeapon() ||
fight.canUseSecondaryWeapon()) {
- enemies.add(unit);
+ if (canAttackUnit) {
+ enemies.add(unit);
+ } else {
+ enemies.add(city);
+ }
}
}
}
@@ -726,6 +730,7 @@

/**
* Determines if at least 1 unit in the transport can be dropped on the
drop location.
+ * If the transport is empty false is returned.
*
* @param dropLocation The tile that a unit wants to be dropped on
* @param transporter The transport unit that attempts to drop a unit
to the dropLocation
@@ -733,6 +738,8 @@
* @see #isFreeDropLocation(Unit, Unit, Tile)
*/
public boolean canDropAtLeast1Unit(Unit transporter, Tile dropLocation) {
+ if (transporter.getLocatableCount() == 0) return false;
+
for (int i = 0; i < transporter.getLocatableCount(); i++) {
Unit unit = (Unit) transporter.getLocatable(i);
if (!isFreeDropLocation(transporter, unit, dropLocation)) {
=======================================
--- /trunk/v2/test/com/customwars/client/model/TestData.java Tue Aug 3
13:14:57 2010
+++ /trunk/v2/test/com/customwars/client/model/TestData.java Mon Mar 14
07:18:14 2011
@@ -19,16 +19,14 @@
import com.customwars.client.model.map.Direction;
import com.customwars.client.model.map.Range;
import com.customwars.client.script.ScriptManager;
+import com.customwars.client.tools.ListUtil;

import java.awt.Color;
import java.util.Arrays;
import java.util.List;

/**
- * Contains test data
- * The ids for Unit,Terrain,City are the indexes within the corresponding
image.
- *
- * @author stefan
+ * Contains test data.
*/
public class TestData {
private static final String[] EMPTY_ARR = new String[]{};
@@ -51,6 +49,7 @@
public static final int ARTILLERY = 9;
public static final int ROCKETS = 11;
public static final int APC = 13;
+ public static final int CARRIER = 23;

public static final String SMG = "smg";
public static final String BAZOOKA = "bazooka";
@@ -58,6 +57,7 @@
public static final String ROCKET = "rocket";
public static final String ART_CANNON = "art_cannon";
public static final String TANK_CANNON = "tank_cannon";
+ public static final String CARRIER_ANTI_AIR = "naval_anti_air_missle";

public static final int BASE = 0;
public static final int FACTORY = 1;
@@ -73,63 +73,71 @@
private static final List<ArmyBranch> ARMY_BRANCH_LAND_ONLY =
Arrays.asList(ArmyBranch.LAND);
private static final List<ArmyBranch> ARMY_BRANCH_NAVAL_ONLY =
Arrays.asList(ArmyBranch.NAVAL);
private static final List<ArmyBranch> ARMY_BRANCH_AIR_ONLY =
Arrays.asList(ArmyBranch.AIR);
- private static final List<Integer> allLandUnits = Arrays.asList(0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
- private static final List<Integer> allAirUnits = Arrays.asList(14, 15,
17, 18, 19);
- private static final List<Integer> allNavalUnits = Arrays.asList(20, 21,
22, 23, 24, 25);
+ private static final List<String> allLandUnits =
Arrays.asList("infantry", "mech", "bikes", "recon", "flare", "anti_air",
+ "light_tank", "medium_tank", "heavy_tank", "artillery", "anti_tank", "rockets", "missles", "apc");
+ private static final List<String> allAirUnits =
+
Arrays.asList("jet", "bomber", "sea_plane", "fighter", "bcopter", "tcopter");
+ private static final List<String> allNavalUnits =
+
Arrays.asList("gun_boat", "cruiser", "sub", "carrier", "battleship", "lander");
+ private static final List<String> allUnits = ListUtil.join(allLandUnits,
allAirUnits, allNavalUnits);
+ private static final List<String> infAndMech =
Arrays.asList("infantry", "mech");

// Movecosts: INF, MECH, TREAD, TIRES, AIR, NAVAL
- private static int IMP = Terrain.IMPASSIBLE;
- public static List<Integer> plainMoveCosts = Arrays.asList(1, 1, 1, 2,
1, IMP);
- public static List<Integer> riverMoveCosts = Arrays.asList(1, 1, IMP,
IMP, 1, IMP);
- public static List<Integer> mountainMoveCosts = Arrays.asList(3, 2, IMP,
IMP, 1, IMP);
- public static List<Integer> seaMoveCosts = Arrays.asList(IMP, IMP, IMP,
IMP, 1, 1);
+ private static final int IMP = Terrain.IMPASSIBLE;
+ public static final List<Integer> plainMoveCosts = Arrays.asList(1, 1,
1, 2, 1, IMP);
+ public static final List<Integer> riverMoveCosts = Arrays.asList(1, 1,
IMP, IMP, 1, IMP);
+ public static final List<Integer> mountainMoveCosts = Arrays.asList(3,
2, IMP, IMP, 1, IMP);
+ public static final List<Integer> seaMoveCosts = Arrays.asList(IMP, IMP,
IMP, IMP, 1, 1);

// Terrains
- private static Terrain plain = new Terrain(0, "plain", "plain", "", 0,
0, false, 0, plainMoveCosts);
- private static Terrain verticalRiver = new
Terrain(20, "river", "river", "", 0, -1, false, 0, riverMoveCosts);
- private static Terrain mountain = new
Terrain(17, "mountain", "mountain", "", 4, 2, false, 3, mountainMoveCosts);
- private static Terrain sea = new Terrain(SEA, "ocean", "ocean", "", 0,
-2, false, 0, seaMoveCosts);
+ private static final Terrain plain = new
Terrain(0, "plain", "plain", "", 0, 0, false, 0, plainMoveCosts);
+ private static final Terrain verticalRiver = new
Terrain(20, "river", "river", "", 0, -1, false, 0, riverMoveCosts);
+ private static final Terrain mountain = new
Terrain(17, "mountain", "mountain", "", 4, 2, false, 3, mountainMoveCosts);
+ private static final Terrain sea = new
Terrain(SEA, "ocean", "ocean", "", 0, -2, false, 0, seaMoveCosts);

// Units
- private static UnitStats infStats = new UnitStats(INF,
INF, "infantry", "", 3000, 3, 3, 10, UNIT_MAX_HP, MAX_UNIT_SUPPLIES, 0, 0,
true, false, false, false, true, false, false, null, ArmyBranch.LAND,
MOVE_INF, new Range(0, 0), "", SMG, 0, 0, 0);
- private static Unit infantry = new Unit(infStats);
- private static UnitStats mechStats = new UnitStats(MECH,
MECH, "mech", "", 3000, 3, 3, 10, UNIT_MAX_HP, MAX_UNIT_SUPPLIES, 0, 0,
true, false, false, false, true, false, false, null, ArmyBranch.LAND,
MOVE_MECH, new Range(0, 0), BAZOOKA, SMG, 0, 0, 0);
- private static Unit mech = new Unit(mechStats);
- private static UnitStats apcStats = new UnitStats(APC, APC, "apc", "",
8000, 5, 1, 10, UNIT_MAX_HP, MAX_UNIT_SUPPLIES, 3, 0, false, false, true,
true, true, false, false, Arrays.asList(MOVE_INF, MOVE_MECH),
ArmyBranch.LAND, MOVE_TREAD, new Range(1, 1), "", "", 0, 0, 1);
- private static Unit apc = new Unit(apcStats);
- private static UnitStats tankStats = new UnitStats(TANK,
TANK, "light_tank", "", 7000, 6, 3, 10, UNIT_MAX_HP, MAX_UNIT_SUPPLIES, 0,
0, false, false, false, false, true, false, false, null, ArmyBranch.LAND,
MOVE_TIRES, new Range(0, 0), TANK_CANNON, SMG, 0, 0, 0);
- private static Unit tank = new Unit(tankStats);
- private static UnitStats rocketStats = new UnitStats(ROCKETS,
ROCKETS, "rockets", "", 14000, 5, 1, 10, UNIT_MAX_HP, MAX_UNIT_SUPPLIES, 0,
0, false, false, false, false, true, false, false, null, ArmyBranch.LAND,
MOVE_TIRES, new Range(0, 0), ROCKET, "", 0, 0, 0);
- private static Unit rocket = new Unit(rocketStats);
- private static UnitStats artilleryStats = new UnitStats(ARTILLERY,
ARTILLERY, "artillery", "", 6000, 5, 1, 10, UNIT_MAX_HP, 50, 0, 0, false,
false, false, false, true, false, false, null, ArmyBranch.LAND, MOVE_TREAD,
new Range(0, 0), ART_CANNON, "", 0, 0, 0);
- private static Unit artillery = new Unit(artilleryStats);
+ private static final UnitStats infStats = new UnitStats(INF,
INF, "infantry", "", 3000, 3, 3, 10, UNIT_MAX_HP, MAX_UNIT_SUPPLIES, 0, 0,
true, false, true, false, false, false, null, null, null, ArmyBranch.LAND,
MOVE_INF, new Range(0, 0), "", SMG, 0, 0, 0);
+ private static final Unit infantry = new Unit(infStats);
+ private static final UnitStats mechStats = new UnitStats(MECH,
MECH, "mech", "", 3000, 3, 3, 10, UNIT_MAX_HP, MAX_UNIT_SUPPLIES, 0, 0,
true, false, true, false, false, false, null, null, null, ArmyBranch.LAND,
MOVE_MECH, new Range(0, 0), BAZOOKA, SMG, 0, 0, 0);
+ private static final Unit mech = new Unit(mechStats);
+ private static final UnitStats apcStats = new UnitStats(APC,
APC, "apc", "", 8000, 5, 1, 10, UNIT_MAX_HP, MAX_UNIT_SUPPLIES, 3, 0,
false, false, true, false, false, false, Arrays.asList("infantry", "mech"),
null, allUnits, ArmyBranch.LAND, MOVE_TREAD, new Range(1, 1), "", "", 0, 0,
1);
+ private static final Unit apc = new Unit(apcStats);
+ private static final UnitStats tankStats = new UnitStats(TANK,
TANK, "light_tank", "", 7000, 6, 3, 10, UNIT_MAX_HP, MAX_UNIT_SUPPLIES, 0,
0, false, false, true, false, false, false, null, null, null,
ArmyBranch.LAND, MOVE_TIRES, new Range(0, 0), TANK_CANNON, SMG, 0, 0, 0);
+ private static final Unit tank = new Unit(tankStats);
+ private static final UnitStats rocketStats = new UnitStats(ROCKETS,
ROCKETS, "rockets", "", 14000, 5, 1, 10, UNIT_MAX_HP, MAX_UNIT_SUPPLIES, 0,
0, false, false, true, false, false, false, null, null, null,
ArmyBranch.LAND, MOVE_TIRES, new Range(0, 0), ROCKET, "", 0, 0, 0);
+ private static final Unit rocket = new Unit(rocketStats);
+ private static final UnitStats artilleryStats = new UnitStats(ARTILLERY,
ARTILLERY, "artillery", "", 6000, 5, 1, 10, UNIT_MAX_HP, 50, 0, 0, false,
false, true, false, false, false, null, null, null, ArmyBranch.LAND,
MOVE_TREAD, new Range(0, 0), ART_CANNON, "", 0, 0, 0);
+ private static final Unit artillery = new Unit(artilleryStats);
+ private static final UnitStats carrierStats = new UnitStats(CARRIER,
CARRIER, "carrier", "", 25000, 5, 4, 10, UNIT_MAX_HP, 99, 2, 1, false,
false, true, false, false, true, allAirUnits, allAirUnits, null,
ArmyBranch.NAVAL, MOVE_NAVAL, new Range(0, 0), "", CARRIER_ANTI_AIR, 2, 0,
0);
+ private static final Unit carrier = new Unit(carrierStats);

// Weapons
- private static Weapon smg = new Weapon(SMG, "", new Range(1, 1),
Weapon.UNLIMITED_AMMO, false, ARMY_BRANCH_LAND_ONLY);
- private static Weapon bazooka = new Weapon(BAZOOKA, "", new Range(1, 1),
5, false, ARMY_BRANCH_LAND_ONLY);
- private static Weapon tankCannon = new Weapon(TANK_CANNON, "", new
Range(1, 1), 9, false, ARMY_BRANCH_LAND_ONLY);
- private static Weapon cannon = new Weapon(CANNON, "", new Range(2, 3),
9, false, ARMY_BRANCH_LAND_ONLY);
- private static Weapon rockets = new Weapon(ROCKET, "", new Range(3, 5),
6, false, ARMY_BRANCH_LAND_ONLY);
- private static Weapon artilleryCannon = new Weapon(ART_CANNON, "", new
Range(2, 3), 9, false, ARMY_BRANCH_LAND_ONLY);
+ private static final Weapon smg = new Weapon(SMG, "", new Range(1, 1),
Weapon.UNLIMITED_AMMO, false, ARMY_BRANCH_LAND_ONLY);
+ private static final Weapon bazooka = new Weapon(BAZOOKA, "", new
Range(1, 1), 5, false, ARMY_BRANCH_LAND_ONLY);
+ private static final Weapon tankCannon = new Weapon(TANK_CANNON, "", new
Range(1, 1), 9, false, ARMY_BRANCH_LAND_ONLY);
+ private static final Weapon cannon = new Weapon(CANNON, "", new Range(2,
3), 9, false, ARMY_BRANCH_LAND_ONLY);
+ private static final Weapon rockets = new Weapon(ROCKET, "", new
Range(3, 5), 6, false, ARMY_BRANCH_LAND_ONLY);
+ private static final Weapon artilleryCannon = new Weapon(ART_CANNON, "",
new Range(2, 3), 9, false, ARMY_BRANCH_LAND_ONLY);
+ private static final Weapon carrierAA = new Weapon(CARRIER_ANTI_AIR, "",
new Range(1, 1), 4, false, ARMY_BRANCH_AIR_ONLY);

// City
private static City base = new City(0, 0, "road", "road", "base", "", 0,
0, plainMoveCosts, 1, true,
- cityRoadConnection, ARMY_BRANCH_LAND_ONLY, Arrays.asList(INF, MECH),
null, 20, CITY_HEAL_RATE, 0, true);
+ cityRoadConnection, ARMY_BRANCH_LAND_ONLY, infAndMech, null, null, 20,
CITY_HEAL_RATE, 0, true);

private static City factory = new City(1,
1, "road", "road", "factory", "", 0, 0, plainMoveCosts, 1, true,
- cityRoadConnection, ARMY_BRANCH_LAND_ONLY, Arrays.asList(INF, MECH),
allLandUnits, 20, CITY_HEAL_RATE, 0, true);
+ cityRoadConnection, ARMY_BRANCH_LAND_ONLY, infAndMech, allLandUnits,
null, 20, CITY_HEAL_RATE, 0, true);

private static City hq = new City(4, 4, "road", "road", "hq", "", 0, 0,
plainMoveCosts, 1, true,
- cityRoadConnection, ARMY_BRANCH_LAND_ONLY, Arrays.asList(INF, MECH),
null, 20, CITY_HEAL_RATE, 0, true);
+ cityRoadConnection, ARMY_BRANCH_LAND_ONLY, infAndMech, null, null, 20,
CITY_HEAL_RATE, 0, true);

private static City airport = new City(AIRPORT,
AIRPORT, "road", "road", "airport", "", 0, 0, plainMoveCosts, 1, true,
- cityRoadConnection, ARMY_BRANCH_AIR_ONLY, Arrays.asList(INF, MECH),
allAirUnits, 20, CITY_HEAL_RATE, 0, true);
+ cityRoadConnection, ARMY_BRANCH_AIR_ONLY, infAndMech, allAirUnits,
null, 20, CITY_HEAL_RATE, 0, true);

private static City port = new City(PORT,
PORT, "road", "road", "port", "", 0, 0, plainMoveCosts, 1, true,
- cityRoadConnection, ARMY_BRANCH_NAVAL_ONLY, Arrays.asList(INF, MECH),
allNavalUnits, 20, CITY_HEAL_RATE, 0, true);
+ cityRoadConnection, ARMY_BRANCH_NAVAL_ONLY, infAndMech, allNavalUnits,
null, 20, CITY_HEAL_RATE, 0, true);

private static City silo = new City(5,
5, "road", "road", "missle_silo", "", 0, 0, plainMoveCosts, 1, true,
- cityRoadConnection, null, null, null, 20, CITY_HEAL_RATE, 0, true);
+ cityRoadConnection, null, null, null, infAndMech, 20, CITY_HEAL_RATE,
0, true);

// CO
private static CO andy = new BasicCO("andy", new COStyle("ORANGE_STAR",
Color.orange, 0, "orange"), "", "", 0, "", "", "", Power.NONE,
Power.NONE, "", EMPTY_ARR, EMPTY_ARR, EMPTY_ARR);
@@ -149,6 +157,7 @@
WeaponFactory.addWeapon(tankCannon);
WeaponFactory.addWeapon(rockets);
WeaponFactory.addWeapon(artilleryCannon);
+ WeaponFactory.addWeapon(carrierAA);

UnitFactory.addUnit(infantry);
UnitFactory.addUnit(mech);
@@ -156,6 +165,7 @@
UnitFactory.addUnit(tank);
UnitFactory.addUnit(artillery);
UnitFactory.addUnit(rocket);
+ UnitFactory.addUnit(carrier);

CityFactory.addCity(base);
CityFactory.addCity(factory);
=======================================
--- /trunk/v2/test/com/customwars/client/model/gameobject/CityTest.java Fri
Feb 18 15:15:52 2011
+++ /trunk/v2/test/com/customwars/client/model/gameobject/CityTest.java Mon
Mar 14 07:18:14 2011
@@ -138,13 +138,40 @@

@Test
// The factory produces Ground units
- // our Infantry is armybranch Ground so the factory can build this unit.
+ // our units are ground units so the factory can build these unit.
+ // A Carrier cannot be build by a factory.
public void testBuildingUnit() {
City factory = CityFactory.getCity(TestData.FACTORY);
map.getTile(4, 0).setTerrain(factory);
factory.setOwner(player1);

+ Unit inf = UnitFactory.getUnit(TestData.INF);
+ Unit mech = UnitFactory.getUnit(TestData.MECH);
+ Unit artillery = UnitFactory.getUnit(TestData.ARTILLERY);
+ Unit rockets = UnitFactory.getUnit(TestData.ROCKETS);
+ Unit apc = UnitFactory.getUnit(TestData.APC);
+ Assert.assertTrue(factory.canBuild());
+ Assert.assertTrue(factory.canBuild(inf));
+ Assert.assertTrue(factory.canBuild(mech));
+ Assert.assertTrue(factory.canBuild(artillery));
+ Assert.assertTrue(factory.canBuild(rockets));
+ Assert.assertTrue(factory.canBuild(apc));
+
+ Unit carrier = UnitFactory.getUnit(TestData.CARRIER);
+ Assert.assertFalse(factory.canBuild(carrier));
+ }
+
+ @Test
+ public void testLaunchRocket() {
+ City silo = CityFactory.getCity(TestData.MISSILE_SILO);
+ map.getTile(4, 0).setTerrain(silo);
+ silo.setOwner(player1);
+
Unit unit = UnitFactory.getUnit(TestData.INF);
- Assert.assertTrue(factory.canBuild(unit));
+ Assert.assertTrue(silo.canLaunchRocket());
+ Assert.assertTrue(silo.canLaunchRocket(unit));
+
+ Unit apc = UnitFactory.getUnit(TestData.APC);
+ Assert.assertFalse(silo.canLaunchRocket(apc));
}
}
=======================================
---
/trunk/v2/test/com/customwars/client/model/gameobject/UnitXStreamTest.java
Sun Jan 3 19:18:44 2010
+++
/trunk/v2/test/com/customwars/client/model/gameobject/UnitXStreamTest.java
Mon Mar 14 07:18:14 2011
@@ -13,8 +13,6 @@

/**
* Tests regarding reading unit+weapon data from xml
- *
- * @author stefan
*/
public class UnitXStreamTest {
private static final XStream xStream = new XStream(new DomDriver());
@@ -23,13 +21,18 @@
public static void beforeAllTests() {
TestData.storeTestData();

- // When we find a unit tag, create a Unit object
- xStream.alias("unit", Unit.class);
- XStreamUtil.useReflectionFor(xStream, Unit.class);
+ // When we find a unit tag, create a UnitStats object
+ xStream.alias("unit", UnitStats.class);
+ XStreamUtil.useReflectionFor(xStream, UnitStats.class);
+
// id, imgRowID and name are read from attributes, not elements
+ XStreamUtil.useReflectionFor(xStream, UnitStats.class);
xStream.useAttributeFor(UnitStats.class, "unitID");
xStream.useAttributeFor(UnitStats.class, "imgRowID");
xStream.useAttributeFor(UnitStats.class, "name");
+
+ xStream.alias("unitID", String.class);
+ xStream.alias("id", String.class);
}

@Before
@@ -44,22 +47,21 @@

@Test
public void validUnitXml() {
- String unitXml = "<unit>" +
- "<stats unitID='1' name='Inf'>" +
- " <description></description>" +
- " <price>3000</price>" +
- " <movement>3</movement>" +
- " <vision>5</vision>" +
- " <maxHp>20</maxHp>" +
- " <maxSupplies>20</maxSupplies>" +
- " <suppliesPerTurn>0</suppliesPerTurn>" +
- " <canCapture>true</canCapture>" +
- " <armyBranch>LAND</armyBranch>" +
- " <movementType>0</movementType>" +
- "</stats>" +
- "</unit>";
- Unit unit = (Unit) xStream.fromXML(unitXml);
- UnitFactory.addUnit(unit);
+ String unitXml =
+ "<unit unitID='1' name='Inf'>" +
+ " <description></description>" +
+ " <price>3000</price>" +
+ " <movement>3</movement>" +
+ " <vision>5</vision>" +
+ " <maxHp>20</maxHp>" +
+ " <maxSupplies>20</maxSupplies>" +
+ " <suppliesPerTurn>0</suppliesPerTurn>" +
+ " <canCapture>true</canCapture>" +
+ " <armyBranch>LAND</armyBranch>" +
+ " <movementType>0</movementType>" +
+ "</unit>";
+ UnitStats unitStats = (UnitStats) xStream.fromXML(unitXml);
+ UnitFactory.addUnit(new Unit(unitStats));
Unit unitCopy = UnitFactory.getUnit(1);

Assert.assertEquals(1, unitCopy.getStats().getID());
@@ -75,15 +77,14 @@
* true doesn't matter
*/
public void unitFromXMLStringCaseCheck() {
- String unitXml = "<unit>" +
- "<stats unitID='1' name='Inf'>" +
- " <canCapture>TrUe</canCapture>" +
- " <armyBranch>LAND</armyBranch>" +
- " <description></description>" +
- "</stats>" +
- "</unit>";
- Unit unit = (Unit) xStream.fromXML(unitXml);
- UnitFactory.addUnit(unit);
+ String unitXml =
+ "<unit unitID='1' name='Inf'>" +
+ " <canCapture>TrUe</canCapture>" +
+ " <armyBranch>LAND</armyBranch>" +
+ " <description></description>" +
+ "</unit>";
+ UnitStats unitStats = (UnitStats) xStream.fromXML(unitXml);
+ UnitFactory.addUnit(new Unit(unitStats));
Unit unitCopy = UnitFactory.getUnit(1);

Assert.assertTrue(unitCopy.getStats().canCapture());

Reply all
Reply to author
Forward
0 new messages