mirror of https://github.com/FreeCol/freecol.git
Merge all changes from 0.9.x
This commit is contained in:
parent
71f54b5575
commit
10e171681f
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
-->
|
||||
<!-- $Revision$ -->
|
||||
<!-- specification version 0.20 -->
|
||||
<!-- specification version 0.21 -->
|
||||
<!-- in case of incompatible changes, please update version number and
|
||||
XSD schema for validation. -->
|
||||
<freecol-specification>
|
||||
|
@ -1313,7 +1313,7 @@
|
|||
<event id="model.event.seeAllColonies"/>
|
||||
</founding-father>
|
||||
<founding-father id="model.foundingFather.hernandoDeSoto" type="exploration"
|
||||
weight1="10" weight2="2" weight3="2">
|
||||
weight1="5" weight2="10" weight3="5">
|
||||
<modifier id="model.modifier.lineOfSightBonus" type="additive" value="1">
|
||||
<scope ability-id="model.ability.navalUnit" ability-value="false"/>
|
||||
</modifier>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
-->
|
||||
<!-- $Revision$ -->
|
||||
<!-- specification version 0.20 -->
|
||||
<!-- specification version 0.21 -->
|
||||
<!-- in case of incompatible changes, please update version number and
|
||||
XSD schema for validation. -->
|
||||
<freecol-specification>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
-->
|
||||
<!-- $Revision$ -->
|
||||
<!-- specification version 0.20 -->
|
||||
<!-- specification version 0.21 -->
|
||||
<!-- in case of incompatible changes, please update version number and
|
||||
XSD schema for validation. -->
|
||||
<freecol-specification>
|
||||
|
|
516
doc/FreeCol.tex
516
doc/FreeCol.tex
|
@ -194,7 +194,11 @@ without any changes in "Info.plist".
|
|||
FreeCol uses context menus in several places. On most platforms,
|
||||
context menus are opened with a click of the right mouse button. If
|
||||
you have only one mouse button, holding down the \texttt{control} key
|
||||
while clicking the mouse button should also work.
|
||||
while clicking the mouse button should also work. Some versions of
|
||||
Java on Windows are unable to display context menus that extend beyond
|
||||
the game window correctly. As we are unable to fix that, we display
|
||||
the context menu in the top left corner of the game window in these
|
||||
cases.
|
||||
|
||||
|
||||
\hypertarget{Compiling FreeCol}{\section{Compiling FreeCol}}
|
||||
|
@ -725,10 +729,7 @@ possess.
|
|||
\item The \Report{Continental Congress Advisor} tells you which
|
||||
Founding Fathers are already present in the \hyperlink{Continental
|
||||
Congress}{Continental Congress} and which Founding Father is currently
|
||||
being elected. It also tells you how many Liberty Bells each of your
|
||||
colonies is producing, and whether they have already built the
|
||||
\hyperlink{Printing Press}{Printing Press} and the
|
||||
\hyperlink{Newspaper}{Newspaper}.
|
||||
being elected.
|
||||
\item The \Report{Military Advisor} informs you of the deployment of
|
||||
your military units, as well as the strength of the \hyperlink{Royal
|
||||
Expeditionary Force}{Royal Expeditionary Force}.
|
||||
|
@ -758,6 +759,9 @@ and which colonies produce a surplus of these materials.
|
|||
important events that took place during the game, such as the first
|
||||
meeting with native tribes, the foundation and abandonment of
|
||||
colonies, among other things.
|
||||
\item The \Report{Production Report} provides you with an overview of
|
||||
the production of up to four different kinds of goods in your
|
||||
colonies, as well as the buildings that produce these goods.
|
||||
|
||||
\end{itemize}
|
||||
|
||||
|
@ -1037,7 +1041,8 @@ The figure \ref{europe_panel_fig} represents the Europe panel.
|
|||
In this panel, you can control the ships sailing between America and
|
||||
Europe, as well as the ships currently docked in Europe. You can also
|
||||
buy goods, recruit, purchase and train units. Units recruited,
|
||||
purchased or trained are in the Docks Area in the Europe panel.
|
||||
purchased or trained are visible in the Docks Area in the Europe
|
||||
panel.
|
||||
|
||||
If a ship has set sail for Europe or America, you can change its
|
||||
direction by dragging it from the Going to America box to the Going
|
||||
|
@ -1069,7 +1074,7 @@ Units present in Europe can also be armed, mounted, equipped with
|
|||
tools or blessed as missionaries in Europe. In order to select one of
|
||||
these actions, you need to right click on the unit. Note that you will
|
||||
have to pay for the arms, horses or tools required to equip your
|
||||
units.
|
||||
units. Blessing a missionary, however, is free.
|
||||
|
||||
In order to send a ship back to the New World, you must drag it to the
|
||||
Going to America section of the Europe panel, or press the ``Set
|
||||
|
@ -1091,12 +1096,10 @@ this panel, colonists can be assigned to cultivate tiles surrounding
|
|||
the colony, to work in buildings, defend the colony against attackers
|
||||
or wait outside of the colony.
|
||||
|
||||
The colony panel consists of several panels and control elements with
|
||||
different functions. At the top of the panel, you can see a select box
|
||||
displaying the name of the colony, which can be used to select a
|
||||
different colony. Next to the colony's name, you can see the
|
||||
production panel, which shows how much food, horses, bells and crosses
|
||||
your colony is producing.
|
||||
The select box at the top left of the panel displaying the name of the
|
||||
colony can be used to select a different colony. Next to the colony's
|
||||
name, the production panel, shows all the goods your colony is
|
||||
producing.
|
||||
|
||||
Below colony name, you can see the area surrounding the colony to the
|
||||
left and a scroll pane displaying the buildings of the colony to the
|
||||
|
@ -1104,22 +1107,26 @@ right. You can drag and drop a unit on a tile or a building. The tiles
|
|||
surrounding the colony can produce several kinds of goods, however. If
|
||||
the unit is not producing the right kind of goods, you can right click
|
||||
on the unit to select a different kind of work. If a tile has a red
|
||||
border, then it can not be used--- it is either assigned to another
|
||||
border, then it can not be used --- it is either assigned to another
|
||||
colony or settlement, or is occupied by a hostile unit, or is a water
|
||||
tile which can not be used until you have built \hyperlink{Dock}{docks}.
|
||||
Note that if you drag a unit onto a tile used by the natives you may
|
||||
be offered the chance to purchase the land.
|
||||
|
||||
Below the surrounding area, you can see a status panel that tells you
|
||||
how many colonists support independence and how many support the
|
||||
crown. Below the status panel, the port panel shows you any ships or
|
||||
wagon trains in the colony. If there is at least one unit present, the
|
||||
cargo panel below the port panel shows you the cargo of the selected
|
||||
carrier (if any).
|
||||
Below the surrounding area, you can see the population panel, which
|
||||
displays the size of your colony, the number and percentage of
|
||||
colonists that support independence, the number and percentage of
|
||||
colonists that support the crown, as well as the current production
|
||||
bonus.
|
||||
|
||||
Below the status panel, the port panel shows you any ships or wagon
|
||||
trains in the colony. If there is at least one unit present, the cargo
|
||||
panel below the port panel shows you the cargo of the selected carrier
|
||||
(if any).
|
||||
|
||||
On the right hand side of the panel, you can see the buildings panel,
|
||||
which displays an image for every building in the colony, as well as
|
||||
the building or unit currenlty being built. You can see the units
|
||||
the building or unit currently being built. You can see the units
|
||||
working in a building, as well as its production. If you let the mouse
|
||||
hover over a building, you can see a slightly larger and more detailed
|
||||
view. You can click on any building in order to open the build queue
|
||||
|
@ -2672,473 +2679,6 @@ therefore the external tax rate will be fixed at zero, with no threat of
|
|||
boycotts. However, you will no longer be able to sail to your former
|
||||
home port. Future versions may implement sailing to all European ports.
|
||||
|
||||
\hypertarget{Changing the Rules}{\chapter{Changing the Rules}}
|
||||
|
||||
We would like to make FreeCol configurable, so that the game engine
|
||||
becomes capable of emulating many similar games. For this purpose,
|
||||
we have made many of the game's features configurable.
|
||||
|
||||
At some point in the future, we will probably add a special rule set
|
||||
editor, but at the moment, your only option is to edit the file
|
||||
specification.xml directly. This file defines the abilities of units,
|
||||
founding fathers, buildings, terrain types, goods and equipment, for
|
||||
example. You can find this file in the \textit{data/freecol} directory.
|
||||
|
||||
This is still work in progress, however, and the schema for the rule
|
||||
set certain to change again in the future. If you wish to develop your
|
||||
own rule set, you will have to monitor FreeCol development closely.
|
||||
|
||||
This having been said, we are particularly interested in hearing about
|
||||
problems caused by your changes to the rule set. Some dialogs might be
|
||||
unable to display more types of goods than are currently defined, for
|
||||
example. Or other dialogs might not recognize your new Minuteman unit
|
||||
as an armed unit. Please help us improve FreeCol by telling us about
|
||||
such problems.
|
||||
|
||||
If you have a working rule set that adds a new flavour to the game, we
|
||||
will gladly distribute it along with our default rule set. If you have
|
||||
ideas that can not currently be implemented, we will probably try to
|
||||
remove these limitations.
|
||||
|
||||
If you try to modify the rule set, you are strongly encouraged to
|
||||
check whether the result is still valid. You can do this by validating
|
||||
the result with the command \verb$ant validate$.
|
||||
|
||||
|
||||
\hypertarget{Modifiers and Abilities}{\section{Modifiers and Abilities}}
|
||||
|
||||
Most of the objects defined by the rule set can be customized via
|
||||
modifiers and abilities. Abilities are boolean values (``true'' or
|
||||
``false''). If the value is not explicitly stated, it defaults to
|
||||
true. If an ability is not present, it defaults to false. Modifiers
|
||||
define a bonus or penalty to be applied to a numeric value, such as
|
||||
the number of goods produced by a unit. The modifier may be an
|
||||
additive, multiplicative or a percentage modifier. Modifiers default
|
||||
to ``identity'', which means they have no effect.
|
||||
|
||||
The code also checks that all abilities and modifiers it uses are
|
||||
defined by the specification. Therefore, you must define all of them,
|
||||
even if you do not use them. You can do this by setting their value to
|
||||
the default value, e.g. ``false'' in the case of an ability, or ``0''
|
||||
in the case of an additive modifier.
|
||||
|
||||
\newcommand{\ability}[1]{\index{#1}\index{Ability!#1}\hypertarget{#1}{\vspace{1em}\noindent\textbf{#1}}}
|
||||
\newcommand{\modifier}[1]{\index{#1}\index{Modifier!#1}\hypertarget{#1}{\vspace{1em}\noindent\textbf{#1}}}
|
||||
\newcommand{\affectsPlayer}{\\\textit{Affects: Player\\Provided by:
|
||||
Nation, Nation Type, Founding Father}}
|
||||
\newcommand{\affectsUnit}{\\\textit{Affects: Unit\\Provided by:
|
||||
Nation, Nation Type, Founding Father, Unit Type, Equipment Type}}
|
||||
\newcommand{\affectsBuilding}{\\\textit{Affects: Building\\Provided by:
|
||||
Building Type}}
|
||||
\newcommand{\affectsColony}{\\\textit{Affects: Colony\\Provided by:
|
||||
Map}}
|
||||
\newcommand{\affectsColonyTwo}{\\\textit{Affects: Colony\\Provided by:
|
||||
Building Type, Nation, Nation Type, Founding Father}}
|
||||
\newcommand{\affectsTile}{\\\textit{Affects: Tile\\Provided by:
|
||||
Tile Type}}
|
||||
|
||||
|
||||
\ability{model.ability.addTaxToBells}
|
||||
\affectsPlayer
|
||||
|
||||
The player adds the current tax rate as a bonus to bells
|
||||
production. The bonus is modified every time the tax increases or
|
||||
decreases.
|
||||
|
||||
\ability{model.ability.alwaysOfferedPeace}
|
||||
\affectsPlayer
|
||||
|
||||
The player is always offered peace in negotiations with AI players.
|
||||
|
||||
\ability{model.ability.ambushBonus}
|
||||
\affectsUnit
|
||||
|
||||
The unit is granted an ambush bonus equal to the terrain's defence value.
|
||||
|
||||
\ability{model.ability.ambushPenalty}
|
||||
\affectsUnit
|
||||
|
||||
The unit suffers an ambush penalty equal to the terrain's defence value.
|
||||
|
||||
\ability{model.ability.autoProduction}
|
||||
\affectsBuilding
|
||||
|
||||
The building needs no units to produce goods, and will never produce
|
||||
more goods than can be stored in the colony.
|
||||
|
||||
\ability{model.ability.automaticEquipment}
|
||||
\affectsUnit
|
||||
|
||||
The unit automatically picks up equipment if attacked.
|
||||
|
||||
\ability{model.ability.automaticPromotion}
|
||||
\affectsUnit
|
||||
|
||||
A unit that can be promoted will always be promoted when successful in
|
||||
battle.
|
||||
|
||||
\ability{model.ability.betterForeignAffairsReport}
|
||||
\affectsPlayer
|
||||
|
||||
The player is provided with more information about foreign powers.
|
||||
|
||||
\ability{model.ability.bombard}
|
||||
\affectsUnit
|
||||
|
||||
The unit is able to bombard other units.
|
||||
|
||||
\ability{model.ability.bombardShips}
|
||||
\affectsBuilding
|
||||
|
||||
The building has the ability to bombard enemy ships on adjacent tiles.
|
||||
|
||||
\ability{model.ability.bornInColony}
|
||||
\affectsUnit
|
||||
|
||||
The unit can be born in a colony, provided that enough food is available.
|
||||
|
||||
\ability{model.ability.bornInIndianSettlement}
|
||||
\affectsUnit
|
||||
|
||||
The unit can be born in an Indian settlement, provided that enough food is available.
|
||||
|
||||
\ability{model.ability.build}
|
||||
\affectsBuilding
|
||||
|
||||
The building can build units or equipment.
|
||||
|
||||
\ability{model.ability.buildCustomHouse}
|
||||
\affectsPlayer
|
||||
|
||||
The player can build custom houses.
|
||||
|
||||
\ability{model.ability.buildFactory}
|
||||
\affectsPlayer
|
||||
|
||||
The player can build factories.
|
||||
|
||||
\ability{model.ability.canBeCaptured}
|
||||
\affectsUnit
|
||||
|
||||
The unit can be captured. Land units that can not be captured are
|
||||
destroyed, naval units that can not be captured are either sunk or
|
||||
damaged.
|
||||
|
||||
\ability{model.ability.canBeEquipped}
|
||||
\affectsUnit
|
||||
|
||||
The unit can be equipped.
|
||||
|
||||
\ability{model.ability.canNotRecruitUnit}
|
||||
\affectsPlayer
|
||||
|
||||
The player can not recruit specified units.
|
||||
|
||||
\ability{model.ability.captureEquipment}
|
||||
\affectsUnit
|
||||
|
||||
The unit can capture equipment from another unit.
|
||||
|
||||
\ability{model.ability.captureGoods}
|
||||
\affectsUnit
|
||||
|
||||
The unit can capture goods from another unit.
|
||||
|
||||
\ability{model.ability.captureUnits}
|
||||
\affectsUnit
|
||||
|
||||
The unit can capture enemy units.
|
||||
|
||||
\ability{model.ability.carryGoods}
|
||||
\affectsUnit
|
||||
|
||||
The unit can transport goods.
|
||||
|
||||
\ability{model.ability.carryTreasure}
|
||||
\affectsUnit
|
||||
|
||||
The unit can transport treasures, not treasure trains.
|
||||
|
||||
\ability{model.ability.carryUnits}
|
||||
\affectsUnit
|
||||
|
||||
The unit can transport other units.
|
||||
|
||||
\ability{model.ability.convert}
|
||||
\affectsUnit
|
||||
|
||||
The unit is a native convert.
|
||||
|
||||
\ability{model.ability.dressMissionary}
|
||||
\affectsBuilding
|
||||
|
||||
The building can commission missionaries.
|
||||
|
||||
\ability{model.ability.electFoundingFather}
|
||||
\affectsPlayer
|
||||
|
||||
The player can elect Founding Fathers.
|
||||
|
||||
\ability{model.ability.expertMissionary}
|
||||
\affectsUnit
|
||||
|
||||
The unit is an expert missionary, but not necessarily commissioned.
|
||||
|
||||
\ability{model.ability.expertPioneer}
|
||||
\affectsUnit
|
||||
|
||||
The unit is an expert pioneer, but not necessarily equipped with tools.
|
||||
|
||||
\ability{model.ability.expertScout}
|
||||
\affectsUnit
|
||||
|
||||
The unit is an expert scout, but not necessarily equipped with horses.
|
||||
|
||||
\ability{model.ability.expertSoldier}
|
||||
\affectsUnit
|
||||
|
||||
The unit is an expert soldier, but not necessarily equipped with muskets.
|
||||
|
||||
\ability{model.ability.expertsUseConnections}
|
||||
\affectsPlayer
|
||||
|
||||
Experts working in factories can produce a small amount of goods even
|
||||
if the raw materials are not available in the colony.
|
||||
|
||||
\ability{model.ability.export}
|
||||
\affectsBuilding
|
||||
|
||||
The building can export goods to Europe directly.
|
||||
|
||||
\ability{model.ability.foundColony}
|
||||
\affectsUnit
|
||||
|
||||
The unit can found new colonies.
|
||||
|
||||
\ability{model.ability.foundInLostCity}
|
||||
\affectsUnit
|
||||
|
||||
The unit may be generated as the result of exploring a Lost City Rumour.
|
||||
|
||||
\ability{model.ability.hasPort}
|
||||
\affectsColony
|
||||
|
||||
The colony has access to at least one water tile. This ability can not
|
||||
be set by the specification, but it can be used as a required ability.
|
||||
|
||||
\ability{model.ability.ignoreEuropeanWars}
|
||||
\affectsPlayer
|
||||
|
||||
The player will not be affected by the Monarch's declarations of war.
|
||||
|
||||
\ability{model.ability.improveTerrain}
|
||||
\affectsUnit
|
||||
|
||||
The unit is able to improve terrain.
|
||||
|
||||
\ability{model.ability.independenceDeclared}
|
||||
\affectsPlayer
|
||||
|
||||
The player has declared independence.
|
||||
|
||||
\ability{model.ability.mercenaryUnit}
|
||||
\affectsUnit
|
||||
|
||||
The unit may be offered as a mercenary unit.
|
||||
|
||||
\ability{model.ability.missionary}
|
||||
\affectsUnit
|
||||
|
||||
The unit is able to establish missions and incite unrest in native
|
||||
settlements.
|
||||
|
||||
\ability{model.ability.moveToEurope}
|
||||
\affectsTile
|
||||
|
||||
Units on the tile are able to move to Europe.
|
||||
|
||||
\ability{model.ability.multipleAttacks}
|
||||
\affectsUnit
|
||||
|
||||
The unit can attack more than once.
|
||||
|
||||
\ability{model.ability.native}
|
||||
\affectsUnit
|
||||
|
||||
The unit is a native unit.
|
||||
|
||||
\ability{model.ability.navalUnit}
|
||||
\affectsUnit
|
||||
|
||||
The unit is a naval unit.
|
||||
|
||||
\ability{model.ability.pillageUnprotectedColony}
|
||||
\affectsUnit
|
||||
|
||||
The unit is able to steal goods from and destroy buildings in an
|
||||
unprotected colony.
|
||||
|
||||
\ability{model.ability.piracy}
|
||||
\affectsUnit
|
||||
|
||||
The unit is a privateer.
|
||||
|
||||
\ability{model.ability.produceInWater}
|
||||
\affectsBuilding
|
||||
|
||||
The building enables units to produce on water tiles.
|
||||
|
||||
\ability{model.ability.refUnit}
|
||||
\affectsUnit
|
||||
|
||||
The unit can be part of the Royal Expeditionary Force.
|
||||
|
||||
\ability{model.ability.repairUnits}
|
||||
\affectsBuilding
|
||||
|
||||
The building can repair units.
|
||||
|
||||
\ability{model.ability.royalExpeditionaryForce}
|
||||
\affectsPlayer
|
||||
|
||||
The player is a Royal Expeditionary Force.
|
||||
|
||||
\ability{model.ability.rumoursAlwaysPositive}
|
||||
\affectsPlayer
|
||||
|
||||
The player will always get positive results from exploring Lost City
|
||||
Rumours.
|
||||
|
||||
\ability{model.ability.scoutForeignColony}
|
||||
\affectsUnit
|
||||
|
||||
The unit can scout out foreign colonies.
|
||||
|
||||
\ability{model.ability.scoutIndianSettlement}
|
||||
\affectsUnit
|
||||
|
||||
The unit can scout out native settlements.
|
||||
|
||||
\ability{model.ability.selectRecruit}
|
||||
\affectsPlayer
|
||||
|
||||
The player can select a unit to recruit in Europe. This also applies
|
||||
to units generated as a result of finding a Fountain of Youth.
|
||||
|
||||
\ability{model.ability.teach}
|
||||
\affectsBuilding
|
||||
|
||||
The building enables experts to teach other units. However, the
|
||||
building may place limits on the experience level of teachers.
|
||||
|
||||
\ability{model.ability.tradeWithForeignColonies}
|
||||
\affectsPlayer
|
||||
|
||||
The player may trade goods in foreign colonies.
|
||||
|
||||
\ability{model.ability.undead}
|
||||
\affectsUnit
|
||||
|
||||
The unit is an undead unit (used only in revenge mode).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\modifier{model.modifier.bombardBonus}
|
||||
\affectsPlayer
|
||||
|
||||
The player's units are granted a bombard bonus when attacking.
|
||||
|
||||
\modifier{model.modifier.buildingPriceBonus}
|
||||
\affectsPlayer
|
||||
|
||||
The player can build or buy buildings at a reduced price.
|
||||
|
||||
\modifier{model.modifier.defence}
|
||||
\affectsUnit
|
||||
|
||||
The unit has a defence bonus or penalty.
|
||||
|
||||
\modifier{model.modifier.immigration}
|
||||
\textit{Affects: Player\\Provided by: Goods Type}
|
||||
|
||||
Goods of this type contribute to the player's immigration points.
|
||||
|
||||
\modifier{model.modifier.landPaymentModifier}
|
||||
\affectsPlayer
|
||||
|
||||
The player can buy Indian land at a reduced price.
|
||||
|
||||
\modifier{model.modifier.liberty}
|
||||
\textit{Affects: Player\\Provided by: Goods Type}
|
||||
|
||||
Goods of this type contribute to the colony's and the owning player's
|
||||
liberty points.
|
||||
|
||||
\modifier{model.modifier.lineOfSightBonus}
|
||||
\affectsUnit
|
||||
|
||||
The unit has an increased line of sight.
|
||||
|
||||
\modifier{model.modifier.minimumColonySize}
|
||||
\affectsColonyTwo
|
||||
|
||||
The population of the colony can not be voluntarily reduced below this
|
||||
number. The modifier does not in any way affect a population reduction
|
||||
due to starvation or other events.
|
||||
|
||||
\modifier{model.modifier.movementBonus}
|
||||
\affectsUnit
|
||||
|
||||
The unit has an increased movement range.
|
||||
|
||||
\modifier{model.modifier.nativeAlarmModifier}
|
||||
\affectsPlayer
|
||||
|
||||
The player generates less native alarm.
|
||||
|
||||
\modifier{model.modifier.nativeConvertBonus}
|
||||
\affectsPlayer
|
||||
|
||||
The player has a greater chance of converting natives.
|
||||
|
||||
\modifier{model.modifier.nativeTreasureModifier}
|
||||
\affectsPlayer
|
||||
|
||||
The player generates greater treasures when destroying native settlements.
|
||||
|
||||
\modifier{model.modifier.offence}
|
||||
\affectsUnit
|
||||
|
||||
The unit has an offence bonus or penalty.
|
||||
|
||||
\modifier{model.modifier.religiousUnrestBonus}
|
||||
\affectsPlayer
|
||||
|
||||
The player generates greater religious unrest in Europe.
|
||||
|
||||
\modifier{model.modifier.sailHighSeas}
|
||||
\affectsUnit
|
||||
|
||||
The unit's travel time between Europe and the New World is reduced.
|
||||
|
||||
\modifier{model.modifier.tradeBonus}
|
||||
\affectsPlayer
|
||||
|
||||
Prices in the player's market remain stable for longer.
|
||||
|
||||
\modifier{model.modifier.treasureTransportFee}
|
||||
\affectsPlayer
|
||||
|
||||
The player pays a smaller fee for transporting treasures to Europe.
|
||||
|
||||
\modifier{model.modifier.warehouseStorage}
|
||||
\affectsBuilding
|
||||
|
||||
The building increases the capacity of the warehouse.
|
||||
|
||||
|
||||
|
||||
|
||||
\hypertarget{Known bugs}{\chapter{Known bugs}}
|
||||
|
|
|
@ -0,0 +1,486 @@
|
|||
\documentclass[12pt]{book}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{longtable}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{index}
|
||||
\usepackage[colorlinks=true,hyperindex=true]{hyperref}
|
||||
\makeindex
|
||||
|
||||
\begin{document}
|
||||
\author{\href{http://freecol.sourceforge.net/index.php?section=8}{The FreeCol Team}}
|
||||
\title{FreeCol Documentation\\Developer Guide for Version v0.9.0}
|
||||
\maketitle{}
|
||||
|
||||
\tableofcontents
|
||||
\newpage
|
||||
|
||||
\hypertarget{Changing the Rules}{\chapter{Changing the Rules}}
|
||||
|
||||
We would like to make FreeCol configurable, so that the game engine
|
||||
becomes capable of emulating many similar games. For this purpose,
|
||||
we have made many of the game's features configurable.
|
||||
|
||||
At some point in the future, we will probably add a special rule set
|
||||
editor, but at the moment, your only option is to edit the file
|
||||
specification.xml directly. This file defines the abilities of units,
|
||||
founding fathers, buildings, terrain types, goods and equipment, for
|
||||
example. You can find this file in the \textit{data/freecol} directory.
|
||||
|
||||
This is still work in progress, however, and the schema for the rule
|
||||
set certain to change again in the future. If you wish to develop your
|
||||
own rule set, you will have to monitor FreeCol development closely.
|
||||
|
||||
This having been said, we are particularly interested in hearing about
|
||||
problems caused by your changes to the rule set. Some dialogs might be
|
||||
unable to display more types of goods than are currently defined, for
|
||||
example. Or other dialogs might not recognize your new Minuteman unit
|
||||
as an armed unit. Please help us improve FreeCol by telling us about
|
||||
such problems.
|
||||
|
||||
If you have a working rule set that adds a new flavour to the game, we
|
||||
will gladly distribute it along with our default rule set. If you have
|
||||
ideas that can not currently be implemented, we will probably try to
|
||||
remove these limitations.
|
||||
|
||||
If you try to modify the rule set, you are strongly encouraged to
|
||||
check whether the result is still valid. You can do this by validating
|
||||
the result with the command \verb$ant validate$.
|
||||
|
||||
|
||||
\hypertarget{Modifiers and Abilities}{\section{Modifiers and Abilities}}
|
||||
|
||||
Most of the objects defined by the rule set can be customized via
|
||||
modifiers and abilities. Abilities are boolean values (``true'' or
|
||||
``false''). If the value is not explicitly stated, it defaults to
|
||||
true. If an ability is not present, it defaults to false. Modifiers
|
||||
define a bonus or penalty to be applied to a numeric value, such as
|
||||
the number of goods produced by a unit. The modifier may be an
|
||||
additive, multiplicative or a percentage modifier. Modifiers default
|
||||
to ``identity'', which means they have no effect.
|
||||
|
||||
The code also checks that all abilities and modifiers it uses are
|
||||
defined by the specification. Therefore, you must define all of them,
|
||||
even if you do not use them. You can do this by setting their value to
|
||||
the default value, e.g. ``false'' in the case of an ability, or ``0''
|
||||
in the case of an additive modifier.
|
||||
|
||||
\newcommand{\ability}[1]{\index{#1}\index{Ability!#1}\hypertarget{#1}{\vspace{1em}\noindent\textbf{#1}}}
|
||||
\newcommand{\modifier}[1]{\index{#1}\index{Modifier!#1}\hypertarget{#1}{\vspace{1em}\noindent\textbf{#1}}}
|
||||
\newcommand{\affectsPlayer}{\\\textit{Affects: Player\\Provided by:
|
||||
Nation, Nation Type, Founding Father}}
|
||||
\newcommand{\affectsUnit}{\\\textit{Affects: Unit\\Provided by:
|
||||
Nation, Nation Type, Founding Father, Unit Type, Equipment Type}}
|
||||
\newcommand{\affectsBuilding}{\\\textit{Affects: Building\\Provided by:
|
||||
Building Type}}
|
||||
\newcommand{\affectsColony}{\\\textit{Affects: Colony\\Provided by:
|
||||
Map}}
|
||||
\newcommand{\affectsColonyTwo}{\\\textit{Affects: Colony\\Provided by:
|
||||
Building Type, Nation, Nation Type, Founding Father}}
|
||||
\newcommand{\affectsTile}{\\\textit{Affects: Tile\\Provided by:
|
||||
Tile Type}}
|
||||
|
||||
|
||||
\ability{model.ability.addTaxToBells}
|
||||
\affectsPlayer
|
||||
|
||||
The player adds the current tax rate as a bonus to bells
|
||||
production. The bonus is modified every time the tax increases or
|
||||
decreases.
|
||||
|
||||
\ability{model.ability.alwaysOfferedPeace}
|
||||
\affectsPlayer
|
||||
|
||||
The player is always offered peace in negotiations with AI players.
|
||||
|
||||
\ability{model.ability.ambushBonus}
|
||||
\affectsUnit
|
||||
|
||||
The unit is granted an ambush bonus equal to the terrain's defence value.
|
||||
|
||||
\ability{model.ability.ambushPenalty}
|
||||
\affectsUnit
|
||||
|
||||
The unit suffers an ambush penalty equal to the terrain's defence value.
|
||||
|
||||
\ability{model.ability.autoProduction}
|
||||
\affectsBuilding
|
||||
|
||||
The building needs no units to produce goods, and will never produce
|
||||
more goods than can be stored in the colony.
|
||||
|
||||
\ability{model.ability.automaticEquipment}
|
||||
\affectsUnit
|
||||
|
||||
The unit automatically picks up equipment if attacked.
|
||||
|
||||
\ability{model.ability.automaticPromotion}
|
||||
\affectsUnit
|
||||
|
||||
A unit that can be promoted will always be promoted when successful in
|
||||
battle.
|
||||
|
||||
\ability{model.ability.betterForeignAffairsReport}
|
||||
\affectsPlayer
|
||||
|
||||
The player is provided with more information about foreign powers.
|
||||
|
||||
\ability{model.ability.bombard}
|
||||
\affectsUnit
|
||||
|
||||
The unit is able to bombard other units.
|
||||
|
||||
\ability{model.ability.bombardShips}
|
||||
\affectsBuilding
|
||||
|
||||
The building has the ability to bombard enemy ships on adjacent tiles.
|
||||
|
||||
\ability{model.ability.bornInColony}
|
||||
\affectsUnit
|
||||
|
||||
The unit can be born in a colony, provided that enough food is available.
|
||||
|
||||
\ability{model.ability.bornInIndianSettlement}
|
||||
\affectsUnit
|
||||
|
||||
The unit can be born in an Indian settlement, provided that enough food is available.
|
||||
|
||||
\ability{model.ability.build}
|
||||
\affectsBuilding
|
||||
|
||||
The building can build units or equipment.
|
||||
|
||||
\ability{model.ability.buildCustomHouse}
|
||||
\affectsPlayer
|
||||
|
||||
The player can build custom houses.
|
||||
|
||||
\ability{model.ability.buildFactory}
|
||||
\affectsPlayer
|
||||
|
||||
The player can build factories.
|
||||
|
||||
\ability{model.ability.canBeCaptured}
|
||||
\affectsUnit
|
||||
|
||||
The unit can be captured. Land units that can not be captured are
|
||||
destroyed, naval units that can not be captured are either sunk or
|
||||
damaged.
|
||||
|
||||
\ability{model.ability.canBeEquipped}
|
||||
\affectsUnit
|
||||
|
||||
The unit can be equipped.
|
||||
|
||||
\ability{model.ability.canNotRecruitUnit}
|
||||
\affectsPlayer
|
||||
|
||||
The player can not recruit specified units.
|
||||
|
||||
\ability{model.ability.captureEquipment}
|
||||
\affectsUnit
|
||||
|
||||
The unit can capture equipment from another unit.
|
||||
|
||||
\ability{model.ability.captureGoods}
|
||||
\affectsUnit
|
||||
|
||||
The unit can capture goods from another unit.
|
||||
|
||||
\ability{model.ability.captureUnits}
|
||||
\affectsUnit
|
||||
|
||||
The unit can capture enemy units.
|
||||
|
||||
\ability{model.ability.carryGoods}
|
||||
\affectsUnit
|
||||
|
||||
The unit can transport goods.
|
||||
|
||||
\ability{model.ability.carryTreasure}
|
||||
\affectsUnit
|
||||
|
||||
The unit can transport treasures, not treasure trains.
|
||||
|
||||
\ability{model.ability.carryUnits}
|
||||
\affectsUnit
|
||||
|
||||
The unit can transport other units.
|
||||
|
||||
\ability{model.ability.convert}
|
||||
\affectsUnit
|
||||
|
||||
The unit is a native convert.
|
||||
|
||||
\ability{model.ability.dressMissionary}
|
||||
\affectsBuilding
|
||||
|
||||
The building can commission missionaries.
|
||||
|
||||
\ability{model.ability.electFoundingFather}
|
||||
\affectsPlayer
|
||||
|
||||
The player can elect Founding Fathers.
|
||||
|
||||
\ability{model.ability.expertMissionary}
|
||||
\affectsUnit
|
||||
|
||||
The unit is an expert missionary, but not necessarily commissioned.
|
||||
|
||||
\ability{model.ability.expertPioneer}
|
||||
\affectsUnit
|
||||
|
||||
The unit is an expert pioneer, but not necessarily equipped with tools.
|
||||
|
||||
\ability{model.ability.expertScout}
|
||||
\affectsUnit
|
||||
|
||||
The unit is an expert scout, but not necessarily equipped with horses.
|
||||
|
||||
\ability{model.ability.expertSoldier}
|
||||
\affectsUnit
|
||||
|
||||
The unit is an expert soldier, but not necessarily equipped with muskets.
|
||||
|
||||
\ability{model.ability.expertsUseConnections}
|
||||
\affectsPlayer
|
||||
|
||||
Experts working in factories can produce a small amount of goods even
|
||||
if the raw materials are not available in the colony.
|
||||
|
||||
\ability{model.ability.export}
|
||||
\affectsBuilding
|
||||
|
||||
The building can export goods to Europe directly.
|
||||
|
||||
\ability{model.ability.foundColony}
|
||||
\affectsUnit
|
||||
|
||||
The unit can found new colonies.
|
||||
|
||||
\ability{model.ability.foundInLostCity}
|
||||
\affectsUnit
|
||||
|
||||
The unit may be generated as the result of exploring a Lost City Rumour.
|
||||
|
||||
\ability{model.ability.hasPort}
|
||||
\affectsColony
|
||||
|
||||
The colony has access to at least one water tile. This ability can not
|
||||
be set by the specification, but it can be used as a required ability.
|
||||
|
||||
\ability{model.ability.ignoreEuropeanWars}
|
||||
\affectsPlayer
|
||||
|
||||
The player will not be affected by the Monarch's declarations of war.
|
||||
|
||||
\ability{model.ability.improveTerrain}
|
||||
\affectsUnit
|
||||
|
||||
The unit is able to improve terrain.
|
||||
|
||||
\ability{model.ability.independenceDeclared}
|
||||
\affectsPlayer
|
||||
|
||||
The player has declared independence.
|
||||
|
||||
\ability{model.ability.mercenaryUnit}
|
||||
\affectsUnit
|
||||
|
||||
The unit may be offered as a mercenary unit.
|
||||
|
||||
\ability{model.ability.missionary}
|
||||
\affectsUnit
|
||||
|
||||
The unit is able to establish missions and incite unrest in native
|
||||
settlements.
|
||||
|
||||
\ability{model.ability.moveToEurope}
|
||||
\affectsTile
|
||||
|
||||
Units on the tile are able to move to Europe.
|
||||
|
||||
\ability{model.ability.multipleAttacks}
|
||||
\affectsUnit
|
||||
|
||||
The unit can attack more than once.
|
||||
|
||||
\ability{model.ability.native}
|
||||
\affectsUnit
|
||||
|
||||
The unit is a native unit.
|
||||
|
||||
\ability{model.ability.navalUnit}
|
||||
\affectsUnit
|
||||
|
||||
The unit is a naval unit.
|
||||
|
||||
\ability{model.ability.pillageUnprotectedColony}
|
||||
\affectsUnit
|
||||
|
||||
The unit is able to steal goods from and destroy buildings in an
|
||||
unprotected colony.
|
||||
|
||||
\ability{model.ability.piracy}
|
||||
\affectsUnit
|
||||
|
||||
The unit is a privateer.
|
||||
|
||||
\ability{model.ability.produceInWater}
|
||||
\affectsBuilding
|
||||
|
||||
The building enables units to produce on water tiles.
|
||||
|
||||
\ability{model.ability.refUnit}
|
||||
\affectsUnit
|
||||
|
||||
The unit can be part of the Royal Expeditionary Force.
|
||||
|
||||
\ability{model.ability.repairUnits}
|
||||
\affectsBuilding
|
||||
|
||||
The building can repair units.
|
||||
|
||||
\ability{model.ability.royalExpeditionaryForce}
|
||||
\affectsPlayer
|
||||
|
||||
The player is a Royal Expeditionary Force.
|
||||
|
||||
\ability{model.ability.rumoursAlwaysPositive}
|
||||
\affectsPlayer
|
||||
|
||||
The player will always get positive results from exploring Lost City
|
||||
Rumours.
|
||||
|
||||
\ability{model.ability.scoutForeignColony}
|
||||
\affectsUnit
|
||||
|
||||
The unit can scout out foreign colonies.
|
||||
|
||||
\ability{model.ability.scoutIndianSettlement}
|
||||
\affectsUnit
|
||||
|
||||
The unit can scout out native settlements.
|
||||
|
||||
\ability{model.ability.selectRecruit}
|
||||
\affectsPlayer
|
||||
|
||||
The player can select a unit to recruit in Europe. This also applies
|
||||
to units generated as a result of finding a Fountain of Youth.
|
||||
|
||||
\ability{model.ability.teach}
|
||||
\affectsBuilding
|
||||
|
||||
The building enables experts to teach other units. However, the
|
||||
building may place limits on the experience level of teachers.
|
||||
|
||||
\ability{model.ability.tradeWithForeignColonies}
|
||||
\affectsPlayer
|
||||
|
||||
The player may trade goods in foreign colonies.
|
||||
|
||||
\ability{model.ability.undead}
|
||||
\affectsUnit
|
||||
|
||||
The unit is an undead unit (used only in revenge mode).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\modifier{model.modifier.bombardBonus}
|
||||
\affectsPlayer
|
||||
|
||||
The player's units are granted a bombard bonus when attacking.
|
||||
|
||||
\modifier{model.modifier.buildingPriceBonus}
|
||||
\affectsPlayer
|
||||
|
||||
The player can build or buy buildings at a reduced price.
|
||||
|
||||
\modifier{model.modifier.defence}
|
||||
\affectsUnit
|
||||
|
||||
The unit has a defence bonus or penalty.
|
||||
|
||||
\modifier{model.modifier.immigration}
|
||||
\textit{Affects: Player\\Provided by: Goods Type}
|
||||
|
||||
Goods of this type contribute to the player's immigration points.
|
||||
|
||||
\modifier{model.modifier.landPaymentModifier}
|
||||
\affectsPlayer
|
||||
|
||||
The player can buy Indian land at a reduced price.
|
||||
|
||||
\modifier{model.modifier.liberty}
|
||||
\textit{Affects: Player\\Provided by: Goods Type}
|
||||
|
||||
Goods of this type contribute to the colony's and the owning player's
|
||||
liberty points.
|
||||
|
||||
\modifier{model.modifier.lineOfSightBonus}
|
||||
\affectsUnit
|
||||
|
||||
The unit has an increased line of sight.
|
||||
|
||||
\modifier{model.modifier.minimumColonySize}
|
||||
\affectsColonyTwo
|
||||
|
||||
The population of the colony can not be voluntarily reduced below this
|
||||
number. The modifier does not in any way affect a population reduction
|
||||
due to starvation or other events.
|
||||
|
||||
\modifier{model.modifier.movementBonus}
|
||||
\affectsUnit
|
||||
|
||||
The unit has an increased movement range.
|
||||
|
||||
\modifier{model.modifier.nativeAlarmModifier}
|
||||
\affectsPlayer
|
||||
|
||||
The player generates less native alarm.
|
||||
|
||||
\modifier{model.modifier.nativeConvertBonus}
|
||||
\affectsPlayer
|
||||
|
||||
The player has a greater chance of converting natives.
|
||||
|
||||
\modifier{model.modifier.nativeTreasureModifier}
|
||||
\affectsPlayer
|
||||
|
||||
The player generates greater treasures when destroying native settlements.
|
||||
|
||||
\modifier{model.modifier.offence}
|
||||
\affectsUnit
|
||||
|
||||
The unit has an offence bonus or penalty.
|
||||
|
||||
\modifier{model.modifier.religiousUnrestBonus}
|
||||
\affectsPlayer
|
||||
|
||||
The player generates greater religious unrest in Europe.
|
||||
|
||||
\modifier{model.modifier.sailHighSeas}
|
||||
\affectsUnit
|
||||
|
||||
The unit's travel time between Europe and the New World is reduced.
|
||||
|
||||
\modifier{model.modifier.tradeBonus}
|
||||
\affectsPlayer
|
||||
|
||||
Prices in the player's market remain stable for longer.
|
||||
|
||||
\modifier{model.modifier.treasureTransportFee}
|
||||
\affectsPlayer
|
||||
|
||||
The player pays a smaller fee for transporting treasures to Europe.
|
||||
|
||||
\modifier{model.modifier.warehouseStorage}
|
||||
\affectsBuilding
|
||||
|
||||
The building increases the capacity of the warehouse.
|
||||
|
||||
|
||||
\printindex
|
||||
|
||||
\end{document}
|
Binary file not shown.
Before Width: | Height: | Size: 647 KiB After Width: | Height: | Size: 650 KiB |
Binary file not shown.
Before Width: | Height: | Size: 993 KiB After Width: | Height: | Size: 594 KiB |
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- XSD for specification version 0.20 -->
|
||||
<!-- XSD for specification version 0.21 -->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
|
||||
<xs:element name="freecol-specification">
|
||||
<xs:complexType>
|
||||
|
|
|
@ -176,8 +176,6 @@ public final class Canvas extends JDesktopPane {
|
|||
|
||||
private static final Integer STATUS_LAYER = JLayeredPane.POPUP_LAYER;
|
||||
|
||||
//private static final int EXIT = 0, RECRUIT = 1, PURCHASE = 2, TRAIN = 3, UNLOAD = 4;
|
||||
|
||||
/**
|
||||
* To save the most recently open dialog in Europe
|
||||
* (<code>RecruitDialog</code>, <code>PurchaseDialog</code>, <code>TrainDialog</code>)
|
||||
|
@ -1429,8 +1427,7 @@ public final class Canvas extends JDesktopPane {
|
|||
*/
|
||||
public void showColonyPanel(Colony colony) {
|
||||
freeColClient.getGUI().stopBlinking();
|
||||
ColonyPanel colonyPanel = new ColonyPanel(this);
|
||||
colonyPanel.initialize(colony);
|
||||
ColonyPanel colonyPanel = new ColonyPanel(colony, this);
|
||||
addAsFrame(colonyPanel);
|
||||
colonyPanel.requestFocus();
|
||||
}
|
||||
|
@ -1529,7 +1526,10 @@ public final class Canvas extends JDesktopPane {
|
|||
public void remove(Component comp, boolean update) {
|
||||
if (comp == null) {
|
||||
return;
|
||||
} else if (comp instanceof FreeColPanel) {
|
||||
((FreeColPanel) comp).setSavedSize(comp.getSize());
|
||||
}
|
||||
|
||||
final Rectangle updateBounds = comp.getBounds();
|
||||
final JInternalFrame frame = getInternalFrame(comp);
|
||||
if (frame != null && frame != comp) {
|
||||
|
|
|
@ -2572,23 +2572,17 @@ public final class GUI {
|
|||
* are none.
|
||||
*/
|
||||
public int getBreakingPoint(String string) {
|
||||
int center = string.length() / 2;
|
||||
int bestIndex = string.indexOf(' ');
|
||||
|
||||
int index = 0;
|
||||
while (index != -1 && index != bestIndex) {
|
||||
if (Math.abs(center-index) < Math.abs(center-bestIndex)) {
|
||||
bestIndex = index;
|
||||
int center = string.length() / 2;
|
||||
for (int offset = 0; offset < center; offset++) {
|
||||
if (string.charAt(center + offset) == ' ') {
|
||||
return center + offset;
|
||||
} else if (string.charAt(center - offset) == ' ') {
|
||||
index = center - offset;
|
||||
return center - offset;
|
||||
}
|
||||
|
||||
index = string.indexOf(' ', bestIndex);
|
||||
}
|
||||
|
||||
if (bestIndex == 0 || bestIndex == string.length()) {
|
||||
return -1;
|
||||
} else {
|
||||
return bestIndex;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
|
||||
package net.sf.freecol.client.gui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
@ -31,6 +33,7 @@ import java.util.logging.Logger;
|
|||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JSeparator;
|
||||
|
||||
import net.sf.freecol.FreeCol;
|
||||
import net.sf.freecol.client.FreeColClient;
|
||||
|
@ -38,6 +41,7 @@ import net.sf.freecol.client.gui.action.UnloadAction;
|
|||
import net.sf.freecol.client.gui.i18n.Messages;
|
||||
import net.sf.freecol.client.gui.panel.ChoiceItem;
|
||||
import net.sf.freecol.client.gui.panel.IndianSettlementPanel;
|
||||
import net.sf.freecol.client.gui.panel.ReportPanel;
|
||||
import net.sf.freecol.client.gui.panel.TilePanel;
|
||||
import net.sf.freecol.common.model.Colony;
|
||||
import net.sf.freecol.common.model.FreeColObject;
|
||||
|
@ -101,7 +105,8 @@ public final class TilePopup extends JPopupMenu {
|
|||
if (activeUnit.isOffensiveUnit() &&
|
||||
activeUnit.getTile().isAdjacent(tile) &&
|
||||
activeUnit.getMoveType(tile) == MoveType.ATTACK) {
|
||||
CombatOdds combatOdds = activeUnit.getGame().getCombatModel().calculateCombatOdds(activeUnit, tile.getDefendingUnit(activeUnit));
|
||||
CombatOdds combatOdds = activeUnit.getGame().getCombatModel()
|
||||
.calculateCombatOdds(activeUnit, tile.getDefendingUnit(activeUnit));
|
||||
|
||||
String victoryPercent;
|
||||
//If attacking a settlement, the true odds are never known because units may be hidden within
|
||||
|
@ -161,7 +166,10 @@ public final class TilePopup extends JPopupMenu {
|
|||
int lineCount = 0;
|
||||
int maxUnits = UNIT_LINES_IN_FIRST_MENU;
|
||||
Container currentMenu = this;
|
||||
for (final Unit currentUnit : tile.getUnitList()) {
|
||||
boolean moreUnits = false;
|
||||
List<Unit> units = new ArrayList<Unit>(tile.getUnitList());
|
||||
Collections.sort(units, ReportPanel.unitTypeComparator);
|
||||
for (final Unit currentUnit : units) {
|
||||
|
||||
if (lineCount > maxUnits) {
|
||||
JMenu more = new JMenu(Messages.message("more"));
|
||||
|
@ -169,6 +177,7 @@ public final class TilePopup extends JPopupMenu {
|
|||
more.setOpaque(false);
|
||||
currentMenu.add(more);
|
||||
currentMenu = more;
|
||||
moreUnits = true;
|
||||
lineCount = 0;
|
||||
maxUnits = UNIT_LINES_IN_OTHER_MENUS;
|
||||
}
|
||||
|
@ -176,24 +185,22 @@ public final class TilePopup extends JPopupMenu {
|
|||
lineCount += addUnit(currentMenu, currentUnit, !currentUnit.isUnderRepair(), false);
|
||||
}
|
||||
|
||||
if (tile.getUnitCount() > 0) {
|
||||
if (tile.getUnitCount() > 1) {
|
||||
if (tile.getUnitCount() > 1) {
|
||||
if (moreUnits) {
|
||||
addSeparator();
|
||||
JMenuItem activateAllItem = new JMenuItem(Messages.message("activateAllUnits"));
|
||||
activateAllItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
Unit lastUnit = null;
|
||||
for (Unit unit: tile.getUnitList()) {
|
||||
freeColClient.getInGameController().clearOrders(unit);
|
||||
lastUnit = unit;
|
||||
}
|
||||
gui.setActiveUnit(lastUnit);
|
||||
}
|
||||
}
|
||||
);
|
||||
add(activateAllItem);
|
||||
}
|
||||
addSeparator();
|
||||
JMenuItem activateAllItem = new JMenuItem(Messages.message("activateAllUnits"));
|
||||
activateAllItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
Unit lastUnit = null;
|
||||
for (Unit unit: tile.getUnitList()) {
|
||||
freeColClient.getInGameController().clearOrders(unit);
|
||||
lastUnit = unit;
|
||||
}
|
||||
gui.setActiveUnit(lastUnit);
|
||||
}
|
||||
});
|
||||
add(activateAllItem);
|
||||
}
|
||||
|
||||
// START DEBUG
|
||||
|
@ -322,6 +329,10 @@ public final class TilePopup extends JPopupMenu {
|
|||
add(dumpItem);
|
||||
}
|
||||
// END DEBUG
|
||||
Component lastComponent = getComponent(getComponentCount() - 1);
|
||||
if (lastComponent instanceof JSeparator) {
|
||||
remove(lastComponent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2114,6 +2114,7 @@ report.sonsOfLiberty=Sons of Liberty
|
|||
report.stance=Stance
|
||||
report.50percent=Turns to reach 50%
|
||||
report.100percent=Turns to reach 100%
|
||||
report.nextMember=Turns to increase rebels
|
||||
|
||||
report.requirements.noExpert=%colony% is producing %goods%, but has no %unit%.
|
||||
report.requirements.missingGoods=%colony% is producing %goods%, but requires more %input%.
|
||||
|
|
|
@ -22,6 +22,7 @@ package net.sf.freecol.client.gui.panel;
|
|||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
|
@ -39,6 +40,7 @@ import java.awt.event.MouseEvent;
|
|||
import java.awt.event.MouseListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -46,7 +48,6 @@ import java.util.logging.Logger;
|
|||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ComponentInputMap;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.InputMap;
|
||||
import javax.swing.JButton;
|
||||
|
@ -55,6 +56,7 @@ import javax.swing.JComponent;
|
|||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JToolTip;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
|
@ -67,6 +69,8 @@ import net.sf.freecol.client.ClientOptions;
|
|||
import net.sf.freecol.client.gui.Canvas;
|
||||
import net.sf.freecol.client.gui.GUI;
|
||||
import net.sf.freecol.client.gui.i18n.Messages;
|
||||
import net.sf.freecol.common.Specification;
|
||||
import net.sf.freecol.common.model.AbstractGoods;
|
||||
import net.sf.freecol.common.model.BuildableType;
|
||||
import net.sf.freecol.common.model.Building;
|
||||
import net.sf.freecol.common.model.Colony;
|
||||
|
@ -115,8 +119,12 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
private final JLabel popLabel = new JLabel();
|
||||
private final JLabel royalistMemberLabel = new JLabel();
|
||||
|
||||
private final JPanel productionPanel = new JPanel();
|
||||
private final JPanel populationPanel = new JPanel();
|
||||
private final JPanel rightProductionPanel = new JPanel();
|
||||
private final JPanel populationPanel = new JPanel() {
|
||||
public JToolTip createToolTip() {
|
||||
return new RebelToolTip(colony, getCanvas());
|
||||
}
|
||||
};
|
||||
|
||||
private final JComboBox nameBox;
|
||||
|
||||
|
@ -152,13 +160,18 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
|
||||
private static final Font hugeFont = new Font("Dialog", Font.BOLD, 24);
|
||||
|
||||
/**
|
||||
* The saved size of this panel.
|
||||
*/
|
||||
private static Dimension savedSize = null;
|
||||
|
||||
|
||||
/**
|
||||
* The constructor for the panel.
|
||||
*
|
||||
* @param parent The parent of this panel
|
||||
*/
|
||||
public ColonyPanel(Canvas parent) {
|
||||
public ColonyPanel(Colony colony, Canvas parent) {
|
||||
super(parent);
|
||||
|
||||
setFocusCycleRoot(true);
|
||||
|
@ -179,9 +192,10 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
fillInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_L, 0, true), "released");
|
||||
SwingUtilities.replaceUIInputMap(fillButton, JComponent.WHEN_IN_FOCUSED_WINDOW, fillInputMap);
|
||||
|
||||
productionPanel.setOpaque(false);
|
||||
rightProductionPanel.setOpaque(false);
|
||||
|
||||
populationPanel.setOpaque(false);
|
||||
populationPanel.setToolTipText(" ");
|
||||
populationPanel.setLayout(new MigLayout("wrap 5, fill, insets 0",
|
||||
"[][]:push[center]:push[right][]", ""));
|
||||
populationPanel.add(rebelShield, "bottom");
|
||||
|
@ -245,6 +259,17 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
// Make the colony label
|
||||
nameBox = new JComboBox();
|
||||
nameBox.setFont(smallHeaderFont);
|
||||
List<Colony> settlements = colony.getOwner().getColonies();
|
||||
sortColonies(settlements);
|
||||
for (Colony aColony : settlements) {
|
||||
nameBox.addItem(aColony);
|
||||
}
|
||||
nameBox.setSelectedItem(colony);
|
||||
nameBox.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
initialize((Colony) nameBox.getSelectedItem());
|
||||
}
|
||||
});
|
||||
|
||||
buildingsScroll.setAutoscrolls(true);
|
||||
|
||||
|
@ -281,8 +306,8 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
|
||||
setLayout(new MigLayout("fill, wrap 2", "[390!][fill]", ""));
|
||||
|
||||
add(nameBox, "growx, height 48:");
|
||||
add(productionPanel, "align center");
|
||||
add(nameBox, "height 48:, grow");
|
||||
add(rightProductionPanel);
|
||||
add(tilesScroll, "width 390!, height 200!, top");
|
||||
add(buildingsScroll, "span 1 3, grow 200");
|
||||
add(populationPanel, "grow");
|
||||
|
@ -295,7 +320,10 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
add(warehouseButton);
|
||||
add(exitButton);
|
||||
|
||||
setSize(parent.getWidth(), parent.getHeight());
|
||||
initialize(colony);
|
||||
if (savedSize != null) {
|
||||
setPreferredSize(savedSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -304,6 +332,24 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
exitButton.requestFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <code>SavedSize</code> value.
|
||||
*
|
||||
* @return a <code>Dimension</code> value
|
||||
*/
|
||||
public final Dimension getSavedSize() {
|
||||
return savedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the <code>SavedSize</code> value.
|
||||
*
|
||||
* @param newSavedSize The new SavedSize value.
|
||||
*/
|
||||
public final void setSavedSize(final Dimension newSavedSize) {
|
||||
this.savedSize = newSavedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the data on the window. This is the same as calling:
|
||||
* <code>initialize(colony, game, null)</code>.
|
||||
|
@ -331,9 +377,6 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
+ ".coat-of-arms.image", 0.5)));
|
||||
royalistShield.setIcon(new ImageIcon(ResourceManager.getImage(colony.getOwner().getNation().getRefNation().getId()
|
||||
+ ".coat-of-arms.image", 0.5)));
|
||||
popLabel.setText(Messages.message("colonyPanel.populationLabel", "%number%",
|
||||
Integer.toString(colony.getUnitCount())));
|
||||
|
||||
// Set listeners and transfer handlers
|
||||
outsideColonyPanel.removeMouseListener(releaseListener);
|
||||
inPortPanel.removeMouseListener(releaseListener);
|
||||
|
@ -394,11 +437,9 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
|
||||
tilePanel.initialize();
|
||||
|
||||
updateNameBox();
|
||||
updateProductionPanel();
|
||||
updateSoLLabel();
|
||||
|
||||
|
||||
outsideColonyPanel.setColony(colony);
|
||||
|
||||
}
|
||||
|
@ -428,20 +469,35 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
* Updates the SoL membership label.
|
||||
*/
|
||||
private void updateSoLLabel() {
|
||||
if (getColony() == null) {
|
||||
// Apparently this can happen
|
||||
logger.warning("Colony panel has 'null' colony.");
|
||||
return;
|
||||
}
|
||||
int population = colony.getUnitCount();
|
||||
int members = getColony().getMembers();
|
||||
int rebels = getColony().getSoL();
|
||||
rebelLabel.setText(Messages.message("colonyPanel.rebelLabel", "%number%",
|
||||
Integer.toString(members)));
|
||||
String rebelNumber = Messages.message("colonyPanel.rebelLabel", "%number%",
|
||||
Integer.toString(members));
|
||||
String royalistNumber = Messages.message("colonyPanel.royalistLabel", "%number%",
|
||||
Integer.toString(population - members));
|
||||
/*
|
||||
* TODO : remove compatibility code sometime after 0.9.1
|
||||
*
|
||||
* The string templates were changed from percentages to
|
||||
* absolute numbers shortly before 0.9.0, so that translators
|
||||
* had no chance to catch up.
|
||||
*/
|
||||
if (rebelNumber.endsWith("%")) {
|
||||
rebelNumber = rebelNumber.substring(0, rebelNumber.length() - 1);
|
||||
}
|
||||
if (royalistNumber.endsWith("%")) {
|
||||
royalistNumber = royalistNumber.substring(0, royalistNumber.length() - 1);
|
||||
}
|
||||
// end TODO
|
||||
|
||||
popLabel.setText(Messages.message("colonyPanel.populationLabel", "%number%",
|
||||
Integer.toString(population)));
|
||||
rebelLabel.setText(rebelNumber);
|
||||
rebelMemberLabel.setText(Integer.toString(rebels) + "%");
|
||||
bonusLabel.setText(Messages.message("colonyPanel.bonusLabel", "%number%",
|
||||
Integer.toString(getColony().getProductionBonus())));
|
||||
royalistLabel.setText(Messages.message("colonyPanel.royalistLabel", "%number%",
|
||||
Integer.toString(getColony().getUnitCount() - members)));
|
||||
royalistLabel.setText(royalistNumber);
|
||||
royalistMemberLabel.setText(Integer.toString(getColony().getTory()) + "%");
|
||||
}
|
||||
|
||||
|
@ -457,24 +513,6 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
tilePanel.initialize();
|
||||
}
|
||||
|
||||
public void updateNameBox() {
|
||||
if (getColony() == null) {
|
||||
// Apparently this can happen
|
||||
return;
|
||||
} else if (((DefaultComboBoxModel) nameBox.getModel()).getSize() == 0) {
|
||||
List<Colony> settlements = getColony().getOwner().getColonies();
|
||||
sortColonies(settlements);
|
||||
for (Colony colony : settlements) {
|
||||
nameBox.addItem(colony);
|
||||
}
|
||||
nameBox.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
initialize((Colony) nameBox.getSelectedItem());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void sortBuildings(List<Building> buildings) {
|
||||
Collections.sort(buildings, Building.getBuildingComparator());
|
||||
}
|
||||
|
@ -484,66 +522,50 @@ public final class ColonyPanel extends FreeColPanel implements ActionListener,Pr
|
|||
}
|
||||
|
||||
public void updateProductionPanel() {
|
||||
productionPanel.removeAll();
|
||||
rightProductionPanel.removeAll();
|
||||
|
||||
final int foodFarmsProduction = colony.getProductionOf(Goods.FOOD);
|
||||
final int foodFishProduction = colony.getProductionOf(Goods.FISH);
|
||||
final int humanFoodConsumption = colony.getFoodConsumption();
|
||||
final int horsesProduced = colony.getGoodsCount(Goods.HORSES) <= 0 ?
|
||||
0 : colony.getProductionOf(Goods.HORSES);
|
||||
final int bells = colony.getProductionOf(Goods.BELLS);
|
||||
final int crosses = colony.getProductionOf(Goods.CROSSES);
|
||||
|
||||
int foodProduction = foodFarmsProduction + foodFishProduction;
|
||||
|
||||
// The food that is used. If not enough food is produced, the
|
||||
// complete production. Horses consume 1 food each, so they
|
||||
// need to be added to the used food.
|
||||
|
||||
// Fish should be consumed preferably, to allow surplus for production of horses
|
||||
final int usedFood = Math.min(humanFoodConsumption, foodProduction) + horsesProduced;
|
||||
final int usedFish = colony.getFoodConsumptionByType(Goods.FISH);
|
||||
final int usedCorn = Math.max(usedFood - usedFish, 0);
|
||||
|
||||
if (usedFish == 0) {
|
||||
ProductionLabel label = new ProductionLabel(Goods.FOOD, usedFood, getCanvas());
|
||||
label.setToolTipPrefix(Messages.message("totalProduction"));
|
||||
productionPanel.add(label);
|
||||
} else {
|
||||
ProductionMultiplesLabel label = new ProductionMultiplesLabel(Goods.FOOD, usedCorn,
|
||||
Goods.FISH, usedFish, getCanvas());
|
||||
label.setToolTipPrefix(Messages.message("totalProduction"));
|
||||
productionPanel.add(label);
|
||||
List<AbstractGoods> foodProduction = new ArrayList<AbstractGoods>();
|
||||
List<AbstractGoods> surplusProduction = new ArrayList<AbstractGoods>();
|
||||
for (GoodsType goodsType : Specification.getSpecification().getGoodsTypeList()) {
|
||||
int production = colony.getProductionOf(goodsType);
|
||||
if (production != 0) {
|
||||
if (goodsType.isFoodType()) {
|
||||
int surplus = production - colony.getFoodConsumptionByType(goodsType);
|
||||
foodProduction.add(new AbstractGoods(goodsType, production));
|
||||
surplusProduction.add(new AbstractGoods(goodsType, surplus));
|
||||
} else if (goodsType.isBreedable()) {
|
||||
ProductionLabel horseLabel = new ProductionLabel(goodsType, production, getCanvas());
|
||||
horseLabel.setMaxGoodsIcons(1);
|
||||
rightProductionPanel.add(horseLabel);
|
||||
} else if (goodsType.isImmigrationType() || goodsType.isLibertyType()) {
|
||||
int consumption = colony.getConsumption(goodsType);
|
||||
ProductionLabel bellsLabel = new ProductionLabel(goodsType, production, getCanvas());
|
||||
bellsLabel.setToolTipPrefix(Messages.message("totalProduction"));
|
||||
if (consumption != 0) {
|
||||
int surplus = production - consumption;
|
||||
ProductionLabel surplusLabel = new ProductionLabel(goodsType, surplus, getCanvas());
|
||||
surplusLabel.setToolTipPrefix(Messages.message("surplusProduction"));
|
||||
rightProductionPanel.add(surplusLabel, 0);
|
||||
}
|
||||
rightProductionPanel.add(bellsLabel, 0);
|
||||
} else {
|
||||
production = colony.getProductionNetOf(goodsType);
|
||||
rightProductionPanel.add(new ProductionLabel(goodsType, production, getCanvas()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int remainingCorn = foodFarmsProduction - usedCorn;
|
||||
final int remainingFish = foodFishProduction - usedFish;
|
||||
|
||||
int surplusFood = foodProduction - humanFoodConsumption - horsesProduced;
|
||||
remainingCorn = Math.min(surplusFood, remainingCorn);
|
||||
ProductionMultiplesLabel surplusLabel =
|
||||
new ProductionMultiplesLabel(Goods.FOOD, remainingCorn, Goods.FISH, remainingFish, getCanvas());
|
||||
new ProductionMultiplesLabel(surplusProduction, getCanvas());
|
||||
surplusLabel.setDrawPlus(true);
|
||||
surplusLabel.setToolTipPrefix(Messages.message("surplusProduction"));
|
||||
productionPanel.add(surplusLabel);
|
||||
rightProductionPanel.add(surplusLabel, 0);
|
||||
|
||||
if (horsesProduced != 0) {
|
||||
// Skip the horses label if there is no stock
|
||||
ProductionLabel horseLabel = new ProductionLabel(Goods.HORSES, horsesProduced, getCanvas());
|
||||
horseLabel.setMaxGoodsIcons(1);
|
||||
productionPanel.add(horseLabel);
|
||||
}
|
||||
ProductionMultiplesLabel label = new ProductionMultiplesLabel(foodProduction, getCanvas());
|
||||
label.setToolTipPrefix(Messages.message("totalProduction"));
|
||||
rightProductionPanel.add(label, 0);
|
||||
|
||||
ProductionLabel bellsLabel = new ProductionLabel(Goods.BELLS, bells, getCanvas());
|
||||
bellsLabel.setToolTipPrefix(Messages.message("totalProduction"));
|
||||
productionPanel.add(bellsLabel);
|
||||
int surplusBells = bells - colony.getConsumption(Goods.BELLS);
|
||||
ProductionLabel bellsSurplusLabel = new ProductionLabel(Goods.BELLS, surplusBells, getCanvas());
|
||||
bellsSurplusLabel.setToolTipPrefix(Messages.message("surplusProduction"));
|
||||
productionPanel.add(bellsSurplusLabel);
|
||||
|
||||
productionPanel.add(new ProductionLabel(Goods.CROSSES, crosses, getCanvas()));
|
||||
productionPanel.revalidate();
|
||||
rightProductionPanel.revalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -113,6 +113,12 @@ public final class ColopediaPanel extends FreeColPanel implements TreeSelectionL
|
|||
|
||||
private JTree tree;
|
||||
|
||||
/**
|
||||
* The saved size of this panel.
|
||||
*/
|
||||
private static Dimension savedSize = new Dimension(850, 600);
|
||||
|
||||
|
||||
/**
|
||||
* The constructor that will add the items to this panel.
|
||||
*
|
||||
|
@ -123,7 +129,7 @@ public final class ColopediaPanel extends FreeColPanel implements TreeSelectionL
|
|||
|
||||
none = Messages.message("none");
|
||||
|
||||
setLayout(new MigLayout("", "[]unrelated[grow, fill]", "[][grow, fill][]"));
|
||||
setLayout(new MigLayout("fill", "[200:]unrelated[550:, grow, fill]", "[][grow, fill][]"));
|
||||
|
||||
header = getDefaultHeader(Messages.message("menuBar.colopedia"));
|
||||
add(header, "span, align center");
|
||||
|
@ -139,29 +145,36 @@ public final class ColopediaPanel extends FreeColPanel implements TreeSelectionL
|
|||
|
||||
detailPanel = new JPanel();
|
||||
detailPanel.setOpaque(false);
|
||||
JScrollPane detail = new JScrollPane(detailPanel,
|
||||
JScrollPane detail = new JScrollPane(detailPanel,
|
||||
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
detail.getVerticalScrollBar().setUnitIncrement(16);
|
||||
detail.getViewport().setOpaque(false);
|
||||
add(detail);
|
||||
add(detail, "grow");
|
||||
|
||||
add(okButton, "newline 20, span, tag ok");
|
||||
|
||||
setSize(getPreferredSize());
|
||||
setPreferredSize(savedSize);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return new Dimension(850, 600);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(850, getCanvas().getHeight() - 100);
|
||||
|
||||
/**
|
||||
* Get the <code>SavedSize</code> value.
|
||||
*
|
||||
* @return a <code>Dimension</code> value
|
||||
*/
|
||||
public final Dimension getSavedSize() {
|
||||
return savedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the <code>SavedSize</code> value.
|
||||
*
|
||||
* @param newSavedSize The new SavedSize value.
|
||||
*/
|
||||
public final void setSavedSize(final Dimension newSavedSize) {
|
||||
this.savedSize = newSavedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares this panel to be displayed.
|
||||
|
@ -633,7 +646,7 @@ public final class ColopediaPanel extends FreeColPanel implements TreeSelectionL
|
|||
return;
|
||||
}
|
||||
|
||||
detailPanel.setLayout(new MigLayout("wrap 4, fillx, gap 20", "[][]push[][]", ""));
|
||||
detailPanel.setLayout(new MigLayout("wrap 4, gap 20", "[][]push[][]", ""));
|
||||
|
||||
String movementCost = String.valueOf(tileType.getBasicMoveCost() / 3);
|
||||
String defenseBonus = none;
|
||||
|
@ -693,7 +706,7 @@ public final class ColopediaPanel extends FreeColPanel implements TreeSelectionL
|
|||
}
|
||||
|
||||
detailPanel.add(new JLabel(Messages.message("colopedia.terrain.description")));
|
||||
detailPanel.add(getDefaultTextArea(tileType.getDescription()), "span, growx");
|
||||
detailPanel.add(getDefaultTextArea(tileType.getDescription(), 20), "span, growx");
|
||||
|
||||
detailPanel.revalidate();
|
||||
detailPanel.repaint();
|
||||
|
@ -746,7 +759,7 @@ public final class ColopediaPanel extends FreeColPanel implements TreeSelectionL
|
|||
detailPanel.add(goodsPanel);
|
||||
|
||||
detailPanel.add(new JLabel(Messages.message("colopedia.resource.description")), "newline 20");
|
||||
detailPanel.add(getDefaultTextArea(type.getDescription()), "growx");
|
||||
detailPanel.add(getDefaultTextArea(type.getDescription(), 20), "growx");
|
||||
|
||||
detailPanel.revalidate();
|
||||
detailPanel.repaint();
|
||||
|
@ -881,7 +894,7 @@ public final class ColopediaPanel extends FreeColPanel implements TreeSelectionL
|
|||
|
||||
detailPanel.add(new JLabel(Messages.message("colopedia.unit.description")),
|
||||
"newline 20");
|
||||
detailPanel.add(getDefaultTextArea(type.getDescription()), "growx");
|
||||
detailPanel.add(getDefaultTextArea(type.getDescription(), 20), "growx");
|
||||
|
||||
detailPanel.revalidate();
|
||||
detailPanel.repaint();
|
||||
|
@ -953,7 +966,7 @@ public final class ColopediaPanel extends FreeColPanel implements TreeSelectionL
|
|||
}
|
||||
|
||||
detailPanel.add(new JLabel(Messages.message("colopedia.goods.description")));
|
||||
detailPanel.add(getDefaultTextArea(type.getDescription()), "growx");
|
||||
detailPanel.add(getDefaultTextArea(type.getDescription(), 20), "growx");
|
||||
|
||||
detailPanel.revalidate();
|
||||
detailPanel.repaint();
|
||||
|
@ -1108,7 +1121,7 @@ public final class ColopediaPanel extends FreeColPanel implements TreeSelectionL
|
|||
|
||||
// Notes
|
||||
detailPanel.add(new JLabel(Messages.message("colopedia.buildings.notes")), "newline 20, top");
|
||||
detailPanel.add(getDefaultTextArea(buildingType.getDescription()), "growx");
|
||||
detailPanel.add(getDefaultTextArea(buildingType.getDescription(), 20), "growx");
|
||||
|
||||
detailPanel.revalidate();
|
||||
detailPanel.repaint();
|
||||
|
@ -1146,8 +1159,8 @@ public final class ColopediaPanel extends FreeColPanel implements TreeSelectionL
|
|||
String text = Messages.message(father.getDescription()) + "\n\n" + "["
|
||||
+ Messages.message(father.getBirthAndDeath()) + "] "
|
||||
+ Messages.message(father.getText());
|
||||
JTextArea description = getDefaultTextArea(text);
|
||||
detailPanel.add(description, "top, growx, shrink");
|
||||
JTextArea description = getDefaultTextArea(text, 20);
|
||||
detailPanel.add(description, "top, growx");
|
||||
|
||||
detailPanel.revalidate();
|
||||
detailPanel.repaint();
|
||||
|
|
|
@ -21,6 +21,7 @@ package net.sf.freecol.client.gui.panel;
|
|||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.Image;
|
||||
|
@ -131,12 +132,37 @@ public class FreeColPanel extends JPanel implements ActionListener {
|
|||
BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, LINK_COLOR),
|
||||
BorderFactory.createEmptyBorder(2, 2, 2, 2));
|
||||
|
||||
private static final FreeColImageBorder imageBorder =
|
||||
new FreeColImageBorder(ResourceManager.getImage("menuborder.n.image"),
|
||||
ResourceManager.getImage("menuborder.w.image"),
|
||||
ResourceManager.getImage("menuborder.s.image"),
|
||||
ResourceManager.getImage("menuborder.e.image"),
|
||||
ResourceManager.getImage("menuborder.nw.image"),
|
||||
ResourceManager.getImage("menuborder.ne.image"),
|
||||
ResourceManager.getImage("menuborder.sw.image"),
|
||||
ResourceManager.getImage("menuborder.se.image"));
|
||||
|
||||
protected boolean editable = true;
|
||||
|
||||
protected JButton okButton = new JButton(Messages.message("ok"));
|
||||
|
||||
protected static StyleContext styleContext = null;
|
||||
protected static StyleContext styleContext = new StyleContext();
|
||||
|
||||
static {
|
||||
Style defaultStyle = styleContext.getDefaultStyleContext()
|
||||
.getStyle(StyleContext.DEFAULT_STYLE);
|
||||
|
||||
Style regular = styleContext.addStyle("regular", defaultStyle);
|
||||
StyleConstants.setFontFamily(regular, "Dialog");
|
||||
StyleConstants.setBold(regular, true);
|
||||
StyleConstants.setFontSize(regular, 12);
|
||||
|
||||
Style buttonStyle = styleContext.addStyle("button", regular);
|
||||
StyleConstants.setForeground(buttonStyle, LINK_COLOR);
|
||||
|
||||
Style right = styleContext.addStyle("right", regular);
|
||||
StyleConstants.setAlignment(right, StyleConstants.ALIGN_RIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -157,18 +183,8 @@ public class FreeColPanel extends JPanel implements ActionListener {
|
|||
this.canvas = parent;
|
||||
setFocusCycleRoot(true);
|
||||
|
||||
Image menuborderN = ResourceManager.getImage("menuborder.n.image");
|
||||
Image menuborderNW = ResourceManager.getImage("menuborder.nw.image");
|
||||
Image menuborderNE = ResourceManager.getImage("menuborder.ne.image");
|
||||
Image menuborderW = ResourceManager.getImage("menuborder.w.image");
|
||||
Image menuborderE = ResourceManager.getImage("menuborder.e.image");
|
||||
Image menuborderS = ResourceManager.getImage("menuborder.s.image");
|
||||
Image menuborderSW = ResourceManager.getImage("menuborder.sw.image");
|
||||
Image menuborderSE = ResourceManager.getImage("menuborder.se.image");
|
||||
final FreeColImageBorder imageBorder = new FreeColImageBorder(menuborderN, menuborderW, menuborderS,
|
||||
menuborderE, menuborderNW, menuborderNE, menuborderSW, menuborderSE);
|
||||
setBorder(BorderFactory.createCompoundBorder(imageBorder,
|
||||
BorderFactory.createEmptyBorder(margin, margin,margin,margin)));
|
||||
BorderFactory.createEmptyBorder(margin, margin, margin, margin)));
|
||||
|
||||
// See the message of Ulf Onnen for more information about the presence
|
||||
// of this fake mouse listener.
|
||||
|
@ -181,6 +197,15 @@ public class FreeColPanel extends JPanel implements ActionListener {
|
|||
setCancelComponent(okButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the <code>SavedSize</code> value.
|
||||
*
|
||||
* @param newSavedSize The new SavedSize value.
|
||||
*/
|
||||
public void setSavedSize(final Dimension newSavedSize) {
|
||||
// override this if you want a panel to remember its size
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <code>Canvas</code> value.
|
||||
*
|
||||
|
@ -242,18 +267,30 @@ public class FreeColPanel extends JPanel implements ActionListener {
|
|||
return editable;
|
||||
}
|
||||
|
||||
/**
|
||||
* The OK button requests focus.
|
||||
*
|
||||
*/
|
||||
public void requestFocus() {
|
||||
okButton.requestFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JTextPane with default styles.
|
||||
*
|
||||
* @return a <code>JTextPane</code> value
|
||||
*/
|
||||
public static JTextPane getDefaultTextPane() {
|
||||
return getDefaultTextPane(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JTextPane with default styles and given text.
|
||||
*
|
||||
* @param text a <code>String</code> value
|
||||
* @return a <code>JTextPane</code> value
|
||||
*/
|
||||
public static JTextPane getDefaultTextPane(String text) {
|
||||
if (styleContext == null) {
|
||||
styleContext = createStyleContext();
|
||||
}
|
||||
JTextPane textPane = new JTextPane(new DefaultStyledDocument(styleContext));
|
||||
textPane.setOpaque(false);
|
||||
textPane.setEditable(false);
|
||||
|
@ -264,24 +301,6 @@ public class FreeColPanel extends JPanel implements ActionListener {
|
|||
}
|
||||
|
||||
|
||||
private static StyleContext createStyleContext() {
|
||||
StyleContext defaultContext = new StyleContext();
|
||||
Style defaultStyle = defaultContext.getDefaultStyleContext()
|
||||
.getStyle(StyleContext.DEFAULT_STYLE);
|
||||
|
||||
Style regular = defaultContext.addStyle("regular", defaultStyle);
|
||||
StyleConstants.setFontFamily(regular, "Dialog");
|
||||
StyleConstants.setBold(regular, true);
|
||||
StyleConstants.setFontSize(regular, 12);
|
||||
|
||||
Style buttonStyle = defaultContext.addStyle("button", regular);
|
||||
StyleConstants.setForeground(buttonStyle, LINK_COLOR);
|
||||
|
||||
Style right = defaultContext.addStyle("right", regular);
|
||||
StyleConstants.setAlignment(right, StyleConstants.ALIGN_RIGHT);
|
||||
|
||||
return defaultContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a text area with standard settings suitable for use in FreeCol
|
||||
|
@ -294,6 +313,7 @@ public class FreeColPanel extends JPanel implements ActionListener {
|
|||
public static JTextArea getDefaultTextArea(String text) {
|
||||
return getDefaultTextArea(text, COLUMNS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a text area with standard settings suitable for use in FreeCol
|
||||
* dialogs.
|
||||
|
@ -316,6 +336,15 @@ public class FreeColPanel extends JPanel implements ActionListener {
|
|||
return textArea;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a button suitable for linking to another panel
|
||||
* (e.g. ColopediaPanel).
|
||||
*
|
||||
* @param text a <code>String</code> value
|
||||
* @param icon an <code>Icon</code> value
|
||||
* @param action a <code>String</code> value
|
||||
* @return a <code>JButton</code> value
|
||||
*/
|
||||
public static JButton getLinkButton(String text, Icon icon, String action) {
|
||||
JButton button = new JButton(text, icon);
|
||||
button.setMargin(emptyMargin);
|
||||
|
@ -341,6 +370,11 @@ public class FreeColPanel extends JPanel implements ActionListener {
|
|||
return header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the given button the CANCEL button.
|
||||
*
|
||||
* @param cancelButton an <code>AbstractButton</code> value
|
||||
*/
|
||||
public void setCancelComponent(AbstractButton cancelButton) {
|
||||
if (cancelButton == null) {
|
||||
throw new NullPointerException();
|
||||
|
@ -354,7 +388,7 @@ public class FreeColPanel extends JPanel implements ActionListener {
|
|||
}
|
||||
|
||||
/**
|
||||
* Registers enter key for a jbutton.
|
||||
* Registers enter key for a JButton.
|
||||
*
|
||||
* @param button
|
||||
*/
|
||||
|
@ -367,10 +401,20 @@ public class FreeColPanel extends JPanel implements ActionListener {
|
|||
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), JComponent.WHEN_FOCUSED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default modifier value format.
|
||||
*
|
||||
* @return a <code>DecimalFormat</code> value
|
||||
*/
|
||||
public static final DecimalFormat getModifierFormat() {
|
||||
return modifierFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the given modifiers according to type.
|
||||
*
|
||||
* @return a sorted Set of Modifiers
|
||||
*/
|
||||
public Set<Modifier> sortModifiers(Set<Modifier> result) {
|
||||
EnumMap<Modifier.Type, List<Modifier>> modifierMap =
|
||||
new EnumMap<Modifier.Type, List<Modifier>>(Modifier.Type.class);
|
||||
|
|
|
@ -199,7 +199,9 @@ public class FreeColProgressBar extends JPanel {
|
|||
String stepSignal = (step < 0) ? "-" : "+";
|
||||
String progressString = String.valueOf(value) + stepSignal + Math.abs(step) + "/" + max;
|
||||
String turnsString = Messages.message("notApplicable.short");
|
||||
if (max > value && step > 0) {
|
||||
if (max <= value) {
|
||||
turnsString = "0";
|
||||
} else if (step > 0) {
|
||||
// There is progress, find how many turns necessary with current production
|
||||
int turns = (max - value) / step;
|
||||
if ((max - value) % step > 0) {
|
||||
|
|
|
@ -424,18 +424,28 @@ public final class InfoPanel extends FreeColPanel {
|
|||
*/
|
||||
public class EndTurnPanel extends JPanel {
|
||||
|
||||
private JLabel endTurnLabel = new JLabel(Messages.message("infoPanel.endTurnPanel.text"), JLabel.CENTER);
|
||||
|
||||
private JButton endTurnButton = new JButton(Messages.message("infoPanel.endTurnPanel.endTurnButton"));
|
||||
|
||||
|
||||
public EndTurnPanel() {
|
||||
super(new FlowLayout(FlowLayout.CENTER, 10, 10));
|
||||
|
||||
add(endTurnLabel);
|
||||
super(new MigLayout("wrap 1, center", "[center]", ""));
|
||||
|
||||
String labelString = Messages.message("infoPanel.endTurnPanel.text");
|
||||
int width = getFontMetrics(getFont()).stringWidth(labelString);
|
||||
if (width > 150 ) {
|
||||
int index = getCanvas().getGUI().getBreakingPoint(labelString);
|
||||
if (index > 0) {
|
||||
add(new JLabel(labelString.substring(0, index)));
|
||||
add(new JLabel(labelString.substring(index + 1)));
|
||||
} else {
|
||||
add(new JLabel(labelString));
|
||||
}
|
||||
} else {
|
||||
add(new JLabel(labelString));
|
||||
}
|
||||
|
||||
add(endTurnButton);
|
||||
setOpaque(false);
|
||||
setSize(230, endTurnLabel.getPreferredSize().height + endTurnButton.getPreferredSize().height + 30);
|
||||
setSize(getPreferredSize());
|
||||
|
||||
/*
|
||||
* TODO: The action listener does not work, because this button
|
||||
|
|
|
@ -460,11 +460,12 @@ public final class ProductionLabel extends JComponent {
|
|||
int coverage = pixelsPerIcon * (drawImageCount - 1) + iconWidth;
|
||||
int leftOffset = 0;
|
||||
|
||||
if (centered && coverage < stringWidth) {
|
||||
leftOffset = (stringWidth - coverage)/2;
|
||||
int width = Math.max(getWidth(), Math.max(stringWidth, coverage));
|
||||
|
||||
if (centered && coverage < width) {
|
||||
leftOffset = (width - coverage)/2;
|
||||
}
|
||||
|
||||
int width = Math.max(stringWidth, coverage);
|
||||
int height = Math.max(getHeight(), goodsIcon.getImage().getHeight(null));
|
||||
setSize(new Dimension(width, height));
|
||||
|
||||
|
@ -475,7 +476,7 @@ public final class ProductionLabel extends JComponent {
|
|||
}
|
||||
|
||||
if (stringImage != null) {
|
||||
int textOffset = coverage > stringWidth ? (coverage - stringWidth)/2 : 0;
|
||||
int textOffset = width > stringWidth ? (width - stringWidth)/2 : 0;
|
||||
textOffset = (textOffset >= 0) ? textOffset : 0;
|
||||
g.drawImage(stringImage, textOffset,
|
||||
goodsIcon.getIconHeight()/2 - stringImage.getHeight()/2, null);
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.awt.Dimension;
|
|||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
|
@ -31,6 +32,7 @@ import javax.swing.JComponent;
|
|||
|
||||
import net.sf.freecol.client.ClientOptions;
|
||||
import net.sf.freecol.client.gui.Canvas;
|
||||
import net.sf.freecol.common.model.AbstractGoods;
|
||||
import net.sf.freecol.common.model.Goods;
|
||||
import net.sf.freecol.common.model.GoodsType;
|
||||
import net.sf.freecol.common.util.Utils;
|
||||
|
@ -103,43 +105,6 @@ public final class ProductionMultiplesLabel extends JComponent {
|
|||
*/
|
||||
private String toolTipPrefix = null;
|
||||
|
||||
/**
|
||||
* Creates a new <code>ProductionLabel</code> instance.
|
||||
*
|
||||
* @param goods a <code>Goods</code> value
|
||||
* @param parent a <code>Canvas</code> value
|
||||
*/
|
||||
public ProductionMultiplesLabel(Goods goods, Canvas parent) {
|
||||
this(goods.getType(), goods.getAmount(), -1, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>ProductionLabel</code> instance.
|
||||
*
|
||||
* @param goodsType an <code>int</code> value
|
||||
* @param amount an <code>int</code> value
|
||||
* @param parent a <code>Canvas</code> value
|
||||
*/
|
||||
public ProductionMultiplesLabel(GoodsType goodsType, int amount, Canvas parent) {
|
||||
this(goodsType, amount, -1, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>ProductionLabel</code> instance.
|
||||
*
|
||||
* @param goodsType an <code>int</code> value
|
||||
* @param amount an <code>int</code> value
|
||||
* @param maximumProduction an <code>int</code> value
|
||||
* @param parent a <code>Canvas</code> value
|
||||
*/
|
||||
public ProductionMultiplesLabel(GoodsType goodsType, int amount, int maximumProduction, Canvas parent) {
|
||||
this( new GoodsType[]{goodsType}, new int[]{amount}, maximumProduction, parent);
|
||||
}
|
||||
|
||||
public ProductionMultiplesLabel(GoodsType goodsType, int amount, GoodsType goodsType2, int amount2, Canvas parent) {
|
||||
this( new GoodsType[]{goodsType, goodsType2}, new int[]{amount, amount2}, -1, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow labels to include multiple goods.
|
||||
* This is especially useful for Food.
|
||||
|
@ -149,12 +114,10 @@ public final class ProductionMultiplesLabel extends JComponent {
|
|||
* @param maximumProduction
|
||||
* @param parent
|
||||
*/
|
||||
public ProductionMultiplesLabel(GoodsType[] goodsType, int[] amount, int maximumProduction, Canvas parent) {
|
||||
public ProductionMultiplesLabel(List<AbstractGoods> goods, Canvas parent) {
|
||||
super();
|
||||
this.parent = parent;
|
||||
this.production = amount;
|
||||
this.goodsType = goodsType;
|
||||
this.maximumProduction = maximumProduction;
|
||||
//this.maximumProduction = maximumProduction;
|
||||
ClientOptions options = parent.getClient().getClientOptions();
|
||||
maxIcons = options.getInteger(ClientOptions.MAX_NUMBER_OF_GOODS_IMAGES);
|
||||
displayNumber = options.getInteger(ClientOptions.MIN_NUMBER_FOR_DISPLAYING_GOODS_COUNT);
|
||||
|
@ -162,11 +125,17 @@ public final class ProductionMultiplesLabel extends JComponent {
|
|||
setFont(new Font("Dialog", Font.BOLD, 12));
|
||||
totalProduction = 0;
|
||||
|
||||
if (goodsType != null) {
|
||||
goodsIcon = new ImageIcon[goodsType.length];
|
||||
for (int ii=0; ii < goodsType.length; ii++) {
|
||||
goodsIcon[ii] = parent.getImageLibrary().getGoodsImageIcon(goodsType[ii]);
|
||||
totalProduction += amount[ii];
|
||||
if (goods != null) {
|
||||
int size = goods.size();
|
||||
goodsType = new GoodsType[size];
|
||||
goodsIcon = new ImageIcon[size];
|
||||
production = new int[size];
|
||||
for (int ii=0; ii < size; ii++) {
|
||||
AbstractGoods current = goods.get(ii);
|
||||
goodsType[ii] = current.getType();
|
||||
goodsIcon[ii] = parent.getImageLibrary().getGoodsImageIcon(current.getType());
|
||||
production[ii] = current.getAmount();
|
||||
totalProduction += current.getAmount();
|
||||
}
|
||||
compressedWidth = getMaximumIconWidth()*2;
|
||||
updateToolTipText();
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* Copyright (C) 2002-2007 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.client.gui.panel;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JToolTip;
|
||||
|
||||
import net.sf.freecol.client.gui.Canvas;
|
||||
import net.sf.freecol.client.gui.i18n.Messages;
|
||||
import net.sf.freecol.common.Specification;
|
||||
import net.sf.freecol.common.model.Colony;
|
||||
import net.sf.freecol.common.model.GoodsType;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* This panel provides detailed information about rebels in a colony.
|
||||
*/
|
||||
public class RebelToolTip extends JToolTip {
|
||||
|
||||
/**
|
||||
* Creates this RebelToolTip.
|
||||
*
|
||||
* @param colony the colony for which to display information
|
||||
* @param parent a <code>Canvas</code> value
|
||||
*/
|
||||
public RebelToolTip(Colony colony, Canvas parent) {
|
||||
|
||||
setLayout(new MigLayout("fillx, wrap 3", "[][right][right]", ""));
|
||||
|
||||
int members = colony.getMembers();
|
||||
int rebels = colony.getSoL();
|
||||
|
||||
add(new JLabel(Messages.message("colonyPanel.rebelLabel", "%number%", "")));
|
||||
add(new JLabel(Integer.toString(members)));
|
||||
add(new JLabel(Integer.toString(rebels) + "%"));
|
||||
add(new JLabel(Messages.message("colonyPanel.royalistLabel", "%number%", "")));
|
||||
add(new JLabel(Integer.toString(colony.getUnitCount() - members)));
|
||||
add(new JLabel(Integer.toString(colony.getTory()) + "%"));
|
||||
|
||||
int libertyProduction = 0;
|
||||
for (GoodsType goodsType : Specification.getSpecification().getLibertyGoodsTypeList()) {
|
||||
add(new JLabel(goodsType.getName()));
|
||||
int netProduction = colony.getProductionNetOf(goodsType);
|
||||
libertyProduction += netProduction;
|
||||
add(new ProductionLabel(goodsType, netProduction, parent), "span 2");
|
||||
}
|
||||
|
||||
float turns100 = 0;
|
||||
float turns50 = 0;
|
||||
float turnsNext = 0;
|
||||
|
||||
if (libertyProduction > 0) {
|
||||
int liberty = colony.getLiberty();
|
||||
int requiredLiberty = Colony.LIBERTY_PER_REBEL * colony.getUnitCount();
|
||||
|
||||
if (liberty < requiredLiberty) {
|
||||
turns100 = (requiredLiberty - liberty) / libertyProduction;
|
||||
}
|
||||
|
||||
requiredLiberty = requiredLiberty / 2;
|
||||
if (liberty < requiredLiberty) {
|
||||
turns50 = (requiredLiberty - liberty) / libertyProduction;
|
||||
}
|
||||
|
||||
if (members < colony.getUnitCount()) {
|
||||
requiredLiberty = Colony.LIBERTY_PER_REBEL * (members + 1);
|
||||
if (liberty < requiredLiberty) {
|
||||
turnsNext = (requiredLiberty - liberty) / libertyProduction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String na = Messages.message("notApplicable.short");
|
||||
add(new JLabel(Messages.message("report.nextMember")));
|
||||
add(new JLabel(turnsNext == 0 ? na : Integer.toString((int) Math.ceil(turnsNext))), "skip");
|
||||
add(new JLabel(Messages.message("report.50percent")));
|
||||
add(new JLabel(turns50 == 0 ? na : Integer.toString((int) Math.ceil(turns50))), "skip");
|
||||
add(new JLabel(Messages.message("report.100percent")));
|
||||
add(new JLabel(turns100 == 0 ? na : Integer.toString((int) Math.ceil(turns100))), "skip");
|
||||
|
||||
}
|
||||
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(350, 250);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ public final class ReportColonyPanel extends ReportPanel {
|
|||
// Display Panel
|
||||
Collections.sort(colonies, getClient().getClientOptions().getColonyComparator());
|
||||
|
||||
reportPanel.setLayout(new MigLayout("fill, wrap 24", "", ""));
|
||||
reportPanel.setLayout(new MigLayout("fill, wrap 16"));
|
||||
|
||||
for (Colony colony : colonies) {
|
||||
|
||||
|
@ -80,9 +80,9 @@ public final class ReportColonyPanel extends ReportPanel {
|
|||
Collections.sort(unitList, getUnitTypeComparator());
|
||||
for (Unit unit : unitList) {
|
||||
UnitLabel unitLabel = new UnitLabel(unit, getCanvas(), true, true);
|
||||
reportPanel.add(unitLabel, "span 2");
|
||||
reportPanel.add(unitLabel, "sg units");
|
||||
}
|
||||
if (unitList.size() % 12 != 0) {
|
||||
if (unitList.size() % 16 != 0) {
|
||||
reportPanel.add(new JLabel(), "wrap");
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ public final class ReportColonyPanel extends ReportPanel {
|
|||
UnitLabel unitLabel = new UnitLabel(unit, getCanvas(), true, true);
|
||||
reportPanel.add(unitLabel, "span 2");
|
||||
}
|
||||
if (unitList.size() % 12 != 0) {
|
||||
if (unitList.size() % 8 != 0) {
|
||||
reportPanel.add(new JLabel(), "wrap");
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ public final class ReportColonyPanel extends ReportPanel {
|
|||
if (netFood != 0) {
|
||||
ProductionLabel productionLabel = new ProductionLabel(Goods.FOOD, netFood, getCanvas());
|
||||
productionLabel.setStockNumber(colony.getFoodCount());
|
||||
reportPanel.add(productionLabel, "span 3, top");
|
||||
reportPanel.add(productionLabel, "span 2, top");
|
||||
count++;
|
||||
}
|
||||
for (GoodsType goodsType : FreeCol.getSpecification().getGoodsTypeList()) {
|
||||
|
@ -121,7 +121,7 @@ public final class ReportColonyPanel extends ReportPanel {
|
|||
productionLabel.setMaxGoodsIcons(1);
|
||||
}
|
||||
productionLabel.setStockNumber(stockValue); // Show stored items in ReportColonyPanel
|
||||
reportPanel.add(productionLabel, "span 3, top");
|
||||
reportPanel.add(productionLabel, "span 2, top");
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
@ -136,19 +136,20 @@ public final class ReportColonyPanel extends ReportPanel {
|
|||
new JLabel(new ImageIcon(ResourceManager.getImage(building.getType().getId()
|
||||
+ ".image", 0.66)));
|
||||
buildingLabel.setToolTipText(building.getName());
|
||||
reportPanel.add(buildingLabel, "span 3");
|
||||
reportPanel.add(buildingLabel, "span 2");
|
||||
}
|
||||
|
||||
// Buildings
|
||||
BuildableType currentType = colony.getCurrentlyBuilding();
|
||||
JLabel buildableLabel =
|
||||
new JLabel(new ImageIcon(ResourceManager.getImage(currentType.getId()
|
||||
+ ".image", 0.66)));
|
||||
buildableLabel.setToolTipText(Messages.message("colonyPanel.currentlyBuilding",
|
||||
"%buildable%", currentType.getName()));
|
||||
buildableLabel.setIcon(buildableLabel.getDisabledIcon());
|
||||
reportPanel.add(buildableLabel, "span 3");
|
||||
|
||||
if (currentType != null) {
|
||||
JLabel buildableLabel =
|
||||
new JLabel(new ImageIcon(ResourceManager.getImage(currentType.getId()
|
||||
+ ".image", 0.66)));
|
||||
buildableLabel.setToolTipText(Messages.message("colonyPanel.currentlyBuilding",
|
||||
"%buildable%", currentType.getName()));
|
||||
buildableLabel.setIcon(buildableLabel.getDisabledIcon());
|
||||
reportPanel.add(buildableLabel, "span 2");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,7 +58,12 @@ public class ReportPanel extends FreeColPanel implements ActionListener {
|
|||
|
||||
protected JScrollPane scrollPane;
|
||||
|
||||
private static final Comparator<Unit> unitTypeComparator = new Comparator<Unit>() {
|
||||
/**
|
||||
* The saved size of this panel.
|
||||
*/
|
||||
private static Dimension savedSize = new Dimension(850, 600);
|
||||
|
||||
public static final Comparator<Unit> unitTypeComparator = new Comparator<Unit>() {
|
||||
public int compare(Unit unit1, Unit unit2) {
|
||||
int deltaType = unit2.getType().getIndex() - unit1.getType().getIndex();
|
||||
if (deltaType == 0) {
|
||||
|
@ -95,23 +100,30 @@ public class ReportPanel extends FreeColPanel implements ActionListener {
|
|||
|
||||
add(okButton, "tag ok");
|
||||
|
||||
setSize(850, 600);
|
||||
setPreferredSize(savedSize);
|
||||
}
|
||||
|
||||
protected Border createBorder() {
|
||||
return new EmptyBorder(20, 20, 20, 20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return new Dimension(850, 600);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return getMinimumSize();
|
||||
/**
|
||||
* Get the <code>SavedSize</code> value.
|
||||
*
|
||||
* @return a <code>Dimension</code> value
|
||||
*/
|
||||
public final Dimension getSavedSize() {
|
||||
return savedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the <code>SavedSize</code> value.
|
||||
*
|
||||
* @param newSavedSize The new SavedSize value.
|
||||
*/
|
||||
public final void setSavedSize(final Dimension newSavedSize) {
|
||||
this.savedSize = newSavedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares this panel to be displayed.
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.List;
|
|||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.text.StyleConstants;
|
||||
import javax.swing.text.StyledDocument;
|
||||
|
||||
|
@ -39,6 +40,8 @@ import net.sf.freecol.common.model.Player;
|
|||
import net.sf.freecol.common.model.Unit;
|
||||
import net.sf.freecol.common.model.UnitType;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* This panel displays the Advanced Colony Report.
|
||||
*/
|
||||
|
@ -169,6 +172,8 @@ public final class ReportRequirementsPanel extends ReportPanel {
|
|||
}
|
||||
|
||||
// text area
|
||||
int width = ((JViewport) reportPanel.getParent()).getWidth();
|
||||
reportPanel.setLayout(new MigLayout("width " + width + "!"));
|
||||
reportPanel.add(textPane);
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ package net.sf.freecol.client.gui.panel;
|
|||
import java.awt.Image;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
@ -97,7 +96,7 @@ public final class ReportTurnPanel extends ReportPanel {
|
|||
|
||||
// Display Panel
|
||||
reportPanel.removeAll();
|
||||
reportPanel.setLayout(new MigLayout("wrap 4, fillx", "[][500!][][]", ""));
|
||||
reportPanel.setLayout(new MigLayout("wrap 4", "[center][550!]:push[][]", ""));
|
||||
|
||||
source = this;
|
||||
type = null;
|
||||
|
|
|
@ -228,9 +228,12 @@ public final class UnitLabel extends JLabel implements ActionListener {
|
|||
*/
|
||||
public void paintComponent(Graphics g) {
|
||||
|
||||
if (getToolTipText() == null) {
|
||||
setToolTipText(unit.getName());
|
||||
String name = unit.getName();
|
||||
String equipmentLabel = unit.getEquipmentLabel();
|
||||
if (equipmentLabel != null) {
|
||||
name = name + " (" + equipmentLabel + ")";
|
||||
}
|
||||
setToolTipText(name);
|
||||
|
||||
if (ignoreLocation || selected || (!unit.isCarrier() && unit.getState() != UnitState.SENTRY)) {
|
||||
setEnabled(true);
|
||||
|
|
|
@ -30,6 +30,7 @@ import java.util.Set;
|
|||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.border.Border;
|
||||
|
||||
import net.sf.freecol.client.gui.Canvas;
|
||||
import net.sf.freecol.client.gui.i18n.Messages;
|
||||
|
@ -50,6 +51,10 @@ import net.miginfocom.swing.MigLayout;
|
|||
|
||||
public class WorkProductionPanel extends FreeColPanel {
|
||||
|
||||
private static final Border border = BorderFactory
|
||||
.createCompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.BLACK),
|
||||
BorderFactory.createEmptyBorder(2, 2, 2, 2));
|
||||
|
||||
public WorkProductionPanel(Canvas canvas, Unit unit) {
|
||||
super(canvas);
|
||||
|
||||
|
@ -69,7 +74,6 @@ public class WorkProductionPanel extends FreeColPanel {
|
|||
modifiers = sortModifiers(basicModifiers);
|
||||
basicModifiers.addAll(colony.getModifierSet(goodsType.getId()));
|
||||
if (colony.getProductionBonus() != 0) {
|
||||
colonyModifiers.add(colony.getProductionModifier(goodsType));
|
||||
modifiers.add(colony.getProductionModifier(goodsType));
|
||||
}
|
||||
|
||||
|
@ -91,13 +95,16 @@ public class WorkProductionPanel extends FreeColPanel {
|
|||
basicModifiers.add(building.getType().getProductionModifier());
|
||||
}
|
||||
if (goodsType != null) {
|
||||
basicModifiers.addAll(unit.getModifierSet(goodsType.getId()));
|
||||
basicModifiers.addAll(unit.getType().getModifierSet(goodsType.getId()));
|
||||
}
|
||||
modifiers = sortModifiers(basicModifiers);
|
||||
colonyModifiers.addAll(colony.getModifierSet(goodsType.getId()));
|
||||
modifiers.addAll(unit.getColony().getModifierSet(goodsType.getId()));
|
||||
for (Modifier modifier : colony.getModifierSet(goodsType.getId())) {
|
||||
if (modifier.getSource() != building.getType()) {
|
||||
colonyModifiers.add(modifier);
|
||||
}
|
||||
}
|
||||
modifiers.addAll(sortModifiers(colonyModifiers));
|
||||
if (colony.getProductionBonus() != 0) {
|
||||
colonyModifiers.add(colony.getProductionModifier(goodsType));
|
||||
modifiers.add(colony.getProductionModifier(goodsType));
|
||||
}
|
||||
add(new JLabel(building.getName()), "span, align center, wrap 30");
|
||||
|
@ -107,6 +114,7 @@ public class WorkProductionPanel extends FreeColPanel {
|
|||
|
||||
add(new UnitLabel(unit, canvas, false, false), "wrap");
|
||||
|
||||
int totalPercentage = 0;
|
||||
for (Modifier modifier : modifiers) {
|
||||
FreeColGameObjectType source = modifier.getSource();
|
||||
String sourceName;
|
||||
|
@ -122,7 +130,6 @@ public class WorkProductionPanel extends FreeColPanel {
|
|||
}
|
||||
}
|
||||
}
|
||||
add(new JLabel(sourceName), "newline");
|
||||
String bonus = getModifierFormat().format(modifier.getValue());
|
||||
boolean percentage = false;
|
||||
switch(modifier.getType()) {
|
||||
|
@ -141,7 +148,21 @@ public class WorkProductionPanel extends FreeColPanel {
|
|||
bonus = "\u00D7" + bonus;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
if (modifier.getType() == Modifier.Type.PERCENTAGE) {
|
||||
totalPercentage += modifier.getValue();
|
||||
} else if (totalPercentage != 0) {
|
||||
String result = getModifierFormat().format(totalPercentage);
|
||||
if (totalPercentage > 0) {
|
||||
result = "+" + result;
|
||||
}
|
||||
JLabel resultLabel = new JLabel(result);
|
||||
resultLabel.setBorder(border);
|
||||
add(resultLabel, "skip");
|
||||
add(new JLabel("%"));
|
||||
totalPercentage = 0;
|
||||
}
|
||||
add(new JLabel(sourceName), "newline");
|
||||
add(new JLabel(bonus));
|
||||
if (percentage) {
|
||||
add(new JLabel("%"));
|
||||
|
@ -150,17 +171,17 @@ public class WorkProductionPanel extends FreeColPanel {
|
|||
|
||||
Font bigFont = getFont().deriveFont(Font.BOLD, 16);
|
||||
|
||||
int result = (int) (FeatureContainer.applyModifierSet(0, getGame().getTurn(), basicModifiers)
|
||||
+ FeatureContainer.applyModifierSet(0, getGame().getTurn(), colonyModifiers));
|
||||
int result = (int) FeatureContainer.applyModifierSet(0, getGame().getTurn(), basicModifiers);
|
||||
result = (int) FeatureContainer.applyModifierSet(result, getGame().getTurn(), colonyModifiers);
|
||||
result += colony.getProductionBonus();
|
||||
|
||||
JLabel finalLabel = new JLabel(Messages.message("model.source.finalResult.name"));
|
||||
finalLabel.setFont(bigFont);
|
||||
add(finalLabel, "newline");
|
||||
|
||||
JLabel finalResult = new JLabel(getModifierFormat().format(result));
|
||||
finalResult.setFont(bigFont);
|
||||
finalResult.setBorder(BorderFactory
|
||||
.createCompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.BLACK),
|
||||
BorderFactory.createEmptyBorder(2, 2, 2, 2)));
|
||||
finalResult.setBorder(border);
|
||||
add(finalResult, "wrap 30");
|
||||
|
||||
add(okButton, "span, tag ok");
|
||||
|
|
|
@ -229,13 +229,7 @@ public abstract class Feature extends FreeColObject {
|
|||
return true;
|
||||
} else if (o instanceof Feature) {
|
||||
Feature feature = (Feature) o;
|
||||
if (getId() == null) {
|
||||
if (feature.getId() != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (feature.getId() == null) {
|
||||
return false;
|
||||
} else if (!getId().equals(feature.getId())) {
|
||||
if (getId() != feature.getId()) {
|
||||
return false;
|
||||
}
|
||||
if (source != feature.source) {
|
||||
|
|
|
@ -530,14 +530,14 @@ abstract public class Settlement extends FreeColGameObject implements Location,
|
|||
* Gets food consumption by type
|
||||
*/
|
||||
public int getFoodConsumptionByType(GoodsType type) {
|
||||
// Since for now only model.goods.food are needed for other purposes
|
||||
//we will hard code the preference of consumption for other types of food
|
||||
// If later other requirements appear, an allocation algorithm needs to be
|
||||
//implemented
|
||||
// Since for now only model.goods.food are needed for other
|
||||
// purposes we will hard code the preference of consumption
|
||||
// for other types of food If later other requirements appear,
|
||||
// an allocation algorithm needs to be implemented
|
||||
|
||||
if(!type.isFoodType()){
|
||||
logger.warning("Good type given isnt food type");
|
||||
return 0;
|
||||
logger.warning("Good type given isnt food type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int required = getFoodConsumption();
|
||||
|
@ -545,16 +545,16 @@ abstract public class Settlement extends FreeColGameObject implements Location,
|
|||
GoodsType corn = FreeCol.getSpecification().getGoodsType("model.goods.food");
|
||||
|
||||
for (GoodsType foodType : FreeCol.getSpecification().getGoodsFood()) {
|
||||
if(foodType == corn){
|
||||
// consumption of corn calculated last
|
||||
continue;
|
||||
}
|
||||
if(foodType == corn){
|
||||
// consumption of corn calculated last
|
||||
continue;
|
||||
}
|
||||
|
||||
consumed = Math.min(getProductionOf(foodType),required);
|
||||
if(type == foodType){
|
||||
return consumed;
|
||||
}
|
||||
required -= consumed;
|
||||
consumed = Math.min(getProductionOf(foodType),required);
|
||||
if(type == foodType){
|
||||
return consumed;
|
||||
}
|
||||
required -= consumed;
|
||||
}
|
||||
|
||||
// type asked is corn, calculate consumption and return
|
||||
|
|
|
@ -709,17 +709,19 @@ public class SimpleCombatModel implements CombatModel {
|
|||
// the attacker is Indian, which cannot be a player
|
||||
// only messages directed to the losing player need to be sent
|
||||
if (colony.getUnitCount() <= 1) {
|
||||
defendingPlayer.getHistory().add(new HistoryEvent(defendingPlayer.getGame().getTurn().getNumber(),
|
||||
HistoryEvent.Type.COLONY_DESTROYED,
|
||||
"%nation%", defendingPlayer.getNationAsString(),
|
||||
"%colony%", colony.getName()));
|
||||
defendingPlayer.addModelMessage(defendingPlayer,
|
||||
ModelMessage.MessageType.COMBAT_RESULT,
|
||||
"model.unit.colonyBurning",
|
||||
"%colony%", colony.getName(),
|
||||
"%amount%", Integer.toString(plunderGold),
|
||||
"%nation%", attackingPlayer.getNationAsString(),
|
||||
"%unit%", attacker.getName());
|
||||
defendingPlayer.getHistory()
|
||||
.add(new HistoryEvent(defendingPlayer.getGame().getTurn().getNumber(),
|
||||
HistoryEvent.Type.COLONY_DESTROYED,
|
||||
"%nation%", attackingPlayer.getNationAsString(),
|
||||
"%colony%", colony.getName()));
|
||||
defendingPlayer
|
||||
.addModelMessage(defendingPlayer,
|
||||
ModelMessage.MessageType.COMBAT_RESULT,
|
||||
"model.unit.colonyBurning",
|
||||
"%colony%", colony.getName(),
|
||||
"%amount%", Integer.toString(plunderGold),
|
||||
"%nation%", attackingPlayer.getNationAsString(),
|
||||
"%unit%", attacker.getName());
|
||||
attackingPlayer.modifyGold(plunderGold);
|
||||
defendingPlayer.modifyGold(-plunderGold);
|
||||
damageAllShips(colony, attacker, repairLocation);
|
||||
|
|
|
@ -2457,6 +2457,36 @@ public class Unit extends FreeColGameObject implements Locatable, Location, Owna
|
|||
return completeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of the unit's equipment.
|
||||
*
|
||||
* @return a <code>String</code> value
|
||||
*/
|
||||
public String getEquipmentLabel() {
|
||||
if (equipment != null && !equipment.isEmpty()) {
|
||||
List<String> equipmentStrings = new ArrayList<String>();
|
||||
for (java.util.Map.Entry<EquipmentType, Integer> entry : equipment.getValues().entrySet()) {
|
||||
EquipmentType type = entry.getKey();
|
||||
int amount = entry.getValue().intValue();
|
||||
if (type.getGoodsRequired().isEmpty()) {
|
||||
equipmentStrings.add(Messages.message("model.goods.goodsAmount",
|
||||
"%goods%", type.getName(),
|
||||
"%amount%", Integer.toString(amount)));
|
||||
} else {
|
||||
for (AbstractGoods goods : type.getGoodsRequired()) {
|
||||
equipmentStrings.add(Messages.message("model.goods.goodsAmount",
|
||||
"%goods%", goods.getType().getName(),
|
||||
"%amount%", Integer.toString(amount * goods.getAmount())));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Utils.join("/", equipmentStrings.toArray(new String[equipmentStrings.size()]));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of a unit in a human readable format. The return value
|
||||
* can be used when communicating with the user.
|
||||
|
|
|
@ -58,7 +58,9 @@ public class LanguageOption extends AbstractOption {
|
|||
{"arz", "\u0645\u0635\u0631\u064A"},
|
||||
{"hsb", "Serb\u0161\u0107ina"},
|
||||
{"nds", "Plattd\u00fc\u00fctsch"},
|
||||
{"pms", "Piemont\u00e9s"}
|
||||
{"pms", "Piemont\u00e9s"},
|
||||
{"be-tarask", "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f "
|
||||
+ "(\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430)" }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1028,6 +1028,14 @@ public final class InGameInputHandler extends InputHandler implements NetworkCon
|
|||
defendingPlayer.surrenderTo(player);
|
||||
}
|
||||
|
||||
// We need to send an update of the unit, may have been changed
|
||||
//like getting cargo
|
||||
if (result.type.compareTo(CombatResultType.WIN) >= 0 && unit.isNaval()){
|
||||
Element update = reply.getOwnerDocument().createElement("update");
|
||||
update.appendChild(unit.toXMLElement(player,update.getOwnerDocument()));
|
||||
reply.appendChild(update);
|
||||
}
|
||||
|
||||
if (result.type.compareTo(CombatResultType.WIN) >= 0
|
||||
&& unit.getTile() != newTile
|
||||
&& oldUnits < unit.getTile().getUnitCount()) {
|
||||
|
|
|
@ -395,15 +395,76 @@ public class BuildingTest extends FreeColTestCase {
|
|||
game.setMap(getTestMap(plainsType,true));
|
||||
|
||||
Colony colony = getStandardColony(6);
|
||||
Unit unit = colony.getRandomUnit();
|
||||
Building building = colony.getBuilding(spec().getBuildingType("model.building.TownHall"));
|
||||
int bellProduction = building.getProduction();
|
||||
int expectBellProd = 1;
|
||||
assertEquals("Wrong initial bell production",expectBellProd,bellProduction);
|
||||
building.add(unit);
|
||||
bellProduction = building.getProduction();
|
||||
expectBellProd = 4; // 1 initial plus 3 from the colonist
|
||||
assertEquals("Wrong bell production",expectBellProd,bellProduction);
|
||||
Player owner = colony.getOwner();
|
||||
Unit unit1 = colony.getUnitList().get(0);
|
||||
Unit unit2 = colony.getUnitList().get(1);
|
||||
BuildingType townHall = spec().getBuildingType("model.building.TownHall");
|
||||
Building building = colony.getBuilding(townHall);
|
||||
|
||||
Set<Modifier> modifiers = colony.getModifierSet("model.goods.bells");
|
||||
assertEquals(1, modifiers.size());
|
||||
Modifier bellsModifier = modifiers.iterator().next();
|
||||
assertEquals(Modifier.Type.ADDITIVE, bellsModifier.getType());
|
||||
assertEquals(1.0f, bellsModifier.getValue());
|
||||
|
||||
assertEquals("Wrong initial bell production",
|
||||
(int) bellsModifier.getValue(), building.getProduction());
|
||||
|
||||
building.add(unit1);
|
||||
// 3 from the colonist
|
||||
assertEquals(3, unit1.getProductionOf(Goods.BELLS, townHall.getBasicProduction()));
|
||||
assertEquals(3, building.getUnitProductivity(unit1));
|
||||
// 3 from the colonist + 1
|
||||
assertEquals("Wrong bell production", 4, building.getProduction());
|
||||
|
||||
owner.addFather(spec().getFoundingFather("model.foundingFather.thomasJefferson"));
|
||||
// 3 from the colonist + 50% = 5
|
||||
assertEquals(5, unit1.getProductionOf(Goods.BELLS, townHall.getBasicProduction()));
|
||||
assertEquals(5, building.getUnitProductivity(unit1));
|
||||
// 3 from the colonist + 50% + 1 = 6
|
||||
assertEquals("Wrong bell production with Jefferson", 6, building.getProduction());
|
||||
|
||||
building.add(unit2);
|
||||
// 3 from each colonist + 50% = 5
|
||||
assertEquals(5, unit1.getProductionOf(Goods.BELLS, townHall.getBasicProduction()));
|
||||
assertEquals(5, building.getUnitProductivity(unit1));
|
||||
assertEquals(5, unit2.getProductionOf(Goods.BELLS, townHall.getBasicProduction()));
|
||||
assertEquals(5, building.getUnitProductivity(unit2));
|
||||
// 5 + 5 + 1 = 11
|
||||
assertEquals("Wrong bell production with Jefferson", 11, building.getProduction());
|
||||
|
||||
setProductionBonus(colony, 2);
|
||||
// 3 from each colonist + 50% + 2 = 7
|
||||
assertEquals(5, unit1.getProductionOf(Goods.BELLS, townHall.getBasicProduction()));
|
||||
assertEquals(7, building.getUnitProductivity(unit1));
|
||||
assertEquals(5, unit2.getProductionOf(Goods.BELLS, townHall.getBasicProduction()));
|
||||
assertEquals(7, building.getUnitProductivity(unit2));
|
||||
// 7 + 7 + 1 = 15
|
||||
assertEquals("Wrong bell production with Jefferson and +2 production bonus",
|
||||
15, building.getProduction());
|
||||
|
||||
Building newspaper = new Building(getGame(), colony, newspaperType);
|
||||
colony.addBuilding(newspaper);
|
||||
|
||||
System.out.println("unit");
|
||||
for (Modifier modifier : unit1.getModifierSet("model.goods.bells")) {
|
||||
System.out.println(modifier);
|
||||
}
|
||||
System.out.println("colony");
|
||||
for (Modifier modifier : colony.getModifierSet("model.goods.bells")) {
|
||||
System.out.println(modifier);
|
||||
}
|
||||
|
||||
// 3 from each colonist + 50% + 2 = 7
|
||||
assertEquals(5, unit1.getProductionOf(Goods.BELLS, townHall.getBasicProduction()));
|
||||
assertEquals(7, building.getUnitProductivity(unit1));
|
||||
assertEquals(5, unit2.getProductionOf(Goods.BELLS, townHall.getBasicProduction()));
|
||||
assertEquals(7, building.getUnitProductivity(unit2));
|
||||
// 7 + 7 + 1 + 150% = 38
|
||||
assertEquals("Wrong bell production with Jefferson, newspaper and +2 production bonus",
|
||||
38, building.getProduction());
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void testPrintingPressBonus() {
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
package net.sf.freecol.common.model;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -94,16 +92,6 @@ public class SchoolTest extends FreeColTestCase {
|
|||
return colony.getBuilding(schoolType);
|
||||
}
|
||||
|
||||
private void setProductionBonus(Colony colony, int value) {
|
||||
try {
|
||||
Field productionBonus = Colony.class.getDeclaredField("productionBonus");
|
||||
productionBonus.setAccessible(true);
|
||||
productionBonus.setInt(colony, value);
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BuildingType schoolType = spec().getBuildingType("model.building.Schoolhouse");
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package net.sf.freecol.util.test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Locale;
|
||||
|
@ -523,4 +525,23 @@ public class FreeColTestCase extends TestCase {
|
|||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the production bonus of the given colony to the given
|
||||
* value.
|
||||
*
|
||||
* @param colony a <code>Colony</code> value
|
||||
* @param value an <code>int</code> value
|
||||
*/
|
||||
public void setProductionBonus(Colony colony, int value) {
|
||||
try {
|
||||
Field productionBonus = Colony.class.getDeclaredField("productionBonus");
|
||||
productionBonus.setAccessible(true);
|
||||
productionBonus.setInt(colony, value);
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue