Show EMapDetailsPanel.java syntax highlighted
/*
* Copyright (C) 2000-2004 Roger Butenuth, Andreas Gampe,
* Stefan Goetz, Sebastian Pappert,
* Klaas Prause, Enno Rehling,
* Sebastian Tusk, Ulrich Kuester,
* Ilja Pavkovic
*
* This file is part of the Eressea Java Code Base, see the
* file LICENSING for the licensing information applying to
* this file.
*
*/
package com.eressea.demo;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.border.TitledBorder;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.undo.UndoManager;
import com.eressea.Alliance;
import com.eressea.Border;
import com.eressea.Building;
import com.eressea.CombatSpell;
import com.eressea.Described;
import com.eressea.DescribedObject;
import com.eressea.Faction;
import com.eressea.GameData;
import com.eressea.Group;
import com.eressea.ID;
import com.eressea.Island;
import com.eressea.Item;
import com.eressea.LuxuryPrice;
import com.eressea.NamedObject;
import com.eressea.Potion;
import com.eressea.Region;
import com.eressea.RegionResource;
import com.eressea.Rules;
import com.eressea.Scheme;
import com.eressea.Ship;
import com.eressea.Skill;
import com.eressea.Spell;
import com.eressea.StringID;
import com.eressea.Unit;
import com.eressea.UnitContainer;
import com.eressea.UnitID;
import com.eressea.ZeroUnit;
import com.eressea.completion.AutoCompletion;
import com.eressea.demo.desktop.DesktopEnvironment;
import com.eressea.demo.desktop.ShortcutListener;
import com.eressea.event.EventDispatcher;
import com.eressea.event.GameDataEvent;
import com.eressea.event.SelectionEvent;
import com.eressea.event.SelectionListener;
import com.eressea.event.UnitOrdersEvent;
import com.eressea.event.UnitOrdersListener;
import com.eressea.gamebinding.eressea.EresseaConstants;
import com.eressea.relation.ControlRelation;
import com.eressea.relation.PersonTransferRelation;
import com.eressea.relation.UnitTransferRelation;
import com.eressea.rules.BuildingType;
import com.eressea.rules.CastleType;
import com.eressea.rules.ItemCategory;
import com.eressea.rules.ItemType;
import com.eressea.rules.ShipType;
import com.eressea.rules.SkillCategory;
import com.eressea.rules.SkillType;
import com.eressea.rules.UnitContainerType;
import com.eressea.swing.BasicRegionPanel;
import com.eressea.swing.InternationalizedDataPanel;
import com.eressea.swing.MenuProvider;
import com.eressea.swing.completion.MultiEditorOrderEditorList;
import com.eressea.swing.context.ContextFactory;
import com.eressea.swing.context.UnitCapacityContextMenu;
import com.eressea.swing.context.UnitContextMenu;
import com.eressea.swing.preferences.ExtendedPreferencesAdapter;
import com.eressea.swing.preferences.PreferencesAdapter;
import com.eressea.swing.preferences.PreferencesFactory;
import com.eressea.swing.tree.CellObject;
import com.eressea.swing.tree.CellRenderer;
import com.eressea.swing.tree.ContextManager;
import com.eressea.swing.tree.CopyTree;
import com.eressea.swing.tree.ItemCategoryNodeWrapper;
import com.eressea.swing.tree.ItemNodeWrapper;
import com.eressea.swing.tree.NodeWrapperDrawPolicy;
import com.eressea.swing.tree.NodeWrapperFactory;
import com.eressea.swing.tree.PotionNodeWrapper;
import com.eressea.swing.tree.RegionNodeWrapper;
import com.eressea.swing.tree.SimpleNodeWrapper;
import com.eressea.swing.tree.TreeUpdate;
import com.eressea.swing.tree.UnitCommentNodeWrapper;
import com.eressea.swing.tree.UnitContainerCommentNodeWrapper;
import com.eressea.swing.tree.UnitContainerNodeWrapper;
import com.eressea.swing.tree.UnitListNodeWrapper;
import com.eressea.swing.tree.UnitNodeWrapper;
import com.eressea.util.CollectionFactory;
import com.eressea.util.Direction;
import com.eressea.util.PropertiesHelper;
import com.eressea.util.ShipRoutePlanner;
import com.eressea.util.Taggable;
import com.eressea.util.Translations;
import com.eressea.util.Umlaut;
import com.eressea.util.Units;
import com.eressea.util.comparator.AllianceFactionComparator;
import com.eressea.util.comparator.BestSkillComparator;
import com.eressea.util.comparator.IDComparator;
import com.eressea.util.comparator.NameComparator;
import com.eressea.util.comparator.PotionLevelComparator;
import com.eressea.util.comparator.SkillComparator;
import com.eressea.util.comparator.SkillTypeComparator;
import com.eressea.util.comparator.SkillTypeRankComparator;
import com.eressea.util.comparator.SortIndexComparator;
import com.eressea.util.comparator.SpecifiedSkillTypeSkillComparator;
import com.eressea.util.comparator.SpellLevelComparator;
import com.eressea.util.comparator.UnitSkillComparator;
import com.eressea.util.logging.Logger;
/**
* TODO: DOCUMENT ME!
*
* @author $author$
* @version $Revision: 399 $
*/
public class EMapDetailsPanel extends InternationalizedDataPanel implements SelectionListener,
ShortcutListener,
ActionListener,
TreeUpdate,
PreferencesFactory,
MenuProvider
{
private static final Logger log = Logger.getInstance(EMapDetailsPanel.class);
// GUI elements
private JTextArea name = null;
private JTextArea description = null;
private DefaultTreeModel treeModel = null;
private DefaultMutableTreeNode rootNode = null;
private CopyTree tree = null;
private AutoCompletion orders = null;
private MultiEditorOrderEditorList editor;
private Region lastRegion = null;
private Units unitsTools = null;
/**
* A list containing nodewrapper objects, the expansion state of nodes contained in this list
* can be automatically stored and restored
*/
private Collection myExpandableNodes = CollectionFactory.createLinkedList();
/** The currently displayed object */
private Object displayedObject = null;
/**
* A list containing selected units
*/
private Collection mySelectedUnits = CollectionFactory.createLinkedList();
/** split pane */
JSplitPane topSplitPane;
/** split pane */
JSplitPane bottomSplitPane;
private static final NumberFormat weightNumberFormat = NumberFormat.getNumberInstance();
protected NodeWrapperFactory nodeWrapperFactory;
private List shortCuts;
protected Collection excludeTags = CollectionFactory.createLinkedList();
protected AbstractButton addTag;
protected AbstractButton removeTag;
protected Container tagContainer;
protected Container treeContainer;
protected boolean showTagButtons = false;
protected boolean allowCustomIcons = true;
protected ContextManager contextManager;
protected StealthContextFactory stealthContext;
protected CombatStateContextFactory combatContext;
protected CommentContextFactory commentContext;
protected UnitCommentContextFactory unitCommentContext;
protected DetailsUnitContextFactory unitContext;
protected UndoManager undoMgr;
protected BasicRegionPanel regionPanel;
// pre-initialize this comparator so it is not created over and
// over again when needed
private Comparator sortIndexComparator = new SortIndexComparator(IDComparator.DEFAULT);
private final ID ironID = StringID.create("Eisen");
private final ID laenID = StringID.create("Laen");
private final ID treesID = StringID.create("Baeume");
private final ID mallornID = StringID.create("Mallorn");
private final ID sproutsID = StringID.create("Schoesslinge");
private final ID mallornSproutsID = StringID.create("Mallornschösslinge");
private final ID stonesID = StringID.create("Steine");
/**
* Creates a new EMapDetailsPanel object.
*
* @param d TODO: DOCUMENT ME!
* @param data TODO: DOCUMENT ME!
* @param p TODO: DOCUMENT ME!
* @param _undoMgr TODO: DOCUMENT ME!
*/
public EMapDetailsPanel(EventDispatcher d, GameData data, Properties p, UndoManager _undoMgr) {
super(d, data, p);
initGUI(_undoMgr);
}
private void initGUI(UndoManager _undoMgr) {
// store undomanager
undoMgr = _undoMgr;
nodeWrapperFactory = new NodeWrapperFactory(settings, "EMapDetailsPanel",
getString("wrapperfactory.title"));
nodeWrapperFactory.setSource(this);
// to get the pref-adapter
Unit temp = new Unit(UnitID.createUnitID(0,10));
nodeWrapperFactory.createUnitNodeWrapper(temp);
nodeWrapperFactory.createSkillNodeWrapper(temp,
new Skill(new SkillType(StringID.create("Test")),
0, 0, 0, false), null);
nodeWrapperFactory.createItemNodeWrapper(new Item(new ItemType(StringID.create("Test")), 0));
nodeWrapperFactory.createSimpleNodeWrapper(null, null);
weightNumberFormat.setMaximumFractionDigits(2);
weightNumberFormat.setMinimumFractionDigits(0);
unitsTools = (data != null) ? new Units(data.rules) : new Units(null);
dispatcher.addSelectionListener(this);
// name text area
name = new JTextArea();
name.setLineWrap(false);
//name.setFont(new Font("SansSerif", Font.PLAIN, name.getFont().getSize()));
name.setCursor(new Cursor(Cursor.TEXT_CURSOR));
name.setEditable(false);
name.getDocument().addUndoableEditListener(_undoMgr);
name.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
if((name.isEditable() == false) || (displayedObject == null)) {
return;
}
if(displayedObject instanceof Unit) {
Unit u = (Unit) displayedObject;
if((((u.getName() == null) && (name.getText().equals("") == false)) ||
((u.getName() != null) &&
(name.getText().equals(u.getName()) == false))) &&
isPrivilegedAndNoSpy(u) && !u.ordersAreNull()) {
// the following code only changes the name
// right now it is not necessary to refresh the relations; are we sure??
data.getGameSpecificStuff().getOrderChanger().addNamingOrder(u,
name.getText());
dispatcher.fire(new UnitOrdersEvent(EMapDetailsPanel.this, u));
//if (u.cache != null && u.cache.orderEditor != null) {
// u.cache.orderEditor.reloadOrders();
//}
}
} else if(displayedObject instanceof UnitContainer) {
UnitContainer uc = (UnitContainer) displayedObject;
Unit modUnit = null;
if(uc instanceof Faction) {
modUnit = (Unit) uc.units().iterator().next();
} else {
modUnit = uc.getOwnerUnit();
}
if(isPrivilegedAndNoSpy(modUnit) && !modUnit.ordersAreNull()) {
if(((uc.getName() == null) && (name.getText().equals("") == false)) ||
((uc.getName() != null) &&
(name.getText().equals(uc.getName()) == false))) {
data.getGameSpecificStuff().getOrderChanger().addNamingOrder(modUnit,
uc,
name.getText());
dispatcher.fire(new UnitOrdersEvent(EMapDetailsPanel.this, modUnit));
//if (modUnit.cache != null && modUnit.cache.orderEditor != null) {
// modUnit.cache.orderEditor.reloadOrders();
//}
}
} else {
JOptionPane.showMessageDialog(((JComponent) e.getSource()).getTopLevelAncestor(),
getString("msg.cannotrename.text"),
getString("error"),
javax.swing.JOptionPane.WARNING_MESSAGE);
tree.grabFocus();
}
} else if(displayedObject instanceof Island) {
((Island) displayedObject).setName(name.getText());
}
}
});
// description text area
description = new JTextArea();
description.setLineWrap(true);
description.setWrapStyleWord(true);
description.setFont(new Font("SansSerif", Font.PLAIN, description.getFont().getSize()));
description.setCursor(new Cursor(Cursor.TEXT_CURSOR));
description.setEditable(false);
description.getDocument().addUndoableEditListener(_undoMgr);
description.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
if((description.isEditable() == false) || (displayedObject == null)) {
return;
}
if(displayedObject instanceof Unit) {
Unit u = (Unit) displayedObject;
if((((u.getDescription() == null) &&
(description.getText().equals("") == false)) ||
((u.getDescription() != null) &&
(description.getText().equals(u.getDescription()) == false))) &&
isPrivilegedAndNoSpy(u) && !u.ordersAreNull()) {
String descr = getDescriptionPart(description.getText());
String privat = getPrivatePart(description.getText());
data.getGameSpecificStuff().getOrderChanger().addDescribeUnitOrder(u,
descr);
if(((u.privDesc == null) && (privat.length() > 0)) ||
((u.privDesc != null) && !privat.equals(u.privDesc))) {
data.getGameSpecificStuff().getOrderChanger()
.addDescribeUnitPrivateOrder(u, privat);
u.privDesc = privat;
}
dispatcher.fire(new UnitOrdersEvent(EMapDetailsPanel.this, u));
//if (u.cache != null && u.cache.orderEditor != null) {
// u.cache.orderEditor.reloadOrders();
//}
}
} else if(displayedObject instanceof UnitContainer) {
UnitContainer uc = (UnitContainer) displayedObject;
Unit modUnit = null;
if(uc instanceof Faction) {
modUnit = (Unit) uc.units().iterator().next();
} else {
modUnit = uc.getOwnerUnit();
}
if(isPrivilegedAndNoSpy(modUnit) && !modUnit.ordersAreNull()) {
if(((uc.getDescription() == null) &&
(description.getText().equals("") == false)) ||
((uc.getDescription() != null) &&
(description.getText().equals(uc.getDescription()) == false))) {
data.getGameSpecificStuff().getOrderChanger()
.addDescribeUnitContainerOrder(modUnit, uc,
normalizeDescription(description.getText()));
dispatcher.fire(new UnitOrdersEvent(EMapDetailsPanel.this, modUnit));
//if (modUnit.cache != null && modUnit.cache.orderEditor != null) {
// modUnit.cache.orderEditor.reloadOrders();
//}
}
} else {
JOptionPane.showMessageDialog(((JComponent) e.getSource()).getTopLevelAncestor(),
getString("msg.cannotdescribe.text"),
getString("error"),
javax.swing.JOptionPane.WARNING_MESSAGE);
tree.grabFocus();
}
} else if(displayedObject instanceof Island) {
((Described) displayedObject).setDescription(normalizeDescription(description.getText()));
}
}
});
JScrollPane descScrollPane = new JScrollPane(description,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
// ClearLook suggests to remove border
descScrollPane.setBorder(null);
// panel combining name and description
JPanel nameDescPanel = new JPanel(new BorderLayout(0, 2));
nameDescPanel.add(name, BorderLayout.NORTH);
nameDescPanel.add(descScrollPane, BorderLayout.CENTER);
nameDescPanel.setPreferredSize(new Dimension(100, 100));
// tree
rootNode = new DefaultMutableTreeNode(null);
treeModel = new DefaultTreeModel(rootNode);
tree = new CopyTree(treeModel);
tree.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if(e.getClickCount() == 2) {
handleValueChange();
}
}
});
// keeping track of selection changes for mySelectedUnits (fiete)
tree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent tslE) {
handleTreeSelectionChangeEvent(tslE);
}
});
// FIXME: bugzilla bug #823 ?
tree.putClientProperty("JTree.lineStyle", "Angled");
tree.setRootVisible(false);
tree.setEditable(true);
tree.setCellRenderer(new CellRenderer(getMagellanContext()));
tree.getCellEditor().addCellEditorListener(new CellEditorListener() {
public void editingCanceled(ChangeEvent e) {
}
public void editingStopped(ChangeEvent e) {
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
if((selectedNode != null) && selectedNode.getUserObject() instanceof UnitContainerCommentNodeWrapper) {
UnitContainerCommentNodeWrapper cnW = (UnitContainerCommentNodeWrapper) selectedNode.getUserObject();
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) selectedNode.getParent();
UnitContainer uc = cnW.getUnitContainer();
if((uc != null) && (uc.comments != null)) {
uc.comments.set(parent.getIndex(selectedNode),
tree.getCellEditor().getCellEditorValue());
}
show(displayedObject,false);
}
}
});
tree.getCellEditor().addCellEditorListener(new CellEditorListener() {
public void editingCanceled(ChangeEvent e) {
}
public void editingStopped(ChangeEvent e) {
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
if((selectedNode != null) && selectedNode.getUserObject() instanceof UnitCommentNodeWrapper) {
UnitCommentNodeWrapper cnW = (UnitCommentNodeWrapper) selectedNode.getUserObject();
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) selectedNode.getParent();
Unit u = cnW.getUnit();
if((u != null) && (u.comments != null)) {
u.comments.set(parent.getIndex(selectedNode),
tree.getCellEditor().getCellEditorValue());
}
show(displayedObject,false);
}
}
});
contextManager = new ContextManager(tree,dispatcher);
stealthContext = new StealthContextFactory();
combatContext = new CombatStateContextFactory();
commentContext = new CommentContextFactory();
unitCommentContext = new UnitCommentContextFactory();
unitContext = new DetailsUnitContextFactory();
contextManager.putSimpleObject(CommentListNode.class, commentContext);
contextManager.putSimpleObject(CommentNode.class, commentContext);
contextManager.putSimpleObject(UnitCommentNode.class, unitCommentContext);
contextManager.putSimpleObject(UnitCommentListNode.class, unitCommentContext);
contextManager.putSimpleObject(UnitNodeWrapper.class, unitContext);
contextManager.putSimpleObject(UnitListNodeWrapper.class, unitContext);
contextManager.putSimpleObject(DefaultMutableTreeNode.class, unitContext);
JScrollPane treeScrollPane = new JScrollPane(tree);
// ClearLook suggests to remove border
treeScrollPane.setBorder(null);
// panel combining the region info and the tree
JPanel pnlRegionInfoTree = new JPanel(new BorderLayout());
pnlRegionInfoTree.add(regionPanel = new BasicRegionPanel(dispatcher, settings),
BorderLayout.NORTH);
pnlRegionInfoTree.add(treeScrollPane, BorderLayout.CENTER);
tagContainer = new JPanel();
tagContainer.setLayout(new GridLayout(1, 2));
treeContainer = pnlRegionInfoTree;
addTag = new JButton(getString("addtag.caption"));
addTag.addActionListener(this);
addTag.setEnabled(false);
tagContainer.add(addTag);
removeTag = new JButton(getString("removetag.caption"));
removeTag.addActionListener(this);
removeTag.setEnabled(false);
tagContainer.add(removeTag);
showTagButtons = settings.getProperty("EMapDetailsPanel.ShowTagButtons", "false").equals("true");
if(showTagButtons) {
pnlRegionInfoTree.add(tagContainer, BorderLayout.SOUTH);
}
allowCustomIcons = settings.getProperty("EMapDetailsPanel.AllowCustomIcons", "true").equals("true");
// split pane combining name, desc & tree
topSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, nameDescPanel, pnlRegionInfoTree);
topSplitPane.setOneTouchExpandable(true);
editor = new MultiEditorOrderEditorList(dispatcher, data, settings, _undoMgr);
// build auto completion structure
orders = new AutoCompletion(dispatcher.getMagellanContext());
orders.attachEditorManager(editor);
shortCuts = CollectionFactory.createArrayList(3);
shortCuts.add(KeyStroke.getKeyStroke(KeyEvent.VK_3, KeyEvent.CTRL_MASK));
shortCuts.add(KeyStroke.getKeyStroke(KeyEvent.VK_3, KeyEvent.ALT_MASK));
// toggle "limit make completion"
shortCuts.add(KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.CTRL_MASK));
// split pane combining top split pane and orders
bottomSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topSplitPane, editor);
bottomSplitPane.setOneTouchExpandable(true);
setLayout(new GridLayout(1, 0));
add(bottomSplitPane);
// adjust split panes
bottomSplitPane.setDividerLocation(Integer.parseInt(settings.getProperty("EMapDetailsPanel.bottomSplitPane",
"400")));
topSplitPane.setDividerLocation(Integer.parseInt(settings.getProperty("EMapDetailsPanel.topSplitPane",
"200")));
// save split pane changes
ComponentAdapter splitPaneListener = new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
settings.setProperty("EMapDetailsPanel.bottomSplitPane",
"" + bottomSplitPane.getDividerLocation());
settings.setProperty("EMapDetailsPanel.topSplitPane",
"" + topSplitPane.getDividerLocation());
}
};
treeScrollPane.addComponentListener(splitPaneListener);
nameDescPanel.addComponentListener(splitPaneListener);
editor.addComponentListener(splitPaneListener);
// register for shortcuts
DesktopEnvironment.registerShortcutListener(this);
// update this component if the orders of the currently displayed unit changed
dispatcher.addUnitOrdersListener(new UnitOrdersListener() {
public void unitOrdersChanged(UnitOrdersEvent e) {
if(e.getRelatedUnits().contains(EMapDetailsPanel.this.displayedObject)) {
EMapDetailsPanel.this.show(e.getUnit(), false);
}
}
});
excludeTags.add("magStyle");
excludeTags.add("regionicon");
}
/**
* TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
public NodeWrapperFactory getNodeWrapperFactory() {
return nodeWrapperFactory;
}
/*
* Function to translate a\nb (view representation to "a\\nb" (String representation)
* It also translates \r to \n
*/
protected String normalizeDescription(String s) {
if(s == null) {
return null;
}
StringBuffer ret = new StringBuffer(s.length());
for(StringTokenizer st = new StringTokenizer(s, "\n\r"); st.hasMoreTokens();) {
ret.append(st.nextToken());
if(st.hasMoreTokens()) {
ret.append("\\n");
}
}
return ret.toString();
}
private static final String DESCRIPTION_SEPARATOR = "\n---\n";
protected String getDescriptionPart(String s) {
if(s.indexOf(DESCRIPTION_SEPARATOR) == -1) {
return normalizeDescription(s);
}
return normalizeDescription(s.substring(0, s.indexOf(DESCRIPTION_SEPARATOR)));
}
protected String getPrivatePart(String s) {
if(s.indexOf(DESCRIPTION_SEPARATOR) == -1) {
return "";
}
return normalizeDescription(s.substring(s.indexOf(DESCRIPTION_SEPARATOR) +
DESCRIPTION_SEPARATOR.length()));
}
/**
* TODO: DOCUMENT ME!
*
* @param u TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
public static boolean isPrivilegedAndNoSpy(Unit u) {
return (u != null) && isPrivileged(u.getFaction()) && !u.isSpy();
}
/**
* TODO: DOCUMENT ME!
*
* @param f TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
public static boolean isPrivileged(Faction f) {
return (f != null) && (f.isPrivileged());
}
private void setNameAndDescription(DescribedObject d, boolean isEditable) {
if(d == null) {
return;
}
setNameAndDescription(this.data.getTranslation(d), d.getDescription(), isEditable);
}
private void setNameAndDescription(String n, String desc, boolean isEditable) {
//pavkovic 2003.10.07: dont notify this as undo action:
// disable undo
name.getDocument().removeUndoableEditListener(undoMgr);
description.getDocument().removeUndoableEditListener(undoMgr);
// change values
name.setText((n == null) ? "" : n);
name.setCaretPosition(0);
name.setEditable(isEditable);
description.setText((desc == null) ? "" : desc);
description.setCaretPosition(0);
description.setEditable(isEditable);
// enable undo
name.getDocument().addUndoableEditListener(undoMgr);
description.getDocument().addUndoableEditListener(undoMgr);
}
private void showRegion(Region r) {
// make editable for privileged units
setNameAndDescription(r, (r != null) && isPrivilegedAndNoSpy(r.getOwnerUnit()));
// build tree
appendRegionInfo(r, rootNode, myExpandableNodes);
// enable enable tag button (disable remove tag button?)
addTag.setEnabled(true);
removeTag.setEnabled(false);
}
/**
* Shows a tree: Terrain : region.type Coordinates : region.coordinates guarding units (Orc
* Infestination) (resources) (peasants) (luxuries) (schemes) (comments) (tags)
*
* @param r
* @param parent
* @param expandableNodes
*/
private void appendRegionInfo(Region r, DefaultMutableTreeNode parent,
Collection expandableNodes) {
// terrain type
parent.add(createSimpleNode(getString("node.terrain") + ": " + r.getType().getName(),
r.getType().getID() + "-detail"));
// terrain coordinates
parent.add(createSimpleNode(getString("node.coordinates") + ": " + r.getID(), "koordinaten"));
// region guards
appendRegionGuardInfo(r, parent, expandableNodes);
// orc infestation
if(r.orcInfested) {
parent.add(createSimpleNode(getString("node.orcinfestation"), "orkinfest"));
}
// resources
appendRegionResourceInfo(r, parent, expandableNodes);
// peasants
appendRegionPeasantInfo(r, parent, expandableNodes);
// luxuries
appendRegionLuxuriesInfo(r, parent, expandableNodes);
// schemes
appendRegionSchemes(r, parent, expandableNodes);
// comments
appendComments(r, parent, expandableNodes);
// tags
appendTags(r, parent, expandableNodes);
}
/**
* This function adds a node with subnodes to given parent - Luxuries: amount luxury item 1:
* price 1 ... luxury item n: price n
*
* @param r
* @param parent
* @param expandableNodes
*/
private void appendRegionLuxuriesInfo(Region r, DefaultMutableTreeNode parent,
Collection expandableNodes) {
if((r == null) || (r.prices == null) || r.prices.values().isEmpty()) {
return;
}
/*
DefaultMutableTreeNode luxuriesNode = new DefaultMutableTreeNode(getString("node.trade") +
": " +
getDiffString(r.maxLuxuries(),
r.maxOldLuxuries()));
*/
DefaultMutableTreeNode luxuriesNode = createSimpleNode(getString("node.trade") + ": " +
getDiffString(r.maxLuxuries(),r.maxOldLuxuries()), "handeln");
parent.add(luxuriesNode);
expandableNodes.add(new NodeWrapper(luxuriesNode, "EMapDetailsPanel.RegionLuxuriesExpanded"));
for(Iterator luxuries = r.prices.values().iterator(); luxuries.hasNext();) {
LuxuryPrice p = (LuxuryPrice) luxuries.next();
int oldPrice = -1;
if(r.oldPrices != null) {
LuxuryPrice old = (LuxuryPrice) r.oldPrices.get(p.getItemType().getID());
if(old != null) {
oldPrice = old.getPrice();
}
}
luxuriesNode.add(createSimpleNode(p.getItemType().getName() + ": " +
getDiffString(p.getPrice(), oldPrice),
"items/" + p.getItemType().getIconName()));
}
}
/**
* This function adds a node with subnodes to given parent - Peasants: amount / max amount
* recruit: recruit amount of recruit amount silver: silver surplus: surplus wage: entertain:
*
* @param r
* @param parent
* @param expandableNodes
*/
private void appendRegionPeasantInfo(Region r, DefaultMutableTreeNode parent,
Collection expandableNodes) {
if(r.peasants <= 0) {
return;
}
// peasants
int maxWorkers = r.getRegionType().getInhabitants() - (Math.max(r.trees, 0) * 8) -
(Math.max(r.sprouts, 0) * 4);
int workers = Math.min(maxWorkers, r.peasants);
int surplus = (workers * r.getPeasantWage()) - (r.peasants * 10);
int oldWorkers = Math.min(maxWorkers, r.oldPeasants);
int oldSurplus = -1;
if((oldWorkers != -1) && (r.oldWage != -1) && (r.oldPeasants != -1)) {
oldSurplus = (oldWorkers * (r.oldWage + 1)) - (r.oldPeasants * 10);
}
String peasantsInfo = getDiffString(r.peasants, r.oldPeasants, r.getModifiedPeasants())
.toString();
peasantsInfo += (" / " + maxWorkers);
DefaultMutableTreeNode peasantsNode = createSimpleNode(getString("node.peasants") + ": " +
peasantsInfo, "bauern");
parent.add(peasantsNode);
expandableNodes.add(new NodeWrapper(peasantsNode, "EMapDetailsPanel.RegionPeasantsExpanded"));
// recruit
peasantsNode.add(createSimpleNode(getString("node.recruit") + ": " +
getDiffString(r.maxRecruit(), r.maxRecruit(),
r.modifiedRecruit()) + " " +
getString("node.of") + r.maxRecruit(), "rekruten"));
// silver
peasantsNode.add(createSimpleNode(getString("node.silver") + ": " +
getDiffString(r.silver, r.oldSilver), "items/silber"));
// surplus
peasantsNode.add(createSimpleNode(getString("node.surplus") + ": " +
getDiffString(surplus, oldSurplus), "items/silber"));
// wage
int wage = r.getPeasantWage() - 1;
if((getWage(wage, false) != r.wage) && (getWage(wage, true) != r.wage)) {
// well, this can't be standard or orc wage, so let's
// display this special wage
wage = r.wage;
}
StringBuffer nodeText = new StringBuffer(getString("node.wage")).append(": ").append(getDiffString(getWage(wage,
false),
getWage(r.oldWage,
false)));
if(data.rules.getRace(EresseaConstants.R_ORKS) != null) {
nodeText.append(", ").append(data.rules.getRace(EresseaConstants.R_ORKS).getName())
.append(": ").append(getDiffString(getWage(wage, true), getWage(r.oldWage, true)));
}
peasantsNode.add(createSimpleNode(nodeText.toString(), "lohn"));
// entertain
peasantsNode.add(createSimpleNode(getString("node.enterainment") + ": " +
getDiffString(r.maxEntertain(), r.maxOldEntertain()),
"items/silber"));
}
/**
* Appends the resources of the region.
*
* @param r
* @param parent
* @param expandableNodes
*/
private void appendRegionResourceInfo(Region r, DefaultMutableTreeNode parent,
Collection expandableNodes) {
// DefaultMutableTreeNode resourceNode = new DefaultMutableTreeNode(getString("node.resources"));
DefaultMutableTreeNode resourceNode = createSimpleNode(getString("node.resources"), "ressourcen");
String icon = null;
if(!r.resources().isEmpty()) {
// resources of region
for(Iterator iter = r.resources().iterator(); iter.hasNext();) {
RegionResource res = (RegionResource) iter.next();
int oldValue = findOldValueByResourceType(r, res);
appendResource(res, resourceNode, oldValue);
}
} else {
// here we dont have resources, so make the "classic" way to create resource information
if((r.trees > 0) || (r.oldTrees > 0)) {
DefaultMutableTreeNode treeNode;
if(r.mallorn) {
icon = "items/" + mallornID;
if (getMagellanContext().getImageFactory().existImageIcon(icon + "_region")){
icon += "_region";
}
treeNode = createSimpleNode(getString("node.mallorntrees") + ": " +
getDiffString(r.trees, r.oldTrees),
icon);
} else {
icon = "items/" + treesID;
if (getMagellanContext().getImageFactory().existImageIcon(icon + "_region")){
icon += "_region";
}
treeNode = createSimpleNode(getString("node.trees") + ": " +
getDiffString(r.trees, r.oldTrees),
icon);
}
resourceNode.add(treeNode);
}
if((r.iron > 0) || (r.oldIron > 0)) {
icon = "items/eisen";
if (getMagellanContext().getImageFactory().existImageIcon(icon + "_region")){
icon += "_region";
}
resourceNode.add(createSimpleNode(data.rules.getItemType(StringID.create("Eisen"))
.getName() + ": " +
getDiffString(r.iron, r.oldIron), icon));
}
if((r.laen > 0) || (r.oldLaen > 0)) {
icon = "items/" + laenID;
if (getMagellanContext().getImageFactory().existImageIcon(icon + "_region")){
icon += "_region";
}
resourceNode.add(createSimpleNode(getString("node.laen") + ": " +
getDiffString(r.laen, r.oldLaen),
icon));
}
}
// horse
if((r.horses > 0) || (r.oldHorses > 0)) {
icon = "items/pferd";
if (getMagellanContext().getImageFactory().existImageIcon(icon + "_region")){
icon += "_region";
}
resourceNode.add(createSimpleNode(getString("node.horses") + ": " +
getDiffString(r.horses, r.oldHorses), icon));
}
// herb
if(r.herb != null) {
StringBuffer sb = new StringBuffer(getString("node.herbs")).append(": ").append(r.herb.getName());
if(r.herbAmount != null) {
sb.append(" (").append(r.herbAmount).append(")");
}
icon = null;
try {
icon = r.herb.getMakeSkill().getSkillType().getID().toString();
} catch(Exception exc) {
icon = "kraeuterkunde";
}
resourceNode.add(createSimpleNode(sb.toString(), icon));
}
if(resourceNode.getChildCount() > 0) {
parent.add(resourceNode);
expandableNodes.add(new NodeWrapper(resourceNode,
"EMapDetailsPanel.RegionResourcesExpanded"));
}
}
private int findOldValueByResourceType(Region r, RegionResource res) {
if((r == null) || (res == null)) {
return -1;
}
if(res.getType().getID().equals(ironID)) {
return r.oldIron;
}
if(res.getType().getID().equals(laenID)) {
return r.oldLaen;
}
if(res.getType().getID().equals(treesID) || res.getType().getID().equals(mallornID)) {
return r.oldTrees;
}
if(res.getType().getID().equals(sproutsID) || res.getType().getID().equals(mallornSproutsID)) {
return r.oldSprouts;
}
if(res.getType().getID().equals(stonesID)) {
return r.oldStones;
}
return -1;
}
private void appendMultipleRegionInfo(Collection r, DefaultMutableTreeNode parent,
Collection expandableNodes) {
// collect the data
// Sort regions for types. Key: RegionType; Value: LinkedList containing the region-objects
Map regions = CollectionFactory.createHashtable();
// Collect resources: key: ItemType; value: Integer
Map resources = CollectionFactory.createHashtable();
// Collect herbs: key: ItemType; value: LinkedList containing the region-objects
Map herbs = CollectionFactory.createHashtable();
// Count peasants, silver
int peasants = 0;
int silver = 0;
for(Iterator iter = r.iterator(); iter.hasNext();) {
Region region = (Region) iter.next();
if(region.peasants != -1) {
peasants += region.peasants;
}
if(region.silver != -1) {
silver += region.silver;
}
if(region.herb != null) {
List regionList = (List) herbs.get(region.herb);
if(regionList == null) {
regionList = CollectionFactory.createLinkedList();
herbs.put(region.herb, regionList);
}
regionList.add(region);
}
List list = (List) regions.get(region.getType());
if(list == null) {
list = CollectionFactory.createLinkedList();
regions.put(region.getType(), list);
}
list.add(region);
if(!region.resources().isEmpty()) {
for(Iterator iterator = region.resources().iterator(); iterator.hasNext();) {
RegionResource res = (RegionResource) iterator.next();
Integer amount = (Integer) resources.get(res.getType());
int i = res.getAmount();
if(amount != null) {
i += amount.intValue();
}
resources.put(res.getType(), new Integer(i));
}
}
if(region.horses > 0) {
ItemType iType = data.rules.getItemType(StringID.create("Pferd"));
Integer amount = (Integer) resources.get(iType);
int i = region.horses;
if(amount != null) {
i += amount.intValue();
}
resources.put(iType, new Integer(i));
}
}
// Now the data is prepared. Build the tree:
// peasants
parent.add(createSimpleNode(getString("node.peasants") + ": " + peasants, "bauern"));
// silver
parent.add(createSimpleNode(getString("node.silver") + ": " + silver, "items/silber"));
// terrains sorted by region type
DefaultMutableTreeNode terrainsNode = new DefaultMutableTreeNode(getString("node.terrains"));
parent.add(terrainsNode);
expandableNodes.add(new NodeWrapper(terrainsNode, "EMapDetailsPanel.RegionTerrainsExpanded"));
List sortedList = CollectionFactory.createLinkedList(regions.keySet());
Collections.sort(sortedList, new NameComparator(IDComparator.DEFAULT));
for(ListIterator iter = sortedList.listIterator(); iter.hasNext();) {
UnitContainerType rType = (UnitContainerType) iter.next();
List list = (List) regions.get(rType);
Collections.sort(list, new NameComparator(IDComparator.DEFAULT));
DefaultMutableTreeNode regionsNode = createSimpleNode(rType.getName() + ": " +
list.size(),
rType.getID().toString());
terrainsNode.add(regionsNode);
for(Iterator iter2 = list.iterator(); iter2.hasNext();) {
Region region = (Region) iter2.next();
int persons = 0;
for(Iterator iter3 = region.units().iterator(); iter3.hasNext();) {
persons += ((Unit) iter3.next()).getPersons();
}
regionsNode.add(new DefaultMutableTreeNode(nodeWrapperFactory.createRegionNodeWrapper(region,
persons)));
}
}
// resources of the regions sorted by name,id of resource
DefaultMutableTreeNode resourcesNode = new DefaultMutableTreeNode(getString("node.resources"));
sortedList = CollectionFactory.createLinkedList(resources.keySet());
Collections.sort(sortedList, new NameComparator(IDComparator.DEFAULT));
for(ListIterator iter = sortedList.listIterator(); iter.hasNext();) {
ItemType resType = (ItemType) iter.next();
int amount = ((Integer) resources.get(resType)).intValue();
if(amount > 0) {
resourcesNode.add(createSimpleNode(resType.getName() + ": " + amount,
"items/" + resType.getIconName()));
}
}
if(resourcesNode.getChildCount() > 0) {
parent.add(resourcesNode);
expandableNodes.add(new NodeWrapper(resourcesNode,
"EMapDetailsPanel.RegionResourcesExpanded"));
}
// herbs of the regions sorted by name, id of herb
DefaultMutableTreeNode herbsNode = new DefaultMutableTreeNode(getString("node.herbs"));
sortedList = CollectionFactory.createLinkedList(herbs.keySet());
Collections.sort(sortedList, new NameComparator(IDComparator.DEFAULT));
for(ListIterator iter = sortedList.listIterator(); iter.hasNext();) {
ItemType herbType = (ItemType) iter.next();
List regionList = (List) herbs.get(herbType);
int i = regionList.size();
DefaultMutableTreeNode regionsNode = new DefaultMutableTreeNode(herbType.getName() +
": " + i, true);
// m = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(herbType.getName() + ": " + i, herbType.getIconName()));
herbsNode.add(regionsNode);
Collections.sort(regionList, new NameComparator(IDComparator.DEFAULT));
for(ListIterator iter2 = regionList.listIterator(); iter2.hasNext();) {
Region myRegion = (Region) iter2.next();
regionsNode.add(new DefaultMutableTreeNode(nodeWrapperFactory.createRegionNodeWrapper(myRegion)));
}
}
if(herbsNode.getChildCount() > 0) {
parent.add(herbsNode);
expandableNodes.add(new NodeWrapper(herbsNode, "EMapDetailsPanel.HerbStatisticExpanded"));
}
}
/**
* Returns a simple node
*
* @param obj TODO: DOCUMENT ME!
* @param icons TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
private DefaultMutableTreeNode createSimpleNode(Object obj, String icons) {
return new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(obj, icons));
}
private DefaultMutableTreeNode createSimpleNode(NamedObject obj, String icons) {
return new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(obj,this.data.getTranslation(obj),(Object) icons));
}
/**
* Return a string showing the signed difference of the two int values in the form
* "<tt>current</tt> [<sign><number>]". If the two values are equal or if one of
* them is -1, an empty string is returned.
*
* @param current TODO: DOCUMENT ME!
* @param old TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
private StringBuffer getDiffString(int current, int old) {
return getDiffString(current, old, current);
}
/**
* Return a string showing the signed difference of the three int values in the form
* "<tt>current</tt> (future) [<sign><change>]". e.g. (1,2,1) returns 1 [-1] e.g.
* (1,2,2) returns 1 (2) [-1] e.g. (1,1,2) returns 1 (2) e.g. (1,1,1) returns 1 If future ==
* -1, then ignore
*
* @param current TODO: DOCUMENT ME!
* @param old TODO: DOCUMENT ME!
* @param future TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
private StringBuffer getDiffString(int current, int old, int future) {
StringBuffer ret = new StringBuffer(String.valueOf(current));
if(current == -1) {
return ret;
}
if((old != -1) && (current != old)) {
ret.append(" ");
ret.append(getDiffString(current - old, true));
}
// future value is treated differently, also negative numbers may exist
if(current != future) {
ret.append(" ");
ret.append(getDiffString(future, false));
}
return ret;
}
private StringBuffer getDiffString(int value, boolean printSign) {
StringBuffer ret = new StringBuffer(4);
if(printSign) {
ret.append("[");
if(value > 0) {
ret.append("+");
}
ret.append(value);
ret.append("]");
} else {
ret.append("(");
ret.append(value);
ret.append(")");
}
return ret;
}
/**
* Appends a folder with the (region) resources to the specified parent node.
*
* @param r
* @param parent
* @param expandableNodes
*/
private void appendRegionGuardInfo(Region r, DefaultMutableTreeNode parent,
Collection expandableNodes) {
Set parties = CollectionFactory.createHashSet();
Set units = CollectionFactory.createHashSet();
for(Iterator iter = r.units().iterator(); iter.hasNext();) {
Unit unit = (Unit) iter.next();
if(unit.guard != 0) {
parties.add(unit.getFaction());
units.add(unit);
}
}
if(parties.size() > 0) {
// DefaultMutableTreeNode guardRoot = new DefaultMutableTreeNode(getString("node.guarded") + ": ");
// Fiete 20060911: added support for "bewacht" - icon
DefaultMutableTreeNode guardRoot = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.guarded") +
": ",
"bewacht"));
parent.add(guardRoot);
expandableNodes.add(new NodeWrapper(guardRoot, "EMapDetailsPanel.RegionGuardExpanded"));
for(Iterator iter = parties.iterator(); iter.hasNext();) {
Faction faction = (Faction) iter.next();
int iGuardFlags = 0;
StringBuffer strFaction = new StringBuffer();
DefaultMutableTreeNode guardParty = new DefaultMutableTreeNode(strFaction);
guardRoot.add(guardParty);
Iterator iterUnits = units.iterator();
while(iterUnits.hasNext()) {
Unit unit = (Unit) iterUnits.next();
if(unit.getFaction().equals(faction)) {
DefaultMutableTreeNode guardUnit = new DefaultMutableTreeNode(nodeWrapperFactory.createUnitNodeWrapper(unit));
guardParty.add(guardUnit);
iGuardFlags |= unit.guard;
}
}
strFaction.append(faction.toString() + ", ");
strFaction.append(Unit.guardFlagsToString(iGuardFlags));
}
}
}
/**
* Appends a folder with the (region) resources to the specified parent node.
*
* @param res
* @param parent
* @param oldValue
*/
private void appendResource(RegionResource res, DefaultMutableTreeNode parent, int oldValue) {
StringBuffer sb = new StringBuffer();
sb.append(res.getType().getName());
if((res.getAmount() != -1) || (res.getSkillLevel() != -1)) {
sb.append(": ");
if(res.getAmount() != -1) {
sb.append(getDiffString(res.getAmount(), oldValue));
if(res.getSkillLevel() != -1) {
sb.append(" / ");
}
}
if(res.getSkillLevel() != -1) {
sb.append("T").append(res.getSkillLevel());
}
}
String icon = res.getType().getIconName();
if(icon.equalsIgnoreCase("Steine")) {
icon = "stein";
}
if (getMagellanContext().getImageFactory().existImageIcon("items/" + icon + "_region")){
icon = icon + "_region";
}
parent.add(createSimpleNode(sb.toString(), "items/" + icon));
}
/**
* Appends a folder with the schemes in the specified region to the specified parent node.
*
* @param region
* @param parent
* @param expandableNodes
*/
private void appendRegionSchemes(Region region, DefaultMutableTreeNode parent,
Collection expandableNodes) {
if(region.schemes().isEmpty()) {
return;
}
DefaultMutableTreeNode schemeNode = new DefaultMutableTreeNode(getString("node.schemes"));
parent.add(schemeNode);
expandableNodes.add(new NodeWrapper(schemeNode, "EMapDetailsPanel.RegionSchemesExpanded"));
for(Iterator iter = region.schemes().iterator(); iter.hasNext();) {
Scheme s = (Scheme) iter.next();
schemeNode.add(new DefaultMutableTreeNode(s));
}
}
// NOTE: Don't know if to add the exclusion code for
// well-known external tags (magStyle, regionicon)
/**
* Appends a folder with the external tags of a unit container to the given node.
*
* @param uc
* @param parent
* @param expandableNodes
*/
private void appendTags(UnitContainer uc, DefaultMutableTreeNode parent,
Collection expandableNodes) {
appendTags(uc, parent, expandableNodes, uc.getType().getID().toString() + "TagsExpanded");
}
/**
* Appends a folder with the external tags of a unit to the given node.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendTags(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
appendTags(u, parent, expandableNodes, "UnitTagsExpanded");
}
/**
* Appends the tags of a taggable.
*
* @param taggable
* @param parent
* @param expandableNodes
* @param nodeInfo An identifier for the expandable node
*/
private void appendTags(Taggable taggable, DefaultMutableTreeNode parent, Collection expandableNodes,
String nodeInfo) {
if(!taggable.hasTags()) {
return;
}
DefaultMutableTreeNode tags = new DefaultMutableTreeNode(getString("node.tags"));
for(Iterator iter = taggable.getTagMap().keySet().iterator(); iter.hasNext();) {
String tempName = (String) iter.next();
String value = taggable.getTag(tempName);
tags.add(new DefaultMutableTreeNode(tempName + ": " + value));
}
parent.add(tags);
expandableNodes.add(new NodeWrapper(tags, "EMapDetailsPanel." + nodeInfo));
}
private void showFaction(Faction f) {
setNameAndDescription(f, isPrivileged(f));
appendFactionsInfo(Collections.singleton(f), rootNode, myExpandableNodes);
}
/**
* Append information for several selected factions.
*
* @param factions
* @param parent
* @param expandableNodes
*/
private void appendFactionsInfo(Collection factions, DefaultMutableTreeNode parent,
Collection expandableNodes) {
// if only one faction selected...show faction info
if (factions !=null && factions.size()==1){
Object[] oO = factions.toArray();
Object o = oO[0];
if (o instanceof Faction) {
Faction f = (Faction) o;
appendFactionInfo(f, parent, expandableNodes);
}
}
if(lastRegion != null) {
Collection units = CollectionFactory.createLinkedList();
for(Iterator iter = lastRegion.units().iterator(); iter.hasNext();) {
Unit u = (Unit) iter.next();
if((u.getFaction() != null) && factions.contains(u.getFaction())) {
units.add(u);
}
}
appendUnitsInfo(units, parent, expandableNodes);
}
// comments
for(Iterator iter = factions.iterator(); iter.hasNext();) {
appendComments((Faction) iter.next(), parent, expandableNodes);
}
}
/**
* Append summary information for several selected units.
*
* @param units
* @param parent
* @param expandableNodes
*/
private void appendUnitsInfo(Collection units, DefaultMutableTreeNode parent,
Collection expandableNodes) {
Map skills = CollectionFactory.createHashtable();
// key: racename (string), Value: Integer-Object containing number of persons of that race
// Fiete: Value: raceInfo with realRace ( nor Prefix, and the amount of Persons
Map races = CollectionFactory.createHashtable();
// Fiete: calculate weight and modified weight within this loop
float uWeight = 0;
float modUWeight = 0;
for(Iterator iter = units.iterator(); iter.hasNext();) {
Unit u = (Unit) iter.next();
// weight (Fiete)
Float actUWeight = new Float(u.getWeight() / 100.0F);
uWeight += actUWeight.floatValue();
Float actModUWeight= new Float(u.getModifiedWeight() / 100.0F);
modUWeight += actModUWeight.floatValue();
RaceInfo rInfo = (RaceInfo) races.get(u.getRaceName(data));
if (rInfo == null){
rInfo = new RaceInfo();
// rInfo.raceNoPrefix = com.eressea.util.Umlaut.convertUmlauts(u.getRealRaceName());
// umlaut check is done late when loading the image
rInfo.raceNoPrefix = u.getRealRaceName();
}
rInfo.amount +=u.getPersons();
rInfo.amount_modified += u.getModifiedPersons();
races.put(u.getRaceName(data), rInfo);
for(Iterator i = u.getSkills().iterator(); i.hasNext();) {
Skill skill = (Skill) i.next();
SkillStatItem stored = (SkillStatItem) skills.get(skill.getName() +
skill.getLevel());
if(stored != null) {
stored.unitCounter += u.getPersons();
stored.units.add(u);
} else {
stored = new SkillStatItem(skill, u.getPersons());
stored.units.add(u);
skills.put(skill.getName() + skill.getLevel(), stored);
}
}
}
for(Iterator iter = races.keySet().iterator(); iter.hasNext();) {
String race = (String) iter.next();
RaceInfo rI = (RaceInfo) races.get(race);
int i = rI.amount;
int i_modified = rI.amount_modified;
String personIconName = "person";
/**
String gifNameEN = getString(rI.raceNoPrefix);
if (!gifNameEN.equalsIgnoreCase(rI.raceNoPrefix)){
personIconName = gifNameEN;
}
*/
// we check if specific icon for race exists, if so, we use it
// Fiete 20061218
if (getMagellanContext().getImageFactory().existImageIcon(rI.raceNoPrefix)){
personIconName = rI.raceNoPrefix;
}
if (i_modified==i){
parent.add(createSimpleNode(i + " " + race, personIconName));
} else {
parent.add(createSimpleNode(i + " (" + i_modified + ") " + race, personIconName));
}
}
// weight (Fiete)
String text = getString("node.totalweight") + ": " + weightNumberFormat.format(uWeight);
if(uWeight != modUWeight) {
text += (" (" + weightNumberFormat.format(modUWeight) + ")");
}
text += (" " + getString("node.weightunits"));
parent.add(createSimpleNode(text, "gewicht"));
// categorized items
Collection catNodes = unitsTools.addCategorizedUnitItems(units, parent, null, null,
true, nodeWrapperFactory);
if(catNodes != null) {
for(Iterator catIter = catNodes.iterator(); catIter.hasNext();) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) catIter.next();
Object o = node.getUserObject();
ItemCategory cat = null;
if(o instanceof ItemCategoryNodeWrapper) {
cat = ((ItemCategoryNodeWrapper) o).getItemCategory();
} else {
cat = (ItemCategory) o;
}
expandableNodes.add(new NodeWrapper(node,
"EMapDetailsPanel." +
cat.getID().toString() + "Expanded"));
}
}
if(skills.size() > 0) {
// DefaultMutableTreeNode skillsNode = new DefaultMutableTreeNode(getString("node.skills"));
DefaultMutableTreeNode skillsNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.skills"),
"skills"));
parent.add(skillsNode);
expandableNodes.add(new NodeWrapper(skillsNode, "EMapDetailsPanel.FactionSkillsExpanded"));
List sortedSkills = CollectionFactory.createLinkedList(skills.values());
Collections.sort(sortedSkills, new SkillStatItemComparator());
for(Iterator iter = sortedSkills.iterator(); iter.hasNext();) {
SkillStatItem item = (SkillStatItem) iter.next();
DefaultMutableTreeNode skillNode = createSimpleNode(item.skill.getName() + " " +
item.skill.getLevel() + ": " +
item.unitCounter,
item.skill.getSkillType().getID()
.toString());
skillsNode.add(skillNode);
Comparator idCmp = IDComparator.DEFAULT;
Comparator unitCmp = new UnitSkillComparator(new SpecifiedSkillTypeSkillComparator(item.skill.getSkillType(),
new SkillComparator(),
null),
idCmp);
Collections.sort(item.units, unitCmp);
for(Iterator uIter = item.units.iterator(); uIter.hasNext();) {
Unit u = (Unit) uIter.next();
StringBuffer sb = new StringBuffer();
sb.append(u.toString());
sb.append(": " + u.getPersons());
if(u.getPersons() != u.getModifiedPersons()) {
sb.append(" (").append(u.getModifiedPersons()).append(")");
}
skillNode.add(new DefaultMutableTreeNode(nodeWrapperFactory.createUnitNodeWrapper(u,
sb.toString())));
}
}
}
}
private void showGroup(Group g) {
setNameAndDescription(g.getName(), "", false);
appendGroupInfo(g, rootNode, myExpandableNodes);
}
/**
* Append information about the specified group.
*
* @param g
* @param parent
* @param expandableNodes
*/
private void appendGroupInfo(Group g, DefaultMutableTreeNode parent, Collection expandableNodes) {
if(lastRegion != null) {
int personCount = 0;
Map skills = CollectionFactory.createHashtable();
Iterator units = lastRegion.units().iterator();
Collection regionUnits = CollectionFactory.createLinkedList();
while(units.hasNext() == true) {
Unit u = (Unit) units.next();
if((u.getGroup() != null) && u.getGroup().equals(g)) {
personCount += u.getPersons();
regionUnits.add(u);
for(Iterator i = u.getSkills().iterator(); i.hasNext();) {
Skill skill = (Skill) i.next();
SkillStatItem stored = (SkillStatItem) skills.get(skill.getName() +
skill.getLevel());
if(stored != null) {
stored.unitCounter += u.getPersons();
stored.units.add(u);
} else {
stored = new SkillStatItem(skill, u.getPersons());
stored.units.add(u);
skills.put(skill.getName() + skill.getLevel(), stored);
}
}
}
}
DefaultMutableTreeNode n = new DefaultMutableTreeNode(personCount + " " +
getString("node.persons"));
parent.add(n);
if((g.allies() != null) && (g.allies().values().size() > 0)) {
n = new DefaultMutableTreeNode(getString("node.alliances"));
parent.add(n);
expandableNodes.add(new NodeWrapper(n, "EMapDetailsPanel.AlliancesExpanded"));
List sortedAllies = CollectionFactory.createLinkedList(g.allies().values());
Collections.sort(sortedAllies,
new AllianceFactionComparator(new NameComparator(IDComparator.DEFAULT)));
for(Iterator iter = sortedAllies.iterator(); iter.hasNext();) {
DefaultMutableTreeNode m = new DefaultMutableTreeNode(iter.next());
n.add(m);
}
}
// categorized items
Collection catNodes = unitsTools.addCategorizedUnitItems(regionUnits, parent, null,
null, true,
nodeWrapperFactory);
if(catNodes != null) {
for(Iterator catIter = catNodes.iterator(); catIter.hasNext();) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) catIter.next();
if(log.isDebugEnabled()) {
log.debug("EmapDetailPanel.appendGroupInfo: found class " +
node.getUserObject().getClass() + " (expected ItemCategory)");
}
Object o = node.getUserObject();
ItemCategory cat = null;
if(o instanceof ItemCategoryNodeWrapper) {
cat = ((ItemCategoryNodeWrapper) o).getItemCategory();
} else {
cat = (ItemCategory) o;
}
expandableNodes.add(new NodeWrapper(node,
"EMapDetailsPanel." +
cat.getID().toString() + "Expanded"));
}
}
if(skills.size() > 0) {
// n = new DefaultMutableTreeNode(getString("node.skills"));
n = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.skills"),
"skills"));
parent.add(n);
expandableNodes.add(new NodeWrapper(n, "EMapDetailsPanel.RegionSkillsExpanded"));
List sortedSkills = CollectionFactory.createLinkedList(skills.values());
Collections.sort(sortedSkills, new SkillStatItemComparator());
for(Iterator iter = sortedSkills.iterator(); iter.hasNext();) {
SkillStatItem item = (SkillStatItem) iter.next();
int bonus = 0;
Faction f = null;
if(((f = g.getFaction()) != null) && (f.getType() != null)) {
bonus = f.getRace().getSkillBonus(item.skill.getSkillType());
if(lastRegion != null) {
bonus += f.getRace().getSkillBonus(item.skill.getSkillType(),
lastRegion.getRegionType());
}
}
DefaultMutableTreeNode m = new DefaultMutableTreeNode(new SimpleNodeWrapper(item.skill.getName() +
" " +
item.skill.getLevel() +
": " +
item.unitCounter,
item.skill.getSkillType()
.getID()
.toString()));
n.add(m);
Comparator idCmp = IDComparator.DEFAULT;
Comparator unitCmp = new UnitSkillComparator(new BestSkillComparator(new SkillComparator(),
new SkillTypeComparator(new SkillTypeRankComparator(new NameComparator(idCmp),
settings),
new SkillComparator()),
null),
idCmp);
Collections.sort(item.units, unitCmp);
for(Iterator uIter = item.units.iterator(); uIter.hasNext();) {
Unit u = (Unit) uIter.next();
StringBuffer sb = new StringBuffer();
sb.append(u.toString());
Skill skill = u.getSkill(item.skill.getSkillType());
if(skill != null) {
sb.append(": [").append(skill.getPointsPerPerson()).append(" -> ")
.append(Skill.getPointsAtLevel((item.skill.getLevel() - bonus) + 1))
.append("]");
}
sb.append(", ").append(u.getPersons());
if(u.getPersons() != u.getModifiedPersons()) {
sb.append(" (").append(u.getModifiedPersons()).append(")");
}
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(u,
sb.toString());
m.add(new DefaultMutableTreeNode(w));
}
}
}
}
}
private void showUnit(Unit u) {
// update description text area
String strDesc = "";
if(u.getDescription() != null) {
strDesc += u.getDescription();
}
if(u.privDesc != null) {
strDesc += (DESCRIPTION_SEPARATOR + u.privDesc);
}
setNameAndDescription(u.getName(), strDesc, isPrivilegedAndNoSpy(u));
appendUnitInfo(u, rootNode, myExpandableNodes);
addTag.setEnabled(true);
removeTag.setEnabled(false);
}
/**
* Appends information for the specified unit
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
/* make sure that all unit relations have been established */
if(u.getRegion() != null) {
u.getRegion().refreshUnitRelations();
}
// Heldenanzeige
if(u.isHero) {
parent.add(createSimpleNode(getString("node.hero"), "hero"));
}
// Personenanzeige
appendUnitPersonInfo(u, parent, expandableNodes);
// Partei
appendUnitFactionInfo(u, parent, expandableNodes);
// Race
appendUnitRaceInfo(u, parent, expandableNodes);
// Group
appendUnitGroupInfo(u, parent, expandableNodes);
// Kampfreihenanzeige
SimpleNodeWrapper cWrapper = nodeWrapperFactory
.createSimpleNodeWrapper(getString("node.combatstatus") + ": "
+ Unit.combatStatusToString(u), "kampfstatus");
if(isPrivileged(u.getFaction())) {
cWrapper.setContextFactory(combatContext);
cWrapper.setArgument(u);
}
parent.add(new DefaultMutableTreeNode(cWrapper));
// starvation
if(u.isStarving) {
parent.add(createSimpleNode(getString("node.starved"), "hunger"));
}
// health state
if(u.health != null) {
// Fiete 20060910
// the hp-string is not translated in the cr
// so u.health = german
parent.add(createSimpleNode(getString("node.health") + ": " + data.getTranslation(u.health), u.health));
}
// guard state
if(u.guard != 0) {
parent.add(createSimpleNode(getString("node.guards") + ": " +
Unit.guardFlagsToString(u.guard), "bewacht"));
}
// stealth info
appendUnitStealthInfo(u, parent, expandableNodes);
// spy
if(u.isSpy()) {
parent.add(createSimpleNode(getString("node.spy"), "spion"));
}
// Gebaeude-/Schiffsanzeige
appendContainerInfo(u, parent, expandableNodes);
// magic aura
if(u.aura != -1) {
parent.add(createSimpleNode(getString("node.aura") + ": " + u.aura + " / " + u.auraMax,
"aura"));
}
// familiar
appendFamiliarInfo(u, parent, expandableNodes);
// weight
appendUnitWeight(u, parent, expandableNodes);
// Fiete 20060915: feature wish..calculate max Horses for walking and riding
appendUnitHorses(u, parent, expandableNodes);
// load
appendUnitLoadInfo(u, parent, expandableNodes);
// items
appendUnitItemInfo(u, parent, expandableNodes);
// skills
boolean isTrader = appendUnitSkillInfo(u, parent, expandableNodes);
// teaching
appendUnitTeachInfo(u, parent, expandableNodes);
// transportation
appendUnitTransportationInfo(u, parent, expandableNodes);
// attacking
appendUnitAttackInfo(u, parent, expandableNodes);
// magic spells
appendUnitSpellsInfo(u, parent, expandableNodes);
// Kampfzauber-Anzeige
appendUnitCombatSpells(u.combatSpells, parent, expandableNodes);
// Trank Anzeige
appendUnitPotionInfo(u, parent, expandableNodes);
// luxuries
if(isTrader) {
appendRegionLuxuriesInfo(u.getRegion(), parent, expandableNodes);
}
// region resources if maker
appendUnitRegionResource(u, parent, expandableNodes);
// comments
appendComments(u, parent, expandableNodes);
// tags
appendTags(u, parent, expandableNodes);
}
/**
* Appends information on number of persons (and their race).
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitPersonInfo(Unit u, DefaultMutableTreeNode parent,
Collection expandableNodes) {
// display custom Unit Icon ?
String customUnitIconFileName = "custom/units/" + u.toString(false);
if (this.isAllowingCustomIcons() && getMagellanContext().getImageFactory().existImageIcon(customUnitIconFileName)){
DefaultMutableTreeNode customUnitIconNode = null;
if (getMagellanContext().getImageFactory().imageIconSizeCheck(customUnitIconFileName,40,40)){
customUnitIconNode = createSimpleNode(u.getModifiedName(), customUnitIconFileName);
} else {
customUnitIconNode = createSimpleNode(u.getModifiedName(), "tobig");
}
parent.add(customUnitIconNode);
}
String strPersons = getString("node.persons") + ": " + u.getPersons();
if(u.getPersons() != u.getModifiedPersons()) {
strPersons += (" (" + u.getModifiedPersons() + ")");
}
String iconPersonName = "person";
/**
* Fiete 20061218...was just a first try....not that good, needs
* allways some support..
String iconNameEN = getString(com.eressea.util.Umlaut.convertUmlauts(u.getRealRaceName()));
if (!iconNameEN.equalsIgnoreCase(com.eressea.util.Umlaut.convertUmlauts(u.getRealRaceName()))) {
iconPersonName = iconNameEN;
}
*/
// now we check if a specific race icon exists, if true, we use it
if (getMagellanContext().getImageFactory().existImageIcon(u.getRealRaceName())){
iconPersonName = u.getRealRaceName();
}
DefaultMutableTreeNode personNode = createSimpleNode(strPersons, iconPersonName);
parent.add(personNode);
expandableNodes.add(new NodeWrapper(personNode, "EMapDetailsPanel.PersonsExpanded"));
for(Iterator iter = u.getPersonTransferRelations().iterator(); iter.hasNext();) {
PersonTransferRelation itr = (PersonTransferRelation) iter.next();
String prefix = String.valueOf(itr.amount) + " ";
String addIcon = null;
Unit u2 = null;
if(itr.source == u) {
addIcon = "get";
u2 = itr.target;
} else if(itr.target == u) {
addIcon = "give";
u2 = itr.source;
}
UnitNodeWrapper unw = nodeWrapperFactory.createUnitNodeWrapper(u2, prefix,
u2.getPersons(),
u2.getModifiedPersons());
unw.setAdditionalIcon(addIcon);
unw.setReverseOrder(true);
personNode.add(new DefaultMutableTreeNode(unw));
}
for (Iterator it = u.getRelations(UnitTransferRelation.class).iterator(); it.hasNext(); ){
UnitTransferRelation relation = (UnitTransferRelation) it.next();
String addIcon = null;
Unit u2 = null;
if(relation.source == u) {
addIcon = "get";
u2 = relation.target;
} else if(relation.target == u) {
addIcon = "give";
u2 = relation.source;
}
UnitNodeWrapper unw = nodeWrapperFactory.createUnitNodeWrapper(u2);
unw.setAdditionalIcon(addIcon);
unw.setReverseOrder(true);
personNode.add(new DefaultMutableTreeNode(unw));
}
}
/**
* Appends information about this unit's faction.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitFactionInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
appendFactionInfo(u.getFaction(), parent, expandableNodes);
}
/**
* Appends information about this faction.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendFactionInfo(Faction f, DefaultMutableTreeNode parent, Collection expandableNodes) {
DefaultMutableTreeNode fNode;
if(f == null) {
fNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.faction") +
": " +
getString("node.unknownfaction"),
"faction"));
} else {
// custom faction icon ?
String customFactionIconFileName = "custom/factions/" + f.getID();
if (this.isAllowingCustomIcons() && getMagellanContext().getImageFactory().existImageIcon(customFactionIconFileName)){
if (getMagellanContext().getImageFactory().imageIconSizeCheck(customFactionIconFileName,40,40)){
fNode = createSimpleNode(f.toString(), customFactionIconFileName);
} else {
fNode = createSimpleNode(f.toString(), "tobig");
}
} else {
fNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.faction") +
": " +
f.toString(),
"faction"));
}
}
parent.add(fNode);
}
/**
* Appends information on the unit's race.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitRaceInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
if(u.race != null) {
StringBuffer nodeText = new StringBuffer(getString("node.race")).append(": ").append(u.getRaceName(this.data));
if(u.realRace != null) {
nodeText.append(" (").append(u.realRace.getName()).append(")");
}
parent.add(createSimpleNode(nodeText.toString(), "rasse"));
}
}
/**
* Appends information on the unit's group.
*
* @param u
*/
private void appendUnitGroupInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
if(u.getGroup() != null) {
Group group = u.getGroup();
DefaultMutableTreeNode groupNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.group") +
": \"" + group.getName() +
"\"","groups"));
parent.add(groupNode);
expandableNodes.add(new NodeWrapper(groupNode, "EMapDetailsPanel.UnitGroupExpanded"));
appendAlliances(group.allies(), groupNode);
}
}
/**
* Append Information on the stealth level etc. for this unit.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitStealthInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
// faction hidden, stealth level
Skill stealth = u.getSkill(data.rules.getSkillType(EresseaConstants.S_TARNUNG, true));
int stealthLevel = 0;
if(stealth != null) {
stealthLevel = stealth.getLevel();
}
if(u.hideFaction || stealthLevel > 0) {
String strHide = getString("node.stealth") + ":";
if(stealthLevel > 0) {
if(u.stealth == -1) {
strHide += (" " + stealthLevel);
} else {
strHide += (" " + u.stealth + " / " + stealthLevel);
}
}
if(u.hideFaction) {
if(stealthLevel > 0) {
strHide += ",";
}
strHide += (" " + getString("node.disguised"));
}
String icon = null;
try {
icon = stealth.getSkillType().getID().toString();
} catch(Exception exc) {
icon = "tarnung";
}
SimpleNodeWrapper wrapper = nodeWrapperFactory.createSimpleNodeWrapper(strHide, icon);
if((stealthLevel > 0) && isPrivileged(u.getFaction())) {
wrapper.setContextFactory(stealthContext);
wrapper.setArgument(u);
}
parent.add(new DefaultMutableTreeNode(wrapper));
}
// disguise
if(u.getGuiseFaction() != null) {
parent.add(createSimpleNode(getString("node.disguisedas") + u.getGuiseFaction(),
((stealth != null)
? stealth.getSkillType().getID().toString() : "tarnung")));
}
}
private void appendFamiliarInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
// familiar mages (Fiete)
// we use auraMax to determine a mage...should be OK
if (u.auraMax != -1) {
if (u.familiarmageID != null) {
// ok..this unit is a familiar (Vertrauter)
// get the parent unit
Unit parentUnit = this.data.getUnit(u.familiarmageID);
if (parentUnit != null) {
// DefaultMutableTreeNode parentsNode = new DefaultMutableTreeNode("Parents");
DefaultMutableTreeNode parentsNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.FamiliarParents"),
"aura"));
parent.add(parentsNode);
expandableNodes.add(new NodeWrapper(parentsNode, "EMapDetailsPanel.FamiliarParentsExpanded"));
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(parentUnit);
DefaultMutableTreeNode parentUnitNode = new DefaultMutableTreeNode(w);
parentsNode.add(parentUnitNode);
}
} else {
// ok..we have a real mage..may be he has an familiar...
// for further purpose lets look for all familiars...
Collection familiars = CollectionFactory.createLinkedList();
for (Iterator iter = this.data.units().keySet().iterator();iter.hasNext();){
UnitID uID = (UnitID) iter.next();
Unit uTest = this.data.getUnit(uID);
if (uTest.familiarmageID == u.getID()) {
familiars.add(uTest);
}
}
if (familiars.size()>0){
DefaultMutableTreeNode childsNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.FamiliarChilds"),
"aura"));
parent.add(childsNode);
expandableNodes.add(new NodeWrapper(childsNode, "EMapDetailsPanel.FamiliarChildsExpanded"));
for (Iterator iter=familiars.iterator();iter.hasNext();){
Unit uT = (Unit) iter.next();
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(uT);
DefaultMutableTreeNode parentUnitNode = new DefaultMutableTreeNode(w);
childsNode.add(parentUnitNode);
}
}
}
}
}
/**
* Append information on the unit's weight.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitWeight(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
Float uWeight = new Float(u.getWeight() / 100.0F);
Float modUWeight = new Float(u.getModifiedWeight() / 100.0F);
String text = getString("node.totalweight") + ": " + weightNumberFormat.format(uWeight);
if(!uWeight.equals(modUWeight)) {
text += (" (" + weightNumberFormat.format(modUWeight) + ")");
}
text += (" " + getString("node.weightunits"));
parent.add(createSimpleNode(text, "gewicht"));
}
/**
* Append information on the possible horses.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitHorses(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
int skillLevel = 0;
Skill s = u.getModifiedSkill(new SkillType(StringID.create("Reiten")));
if(s != null) {
skillLevel = s.getLevel();
}
int maxHorsesWalking = ((skillLevel * u.getModifiedPersons() * 4) + u.getModifiedPersons());
int maxHorsesRiding = (skillLevel * u.getModifiedPersons() * 2);
String text = "Max: " + maxHorsesWalking + " / " + maxHorsesRiding;
parent.add(createSimpleNode(text, "pferd"));
}
/**
* Append information on this unit's payload and capacity.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitLoadInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
// load
int load = u.getLoad();
int modLoad = u.getModifiedLoad();
if((load != 0) || (modLoad != 0)) {
String text = getString("node.load") + ": " +
weightNumberFormat.format(new Float(load / 100.0F));
if(load != modLoad) {
text += (" (" + weightNumberFormat.format(new Float(modLoad / 100.0F)) + ")");
}
text += (" " + getString("node.weightunits"));
parent.add(createSimpleNode(text, "beladung"));
}
// payload
int maxOnFoot = u.getPayloadOnFoot();
if(maxOnFoot == Unit.CAP_UNSKILLED) {
parent.add(createSimpleNode(getString("node.capacityonfoot") + ": " +
getString("node.toomanyhorses"), "warnung"));
} else {
Float max = new Float(maxOnFoot / 100.0F);
Float free = new Float(Math.abs(maxOnFoot - modLoad) / 100.0F);
DefaultMutableTreeNode capacityNode;
if((maxOnFoot - modLoad) < 0) {
capacityNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.capacityonfoot") +
": " +
getString("node.overloadedby") +
weightNumberFormat.format(free) +
" " +
getString("node.weightunits"),
"warnung"));
} else {
capacityNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.capacityonfoot") +
": " +
weightNumberFormat.format(free) +
" / " +
weightNumberFormat.format(max) +
" " +
getString("node.weightunits"),
"ladfuss"));
appendUnitCapacityByItems(capacityNode, u, maxOnFoot - modLoad);
if(capacityNode.getChildCount() > 0) {
expandableNodes.add(new NodeWrapper(capacityNode,
"EMapDetailsPanel.UnitCapacityOnFootExpanded"));
}
}
parent.add(capacityNode);
}
int maxOnHorse = u.getPayloadOnHorse();
if(maxOnHorse == Unit.CAP_UNSKILLED) {
parent.add(createSimpleNode(getString("node.capacityonhorse") + ": " +
getString("node.toomanyhorses"), "warnung"));
} else if(maxOnHorse == Unit.CAP_NO_HORSES) {
} else {
Float max = new Float(maxOnHorse / 100.0F);
Float free = new Float(Math.abs(maxOnHorse - modLoad) / 100.0F);
DefaultMutableTreeNode capacityNode;
if((maxOnHorse - modLoad) < 0) {
capacityNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.capacityonhorse") +
": " +
getString("node.overloadedby") +
weightNumberFormat.format(free) +
" " +
getString("node.weightunits"),
"warnung"));
} else {
capacityNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.capacityonhorse") +
": " +
weightNumberFormat.format(free) +
" / " +
weightNumberFormat.format(max) +
" " +
getString("node.weightunits"),
"ladpferd"));
appendUnitCapacityByItems(capacityNode, u, maxOnHorse - modLoad);
if(capacityNode.getChildCount() > 0) {
expandableNodes.add(new NodeWrapper(capacityNode,
"EMapDetailsPanel.UnitCapacityOnHorseExpanded"));
}
}
parent.add(capacityNode);
}
}
private void appendUnitItemInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
// items
if(u.getModifiedItems().size() > 0) {
// DefaultMutableTreeNode itemsNode = new DefaultMutableTreeNode(getString("node.items"));
DefaultMutableTreeNode itemsNode = createSimpleNode(getString("node.items"), "things");
parent.add(itemsNode);
expandableNodes.add(new NodeWrapper(itemsNode, "EMapDetailsPanel.UnitItemsExpanded"));
Collection catNodes = unitsTools.addCategorizedUnitItems(Collections.singleton(u), itemsNode, null, null, false, nodeWrapperFactory);
if(catNodes != null) {
for(Iterator catIter = catNodes.iterator(); catIter.hasNext();) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) catIter.next();
Object o = node.getUserObject();
ID id = null;
if(o instanceof ItemCategoryNodeWrapper) {
id = (((ItemCategoryNodeWrapper) o).getItemCategory()).getID();
} else {
if(o instanceof ItemCategory) {
id = ((ItemCategory) o).getID();
} else {
if(o instanceof ItemNodeWrapper) {
id = ((ItemNodeWrapper) o).getItem().getItemType().getID();
}
}
}
if(id != null) {
expandableNodes.add(new NodeWrapper(node,
"EMapDetailsPanel.UnitItems"+id+"Expanded"));
}
}
}
}
}
/**
* Append information on the skills of this unit.
*
* @return <code>true</code> iff <code>u</code> is a trader
*/
private boolean appendUnitSkillInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
// skills
boolean isTrader = false;
SkillCategory tradeCat = data.rules.getSkillCategory(StringID.create("trade"));
SkillType tradeSkill = null;
if(tradeCat == null) {
tradeSkill = data.rules.getSkillType(StringID.create("Handeln"));
}
Collection modSkills = u.getModifiedSkills();
List sortedSkills = null;
if((modSkills != null) && (modSkills.size() > 0)) {
sortedSkills = CollectionFactory.createLinkedList(modSkills);
} else {
sortedSkills = CollectionFactory.createLinkedList(u.getSkills());
}
Collections.sort(sortedSkills, new SkillComparator());
if(!sortedSkills.isEmpty()) {
// DefaultMutableTreeNode skillsNode = new DefaultMutableTreeNode(getString("node.skills"));
DefaultMutableTreeNode skillsNode = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.skills"),
"skills"));
parent.add(skillsNode);
expandableNodes.add(new NodeWrapper(skillsNode, "EMapDetailsPanel.UnitSkillsExpanded"));
for(Iterator iter = sortedSkills.iterator(); iter.hasNext();) {
Skill os = null;
Skill ms = null;
if(modSkills != null) {
// assume that we are iterating over the mod skills
ms = (Skill) iter.next();
os = u.getSkill(ms.getSkillType());
} else {
// assume that we are iterating over the original skills
os = (Skill) iter.next();
}
if(!isTrader && (os != null)) { // check for trader
if((tradeCat != null) && tradeCat.isInstance(os.getSkillType())) {
isTrader = true;
} else if((tradeSkill != null) && tradeSkill.equals(os.getSkillType())) {
isTrader = true;
}
}
skillsNode.add(new DefaultMutableTreeNode(nodeWrapperFactory.createSkillNodeWrapper(u,
os,
ms)));
}
}
return isTrader;
}
/**
* Append information on this unit's teachers and pupils.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitTeachInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
// teacher pupil relations
Collection pupils = CollectionFactory.createLinkedList();
Collection teachers = CollectionFactory.createLinkedList();
pupils = u.getPupils();
teachers = u.getTeachers();
// for(Iterator iter = u.getRelations(TeachRelation.class).iterator(); iter.hasNext();) {
// TeachRelation tr = (TeachRelation) iter.next();
//
// if(u.equals(tr.source)) {
// if(tr.target != null) {
// pupils.add(tr.target);
// }
// } else {
// teachers.add(tr.source);
// }
// }
if(teachers.size() > 0) {
// DefaultMutableTreeNode teachersNode = new DefaultMutableTreeNode("");
DefaultMutableTreeNode teachersNode = createSimpleNode("", "teacher");
parent.add(teachersNode);
expandableNodes.add(new NodeWrapper(teachersNode,
"EMapDetailsPanel.UnitTeachersExpanded"));
int teacherCounter = 0;
for(Iterator iter = teachers.iterator(); iter.hasNext();) {
Unit teacher = (Unit) iter.next();
teacherCounter += teacher.getModifiedPersons();
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(teacher,
teacher.getPersons(),
teacher.getModifiedPersons());
DefaultMutableTreeNode teacherNode = new DefaultMutableTreeNode(w);
teachersNode.add(teacherNode);
}
teachersNode.setUserObject(new UnitListNodeWrapper(getString("node.teacher") + ": " +
teacherCounter + " / " +
(((u.getModifiedPersons() % 10) == 0)
? (u.getModifiedPersons() / 10)
: ((u.getModifiedPersons() / 10) +
1)), null, teachers,"teacher"));
}
if(pupils.size() > 0) {
boolean duplicatePupil = false;
Collection checkPupils = CollectionFactory.createLinkedList();
// DefaultMutableTreeNode pupilsNode = new DefaultMutableTreeNode("");
DefaultMutableTreeNode pupilsNode = createSimpleNode("", "pupils");
parent.add(pupilsNode);
expandableNodes.add(new NodeWrapper(pupilsNode, "EMapDetailsPanel.UnitPupilsExpanded"));
int pupilCounter = 0;
for(Iterator iter = pupils.iterator(); iter.hasNext();) {
Unit pupil = (Unit) iter.next();
pupilCounter += pupil.getModifiedPersons();
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(pupil,
pupil.getPersons(),
pupil.getModifiedPersons());
DefaultMutableTreeNode pupilNode = new DefaultMutableTreeNode(w);
pupilsNode.add(pupilNode);
// duplicate check
if (checkPupils.contains(pupil)){
duplicatePupil=true;
} else {
checkPupils.add(pupil);
}
}
String duplicatePupilWarning = "";
if (duplicatePupil){
duplicatePupilWarning = " (!!!)";
}
pupilsNode.setUserObject(new UnitListNodeWrapper(getString("node.pupils") + ": " +
pupilCounter + " / " +
(u.getModifiedPersons() * 10) + duplicatePupilWarning, null,
pupils,"pupils"));
}
}
private void appendUnitTransportationInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
// transportation relations
Collection carriers = u.getCarriers();
if(carriers.size() > 0) {
DefaultMutableTreeNode carriersNode = new DefaultMutableTreeNode(new UnitListNodeWrapper(getString("node.carriers"),
null,
carriers));
parent.add(carriersNode);
expandableNodes.add(new NodeWrapper(carriersNode,
"EMapDetailsPanel.UnitCarriersExpanded"));
for(Iterator iter = carriers.iterator(); iter.hasNext();) {
Unit carrier = (Unit) iter.next();
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(carrier,
carrier.getPersons(),
carrier.getModifiedPersons());
carriersNode.add(new DefaultMutableTreeNode(w));
}
}
Collection passengers = u.getPassengers();
if(passengers.size() > 0) {
DefaultMutableTreeNode passengersNode = new DefaultMutableTreeNode(new UnitListNodeWrapper(getString("node.passengers"),
null,
passengers));
parent.add(passengersNode);
expandableNodes.add(new NodeWrapper(passengersNode,
"EMapDetailsPanel.UnitPassengersExpanded"));
for(Iterator iter = passengers.iterator(); iter.hasNext();) {
Unit passenger = (Unit) iter.next();
String str = passenger.toString() + ": " +
weightNumberFormat.format(new Float(passenger.getWeight() / 100.0f)) +
" " + getString("node.weightunits");
if(passenger.getWeight() != passenger.getModifiedWeight()) {
str += (" (" +
weightNumberFormat.format(new Float(passenger.getModifiedWeight() / 100.0f)) +
" " + getString("node.weightunits") + ")");
}
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(passenger, str);
passengersNode.add(new DefaultMutableTreeNode(w));
}
}
}
private void appendUnitAttackInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
// attack relations
Collection attacks = u.getAttackVictims();
if(attacks.size() > 0) {
DefaultMutableTreeNode attacksNode = new DefaultMutableTreeNode(new UnitListNodeWrapper(getString("node.attacks"),
null,
attacks));
parent.add(attacksNode);
expandableNodes.add(new NodeWrapper(attacksNode,
"EMapDetailsPanel.UnitAttacksExpanded"));
for(Iterator iter = attacks.iterator(); iter.hasNext();) {
Unit victim = (Unit) iter.next();
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(victim,
victim.getPersons(),
victim.getModifiedPersons());
attacksNode.add(new DefaultMutableTreeNode(w));
}
}
Collection attackedBy = u.getAttackAggressors();
if(attackedBy.size() > 0) {
DefaultMutableTreeNode attackedByNode = new DefaultMutableTreeNode(new UnitListNodeWrapper(getString("node.attackedBy"),
null,
attackedBy));
parent.add(attackedByNode);
expandableNodes.add(new NodeWrapper(attackedByNode,
"EMapDetailsPanel.UnitAttackedByExpanded"));
for(Iterator iter = attackedBy.iterator(); iter.hasNext();) {
Unit victim = (Unit) iter.next();
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(victim,
victim.getPersons(),
victim.getModifiedPersons());
attackedByNode.add(new DefaultMutableTreeNode(w));
}
}
}
/**
* Append information on the unit's spells
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitSpellsInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
if((u.spells != null) && (u.spells.size() > 0)) {
// DefaultMutableTreeNode spellsNode = new DefaultMutableTreeNode(getString("node.spells"));
DefaultMutableTreeNode spellsNode = createSimpleNode(getString("node.spells"), "magicschool");
parent.add(spellsNode);
expandableNodes.add(new NodeWrapper(spellsNode, "EMapDetailsPanel.UnitSpellsExpanded"));
List sortedSpells = CollectionFactory.createLinkedList(u.spells.values());
Collections.sort(sortedSpells, new SpellLevelComparator(new NameComparator(null)));
for(Iterator iter = sortedSpells.iterator(); iter.hasNext();) {
Spell spell = (Spell) iter.next();
spellsNode.add(createSimpleNode(spell, "spell"));
}
}
}
private void appendUnitCombatSpells(Map spells, DefaultMutableTreeNode parent,
Collection expandableNodes) {
if((spells == null) || spells.isEmpty()) {
return;
}
DefaultMutableTreeNode combatSpells = new DefaultMutableTreeNode(getString("node.combatspells"));
parent.add(combatSpells);
expandableNodes.add(new NodeWrapper(combatSpells,
"EMapDetailsPanel.UnitCombatSpellsExpanded"));
for(Iterator iter = spells.values().iterator(); iter.hasNext();) {
CombatSpell spell = (CombatSpell) iter.next();
combatSpells.add(createSimpleNode(spell, "spell"));
}
}
/**
* Appends information on the potions that this unit can make.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitPotionInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
if((data.potions() != null) && (u.skills != null) &&
u.skills.containsKey(EresseaConstants.S_ALCHEMIE)) {
// DefaultMutableTreeNode potionsNode = new DefaultMutableTreeNode(getString("node.potions"));
DefaultMutableTreeNode potionsNode = createSimpleNode(getString("node.potions"), "Alchemie");
Skill alchSkill = (Skill) u.skills.get(EresseaConstants.S_ALCHEMIE);
List potions = CollectionFactory.createLinkedList(data.potions().values());
Collections.sort(potions, new PotionLevelComparator(new NameComparator(null)));
for(Iterator iter = potions.iterator(); iter.hasNext();) {
Potion p = (Potion) iter.next();
if((p.getLevel() * 2) <= alchSkill.getLevel()) {
int max = getBrewablePotions(data.rules, p, u.getRegion());
potionsNode.add(new DefaultMutableTreeNode(nodeWrapperFactory.createPotionNodeWrapper(p,
data.getTranslation(p),
": " +
max)));
}
}
if(potionsNode.getChildCount() > 0) {
parent.add(potionsNode);
expandableNodes.add(new NodeWrapper(potionsNode,
"EMapDetailsPanel.UnitPotionsExpanded"));
}
}
}
/**
* Append information on the region resources if this unit is a maker.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendUnitRegionResource(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
DefaultMutableTreeNode resourceNode = null;
if(!u.getRegion().resources().isEmpty()) {
for(Iterator iter = u.getRegion().resources().iterator(); iter.hasNext();) {
RegionResource res = (RegionResource) iter.next();
ItemType resItemType = res.getType();
if (resItemType!=null && resItemType.getMakeSkill()!=null) {
Skill resMakeSkill = resItemType.getMakeSkill();
SkillType resMakeSkillType = resMakeSkill.getSkillType();
if (resMakeSkillType!=null && u.getModifiedSkill(resMakeSkillType)!=null){
Skill unitSkill = u.getModifiedSkill(resMakeSkillType);
if (unitSkill.getLevel()>0){
if (resourceNode==null){
// resourceNode=new DefaultMutableTreeNode(getString("node.resources_region"));
resourceNode=createSimpleNode(getString("node.resources_region"), "ressourcen");
expandableNodes.add(new NodeWrapper(resourceNode, "EMapDetailsPanel.UnitRegionResourceExpanded"));
}
int oldValue = findOldValueByResourceType(u.getRegion(), res);
appendResource(res, resourceNode, oldValue);
}
}
}
}
}
if (resourceNode!=null){
parent.add(resourceNode);
}
}
/**
* Append information on the containers this unit is in, if it is commanding any and who it is
* passing command.
*
* @param u
* @param parent
* @param expandableNodes
*/
private void appendContainerInfo(Unit u, DefaultMutableTreeNode parent, Collection expandableNodes) {
if (u.getUnitContainer() != null) {
DefaultMutableTreeNode containerNode = null;
boolean isOwner = u.getUnitContainer().getOwnerUnit() == u;
UnitContainerNodeWrapper cnw = nodeWrapperFactory.createUnitContainerNodeWrapper(u
.getUnitContainer(), true, isOwner);
containerNode = new DefaultMutableTreeNode(cnw);
parent.add(containerNode);
}
if (u.getModifiedUnitContainer() != null
&& !u.getModifiedUnitContainer().equals(u.getUnitContainer())) {
DefaultMutableTreeNode containerNode = null;
boolean isOwner = false; // TODO: can we calculate if the unit is going to be the
// owner of its new container?
containerNode = new DefaultMutableTreeNode(nodeWrapperFactory
.createUnitContainerNodeWrapper(u.getModifiedUnitContainer(), true, isOwner));
parent.add(containerNode);
}
// command relations
Set getters = null;
Set givers = null;
for (Iterator it = u.getRelations(ControlRelation.class).iterator(); it.hasNext();){
ControlRelation rel = (ControlRelation) it.next();
if (givers==null)
givers = CollectionFactory.createHashSet();
if (getters==null)
getters = CollectionFactory.createHashSet();
if (rel.source==u)
getters.add(rel.target);
if (rel.target==u)
givers.add(rel.source);
}
if (givers!=null || getters!=null){
DefaultMutableTreeNode commandNode = new DefaultMutableTreeNode(getString("node.command"));
expandableNodes.add(new NodeWrapper(commandNode, "EMapDetailsPanel.PersonsExpanded"));
if (givers!=null){
for (Iterator it = givers.iterator(); it.hasNext();){
Unit u2 = (Unit) it.next();
UnitNodeWrapper unw = nodeWrapperFactory.createUnitNodeWrapper(u2);
unw.setAdditionalIcon("give");
unw.setReverseOrder(true);
commandNode.add(new DefaultMutableTreeNode(unw));
}
}
if (getters!=null){
for (Iterator it = getters.iterator(); it.hasNext();){
Unit u2 = (Unit) it.next();
UnitNodeWrapper unw = nodeWrapperFactory.createUnitNodeWrapper(u2);
unw.setAdditionalIcon("get");
unw.setReverseOrder(true);
commandNode.add(new DefaultMutableTreeNode(unw));
}
}
parent.add(commandNode);
}
}
private void appendUnitCapacityByItems(DefaultMutableTreeNode parent, Unit u, int freeCapacity) {
ItemType horses = data.rules.getItemType(StringID.create("Pferd"));
ItemType carts = data.rules.getItemType(StringID.create("Wagen"));
ItemType silver = data.rules.getItemType(StringID.create("Silber"));
// Fiete: feature request...showing not only capacity for "good" items in region...
if (PropertiesHelper.getboolean(settings, "unitCapacityContextMenuShowFriendly", true)){
for(Iterator iter = u.getRegion().items().iterator(); iter.hasNext();) {
Item item = (Item) iter.next();
ItemType type = item.getItemType();
if((type.getWeight() > 0.0) && !type.equals(horses) && !type.equals(carts) &&
!type.equals(silver)) {
int weight = (int) (type.getWeight() * 100);
parent.add(createSimpleNode("Max. " + type.getName() + ": " +
(freeCapacity / weight), "items/" + type.getIconName()));
}
}
}
if (PropertiesHelper.getboolean(settings, "unitCapacityContextMenuShowSome", false)){
for(Iterator iter = u.getRegion().allItems().iterator(); iter.hasNext();) {
Item item = (Item) iter.next();
ItemType type = item.getItemType();
if((type.getWeight() > 0.0) && !type.equals(horses) && !type.equals(carts) &&
!type.equals(silver)) {
int weight = (int) (type.getWeight() * 100);
parent.add(createSimpleNode("Max. " + type.getName() + ": " +
(freeCapacity / weight), "items/" + type.getIconName()));
}
}
}
if (PropertiesHelper.getboolean(settings, "unitCapacityContextMenuShowAll", false)) {
// show all itemtypes...need to built and sort a list
// we take natural order - it works - added Comparable to ItemType (Fiete)
TreeSet l = new TreeSet();
// only use the items found in gamedata
// without fancy merging, for all items should pe Translation present
for (Iterator iter2 = u.getRegion().getData().regions().values().iterator();iter2.hasNext();){
Region r = (Region) iter2.next();
for (Iterator iteri = r.allItems().iterator();iteri.hasNext();){
Item item = (Item) iteri.next();
ItemType type = item.getItemType();
l.add(type);
}
}
String actLocale = u.getRegion().getData().getLocale().toString();
if (actLocale.equalsIgnoreCase("de")) {
// ok...a de GameData...here we use all defined ItemTypes from the rules...too
// need no present Translation for those...in CR all in german...
for (Iterator iter2 = u.getRegion().getData().rules.getItemTypeIterator();iter2.hasNext();){
ItemType type = (ItemType)iter2.next();
l.add(type);
}
}
for (Iterator iter3 = l.iterator();iter3.hasNext();){
ItemType type = (ItemType) iter3.next();
if((type.getWeight() > 0.0) && !type.equals(horses) && !type.equals(carts) &&
!type.equals(silver)) {
int weight = (int) (type.getWeight() * 100);
parent.add(createSimpleNode("Max. " + type.getName() + ": " +
(freeCapacity / weight), "items/" + type.getIconName()));
}
}
}
}
/**
* Determines how many potions potion can be brewed from the herbs owned by privileged factions
* in the specified region.
*
* @param rules TODO: DOCUMENT ME!
* @param potion TODO: DOCUMENT ME!
* @param region TODO: DOCUMENT ME!
*
* @return TODO: DOCUMENT ME!
*/
private int getBrewablePotions(Rules rules, Potion potion, Region region) {
int max = Integer.MAX_VALUE;
for(Iterator iter = potion.ingredients().iterator(); iter.hasNext();) {
Item ingredient = (Item) iter.next();
if(ingredient.getItemType() != null) {
// units can not own peasants!
int amount = 0;
if(ingredient.getItemType().equals(data.rules.getItemType(StringID.create("Bauer")))) {
amount = region.peasants;
} else {
Item item = region.getItem(ingredient.getItemType());
if(item != null) {
amount = item.getAmount();
}
}
max = Math.min(amount, max);
}
}
return max;
}
private void showBuilding(Building b) {
setNameAndDescription(b, isPrivilegedAndNoSpy(b.getOwnerUnit()));
appendBuildingInfo(b, rootNode, myExpandableNodes);
}
/**
* Appends information on a buildig: Type, owner, inmates, maintenance and costs.
*
* @param b
* @param parent
* @param expandableNodes
*/
private void appendBuildingInfo(Building b, DefaultMutableTreeNode parent,
Collection expandableNodes) {
/* make sure that all unit relations have been established
(necessary for enter-/leave relations) */
if(b.getRegion() != null) {
b.getRegion().refreshUnitRelations();
}
// type and true type
appendBuildingTypeInfo(b, parent, expandableNodes);
// Besitzer
appendBuildingOwnerInfo(b, parent, expandableNodes);
// GIB KOMMANDO?
appendContainerCommandInfo(b, parent, expandableNodes);
// Insassen
appendBuildingInmatesInfo(b, parent, expandableNodes);
// Gebaeudeunterhalt
appendBuildingMaintenance(b, parent, expandableNodes);
// Baukosten
appendBuildingCosts(b, parent, expandableNodes);
// Kommentare
appendComments(b, parent, expandableNodes);
appendTags(b, parent, expandableNodes);
}
/**
*
*
* @param b
* @param parent
* @param expandableNodes
*/
private void appendBuildingCosts(Building b, DefaultMutableTreeNode parent, Collection expandableNodes) {
Iterator iter = b.getBuildingType().getRawMaterials();
DefaultMutableTreeNode n;
if(iter.hasNext()) {
// n = new DefaultMutableTreeNode(getString("node.buildingcost"));
n = createSimpleNode(getString("node.buildingcost"), "buildingcost");
parent.add(n);
expandableNodes.add(new NodeWrapper(n, "EMapDetailsPanel.BuildingCostExpanded"));
} else {
n=null;
}
DefaultMutableTreeNode m;
while(iter.hasNext()) {
Item i = (Item) iter.next();
String text = i.getName();
m = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(
i.getAmount() +
" " + text,
"items/" +
i.getItemType()
.getID()
.toString()));
n.add(m);
}
if (n!=null){
// minddestTalent
BuildingType buildungType = b.getBuildingType();
if (buildungType!=null && buildungType.getMinSkillLevel()>-1){
m = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(
getString("node.buildingminskilllevel") + ": " + buildungType.getMinSkillLevel(),"skills"));
n.add(m);
}
// maxGrösse (bzw bei Burgen Min-Max)
// Bei Zitadelle: keine max oder min grössenangabe..(kein maxSize verfügbar)
if (buildungType!=null && buildungType.getMaxSize()>-1){
if (buildungType instanceof CastleType){
CastleType castleType = (CastleType) buildungType;
m = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(
getString("node.buildingcastlesizelimits") + ": " +
castleType.getMinSize() + " - " + castleType.getMaxSize(),"build_size"));
} else {
m = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(
"MAX: " + buildungType.getMaxSize(),"build_size"));
}
n.add(m);
}
}
}
/**
*
*
* @param b
* @param parent
* @param expandableNodes
*/
private void appendBuildingMaintenance(Building b, DefaultMutableTreeNode parent, Collection expandableNodes) {
Iterator iter = b.getBuildingType().getMaintenanceItems();
if(iter.hasNext()) {
// DefaultMutableTreeNode maintNode = new DefaultMutableTreeNode(getString("node.upkeep"));
DefaultMutableTreeNode maintNode = createSimpleNode(getString("node.upkeep"), "upkeep");
parent.add(maintNode);
expandableNodes.add(new NodeWrapper(maintNode, "EMapDetailsPanel.BuildingMaintenanceExpanded"));
while(iter.hasNext()) {
Item i = (Item) iter.next();
String text = i.getName();
DefaultMutableTreeNode m;
if(text.endsWith(" pro Größenpunkt")) {
int amount = b.getSize() * i.getAmount();
String newText = text.substring(0, text.indexOf(" pro Größenpunkt"));
m = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(amount +
" " +
newText,
"items/" +
i.getItemType()
.getID()
.toString()));
} else {
m = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(i.getAmount() +
" " +
text,
"items/" +
i.getItemType()
.getID()
.toString()));
}
maintNode.add(m);
}
}
}
/**
* Appends information on the inmates of this building.
*
* @param b
* @param parent
* @param expandableNodes
*/
private void appendBuildingInmatesInfo(Building b, DefaultMutableTreeNode parent, Collection expandableNodes) {
List units = CollectionFactory.createLinkedList(b.units()); // the collection of units currently in the building
Collections.sort(units, sortIndexComparator);
Collection modUnits = b.modifiedUnits(); // the collection of units in the building in the next turn
Collection allInmates = CollectionFactory.createLinkedList();
allInmates.addAll(units);
allInmates.addAll(modUnits);
int inmates = 0;
int modInmates = 0;
if((units.size() > 0) || (modUnits.size() > 0)) {
DefaultMutableTreeNode n = new DefaultMutableTreeNode("");
parent.add(n);
expandableNodes.add(new NodeWrapper(n, "EMapDetailsPanel.BuildingInmatesExpanded"));
DefaultMutableTreeNode m;
for(Iterator iter = units.iterator(); iter.hasNext();) {
Unit u = (Unit) iter.next();
StringBuffer text = new StringBuffer();
if(b.getModifiedUnit(u.getID()) == null) {
text.append("<- ");
}
text.append(u.toString()).append(": ").append(u.getModifiedPersons());
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(u, text.toString());
m = new DefaultMutableTreeNode(w);
n.add(m);
inmates += u.getPersons();
}
for(Iterator iter = modUnits.iterator(); iter.hasNext();) {
Unit u = (Unit) iter.next();
modInmates += u.getModifiedPersons();
if(b.getUnit(u.getID()) == null) {
StringBuffer text = new StringBuffer();
text.append("-> ");
text.append(u.toString()).append(": ").append(u.getModifiedPersons());
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(u, text.toString());
m = new DefaultMutableTreeNode(w);
n.add(m);
}
}
if(inmates == modInmates) {
// n.setUserObject(getString("node.inmates") + ": " + inmates);
n.setUserObject(new UnitListNodeWrapper(getString("node.inmates") + ": " + inmates, null,
allInmates,"occupants"));
} else {
// n.setUserObject(getString("node.inmates") + ": " + inmates + " (" + modInmates + ")");
n.setUserObject(new UnitListNodeWrapper(getString("node.inmates") + ": " + inmates + " (" + modInmates +
")", null, allInmates,"occupants"));
}
}
DefaultMutableTreeNode n = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(((inmates == modInmates)
? (getString("node.size") +
": " + inmates)
: (getString("node.size") +
": " + inmates +
" (" +
modInmates +
")")) + " / " +
b.getSize(),
"build_size"));
parent.insert(n, 0);
}
/**
* Append information on the owner.
*
* @param b
* @param parent
* @param expandableNodes
*/
private void appendBuildingOwnerInfo(Building b, DefaultMutableTreeNode parent, Collection expandableNodes) {
if(b.getOwnerUnit() != null) {
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(b.getOwnerUnit(),
getString("node.owner") +
": ",
b.getOwnerUnit()
.getPersons(),
b.getOwnerUnit()
.getModifiedPersons());
DefaultMutableTreeNode n = new DefaultMutableTreeNode(w);
parent.add(n);
if(b.getOwnerUnit().getFaction() == null) {
n = createSimpleNode(getString("node.faction") + ": " +
getString("node.unknownfaction"), "faction");
} else {
n = createSimpleNode(getString("node.faction") + ": " +
b.getOwnerUnit().getFaction().toString(), "faction");
}
parent.add(n);
}
}
/**
* Append information on the buildings type and true type.
*
* @param b
* @param parent
* @param expandableNodes
*/
private void appendBuildingTypeInfo(Building b, DefaultMutableTreeNode parent, Collection expandableNodes) {
DefaultMutableTreeNode n;
// Fiete 20060910
// added support for wahrerTyp
if (b.getTrueBuildingType()!=null){
n = createSimpleNode(getString(b.getTrueBuildingType()),
"warnung");
parent.add(n);
}
// Typ
n = createSimpleNode(getString("node.type") + ": " + b.getType().getName(),
b.getType().getID().toString());
parent.add(n);
}
/**
* sets the ship name editable sets the ship description editable shows a tree: (Type :
* ship.type) (Completion : x % (y/z)) (Coast : ship.direction) (if completed) (Range :
* node.range (- components) Back - ingredients: 1.name ... n.name
*
* @param s TODO: DOCUMENT ME!
*/
private void showShip(Ship s) {
setNameAndDescription(s, isPrivilegedAndNoSpy(s.getOwnerUnit()));
appendShipInfo(s, rootNode, myExpandableNodes);
}
private void appendShipInfo(Ship s, DefaultMutableTreeNode parent, Collection expandableNodes) {
/* make sure that all unit relations have been established
(necessary for enter-/leave relations) */
if(s.getRegion() != null) {
s.getRegion().refreshUnitRelations();
}
// Schiffstyp
if((s.getName() != null) && (s.getType().getName() != null)) {
parent.add(createSimpleNode(getString("node.type") + ": " + s.getType().getName(),
s.getType().getID().toString()));
}
int nominalShipSize = s.getShipType().getMaxSize();
if(s.size != nominalShipSize) {
// nominal size and damage
int ratio = nominalShipSize != 0 ? ratio = (s.size * 100) / nominalShipSize : 0;
parent.add(createSimpleNode(getString("node.completion") + ": " + ratio +
"% (" + s.size + "/" + nominalShipSize + ")","sonstiges"));
appendShipDamageInfo(s, parent, expandableNodes);
} else {
// Kueste
if (s.shoreId > -1) {
parent.add(createSimpleNode(getString("node.shore") + ": "
+ Direction.toString(s.shoreId), "shore_" + String.valueOf(s.shoreId)));
}
// Reichweite
appendShipRangeInfo(s, parent, expandableNodes);
// damage
appendShipDamageInfo(s, parent, expandableNodes);
// Fiete rework: Load and Overload
appendShipLoadInfo(s, parent, expandableNodes);
}
// Besitzer
if (s.getOwnerUnit() != null) {
appendShipOwnerInfo(s, parent, expandableNodes);
}
appendContainerCommandInfo(s, parent, expandableNodes);
// Insassen
appendShipInmateInfo(s, parent, expandableNodes);
// Baukosten info
appendShipCosts(s, parent, expandableNodes);
// Kommentare
appendComments(s, parent, expandableNodes);
}
/**
*
* @param s
* @param parent
* @param expandableNodes
*/
private void appendShipCosts(Ship s, DefaultMutableTreeNode parent, Collection expandableNodes) {
ShipType shipType = s.getShipType();
if (shipType!=null && shipType.getMaxSize()>-1){
// DefaultMutableTreeNode n = new DefaultMutableTreeNode(getString("node.buildingcost"));
DefaultMutableTreeNode n = createSimpleNode(getString("node.buildingcost"), "buildingcost");
parent.add(n);
expandableNodes.add(new NodeWrapper(n, "EMapDetailsPanel.ShipCostExpanded"));
DefaultMutableTreeNode m = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(
shipType.getMaxSize() + " " + data.getTranslation("Holz"),"items/holz"));
n.add(m);
m = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(
getString("node.buildingminskilllevel") + ": " + shipType.getBuildLevel(),"skills"));
n.add(m);
}
}
/**
* Appends information about inmates, modified inmates and their respective weights.
*
* @param s
* @param parent
* @param expandableNodes
*/
private void appendShipInmateInfo(Ship s, DefaultMutableTreeNode parent, Collection expandableNodes) {
List units = CollectionFactory.createLinkedList(s.units()); // the collection of units currently on the ship
Collections.sort(units, sortIndexComparator);
Collection modUnits = s.modifiedUnits(); // the collection of units on the ship in the next turn
Collection allInmates = CollectionFactory.createLinkedList();
allInmates.addAll(units);
allInmates.addAll(modUnits);
// sum up load, inmates, modified inmates over all units;
int load=0;
int inmates=0;
int modInmates=0;
if((units.size() > 0) || (modUnits.size() > 0)) {
DefaultMutableTreeNode n = new DefaultMutableTreeNode("");
parent.add(n);
expandableNodes.add(new NodeWrapper(n, "EMapDetailsPanel.ShipInmatesExpanded"));
DefaultMutableTreeNode m;
for(Iterator iter = units.iterator(); iter.hasNext();) {
Unit u = (Unit) iter.next();
StringBuffer text = new StringBuffer();
Float weight = new Float(u.getWeight() / 100.0F);
Float modWeight = new Float(u.getModifiedWeight() / 100.0F);
if(s.getModifiedUnit(u.getID()) == null) {
text.append("<- ");
} else {
//modLoad += u.getModifiedWeight();
}
// FIXME: pavkovic2004.07.01: check this out: load += u.getModifiedWeight();
load += u.getWeight();
text.append(u.toString()).append(": ").append(weightNumberFormat.format(weight));
if(weight.equals(modWeight) == false) {
text.append(" (").append(weightNumberFormat.format(modWeight)).append(")");
}
text.append(" " + getString("node.weightunits"));
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(u, text.toString());
m = new DefaultMutableTreeNode(w);
n.add(m);
inmates += u.getPersons();
}
for(Iterator iter = modUnits.iterator(); iter.hasNext();) {
Unit u = (Unit) iter.next();
modInmates += u.getModifiedPersons();
if(s.getUnit(u.getID()) == null) {
StringBuffer text = new StringBuffer();
Float weight = new Float(u.getWeight() / 100.0F);
Float modWeight = new Float(u.getModifiedWeight() / 100.0F);
// modLoad += u.getModifiedWeight();
text.append("-> ");
text.append(u.toString()).append(": ").append(weightNumberFormat.format(weight));
if(weight.equals(modWeight) == false) {
text.append(" (").append(weightNumberFormat.format(modWeight)).append(")");
}
text.append(" " + getString("node.weightunits"));
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(u, text.toString());
m = new DefaultMutableTreeNode(w);
n.add(m);
}
}
if(inmates == modInmates) {
// n.setUserObject(getString("node.inmates") + ": " + inmates);
n.setUserObject(new UnitListNodeWrapper(getString("node.inmates")
+ ": " + inmates, null, allInmates,"occupants"));
} else {
// n.setUserObject(getString("node.inmates") + ": " + inmates + " (" + modInmates + ")");
n.setUserObject(new UnitListNodeWrapper(getString("node.inmates") + ": " + inmates + " (" + modInmates +
")", null, allInmates,"occupants"));
}
if(ShipRoutePlanner.canPlan(s)) { // add a link to the ship route planer
parent.add(new DefaultMutableTreeNode(new ShipRoutingPlanerButton(s)));
}
}
}
/**
* TODO DOCUMENT ME!
* One line description.
*
* Long description.
*
* @param s
* @param parent
* @param expandableNodes
*/
private void appendShipOwnerInfo(Ship s, DefaultMutableTreeNode parent, Collection expandableNodes) {
Unit owner = s.getOwnerUnit();
SkillType sailingSkillType = data.rules.getSkillType(StringID.create("Segeln"), true);
// owner faction
Faction fac = owner.getFaction();
DefaultMutableTreeNode n;
if (fac == null) {
n = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(
getString("node.faction") + ": " + getString("node.unknownfaction"),
"faction"));
} else {
n = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(
getString("node.faction") + ": " + fac.toString(), "faction"));
}
parent.add(n);
// captain
UnitNodeWrapper w = nodeWrapperFactory.createUnitNodeWrapper(owner,
getString("node.captain") + ": ", owner.getPersons(), owner
.getModifiedPersons());
w.setReverseOrder(true);
w.setAdditionalIcon("captain");
DefaultMutableTreeNode ownerNode = new DefaultMutableTreeNode(w);
parent.add(ownerNode);
// skill
Skill sailingSkill = s.getOwnerUnit().getModifiedSkill(sailingSkillType);
int sailingSkillAmount = (sailingSkill == null) ? 0 : sailingSkill.getLevel();
String text = getString("node.sailingskill") + ": " + getString("node.captain")+" "
+ sailingSkillAmount + " / " + s.getShipType().getCaptainSkillLevel() + ", ";
// n = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(
// getString("node.captainskill") + ": " + sailingSkillAmount + " / "
// + s.getShipType().getCaptainSkillLevel(), "captain"));
// parent.add(n);
// Matrosen
sailingSkillAmount = 0;
// pavkovic 2003.10.03: use modifiedUnits to reflect FUTURE value?
Collection modUnits = s.modifiedUnits(); // the collection of units on the ship in the next turn
for(Iterator sailors = modUnits.iterator(); sailors.hasNext();) {
Unit u = (Unit) sailors.next();
sailingSkill = u.getModifiedSkill(sailingSkillType);
if(sailingSkill != null) {
sailingSkillAmount += (sailingSkill.getLevel() * u.getModifiedPersons());
}
}
text += getString("node.crew")+" "+sailingSkillAmount + " / "
+ s.getShipType().getSailorSkillLevel();
n = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(text, "crew"));
parent.add(n);
}
/**
* TODO DOCUMENT ME!
* One line description.
*
* Long description.
*
* @param s
* @param parent
* @param expandableNodes
*/
private void appendShipLoadInfo(Ship s, DefaultMutableTreeNode parent, Collection expandableNodes) {
int cargo = s.getCargo();
// if(cargo == -1) {
// cargo = load;
// }
String strLoad = weightNumberFormat.format(new Float(cargo / 100.0F));
String strModLoad = weightNumberFormat.format(new Float(s.getModifiedLoad() / 100.0F));
String strCap = weightNumberFormat.format(new Float(s.getMaxCapacity() / 100.0F));
// mark overloading with (!!!) (Fiete)
String overLoad = "";
if (s.getModifiedLoad()>s.getMaxCapacity()){
overLoad = " (!!!)";
}
if(log.isDebugEnabled()) {
log.debug("outer ship state: " + s.getShipType().getCapacity() + "(strCap " +
strCap + ")");
}
DefaultMutableTreeNode n = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.load") +
": " + strLoad +
((!strModLoad.equals(strLoad))
? (" (" +
strModLoad + ") ")
: " ") + "/ " +
strCap + " " +
getString("node.weightunits") + overLoad,
"beladung"));
parent.add(n);
// explizit node for overloading a ship
if (s.getModifiedLoad()>s.getMaxCapacity()) {
n = new DefaultMutableTreeNode(nodeWrapperFactory.createSimpleNodeWrapper(getString("node.load") +
": " +
getString("node.overloadedby") +
weightNumberFormat.format(new Float((s.getModifiedLoad() - s.getMaxCapacity()) / 100.0F)) +
" " +
getString("node.weightunit