/**
* Copyright (C) 2002-2012 The FreeCol Team
*
* This file is part of FreeCol.
*
* FreeCol is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* FreeCol is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FreeCol. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.freecol.client.gui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import org.freecolandroid.repackaged.java.awt.Component;
import org.freecolandroid.repackaged.java.awt.Container;
import org.freecolandroid.repackaged.java.awt.Font;
import org.freecolandroid.repackaged.java.awt.event.ActionEvent;
import org.freecolandroid.repackaged.java.awt.event.ActionListener;
import org.freecolandroid.repackaged.javax.swing.JMenu;
import org.freecolandroid.repackaged.javax.swing.JMenuItem;
import org.freecolandroid.repackaged.javax.swing.JPopupMenu;
import org.freecolandroid.repackaged.javax.swing.JSeparator;
import net.sf.freecol.FreeCol;
import net.sf.freecol.client.FreeColClient;
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.ReportPanel;
import net.sf.freecol.common.model.Colony;
import net.sf.freecol.common.model.CombatModel.CombatOdds;
import net.sf.freecol.common.model.Game;
import net.sf.freecol.common.model.Goods;
import net.sf.freecol.common.model.GoodsContainer;
import net.sf.freecol.common.model.GoodsType;
import net.sf.freecol.common.model.IndianSettlement;
import net.sf.freecol.common.model.LostCityRumour.RumourType;
import net.sf.freecol.common.model.Player;
import net.sf.freecol.common.model.Settlement;
import net.sf.freecol.common.model.Specification;
import net.sf.freecol.common.model.StringTemplate;
import net.sf.freecol.common.model.Tension;
import net.sf.freecol.common.model.Tile;
import net.sf.freecol.common.model.TradeRoute;
import net.sf.freecol.common.model.Unit;
import net.sf.freecol.common.model.UnitType;
import net.sf.freecol.common.networking.DOMMessage;
import net.sf.freecol.server.ai.AIColony;
import net.sf.freecol.server.ai.AIGoods;
import net.sf.freecol.server.ai.AIUnit;
import net.sf.freecol.server.ai.TileImprovementPlan;
import net.sf.freecol.server.ai.Wish;
import net.sf.freecol.server.ai.mission.TransportMission;
import net.sf.freecol.server.model.ServerUnit;
/**
* Allows the user to obtain more info about a certain tile or to
* activate a specific unit on the tile, or perform various debug mode
* actions.
*/
public final class TilePopup extends JPopupMenu {
@SuppressWarnings("unused")
private static final Logger logger = Logger.getLogger(TilePopup.class.getName());
public static final int UNIT_LINES_IN_FIRST_MENU = 9;
public static final int UNIT_LINES_IN_OTHER_MENUS = 19;
private final FreeColClient freeColClient;
private final GUI gui;
private final MapViewer mapViewer;
private boolean hasAnItem = false;
/**
* The constructor that will insert the MenuItems.
* @param freeColClient The main controller object for the client.
* @param tile The <code>Tile</code> to create a popup for.
* The popup menu also appears near this <code>Tile</code>.
* @param gui The GUI frontend.
* @param gui An object with methods used for making the popup.
*/
public TilePopup(final FreeColClient freeColClient, final GUI gui, final Tile tile) {
super(Messages.message(StringTemplate.template("tile")
.addAmount("%x%", tile.getX())
.addAmount("%y%", tile.getY())));
this.freeColClient = freeColClient;
this.gui = gui;
this.mapViewer = gui.getMapViewer();
final Player player = freeColClient.getMyPlayer();
final Unit activeUnit = gui.getActiveUnit();
if (activeUnit != null) {
Tile unitTile = activeUnit.getTile();
JMenuItem gotoMenuItem = null;
if (activeUnit.isOffensiveUnit() &&
unitTile.isAdjacent(tile) &&
activeUnit.getMoveType(tile).isAttack()) {
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
if (tile.getSettlement() != null || combatOdds.win == CombatOdds.UNKNOWN_ODDS) {
victoryPercent = "??";
} else {
victoryPercent = Integer.toString((int)(combatOdds.win * 100));
}
gotoMenuItem = new JMenuItem(Messages.message(StringTemplate.
template("attackTileOdds").addName("%chance%", victoryPercent)));
} else if (activeUnit.getSimpleMoveType(unitTile, tile).isLegal()) {
//final Image gotoImage = (Image) UIManager.get("cursor.go.image");
//JMenuItem gotoMenuItem = new JMenuItem(Messages.message("gotoThisTile"), new ImageIcon(gotoImage));
gotoMenuItem = new JMenuItem(Messages.message("gotoThisTile"));
}
if (gotoMenuItem != null) {
gotoMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (!freeColClient.currentPlayerIsMyPlayer()) {
return;
}
Tile currTile = activeUnit.getTile();
// just checking we are not already at the destination
if (currTile==tile) {
return;
}
freeColClient.getInGameController().setDestination(activeUnit, tile);
freeColClient.getInGameController().moveToDestination(activeUnit);
//if unit did not move, we should show the goto path
if(activeUnit.getTile() == currTile){
mapViewer.updateGotoPathForActiveUnit();
}
}
});
add(gotoMenuItem);
hasAnItem = true;
}
// Add move to Europe entry if the unit can do so
if (unitTile == tile && activeUnit.isNaval()
&& activeUnit.canMoveToEurope()) {
JMenuItem europeMenuItem
= new JMenuItem(Messages.message(StringTemplate.template("gotoEurope")));
europeMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (!freeColClient.currentPlayerIsMyPlayer()) {
return;
}
freeColClient.getInGameController()
.moveTo(activeUnit, player.getEurope());
}
});
add(europeMenuItem);
hasAnItem = true;
}
if (hasAnItem) addSeparator();
}
Settlement settlement = tile.getSettlement();
if (settlement != null) {
if (settlement.getOwner() == player) {
addColony(((Colony) settlement));
} else if (settlement instanceof IndianSettlement) {
addIndianSettlement((IndianSettlement) settlement);
}
if (hasItem()) {
addSeparator();
}
}
addTile(tile);
addSeparator();
int lineCount = 0;
int maxUnits = UNIT_LINES_IN_FIRST_MENU;
Container currentMenu = this;
boolean moreUnits = false;
List<Unit> units = tile.getUnitList();
Collections.sort(units, ReportPanel.unitTypeComparator);
for (final Unit currentUnit : units) {
if (lineCount > maxUnits) {
JMenu more = new JMenu(Messages.message("more"));
more.setFont(more.getFont().deriveFont(Font.ITALIC));
more.setOpaque(false);
currentMenu.add(more);
currentMenu = more;
moreUnits = true;
lineCount = 0;
maxUnits = UNIT_LINES_IN_OTHER_MENUS;
}
lineCount += addUnit(currentMenu, currentUnit, !currentUnit.isUnderRepair(), false);
}
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);
}
// START DEBUG
if (FreeCol.isInDebugMode()
&& freeColClient.getFreeColServer() != null) {
final Game serverGame = freeColClient.getFreeColServer().getGame();
final Player serverPlayer = (Player)
serverGame.getFreeColGameObject(player.getId());
boolean notEmpty = false;
addSeparator();
JMenu takeOwnership = new JMenu("Take ownership");
takeOwnership.setOpaque(false);
JMenu transportLists = new JMenu("Transport lists");
transportLists.setOpaque(false);
for (final Unit currentUnit : tile.getUnitList()) {
JMenuItem toMenuItem = new JMenuItem(currentUnit.toString());
toMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// Server:
final Unit serverUnit = (Unit) serverGame.getFreeColGameObject(currentUnit.getId());
serverUnit.setOwner(serverPlayer);
for (Unit serverChildUnit : currentUnit.getUnitList()) {
serverChildUnit.setOwner(serverPlayer);
}
freeColClient.getConnectController().reconnect();
}
});
takeOwnership.add(toMenuItem);
notEmpty = true;
if (currentUnit.isCarrier()) {
final AIUnit au = freeColClient.getFreeColServer()
.getAIMain().getAIUnit(currentUnit);
if (au.getMission() != null && au.getMission() instanceof TransportMission) {
JMenuItem menuItem = new JMenuItem(currentUnit.toString());
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
gui.showInformationMessage(au.getMission().toString());
}
});
transportLists.add(menuItem);
}
}
}
if (transportLists.getItemCount() > 0) {
add(transportLists);
}
if (tile.getColony() != null) {
if (!notEmpty) {
takeOwnership.addSeparator();
}
JMenuItem toMenuItem = new JMenuItem(tile.getSettlement().toString());
toMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// Server:
final Tile serverTile = (Tile)
serverGame.getFreeColGameObject(tile.getId());
serverTile.getSettlement().changeOwner(serverPlayer);
freeColClient.getConnectController().reconnect();
}
});
takeOwnership.add(toMenuItem);
notEmpty = true;
JMenuItem displayColonyPlan = new JMenuItem("Display Colony Plan");
displayColonyPlan.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// Server:
final Tile serverTile = (Tile)
serverGame.getFreeColGameObject(tile.getId());
final AIColony ac = freeColClient.getFreeColServer()
.getAIMain().getAIColony(serverTile.getColony());
StringBuilder info = new StringBuilder(ac.getColonyPlan().toString());
info.append("\n\nTILE IMPROVEMENTS:\n");
for (TileImprovementPlan tip : ac.getTileImprovementPlans()) {
info.append(tip.toString());
info.append("\n");
}
info.append("\n\nWISHES:\n");
for (Wish w : ac.getWishes()) {
info.append(w.toString());
info.append("\n");
}
info.append("\n\nEXPORT GOODS:\n");
for (AIGoods aig : ac.getAIGoods()) {
info.append(aig.toString());
info.append("\n");
}
gui.showInformationMessage(info.toString());
}
});
add(displayColonyPlan);
}
if (tile.getIndianSettlement() != null) {
JMenuItem displayGoods = new JMenuItem("Examine Settlement");
final IndianSettlement is = tile.getIndianSettlement();
displayGoods.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
final IndianSettlement sis = (IndianSettlement)
serverGame.getFreeColGameObject(is.getId());
gui.showInformationMessage(
debugSummarizeSettlement(serverGame, sis));
}
});
add(displayGoods);
}
if (notEmpty) {
add(takeOwnership);
hasAnItem = true;
}
if (tile.hasLostCityRumour()) {
JMenuItem rumourItem = new JMenuItem("Set Lost City Rumour type");
rumourItem.setOpaque(false);
rumourItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
debugSetRumourType(serverGame, tile);
}
});
add(rumourItem);
}
JMenuItem addu = new JMenuItem("Add unit");
addu.setOpaque(false);
addu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
debugAddNewUnitToTile(serverGame, tile);
}
});
add(addu);
if (!tile.isEmpty()) {
final List<Unit> tileUnits = tile.getUnitList();
JMenuItem adda = new JMenuItem("Reset moves");
adda.setOpaque(false);
adda.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
debugResetUnitsMoves(serverGame, tileUnits);
}
});
add(adda);
}
for (Unit u : tile.getUnitList()) {
if (u.getSpaceLeft() > 0) {
final Unit unit = u;
JMenuItem addg = new JMenuItem("Add goods");
addg.setOpaque(false);
addg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
debugAddGoodsToUnit(serverGame, unit);
}
});
add(addg);
break;
}
}
JMenuItem dumpItem = new JMenuItem("Dump tile");
dumpItem.setOpaque(false);
dumpItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.err.println("\nClient side:");
tile.dumpObject();
System.err.println("\n\nServer side:");
serverGame.getFreeColGameObject(tile.getId())
.dumpObject();
System.err.println("\n");
}
});
add(dumpItem);
}
// END DEBUG
Component lastComponent = getComponent(getComponentCount() - 1);
if (lastComponent instanceof JSeparator) {
remove(lastComponent);
}
}
/**
* Adds a unit entry to this popup.
* @param menu a <code>Container</code> value
* @param unit The unit that will be represented on the popup.
* @param enabled The initial state for the menu item.
* @param indent Should be <code>true</code> if the text should be
* indented on the menu.
* @return an <code>int</code> value
*/
private int addUnit(Container menu, final Unit unit, boolean enabled, boolean indent) {
StringTemplate occ;
TradeRoute tradeRoute = unit.getTradeRoute();
if (unit.getState() == Unit.UnitState.ACTIVE
&& unit.getMovesLeft() == 0) {
if (unit.isUnderRepair()) {
occ = StringTemplate.label(": ")
.add("model.unit.occupation.underRepair")
.add(Integer.toString(unit.getTurnsForRepair()));
} else if (tradeRoute != null) {
occ = StringTemplate.label(": ")
.add("model.unit.occupation.inTradeRoute")
.addName(tradeRoute.getName());
} else {
occ = StringTemplate.key("model.unit.occupation.activeNoMovesLeft");
}
} else if (unit.getState() == Unit.UnitState.IMPROVING
&& unit.getWorkImprovement() != null) {
occ = StringTemplate.label(": ")
.add(unit.getWorkImprovement().getType() + ".occupationString")
.add(Integer.toString(unit.getWorkTurnsLeft()));
} else if (tradeRoute != null) {
occ = StringTemplate.label(": ")
.add("model.unit.occupation.inTradeRoute")
.add(tradeRoute.getName());
} else if (unit.getDestination() != null) {
occ = StringTemplate.key("model.unit.occupation.goingSomewhere");
} else {
occ = StringTemplate.key("model.unit.occupation." + unit.getState().toString().toLowerCase());
}
String text = (indent ? " " : "")
+ Messages.message(StringTemplate.template("model.unit.nationUnit")
.addStringTemplate("%nation%", unit.getOwner().getNationName())
.addStringTemplate("%unit%", Messages.getLabel(unit)))
+ " (" + Messages.message(occ) + ")";
JMenuItem menuItem = new JMenuItem(text);
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
gui.setActiveUnit(unit);
}
});
int lineCount = 1;
if (indent) {
menuItem.setFont(menuItem.getFont().deriveFont(Font.ITALIC));
}
menuItem.setEnabled(enabled);
menu.add(menuItem);
for (Unit passenger : unit.getUnitList()) {
lineCount += addUnit(menu, passenger, true, true);
}
boolean hasGoods = false;
for (Goods goods: unit.getGoodsList()) {
text = (indent ? " " : " ")
+ Messages.message(goods.getLabel(true));
menuItem = new JMenuItem(text);
menuItem.setFont(menuItem.getFont().deriveFont(Font.ITALIC));
menuItem.setEnabled(false);
menu.add(menuItem);
lineCount++;
hasGoods = true;
}
if (hasGoods) {
JMenuItem dumpItem = new JMenuItem(Messages.message("dumpCargo"));
dumpItem.setAction(new UnloadAction(freeColClient, gui, unit));
menu.add(dumpItem);
lineCount++;
}
hasAnItem = true;
return lineCount;
}
/**
* Adds a colony entry to this popup.
* @param colony The colony that will be represented on the popup.
*/
private void addColony(final Colony colony) {
String name = colony.getNameFor(freeColClient.getMyPlayer());
JMenuItem menuItem = new JMenuItem(Messages.message(name));
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
gui.showColonyPanel(colony);
}
});
add(menuItem);
menuItem = new JMenuItem(Messages.message("rename"));
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
freeColClient.getInGameController().rename(colony);
}
});
add(menuItem);
hasAnItem = true;
}
/**
* Adds an indian settlement entry to this popup.
*
* @param settlement The Indian settlement that will be
* represented on the popup.
*/
private void addIndianSettlement(final IndianSettlement settlement) {
String name = settlement.getNameFor(freeColClient.getMyPlayer());
JMenuItem menuItem = new JMenuItem(Messages.message(name));
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
gui.showIndianSettlementPanel(settlement);
}
});
add(menuItem);
hasAnItem = true;
}
/**
* Adds a tile entry to this popup.
*
* @param tile The tile that will be represented on the popup.
*/
private void addTile(final Tile tile) {
JMenuItem menuItem = new JMenuItem(Messages.message(tile.getNameKey()));
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
gui.showTilePanel(tile);
}
});
add(menuItem);
/**
* Don't set hasAnItem to true, we want the tile panel to open
* automatically whenever there is no other item on the list.
*/
// hasAnItem = true;
}
/**
* Returns true if this popup has at least one menuitem so that we
* know that we can show it to the user. Returns false if there
* are no menuitems.
*
* @return True if this popup has at least one menuitem, false otherwise.
*/
public boolean hasItem() {
return hasAnItem || FreeCol.isInDebugMode();
}
/**
* Debug action to set the lost city rumour type on a tile.
*
* @param serverGame The server <code>Game</code> containing the tile.
* @param tile The <code>Tile</code> to operate on.
*/
private void debugSetRumourType(final Game serverGame, Tile tile) {
List<ChoiceItem<RumourType>> rumours
= new ArrayList<ChoiceItem<RumourType>>();
for (RumourType rumour : RumourType.values()) {
if (rumour == RumourType.NO_SUCH_RUMOUR) continue;
rumours.add(new ChoiceItem<RumourType>(rumour.toString(), rumour));
}
RumourType rumourChoice = gui.showChoiceDialog(null, "Select Lost City Rumour", "Cancel",
rumours);
tile.getTileItemContainer().getLostCityRumour().setType(rumourChoice);
final Tile serverTile = (Tile) serverGame
.getFreeColGameObject(tile.getId());
serverTile.getTileItemContainer().getLostCityRumour()
.setType(rumourChoice);
}
/**
* Debug action to add a new unit to a tile.
*
* @param serverGame The server <code>Game</code> containing the tile.
* @param tile The <code>Tile</code> to add to.
*/
private void debugAddNewUnitToTile(final Game serverGame, Tile tile) {
Specification spec = serverGame.getSpecification();
List<ChoiceItem<UnitType>> uts = new ArrayList<ChoiceItem<UnitType>>();
for (UnitType t : spec.getUnitTypeList()) {
uts.add(new ChoiceItem<UnitType>(Messages.message(t.toString()
+ ".name"), t));
}
UnitType unitChoice = gui.showChoiceDialog(null, "Select Unit Type", "Cancel", uts);
if (unitChoice == null) return;
Player player = freeColClient.getMyPlayer();
Player serverPlayer = (Player) serverGame
.getFreeColGameObject(player.getId());
Tile serverTile = (Tile) serverGame
.getFreeColGameObject(tile.getId());
Unit carrier = null;
if (!serverTile.isLand() && !unitChoice.isNaval()) {
for (Unit u : serverTile.getUnitList()) {
if (u.isNaval()
&& u.getSpaceLeft() >= unitChoice.getSpaceTaken()) {
carrier = u;
break;
}
}
}
ServerUnit serverUnit = new ServerUnit(serverGame,
(carrier != null) ? carrier : serverTile,
serverPlayer, unitChoice);
serverUnit.setMovesLeft(serverUnit.getInitialMovesLeft());
Game game = freeColClient.getGame();
Unit unit = new Unit(game,
serverUnit.toXMLElement(DOMMessage.createNewDocument()));
if (carrier == null) {
tile.add(unit);
} else {
((Unit)game.getFreeColGameObject(carrier.getId())).add(unit);
}
gui.setActiveUnit(unit);
player.invalidateCanSeeTiles();
gui.refresh();
}
/**
* Debug action to reset the moves left of the units on a tile.
*
* @param serverGame The server <code>Game</code> containing the tile.
* @param units The <code>Unit</code>s to reactivate.
*/
private void debugResetUnitsMoves(final Game serverGame, List<Unit> units) {
boolean first = true;
for (Unit u : units) {
Unit su = (Unit)serverGame.getFreeColGameObject(u.getId());
u.setMovesLeft(u.getInitialMovesLeft());
su.setMovesLeft(su.getInitialMovesLeft());
if (first) {
gui.setActiveUnit(u);
first = false;
}
}
gui.refresh();
}
/**
* Debug action to add goods to a unit.
*
* @param serverGame The server <code>Game</code> containing the tile.
* @param tile The <code>Unit</code> to add to.
*/
private void debugAddGoodsToUnit(final Game serverGame, Unit unit) {
Specification spec = serverGame.getSpecification();
List<ChoiceItem<GoodsType>> gtl
= new ArrayList<ChoiceItem<GoodsType>>();
for (GoodsType t : spec.getGoodsTypeList()) {
if (t.isFoodType() && t != spec.getPrimaryFoodType()) continue;
gtl.add(new ChoiceItem<GoodsType>(Messages.message(t.toString() + ".name"),
t));
}
GoodsType goodsType = gui.showChoiceDialog(null, "Select Goods Type", "Cancel", gtl);
if (goodsType == null) return;
String amount = gui.showInputDialog(null,
StringTemplate.name("Select Goods Amount"), "20",
"ok", "cancel", true);
if (amount == null) return;
int a;
try {
a = Integer.parseInt(amount);
} catch (NumberFormatException nfe) {
return;
}
GoodsType sGoodsType = spec.getGoodsType(goodsType.getId());
GoodsContainer ugc = unit.getGoodsContainer();
GoodsContainer sgc = (GoodsContainer) serverGame
.getFreeColGameObject(ugc.getId());
ugc.setAmount(goodsType, a);
sgc.setAmount(sGoodsType, a);
}
/**
* Debug action to summarize information about a native settlement
* that is normally hidden.
*
* @param serverGame The server <code>Game</code> containing the
* settlement.
* @param sis The server version of the <code>IndianSettlement</code>
* to summarize.
* @return A string summarizing the settlement.
*/
private String debugSummarizeSettlement(final Game serverGame,
final IndianSettlement sis) {
Specification spec = serverGame.getSpecification();
StringBuilder sb = new StringBuilder(sis.getName() + "\n");
sb.append("\nAlarm\n");
for (Player p : serverGame.getLiveEuropeanPlayers()) {
Tension tension = sis.getAlarm(p);
sb.append(Messages.message(p.getNationName())
+ " " + ((tension == null) ? "(none)"
: Integer.toString(tension.getValue()))
+ " " + Messages.message(sis.getShortAlarmLevelMessageId(p))
+ " " + ((sis.hasSpokenToChief(p)) ? "(spoke to chief)"
: "")
+ "\n");
}
sb.append("\nGoods Present\n");
for (Goods goods : sis.getCompactGoods()) {
sb.append(Messages.message(goods.getLabel(true)) + "\n");
}
sb.append("\nGoods Production\n");
for (GoodsType type : spec.getGoodsTypeList()) {
int prod = sis.getProductionOf(type);
if (prod > 0) {
sb.append(Messages.message(type.getNameKey())
+ " " + prod + "\n");
}
}
sb.append("\nPrices (buy 1/100 / sell 1/100)\n");
GoodsType[] wanted = sis.getWantedGoods();
for (GoodsType type : spec.getGoodsTypeList()) {
if (!type.isStorable()) continue;
int i;
for (i = wanted.length - 1; i >= 0; i--) {
if (type == wanted[i]) break;
}
sb.append(Messages.message(type.getNameKey())
+ ": " + sis.getPriceToBuy(type, 1)
+ "/" + sis.getPriceToBuy(type, 100)
+ " / " + sis.getPriceToSell(type, 1)
+ "/" + sis.getPriceToSell(type, 100)
+ ((i < 0) ? "" : " wanted[" + Integer.toString(i) + "]")
+ "\n");
}
sb.append("\nOwned Units\n");
for (Unit u : sis.getOwnedUnits()) {
sb.append(u + "\n");
sb.append(" at " + u.getTile() + "\n");
}
sb.append("\nTiles\n");
for (Tile t : sis.getOwnedTiles()) {
sb.append(t + "\n");
}
return sb.toString();
}
}