Add generalized production element, step 1.

This commit adds a new generalized production element, which allows
for production types with several input and output goods, and also
subsumes the basic production and factory production features of
building types. The production element is added to tile types and
building types, but the original semantics are preserved as far as
possible. They will be replaced in subsequent commits.
This commit is contained in:
Michael Vehrs 2013-02-10 13:39:53 +01:00
parent 89ede8cbfb
commit 183dc7c924
15 changed files with 856 additions and 455 deletions

5
.gitignore vendored
View File

@ -8,7 +8,4 @@ FreeCol.log
FreeCol.jar
src/MANIFEST.MF
test/data
build/TEST-net.sf.freecol.AllTests.txt
build/dependencies.txt
build/net/
build/svn.properties
build/

View File

@ -1,27 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Revision$ -->
<!--
* Copyright (C) 2002-2012 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/>.
*
-->
<!-- specification version 0.70 -->
* Copyright (C) 2002-2012 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/>.
*
-->
<!-- specification version 0.75 -->
<!-- in case of incompatible changes, please update version number and
XSD schema for validation. -->
XSD schema for validation. -->
<freecol-specification id="classic">
<!-- Modifiers that are not attached to other game object
@ -105,8 +105,8 @@
<goods-type id="model.goods.fish" is-farmed="true" storable="false"
stored-as="model.goods.food" is-food="true" />
<!--
<goods-type id="model.goods.meat" is-farmed="true" storable="false"
stored-as="model.goods.food" is-food="true" />
<goods-type id="model.goods.meat" is-farmed="true" storable="false"
stored-as="model.goods.food" is-food="true" />
-->
<goods-type id="model.goods.sugar" is-farmed="true" new-world-goods="true">
<market initial-amount="1500" initial-price="2" price-difference="4"/>
@ -237,85 +237,147 @@
resource if any must have the following structure:
<resource type="model.resource.resourcename" probability="X"/>
- X is a relative probability, not necessarily a percentage value
-->
-->
<tile-types>
<tile-type id="model.tile.plains" basic-move-cost="3" basic-work-turns="3">
<gen humidityMin="0" humidityMax="60" temperatureMin="0" temperatureMax="15" altitudeMin="1" altitudeMax="2"/>
<primary-production goods-type="model.goods.grain" value="5"/>
<secondary-production goods-type="model.goods.cotton" value="2"/>
<production goods-type="model.goods.grain" value="5"/>
<production goods-type="model.goods.cotton" value="2"/>
<production goods-type="model.goods.ore" value="1"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="5"/>
<output goods-type="model.goods.cotton" value="2"/>
</production>
<production>
<output goods-type="model.goods.grain" value="5"/>
</production>
<production>
<output goods-type="model.goods.cotton" value="2"/>
</production>
<production>
<output goods-type="model.goods.ore" value="1"/>
</production>
<resource type="model.resource.grain" probability="100"/>
<disaster id="model.disaster.tornado" probability="100"/>
</tile-type>
<tile-type id="model.tile.grassland" basic-move-cost="3" basic-work-turns="3">
<gen humidityMin="25" humidityMax="70" temperatureMin="10" temperatureMax="25" altitudeMin="1" altitudeMax="1"/>
<primary-production goods-type="model.goods.grain" value="3"/>
<secondary-production goods-type="model.goods.tobacco" value="3"/>
<production goods-type="model.goods.grain" value="3"/>
<production goods-type="model.goods.tobacco" value="3"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.tobacco" value="3"/>
</production>
<production>
<output goods-type="model.goods.grain" value="3"/>
</production>
<production>
<output goods-type="model.goods.tobacco" value="3"/>
</production>
<resource type="model.resource.tobacco" probability="100"/>
</tile-type>
<tile-type id="model.tile.prairie" basic-move-cost="3" basic-work-turns="3">
<gen humidityMin="20" humidityMax="50" temperatureMin="15" temperatureMax="30" altitudeMin="1" altitudeMax="1"/>
<primary-production goods-type="model.goods.grain" value="3"/>
<secondary-production goods-type="model.goods.cotton" value="3"/>
<production goods-type="model.goods.grain" value="3"/>
<production goods-type="model.goods.cotton" value="3"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.cotton" value="3"/>
</production>
<production>
<output goods-type="model.goods.grain" value="3"/>
</production>
<production>
<output goods-type="model.goods.cotton" value="3"/>
</production>
<resource type="model.resource.cotton" probability="100"/>
<disaster id="model.disaster.tornado" probability="100"/>
</tile-type>
<tile-type id="model.tile.savannah" basic-move-cost="3" basic-work-turns="3">
<gen humidityMin="25" humidityMax="70" temperatureMin="30" temperatureMax="40" altitudeMin="1" altitudeMax="1"/>
<primary-production goods-type="model.goods.grain" value="4"/>
<secondary-production goods-type="model.goods.sugar" value="3"/>
<production goods-type="model.goods.grain" value="4"/>
<production goods-type="model.goods.sugar" value="3"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="4"/>
<output goods-type="model.goods.sugar" value="3"/>
</production>
<production>
<output goods-type="model.goods.grain" value="4"/>
</production>
<production>
<output goods-type="model.goods.sugar" value="3"/>
</production>
<resource type="model.resource.sugar" probability="100"/>
</tile-type>
<tile-type id="model.tile.marsh" basic-move-cost="6" basic-work-turns="5">
<gen humidityMin="50" humidityMax="100" temperatureMin="5" temperatureMax="15" altitudeMin="2" altitudeMax="2"/>
<modifier id="model.modifier.defence" type="percentage" value="25"/>
<primary-production goods-type="model.goods.grain" value="3"/>
<secondary-production goods-type="model.goods.tobacco" value="2"/>
<production goods-type="model.goods.grain" value="3"/>
<production goods-type="model.goods.tobacco" value="2"/>
<production goods-type="model.goods.ore" value="2"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.tobacco" value="2"/>
</production>
<production>
<output goods-type="model.goods.grain" value="3"/>
</production>
<production>
<output goods-type="model.goods.tobacco" value="2"/>
</production>
<production>
<output goods-type="model.goods.ore" value="2"/>
</production>
<resource type="model.resource.minerals" probability="100"/>
<disaster id="model.disaster.disease" probability="100"/>
</tile-type>
<tile-type id="model.tile.swamp" basic-move-cost="6" basic-work-turns="7">
<gen humidityMin="50" humidityMax="100" temperatureMin="10" temperatureMax="40" altitudeMin="1" altitudeMax="1"/>
<modifier id="model.modifier.defence" type="percentage" value="25"/>
<primary-production goods-type="model.goods.grain" value="3"/>
<secondary-production goods-type="model.goods.sugar" value="2"/>
<production goods-type="model.goods.grain" value="3"/>
<production goods-type="model.goods.sugar" value="2"/>
<production goods-type="model.goods.ore" value="2"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.sugar" value="2"/>
</production>
<production>
<output goods-type="model.goods.grain" value="3"/>
</production>
<production>
<output goods-type="model.goods.sugar" value="2"/>
</production>
<production>
<output goods-type="model.goods.ore" value="2"/>
</production>
<resource type="model.resource.minerals" probability="100"/>
<disaster id="model.disaster.disease" probability="50"/>
<disaster id="model.disaster.flood" probability="50"/>
</tile-type>
<tile-type id="model.tile.desert" basic-move-cost="3" basic-work-turns="3">
<gen humidityMin="0" humidityMax="25" temperatureMin="10" temperatureMax="40" altitudeMin="1" altitudeMax="2"/>
<primary-production goods-type="model.goods.grain" value="3" tile-production="veryHigh" />
<primary-production goods-type="model.goods.grain" value="2"/>
<primary-production goods-type="model.goods.grain" value="1" tile-production="veryLow" />
<secondary-production goods-type="model.goods.cotton" value="1"/>
<production goods-type="model.goods.grain" value="2"/>
<production goods-type="model.goods.cotton" value="1"/>
<production goods-type="model.goods.ore" value="2"/>
<production colonyCenterTile="true" productionLevel="veryHigh">
<output goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.cotton" value="1"/>
</production>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="2"/>
<output goods-type="model.goods.cotton" value="1"/>
</production>
<production colonyCenterTile="true" productionLevel="veryLow">
<output goods-type="model.goods.grain" value="1"/>
<output goods-type="model.goods.cotton" value="1"/>
</production>
<production>
<output goods-type="model.goods.grain" value="2"/>
</production>
<production>
<output goods-type="model.goods.cotton" value="1"/>
</production>
<production>
<output goods-type="model.goods.ore" value="2"/>
</production>
<resource type="model.resource.oasis" probability="100"/>
<disaster id="model.disaster.sandstorm" probability="50"/>
<disaster id="model.disaster.drought" probability="50"/>
</tile-type>
<tile-type id="model.tile.tundra" basic-move-cost="3" basic-work-turns="4">
<gen humidityMin="0" humidityMax="100" temperatureMin="-5" temperatureMax="5" altitudeMin="1" altitudeMax="3"/>
<primary-production goods-type="model.goods.grain" value="3"/>
<secondary-production goods-type="model.goods.ore" value="2"/>
<production goods-type="model.goods.grain" value="3"/>
<production goods-type="model.goods.ore" value="2"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.ore" value="2"/>
</production>
<production>
<output goods-type="model.goods.grain" value="3"/>
</production>
<production>
<output goods-type="model.goods.ore" value="2"/>
</production>
<!-- Col1 had minerals here, even if not mentioned in the Colonizopedia -->
<resource type="model.resource.minerals" probability="100"/>
<disaster id="model.disaster.blizzard" probability="100"/>
@ -323,85 +385,167 @@
<tile-type id="model.tile.mixedForest" basic-move-cost="6" basic-work-turns="4" is-forest="true">
<gen humidityMin="0" humidityMax="60" temperatureMin="0" temperatureMax="15" altitudeMin="1" altitudeMax="2"/>
<modifier id="model.modifier.defence" type="percentage" value="50"/>
<primary-production goods-type="model.goods.grain" value="3"/>
<secondary-production goods-type="model.goods.furs" value="3"/>
<production goods-type="model.goods.grain" value="3"/>
<production goods-type="model.goods.cotton" value="1"/>
<production goods-type="model.goods.furs" value="3"/>
<production goods-type="model.goods.lumber" value="6"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.furs" value="3"/>
</production>
<production>
<output goods-type="model.goods.grain" value="3"/>
</production>
<production>
<output goods-type="model.goods.cotton" value="1"/>
</production>
<production>
<output goods-type="model.goods.furs" value="3"/>
</production>
<production>
<output goods-type="model.goods.lumber" value="6"/>
</production>
<resource type="model.resource.furs" probability="100"/>
</tile-type>
<tile-type id="model.tile.coniferForest" basic-move-cost="6" basic-work-turns="4" is-forest="true">
<gen humidityMin="25" humidityMax="70" temperatureMin="10" temperatureMax="25" altitudeMin="1" altitudeMax="1"/>
<modifier id="model.modifier.defence" type="percentage" value="50"/>
<primary-production goods-type="model.goods.grain" value="2"/>
<secondary-production goods-type="model.goods.furs" value="2"/>
<production goods-type="model.goods.grain" value="2"/>
<production goods-type="model.goods.tobacco" value="1"/>
<production goods-type="model.goods.furs" value="2"/>
<production goods-type="model.goods.lumber" value="6"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="2"/>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production>
<output goods-type="model.goods.grain" value="2"/>
</production>
<production>
<output goods-type="model.goods.tobacco" value="1"/>
</production>
<production>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production>
<output goods-type="model.goods.lumber" value="6"/>
</production>
<resource type="model.resource.lumber" probability="100"/>
</tile-type>
<tile-type id="model.tile.broadleafForest" basic-move-cost="6" basic-work-turns="4" is-forest="true">
<gen humidityMin="20" humidityMax="50" temperatureMin="15" temperatureMax="30" altitudeMin="1" altitudeMax="1"/>
<modifier id="model.modifier.defence" type="percentage" value="50"/>
<primary-production goods-type="model.goods.grain" value="2"/>
<secondary-production goods-type="model.goods.furs" value="2"/>
<production goods-type="model.goods.grain" value="2"/>
<production goods-type="model.goods.cotton" value="1"/>
<production goods-type="model.goods.furs" value="2"/>
<production goods-type="model.goods.lumber" value="4"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="2"/>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production>
<output goods-type="model.goods.grain" value="2"/>
</production>
<production>
<output goods-type="model.goods.cotton" value="1"/>
</production>
<production>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production>
<output goods-type="model.goods.lumber" value="4"/>
</production>
<resource type="model.resource.game" probability="100"/>
</tile-type>
<tile-type id="model.tile.tropicalForest" basic-move-cost="6" basic-work-turns="6" is-forest="true">
<modifier id="model.modifier.defence" type="percentage" value="50"/>
<gen humidityMin="25" humidityMax="70" temperatureMin="30" temperatureMax="40" altitudeMin="1" altitudeMax="1"/>
<primary-production goods-type="model.goods.grain" value="3"/>
<secondary-production goods-type="model.goods.furs" value="2"/>
<production goods-type="model.goods.grain" value="3"/>
<production goods-type="model.goods.sugar" value="1"/>
<production goods-type="model.goods.furs" value="2"/>
<production goods-type="model.goods.lumber" value="4"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production>
<output goods-type="model.goods.grain" value="3"/>
</production>
<production>
<output goods-type="model.goods.sugar" value="1"/>
</production>
<production>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production>
<output goods-type="model.goods.lumber" value="4"/>
</production>
<resource type="model.resource.lumber" probability="100"/>
<disaster id="model.disaster.hurricane" probability="100"/>
</tile-type>
<tile-type id="model.tile.wetlandForest" basic-move-cost="9" basic-work-turns="6" is-forest="true">
<gen humidityMin="50" humidityMax="100" temperatureMin="5" temperatureMax="15" altitudeMin="2" altitudeMax="2"/>
<modifier id="model.modifier.defence" type="percentage" value="50"/>
<primary-production goods-type="model.goods.grain" value="2"/>
<secondary-production goods-type="model.goods.furs" value="2"/>
<production goods-type="model.goods.grain" value="2"/>
<production goods-type="model.goods.tobacco" value="1"/>
<production goods-type="model.goods.furs" value="2"/>
<production goods-type="model.goods.lumber" value="4"/>
<production goods-type="model.goods.ore" value="1"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="2"/>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production>
<output goods-type="model.goods.grain" value="2"/>
</production>
<production>
<output goods-type="model.goods.tobacco" value="1"/>
</production>
<production>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production>
<output goods-type="model.goods.lumber" value="4"/>
</production>
<production>
<output goods-type="model.goods.ore" value="1"/>
</production>
<resource type="model.resource.minerals" probability="100"/>
</tile-type>
<tile-type id="model.tile.rainForest" basic-move-cost="9" basic-work-turns="7" is-forest="true">
<gen humidityMin="50" humidityMax="100" temperatureMin="10" temperatureMax="40" altitudeMin="1" altitudeMax="1"/>
<modifier id="model.modifier.defence" type="percentage" value="75"/>
<primary-production goods-type="model.goods.grain" value="2"/>
<secondary-production goods-type="model.goods.furs" value="1"/>
<production goods-type="model.goods.grain" value="2"/>
<production goods-type="model.goods.sugar" value="1"/>
<production goods-type="model.goods.furs" value="1"/>
<production goods-type="model.goods.lumber" value="4"/>
<production goods-type="model.goods.ore" value="1"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="2"/>
<output goods-type="model.goods.furs" value="1"/>
</production>
<production>
<output goods-type="model.goods.grain" value="2"/>
</production>
<production>
<output goods-type="model.goods.sugar" value="1"/>
</production>
<production>
<output goods-type="model.goods.furs" value="1"/>
</production>
<production>
<output goods-type="model.goods.lumber" value="4"/>
</production>
<production>
<output goods-type="model.goods.ore" value="1"/>
</production>
<resource type="model.resource.minerals" probability="100"/>
<disaster id="model.disaster.disease" probability="100"/>
</tile-type>
<tile-type id="model.tile.scrubForest" basic-move-cost="3" basic-work-turns="4" is-forest="true">
<gen humidityMin="0" humidityMax="25" temperatureMin="10" temperatureMax="40" altitudeMin="1" altitudeMax="2"/>
<modifier id="model.modifier.defence" type="percentage" value="50"/>
<primary-production goods-type="model.goods.grain" value="3" tile-production="veryHigh" />
<primary-production goods-type="model.goods.grain" value="2"/>
<primary-production goods-type="model.goods.grain" value="1" tile-production="veryLow" />
<secondary-production goods-type="model.goods.furs" value="2"/>
<production goods-type="model.goods.grain" value="2"/>
<production goods-type="model.goods.cotton" value="1"/>
<production goods-type="model.goods.furs" value="2"/>
<production goods-type="model.goods.lumber" value="2"/>
<production goods-type="model.goods.ore" value="1"/>
<production colonyCenterTile="true" productionLevel="veryHigh">
<output goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="2"/>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production colonyCenterTile="true" productionLevel="veryLow">
<output goods-type="model.goods.grain" value="1"/>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production>
<output goods-type="model.goods.grain" value="2"/>
</production>
<production>
<output goods-type="model.goods.cotton" value="1"/>
</production>
<production>
<output goods-type="model.goods.furs" value="2"/>
</production>
<production>
<output goods-type="model.goods.lumber" value="2"/>
</production>
<production>
<output goods-type="model.goods.ore" value="1"/>
</production>
<resource type="model.resource.oasis" probability="100"/>
<disaster id="model.disaster.brushfire" probability="50"/>
<disaster id="model.disaster.drought" probability="50"/>
@ -409,21 +553,37 @@
<tile-type id="model.tile.borealForest" basic-move-cost="6" basic-work-turns="4" is-forest="true">
<gen humidityMin="0" humidityMax="100" temperatureMin="-5" temperatureMax="5" altitudeMin="1" altitudeMax="3"/>
<modifier id="model.modifier.defence" type="percentage" value="50"/>
<primary-production goods-type="model.goods.grain" value="2"/>
<secondary-production goods-type="model.goods.furs" value="3"/>
<production goods-type="model.goods.grain" value="2"/>
<production goods-type="model.goods.furs" value="3"/>
<production goods-type="model.goods.lumber" value="4"/>
<production goods-type="model.goods.ore" value="1"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="2"/>
<output goods-type="model.goods.furs" value="3"/>
</production>
<production>
<output goods-type="model.goods.grain" value="2"/>
</production>
<production>
<output goods-type="model.goods.furs" value="3"/>
</production>
<production>
<output goods-type="model.goods.lumber" value="4"/>
</production>
<production>
<output goods-type="model.goods.ore" value="1"/>
</production>
<resource type="model.resource.game" probability="100"/>
</tile-type>
<tile-type id="model.tile.hills" basic-move-cost="6" basic-work-turns="4" is-elevation="true">
<gen humidityMin="0" humidityMax="100" temperatureMin="-20" temperatureMax="40" altitudeMin="2" altitudeMax="3"/>
<modifier id="model.modifier.defence" type="percentage" value="100"/>
<primary-production goods-type="model.goods.grain" value="2"/>
<secondary-production goods-type="model.goods.ore" value="4"/>
<production goods-type="model.goods.grain" value="2"/>
<production goods-type="model.goods.ore" value="4"/>
<production colonyCenterTile="true">
<output goods-type="model.goods.grain" value="2"/>
<output goods-type="model.goods.ore" value="4"/>
</production>
<production>
<output goods-type="model.goods.grain" value="2"/>
</production>
<production>
<output goods-type="model.goods.ore" value="4"/>
</production>
<resource type="model.resource.ore" probability="100"/>
<disaster id="model.disaster.earthquake" probability="50"/>
<disaster id="model.disaster.landslide" probability="50"/>
@ -431,43 +591,59 @@
<tile-type id="model.tile.mountains" basic-move-cost="9" basic-work-turns="7" is-elevation="true" can-settle="false">
<gen humidityMin="0" humidityMax="100" temperatureMin="-20" temperatureMax="40" altitudeMin="3" altitudeMax="3"/>
<modifier id="model.modifier.defence" type="percentage" value="150"/>
<production goods-type="model.goods.ore" value="4"/>
<production goods-type="model.goods.silver" value="1"/>
<production>
<output goods-type="model.goods.ore" value="4"/>
</production>
<production>
<output goods-type="model.goods.silver" value="1"/>
</production>
<resource type="model.resource.silver" probability="100"/>
<disaster id="model.disaster.earthquake" probability="50"/>
<disaster id="model.disaster.landslide" probability="50"/>
</tile-type>
<tile-type id="model.tile.arctic" basic-move-cost="6" basic-work-turns="4">
<gen humidityMin="0" humidityMax="100" temperatureMin="-20" temperatureMax="0" altitudeMin="1" altitudeMax="3"/>
<primary-production goods-type="model.goods.grain" value="2" tile-production="veryHigh" />
<primary-production goods-type="model.goods.grain" value="1" tile-production="high" />
<production colonyCenterTile="true" productionLevel="veryHigh">
<output goods-type="model.goods.grain" value="2"/>
</production>
<production colonyCenterTile="true" productionLevel="high">
<output goods-type="model.goods.grain" value="1"/>
</production>
<disaster id="model.disaster.blizzard" probability="100"/>
</tile-type>
<tile-type id="model.tile.ocean" basic-move-cost="3" basic-work-turns="4" is-water="true"
can-settle="false" is-connected="true">
<gen humidityMin="0" humidityMax="100" temperatureMin="-20" temperatureMax="40" altitudeMin="-2" altitudeMax="-1"/>
<production goods-type="model.goods.fish" value="2"/>
<production>
<output goods-type="model.goods.fish" value="2"/>
</production>
<resource type="model.resource.fish" probability="100"/>
<disaster id="model.disaster.stormsurge" probability="100"/>
</tile-type>
<tile-type id="model.tile.lake" basic-move-cost="3" basic-work-turns="4" is-water="true"
can-settle="false" is-connected="false">
<gen humidityMin="0" humidityMax="100" temperatureMin="-20" temperatureMax="40" altitudeMin="-2" altitudeMax="-1"/>
<production goods-type="model.goods.fish" value="2"/>
<production>
<output goods-type="model.goods.fish" value="2"/>
</production>
<resource type="model.resource.fish" probability="100"/>
<disaster id="model.disaster.flood" probability="100"/>
</tile-type>
<tile-type id="model.tile.highSeas" basic-move-cost="3" basic-work-turns="4" is-water="true"
can-settle="false" is-connected="true">
<gen humidityMin="0" humidityMax="100" temperatureMin="-20" temperatureMax="40" altitudeMin="-3" altitudeMax="-2"/>
<production goods-type="model.goods.fish" value="2"/>
<production>
<output goods-type="model.goods.fish" value="2"/>
</production>
<ability id="model.ability.moveToEurope"/>
</tile-type>
<tile-type id="model.tile.greatRiver" basic-move-cost="3" basic-work-turns="4" is-water="true"
can-settle="false">
<gen humidityMin="0" humidityMax="100" temperatureMin="-20" temperatureMax="40"
altitudeMin="-3" altitudeMax="-2" />
<production goods-type="model.goods.fish" value="2"/>
<production>
<output goods-type="model.goods.fish" value="2"/>
</production>
<resource type="model.resource.fish" probability="100"/>
<disaster id="model.disaster.flood" probability="100"/>
</tile-type>
@ -728,10 +904,10 @@
tile child options: id
change child options: from, to
zIndex: tile improvements will be layered according to their z-index
tile overlays (e.g. hills) have a zIndex of 100, forests of 200,
resources of 400, lost city rumours of 500
-->
zIndex: tile improvements will be layered according to their z-index
tile overlays (e.g. hills) have a zIndex of 100, forests of 200,
resources of 400, lost city rumours of 500
-->
<tileimprovement-types>
<tileimprovement-type id="model.improvement.river" natural="true" add-work-turns="0" magnitude="1"
movement-cost="1" zIndex="150">
@ -1157,9 +1333,9 @@
</limit>
</unit-type>
<!--
<unit-type id="model.unit.milkmaid" extends="colonist"
expert-production="model.goods.grain" />
-->
<unit-type id="model.unit.milkmaid" extends="colonist"
expert-production="model.goods.grain" />
-->
<unit-type id="model.unit.revenger" offence="666" defence="666" movement="18" lineOfSight="3">
<ability id="model.ability.undead" value="true"/>
<ability id="model.ability.multipleAttacks" value="true"/>
@ -1186,118 +1362,167 @@
served first.
-->
<building-types>
<building-type id="model.building.townHall" basicProduction="3"
produces="model.goods.bells">
<building-type id="model.building.townHall">
<production>
<output goods-type="model.goods.bells" value="3"/>
</production>
<modifier id="model.goods.bells" type="additive" value="1">
<scope ability-id="model.ability.person" matchNegated="true"/>
</modifier>
</modifier>
</building-type>
<building-type id="model.building.carpenterHouse" basicProduction="3"
consumes="model.goods.lumber" produces="model.goods.hammers">
<building-type id="model.building.carpenterHouse">
<production>
<input goods-type="model.goods.lumber" value="3"/>
<output goods-type="model.goods.hammers" value="3"/>
</production>
<ability id="model.ability.build">
<scope type="model.unit.wagonTrain"/>
</ability>
</building-type>
<building-type id="model.building.lumberMill" extends="model.building.carpenterHouse"
basicProduction="6" upgradesFrom="model.building.carpenterHouse"
upgradesFrom="model.building.carpenterHouse"
required-population="3" upkeep="10">
<production>
<input goods-type="model.goods.lumber" value="6"/>
<output goods-type="model.goods.hammers" value="6"/>
</production>
<required-goods id="model.goods.hammers" value="52"/>
<modifier id="model.modifier.tileTypeChangeProduction" value="3" type="multiplicative">
<scope type="model.goods.lumber" />
</modifier>
</building-type>
<building-type id="model.building.blacksmithHouse" basicProduction="3"
consumes="model.goods.ore" produces="model.goods.tools">
<building-type id="model.building.blacksmithHouse">
<production>
<input goods-type="model.goods.ore" value="3"/>
<output goods-type="model.goods.tools" value="3"/>
</production>
<ability id="model.ability.build">
<scope type="model.equipment.tools"/>
<scope type="model.equipment.muskets"/>
</ability>
</building-type>
<building-type id="model.building.blacksmithShop" extends="model.building.blacksmithHouse"
basicProduction="6" upgradesFrom="model.building.blacksmithHouse" upkeep="5">
upgradesFrom="model.building.blacksmithHouse" upkeep="5">
<production>
<input goods-type="model.goods.ore" value="6"/>
<output goods-type="model.goods.tools" value="6"/>
</production>
<required-goods id="model.goods.hammers" value="64"/>
<required-goods id="model.goods.tools" value="20"/>
</building-type>
<building-type id="model.building.ironWorks" extends="model.building.blacksmithShop"
upgradesFrom="model.building.blacksmithShop" required-population="8" upkeep="15">
<production>
<input goods-type="model.goods.ore" value="6"/>
<output goods-type="model.goods.tools" value="9"/>
</production>
<required-goods id="model.goods.hammers" value="240"/>
<required-goods id="model.goods.tools" value="100"/>
<required-ability id="model.ability.buildFactory"/>
<modifier id="model.goods.tools" type="percentage" value="50">
<scope ability-id="model.ability.person" matchNegated="true"/>
</modifier>
<ability id="model.ability.expertsUseConnections" value="true"/>
</building-type>
<building-type id="model.building.tobacconistHouse" basicProduction="3"
consumes="model.goods.tobacco" produces="model.goods.cigars">
<building-type id="model.building.tobacconistHouse">
<production>
<input goods-type="model.goods.tobacco" value="3"/>
<output goods-type="model.goods.cigars" value="3"/>
</production>
</building-type>
<building-type id="model.building.tobacconistShop" extends="model.building.tobacconistHouse"
basicProduction="6" upgradesFrom="model.building.tobacconistHouse" upkeep="5">
upgradesFrom="model.building.tobacconistHouse" upkeep="5">
<production>
<input goods-type="model.goods.tobacco" value="6"/>
<output goods-type="model.goods.cigars" value="6"/>
</production>
<required-goods id="model.goods.hammers" value="64"/>
<required-goods id="model.goods.tools" value="20"/>
</building-type>
<building-type id="model.building.cigarFactory" extends="model.building.tobacconistShop"
upgradesFrom="model.building.tobacconistShop" required-population="8" upkeep="15">
<production>
<input goods-type="model.goods.tobacco" value="6"/>
<output goods-type="model.goods.cigars" value="9"/>
</production>
<required-goods id="model.goods.hammers" value="160"/>
<required-goods id="model.goods.tools" value="100"/>
<required-ability id="model.ability.buildFactory"/>
<modifier id="model.goods.cigars" type="percentage" value="50">
<scope ability-id="model.ability.person" matchNegated="true"/>
</modifier>
<ability id="model.ability.expertsUseConnections" value="true"/>
</building-type>
<building-type id="model.building.weaverHouse" basicProduction="3"
consumes="model.goods.cotton" produces="model.goods.cloth">
<building-type id="model.building.weaverHouse">
<production>
<input goods-type="model.goods.cotton" value="3"/>
<output goods-type="model.goods.cloth" value="3"/>
</production>
</building-type>
<building-type id="model.building.weaverShop" extends="model.building.weaverHouse"
basicProduction="6" upgradesFrom="model.building.weaverHouse" upkeep="5">
upgradesFrom="model.building.weaverHouse" upkeep="5">
<production>
<input goods-type="model.goods.cotton" value="6"/>
<output goods-type="model.goods.cloth" value="6"/>
</production>
<required-goods id="model.goods.hammers" value="64"/>
<required-goods id="model.goods.tools" value="20"/>
</building-type>
<building-type id="model.building.textileMill" extends="model.building.weaverShop"
upgradesFrom="model.building.weaverShop" required-population="8" upkeep="15">
<production>
<input goods-type="model.goods.cotton" value="6"/>
<output goods-type="model.goods.cloth" value="9"/>
</production>
<required-goods id="model.goods.hammers" value="160"/>
<required-goods id="model.goods.tools" value="100"/>
<required-ability id="model.ability.buildFactory"/>
<modifier id="model.goods.cloth" type="percentage" value="50">
<scope ability-id="model.ability.person" matchNegated="true"/>
</modifier>
<ability id="model.ability.expertsUseConnections" value="true"/>
</building-type>
<building-type id="model.building.distillerHouse" basicProduction="3"
consumes="model.goods.sugar" produces="model.goods.rum">
<building-type id="model.building.distillerHouse">
<production>
<input goods-type="model.goods.sugar" value="3"/>
<output goods-type="model.goods.rum" value="3"/>
</production>
</building-type>
<building-type id="model.building.rumDistillery" extends="model.building.distillerHouse"
basicProduction="6" upgradesFrom="model.building.distillerHouse" upkeep="5">
upgradesFrom="model.building.distillerHouse" upkeep="5">
<production>
<input goods-type="model.goods.sugar" value="6"/>
<output goods-type="model.goods.rum" value="6"/>
</production>
<required-goods id="model.goods.hammers" value="64"/>
<required-goods id="model.goods.tools" value="20"/>
</building-type>
<building-type id="model.building.rumFactory" extends="model.building.rumDistillery"
upgradesFrom="model.building.rumDistillery" required-population="8" upkeep="15">
<production>
<input goods-type="model.goods.sugar" value="6"/>
<output goods-type="model.goods.rum" value="9"/>
</production>
<required-goods id="model.goods.hammers" value="160"/>
<required-goods id="model.goods.tools" value="100"/>
<required-ability id="model.ability.buildFactory"/>
<modifier id="model.goods.rum" type="percentage" value="50">
<scope ability-id="model.ability.person" matchNegated="true"/>
</modifier>
<ability id="model.ability.expertsUseConnections" value="true"/>
</building-type>
<building-type id="model.building.furTraderHouse" basicProduction="3"
consumes="model.goods.furs" produces="model.goods.coats">
<building-type id="model.building.furTraderHouse">
<production>
<input goods-type="model.goods.furs" value="3"/>
<output goods-type="model.goods.coats" value="3"/>
</production>
</building-type>
<building-type id="model.building.furTradingPost" extends="model.building.furTraderHouse"
basicProduction="6" upgradesFrom="model.building.furTraderHouse" upkeep="5">
upgradesFrom="model.building.furTraderHouse" upkeep="5">
<production>
<input goods-type="model.goods.furs" value="6"/>
<output goods-type="model.goods.coats" value="6"/>
</production>
<required-goods id="model.goods.hammers" value="56"/>
<required-goods id="model.goods.tools" value="20"/>
</building-type>
<building-type id="model.building.furFactory" extends="model.building.furTradingPost"
upgradesFrom="model.building.furTradingPost" required-population="6" upkeep="15">
<production>
<input goods-type="model.goods.furs" value="6"/>
<output goods-type="model.goods.coats" value="9"/>
</production>
<required-goods id="model.goods.hammers" value="160"/>
<required-goods id="model.goods.tools" value="100"/>
<required-ability id="model.ability.buildFactory"/>
<modifier id="model.goods.coats" type="percentage" value="50">
<scope ability-id="model.ability.person" matchNegated="true"/>
</modifier>
<ability id="model.ability.expertsUseConnections" value="true"/>
</building-type>
<building-type id="model.building.schoolhouse" workplaces="1" minSkill="1" maxSkill="1"
@ -1317,8 +1542,11 @@
<required-goods id="model.goods.hammers" value="200"/>
<required-goods id="model.goods.tools" value="100"/>
</building-type>
<building-type id="model.building.armory" basicProduction="3" upkeep="5" priority="400"
consumes="model.goods.tools" produces="model.goods.muskets">
<building-type id="model.building.armory" upkeep="5" priority="400">
<production>
<input goods-type="model.goods.tools" value="3"/>
<output goods-type="model.goods.muskets" value="3"/>
</production>
<!-- priority should be less than the colony's build queue -->
<required-goods id="model.goods.hammers" value="52"/>
<ability id="model.ability.build">
@ -1326,42 +1554,53 @@
</ability>
</building-type>
<building-type id="model.building.magazine" extends="model.building.armory" upkeep="10"
basicProduction="6" upgradesFrom="model.building.armory" required-population="8">
upgradesFrom="model.building.armory" required-population="8">
<production>
<input goods-type="model.goods.tools" value="6"/>
<output goods-type="model.goods.muskets" value="6"/>
</production>
<required-goods id="model.goods.hammers" value="120"/>
<required-goods id="model.goods.tools" value="50"/>
</building-type>
<building-type id="model.building.arsenal" extends="model.building.magazine" upkeep="15"
upgradesFrom="model.building.magazine">
<production>
<input goods-type="model.goods.tools" value="6"/>
<output goods-type="model.goods.muskets" value="9"/>
</production>
<required-goods id="model.goods.hammers" value="240"/>
<required-goods id="model.goods.tools" value="100"/>
<required-ability id="model.ability.buildFactory"/>
<modifier id="model.goods.muskets" type="percentage" value="50">
<scope ability-id="model.ability.person" matchNegated="true"/>
</modifier>
<ability id="model.ability.expertsUseConnections" value="true"/>
</building-type>
<building-type id="model.building.chapel" workplaces="0" produces="model.goods.crosses">
<building-type id="model.building.chapel" workplaces="0">
<modifier id="model.goods.crosses" type="additive" value="1">
<scope ability-id="model.ability.person" matchNegated="true"/>
</modifier>
</modifier>
</building-type>
<building-type id="model.building.church" extends="model.building.chapel"
basicProduction="3" upgradesFrom="model.building.chapel"
upgradesFrom="model.building.chapel"
workplaces="3" required-population="3" upkeep="5">
<production>
<output goods-type="model.goods.crosses" value="3"/>
</production>
<required-goods id="model.goods.hammers" value="64"/>
<modifier id="model.goods.crosses" type="additive" value="1">
<scope ability-id="model.ability.person" matchNegated="true"/>
</modifier>
</modifier>
<ability id="model.ability.dressMissionary" value="true"/>
</building-type>
<building-type id="model.building.cathedral" extends="model.building.church"
basicProduction="6" upgradesFrom="model.building.church"
upgradesFrom="model.building.church"
required-population="8" upkeep="15">
<production>
<output goods-type="model.goods.crosses" value="6"/>
</production>
<required-goods id="model.goods.hammers" value="176"/>
<required-goods id="model.goods.tools" value="100"/>
<modifier id="model.goods.crosses" type="additive" value="1">
<scope ability-id="model.ability.person" matchNegated="true"/>
</modifier>
</modifier>
</building-type>
<building-type id="model.building.stockade" workplaces="0" required-population="3">
<required-goods id="model.goods.hammers" value="64"/>
@ -1399,8 +1638,11 @@
<required-goods id="model.goods.tools" value="20"/>
<modifier id="model.modifier.warehouseStorage" type="additive" value="100"/>
</building-type>
<building-type id="model.building.country" workplaces="0" priority="700"
consumes="model.goods.grain" produces="model.goods.horses">
<building-type id="model.building.country" workplaces="0" priority="700">
<production>
<input goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.horses" value="3"/>
</production>
<modifier id="model.modifier.breedingDivisor" type="additive" value="50"/>
<modifier id="model.modifier.breedingFactor" type="additive" value="2"/>
<modifier id="model.goods.horses" type="multiplicative" value="1.0"/>
@ -1413,6 +1655,10 @@
</building-type>
<building-type id="model.building.stables" extends="model.building.country"
upgradesFrom="model.building.country" upkeep="5">
<production>
<input goods-type="model.goods.grain" value="3"/>
<output goods-type="model.goods.horses" value="3"/>
</production>
<modifier id="model.modifier.breedingDivisor" type="multiplicative" value="0.5" />
<required-goods id="model.goods.hammers" value="64"/>
</building-type>
@ -1911,7 +2157,7 @@
burn-probability: determines the probability of missions getting burned
recruit-price-increase: determines how fast the price for recruiting colonists increases
lower-cap-increase: determines how fast the minimum price for recruiting colonists increases
-->
-->
<options>
<optionGroup id="difficultyLevels" recursive="false">
<optionGroup id="model.difficulty.veryEasy" editable="false">

View File

@ -106,8 +106,10 @@
</xs:complexType>
</xs:element>
<xs:element ref="production"/>
<xs:element ref="primary-production"/>
<xs:element ref="secondary-production"/>
<!-- @compat 0.10.x -->
<xs:element name="primary-production"/>
<xs:element name="secondary-production"/>
<!-- end @compat -->
<xs:element ref="ability"/>
<xs:element name="disaster">
<xs:complexType>
@ -124,6 +126,7 @@
<xs:attribute name="can-settle" type="xs:boolean"/>
<xs:attribute name="is-connected" type="xs:boolean"/>
<xs:attribute name="is-elevation" type="xs:boolean"/>
<xs:attribute name="productionLevel" type="xs:string"/>
</xs:complexType>
</xs:element>
@ -146,25 +149,12 @@
<xs:element name="production">
<xs:complexType>
<xs:attribute name="goods-type" use="required" type="GoodsTypeId"/>
<xs:attribute name="value" use="required" type="xs:nonNegativeInteger"/>
<xs:attribute name="tile-production" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="primary-production">
<xs:complexType>
<xs:attribute name="goods-type" use="required" type="GoodsTypeId"/>
<xs:attribute name="value" use="required" type="xs:nonNegativeInteger"/>
<xs:attribute name="tile-production" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="secondary-production">
<xs:complexType>
<xs:attribute name="goods-type" use="required" type="GoodsTypeId"/>
<xs:attribute name="value" use="required" type="xs:nonNegativeInteger"/>
<xs:attribute name="tile-production" type="xs:string"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="input" type="AbstractGoodsType"/>
<xs:element name="output" type="AbstractGoodsType"/>
</xs:choice>
<xs:attribute name="colonyCenterTile" type="xs:boolean"/>
<xs:attribute name="productionLevel" type="xs:string"/>
</xs:complexType>
</xs:element>
@ -288,7 +278,7 @@
<xs:element name="change">
<xs:complexType>
<xs:sequence minOccurs="0">
<xs:element ref="production" />
<xs:element name="production" type="AbstractGoodsType" />
</xs:sequence>
<xs:attribute name="from" use="required" type="TileTypeId"/>
<xs:attribute name="to" use="required" type="TileTypeId"/>
@ -364,14 +354,12 @@
<xs:element ref="ability"/>
<xs:element ref="modifier"/>
<xs:element ref="limit"/>
<xs:element ref="production"/>
</xs:choice>
<xs:attribute name="id" use="required" type="xs:ID"/>
<xs:attribute name="abstract" use="optional" type="xs:boolean" />
<xs:attribute name="extends" use="optional" type="xs:string" />
<xs:attribute name="workplaces" use="optional" type="xs:nonNegativeInteger"/>
<xs:attribute name="basicProduction" type="xs:nonNegativeInteger"/>
<xs:attribute name="produces" type="GoodsTypeId"/>
<xs:attribute name="consumes" type="GoodsTypeId"/>
<xs:attribute name="required-population" type="xs:nonNegativeInteger"/>
<xs:attribute name="priority" type="xs:nonNegativeInteger"/>
<xs:attribute name="minSkill" type="xs:int"/>
@ -1003,6 +991,11 @@
<xs:attribute name="factor" type="xs:int"/>
</xs:complexType>
<xs:complexType name="AbstractGoodsType">
<xs:attribute name="goods-type" use="required" type="GoodsTypeId"/>
<xs:attribute name="value" use="required" type="xs:nonNegativeInteger"/>
</xs:complexType>
<!-- Game Object Types -->
<xs:simpleType name="PercentageType">

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- XSD for specification version 0.74
<!-- XSD for specification version 0.75
CHANGELOG:
0.26: add capture-equipment
0.27: add limits
@ -50,6 +50,7 @@
0.72: allow preserveAttributes attribute to aid spec fragment authors
0.73: generalize preserveAttributes to preserve
0.74: add convertThreshold to settlement
0.75: add generalized production element
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
@ -157,8 +158,6 @@
<xs:element ref="skirmish"/>
<xs:element ref="resource"/>
<xs:element ref="production"/>
<xs:element ref="primary-production"/>
<xs:element ref="secondary-production"/>
<xs:element ref="ability"/>
<xs:element name="disaster">
<xs:complexType>
@ -176,6 +175,7 @@
<xs:attribute name="is-elevation" type="xs:boolean"/>
<xs:attribute name="can-settle" type="xs:boolean"/>
<xs:attribute name="is-connected" type="xs:boolean"/>
<xs:attribute name="productionLevel" type="xs:string"/>
</xs:complexType>
</xs:element>
@ -205,25 +205,12 @@
<xs:element name="production">
<xs:complexType>
<xs:attribute name="goods-type" use="required" type="GoodsTypeId"/>
<xs:attribute name="value" use="required" type="xs:nonNegativeInteger"/>
<xs:attribute name="tile-production" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="primary-production">
<xs:complexType>
<xs:attribute name="goods-type" use="required" type="GoodsTypeId"/>
<xs:attribute name="value" use="required" type="xs:nonNegativeInteger"/>
<xs:attribute name="tile-production" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="secondary-production">
<xs:complexType>
<xs:attribute name="goods-type" use="required" type="GoodsTypeId"/>
<xs:attribute name="value" use="required" type="xs:nonNegativeInteger"/>
<xs:attribute name="tile-production" type="xs:string"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="input" type="AbstractGoodsType"/>
<xs:element name="output" type="AbstractGoodsType"/>
</xs:choice>
<xs:attribute name="colonyCenterTile" type="xs:boolean"/>
<xs:attribute name="productionLevel" type="xs:string"/>
</xs:complexType>
</xs:element>
@ -350,7 +337,7 @@
<xs:element name="change">
<xs:complexType>
<xs:sequence>
<xs:element ref="production" />
<xs:element name="production" type="AbstractGoodsType"/>
</xs:sequence>
<xs:attribute name="from" use="required" type="TileTypeId"/>
<xs:attribute name="to" use="required" type="TileTypeId"/>
@ -427,15 +414,13 @@
<xs:element ref="ability"/>
<xs:element ref="modifier"/>
<xs:element ref="limit"/>
<xs:element ref="production"/>
</xs:choice>
<xs:attribute name="id" use="required" type="xs:ID"/>
<xs:attribute name="preserve" use="optional" type="xs:boolean"/>
<xs:attribute name="abstract" use="optional" type="xs:boolean" />
<xs:attribute name="extends" use="optional" type="xs:string" />
<xs:attribute name="workplaces" use="optional" type="xs:nonNegativeInteger"/>
<xs:attribute name="basicProduction" type="xs:nonNegativeInteger"/>
<xs:attribute name="produces" type="GoodsTypeId"/>
<xs:attribute name="consumes" type="GoodsTypeId"/>
<xs:attribute name="required-population" type="xs:nonNegativeInteger"/>
<xs:attribute name="priority" type="xs:nonNegativeInteger"/>
<xs:attribute name="minSkill" type="xs:int"/>
@ -1176,6 +1161,11 @@
<xs:attribute name="factor" type="xs:int"/>
</xs:complexType>
<xs:complexType name="AbstractGoodsType">
<xs:attribute name="goods-type" use="required" type="GoodsTypeId"/>
<xs:attribute name="value" use="required" type="xs:nonNegativeInteger"/>
</xs:complexType>
<!-- Game Object Types -->
<xs:simpleType name="PercentageType">

View File

@ -230,7 +230,7 @@ public abstract class BuildableType extends FreeColGameObjectType {
for (AbstractGoods goods : getRequiredGoods()) {
out.writeStartElement(REQUIRED_GOODS_TAG);
writeAttribute(out, ID_ATTRIBUTE_TAG, goods.getType());
writeAttribute(out, VALUE_TAG, goods.getAmount());
@ -264,10 +264,10 @@ public abstract class BuildableType extends FreeColGameObjectType {
requiredGoods = null;
limits = null;
}
super.readChildren(in);
}
/**
* {@inheritDoc}
*/

View File

@ -291,7 +291,7 @@ public class Building extends WorkLocation implements Named, Comparable<Building
* exclusive of that of the work location.
*
* Used below, only public for the test suite.
*
*
* @param unit The <code>Unit</code> to check.
* @return The maximum return from this unit.
*/
@ -563,7 +563,7 @@ public class Building extends WorkLocation implements Named, Comparable<Building
if (getGoodsOutputType() == goodsType
&& getType().getBasicProduction() > 0) {
production = (int)FeatureContainer.applyModifiers(0f,
getGame().getTurn(),
getGame().getTurn(),
getProductionModifiers(goodsType, unitType));
}
return Math.max(0, production);

View File

@ -19,6 +19,8 @@
package net.sf.freecol.common.model;
import java.util.ArrayList;
import java.util.List;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
@ -36,18 +38,20 @@ public final class BuildingType extends BuildableType
private int level = 1;
private int workPlaces = 3;
private int basicProduction = 3;
private int minSkill = UNDEFINED;
private int maxSkill = INFINITY;
private int upkeep = 0;
private int priority = Consumer.BUILDING_PRIORITY;
private GoodsType consumes = null;
private GoodsType produces = null;
private Modifier productionModifier = null;
private BuildingType upgradesFrom = null;
private BuildingType upgradesTo = null;
/**
* The possible production types of this building type.
*/
private final List<ProductionType> productionTypes
= new ArrayList<ProductionType>();
/**
* Creates a new <code>BuildingType</code> instance.
@ -88,7 +92,16 @@ public final class BuildingType extends BuildableType
* @return The base production of this building type.
*/
public int getBasicProduction() {
return basicProduction;
if (productionTypes == null || productionTypes.isEmpty()) {
return 0;
} else {
List<AbstractGoods> outputs = productionTypes.get(0).getOutputs();
if (outputs == null || outputs.isEmpty()) {
return 0;
} else {
return outputs.get(0).getAmount();
}
}
}
/**
@ -184,13 +197,49 @@ public final class BuildingType extends BuildableType
return !needsGoodsToBuild() && getUpgradesFrom() == null;
}
/**
* Get the <code>ProductionTypes</code> value.
*
* @return a <code>List<ProductionType></code> value
*/
public List<ProductionType> getProductionTypes() {
return productionTypes;
}
/**
* Return the production types available for the given production
* level. If the production level is null, all production levels
* will be returned.
*
* @param level the production level
* @return a <code>List<ProductionType></code> value
*/
public List<ProductionType> getProductionTypes(String level) {
List<ProductionType> result = new ArrayList<ProductionType>();
for (ProductionType productionType : productionTypes) {
if (level == null || level.equals(productionType.getProductionLevel())) {
result.add(productionType);
}
}
return result;
}
/**
* Get the type of goods consumed by this BuildingType.
*
* @return The consumed <code>GoodsType</code>.
*/
public GoodsType getConsumedGoodsType() {
return consumes;
if (productionTypes == null || productionTypes.isEmpty()) {
return null;
} else {
List<AbstractGoods> inputs = productionTypes.get(0).getInputs();
if (inputs == null || inputs.isEmpty()) {
return null;
} else {
return inputs.get(0).getType();
}
}
}
/**
@ -199,7 +248,16 @@ public final class BuildingType extends BuildableType
* @return The produced <code>GoodsType</code>.
*/
public GoodsType getProducedGoodsType() {
return produces;
if (productionTypes == null || productionTypes.isEmpty()) {
return null;
} else {
List<AbstractGoods> outputs = productionTypes.get(0).getOutputs();
if (outputs == null || outputs.isEmpty()) {
return null;
} else {
return outputs.get(0).getType();
}
}
}
/**
@ -210,6 +268,7 @@ public final class BuildingType extends BuildableType
*/
@Override
public final int getModifierIndex(Modifier modifier) {
GoodsType produces = getProducedGoodsType();
if (produces != null && produces.getId().equals(modifier.getId())) {
return Modifier.AUTO_PRODUCTION_INDEX;
} else {
@ -266,8 +325,6 @@ public final class BuildingType extends BuildableType
writeAttribute(out, WORKPLACES_TAG, workPlaces);
writeAttribute(out, BASIC_PRODUCTION_TAG, basicProduction);
if (minSkill != UNDEFINED) {
writeAttribute(out, MIN_SKILL_TAG, minSkill);
}
@ -284,13 +341,6 @@ public final class BuildingType extends BuildableType
writeAttribute(out, PRIORITY_TAG, priority);
}
if (consumes != null) {
writeAttribute(out, CONSUMES_TAG, consumes);
}
if (produces != null) {
writeAttribute(out, PRODUCES_TAG, produces);
}
}
/**
@ -302,7 +352,7 @@ public final class BuildingType extends BuildableType
super.readAttributes(in);
BuildingType parent = spec.getType(in, EXTENDS_TAG,
BuildingType parent = spec.getType(in, EXTENDS_TAG,
BuildingType.class, this);
upgradesFrom = spec.getType(in, UPGRADES_FROM_TAG,
@ -316,9 +366,6 @@ public final class BuildingType extends BuildableType
workPlaces = getAttribute(in, WORKPLACES_TAG, parent.workPlaces);
basicProduction = getAttribute(in, BASIC_PRODUCTION_TAG,
parent.basicProduction);
minSkill = getAttribute(in, MIN_SKILL_TAG, parent.minSkill);
maxSkill = getAttribute(in, MAX_SKILL_TAG, parent.maxSkill);
@ -327,16 +374,21 @@ public final class BuildingType extends BuildableType
priority = getAttribute(in, PRIORITY_TAG, parent.priority);
consumes = spec.getType(in, CONSUMES_TAG, GoodsType.class,
parent.consumes);
produces = spec.getType(in, PRODUCES_TAG, GoodsType.class,
parent.produces);
if (produces != null && basicProduction > 0) {
productionModifier = new Modifier(produces.getId(), this,
basicProduction,
Modifier.Type.ADDITIVE);
// @compat 0.10.6
int basicProduction = getAttribute(in, BASIC_PRODUCTION_TAG, -1);
if (basicProduction > 0) {
GoodsType consumes = spec.getType(in, CONSUMES_TAG, GoodsType.class,
parent.getConsumedGoodsType());
GoodsType produces = spec.getType(in, PRODUCES_TAG, GoodsType.class,
parent.getProducedGoodsType());
productionTypes.add(new ProductionType(consumes, produces, basicProduction));
if (produces != null) {
productionModifier = new Modifier(produces.getId(), this,
basicProduction,
Modifier.Type.ADDITIVE);
}
}
// end @compat
if (parent != this) { // Handle "extends" for super-type fields
if (!hasAttribute(in, REQUIRED_POPULATION_TAG)) {
@ -350,6 +402,41 @@ public final class BuildingType extends BuildableType
}
}
/**
* {@inheritDoc}
*/
@Override
protected void readChild(XMLStreamReader in) throws XMLStreamException {
final Specification spec = getSpecification();
if ("production".equals(in.getLocalName())) {
ProductionType productionType = new ProductionType(getSpecification());
productionType.readFromXML(in);
productionTypes.add(productionType);
if (!(productionType.getOutputs() == null
|| productionType.getOutputs().isEmpty())) {
AbstractGoods output = productionType.getOutputs().get(0);
productionModifier = new Modifier(output.getType().getId(), this,
output.getAmount(),
Modifier.Type.ADDITIVE);
}
} else {
super.readChild(in);
}
}
/**
* {@inheritDoc}
*/
@Override
protected void writeChildren(XMLStreamWriter out) throws XMLStreamException {
super.writeChildren(out);
for (ProductionType productionType : productionTypes) {
productionType.toXMLImpl(out);
}
}
// @compat 0.9.x
/**
* Compatibility hack, called from the specification reader when

View File

@ -52,6 +52,11 @@ public class ProductionType extends FreeColObject {
*/
private List<AbstractGoods> inputs;
public ProductionType(Specification specification) {
setSpecification(specification);
}
/**
* Creates a new production type that consumes no raw materials
* and produces the given output.
@ -88,6 +93,25 @@ public class ProductionType extends FreeColObject {
productionLevel = level;
}
/**
* Convenience constructor for a new <code>ProductionType</code>
* instance with a single input and output.
*
* @param input a <code>GoodsType</code> value
* @param output a <code>GoodsType</code> value
* @param amount an <code>int</code> value
*/
public ProductionType(GoodsType input, GoodsType output, int amount) {
if (input != null) {
inputs = new ArrayList<AbstractGoods>();
inputs.add(new AbstractGoods(input, amount));
}
if (output != null) {
outputs = new ArrayList<AbstractGoods>();
outputs.add(new AbstractGoods(output, amount));
}
}
/**
* Creates a new <code>ProductionType</code> instance.
*
@ -171,6 +195,12 @@ public class ProductionType extends FreeColObject {
this.productionLevel = newProductionLevel;
}
public boolean appliesTo(String level) {
return (level == null
|| productionLevel == null
|| level.equals(productionLevel));
}
/**
* Makes an XML-representation of this object.
@ -187,36 +217,78 @@ public class ProductionType extends FreeColObject {
if (productionLevel != null) {
out.writeAttribute("productionLevel", productionLevel);
}
for (AbstractGoods input : inputs) {
input.toXML(out, "input");
if (inputs != null) {
for (AbstractGoods input : inputs) {
out.writeStartElement("input");
out.writeAttribute("goods-type", input.getType().getId());
out.writeAttribute("value", Integer.toString(input.getAmount()));
out.writeEndElement();
}
}
for (AbstractGoods output : outputs) {
output.toXML(out, "output");
if (outputs != null) {
for (AbstractGoods output : outputs) {
out.writeStartElement("output");
out.writeAttribute("goods-type", output.getType().getId());
out.writeAttribute("value", Integer.toString(output.getAmount()));
out.writeEndElement();
}
}
out.writeEndElement();
}
/**
* Initializes this object from an XML-representation of this object.
*
* @param in The input stream with the XML.
* @throws XMLStreamException if there are any problems writing
* to the stream.
*/
public void readFromXML(XMLStreamReader in) throws XMLStreamException {
public void readAttributes(XMLStreamReader in) throws XMLStreamException {
colonyCenterTile = "true".equalsIgnoreCase(in.getAttributeValue(null, "colonyCenterTile"));
productionLevel = in.getAttributeValue(null, "productionLevel");
}
while (in.nextTag() != XMLStreamConstants.END_ELEMENT) {
String childName = in.getLocalName();
GoodsType type = getSpecification().getGoodsType(in.getAttributeValue(null, "goods-type"));
int amount = Integer.parseInt(in.getAttributeValue(null, "value"));
if ("input".equals(childName)) {
inputs.add(new AbstractGoods(type, amount));
} else if ("output".equals(childName)) {
outputs.add(new AbstractGoods(type, amount));
public void readChild(XMLStreamReader in) throws XMLStreamException {
String childName = in.getLocalName();
GoodsType type = getSpecification().getGoodsType(in.getAttributeValue(null, "goods-type"));
int amount = Integer.parseInt(in.getAttributeValue(null, "value"));
if ("input".equals(childName)) {
if (inputs == null) {
inputs = new ArrayList<AbstractGoods>(1);
}
inputs.add(new AbstractGoods(type, amount));
in.nextTag();
} else if ("output".equals(childName)) {
if (outputs == null) {
outputs = new ArrayList<AbstractGoods>(1);
}
outputs.add(new AbstractGoods(type, amount));
in.nextTag();
} else {
super.readChild(in);
}
}
public String toString() {
StringBuilder result = new StringBuilder();
result.append("[production: " + productionLevel);
if (colonyCenterTile) {
result.append(", colony center tile");
}
if (!(inputs == null || inputs.isEmpty())) {
result.append(" [inputs: ");
for (AbstractGoods input : inputs) {
result.append(input);
result.append(", ");
}
int length = result.length();
result.replace(length - 2, length, "]");
}
if (!(outputs == null || outputs.isEmpty())) {
result.append(" [outputs: ");
for (AbstractGoods output : outputs) {
result.append(output);
result.append(", ");
}
int length = result.length();
result.replace(length - 2, length, "]");
}
result.append("]");
return result.toString();
}
}

View File

@ -21,6 +21,7 @@ package net.sf.freecol.common.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -66,19 +67,6 @@ public final class TileType extends FreeColGameObjectType {
*/
private boolean connected;
/**
* The primary goods produced by this tile type. In the original
* game, this is always food or null (in the case of the arctic).
*/
private AbstractGoods primaryGoods = null;
/**
* The secondary goods produced by this tile type. In the original
* game, this is never food, but may be null (in the case of the
* arctic).
*/
private AbstractGoods secondaryGoods = null;
/**
* The disasters that may strike this type of tile.
*/
@ -86,19 +74,15 @@ public final class TileType extends FreeColGameObjectType {
= new ArrayList<RandomChoice<Disaster>>();
/**
* A list of AbstractGoods produced by this TileType when it is
* not the colony center tile.
* The possible production types of this tile type. This includes
* the production types available if a tile of this type is a
* colony center tile.
*/
private List<AbstractGoods> production = new ArrayList<AbstractGoods>();
private final List<ProductionType> productionTypes
= new ArrayList<ProductionType>();
private Map<String, AbstractGoods> primaryGoodsMap =
new HashMap<String, AbstractGoods>();
private Map<String, AbstractGoods> secondaryGoodsMap =
new HashMap<String, AbstractGoods>();
private Map<String, Map<GoodsType, AbstractGoods>> productionMap =
new HashMap<String, Map<GoodsType, AbstractGoods>>();
// TODO: make this hack go away!
private String productionLevel = null;
// ------------------------------------------------------------ constructor
@ -223,27 +207,47 @@ public final class TileType extends FreeColGameObjectType {
return getModifierSet(goodsType.getId());
}
/**
* Returns the production types available for the given combination
* of colony center tile and production level. If the production
* level is null, all production levels will be returned.
*
* @param center whether the tile is a colony center tile
* @param level the production level
* @return a <code>List<ProductionType></code> value
*/
public List<ProductionType> getProductionTypes(boolean center, String level) {
List<ProductionType> result = new ArrayList<ProductionType>();
for (ProductionType productionType : productionTypes) {
if (productionType.isColonyCenterTile() == center
&& productionType.appliesTo(level)) {
result.add(productionType);
}
}
return result;
}
public List<ProductionType> getProductionTypes() {
return productionTypes;
}
/**
* Get the <code>PrimaryGoods</code> value.
*
* @return an <code>AbstractGoods</code> value
*/
public AbstractGoods getPrimaryGoods() {
return primaryGoods;
}
/**
* Get the <code>PrimaryGoods</code> value at the tileProduction level
* with the ID given.
*
* @return an <code>AbstractGoods</code> value
*/
public AbstractGoods getPrimaryGoods(String tileProduction) {
AbstractGoods result = primaryGoodsMap.get(tileProduction);
if (result == null) {
result = primaryGoodsMap.get(null);
List<ProductionType> production = getProductionTypes(true, productionLevel);
if (production == null || production.isEmpty()) {
return null;
} else {
List<AbstractGoods> outputs = production.get(0).getOutputs();
if (outputs == null || outputs.isEmpty()) {
return null;
} else {
return outputs.get(0);
}
}
return result;
}
/**
@ -254,48 +258,27 @@ public final class TileType extends FreeColGameObjectType {
* @return a <code>boolean</code> value
*/
public boolean isPrimaryGoodsType(GoodsType type) {
AbstractGoods primaryGoods = getPrimaryGoods();
return (primaryGoods != null && primaryGoods.getType() == type);
}
/**
* Set the <code>PrimaryGoods</code> value.
*
* @param newPrimaryGoods The new PrimaryGoods value.
*/
public void setPrimaryGoods(final AbstractGoods newPrimaryGoods) {
this.primaryGoods = newPrimaryGoods;
}
/**
* Get the <code>SecondaryGoods</code> value.
*
* @return an <code>AbstractGoods</code> value
*/
public AbstractGoods getSecondaryGoods() {
return secondaryGoods;
}
/**
* Get the <code>SecondaryGoods</code> value at the tileProduction level
* with the ID given.
*
* @return an <code>AbstractGoods</code> value
*/
public AbstractGoods getSecondaryGoods(String tileProduction) {
AbstractGoods result = secondaryGoodsMap.get(tileProduction);
if (result == null) {
result = secondaryGoodsMap.get(null);
List<ProductionType> production = getProductionTypes(true, productionLevel);
if (production == null || production.isEmpty()) {
return null;
} else {
List<AbstractGoods> outputs = production.get(0).getOutputs();
if (outputs == null || outputs.size() < 2) {
return null;
} else {
return outputs.get(1);
}
}
return result;
}
/**
* Set the <code>SecondaryGoods</code> value.
*
* @param newSecondaryGoods The new SecondaryGoods value.
*/
public void setSecondaryGoods(final AbstractGoods newSecondaryGoods) {
this.secondaryGoods = newSecondaryGoods;
}
/**
@ -306,9 +289,11 @@ public final class TileType extends FreeColGameObjectType {
* @return a <code>boolean</code> value
*/
public boolean isSecondaryGoodsType(GoodsType type) {
AbstractGoods secondaryGoods = getSecondaryGoods();
return (secondaryGoods != null && secondaryGoods.getType() == type);
}
/**
* Returns a list of all types of AbstractGoods produced by this
* TileType when it is not the colony center tile.
@ -316,28 +301,16 @@ public final class TileType extends FreeColGameObjectType {
* @return a <code>List<AbstractGoods></code> value
*/
public List<AbstractGoods> getProduction() {
List<AbstractGoods> production = new ArrayList<AbstractGoods>();
for (ProductionType productionType : getProductionTypes(false, productionLevel)) {
List<AbstractGoods> outputs = productionType.getOutputs();
if (!(outputs == null || outputs.isEmpty())) {
production.addAll(outputs);
}
}
return production;
}
/**
* Returns a list of all types of AbstractGoods produced by this
* TileType when it is not the colony center tile.
*
* @param tileProduction
* @return a <code>List<AbstractGoods></code> value
*/
public List<AbstractGoods> getProduction(String tileProduction) {
Map<GoodsType, AbstractGoods> result = new HashMap<GoodsType, AbstractGoods>();
Map<GoodsType, AbstractGoods> defaultMap = productionMap.get(null);
Map<GoodsType, AbstractGoods> difficultyMap = productionMap.get(tileProduction);
if (defaultMap != null) {
result.putAll(defaultMap);
}
if (difficultyMap != null) {
result.putAll(difficultyMap);
}
return new ArrayList<AbstractGoods>(result.values());
}
public List<RandomChoice<ResourceType>> getWeightedResources() {
return resourceType;
@ -400,25 +373,28 @@ public final class TileType extends FreeColGameObjectType {
*/
@Override
public void applyDifficultyLevel(OptionGroup difficultyLevel) {
String tileProduction = ((StringOption) difficultyLevel.getOption("model.option.tileProduction"))
productionLevel = ((StringOption) difficultyLevel.getOption("model.option.tileProduction"))
.getValue();
primaryGoods = getPrimaryGoods(tileProduction);
secondaryGoods = getSecondaryGoods(tileProduction);
production = getProduction(tileProduction);
// remove old modifiers
for (GoodsType goodsType : getSpecification().getGoodsTypeList()) {
removeModifiers(goodsType.getId());
}
// add new modifiers
for (AbstractGoods goods : production) {
addModifier(new Modifier(goods.getType().getId(), this,
goods.getAmount(),
Modifier.Type.ADDITIVE));
for (ProductionType productionType : productionTypes) {
if (productionType.appliesTo(productionLevel)) {
List<AbstractGoods> outputs = productionType.getOutputs();
if (!(outputs == null || outputs.isEmpty())) {
for (AbstractGoods goods : outputs) {
addModifier(new Modifier(goods.getType().getId(), this,
goods.getAmount(),
Modifier.Type.ADDITIVE));
}
}
}
}
}
/**
/**
* Makes an XML-representation of this object.
*
* @param out The output stream.
@ -448,6 +424,7 @@ public final class TileType extends FreeColGameObjectType {
out.writeAttribute("is-elevation", Boolean.toString(elevation));
out.writeAttribute("is-connected", Boolean.toString(connected));
out.writeAttribute("can-settle", Boolean.toString(canSettle));
out.writeAttribute("productionLevel", productionLevel);
}
/**
@ -471,44 +448,8 @@ public final class TileType extends FreeColGameObjectType {
out.writeAttribute("altitudeMax", Integer.toString(altitude[1]));
out.writeEndElement();
for (Map.Entry<String, AbstractGoods> entry
: primaryGoodsMap.entrySet()) {
out.writeStartElement("primary-production");
out.writeAttribute("goods-type",
entry.getValue().getType().getId());
out.writeAttribute(VALUE_TAG,
Integer.toString(entry.getValue().getAmount()));
if (entry.getKey() != null) {
out.writeAttribute("tile-production", entry.getKey());
}
out.writeEndElement();
}
for (Map.Entry<String, AbstractGoods> entry
: secondaryGoodsMap.entrySet()) {
out.writeStartElement("secondary-production");
out.writeAttribute("goods-type",
entry.getValue().getType().getId());
out.writeAttribute(VALUE_TAG,
Integer.toString(entry.getValue().getAmount()));
if (entry.getKey() != null) {
out.writeAttribute("tile-production", entry.getKey());
}
out.writeEndElement();
}
for (Map.Entry<String, Map<GoodsType, AbstractGoods>> entry
: productionMap.entrySet()) {
for (AbstractGoods goods : entry.getValue().values()) {
out.writeStartElement("production");
out.writeAttribute("goods-type", goods.getType().getId());
out.writeAttribute(VALUE_TAG,
Integer.toString(goods.getAmount()));
if (entry.getKey() != null) {
out.writeAttribute("tile-production", entry.getKey());
}
out.writeEndElement();
}
for (ProductionType productionType : productionTypes) {
productionType.toXML(out);
}
for (RandomChoice<ResourceType> choice : resourceType) {
@ -549,6 +490,7 @@ public final class TileType extends FreeColGameObjectType {
elevation = getAttribute(in, "is-elevation", false);
canSettle = getAttribute(in, "can-settle", !water);
connected = getAttribute(in, "is-connected", false);
productionLevel = in.getAttributeValue(null, "productionLevel");
}
/**
@ -568,26 +510,37 @@ public final class TileType extends FreeColGameObjectType {
altitude[0] = getAttribute(in, "altitudeMin", 0);
altitude[1] = getAttribute(in, "altitudeMax", 0);
in.nextTag(); // close this element
} else if ("production".equals(childName)
&& in.getAttributeValue(null, "goods-type") == null) {
// new production style
ProductionType productionType = new ProductionType(getSpecification());
productionType.readFromXML(in);
productionTypes.add(productionType);
} else if ("production".equals(childName)
|| "primary-production".equals(childName)
|| "secondary-production".equals(childName)) {
// @compat 0.10.6
GoodsType type = getSpecification().getGoodsType(in.getAttributeValue(null, "goods-type"));
int amount = Integer.parseInt(in.getAttributeValue(null, VALUE_TAG));
AbstractGoods goods = new AbstractGoods(type, amount);
String tileProduction = in.getAttributeValue(null, "tile-production");
// CAUTION: this only works if the primary production is
// defined before the secondary production
if ("primary-production".equals(childName)) {
primaryGoodsMap.put(tileProduction, goods);
productionTypes.add(new ProductionType(goods, true, tileProduction));
} else if ("secondary-production".equals(childName)) {
secondaryGoodsMap.put(tileProduction, goods);
} else {
Map<GoodsType, AbstractGoods> oldValue = productionMap.get(tileProduction);
if (oldValue == null) {
oldValue = new HashMap<GoodsType, AbstractGoods>();
productionMap.put(tileProduction, oldValue);
for (ProductionType productionType : productionTypes) {
if (productionType.isColonyCenterTile()
&& (tileProduction == null
|| tileProduction.equals(productionType.getProductionLevel()))) {
productionType.getOutputs().add(goods);
}
}
oldValue.put(type, goods);
} else {
productionTypes.add(new ProductionType(goods, false, tileProduction));
}
in.nextTag(); // close this element
// end compat
} else if ("resource".equals(childName)) {
ResourceType type = getSpecification().getResourceType(in.getAttributeValue(null, "type"));
int probability = getAttribute(in, "probability", 100);

View File

@ -45,6 +45,11 @@ public abstract class WorkLocation extends UnitLocation implements Ownable {
*/
private Colony colony;
/**
* The production type of this WorkLocation.
*/
private ProductionType productionType;
/**
* Constructor for ServerWorkLocation.
@ -87,6 +92,24 @@ public abstract class WorkLocation extends UnitLocation implements Ownable {
super(game, id);
}
/**
* Get the <code>ProductionType</code> value.
*
* @return a <code>ProductionType</code> value
*/
public final ProductionType getProductionType() {
return productionType;
}
/**
* Set the <code>ProductionType</code> value.
*
* @param newProductionType The new ProductionType value.
*/
public final void setProductionType(final ProductionType newProductionType) {
this.productionType = newProductionType;
}
/**
* Set the <code>Colony</code> value.
*
@ -393,4 +416,26 @@ public abstract class WorkLocation extends UnitLocation implements Ownable {
out.writeAttribute("colony", colony.getId());
}
/**
* {@inheritDoc}
*/
public void readChild(XMLStreamReader in) throws XMLStreamException {
if ("production".equals(in.getLocalName())) {
productionType = new ProductionType(in);
} else {
super.readChild(in);
}
}
/**
* {@inheritDoc}
*/
public void writeChildren(XMLStreamWriter out) throws XMLStreamException {
super.writeChildren(out);
if (productionType != null) {
productionType.toXML(out);
}
}
}

View File

@ -745,6 +745,7 @@ System.err.println("NEWPAGER");
Colony colony = getStandardColony(8);
List<Unit> units = colony.getUnitList();
assertEquals(8, units.size());
// make sure there are enough goods to get started
//colony.addGoods(spec().getGoodsType("model.goods.food"), 100);
colony.addGoods(spec().getGoodsType("model.goods.ore"), 100);
@ -780,9 +781,9 @@ System.err.println("NEWPAGER");
smithy.upgrade();
armory.upgrade();
assertEquals(6, smithy.getType().getBasicProduction());
assertEquals(9, smithy.getType().getBasicProduction());
assertEquals(18, smithy.getTotalProductionOf(toolsType));
assertEquals(6, armory.getType().getBasicProduction());
assertEquals(9, armory.getType().getBasicProduction());
//assertEquals("According to bug report #3430371, the arsenal does not enjoy "
// + "the usual factory level production bonus of 50%",
// 12, armory.getTotalProductionOf(musketsType));

View File

@ -62,14 +62,13 @@ public class SerializationTest extends FreeColTestCase {
private void validateMap(String name) throws Exception {
try{
try {
Validator mapValidator = buildValidator("schema/data/data-savedGame.xsd");
FreeColSavegameFile mapFile = new FreeColSavegameFile(new File(name));
mapValidator.validate(new StreamSource(mapFile.getSavegameInputStream()));
}
catch(SAXParseException e){
} catch(SAXParseException e) {
String errMsg = e.getMessage()
+ " at line=" + e.getLineNumber()
+ " column=" + e.getColumnNumber();
@ -77,6 +76,16 @@ public class SerializationTest extends FreeColTestCase {
}
}
private void logParseFailure(SAXParseException e, String serialized) {
int col = e.getColumnNumber();
String errMsg = e.getMessage()
+ "\nAt line=" + e.getLineNumber()
+ ", column=" + col + ":\n"
+ serialized.substring(Math.max(0, col - 100),
Math.min(col + 100, serialized.length()));
fail(errMsg);
}
public void testValidation() throws Exception {
Game game = ServerTestHelper.startServerGame(getTestMap(true));
@ -86,13 +95,18 @@ public class SerializationTest extends FreeColTestCase {
ServerTestHelper.newTurn();
ServerTestHelper.newTurn();
String serialized = null;
try {
Validator validator = buildValidator("schema/data/data-game.xsd");
validator.validate(buildSource(game, player, true, true));
serialized = serialize(game, player, true, true);
validator.validate(new StreamSource(new StringReader(serialized)));
} catch(SAXParseException e){
int col = e.getColumnNumber();
String errMsg = e.getMessage()
+ " at line=" + e.getLineNumber()
+ " column=" + e.getColumnNumber();
+ "\nAt line=" + e.getLineNumber()
+ ", column=" + col + ":\n"
+ serialized.substring(Math.max(0, col - 100),
Math.min(col + 100, serialized.length()));
fail(errMsg);
}

View File

@ -123,14 +123,16 @@ public final class SpecificationTest extends FreeColTestCase {
Specification spec = spec();
// Percentage Modifier
/*
BuildingType ironWorks = spec.getBuildingType("model.building.ironWorks");
Modifier modifier = ironWorks.getModifierSet("model.goods.tools").iterator().next();
assertEquals(Modifier.Type.PERCENTAGE, modifier.getType());
assertEquals(50f, modifier.getValue());
*/
// Additive Modifier
BuildingType depot = spec.getBuildingType("model.building.depot");
modifier = depot.getModifierSet("model.modifier.warehouseStorage").iterator().next();
Modifier modifier = depot.getModifierSet("model.modifier.warehouseStorage").iterator().next();
assertEquals(Modifier.Type.ADDITIVE, modifier.getType());
assertEquals(100f, modifier.getValue());

View File

@ -287,11 +287,12 @@ public class TileTest extends FreeColTestCase {
public void testPotential() {
Game game = getStandardGame();
Tile tile = new Tile(game, mountains, 0, 0);
assertEquals(0,tile.potential(food, null));
assertEquals(1,tile.potential(silver, null));
assertEquals(0, tile.potential(food, null));
assertEquals(1, tile.getType().getProductionOf(silver, null));
assertEquals(1, tile.potential(silver, null));
tile.addResource(new Resource(game, tile, silverResource));
assertEquals(0,tile.potential(food, null));
assertEquals(3,tile.potential(silver, null));
assertEquals(0, tile.potential(food, null));
assertEquals(3, tile.potential(silver, null));
}
public void testMaximumPotential() {

View File

@ -130,7 +130,7 @@ public class MapGeneratorTest extends FreeColTestCase {
} catch (FreeColException e) {
fail();
}
// Check that the map is created at all
assertNotNull(g.getMap());
@ -164,7 +164,7 @@ public class MapGeneratorTest extends FreeColTestCase {
/**
* Make sure that each tribe has exactly one capital
*
*
*/
public void testIndianCapital() {
((FileOption) spec().getOption(MapGeneratorOptions.IMPORT_FILE)).setValue(null);
@ -206,11 +206,11 @@ public class MapGeneratorTest extends FreeColTestCase {
if (s.isCapital())
capitals++;
}
if (settlements > 0)
if (settlements > 0)
assertEquals(1, capitals);
}
}
public void testImportMap() {
/**
* Make sure we can import all distributed maps.
@ -277,5 +277,5 @@ public class MapGeneratorTest extends FreeColTestCase {
assertFalse(northAtlantic.isPacific());
assertFalse(northAtlantic.isDiscoverable());
assertNull(northAtlantic.getDiscoverableRegion());
}
}
}