0.10.1 compat removal: EquipmentType goes away.

This commit is contained in:
Mike Pope 2017-02-06 22:02:32 +10:30
parent 0541c1cc70
commit e588a48616
19 changed files with 46 additions and 712 deletions

View File

@ -18,7 +18,7 @@
* along with FreeCol. If not, see <http://www.gnu.org/licenses/>.
*
-->
<freecol-specification id="rolesCompat" version="0.110">
<freecol-specification id="rolesCompat" version="0.115">
<!--
A copy of the latest roles section of classic/specification.xml
to be loaded into the specification of games lacking a roles

View File

@ -243,7 +243,8 @@
<tile-improvement-types>
<tile-improvement-type id="model.improvement.road" add-work-turns="0"
expended-equipment-type="model.equipment.tools" expended-amount="1" magnitude="1"
required-role="model.role.pioneer"
expended-amount="1" magnitude="1"
movement-cost="1" zIndex="350">
<scope method-name="isWater" method-value="false" />
<modifier id="model.goods.lumber" type="additive" value="2"/>

View File

@ -21,7 +21,7 @@
<freecol-specification id="plantForest">
<tile-improvement-types>
<tile-improvement-type id="model.improvement.plantForest" add-work-turns="9"
expended-equipment-type="model.equipment.tools"
required-role="model.role.pioneer"
expended-amount="4"
magnitude="2">
<scope method-name="isForested" method-value="false" />

View File

@ -20,7 +20,7 @@
In case of incompatible changes, please update version number and
XSD schema for validation.
-->
<freecol-specification id="classic" version="0.114">
<freecol-specification id="classic" version="0.115">
<!-- Modifiers that are not attached to other game object
types. They may be modified, but MUST NOT be removed. -->
@ -1221,53 +1221,6 @@
</role>
</roles>
<equipment-types>
<equipment-type id="model.equipment.horses" combat-loss-priority="20"
role="model.role.scout">
<required-ability id="model.ability.canBeEquipped" value="true"/>
<required-ability id="model.ability.native" value="false"/>
<required-goods id="model.goods.horses" value="50"/>
<compatible-equipment id="model.equipment.muskets"/>
<capture-equipment id="model.equipment.indian.horses" by-indians="true"/>
</equipment-type>
<equipment-type id="model.equipment.muskets" combat-loss-priority="10"
role="model.role.soldier">
<required-ability id="model.ability.canBeEquipped" value="true"/>
<required-ability id="model.ability.native" value="false"/>
<required-goods id="model.goods.muskets" value="50"/>
<compatible-equipment id="model.equipment.horses"/>
<capture-equipment id="model.equipment.indian.muskets"
by-indians="true"/>
</equipment-type>
<equipment-type id="model.equipment.tools" maximum-count="5"
role="model.role.pioneer">
<required-ability id="model.ability.canBeEquipped" value="true"/>
<required-ability id="model.ability.native" value="false"/>
<required-goods id="model.goods.tools" value="20"/>
</equipment-type>
<equipment-type id="model.equipment.missionary"
role="model.role.missionary">
<required-ability id="model.ability.canBeEquipped" value="true"/>
<required-ability id="model.ability.dressMissionary" value="true"/>
</equipment-type>
<equipment-type id="model.equipment.indian.horses"
combat-loss-priority="20" role="model.role.mountedBrave">
<required-ability id="model.ability.canBeEquipped" value="true"/>
<required-ability id="model.ability.native" value="true"/>
<required-goods id="model.goods.horses" value="25"/>
<compatible-equipment id="model.equipment.indian.muskets"/>
<capture-equipment id="model.equipment.horses" by-indians="false"/>
</equipment-type>
<equipment-type id="model.equipment.indian.muskets"
combat-loss-priority="10" role="model.role.armedBrave">
<required-ability id="model.ability.canBeEquipped" value="true"/>
<required-ability id="model.ability.native" value="true"/>
<required-goods id="model.goods.muskets" value="25"/>
<compatible-equipment id="model.equipment.indian.horses"/>
<capture-equipment id="model.equipment.muskets" by-indians="false"/>
</equipment-type>
</equipment-types>
<!--
Parent options: name, add-work-turns, natural, type,
required-improvement, required-role, expended-amount,

View File

@ -20,7 +20,7 @@
In case of incompatible changes, please update version number and
XSD schema for validation.
-->
<freecol-specification id="freecol" version="0.114" extends="classic">
<freecol-specification id="freecol" version="0.115" extends="classic">
<goods-types>
<goods-type id="model.goods.horses" is-farmed="false"

View File

@ -1,51 +0,0 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:annotation>
<xs:documentation>
Copyright (C) 2002-2017 The FreeCol Team
This file is part of FreeCol.
FreeCol is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
FreeCol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeCol. If not, see http://www.gnu.org/licenses
</xs:documentation>
</xs:annotation>
<xs:include schemaLocation="../spec/spec-model.xsd"/>
<xs:element name="equipment">
<xs:annotation>
<xs:documentation>
List of unit's equipment
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name="xLength" type="xs:int">
<xs:annotation>
<xs:documentation>
Number of elements in the list
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:anyAttribute namespace="##local" processContents="skip">
<xs:annotation>
<xs:documentation>
Equipment type list with attributes "x0", "x1", "x2" etc.
</xs:documentation>
</xs:annotation>
</xs:anyAttribute>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -24,7 +24,6 @@
<xs:include schemaLocation="../spec/spec-model.xsd"/>
<xs:include schemaLocation="data-goodsContainer.xsd"/>
<xs:include schemaLocation="data-equipment.xsd"/>
<xs:include schemaLocation="data-tileimprovement.xsd"/>
<xs:element name="units">
@ -62,7 +61,6 @@
<xs:complexType name="unitElementType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="goodsContainer"/>
<xs:element ref="equipment"/>
<xs:element ref="units"/>
<xs:element ref="tileImprovement">
<xs:annotation>

View File

@ -27,7 +27,6 @@
<xs:include schemaLocation="data-building.xsd" />
<xs:include schemaLocation="data-colony.xsd" />
<xs:include schemaLocation="data-colonyTile.xsd" />
<xs:include schemaLocation="data-equipment.xsd" />
<xs:include schemaLocation="data-europe.xsd" />
<xs:include schemaLocation="data-exportData.xsd" />
<xs:include schemaLocation="data-goods.xsd" />

View File

@ -1,74 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* Copyright (C) 2002-2017 The FreeCol Team
*
* This file is part of FreeCol.
*
* FreeCol is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* FreeCol is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FreeCol. If not, see <http://www.gnu.org/licenses/>.
In case of incompatible changes, please update version number and
XSD schema for validation.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<!-- Equipment Types, to go away -->
<xs:element name="equipment-types">
<xs:complexType>
<xs:sequence>
<xs:element name="delete" minOccurs="0" maxOccurs="unbounded"
type="EquipmentTypeId" />
<xs:element ref="equipment-type" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="equipment-type">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="ability"/>
<xs:element ref="capture-equipment"/>
<xs:element ref="compatible-equipment"/>
<xs:element ref="limit"/>
<xs:element ref="modifier"/>
<xs:element ref="required-ability"/>
<xs:element ref="required-location-ability"/>
<xs:element ref="required-goods"/>
</xs:choice>
<xs:attribute name="id" use="required" type="xs:ID"/>
<xs:attribute name="extends" use="optional" type="xs:string" />
<xs:attribute name="preserve" use="optional" type="xs:boolean"/>
<xs:attribute name="abstract" use="optional" type="xs:boolean" />
<xs:attribute name="combat-loss-priority" type="xs:int"/>
<xs:attribute name="maximum-count" type="xs:nonNegativeInteger"/>
<xs:attribute name="role" type="RoleId"/>
</xs:complexType>
</xs:element>
<xs:element name="compatible-equipment">
<xs:complexType>
<xs:attribute name="id" use="required" type="EquipmentTypeId"/>
</xs:complexType>
</xs:element>
<xs:element name="capture-equipment">
<xs:complexType>
<xs:attribute name="id" type="EquipmentTypeId"/>
<xs:attribute name="by-indians" type="xs:boolean"/>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -40,14 +40,6 @@
</xs:restriction>
</xs:simpleType>
<!-- @compat 0.10.x -->
<xs:simpleType name="EquipmentTypeId">
<xs:restriction base="xs:string">
<xs:pattern value="model\.equipment(\.indian)?\.([a-zA-Z]+)" />
</xs:restriction>
</xs:simpleType>
<!-- end @compat 0.10.x -->
<xs:simpleType name="FoundingFatherId">
<xs:restriction base="xs:string">
<xs:pattern value="model\.foundingFather\.([a-zA-Z]+)" />

View File

@ -66,7 +66,6 @@
<xs:attribute name="required-role" use="optional" type="RoleId"/>
<xs:attribute name="zIndex" type="xs:nonNegativeInteger"/>
<!-- @compat 0.10.x -->
<xs:attribute name="expended-equipment-type" type="EquipmentTypeId"/>
<xs:attribute name="deliver-goods-type" type="GoodsTypeId"/>
<xs:attribute name="deliver-amount" type="xs:nonNegativeInteger"/>
<!-- end @compat 0.10.x -->
@ -123,7 +122,6 @@
<!-- @compat 0.10.x -->
<xs:attribute name="deliver-amount" type="xs:nonNegativeInteger"/>
<xs:attribute name="deliver-goods-type" type="GoodsTypeId"/>
<xs:attribute name="expended-equipment-type" type="EquipmentTypeId"/>
<!-- end @compat 0.10.x -->
</xs:complexType>
</xs:element>

View File

@ -54,13 +54,6 @@
<xs:element ref="modifier"/>
<xs:element ref="required-ability"/>
<xs:element ref="required-goods"/>
<!-- @compat 0.10.7 -->
<xs:element name="default-equipment">
<xs:complexType>
<xs:attribute name="id" use="required" type="EquipmentTypeId"/>
</xs:complexType>
</xs:element>
<!-- end @compat -->
<!-- @compat 0.11.6 -->
<xs:element ref="downgrade"/>
<xs:element ref="upgrade"/>

View File

@ -112,15 +112,13 @@
0.112: Added rebel-factor attribute to building-type.
0.113: Added competence-factor attribute to building-type.
0.114: Drop upgrade element from founding-father.
0.115: Drop equipment.
</xs:documentation>
</xs:annotation>
<xs:include schemaLocation="spec-model.xsd" />
<xs:include schemaLocation="spec-building-types.xsd"/>
<xs:include schemaLocation="spec-disasters.xsd"/>
<!-- @compat 0.10.x -->
<xs:include schemaLocation="spec-equipment-types.xsd"/>
<!-- end @compat 0.10.x -->
<xs:include schemaLocation="spec-events.xsd"/>
<xs:include schemaLocation="spec-founding-fathers.xsd"/>
<xs:include schemaLocation="spec-goods-types.xsd"/>
@ -140,7 +138,6 @@
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="building-types"/>
<xs:element ref="disasters"/>
<xs:element ref="equipment-types"/>
<xs:element ref="events"/>
<xs:element ref="founding-fathers"/>
<xs:element ref="goods-types"/>

View File

@ -1,361 +0,0 @@
/**
* Copyright (C) 2002-2017 The FreeCol Team
*
* This file is part of FreeCol.
*
* FreeCol is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* FreeCol is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FreeCol. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.freecol.common.model;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import javax.xml.stream.XMLStreamException;
import net.sf.freecol.common.io.FreeColXMLReader;
import net.sf.freecol.common.io.FreeColXMLWriter;
import net.sf.freecol.common.model.Colony.NoBuildReason;
import static net.sf.freecol.common.util.CollectionUtils.*;
/**
* This whole class is now @compat 0.10.x. We no longer use equipment types.
*
* EquipmentTypes are now subsumed by roles.
* Delete this whole file in due course.
*
* A type of equipment. Equipment differs from goods (although it is often
* derived from it) in that it must be attached to a unit.
*/
public class EquipmentType extends BuildableType {
public static final EquipmentType[] NO_EQUIPMENT = new EquipmentType[0];
public static final String TAG = "equipment-type";
/** The maximum number of equipment items that can be combined. */
private int maximumCount = 1;
/**
* Determines which type of Equipment will be lost first if the
* Unit carrying it is defeated. Horses should be lost before
* Muskets, for example.
*/
private int combatLossPriority = -1;
/**
* What this equipment type becomes if it is captured by Indians
* (if captureEquipmentByIndians is true) or Europeans (otherwise).
*/
private String captureEquipmentId = null;
private boolean captureEquipmentByIndians = false;
/** The default Role of the Unit carrying this type of Equipment. */
private Role role = null;
/** Is this military equipment? */
private boolean militaryEquipment = false;
/**
* A list containing the object identifiers of equipment types
* compatible with this one.
*/
private List<String> compatibleEquipment = null;
/**
* Simple constructor.
*
* @param id The object identifier.
* @param specification The {@code Specification} to refer to.
*/
public EquipmentType(String id, Specification specification) {
super(id, specification);
}
/**
* Get the maximum combinable amount of this equipment type.
*
* @return The maximum combinable count.
*/
public final int getMaximumCount() {
return maximumCount;
}
/**
* Get the combat loss priority.
*
* @return The combat loss priority.
*/
public final int getCombatLossPriority() {
return combatLossPriority;
}
/**
* Can this equipment type be captured in combat?
*
* @return True if this equipment can be captured.
*/
public boolean canBeCaptured() {
return combatLossPriority > 0;
}
/**
* Get the type of equipment to capture, handling the case where
* Europeans and Indians use different {@code EquipmentType}s
* for the same underlying goods.
*
* @param byIndians Is the capture by the Indians?
* @return The captured {@code EquipmentType}.
*/
public EquipmentType getCaptureEquipment(boolean byIndians) {
return (captureEquipmentId != null
&& byIndians == captureEquipmentByIndians)
? getSpecification().getEquipmentType(captureEquipmentId)
: this;
}
/**
* Is this type of equipment compatible with the given type of equipment?
*
* @param otherType The other {@code EquipmentType}.
* @return True if the equipment is compatible.
*/
public boolean isCompatibleWith(EquipmentType otherType) {
if (this.getId().equals(otherType.getId())) {
// model.equipment.tools for example
return true;
}
return compatibleEquipment != null
&& compatibleEquipment.contains(otherType.getId())
&& otherType.compatibleEquipment.contains(getId());
}
/**
* Add a compatible equipment identifier.
*
* @param equipmentId The equipment identifier.
*/
private void addCompatibleEquipment(String equipmentId) {
if (compatibleEquipment == null) compatibleEquipment = new ArrayList<>();
compatibleEquipment.add(equipmentId);
}
/**
* Get the role for this equipment type.
*
* @return The equipment related role.
*/
public final Role getRole() {
return role;
}
/**
* Set the role for this equipment type.
*
* @param role The new equipment related {@code Role}.
*/
public void setRole(Role role) {
this.role = role;
}
/**
* Is this military equiment?
* (True if it grants an offensive or defensive bonus)
*
* @return True if this is military equipment.
*/
public final boolean isMilitaryEquipment() {
return militaryEquipment;
}
/**
* {@inheritDoc}
*/
public NoBuildReason canBeBuiltInColony(Colony colony,
List<BuildableType> assumeBuilt) {
return Colony.NoBuildReason.NONE;
}
// Serialization
private static final String BY_INDIANS_TAG = "by-indians";
private static final String CAPTURE_EQUIPMENT_TAG = "capture-equipment";
private static final String COMBAT_LOSS_PRIORITY_TAG = "combat-loss-priority";
private static final String COMPATIBLE_EQUIPMENT_TAG = "compatible-equipment";
private static final String MAXIMUM_COUNT_TAG = "maximum-count";
private static final String ROLE_TAG = "role";
// @compat 0.10.0
private static final String REQUIRED_LOCATION_ABILITY_TAG = "required-location-ability";
// end @compat
/**
* {@inheritDoc}
*/
@Override
protected void writeAttributes(FreeColXMLWriter xw) throws XMLStreamException {
super.writeAttributes(xw);
xw.writeAttribute(MAXIMUM_COUNT_TAG, maximumCount);
xw.writeAttribute(COMBAT_LOSS_PRIORITY_TAG, combatLossPriority);
xw.writeAttribute(ROLE_TAG, role);
}
/**
* {@inheritDoc}
*/
@Override
protected void writeChildren(FreeColXMLWriter xw) throws XMLStreamException {
super.writeChildren(xw);
if (captureEquipmentId != null) {
xw.writeStartElement(CAPTURE_EQUIPMENT_TAG);
xw.writeAttribute(ID_ATTRIBUTE_TAG, captureEquipmentId);
xw.writeAttribute(BY_INDIANS_TAG, captureEquipmentByIndians);
xw.writeEndElement();
}
if (compatibleEquipment != null) {
for (String compatible : compatibleEquipment) {
xw.writeStartElement(COMPATIBLE_EQUIPMENT_TAG);
xw.writeAttribute(ID_ATTRIBUTE_TAG, compatible);
xw.writeEndElement();
}
}
}
/**
* {@inheritDoc}
*/
@Override
protected void readAttributes(FreeColXMLReader xr) throws XMLStreamException {
super.readAttributes(xr);
maximumCount = xr.getAttribute(MAXIMUM_COUNT_TAG, 1);
combatLossPriority = xr.getAttribute(COMBAT_LOSS_PRIORITY_TAG, -1);
role = xr.getRole(getSpecification(), ROLE_TAG, Role.class,
getSpecification().getDefaultRole());
}
/**
* {@inheritDoc}
*/
@Override
protected void readChildren(FreeColXMLReader xr) throws XMLStreamException {
// Clear containers.
if (xr.shouldClearContainers()) {
captureEquipmentId = null;
captureEquipmentByIndians = false;
compatibleEquipment = null;
}
super.readChildren(xr);
final Predicate<Modifier> militaryPred = m ->
Modifier.OFFENCE.equals(m.getId()) || Modifier.DEFENCE.equals(m.getId());
militaryEquipment = any(getModifiers(), militaryPred);
}
/**
* {@inheritDoc}
*/
@Override
protected void readChild(FreeColXMLReader xr) throws XMLStreamException {
final Specification spec = getSpecification();
final String tag = xr.getLocalName();
if (CAPTURE_EQUIPMENT_TAG.equals(tag)) {
captureEquipmentId = xr.readId();
captureEquipmentByIndians = xr.getAttribute(BY_INDIANS_TAG, false);
xr.closeTag(CAPTURE_EQUIPMENT_TAG);
} else if (COMPATIBLE_EQUIPMENT_TAG.equals(tag)) {
addCompatibleEquipment(xr.readId());
xr.closeTag(COMPATIBLE_EQUIPMENT_TAG);
// @compat 0.10.0
} else if (REQUIRED_LOCATION_ABILITY_TAG.equals(tag)) {
String abilityId = xr.readId();
Map<String, Boolean> required = getRequiredAbilities();
required.put(abilityId, xr.getAttribute(VALUE_TAG, true));
setRequiredAbilities(required);
spec.addAbility(abilityId);
xr.closeTag(REQUIRED_LOCATION_ABILITY_TAG);
// end @compat
} else {
super.readChild(xr);
}
}
/**
* {@inheritDoc}
*/
public String getXMLTagName() { return TAG; }
// Override Object
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EquipmentType other = (EquipmentType) obj;
if (compatibleEquipment == null) {
if (other.compatibleEquipment != null)
return false;
} else if (!compatibleEquipment.equals(other.compatibleEquipment))
return false;
if (getId() == null) {
if (other.getId() != null)
return false;
} else if (!getId().equals(other.getId()))
return false;
return true;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
int result = 1;
result = 37 * result
+ ((compatibleEquipment == null) ? 0 : compatibleEquipment
.hashCode());
return 37 * result + ((getId() == null) ? 0 : getId().hashCode());
}
}

View File

@ -304,15 +304,6 @@ public class Scope extends FreeColObject {
matchesNull = xr.getAttribute(MATCHES_NULL_TAG, true);
type = xr.getAttribute(TYPE_TAG, (String)null);
// @compat 0.10.x
if ("model.equipment.muskets".equals(type)) {
type = "model.role.soldier";
} else if ("model.equipment.indian.horses".equals(type)) {
type = "model.role.mountedBrave";
} else if ("model.equipment.indian.muskets".equals(type)) {
type = "model.role.armedBrave";
}
// end @compat 0.10.x
abilityId = xr.getAttribute(ABILITY_ID_TAG, (String)null);

View File

@ -185,9 +185,6 @@ public final class Specification {
private final List<BuildingType> buildingTypeList = new ArrayList<>();
// readerMap("disasters")
private final List<Disaster> disasters = new ArrayList<>();
// @compat 0.10.x readerMap("equipment-types")
private final List<EquipmentType> equipmentTypes = new ArrayList<>();
// end @compat 0.10.x
// readerMap("european-nation-types")
private final List<EuropeanNationType> europeanNationTypes = new ArrayList<>();
// readerMap("events")
@ -295,10 +292,6 @@ public final class Specification {
new TypeReader<>(BuildingType.class, buildingTypeList));
readerMap.put(DISASTERS_TAG,
new TypeReader<>(Disaster.class, disasters));
// @compat 0.10.x
readerMap.put(EQUIPMENT_TYPES_TAG,
new TypeReader<>(EquipmentType.class, equipmentTypes));
// end @compat 0.10.x
readerMap.put(EUROPEAN_NATION_TYPES_TAG,
new TypeReader<>(EuropeanNationType.class, europeanNationTypes));
readerMap.put(EVENTS_TAG,
@ -1737,19 +1730,6 @@ public final class Specification {
}
// @compat 0.10.x -- EquipmentTypes --
/**
* Get an equipment type by identifier.
* Still needed by backward compatibility code in Unit.readChild.
*
* @param id The object identifier.
* @return The {@code EquipmentType} found.
*/
public EquipmentType getEquipmentType(String id) {
return getType(id, EquipmentType.class);
}
// end @compat 0.10.x
// -- DifficultyLevels --
/**
@ -2018,7 +1998,7 @@ public final class Specification {
fixSpec();
}
// @compat 0.10.x
// @compat 0.11.0
/**
* Handle the reworking of roles that landed in 0.11.0.
*
@ -2048,7 +2028,7 @@ public final class Specification {
+ transform(getRoles(), alwaysTrue(), Role::getId,
Collectors.joining(" ")));
}
// end @compat 0.10.x
// end @compat 0.11.0
/**
* Specification backward compatibility for the spec in general.
@ -2289,19 +2269,6 @@ public final class Specification {
goodsType = getGoodsType("model.goods.muskets");
goodsType.setMilitary();
// automaticEquipment scope types are now roles
forEach(flatten(flatten(indianNationTypes,
nt -> nt.getAbilities(Ability.AUTOMATIC_EQUIPMENT)),
Ability::getScopes),
scope -> {
String type = scope.getType();
if ("model.equipment.indian.muskets".equals(type)) {
scope.setType("model.role.nativeDragoon");
} else if ("model.equipment.indian.horses".equals(type)) {
scope.setType("model.role.armedBrave");
}
});
// Limit Revere auto-equip of muskets to the soldier role
{
FoundingFather revere
@ -2917,13 +2884,13 @@ public final class Specification {
private static final String UNIT_CHANGE_TYPES_TAG = "unit-change-types";
private static final String UNIT_TYPES_TAG = "unit-types";
private static final String VERSION_TAG = "version";
// @compat 0.10.x
private static final String EQUIPMENT_TYPES_TAG = "equipment-types";
// end @compat 0.10.x
// @compat 0.11.3
private static final String OLD_DIFFICULTY_LEVEL_TAG = "difficultyLevel";
private static final String OLD_TILEIMPROVEMENT_TYPES_TAG = "tileimprovement-types";
// end @compat 0.11.3
// @compat 0.11.x
private static final String OLD_EQUIPMENT_TYPES_TAG = "equipment-types";
// end @compat 0.11.x
/**
* Write an XML-representation of this object to the given stream.
@ -3023,17 +2990,12 @@ public final class Specification {
while (xr.moreTags()) {
String childName = xr.getLocalName();
// @compat 0.10.x
// Ideally we would handle role backward compatibility in
// the type reader triggered by the "roles" section of the
// spec. Alas, specs pre-0.10.6 had no roles section.
// The next section after roles in modern specs is
// "equipment-types", which is also the first place roles
// are referred to directly, and better still is completely
// replaced by roles in 0.11.x. So this is the last chance
// to fix any role omissions.
if ("equipment-types".equals(childName)) fixRoles();
// end @compat 0.10.x
// @compat 0.11.0
if (childName.equals(OLD_EQUIPMENT_TYPES_TAG)) {
xr.swallowTag(OLD_EQUIPMENT_TYPES_TAG);
continue;
}
// end @compat 0.11.0
ChildReader reader = readerMap.get(childName);
if (reader == null) {
logger.warning("No reader found for: " + childName);
@ -3041,7 +3003,10 @@ public final class Specification {
reader.readChildren(xr);
}
}
// @compat 0.11.0
if (roles.isEmpty()) fixRoles();
// end @compat 0.11.0
if (this.needUnitChangeTypes) {
this.needUnitChangeTypes = false;
File uctf = FreeColDirectories.getCompatibilityFile(UNIT_CHANGE_TYPES_COMPAT_FILE_NAME);

View File

@ -403,9 +403,9 @@ public final class TileImprovementType extends FreeColSpecObjectType {
private static final String TO_TAG = "to";
private static final String WORKER_TAG = "worker";
private static final String ZINDEX_TAG = "zIndex";
// @compat 0.10.x
private static final String EXPENDED_EQUIPMENT_TYPE_TAG = "expended-equipment-type";
// end @compat 0.10.x
// @compat 0.11.0
private static final String OLD_EXPENDED_EQUIPMENT_TYPE_TAG = "expended-equipment-type";
// end @compat 0.11.0
// @compat 0.11.3
private static final String OLD_EXPOSE_RESOURCE_PERCENT_TAG = "exposeResourcePercent";
// end @compat 0.11.3
@ -502,11 +502,11 @@ public final class TileImprovementType extends FreeColSpecObjectType {
requiredRole = xr.getType(spec, REQUIRED_ROLE_TAG,
Role.class, (Role)null);
// @compat 0.10.x
if (xr.hasAttribute(EXPENDED_EQUIPMENT_TYPE_TAG)) {
// @compat 0.11.x
if (xr.hasAttribute(OLD_EXPENDED_EQUIPMENT_TYPE_TAG)) {
requiredRole = spec.getRole("model.role.pioneer");
}
// end @compat 0.10.x
// end @compat 0.11.x
expendedAmount = xr.getAttribute(EXPENDED_AMOUNT_TAG, 0);

View File

@ -4306,11 +4306,10 @@ public class Unit extends GoodsLocation
private static final String WORK_TYPE_TAG = "workType";
// @compat 0.10.7
private static final String OLD_HIT_POINTS_TAG = "hitpoints";
private static final String EQUIPMENT_TAG = "equipment";
/** The equipment this Unit carries. Now subsumed into roles. */
private final TypeCountMap<EquipmentType> equipment
= new TypeCountMap<>();
// end @compat 0.10.x
// end @compat 0.10.7
// @compat 0.11.0
private static final String OLD_EQUIPMENT_TAG = "equipment";
// end @compat 0.11.0
// @compat 0.11.3
private static final String OLD_TILE_IMPROVEMENT_TAG = "tileimprovement";
// end @compat 0.11.3
@ -4540,64 +4539,10 @@ public class Unit extends GoodsLocation
protected void readChildren(FreeColXMLReader xr) throws XMLStreamException {
// Clear containers.
if (getGoodsContainer() != null) getGoodsContainer().removeAll();
equipment.clear();
workImprovement = null;
super.readChildren(xr);
// @compat 0.10.x
if (roleCount < 0) {
// If roleCount was not present, set it from equipment
final Specification spec = getSpecification();
Role role = spec.getDefaultRole();
boolean horses = false, muskets = false;
int count = 1;
for (EquipmentType type : equipment.keySet()) {
if ("model.equipment.horses".equals(type.getId())
|| "model.equipment.indian.horses".equals(type.getId())) {
horses = true;
} else if ("model.equipment.muskets".equals(type.getId())
|| "model.equipment.indian.muskets".equals(type.getId())) {
muskets = true;
} else {
role = type.getRole();
if ("model.equipment.tools".equals(type.getId())) {
count = equipment.getCount(type);
}
}
}
if (horses && muskets) {
if (owner.isIndian()) {
role = spec.getRole("model.role.nativeDragoon");
} else if (owner.isREF() && hasAbility(Ability.REF_UNIT)) {
role = spec.getRole("model.role.cavalry");
} else {
role = spec.getRole("model.role.dragoon");
}
} else if (horses) {
if (owner.isIndian()) {
role = spec.getRole("model.role.mountedBrave");
} else if (owner.isREF() && hasAbility(Ability.REF_UNIT)) {
logger.warning("Undefined role: REF Scout");
} else {
role = spec.getRole("model.role.scout");
}
} else if (muskets) {
if (owner.isIndian()) {
role = spec.getRole("model.role.armedBrave");
} else if (owner.isREF() && hasAbility(Ability.REF_UNIT)) {
role = spec.getRole("model.role.infantry");
} else {
role = spec.getRole("model.role.soldier");
}
}
setRoleCount(Math.min(role.getMaximumCount(), count));
} else {
// If roleCount was present, we are now ignoring equipment.
equipment.clear();
}
// end @compat 0.10.x
// @compat 0.10.x
// There was a bug in 0.10.x that did not clear tile
// improvements after they were complete, leading to units
@ -4622,12 +4567,11 @@ public class Unit extends GoodsLocation
final Game game = getGame();
final String tag = xr.getLocalName();
// @compat 0.10.x
if (EQUIPMENT_TAG.equals(tag)) {
equipment.incrementCount(spec.getEquipmentType(xr.readId()),
xr.getAttribute(COUNT_TAG, 0));
xr.closeTag(EQUIPMENT_TAG);
// end @compat 0.10.x
// @compat 0.11.0
if (OLD_EQUIPMENT_TAG.equals(tag)) {
while (xr.moreTags()
|| !OLD_EQUIPMENT_TAG.equals(xr.getLocalName()));
// end @compat 0.11.0
} else if (TileImprovement.TAG.equals(tag)
// @compat 0.11.3

View File

@ -636,9 +636,9 @@ public final class UnitType extends BuildableType implements Consumer {
private static final String SPACE_TAG = "space";
private static final String SPACE_TAKEN_TAG = "space-taken";
private static final String UNIT_TAG = "unit";
// @compat 0.10.7
private static final String DEFAULT_EQUIPMENT_TAG = "default-equipment";
// end @compat
// @compat 0.11.0
private static final String OLD_DEFAULT_EQUIPMENT_TAG = "default-equipment";
// end @compat 0.11.0
// @compat 0.11.3
private static final String OLD_DEFAULT_UNIT_TAG = "defaultUnit";
private static final String OLD_HIT_POINTS_TAG = "hitPoints";
@ -907,32 +907,21 @@ public final class UnitType extends BuildableType implements Consumer {
xr.getAttribute(VALUE_TAG, UNDEFINED));
xr.closeTag(CONSUMES_TAG);
// @compat 0.10.7
} else if (DEFAULT_EQUIPMENT_TAG.equals(tag)) {
String id = xr.getAttribute(ID_ATTRIBUTE_TAG, null);
String roleId = ("model.equipment.horses".equals(id))
? "model.role.scout"
: ("model.equipment.muskets".equals(id))
? "model.role.soldier"
: ("model.equipment.tools".equals(id))
? "model.role.pioneer"
: ("model.equipment.missionary".equals(id))
? "model.role.missionary"
: Specification.DEFAULT_ROLE_ID;
defaultRole = spec.getRole(roleId);
xr.closeTag(DEFAULT_EQUIPMENT_TAG);
// end @compat
// @compat 0.11.0
} else if (OLD_DEFAULT_EQUIPMENT_TAG.equals(tag)) {
xr.swallowTag(OLD_DEFAULT_EQUIPMENT_TAG);
// end @compat 0.11.0
} else if (DEFAULT_ROLE_TAG.equals(tag)) {
defaultRole = xr.getType(spec, ID_ATTRIBUTE_TAG,
Role.class, spec.getDefaultRole());
xr.closeTag(DEFAULT_ROLE_TAG);
// @compat 0.11.6
// @compat 0.11.6
} else if (DOWNGRADE_TAG.equals(tag) || UPGRADE_TAG.equals(tag)) {
spec.setNeedUnitChangeTypes();
xr.closeTag(tag, Scope.TAG);
// end @compat 0.11.6
// end @compat 0.11.6
} else {
super.readChild(xr);