protected void spendXP() {
    String skillName = (String) choiceSkill.getSelectedItem();
    if (choiceNoSkill.equals(skillName)) {
      // This shouldn't happen, but guard against it anyway.
      return;
    }
    int rows = personnelTable.getRowCount();
    int improvedPersonnelCount = rows;
    while (rows > 0) {
      for (int i = 0; i < rows; ++i) {
        Person p = personnelModel.getPerson(personnelTable.convertRowIndexToModel(i));
        int cost = 0;
        if (p.hasSkill(skillName)) {
          cost = p.getCostToImprove(skillName);
        } else {
          cost = SkillType.getType(skillName).getCost(0);
        }
        int experience = p.getExperienceLevel(false);

        // Improve the skill and deduce the cost
        p.improveSkill(skillName);
        campaign.personUpdated(p);
        p.setXp(p.getXp() - cost);

        // The next part is bollocks and doesn't belong here, but as long as we hardcode AtB ...
        if (campaign.getCampaignOptions().getUseAtB()) {
          if ((p.getPrimaryRole() > Person.T_NONE)
              && (p.getPrimaryRole() <= Person.T_CONV_PILOT)
              && (p.getExperienceLevel(false) > experience)
              && (experience >= SkillType.EXP_REGULAR)) {
            String spa = campaign.rollSPA(p.getPrimaryRole(), p);
            if (null == spa) {
              if (campaign.getCampaignOptions().useEdge()) {
                p.acquireAbility(
                    PilotOptions.EDGE_ADVANTAGES, "edge", p.getEdge() + 1); // $NON-NLS-1$
                p.addLogEntry(
                    campaign.getDate(),
                    String.format(resourceMap.getString("gainedEdge.text"))); // $NON-NLS-1$
              }
            } else {
              p.addLogEntry(
                  campaign.getDate(),
                  String.format(resourceMap.getString("gained.format"), spa)); // $NON-NLS-1$
            }
          }
        }
      }
      // Refresh the filter and continue if we still have anyone available
      updatePersonnelTable();
      rows = personnelTable.getRowCount();
      dataChanged = true;
    }
    if (improvedPersonnelCount > 0) {
      campaign.addReport(
          String.format(
              resourceMap.getString("improvedSkills.format"),
              skillName,
              improvedPersonnelCount)); //$NON-NLS-1$
    }
  }
 private long getTrueBuyCost(IAcquisitionWork item, Campaign campaign) {
   long cost = Long.MIN_VALUE;
   if ((item instanceof UnitOrder && campaign.getCampaignOptions().payForUnits())
       || (item instanceof Part && campaign.getCampaignOptions().payForParts())) {
     cost = item.getBuyCost();
   }
   return cost;
 }
 public OptionsChangedEvent(Campaign campaign) {
   this(campaign, campaign.getCampaignOptions());
 }
  private void initComponents() {

    ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.PartsStoreDialog");
    setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
    setName("Form"); // NOI18N
    setTitle(resourceMap.getString("Form.title"));

    getContentPane().setLayout(new BorderLayout());

    partsTable = new JTable(partsModel);
    partsTable.setName("partsTable"); // NOI18N
    partsSorter = new TableRowSorter<PartsTableModel>(partsModel);
    partsSorter.setComparator(PartsTableModel.COL_TARGET, new TargetSorter());
    partsSorter.setComparator(PartsTableModel.COL_COST, new FormattedNumberSorter());
    partsSorter.setComparator(PartsTableModel.COL_DETAIL, new PartsDetailSorter());
    partsTable.setRowSorter(partsSorter);
    TableColumn column = null;
    for (int i = 0; i < PartsTableModel.N_COL; i++) {
      column = partsTable.getColumnModel().getColumn(i);
      column.setPreferredWidth(partsModel.getColumnWidth(i));
      column.setCellRenderer(partsModel.getRenderer());
    }
    partsTable.setIntercellSpacing(new Dimension(0, 0));
    partsTable.setShowGrid(false);
    scrollPartsTable = new JScrollPane();
    scrollPartsTable.setName("scrollPartsTable"); // NOI18N
    scrollPartsTable.setViewportView(partsTable);
    getContentPane().add(scrollPartsTable, BorderLayout.CENTER);

    GridBagConstraints c = new GridBagConstraints();
    panFilter = new JPanel();
    lblPartsChoice = new JLabel(resourceMap.getString("lblPartsChoice.text")); // NOI18N
    DefaultComboBoxModel<String> partsGroupModel = new DefaultComboBoxModel<String>();
    for (int i = 0; i < SG_NUM; i++) {
      partsGroupModel.addElement(getPartsGroupName(i));
    }
    choiceParts = new JComboBox<String>(partsGroupModel);
    choiceParts.setName("choiceParts"); // NOI18N
    choiceParts.setSelectedIndex(0);
    choiceParts.addActionListener(
        new java.awt.event.ActionListener() {
          public void actionPerformed(java.awt.event.ActionEvent evt) {
            filterParts();
          }
        });
    panFilter.setLayout(new GridBagLayout());
    c.gridx = 0;
    c.gridy = 0;
    c.weightx = 0.0;
    c.anchor = java.awt.GridBagConstraints.WEST;
    c.insets = new Insets(5, 5, 5, 5);
    panFilter.add(lblPartsChoice, c);
    c.gridx = 1;
    c.weightx = 1.0;
    panFilter.add(choiceParts, c);

    lblFilter = new JLabel(resourceMap.getString("lblFilter.text")); // NOI18N
    lblFilter.setName("lblFilter"); // NOI18N
    c.gridx = 0;
    c.gridy = 1;
    c.weightx = 0.0;
    panFilter.add(lblFilter, c);
    txtFilter = new javax.swing.JTextField();
    txtFilter.setText(""); // NOI18N
    txtFilter.setMinimumSize(new java.awt.Dimension(200, 28));
    txtFilter.setName("txtFilter"); // NOI18N
    txtFilter.setPreferredSize(new java.awt.Dimension(200, 28));
    txtFilter
        .getDocument()
        .addDocumentListener(
            new DocumentListener() {
              public void changedUpdate(DocumentEvent e) {
                filterParts();
              }

              public void insertUpdate(DocumentEvent e) {
                filterParts();
              }

              public void removeUpdate(DocumentEvent e) {
                filterParts();
              }
            });
    c.gridx = 1;
    c.gridy = 1;
    c.weightx = 1.0;
    panFilter.add(txtFilter, c);
    getContentPane().add(panFilter, BorderLayout.PAGE_START);

    panButtons = new JPanel();
    if (addToCampaign) {
      btnAdd = new JButton(resourceMap.getString("btnAdd.text"));
      btnAdd.addActionListener(
          new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
              addPart(false, false);
            }
          });
      btnAdd.setEnabled(campaign.isGM());
      btnBuyBulk = new JButton(resourceMap.getString("btnBuyBulk.text"));
      btnBuyBulk.addActionListener(
          new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
              addPart(true, true);
              partsModel.fireTableCellUpdated(
                  partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                  PartsTableModel.COL_TARGET);
              partsModel.fireTableCellUpdated(
                  partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                  PartsTableModel.COL_TRANSIT);
              partsModel.fireTableCellUpdated(
                  partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                  PartsTableModel.COL_SUPPLY);
              partsModel.fireTableCellUpdated(
                  partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                  PartsTableModel.COL_QUEUE);
            }
          });
      btnBuy = new JButton(resourceMap.getString("btnBuy.text"));
      btnBuy.addActionListener(
          new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
              addPart(true, false);
              partsModel.fireTableCellUpdated(
                  partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                  PartsTableModel.COL_TARGET);
              partsModel.fireTableCellUpdated(
                  partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                  PartsTableModel.COL_TRANSIT);
              partsModel.fireTableCellUpdated(
                  partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                  PartsTableModel.COL_SUPPLY);
              partsModel.fireTableCellUpdated(
                  partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                  PartsTableModel.COL_QUEUE);
            }
          });
      btnUseBonusPart = new JButton();
      if (campaign.getCampaignOptions().getUseAtB()) {
        int numBonusParts = campaign.totalBonusParts();
        btnUseBonusPart.setText("Use Bonus Part (" + numBonusParts + ")");
        btnUseBonusPart.addActionListener(
            new java.awt.event.ActionListener() {
              public void actionPerformed(java.awt.event.ActionEvent evt) {
                addPart(true, false, true);
                partsModel.fireTableCellUpdated(
                    partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                    PartsTableModel.COL_TARGET);
                partsModel.fireTableCellUpdated(
                    partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                    PartsTableModel.COL_TRANSIT);
                partsModel.fireTableCellUpdated(
                    partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                    PartsTableModel.COL_SUPPLY);
                partsModel.fireTableCellUpdated(
                    partsTable.convertRowIndexToModel(partsTable.getSelectedRow()),
                    PartsTableModel.COL_QUEUE);
                int numBonusParts = campaign.totalBonusParts();
                btnUseBonusPart.setText("Use Bonus Part (" + numBonusParts + ")");
                btnUseBonusPart.setVisible(numBonusParts > 0);
              }
            });
        btnUseBonusPart.setVisible(numBonusParts > 0);
      }
      btnClose = new JButton(resourceMap.getString("btnClose.text"));
      btnClose.addActionListener(
          new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
              setVisible(false);
            }
          });
      panButtons.setLayout(new GridBagLayout());
      panButtons.add(btnBuyBulk, new GridBagConstraints());
      panButtons.add(btnBuy, new GridBagConstraints());
      if (campaign.getCampaignOptions().getUseAtB()) {
        panButtons.add(btnUseBonusPart, new GridBagConstraints());
      }
      panButtons.add(btnAdd, new GridBagConstraints());
      panButtons.add(btnClose, new GridBagConstraints());
    } else {
      // if we arent adding the unit to the campaign, then different buttons
      btnAdd = new JButton("Add");
      btnAdd.addActionListener(
          new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
              setSelectedPart();
              setVisible(false);
            }
          });
      panButtons.add(btnAdd, new GridBagConstraints());

      btnClose = new JButton("Cancel"); // NOI18N
      btnClose.addActionListener(
          new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
              selectedPart = null;
              setVisible(false);
            }
          });
      panButtons.add(btnClose, new GridBagConstraints());
    }
    getContentPane().add(panButtons, BorderLayout.PAGE_END);
    this.setPreferredSize(new Dimension(700, 600));
    pack();
  }