Leveraged PlayerType.

This commit is contained in:
Michael Vehrs 2008-01-12 15:35:57 +00:00
parent 1c290f0a7b
commit cb396c3a37
9 changed files with 145 additions and 47 deletions

View File

@ -648,4 +648,20 @@
<arg value="${localeKey}" />
</java>
</target>
<target name="pmd">
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask"
classpath="./pmd-4.1/lib/pmd-4.1.jar"/>
<pmd shortFilenames="true">
<ruleset>basic</ruleset>
<ruleset>imports</ruleset>
<ruleset>optimizations</ruleset>
<ruleset>unusedcode</ruleset>
<formatter type="html" toFile="pmd_report.html" linkPrefix="http://pmd.sourceforge.net/xref/"/>
<fileset dir="src">
<include name="**/*.java"/>
</fileset>
</pmd>
</target>
</project>

View File

@ -2573,7 +2573,7 @@ public final class InGameController implements NetworkConstants {
if (skillName == null) {
canvas.errorMessage("indianSettlement.noMoreSkill");
} else if (!unit.getType().canBeUpgraded(skill, UnitType.NATIVES)) {
} else if (!unit.getType().canBeUpgraded(skill, UnitType.UpgradeType.NATIVES)) {
canvas.showInformationMessage("indianSettlement.cantLearnSkill",
new String[][] { {"%unit%", unit.getName()}, {"%skill%", skillName} });
} else {

View File

@ -268,7 +268,7 @@ public final class DragListener extends MouseAdapter {
separatorNeeded = false;
}
if (tempUnit.getType().getDowngrade(UnitType.CLEAR_SKILL) != null) {
if (tempUnit.getType().getDowngrade(UnitType.DowngradeType.CLEAR_SKILL) != null) {
menuItem = new JMenuItem(Messages.message("clearSpeciality"));
menuItem.setActionCommand(String.valueOf(UnitLabel.CLEAR_SPECIALITY));
menuItem.addActionListener(unitLabel);

View File

@ -345,7 +345,7 @@ public final class ReportUnitPanel extends JPanel implements ActionListener {
switch (reportType) {
case CARGO:
for (UnitType unitType : FreeCol.getSpecification().getUnitTypeList()) {
if (!unitType.hasAbility("model.ability.undead") &&
if (unitType.isAvailableTo(player.getPlayerType()) &&
(unitType.hasAbility("model.ability.carryUnits") ||
unitType.hasAbility("model.ability.carryGoods"))) {
unitPanel.add(createUnitTypeLabel(unitType, Role.DEFAULT, getCount(others, unitType)));
@ -354,7 +354,7 @@ public final class ReportUnitPanel extends JPanel implements ActionListener {
break;
case NAVAL:
for (UnitType unitType : FreeCol.getSpecification().getUnitTypeList()) {
if (!unitType.hasAbility("model.ability.undead") &&
if (unitType.isAvailableTo(player.getPlayerType()) &&
unitType.hasAbility("model.ability.navalUnit")) {
unitPanel.add(createUnitTypeLabel(unitType, Role.DEFAULT, getCount(others, unitType)));
}
@ -365,7 +365,7 @@ public final class ReportUnitPanel extends JPanel implements ActionListener {
int dragoonCount = 0;
List<UnitType> unitTypes = new ArrayList<UnitType>();
for (UnitType unitType : FreeCol.getSpecification().getUnitTypeList()) {
if (!unitType.hasAbility("model.ability.undead") &&
if (unitType.isAvailableTo(player.getPlayerType()) &&
!unitType.hasAbility("model.ability.navalUnit") &&
(unitType.hasAbility("model.ability.expertSoldier") ||
unitType.getOffence() > 0)) {

View File

@ -38,6 +38,8 @@ import net.sf.freecol.client.gui.i18n.Messages;
import net.sf.freecol.common.model.Map.Direction;
import net.sf.freecol.common.model.Map.Position;
import net.sf.freecol.common.model.Player.Stance;
import net.sf.freecol.common.model.UnitType.DowngradeType;
import net.sf.freecol.common.model.UnitType.UpgradeType;
import net.sf.freecol.common.model.TradeRoute.Stop;
import net.sf.freecol.common.util.EmptyIterator;
import net.sf.freecol.common.util.Utils;
@ -702,7 +704,7 @@ public class Unit extends FreeColGameObject implements Features, Locatable, Loca
*
*/
public static UnitType getUnitTypeTeaching(UnitType typeTeacher, UnitType typeStudent) {
if (typeStudent.canBeUpgraded(typeTeacher, UnitType.EDUCATION)) {
if (typeStudent.canBeUpgraded(typeTeacher, UpgradeType.EDUCATION)) {
return typeTeacher;
} else {
return typeStudent.getEducationUnit(0);
@ -3655,7 +3657,7 @@ public class Unit extends FreeColGameObject implements Features, Locatable, Loca
if (enemyUnit.isUndead()) {
setType(enemyUnit.getType());
} else {
UnitType downgrade = getType().getDowngrade(UnitType.CAPTURE);
UnitType downgrade = getType().getDowngrade(DowngradeType.CAPTURE);
if (downgrade != null) {
setType(downgrade);
}
@ -3700,7 +3702,7 @@ public class Unit extends FreeColGameObject implements Features, Locatable, Loca
}
} else {
// be downgraded as a result of combat
UnitType downgrade = getType().getDowngrade(UnitType.DEMOTION);
UnitType downgrade = getType().getDowngrade(DowngradeType.DEMOTION);
if (downgrade != null) {
setType(downgrade);
messageType = ModelMessage.UNIT_DEMOTED;
@ -3966,7 +3968,7 @@ public class Unit extends FreeColGameObject implements Features, Locatable, Loca
if (isUndead()) {
u.setType(getType());
} else {
UnitType downgrade = u.getType().getDowngrade(UnitType.CAPTURE);
UnitType downgrade = u.getType().getDowngrade(DowngradeType.CAPTURE);
if (downgrade != null) {
u.setType(downgrade);
}
@ -4026,7 +4028,7 @@ public class Unit extends FreeColGameObject implements Features, Locatable, Loca
* to the UnitType specified for clearing
*/
public void clearSpeciality() {
UnitType newType = unitType.getDowngrade(UnitType.CLEAR_SKILL);
UnitType newType = unitType.getDowngrade(DowngradeType.CLEAR_SKILL);
if (newType != null) {
setType(newType);
}
@ -4096,7 +4098,7 @@ public class Unit extends FreeColGameObject implements Features, Locatable, Loca
}
UnitType learnType = FreeCol.getSpecification().getExpertForProducing(goodsType);
if (learnType != null && unitType.canBeUpgraded(learnType, UnitType.EXPERIENCE)) {
if (learnType != null && unitType.canBeUpgraded(learnType, UpgradeType.EXPERIENCE)) {
logger.finest("About to call getRandom for experience");
int random = getGame().getModelController().getRandom(getId() + "experience", 5000);
if (random < Math.min(experience, 200)) {

View File

@ -22,6 +22,7 @@ package net.sf.freecol.common.model;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@ -33,13 +34,14 @@ import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import net.sf.freecol.FreeCol;
import net.sf.freecol.common.model.Player.PlayerType;
public final class UnitType extends BuildableType {
public static int EDUCATION = 0, NATIVES = 1, EXPERIENCE = 2,
LOST_CITY = 3, PROMOTION = 4, NUMBER_OF_UPGRADE_TYPES = 5;
public static enum UpgradeType { EDUCATION, NATIVES, EXPERIENCE,
LOST_CITY, PROMOTION }
public static int CLEAR_SKILL = 0, DEMOTION = 1, CAPTURE = 2, NUMBER_OF_DOWNGRADE_TYPES = 3;
public static enum DowngradeType { CLEAR_SKILL, DEMOTION, CAPTURE }
public static final EquipmentType[] NO_EQUIPMENT = new EquipmentType[0];
@ -113,6 +115,12 @@ public final class UnitType extends BuildableType {
*/
private int scoreValue;
/**
* Describe availableTo here.
*/
private EnumMap<PlayerType, Boolean> availableTo =
new EnumMap<PlayerType, Boolean>(PlayerType.class);
/**
* Describe education here.
*/
@ -389,22 +397,38 @@ public final class UnitType extends BuildableType {
this.pathImage = newPathImage;
}
/**
* Returns true if the UnitType is available to the given
* PlayerType.
*
* @param playerType a <code>PlayerType</code> value
* @return a <code>boolean</code> value
*/
public boolean isAvailableTo(PlayerType playerType) {
return availableTo.get(playerType);
}
public UnitType getPromotion() {
Iterator<Entry<String, Upgrade>> iterator = upgrades.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, Upgrade> pair = iterator.next();
if (pair.getValue().asResultOf[PROMOTION]) {
if (pair.getValue().asResultOf.get(UpgradeType.PROMOTION)) {
return FreeCol.getSpecification().getUnitType(pair.getKey());
}
}
return null;
}
public UnitType getDowngrade(int downgradeType) {
/**
* Describe <code>getDowngrade</code> method here.
*
* @return an <code>UnitType</code> value
*/
public UnitType getDowngrade(DowngradeType downgradeType) {
Iterator<Entry<String, Downgrade>> iterator = downgrades.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, Downgrade> pair = iterator.next();
if (pair.getValue().asResultOf[downgradeType]) {
if (pair.getValue().asResultOf.get(downgradeType)) {
return FreeCol.getSpecification().getUnitType(pair.getKey());
}
}
@ -418,12 +442,12 @@ public final class UnitType extends BuildableType {
* the given means of education.
*
* @param unitType the UnitType to learn
* @param educationType an <code>int</code> value
* @param educationType an <code>UpgradeType</code> value
* @return <code>true</code> if can learn the given UnitType
*/
public boolean canBeUpgraded(UnitType unitType, int educationType) {
public boolean canBeUpgraded(UnitType unitType, UpgradeType educationType) {
Upgrade upgrade = upgrades.get(unitType.getId());
return upgrade != null && upgrade.asResultOf[educationType];
return upgrade != null && upgrade.asResultOf.get(educationType);
}
/**
@ -437,7 +461,7 @@ public final class UnitType extends BuildableType {
ArrayList<UnitType> unitTypes = new ArrayList<UnitType>();
while (iterator.hasNext()) {
Entry<String, Upgrade> pair = iterator.next();
if (pair.getValue().asResultOf[LOST_CITY]) {
if (pair.getValue().asResultOf.get(UpgradeType.LOST_CITY)) {
unitTypes.add(FreeCol.getSpecification().getUnitType(pair.getKey()));
}
}
@ -533,21 +557,27 @@ public final class UnitType extends BuildableType {
Upgrade upgrade = new Upgrade();
String educationUnit = in.getAttributeValue(null, "unit");
upgrade.turnsToLearn = getAttribute(in, "turnsToLearn", UNDEFINED);
upgrade.asResultOf[EDUCATION] = getAttribute(in, "learnInSchool", true);
upgrade.asResultOf[NATIVES] = getAttribute(in, "asResultOfNatives", false);
upgrade.asResultOf[EXPERIENCE] = getAttribute(in, "asResultOfExperience", false);
upgrade.asResultOf[LOST_CITY] = getAttribute(in, "learnInLostCity", false);
upgrade.asResultOf[PROMOTION] = getAttribute(in, "promotion", false);
upgrade.asResultOf.put(UpgradeType.EDUCATION, getAttribute(in, "learnInSchool", true));
upgrade.asResultOf.put(UpgradeType.NATIVES, getAttribute(in, "asResultOfNatives", false));
upgrade.asResultOf.put(UpgradeType.EXPERIENCE, getAttribute(in, "asResultOfExperience", false));
upgrade.asResultOf.put(UpgradeType.LOST_CITY, getAttribute(in, "learnInLostCity", false));
upgrade.asResultOf.put(UpgradeType.PROMOTION, getAttribute(in, "promotion", false));
upgrades.put(educationUnit, upgrade);
in.nextTag(); // close this element
} else if ("downgrade".equals(nodeName)) {
Downgrade downgrade = new Downgrade();
String educationUnit = in.getAttributeValue(null, "unit");
downgrade.asResultOf[CLEAR_SKILL] = getAttribute(in, "clearSkill", false);
downgrade.asResultOf[DEMOTION] = getAttribute(in, "demotion", false);
downgrade.asResultOf[CAPTURE] = getAttribute(in, "capture", false);
downgrade.asResultOf.put(DowngradeType.CLEAR_SKILL, getAttribute(in, "clearSkill", false));
downgrade.asResultOf.put(DowngradeType.DEMOTION, getAttribute(in, "demotion", false));
downgrade.asResultOf.put(DowngradeType.CAPTURE, getAttribute(in, "capture", false));
downgrades.put(educationUnit, downgrade);
in.nextTag(); // close this element
} else if ("available-to".equals(nodeName)) {
for (PlayerType playerType : PlayerType.values()) {
boolean value = getAttribute(in, playerType.toString().toLowerCase(), true);
availableTo.put(playerType, value);
}
in.nextTag(); // close this element
} else if (Modifier.getXMLElementTagName().equals(nodeName)) {
Modifier modifier = new Modifier(in); // Modifier close the element
if (modifier.getSource() == null) {
@ -635,14 +665,16 @@ public final class UnitType extends BuildableType {
private class Upgrade {
protected int turnsToLearn;
protected boolean[] asResultOf = new boolean[NUMBER_OF_UPGRADE_TYPES];
protected EnumMap<UpgradeType, Boolean> asResultOf =
new EnumMap<UpgradeType, Boolean>(UpgradeType.class);
public boolean canBeTaught() {
return asResultOf[EDUCATION] && turnsToLearn > 0;
return asResultOf.get(UpgradeType.EDUCATION) && turnsToLearn > 0;
}
}
private class Downgrade {
protected boolean asResultOf[] = new boolean[NUMBER_OF_DOWNGRADE_TYPES];;
protected EnumMap<DowngradeType, Boolean> asResultOf =
new EnumMap<DowngradeType, Boolean>(DowngradeType.class);
}
}

View File

@ -499,6 +499,7 @@
<unit-types>
<unit-type id="model.unit.freeColonist" offence="0" defence="1" movement="3" lineOfSight="1"
scoreValue="3" skill="0" recruitProbability="20" pathImage="foot">
<available-to native="false"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
<ability id="model.ability.canBeCaptured" value="true"/>
@ -530,6 +531,7 @@
<unit-type id="model.unit.expertFarmer" offence="0" defence="1" movement="3" lineOfSight="1" price="1100"
skill="1" recruitProbability="1" expert-production="model.goods.Food"
scoreValue="4" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -539,6 +541,7 @@
<unit-type id="model.unit.expertFisherman" offence="0" defence="1" movement="3" lineOfSight="1" price="1000"
skill="1" recruitProbability="1" expert-production="model.goods.Fish"
scoreValue="4" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -548,6 +551,7 @@
<unit-type id="model.unit.expertFurTrapper" offence="0" defence="1" movement="3" lineOfSight="1"
skill="1" expert-production="model.goods.Furs"
scoreValue="4" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -557,6 +561,7 @@
<unit-type id="model.unit.expertSilverMiner" offence="0" defence="1" movement="3" lineOfSight="1" price="900"
skill="1" recruitProbability="1" expert-production="model.goods.Silver"
scoreValue="4" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -566,6 +571,7 @@
<unit-type id="model.unit.expertLumberJack" offence="0" defence="1" movement="3" lineOfSight="1" price="700"
skill="1" recruitProbability="1" expert-production="model.goods.Lumber"
scoreValue="4" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -575,6 +581,7 @@
<unit-type id="model.unit.expertOreMiner" offence="0" defence="1" movement="3" lineOfSight="1" price="600"
skill="1" recruitProbability="1" expert-production="model.goods.Ore"
scoreValue="4" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -584,6 +591,7 @@
<unit-type id="model.unit.masterSugarPlanter" offence="0" defence="1" movement="3" lineOfSight="1"
skill="2" expert-production="model.goods.Sugar"
scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -593,6 +601,7 @@
<unit-type id="model.unit.masterCottonPlanter" offence="0" defence="1" movement="3" lineOfSight="1"
skill="2" expert-production="model.goods.Cotton"
scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -602,6 +611,7 @@
<unit-type id="model.unit.masterTobaccoPlanter" offence="0" defence="1" movement="3" lineOfSight="1"
skill="2" expert-production="model.goods.Tobacco"
scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -611,6 +621,7 @@
<unit-type id="model.unit.firebrandPreacher" offence="0" defence="1" movement="3" lineOfSight="1" price="1500"
skill="3" recruitProbability="1" expert-production="model.goods.Crosses"
scoreValue="6" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -620,6 +631,7 @@
<unit-type id="model.unit.elderStatesman" offence="0" defence="1" movement="3" lineOfSight="1" price="1900"
skill="3" recruitProbability="1" expert-production="model.goods.Bells"
scoreValue="6" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -629,6 +641,7 @@
<unit-type id="model.unit.masterCarpenter" offence="0" defence="1" movement="3" lineOfSight="1" price="1000"
skill="1" recruitProbability="1" expert-production="model.goods.Hammers"
scoreValue="4" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -638,6 +651,7 @@
<unit-type id="model.unit.masterDistiller" offence="0" defence="1" movement="3" lineOfSight="1" price="1100"
skill="2" recruitProbability="1" expert-production="model.goods.Rum"
scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -647,6 +661,7 @@
<unit-type id="model.unit.masterWeaver" offence="0" defence="1" movement="3" lineOfSight="1" price="1300"
skill="2" recruitProbability="1" expert-production="model.goods.Cloth"
scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -656,6 +671,7 @@
<unit-type id="model.unit.masterTobacconist" offence="0" defence="1" movement="3" lineOfSight="1" price="1200"
skill="2" recruitProbability="1" expert-production="model.goods.Cigars"
scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -665,6 +681,7 @@
<unit-type id="model.unit.masterFurTrader" offence="0" defence="1" movement="3" lineOfSight="1" price="950"
skill="2" recruitProbability="1" expert-production="model.goods.Coats"
scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -674,6 +691,7 @@
<unit-type id="model.unit.masterBlacksmith" offence="0" defence="1" movement="3" lineOfSight="1" price="1050"
skill="2" recruitProbability="1" expert-production="model.goods.Tools"
scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -683,6 +701,7 @@
<unit-type id="model.unit.masterGunsmith" offence="0" defence="1" movement="3" lineOfSight="1" price="850"
skill="2" recruitProbability="1" expert-production="model.goods.Muskets"
scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -690,16 +709,18 @@
<modifier id="model.goods.Muskets" type="multiplicative" value="2"/>
</unit-type>
<unit-type id="model.unit.seasonedScout" offence="0" defence="1" movement="3" lineOfSight="1"
skill="1" recruitProbability="1" clearSpeciality="model.unit.freeColonist"
scoreValue="4" pathImage="foot">
skill="1" recruitProbability="1" scoreValue="4" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
<ability id="model.ability.canBeCaptured" value="true"/>
<ability id="model.ability.expertScout" value="true"/>
</unit-type>
<unit-type id="model.unit.hardyPioneer" offence="0" defence="1" movement="3" lineOfSight="1" price="1100"
skill="1" recruitProbability="1" clearSpeciality="model.unit.freeColonist"
scoreValue="4" pathImage="foot">
skill="1" recruitProbability="1" scoreValue="4" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
<ability id="model.ability.canBeCaptured" value="true"/>
@ -707,6 +728,7 @@
</unit-type>
<unit-type id="model.unit.veteranSoldier" offence="0" defence="1" movement="3" lineOfSight="1" price="2000"
skill="2" recruitProbability="1" scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist" capture="true"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -716,8 +738,9 @@
<upgrade id="model.unit.colonialRegular" promotion="true"/>
</unit-type>
<unit-type id="model.unit.jesuitMissionary" offence="0" defence="1" movement="3" lineOfSight="1" price="1400"
skill="3" recruitProbability="1" clearSpeciality="model.unit.freeColonist"
scoreValue="5" pathImage="foot">
skill="3" recruitProbability="1" scoreValue="5" pathImage="foot">
<available-to native="false"/>
<downgrade unit="model.unit.freeColonist" capture="true"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
<ability id="model.ability.canBeCaptured" value="true"/>
@ -725,6 +748,7 @@
</unit-type>
<unit-type id="model.unit.indenturedServant" offence="0" defence="1" movement="3" lineOfSight="1"
skill="-1" recruitProbability="20" scoreValue="2" pathImage="foot">
<available-to native="false"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
<ability id="model.ability.canBeCaptured" value="true"/>
@ -751,6 +775,7 @@
</unit-type>
<unit-type id="model.unit.pettyCriminal" offence="0" defence="1" movement="3" lineOfSight="1"
skill="-2" recruitProbability="20" scoreValue="1" pathImage="foot">
<available-to native="false"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
<ability id="model.ability.canBeCaptured" value="true"/>
@ -768,6 +793,7 @@
</unit-type>
<unit-type id="model.unit.indianConvert" offence="0" defence="1" movement="3" lineOfSight="1"
scoreValue="3" skill="0" pathImage="foot">
<available-to native="false"/>
<ability id="model.ability.convert" value="true"/>
<modifier id="model.goods.Food" type="additive" value="1"/>
<modifier id="model.goods.Sugar" type="additive" value="1"/>
@ -787,6 +813,7 @@
<upgrade unit="model.unit.freeColonist" learnInSchool="false"/>
</unit-type>
<unit-type id="model.unit.brave" offence="1" defence="1" movement="3" lineOfSight="1" space="1">
<available-to colonial="false" rebel="false" independent="false" royal="false" undead="false" native="true"/>
<ability id="model.ability.carryGoods" value="true"/>
<ability id="model.ability.bornInIndianSettlement" value="true"/>
<ability id="model.ability.pillageUnprotectedColony" value="true"/>
@ -796,6 +823,7 @@
</unit-type>
<unit-type id="model.unit.colonialRegular" offence="3" defence="3" movement="3" lineOfSight="1"
pathImage="foot">
<available-to colonial="false" rebel="true" independent="true" royal="false" undead="false" native="false"/>
<downgrade unit="model.unit.freeColonist" capture="true"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -805,6 +833,7 @@
<required-ability id="model.ability.independenceDeclared"/>
</unit-type>
<unit-type id="model.unit.kingsRegular" offence="4" defence="4" movement="3" lineOfSight="1">
<available-to colonial="false" rebel="false" independent="false" royal="true" undead="false" native="false"/>
<downgrade unit="model.unit.freeColonist" capture="true"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
@ -814,6 +843,7 @@
</unit-type>
<unit-type id="model.unit.caravel" offence="0" defence="2" movement="12" lineOfSight="1" space="2"
spaceTaken="24" hitPoints="6" price="1000" pathImage="naval" scoreValue="3">
<available-to native="false"/>
<required-goods id="model.goods.Hammers" value="128"/>
<required-goods id="model.goods.Tools" value="40"/>
<required-ability id="model.ability.buildShips"/>
@ -823,6 +853,7 @@
</unit-type>
<unit-type id="model.unit.frigate" offence="16" defence="16" movement="18" lineOfSight="2" space="4"
spaceTaken="32" hitPoints="6" price="5000" pathImage="naval" scoreValue="6">
<available-to native="false"/>
<required-goods id="model.goods.Hammers" value="512"/>
<required-goods id="model.goods.Tools" value="200"/>
<required-ability id="model.ability.buildShips"/>
@ -833,6 +864,7 @@
</unit-type>
<unit-type id="model.unit.galleon" offence="0" defence="10" movement="18" lineOfSight="2" space="6"
spaceTaken="64" hitPoints="6" price="3000" pathImage="naval" scoreValue="5">
<available-to native="false"/>
<required-goods id="model.goods.Hammers" value="320"/>
<required-goods id="model.goods.Tools" value="100"/>
<required-ability id="model.ability.buildShips"/>
@ -842,6 +874,7 @@
</unit-type>
<unit-type id="model.unit.manOWar" offence="24" defence="24" movement="18" lineOfSight="2" space="6"
spaceTaken="64" hitPoints="6" pathImage="naval" scoreValue="8">
<available-to colonial="false" rebel="true" independent="true" royal="true" undead="false" native="false"/>
<required-goods id="model.goods.Hammers" value="1024"/>
<required-goods id="model.goods.Tools" value="300"/>
<required-ability id="model.ability.buildShips"/>
@ -853,6 +886,7 @@
</unit-type>
<unit-type id="model.unit.merchantman" offence="0" defence="6" movement="15" lineOfSight="1" space="4"
spaceTaken="32" hitPoints="6" price="2000" pathImage="naval" scoreValue="4">
<available-to native="false"/>
<required-goods id="model.goods.Hammers" value="192"/>
<required-goods id="model.goods.Tools" value="80"/>
<required-ability id="model.ability.buildShips"/>
@ -862,6 +896,7 @@
</unit-type>
<unit-type id="model.unit.privateer" offence="8" defence="8" movement="24" lineOfSight="2" space="2"
spaceTaken="24" hitPoints="6" price="2000" pathImage="naval" scoreValue="4">
<available-to native="false"/>
<required-goods id="model.goods.Hammers" value="256"/>
<required-goods id="model.goods.Tools" value="120"/>
<required-ability id="model.ability.buildShips"/>
@ -873,6 +908,7 @@
</unit-type>
<unit-type id="model.unit.artillery" offence="7" defence="5" movement="3" lineOfSight="1"
price="500" increasingPrice="100" pathImage="wagon" scoreValue="2">
<available-to native="false"/>
<required-goods id="model.goods.Hammers" value="192"/>
<required-goods id="model.goods.Tools" value="40"/>
<required-ability id="model.ability.buildArtillery"/>
@ -881,38 +917,47 @@
</unit-type>
<unit-type id="model.unit.damagedArtillery" offence="5" defence="3" movement="3"
scoreValue="1" lineOfSight="1" pathImage="wagon">
<available-to native="false"/>
<ability id="model.ability.bombard" value="true"/>
</unit-type>
<unit-type id="model.unit.treasureTrain" offence="0" defence="0" movement="3"
scoreValue="1" lineOfSight="1" spaceTaken="6" pathImage="wagon">
<available-to native="false"/>
<ability id="model.ability.carryTreasure" value="true"/>
<ability id="model.ability.canBeCaptured" value="true"/>
</unit-type>
<unit-type id="model.unit.wagonTrain" offence="0" defence="1" movement="6"
scoreValue="1" lineOfSight="1" spaceTaken="12" space="2"
pathImage="wagon">
<available-to native="false"/>
<required-goods id="model.goods.Hammers" value="40"/>
<ability id="model.ability.carryGoods" value="true"/>
<ability id="model.ability.canBeCaptured" value="true"/>
</unit-type>
<unit-type id="model.unit.milkmaid" offence="0" defence="1" movement="3" lineOfSight="1"
expert-production="food" pathImage="foot">
<available-to native="false"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
<ability id="model.ability.canBeCaptured" value="true"/>
</unit-type>
<unit-type id="model.unit.revenger" offence="666" defence="666" movement="18" lineOfSight="3" pathImage="foot">
<ability id="model.ability.undead" value="true"/>
<ability id="model.ability.multipleAttacks" value="true"/>
<unit-type id="model.unit.revenger" offence="666" defence="666" movement="18" lineOfSight="3"
pathImage="foot">
<available-to colonial="false" rebel="false" independent="false" royal="false" undead="true" native="false"/>
<ability id="model.ability.undead" value="true"/>
<ability id="model.ability.multipleAttacks" value="true"/>
</unit-type>
<unit-type id="model.unit.flyingDutchman" offence="666" defence="666" movement="36" lineOfSight="3" space="6" hitPoints="6" pathImage="naval">
<unit-type id="model.unit.flyingDutchman" offence="666" defence="666" movement="36" lineOfSight="3"
space="6" hitPoints="6" pathImage="naval">
<available-to colonial="false" rebel="false" independent="false" royal="false" undead="true" native="false"/>
<ability id="model.ability.navalUnit" value="true"/>
<ability id="model.ability.carryGoods" value="true"/>
<ability id="model.ability.carryUnits" value="true"/>
<ability id="model.ability.captureGoods" value="true"/>
<ability id="model.ability.undead" value="true"/>
</unit-type>
<unit-type id="model.unit.undead" offence="18" defence="4" movement="3" lineOfSight="1" pathImage="foot">
<unit-type id="model.unit.undead" offence="18" defence="4" movement="3" lineOfSight="1" pathImage="foot">
<available-to colonial="false" rebel="false" independent="false" royal="false" undead="true" native="false"/>
<ability id="model.ability.foundColony" value="true"/>
<ability id="model.ability.canBeEquipped" value="true"/>
<ability id="model.ability.canBeCaptured" value="true"/>

View File

@ -1200,7 +1200,8 @@ public final class InGameInputHandler extends InputHandler implements NetworkCon
Element reply = Message.createNewRootElement("provideSkill");
if (settlement.getLearnableSkill() != null) {
reply.setAttribute("skill", Integer.toString(settlement.getLearnableSkill().getIndex()));
if (unit.getType().canBeUpgraded(settlement.getLearnableSkill(), UnitType.NATIVES)) {
if (unit.getType().canBeUpgraded(settlement.getLearnableSkill(),
UnitType.UpgradeType.NATIVES)) {
// We now put the unit on the indian settlement.
// Normally we shouldn't have to this, but the
// movesLeft are set to 0 for unit and if the player
@ -1542,7 +1543,8 @@ public final class InGameInputHandler extends InputHandler implements NetworkCon
// The unit was relocated to the indian settlement. See askSkill for
// more info.
IndianSettlement settlement = (IndianSettlement) unit.getLocation();
if (!unit.getType().canBeUpgraded(settlement.getLearnableSkill(), UnitType.NATIVES)) {
if (!unit.getType().canBeUpgraded(settlement.getLearnableSkill(),
UnitType.UpgradeType.NATIVES)) {
throw new IllegalStateException("Unit can't learn that skill from settlement!");
}

View File

@ -20,6 +20,7 @@
package net.sf.freecol.common.model;
import net.sf.freecol.common.model.Unit.UnitState;
import net.sf.freecol.common.model.UnitType.DowngradeType;
import net.sf.freecol.util.test.FreeColTestCase;
public class DemotionTest extends FreeColTestCase {
@ -201,7 +202,7 @@ public class DemotionTest extends FreeColTestCase {
public void testVeteranSoldierDemotedBySoldier() {
Game game = getStandardGame();
assertEquals(colonistType, veteranType.getDowngrade(UnitType.CAPTURE));
assertEquals(colonistType, veteranType.getDowngrade(DowngradeType.CAPTURE));
Player dutch = game.getPlayer("model.nation.dutch");
Player french = game.getPlayer("model.nation.french");
Map map = getTestMap(plains);
@ -233,7 +234,7 @@ public class DemotionTest extends FreeColTestCase {
public void testArtilleryDemotedBySoldier() {
Game game = getStandardGame();
assertEquals(damagedArtilleryType, artilleryType.getDowngrade(UnitType.DEMOTION));
assertEquals(damagedArtilleryType, artilleryType.getDowngrade(DowngradeType.DEMOTION));
Player dutch = game.getPlayer("model.nation.dutch");
Player french = game.getPlayer("model.nation.french");
Map map = getTestMap(plains);