/* * MegaMekLab - Copyright (C) 2008 * * Original author - jtighe (torren@users.sourceforge.net) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ package megameklab.com.ui.Mek.views; import java.awt.Color; import java.awt.Dimension; 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.util.ArrayList; import java.util.List; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.SpinnerNumberModel; import javax.swing.SwingConstants; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import megamek.common.EquipmentType; import megamek.common.Mech; import megamek.common.TripodMech; import megameklab.com.ui.EntitySource; import megameklab.com.util.IView; import megameklab.com.util.RefreshListener; import megameklab.com.util.UnitUtil; public class ArmorView extends IView implements ChangeListener, ActionListener { /** * */ private static final long serialVersionUID = 799195356642563937L; private JPanel mainPanel = new JPanel(); private JPanel headPanel = new JPanel(); private JPanel laPanel = new JPanel(); private JPanel raPanel = new JPanel(); private JPanel llPanel = new JPanel(); private JPanel rlPanel = new JPanel(); private JPanel ltPanel = new JPanel(); private JPanel rtPanel = new JPanel(); private JPanel ctPanel = new JPanel(); private JPanel clPanel = new JPanel(); public SpinnerNumberModel laArmorModel = new SpinnerNumberModel(); public SpinnerNumberModel raArmorModel = new SpinnerNumberModel(); public SpinnerNumberModel llArmorModel = new SpinnerNumberModel(); public SpinnerNumberModel rlArmorModel = new SpinnerNumberModel(); public SpinnerNumberModel ltArmorModel = new SpinnerNumberModel(); public SpinnerNumberModel rtArmorModel = new SpinnerNumberModel(); public SpinnerNumberModel ctArmorModel = new SpinnerNumberModel(); public SpinnerNumberModel hdArmorModel = new SpinnerNumberModel(); public SpinnerNumberModel clArmorModel = new SpinnerNumberModel(); private SpinnerNumberModel rtrArmorModel = new SpinnerNumberModel(); private SpinnerNumberModel ltrArmorModel = new SpinnerNumberModel(); private SpinnerNumberModel ctrArmorModel = new SpinnerNumberModel(); private JSpinner laArmorField = new JSpinner(laArmorModel); private JSpinner raArmorField = new JSpinner(raArmorModel); private JSpinner llArmorField = new JSpinner(llArmorModel); private JSpinner rlArmorField = new JSpinner(rlArmorModel); private JSpinner ltArmorField = new JSpinner(ltArmorModel); private JSpinner rtArmorField = new JSpinner(rtArmorModel); private JSpinner ctArmorField = new JSpinner(ctArmorModel); private JSpinner hdArmorField = new JSpinner(hdArmorModel); private JSpinner clArmorField = new JSpinner(clArmorModel); private JSpinner rtrArmorField = new JSpinner(rtrArmorModel); private JSpinner ltrArmorField = new JSpinner(ltrArmorModel); private JSpinner ctrArmorField = new JSpinner(ctrArmorModel); private List<JSpinner> armorFieldList = new ArrayList<JSpinner>(); private JLabel hdArmorMaxLabel = new JLabel("", SwingConstants.CENTER); private JLabel laArmorMaxLabel = new JLabel("", SwingConstants.CENTER); private JLabel raArmorMaxLabel = new JLabel("", SwingConstants.CENTER); private JLabel llArmorMaxLabel = new JLabel("", SwingConstants.CENTER); private JLabel rlArmorMaxLabel = new JLabel("", SwingConstants.CENTER); private JLabel ltArmorMaxLabel = new JLabel("", SwingConstants.CENTER); private JLabel rtArmorMaxLabel = new JLabel("", SwingConstants.CENTER); private JLabel ctArmorMaxLabel = new JLabel("", SwingConstants.CENTER); private JLabel clArmorMaxLabel = new JLabel("", SwingConstants.CENTER); private List<JLabel> armorMaxLabelList = new ArrayList<JLabel>(); private JLabel lblAllocatedArmor = new JLabel("Allocated Armor Points:"); private JTextField valueAllocatedArmor = new JTextField(); private JLabel lblUnallocatedArmor = new JLabel("Unallocated Armor Points:"); private JTextField valueUnallocatedArmor = new JTextField(); private JLabel lblCurrentArmor = new JLabel("Total Armor Points:"); private JTextField valueCurrentArmor = new JTextField(); private JLabel lblMaxArmor = new JLabel("Maximum Possible Armor Points:"); private JTextField valueMaxArmor = new JTextField(); private JLabel lblWastedArmor = new JLabel("Wasted Armor Points:"); private JTextField valueWastedArmor = new JTextField(); private JLabel unallocatedPointsLabelPatchworkHead = new JLabel( "Unalloc.:", SwingConstants.TRAILING); private JLabel unallocatedPointsLabelPatchworkLa = new JLabel( "Unalloc.:", SwingConstants.TRAILING); private JLabel unallocatedPointsLabelPatchworkLt = new JLabel( "Unalloc.:", SwingConstants.TRAILING); private JLabel unallocatedPointsLabelPatchworkCt = new JLabel( "Unalloc.:", SwingConstants.TRAILING); private JLabel unallocatedPointsLabelPatchworkRt = new JLabel( "Unalloc.:", SwingConstants.TRAILING); private JLabel unallocatedPointsLabelPatchworkRa = new JLabel( "Unalloc.:", SwingConstants.TRAILING); private JLabel unallocatedPointsLabelPatchworkLl = new JLabel( "Unalloc.:", SwingConstants.TRAILING); private JLabel unallocatedPointsLabelPatchworkRl = new JLabel( "Unalloc.:", SwingConstants.TRAILING); private JLabel unallocatedPointsLabelPatchworkCl = new JLabel( "Unalloc.:", SwingConstants.TRAILING); private JLabel unallocatedPointsFieldHead = new JLabel(); private JLabel unallocatedPointsFieldLa = new JLabel(); private JLabel unallocatedPointsFieldLt = new JLabel(); private JLabel unallocatedPointsFieldCt = new JLabel(); private JLabel unallocatedPointsFieldRt = new JLabel(); private JLabel unallocatedPointsFieldRa = new JLabel(); private JLabel unallocatedPointsFieldLl = new JLabel(); private JLabel unallocatedPointsFieldRl = new JLabel(); private JLabel unallocatedPointsFieldCl = new JLabel(); private int armorPoints; private int wastedArmorPoints; private JButton allocateArmorButton = new JButton("Auto-Allocate Armor"); private RefreshListener refresh; public ArmorView(EntitySource eSource) { super(eSource); setLayout(new GridLayout(1, 1)); mainPanel.setLayout(new GridBagLayout()); GridBagConstraints gbc; headPanel.setLayout(new BoxLayout(headPanel, BoxLayout.Y_AXIS)); laPanel.setLayout(new BoxLayout(laPanel, BoxLayout.Y_AXIS)); raPanel.setLayout(new BoxLayout(raPanel, BoxLayout.Y_AXIS)); ltPanel.setLayout(new BoxLayout(ltPanel, BoxLayout.Y_AXIS)); ctPanel.setLayout(new BoxLayout(ctPanel, BoxLayout.Y_AXIS)); rtPanel.setLayout(new BoxLayout(rtPanel, BoxLayout.Y_AXIS)); llPanel.setLayout(new BoxLayout(llPanel, BoxLayout.Y_AXIS)); rlPanel.setLayout(new BoxLayout(rlPanel, BoxLayout.Y_AXIS)); clPanel.setLayout(new BoxLayout(clPanel, BoxLayout.Y_AXIS)); int mainPanelGridY; gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 0; mainPanel.add(Box.createVerticalStrut(13), gbc); gbc.gridy++; mainPanel.add(headPanel, gbc); gbc.gridx = 0; gbc.gridy++; mainPanel.add(laPanel, gbc); gbc.gridx = 1; mainPanel.add(ltPanel, gbc); gbc.gridx = 2; mainPanel.add(ctPanel, gbc); gbc.gridx = 3; mainPanel.add(rtPanel, gbc); gbc.gridx = 4; mainPanel.add(raPanel, gbc); gbc.gridx = 1; gbc.gridy++; mainPanel.add(llPanel, gbc); gbc.gridx = 2; mainPanel.add(clPanel, gbc); gbc.gridx = 3; mainPanel.add(rlPanel, gbc); mainPanelGridY = gbc.gridy + 1; laArmorField.setName(Integer.toString(Mech.LOC_LARM)); raArmorField.setName(Integer.toString(Mech.LOC_RARM)); llArmorField.setName(Integer.toString(Mech.LOC_LLEG)); rlArmorField.setName(Integer.toString(Mech.LOC_RLEG)); clArmorField.setName(Integer.toString(Mech.LOC_CLEG)); ltArmorField.setName(Integer.toString(Mech.LOC_LT)); rtArmorField.setName(Integer.toString(Mech.LOC_RT)); ctArmorField.setName(Integer.toString(Mech.LOC_CT)); hdArmorField.setName(Integer.toString(Mech.LOC_HEAD)); rtrArmorField.setName(Integer.toString(Mech.LOC_RT)); ltrArmorField.setName(Integer.toString(Mech.LOC_LT)); ctrArmorField.setName(Integer.toString(Mech.LOC_CT)); armorFieldList.add(laArmorField); armorFieldList.add(raArmorField); armorFieldList.add(llArmorField); armorFieldList.add(rlArmorField); armorFieldList.add(clArmorField); armorFieldList.add(ltArmorField); armorFieldList.add(rtArmorField); armorFieldList.add(ctArmorField); armorFieldList.add(hdArmorField); armorFieldList.add(ltrArmorField); armorFieldList.add(ctrArmorField); armorFieldList.add(rtrArmorField); Dimension size = new Dimension(40, 25); for (JSpinner spinner : armorFieldList) { spinner.setToolTipText("Front Armor"); // you don't set the size of the jspinner, but rather its internal // textfield ((JSpinner.DefaultEditor) spinner.getEditor()).setSize(size); ((JSpinner.DefaultEditor) spinner.getEditor()).setMaximumSize(size); ((JSpinner.DefaultEditor) spinner.getEditor()) .setPreferredSize(size); ((JSpinner.DefaultEditor) spinner.getEditor()).setMinimumSize(size); } rtrArmorField.setToolTipText("Rear Armor"); ltrArmorField.setToolTipText("Rear Armor"); ctrArmorField.setToolTipText("Rear Armor"); armorMaxLabelList.add(hdArmorMaxLabel); armorMaxLabelList.add(laArmorMaxLabel); armorMaxLabelList.add(raArmorMaxLabel); armorMaxLabelList.add(llArmorMaxLabel); armorMaxLabelList.add(rlArmorMaxLabel); armorMaxLabelList.add(clArmorMaxLabel); armorMaxLabelList.add(ltArmorMaxLabel); armorMaxLabelList.add(rtArmorMaxLabel); armorMaxLabelList.add(ctArmorMaxLabel); Dimension labelSize = new Dimension(40, 20); for (JLabel label : armorMaxLabelList) { label.setSize(labelSize); label.setMaximumSize(labelSize); label.setPreferredSize(labelSize); label.setMinimumSize(labelSize); } JPanel topPanel; JPanel bottomPanel; synchronized (getMech()) { for (int location = 0; location < getMech().locations(); location++) { switch (location) { case Mech.LOC_HEAD: topPanel = new JPanel(new GridLayout(2, 0)); topPanel.add(hdArmorField); topPanel.add(hdArmorMaxLabel); headPanel.add(topPanel); bottomPanel = new JPanel(); bottomPanel.add(unallocatedPointsLabelPatchworkHead); bottomPanel.add(unallocatedPointsFieldHead); headPanel.add(bottomPanel); headPanel .setBorder(BorderFactory.createTitledBorder( null, getMech().getLocationAbbr(location), TitledBorder.TOP, TitledBorder.DEFAULT_POSITION)); hdArmorModel.setStepSize(1); hdArmorModel.setMinimum(0); break; case Mech.LOC_LARM: topPanel = new JPanel(new GridLayout(2, 0)); topPanel.add(laArmorField); topPanel.add(laArmorMaxLabel); laPanel.add(topPanel); bottomPanel = new JPanel(); bottomPanel.add(unallocatedPointsLabelPatchworkLa); bottomPanel.add(unallocatedPointsFieldLa); laPanel.add(bottomPanel); laPanel.setBorder(BorderFactory.createTitledBorder( null, getMech().getLocationAbbr(location), TitledBorder.TOP, TitledBorder.DEFAULT_POSITION)); laArmorModel.setStepSize(1); laArmorModel.setMinimum(0); break; case Mech.LOC_RARM: topPanel = new JPanel(new GridLayout(2, 0)); topPanel.add(raArmorField); topPanel.add(raArmorMaxLabel); raPanel.add(topPanel); bottomPanel = new JPanel(); bottomPanel.add(unallocatedPointsLabelPatchworkRa); bottomPanel.add(unallocatedPointsFieldRa); raPanel.add(bottomPanel); raPanel.setBorder(BorderFactory.createTitledBorder( null, getMech().getLocationAbbr(location), TitledBorder.TOP, TitledBorder.DEFAULT_POSITION)); raArmorModel.setStepSize(1); raArmorModel.setMinimum(0); break; case Mech.LOC_CT: topPanel = new JPanel(new GridLayout(4, 0)); topPanel.add(ctArmorField); topPanel.add(new JLabel("Rear", SwingConstants.CENTER)); topPanel.add(ctrArmorField); topPanel.add(ctArmorMaxLabel); ctPanel.setBorder(BorderFactory.createTitledBorder( null, getMech().getLocationAbbr(location), TitledBorder.TOP, TitledBorder.DEFAULT_POSITION)); ctPanel.add(topPanel); bottomPanel = new JPanel(); bottomPanel.add(unallocatedPointsLabelPatchworkCt); bottomPanel.add(unallocatedPointsFieldCt); ctPanel.add(bottomPanel); ctArmorModel.setStepSize(1); ctArmorModel.setMinimum(0); ctrArmorModel.setStepSize(1); ctrArmorModel.setMinimum(0); break; case Mech.LOC_LT: topPanel = new JPanel(new GridLayout(4, 0)); topPanel.add(ltArmorField); topPanel.add(new JLabel("Rear", SwingConstants.CENTER)); topPanel.add(ltrArmorField); topPanel.add(ltArmorMaxLabel); ltPanel.setBorder(BorderFactory.createTitledBorder( null, getMech().getLocationAbbr(location), TitledBorder.TOP, TitledBorder.DEFAULT_POSITION)); ltPanel.add(topPanel); bottomPanel = new JPanel(); bottomPanel.add(unallocatedPointsLabelPatchworkLt); bottomPanel.add(unallocatedPointsFieldLt); ltPanel.add(bottomPanel); ltArmorModel.setStepSize(1); ltArmorModel.setMinimum(0); ltrArmorModel.setStepSize(1); ltrArmorModel.setMinimum(0); break; case Mech.LOC_RT: topPanel = new JPanel(new GridLayout(4, 0)); topPanel.add(rtArmorField); topPanel.add(new JLabel("Rear", SwingConstants.CENTER)); topPanel.add(rtrArmorField); topPanel.add(rtArmorMaxLabel); rtPanel.setBorder(BorderFactory.createTitledBorder( null, getMech().getLocationAbbr(location), TitledBorder.TOP, TitledBorder.DEFAULT_POSITION)); rtPanel.add(topPanel); bottomPanel = new JPanel(); bottomPanel.add(unallocatedPointsLabelPatchworkRt); bottomPanel.add(unallocatedPointsFieldRt); rtPanel.add(bottomPanel); rtArmorModel.setStepSize(1); rtArmorModel.setMinimum(0); rtrArmorModel.setStepSize(1); rtrArmorModel.setMinimum(0); break; case Mech.LOC_LLEG: topPanel = new JPanel(new GridLayout(2, 0)); topPanel.add(llArmorField); topPanel.add(llArmorMaxLabel); llPanel.add(topPanel); bottomPanel = new JPanel(); bottomPanel.add(unallocatedPointsLabelPatchworkLl); bottomPanel.add(unallocatedPointsFieldLl); llPanel.add(bottomPanel); llPanel.setBorder(BorderFactory.createTitledBorder( null, getMech().getLocationAbbr(location), TitledBorder.TOP, TitledBorder.DEFAULT_POSITION)); llArmorModel.setStepSize(1); llArmorModel.setMinimum(0); break; case Mech.LOC_RLEG: topPanel = new JPanel(new GridLayout(2, 0)); topPanel.add(rlArmorField); topPanel.add(rlArmorMaxLabel); rlPanel.add(topPanel); bottomPanel = new JPanel(); bottomPanel.add(unallocatedPointsLabelPatchworkRl); bottomPanel.add(unallocatedPointsFieldRl); rlPanel.add(bottomPanel); rlPanel.setBorder(BorderFactory.createTitledBorder( null, getMech().getLocationAbbr(location), TitledBorder.TOP, TitledBorder.DEFAULT_POSITION)); rlArmorModel.setStepSize(1); rlArmorModel.setMinimum(0); break; case Mech.LOC_CLEG: topPanel = new JPanel(new GridLayout(2, 0)); topPanel.add(clArmorField); topPanel.add(clArmorMaxLabel); clPanel.add(topPanel); bottomPanel = new JPanel(); bottomPanel.add(unallocatedPointsLabelPatchworkCl); bottomPanel.add(unallocatedPointsFieldCl); clPanel.add(bottomPanel); clPanel.setBorder(BorderFactory.createTitledBorder( null, getMech().getLocationAbbr(location), TitledBorder.TOP, TitledBorder.DEFAULT_POSITION)); clArmorModel.setStepSize(1); clArmorModel.setMinimum(0); break; } } } JPanel totalArmorPanel = new JPanel(); Vector<JTextField> valueFields = new Vector<JTextField>(); valueFields.add(valueUnallocatedArmor); valueFields.add(valueAllocatedArmor); valueFields.add(valueCurrentArmor); valueFields.add(valueMaxArmor); valueFields.add(valueWastedArmor); Dimension valueSize = new Dimension(45, 20); for (JTextField field : valueFields) { field.setEditable(false); field.setSize(valueSize); field.setPreferredSize(valueSize); field.setMinimumSize(valueSize); field.setMaximumSize(valueSize); field.setHorizontalAlignment(SwingConstants.RIGHT); } totalArmorPanel.setLayout(new GridBagLayout()); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.insets = new Insets(2, 2, 2, 2); gbc.anchor = GridBagConstraints.WEST; totalArmorPanel.add(Box.createVerticalStrut(18), gbc); gbc.gridy++; totalArmorPanel.add(lblUnallocatedArmor, gbc); gbc.gridx = 1; totalArmorPanel.add(valueUnallocatedArmor, gbc); gbc.gridx = 0; gbc.gridy++; totalArmorPanel.add(lblAllocatedArmor, gbc); gbc.gridx = 1; totalArmorPanel.add(valueAllocatedArmor, gbc); gbc.gridx = 0; gbc.gridy++; totalArmorPanel.add(lblCurrentArmor, gbc); gbc.gridx = 1; totalArmorPanel.add(valueCurrentArmor, gbc); gbc.gridx = 0; gbc.gridy++; totalArmorPanel.add(lblMaxArmor, gbc); gbc.gridx = 1; totalArmorPanel.add(valueMaxArmor, gbc); gbc.gridx = 0; gbc.gridy++; totalArmorPanel.add(lblWastedArmor, gbc); gbc.gridx = 1; totalArmorPanel.add(valueWastedArmor, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; gbc.anchor = GridBagConstraints.CENTER; totalArmorPanel.add(Box.createVerticalStrut(18), gbc); gbc.gridy++; totalArmorPanel.add(allocateArmorButton, gbc); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = mainPanelGridY; gbc.gridwidth = 5; gbc.fill = GridBagConstraints.NONE; gbc.anchor = GridBagConstraints.CENTER; mainPanel.add(totalArmorPanel, gbc); this.add(mainPanel); resetArmorPoints(); addAllListeners(); } private void addAllListeners() { allocateArmorButton.addActionListener(this); for (JSpinner spinner : armorFieldList) { spinner.addChangeListener(this); } } private void removeAllListeners() { allocateArmorButton.removeActionListener(this); for (JSpinner spinner : armorFieldList) { spinner.removeChangeListener(this); } } public void refresh() { removeAllListeners(); clPanel.setVisible(getMech() instanceof TripodMech); for (int location = 0; location < getMech().locations(); location++) { int maxArmor = getMech().getOInternal(location) * 2; int headMaxArmor = 9; if (getMech().isSuperHeavy()) { headMaxArmor = 12; } int rearArmor; switch (location) { case Mech.LOC_HEAD: hdArmorModel.setValue(Math.min(headMaxArmor, getMech().getArmor(location))); hdArmorModel.setMaximum(headMaxArmor); hdArmorMaxLabel.setText("max: "+headMaxArmor); break; case Mech.LOC_LARM: laArmorModel.setValue(Math.min(maxArmor, getMech().getArmor(location))); laArmorModel.setMaximum(maxArmor); laArmorMaxLabel.setText("max: " + Integer.toString(maxArmor)); break; case Mech.LOC_RARM: raArmorModel.setValue(Math.min(maxArmor, getMech().getArmor(location))); raArmorModel.setMaximum(maxArmor); raArmorMaxLabel.setText("max: " + Integer.toString(maxArmor)); break; case Mech.LOC_CT: ctArmorModel.setValue(Math.min(maxArmor, getMech().getArmor(location))); ctArmorModel.setMaximum(maxArmor); ctrArmorModel.setMaximum(maxArmor); rearArmor = Math.min(getMech().getArmor(location, true), maxArmor - getMech().getArmor(location)); ctrArmorModel.setValue(rearArmor); getMech().initializeRearArmor(rearArmor, location); ctArmorMaxLabel.setText("max: " + Integer.toString(maxArmor)); break; case Mech.LOC_LT: ltArmorModel.setValue(Math.min(maxArmor, getMech().getArmor(location))); ltArmorModel.setMaximum(maxArmor); ltrArmorModel.setMaximum(maxArmor); rearArmor = Math.min(getMech().getArmor(location, true), maxArmor - getMech().getArmor(location)); ltrArmorModel.setValue(rearArmor); getMech().initializeRearArmor(rearArmor, location); ltArmorMaxLabel.setText("max: " + Integer.toString(maxArmor)); break; case Mech.LOC_RT: rtArmorModel.setValue(Math.min(maxArmor, getMech().getArmor(location))); rtArmorModel.setMaximum(maxArmor); rtrArmorModel.setMaximum(maxArmor); rearArmor = Math.min(getMech().getArmor(location, true), maxArmor - getMech().getArmor(location)); rtrArmorModel.setValue(rearArmor); getMech().initializeRearArmor(rearArmor, location); rtArmorMaxLabel.setText("max: " + Integer.toString(maxArmor)); break; case Mech.LOC_LLEG: llArmorModel.setValue(Math.min(maxArmor, getMech().getArmor(location))); llArmorModel.setMaximum(maxArmor); llArmorMaxLabel.setText("max: " + Integer.toString(maxArmor)); break; case Mech.LOC_RLEG: rlArmorModel.setValue(Math.min(maxArmor, getMech().getArmor(location))); rlArmorModel.setMaximum(maxArmor); rlArmorMaxLabel.setText("max: " + Integer.toString(maxArmor)); break; case Mech.LOC_CLEG: clArmorModel.setValue(Math.min(maxArmor, getMech().getArmor(location))); clArmorModel.setMaximum(maxArmor); clArmorMaxLabel.setText("max: " + Integer.toString(maxArmor)); break; } } // unallocated armorpoints if (getMech().hasPatchworkArmor()) { valueUnallocatedArmor.setVisible(false); lblUnallocatedArmor.setVisible(false); valueAllocatedArmor.setVisible(false); lblAllocatedArmor.setVisible(false); valueWastedArmor.setVisible(false); lblWastedArmor.setVisible(false); allocateArmorButton.setVisible(false); unallocatedPointsLabelPatchworkHead.setVisible(true); unallocatedPointsLabelPatchworkLa.setVisible(true); unallocatedPointsLabelPatchworkLt.setVisible(true); unallocatedPointsLabelPatchworkCt.setVisible(true); unallocatedPointsLabelPatchworkRt.setVisible(true); unallocatedPointsLabelPatchworkRa.setVisible(true); unallocatedPointsLabelPatchworkLl.setVisible(true); unallocatedPointsLabelPatchworkRl.setVisible(true); unallocatedPointsFieldHead.setVisible(true); unallocatedPointsFieldLa.setVisible(true); unallocatedPointsFieldLt.setVisible(true); unallocatedPointsFieldCt.setVisible(true); unallocatedPointsFieldRt.setVisible(true); unallocatedPointsFieldRa.setVisible(true); unallocatedPointsFieldLl.setVisible(true); unallocatedPointsFieldRl.setVisible(true); unallocatedPointsFieldHead.setText(Integer.toString(UnitUtil .getArmorPoints(getMech(), Mech.LOC_HEAD, getMech().getArmorWeight(Mech.LOC_HEAD)) - getMech().getOArmor(Mech.LOC_HEAD))); unallocatedPointsFieldLa.setText(Integer.toString(UnitUtil .getArmorPoints(getMech(), Mech.LOC_LARM, getMech().getArmorWeight(Mech.LOC_LARM)) - getMech().getOArmor(Mech.LOC_LARM))); unallocatedPointsFieldLt.setText(Integer.toString(UnitUtil .getArmorPoints(getMech(), Mech.LOC_LT, getMech().getArmorWeight(Mech.LOC_LT)) - getMech().getOArmor(Mech.LOC_LT) - getMech().getOArmor(Mech.LOC_LT, true))); unallocatedPointsFieldCt.setText(Integer.toString(UnitUtil .getArmorPoints(getMech(), Mech.LOC_CT, getMech().getArmorWeight(Mech.LOC_CT)) - getMech().getOArmor(Mech.LOC_CT) - getMech().getOArmor(Mech.LOC_CT, true))); unallocatedPointsFieldRt.setText(Integer.toString(UnitUtil .getArmorPoints(getMech(), Mech.LOC_RT, getMech().getArmorWeight(Mech.LOC_RT)) - getMech().getOArmor(Mech.LOC_RT) - getMech().getOArmor(Mech.LOC_RT, true))); unallocatedPointsFieldRa.setText(Integer.toString(UnitUtil .getArmorPoints(getMech(), Mech.LOC_RARM, getMech().getArmorWeight(Mech.LOC_RARM)) - getMech().getOArmor(Mech.LOC_RARM))); unallocatedPointsFieldLl.setText(Integer.toString(UnitUtil .getArmorPoints(getMech(), Mech.LOC_LLEG, getMech().getArmorWeight(Mech.LOC_LLEG)) - getMech().getOArmor(Mech.LOC_LLEG))); unallocatedPointsFieldRl.setText(Integer.toString(UnitUtil .getArmorPoints(getMech(), Mech.LOC_RLEG, getMech().getArmorWeight(Mech.LOC_RLEG)) - getMech().getOArmor(Mech.LOC_RLEG))); if (getMech() instanceof TripodMech) { unallocatedPointsFieldCl.setVisible(true); unallocatedPointsFieldCl.setText(Integer.toString(UnitUtil .getArmorPoints(getMech(), Mech.LOC_CLEG, getMech().getArmorWeight(Mech.LOC_CLEG)) - getMech().getOArmor(Mech.LOC_CLEG))); } } else { valueUnallocatedArmor.setVisible(true); lblUnallocatedArmor.setVisible(true); valueAllocatedArmor.setVisible(true); lblAllocatedArmor.setVisible(true); allocateArmorButton.setVisible(true); valueWastedArmor.setVisible(true); lblWastedArmor.setVisible(true); unallocatedPointsLabelPatchworkHead.setVisible(false); unallocatedPointsLabelPatchworkLa.setVisible(false); unallocatedPointsLabelPatchworkLt.setVisible(false); unallocatedPointsLabelPatchworkCt.setVisible(false); unallocatedPointsLabelPatchworkRt.setVisible(false); unallocatedPointsLabelPatchworkRa.setVisible(false); unallocatedPointsLabelPatchworkLl.setVisible(false); unallocatedPointsLabelPatchworkRl.setVisible(false); unallocatedPointsFieldHead.setVisible(false); unallocatedPointsFieldLa.setVisible(false); unallocatedPointsFieldLt.setVisible(false); unallocatedPointsFieldCt.setVisible(false); unallocatedPointsFieldRt.setVisible(false); unallocatedPointsFieldRa.setVisible(false); unallocatedPointsFieldLl.setVisible(false); unallocatedPointsFieldRl.setVisible(false); if (getMech() instanceof TripodMech) { unallocatedPointsLabelPatchworkCl.setVisible(false); unallocatedPointsFieldCl.setVisible(false); } } valueAllocatedArmor.setText(Integer.toString(getMech().getTotalOArmor())); valueUnallocatedArmor.setText(Integer.toString(armorPoints - getMech().getTotalOArmor())); if (armorPoints != getMech().getTotalOArmor()) { valueUnallocatedArmor.setForeground(Color.RED); lblUnallocatedArmor.setForeground(Color.RED); } else { valueUnallocatedArmor.setForeground(Color.BLACK); lblUnallocatedArmor.setForeground(Color.BLACK); } valueCurrentArmor.setText(Integer.toString(armorPoints)); // Total Possible armor is Internal*2 +3 for the extra 3 armor the head // can support. int headArmor = 3; if (getMech().isSuperHeavy()) { headArmor = 4; } valueMaxArmor.setText(Integer.toString((getMech().getTotalOInternal() * 2) + headArmor)); valueWastedArmor.setText(Integer.toString(wastedArmorPoints)); addAllListeners(); } public void addRefreshedListener(RefreshListener l) { refresh = l; } public void allocateArmor() { double pointsToAllocate = armorPoints; int headPoints = 3; if (getMech().isSuperHeavy()) { headPoints = 4; } double totalArmor = (getMech().getTotalOInternal() * 2) + headPoints; if (pointsToAllocate > totalArmor) { pointsToAllocate = totalArmor; } double percent = pointsToAllocate / totalArmor; int headMaxArmor = 9; if (getMech().isSuperHeavy()) { headMaxArmor = 12; } // put 5 times the percentage of total possible armor into the head int headArmor = (int) Math.min(Math.floor(percent * headMaxArmor * 5), headMaxArmor); getMech().initializeArmor(headArmor, Mech.LOC_HEAD); pointsToAllocate -= headArmor; for (int location = 0; location < getMech().locations(); location++) { double IS = (getMech().getInternal(location) * 2); double allocate = Math.min(IS * percent, pointsToAllocate); switch (location) { case Mech.LOC_HEAD: break; case Mech.LOC_CT: case Mech.LOC_LT: case Mech.LOC_RT: double rear = Math.floor(allocate * .25); double front = Math.ceil(allocate * .75); pointsToAllocate -= (int) rear; pointsToAllocate -= (int) front; getMech().initializeArmor((int) front, location); getMech().initializeRearArmor((int) rear, location); break; default: getMech().initializeArmor((int) allocate, location); pointsToAllocate -= (int) allocate; break; } } allocateLeftoverPoints(pointsToAllocate); if (refresh != null) { refresh.refreshStatus(); } } /** * allocate any leftover points one-by-one * * @param points * the amount of points left over */ private void allocateLeftoverPoints(double points) { int headMaxArmor = 9; if (getMech().isSuperHeavy()) { headMaxArmor = 12; } while (points >= 1) { // if two or more are left, add armor to symmetrical locations, // to torso, legs, arms, in that order if (points >= 2) { if (((getMech().getOArmor(Mech.LOC_LT) + getMech().getOArmor(Mech.LOC_LT, true)) < (getMech().getOInternal(Mech.LOC_LT) * 2)) && ((getMech().getOArmor(Mech.LOC_RT) + getMech().getOArmor( Mech.LOC_RT, true)) < (getMech() .getOInternal(Mech.LOC_RT) * 2))) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_LT) + 1, Mech.LOC_LT); getMech().initializeArmor(getMech().getOArmor(Mech.LOC_RT) + 1, Mech.LOC_RT); points -= 2; } else if ((getMech().getOArmor(Mech.LOC_LLEG) < (getMech() .getOInternal(Mech.LOC_LLEG) * 2)) && (getMech().getOArmor(Mech.LOC_RLEG) < (getMech() .getOInternal(Mech.LOC_RLEG) * 2))) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_LLEG) + 1, Mech.LOC_LLEG); getMech().initializeArmor(getMech().getOArmor(Mech.LOC_RLEG) + 1, Mech.LOC_RLEG); points -= 2; } else if ((getMech().getOArmor(Mech.LOC_LARM) < (getMech() .getOInternal(Mech.LOC_LARM) * 2)) && (getMech().getOArmor(Mech.LOC_RARM) < (getMech() .getOInternal(Mech.LOC_RARM) * 2))) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_LARM) + 1, Mech.LOC_LARM); getMech().initializeArmor(getMech().getOArmor(Mech.LOC_RARM) + 1, Mech.LOC_RARM); points -= 2; } // otherwise, first add to the head, and then even out uneven // allocation } else if (getMech().getOArmor(Mech.LOC_HEAD) < headMaxArmor) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_HEAD) + 1, Mech.LOC_HEAD); points--; } else if (getMech().getOArmor(Mech.LOC_LT) < getMech() .getOArmor(Mech.LOC_RT)) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_LT) + 1, Mech.LOC_LT); points--; } else if (getMech().getOArmor(Mech.LOC_RT) < getMech() .getOArmor(Mech.LOC_LT)) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_RT) + 1, Mech.LOC_RT); points--; } else if (getMech().getOArmor(Mech.LOC_RARM) < getMech() .getOArmor(Mech.LOC_LARM)) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_RARM) + 1, Mech.LOC_RARM); points--; } else if (getMech().getOArmor(Mech.LOC_LARM) < getMech() .getOArmor(Mech.LOC_RARM)) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_LARM) + 1, Mech.LOC_LARM); points--; } else if (getMech().getOArmor(Mech.LOC_RLEG) < getMech() .getArmor(Mech.LOC_LLEG)) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_RLEG) + 1, Mech.LOC_RLEG); points--; } else if (getMech().getOArmor(Mech.LOC_LLEG) < getMech() .getOArmor(Mech.LOC_RLEG)) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_LLEG) + 1, Mech.LOC_LLEG); points--; // if nothing is uneven, add to the CT } else if (((getMech().getOArmor(Mech.LOC_CT) + getMech().getOArmor( Mech.LOC_CT, true)) < (getMech().getOInternal(Mech.LOC_CT) * 2))) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_CT) + 1, Mech.LOC_CT); points--; } // if only one is left, and head and CT have max, remove one from CT // so symmetric locations can get extra, unless they are already at // max if (points == 1) { if ((getMech().getOArmor(Mech.LOC_HEAD) == headMaxArmor) && ((getMech().getOArmor(Mech.LOC_CT) + getMech().getOArmor( Mech.LOC_CT, true)) == (getMech() .getOInternal(Mech.LOC_CT) * 2))) { getMech().initializeArmor(getMech().getOArmor(Mech.LOC_CT) - 1, Mech.LOC_CT); points++; } } // if all locations have max, return boolean toReturn = true; for (int location = 0; location < getMech().locations(); location++) { double is = (getMech().getInternal(location) * 2); switch (location) { case Mech.LOC_HEAD: int headPoints = 3; if (getMech().isSuperHeavy()) { headPoints = 4; } if ((is + headPoints) > getMech().getOArmor(location)) { toReturn = false; } break; case Mech.LOC_CT: case Mech.LOC_LT: case Mech.LOC_RT: if (is > (getMech().getOArmor(location) + getMech().getOArmor( location, true))) { toReturn = false; } break; default: if (is > getMech().getOArmor(location)) { toReturn = false; } break; } } if (toReturn) { return; } } } public void stateChanged(ChangeEvent e) { removeAllListeners(); int allowedArmorPoints = armorPoints; if (getMech().hasPatchworkArmor()) { allowedArmorPoints = UnitUtil.getMaximumArmorPoints(getMech()); } JSpinner field = (JSpinner) e.getSource(); boolean isRear = field.equals(ctrArmorField) || field.equals(ltrArmorField) || field.equals(rtrArmorField); int location = Integer.parseInt(field.getName()); int maxArmor = getMech().getOInternal(location) * 2; int value = (Integer) field.getModel().getValue(); // How much armor do we have without the value that was just changed int totalArmor = 0; for (int loc = 0; loc < getMech().locations(); loc++) { if (loc != location) { totalArmor += getMech().getOArmor(loc); if (getMech().hasRearArmor(loc)) { totalArmor += getMech().getOArmor(loc, true); } } else if ((loc == location) && getMech().hasRearArmor(loc)) { totalArmor += getMech().getOArmor(loc, !isRear); } } // Do we have enough armor points to make this change? if ((allowedArmorPoints - (totalArmor + value)) < 0) { // See if we can pull armor from the opposite location if (getMech().hasRearArmor(location) && getMech().getOArmor(location,!isRear) > 0) { stealArmorFromOppositeSide(location, isRear); } else { // If we can't pull armor, just revert the change and end field.setValue(value - 1); addAllListeners(); return; } } // If this change would put us over the per-location total, may have to // steal a point from the other side if (getMech().hasRearArmor(location) && ((value + getMech().getOArmor(location, !isRear)) > maxArmor)) { stealArmorFromOppositeSide(location, isRear); } // Update armor in the changed location switch (location) { case Mech.LOC_CT: if (isRear) { getMech().initializeRearArmor(value, location); } else { getMech().initializeArmor(value, location); } break; case Mech.LOC_RT: if (isRear) { getMech().initializeRearArmor(value, location); } else { getMech().initializeArmor(value, location); } break; case Mech.LOC_LT: if (isRear) { getMech().initializeRearArmor(value, location); } else { getMech().initializeArmor(value, location); } break; default: getMech().initializeArmor(value, location); break; } if (getMech().hasPatchworkArmor()) { setArmorPoints(getMech().getTotalArmor()); } if (refresh != null) { addAllListeners(); refresh.refreshStructure(); removeAllListeners(); refresh.refreshStatus(); } addAllListeners(); } /** * Given a location and whether it's rear or not, take a point of armor from * the opposite side. That is, given a rear CT location, reduce the front * CT by 1 point of armor. * * @param location * @param isRear */ private void stealArmorFromOppositeSide(int location, boolean isRear) { JSpinner opposite = getOppositeSpinner(location, isRear); int oppositeValue = (Integer)opposite.getValue(); // "Steal" armor from the opposite side oppositeValue--; opposite.setValue(oppositeValue); // Make sure the Unit reflects the armor update if (!isRear) { getMech().initializeRearArmor(oppositeValue, location); } else { getMech().initializeArmor(oppositeValue, location); } } /** * For swapping armor between front and rear locations, we need to get the * JSpinner that correspondes to the opposite side of a location. Ie, if * we are given the front CT, return the rear CT JSpinner. * * @param location * @param isRear * @return */ private JSpinner getOppositeSpinner(int location, boolean isRear) { JSpinner opposite; switch (location) { case Mech.LOC_CT: if (isRear) { opposite = ctArmorField; } else { opposite = ctrArmorField; } break; case Mech.LOC_LT: if (isRear) { opposite = ltArmorField; } else { opposite = ltrArmorField; } break; case Mech.LOC_RT: if (isRear) { opposite = rtArmorField; } else { opposite = rtrArmorField; } break; default : opposite = null; } return opposite; } public void setArmorPoints(int points) { int headPoints = 3; if (getMech().isSuperHeavy()) { headPoints = 4; } int maxArmor = (getMech().getTotalOInternal() * 2) + headPoints; wastedArmorPoints = Math.max(points - maxArmor, 0); armorPoints = Math.min(maxArmor, points); } @Override public void actionPerformed(ActionEvent e) { removeAllListeners(); if (e.getSource().equals(allocateArmorButton)) { allocateArmor(); } addAllListeners(); refresh.refreshAll(); } public void resetArmorPoints() { double armorPerTon = 16.0 * EquipmentType.getArmorPointMultiplier( getMech().getArmorType(0), getMech().getArmorTechLevel(0)); setArmorPoints((int) Math .floor(getMech().getLabArmorTonnage() * armorPerTon)); } }