Skip to content

Commit

Permalink
Merge pull request #1396 from SJuliez/ci-am-gear
Browse files Browse the repository at this point in the history
CI Anti-Mek Gear
  • Loading branch information
HammerGS authored Jan 28, 2024
2 parents 3e338f0 + 66d6517 commit c98cca0
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 22 deletions.
2 changes: 1 addition & 1 deletion megameklab/resources/megameklab/resources/Views.properties
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ InfantryWeaponView.cbNumSecondary.text=# Secondary:
InfantryWeaponView.cbNumSecondary.tooltip=The number of secondary weapons per squad. Limited by the weapon's crew rating.
InfantryWeaponView.cbNumGuns.text=# Field Guns:
InfantryWeaponView.cbNumGuns.tooltip=The number of field guns deployed by the unit. Limited by platoon size and gun tonnage. Artillery is limited to one weapon per platoon.
InfantryWeaponView.chkAntiMek.text=Anti-Mek Training:
InfantryWeaponView.chkAntiMek.text=Anti-Mek Gear:
InfantryWeaponView.chkAntiMek.tooltip=A unit with anti-mek training has a higher platoon tonnage due to special equipment.

CIMountView.colType=Creature Type
Expand Down
84 changes: 84 additions & 0 deletions megameklab/src/megameklab/ui/generalUnit/ClickableLabel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2024 - The MegaMek Team. All Rights Reserved.
*
* This file is part of MegaMekLab.
*
* MegaMek 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 3 of the License, or
* (at your option) any later version.
*
* MegaMek is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MegaMek. If not, see <http://www.gnu.org/licenses/>.
*/
package megameklab.ui.generalUnit;

import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Objects;
import java.util.function.Consumer;

/**
* This is a specialized label for {@link StatusBar} that calls a callback method
* when it is clicked and shows its text underlined while hovered.
*/
class ClickableLabel extends JLabel implements MouseListener {

private static final String HOVERED_PREFIX = "<HTML><U>";
private static final String NON_HOVERED_PREFIX = "<HTML>";
private boolean isHovered = false;
private String baseText = "";
private final Consumer<MouseEvent> clickCallback;

/**
* Creates a new clickable label. The given callback method is called when the
* label is mouse-clicked.
*
* @param clickCallback The method to call when the label is clicked
*/
ClickableLabel(Consumer<MouseEvent> clickCallback) {
this.clickCallback = Objects.requireNonNull(clickCallback);
addMouseListener(this);
}

@Override
public void setText(String text) {
baseText = text;
updateText();
}

private void updateText() {
super.setText((isHovered ? HOVERED_PREFIX : NON_HOVERED_PREFIX) + baseText);
}

@Override
public void mouseClicked(MouseEvent e) {
clickCallback.accept(e);
}

@Override
public void mousePressed(MouseEvent e) {
}

@Override
public void mouseReleased(MouseEvent e) {
}

@Override
public void mouseEntered(MouseEvent e) {
isHovered = true;
updateText();
}

@Override
public void mouseExited(MouseEvent e) {
isHovered = false;
updateText();
}
}
21 changes: 14 additions & 7 deletions megameklab/src/megameklab/ui/generalUnit/StatusBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
package megameklab.ui.generalUnit;

import megamek.client.ui.WrapLayout;
import megamek.client.ui.dialogs.BVDisplayDialog;
import megamek.client.ui.dialogs.CostDisplayDialog;
import megamek.client.ui.dialogs.WeightDisplayDialog;
import megamek.client.ui.swing.GUIPreferences;
import megamek.client.ui.swing.calculationReport.CalculationReport;
import megamek.common.*;
Expand All @@ -40,9 +43,12 @@ public class StatusBar extends ITab {
private static final String WEIGHT_LABEL = "Weight: %s %s / %s %s %s";

private final MegaMekLabMainUI parentFrame;
private final JLabel bvLabel = new JLabel();
protected final JLabel tons = new JLabel();
private final JLabel cost = new JLabel();
private final JLabel bvLabel = new ClickableLabel(
e -> new BVDisplayDialog(getParentFrame(), getEntity()).setVisible(true));
protected final JLabel tons = new ClickableLabel(
e -> new WeightDisplayDialog(getParentFrame(), getEntity()).setVisible(true));
private final JLabel cost = new ClickableLabel(
e -> new CostDisplayDialog(getParentFrame(), getEntity()).setVisible(true));
private final JLabel invalid = new JLabel("Invalid");
private final DecimalFormat formatter;
private TestEntity testEntity;
Expand Down Expand Up @@ -119,21 +125,22 @@ protected void refreshWeight() {
remaining = Math.round((tonnage - currentTonnage) * 1000) + "";
}
String remainingText = ((currentTonnage < tonnage) ? " (" + remaining + " " + unit + " Remaining)" : "");
tons.setText(String.format(WEIGHT_LABEL, current, unit, full, unit, remainingText));
tons.setToolTipText("Current Weight / Max Weight (Remaining Weight, if any)");
tons.setText(String.format(WEIGHT_LABEL, current, unit, full, unit, remainingText).trim());
tons.setToolTipText("Current Weight / Max Weight (Remaining Weight, if any). Click to show the weight calculation.");
tons.setForeground((currentTonnage > tonnage) ? GUIPreferences.getInstance().getWarningColor() : null);
}

private void refreshBV() {
int bv = getEntity().calculateBattleValue();
bvLabel.setText("BV: " + bv);
bvLabel.setToolTipText("Battle Value 2.0");
bvLabel.setToolTipText("Battle Value 2.0. Click to show the BV calculation.");
}

private void refreshCost() {
cost.setText("Dry Cost: " + formatter.format(Math.round(getEntity().getCost(true))) + " C-bills");
cost.setToolTipText("The dry cost of the unit (without ammo). The unit's full cost is "
+ formatter.format(Math.round(getEntity().getCost(false))) + " C-bills.");
+ formatter.format(Math.round(getEntity().getCost(false))) + " C-bills. "
+ "Click to show the cost calculation.");
}

private void refreshInvalid() {
Expand Down
1 change: 1 addition & 0 deletions megameklab/src/megameklab/ui/infantry/CIStatusBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@ protected void refreshWeight() {
double tonnage = getEntity().getWeight();
String full = CalculationReport.formatForReport(tonnage);
tons.setText(String.format(INF_WEIGHT_LABEL, full));
tons.setToolTipText("Click to show the weight calculation.");
}
}
19 changes: 14 additions & 5 deletions megameklab/src/megameklab/ui/infantry/CIStructureTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import megamek.common.*;
import megamek.common.options.IOption;
import megamek.common.options.PilotOptions;
import megamek.common.verifier.TestInfantry;
import megamek.common.weapons.infantry.InfantryWeapon;
import megameklab.ui.EntitySource;
import megameklab.ui.generalUnit.BasicInfoView;
Expand All @@ -56,7 +57,7 @@ public class CIStructureTab extends ITab implements InfantryBuildListener {
public static final int T_SPECIALIZATION = 3;
public static final int T_MOUNT = 4;
public static final int T_AUGMENTATION = 5;

private static final EquipmentType antiMekGear = EquipmentType.get(EquipmentTypeLookup.ANTI_MEK_GEAR);

private BasicInfoView panBasicInfo;
private CIPlatoonTypeView panPlatoonType;
Expand Down Expand Up @@ -171,9 +172,7 @@ public ITechManager getTechManager() {
return panBasicInfo;
}

/*
* Used by MekHQ to set the tech faction for custom refits.
*/
@SuppressWarnings("unused") // used by MekHQ to set the tech faction for custom refits
public void setTechFaction(int techFaction) {
panBasicInfo.setTechFaction(techFaction);
}
Expand Down Expand Up @@ -412,6 +411,7 @@ && getInfantry().getMovementMode() != EntityMovementMode.WHEELED) {
InfantryUtil.replaceFieldGun(getInfantry(), null, 0);
}
enableTabs();
TestInfantry.adaptAntiMekAttacks(getInfantry());
panPlatoonType.setFromEntity(getInfantry());
panWeapons.setFromEntity(getInfantry());
specializationView.refresh();
Expand Down Expand Up @@ -469,7 +469,16 @@ public void numFieldGunsChanged(final int count) {

@Override
public void antiMekChanged(final boolean antiMek) {
getInfantry().setAntiMekSkill(antiMek);
if (antiMek) {
try {
getInfantry().addEquipment(antiMekGear, Infantry.LOC_INFANTRY);
} catch (LocationFullException ignored) {
// Not on infantry
}
} else {
UnitUtil.removeAllMounteds(getInfantry(), antiMekGear);
}
TestInfantry.adaptAntiMekAttacks(getInfantry());
refresh.refreshStatus();
}

Expand Down
12 changes: 3 additions & 9 deletions megameklab/src/megameklab/ui/infantry/CIWeaponView.java
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,9 @@ public void setFromEntity(Infantry inf) {
cbNumGuns.setEnabled(false);
}

if (!inf.isMechanized() && techManager.isLegal(Infantry.getAntiMekTA())) {
chkAntiMek.setEnabled(true);
chkAntiMek.removeActionListener(this);
chkAntiMek.setSelected(inf.isAntiMekTrained());
chkAntiMek.addActionListener(this);
} else {
chkAntiMek.setEnabled(false);
chkAntiMek.setSelected(false);
}
chkAntiMek.removeActionListener(this);
chkAntiMek.setSelected(inf.hasAntiMekGear());
chkAntiMek.addActionListener(this);
}

@Override
Expand Down

0 comments on commit c98cca0

Please sign in to comment.