Skip to content

Commit

Permalink
Merge pull request #4149 from IllianiCBT/stratCon_BonusPartConversion
Browse files Browse the repository at this point in the history
Added Automatic Bonus Parts Exchange at Contract End, Added Bonus Parts Display to Mission Stats Panel
  • Loading branch information
SJuliez authored Jun 8, 2024
2 parents c523ce4 + 36709f2 commit 2628f7f
Show file tree
Hide file tree
Showing 24 changed files with 190 additions and 42 deletions.
4 changes: 3 additions & 1 deletion MekHQ/resources/mekhq/resources/CampaignGUI.properties
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,6 @@ lblFacilityCapacities.text=<html><nobr><b>Facility Capacities:</b></nobr></html>
panLog.title=Daily Activity Log

dialogCheckDueScenarios.text=You must complete scenarios with a date of today or earlier before advancing the day.
dialogCheckDueScenarios.title=Scenarios Must Be Completed
dialogCheckDueScenarios.title=Scenarios Must Be Completed

spareBonusPartExchange.text=Bonus Part Exchange Program
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,10 @@ chkGenerateChases.text=Generate Chase Scenarios
chkGenerateChases.toolTipText=If selected, AtB chase scenarios will be generated. Otherwise, they will be replaced with other scenarios formats depending on the lance role in question.
chkRestrictPartsByMission.text=Restrict parts by mission
chkRestrictPartsByMission.toolTipText=The availability of parts is limited based on the mission type of the current contract.
lblBonusPartExchangeValue.text=Bonus Part Exchange Value
lblBonusPartExchangeValue.toolTipText=At the end of an AtB Contract, any remaining Bonus Parts are converted into c-bills. This setting sets the value of each Bonus Part. Set to 0 to disable Bonus Part exchange.
lblBonusPartMaxExchangeCount.text=Bonus Part Maximum Exchange Count
lblBonusPartMaxExchangeCount.toolTipText=What is the maximum number of Bonus Parts that can be exchanged for c-bills at the end of an AtB Contract? Any Bonus Parts beyond this are lost. Set to 0 to apply no limit.
chkRegionalMechVariations.text=Varied weight distributions by faction
chkRegionalMechVariations.toolTipText=Use alternate weight class distributions for some factions.
chkAttachedPlayerCamouflage.text=Player-controlled allied units use player's camouflage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ lblAllyRating.text=<html><nobr><b>Ally Rating:</b></nobr></html>
lblEnemyRating.text=<html><nobr><b>Enemy Rating:</b></nobr></html>
lblMorale.text=<html><nobr><b>Enemy Morale:</b></nobr></html>
lblScore.text=<html><nobr><b>Contract Score:</b></nobr></html>
lblBonusParts.text=<html><nobr><b>Bonus Parts:</b></nobr></html>
lblDistance.text=<html><nobr><b>Days (Jumps) to Location:</b></nobr></html>
lblOverhead.text=<html><nobr><b>Overhead Compensation:</b></nobr></html>
lblSupport.text=<html><nobr><b>StraightSupport:</b></nobr></html>
Expand Down
2 changes: 2 additions & 0 deletions MekHQ/resources/mekhq/resources/Finances.properties
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ TransactionType.UNIT_PURCHASE.text=Unit Purchase(s)
TransactionType.UNIT_PURCHASE.toolTipText=A financial transaction where a unit was or multiple units were purchased.
TransactionType.UNIT_SALE.text=Unit Sale(s)
TransactionType.UNIT_SALE.toolTipText=A financial transaction where a unit was or multiple units were sold.
TransactionType.BONUS_EXCHANGE.text=Bonus Exchange
TransactionType.BONUS_EXCHANGE.toolTipText=A financial transaction where Bonus Parts were exchanged for c-bills.

## Finances Files
# Peacetime Operating Costs
Expand Down
6 changes: 5 additions & 1 deletion MekHQ/src/mekhq/campaign/Campaign.java
Original file line number Diff line number Diff line change
Expand Up @@ -658,12 +658,14 @@ public void purchaseShipSearchResult() {
}

MechFileParser mechFileParser;

try {
mechFileParser = new MechFileParser(ms.getSourceFile(), ms.getEntryName());
} catch (Exception ex) {
LogManager.getLogger().error("Unable to load unit: " + ms.getEntryName(), ex);
LogManager.getLogger().error("Unable to load unit: {}", ms.getEntryName(), ex);
return;
}

Entity en = mechFileParser.getEntity();

int transitDays = getCampaignOptions().isInstantUnitMarketDelivery() ? 0
Expand Down Expand Up @@ -1229,6 +1231,7 @@ public Unit addNewUnit(Entity en, boolean allowNewPilots, int days, int quality)
if (!unit.isRepairable()) {
unit.setSalvage(true);
}

unit.setDaysToArrival(days);

if (allowNewPilots) {
Expand All @@ -1237,6 +1240,7 @@ public Unit addNewUnit(Entity en, boolean allowNewPilots, int days, int quality)
newCrew.forEach((type, personnel) ->
personnel.forEach(p -> type.getAddMethod().accept(unit, p)));
}

unit.resetPilotAndEntity();

unit.setQuality(quality);
Expand Down
26 changes: 26 additions & 0 deletions MekHQ/src/mekhq/campaign/CampaignOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,8 @@ public static String getTransitUnitName(final int unit) {
// Contract Operations
private boolean mercSizeLimited;
private boolean restrictPartsByMission;
private int bonusPartExchangeValue = 500000;
private int bonusPartMaxExchangeCount = 10;
private boolean limitLanceWeight;
private boolean limitLanceNumUnits;
private boolean useStrategy;
Expand Down Expand Up @@ -1164,6 +1166,8 @@ public CampaignOptions() {
// Contract Operations
mercSizeLimited = false;
restrictPartsByMission = true;
bonusPartExchangeValue = 500000;
bonusPartMaxExchangeCount = 10;
limitLanceWeight = true;
limitLanceNumUnits = true;
useStrategy = true;
Expand Down Expand Up @@ -4363,6 +4367,22 @@ public void setRestrictPartsByMission(final boolean restrictPartsByMission) {
this.restrictPartsByMission = restrictPartsByMission;
}

public int getBonusPartExchangeValue() {
return bonusPartExchangeValue;
}

public void setBonusPartExchangeValue(final int bonusPartExchangeValue) {
this.bonusPartExchangeValue = bonusPartExchangeValue;
}

public int getBonusPartMaxExchangeCount() {
return bonusPartMaxExchangeCount;
}

public void setBonusPartMaxExchangeCount(final int bonusPartMaxExchangeCount) {
this.bonusPartMaxExchangeCount = bonusPartMaxExchangeCount;
}

public boolean isLimitLanceWeight() {
return limitLanceWeight;
}
Expand Down Expand Up @@ -4914,6 +4934,8 @@ public void writeToXml(final PrintWriter pw, int indent) {
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "additionalStrategyDeployment", additionalStrategyDeployment);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "adjustPaymentForStrategy", adjustPaymentForStrategy);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "restrictPartsByMission", restrictPartsByMission);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "bonusPartExchangeValue", bonusPartExchangeValue);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "bonusPartMaxExchangeCount", bonusPartMaxExchangeCount);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "limitLanceWeight", limitLanceWeight);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "limitLanceNumUnits", limitLanceNumUnits);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "assignPortraitOnRoleChange", assignPortraitOnRoleChange);
Expand Down Expand Up @@ -5934,6 +5956,10 @@ public static CampaignOptions generateCampaignOptionsFromXml(Node wn, Version ve
retVal.adjustPaymentForStrategy = Boolean.parseBoolean(wn2.getTextContent().trim());
} else if (wn2.getNodeName().equalsIgnoreCase("restrictPartsByMission")) {
retVal.restrictPartsByMission = Boolean.parseBoolean(wn2.getTextContent().trim());
} else if (wn2.getNodeName().equalsIgnoreCase("bonusPartExchangeValue")) {
retVal.bonusPartExchangeValue = Integer.parseInt(wn2.getTextContent().trim());
} else if (wn2.getNodeName().equalsIgnoreCase("bonusPartMaxExchangeCount")) {
retVal.bonusPartMaxExchangeCount = Integer.parseInt(wn2.getTextContent().trim());
} else if (wn2.getNodeName().equalsIgnoreCase("limitLanceWeight")) {
retVal.limitLanceWeight = Boolean.parseBoolean(wn2.getTextContent().trim());
} else if (wn2.getNodeName().equalsIgnoreCase("limitLanceNumUnits")) {
Expand Down
4 changes: 2 additions & 2 deletions MekHQ/src/mekhq/campaign/Quartermaster.java
Original file line number Diff line number Diff line change
Expand Up @@ -470,13 +470,13 @@ public boolean buyUnit(Entity en, int days) {
Money cost = new Unit(en, getCampaign()).getBuyCost();
if (getCampaign().getFinances().debit(TransactionType.UNIT_PURCHASE, getCampaign().getLocalDate(),
cost, "Purchased " + en.getShortName())) {
getCampaign().addNewUnit(en, false, days);
getCampaign().addNewUnit(en, false, days, 3);
return true;
} else {
return false;
}
} else {
getCampaign().addNewUnit(en, false, days);
getCampaign().addNewUnit(en, false, days, 3);
return true;
}
}
Expand Down
9 changes: 8 additions & 1 deletion MekHQ/src/mekhq/campaign/finances/enums/TransactionType.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public enum TransactionType {
THEFT("TransactionType.THEFT.text", "TransactionType.THEFT.toolTipText"),
TRANSPORTATION("TransactionType.TRANSPORTATION.text", "TransactionType.TRANSPORTATION.toolTipText"),
UNIT_PURCHASE("TransactionType.UNIT_PURCHASE.text", "TransactionType.UNIT_PURCHASE.toolTipText"),
UNIT_SALE("TransactionType.UNIT_SALE.text", "TransactionType.UNIT_SALE.toolTipText");
UNIT_SALE("TransactionType.UNIT_SALE.text", "TransactionType.UNIT_SALE.toolTipText"),
BONUS_EXCHANGE("TransactionType.BONUS_EXCHANGE.text", "TransactionType.BONUS_EXCHANGE.toolTipText");
//endregion Enum Declarations

//region Variable Declarations
Expand Down Expand Up @@ -187,6 +188,10 @@ public boolean isUnitPurchase() {
public boolean isUnitSale() {
return this == UNIT_SALE;
}

public boolean isBonusExchange() {
return this == BONUS_EXCHANGE;
}
//endregion Boolean Comparison Methods

//region File I/O
Expand Down Expand Up @@ -246,6 +251,8 @@ public static TransactionType parseFromString(final String text) {
return PAYOUT;
case 20:
return TAXES;
case 21:
return BONUS_EXCHANGE;
default:
break;
}
Expand Down
2 changes: 1 addition & 1 deletion MekHQ/src/mekhq/campaign/mission/AtBContract.java
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ public void doBonusRoll(Campaign c) {
}

if (null != en) {
c.addNewUnit(en, false, 0);
c.addNewUnit(en, false, 0, 3);
} else {
c.addReport("<html><font color='" + MekHQ.getMHQOptions().getFontColorNegativeHexColor() + "'>Could not load unit</font></html>");
}
Expand Down
2 changes: 1 addition & 1 deletion MekHQ/src/mekhq/campaign/mission/Loot.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public void get(Campaign campaign, Scenario s) {
}

for (Entity e : units) {
campaign.addNewUnit(e, false, 0);
campaign.addNewUnit(e, false, 0, 3);
}

for (Part p : parts) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ protected void execute() {
return;
}
Entity en = mechFileParser.getEntity();
getCampaign().addNewUnit(en, false, 0);
getCampaign().addNewUnit(en, false, 0, 3);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ private List<Unit> createUnits(final Campaign campaign,
continue;
}

final Unit unit = campaign.addNewUnit(tracker.getEntity(), false, 0);
final Unit unit = campaign.addNewUnit(tracker.getEntity(), false, 0, 3);
unit.addPilotOrSoldier(tracker.getPerson());
if (getOptions().isGenerateUnitsAsAttached()) {
tracker.getPerson().setOriginalUnit(unit);
Expand Down Expand Up @@ -1287,7 +1287,7 @@ public List<Entity> generateMothballedEntities(final Campaign campaign,
private List<Unit> createMothballedSpareUnits(final Campaign campaign,
final List<Entity> mothballedEntities) {
final List<Unit> mothballedUnits = mothballedEntities.stream()
.map(entity -> campaign.addNewUnit(entity, false, 0))
.map(entity -> campaign.addNewUnit(entity, false, 0, 3))
.collect(Collectors.toList());
mothballedUnits.forEach(Unit::completeMothball);
return mothballedUnits;
Expand Down
34 changes: 34 additions & 0 deletions MekHQ/src/mekhq/gui/BriefingTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import mekhq.MekHQ;
import mekhq.campaign.ResolveScenarioTracker;
import mekhq.campaign.event.*;
import mekhq.campaign.finances.Money;
import mekhq.campaign.finances.enums.TransactionType;
import mekhq.campaign.force.Lance;
import mekhq.campaign.mission.*;
import mekhq.campaign.mission.atb.AtBScenarioFactory;
Expand Down Expand Up @@ -398,6 +400,8 @@ && getCampaign().getFinances().getBalance().isGreaterOrEqualThan(rdd.totalPayout
((AtBContract) mission).checkForFollowup(getCampaign());
}

bonusPartExchange((AtBContract) mission);

if (getCampaign().getCampaignOptions().isEnableAutoAwards()) {
AutoAwardsController autoAwardsController = new AutoAwardsController();

Expand All @@ -410,6 +414,36 @@ && getCampaign().getFinances().getBalance().isGreaterOrEqualThan(rdd.totalPayout
comboMission.setSelectedItem(missions.isEmpty() ? null : missions.get(0));
}

/**
* Credits the campaign finances with additional funds based on campaign settings and remaining Bonus Parts.
*
* @param mission the mission just concluded
*/
private void bonusPartExchange(AtBContract mission) {
final ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.CampaignGUI",
MekHQ.getMHQOptions().getLocale());

double bonusPartExchangeValue = getCampaign().getCampaignOptions().getBonusPartExchangeValue();

if (bonusPartExchangeValue != 0.0) {
int bonusPartMaxExchangeCount = getCampaign().getCampaignOptions().getBonusPartMaxExchangeCount();

int spareBonusParts = mission.getNumBonusParts();

if (bonusPartMaxExchangeCount != 0) {
spareBonusParts = Math.min(bonusPartMaxExchangeCount, spareBonusParts);
}

bonusPartExchangeValue *= spareBonusParts;

getCampaign().getFinances().credit(
TransactionType.BONUS_EXCHANGE,
getCampaign().getLocalDate(),
Money.of(bonusPartExchangeValue),
resourceMap.getString("spareBonusPartExchange.text"));
}
}

private void deleteMission() {
final Mission mission = comboMission.getSelectedItem();
if (mission == null) {
Expand Down
2 changes: 1 addition & 1 deletion MekHQ/src/mekhq/gui/CampaignGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -1896,7 +1896,7 @@ protected void loadListFile(final boolean allowNewPilots) {
if (unitFile != null) {
try {
for (Entity entity : new MULParser(unitFile, getCampaign().getGameOptions()).getEntities()) {
getCampaign().addNewUnit(entity, allowNewPilots, 0);
getCampaign().addNewUnit(entity, allowNewPilots, 0, 3);
}
} catch (Exception e) {
LogManager.getLogger().error("", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ private void addOneItem(final IAcquisitionWork acquisition) {
if (equipment instanceof Part) {
gui.getCampaign().getQuartermaster().addPart((Part) equipment, 0);
} else if (equipment instanceof Entity) {
gui.getCampaign().addNewUnit((Entity) equipment, false, 0);
gui.getCampaign().addNewUnit((Entity) equipment, false, 0, 3);
} else {
LogManager.getLogger().error("Attempted to add unknown equipment of " + acquisition.getAcquisitionName());
return;
Expand Down
2 changes: 1 addition & 1 deletion MekHQ/src/mekhq/gui/dialog/GMToolsDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -1373,7 +1373,7 @@ private void addRATRolledUnit() {
}

if (getLastRolledUnit() != null) {
final Unit unit = getGUI().getCampaign().addNewUnit(getLastRolledUnit(), false, 0);
final Unit unit = getGUI().getCampaign().addNewUnit(getLastRolledUnit(), false, 0, 3);
if ((getPerson() != null) && (getPerson().getUnit() == null)) {
unit.addPilotOrSoldier(getPerson());
getPerson().setOriginalUnit(unit);
Expand Down
2 changes: 1 addition & 1 deletion MekHQ/src/mekhq/gui/dialog/MekHQUnitSelectorDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ protected JPanel createButtonsPanel() {
protected void select(boolean isGM) {
if (getSelectedEntity() != null) {
if (isGM) {
campaign.addNewUnit(selectedUnit.getEntity(), false, 0);
campaign.addNewUnit(selectedUnit.getEntity(), false, 0, 3);
} else {
campaign.getShoppingList().addShoppingItem(selectedUnit, 1, campaign);
}
Expand Down
2 changes: 1 addition & 1 deletion MekHQ/src/mekhq/gui/dialog/PersonnelMarketDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ private void addUnit(Entity en, boolean pay) {
unitCost, "Purchased " + en.getShortName())) {
return;
}
Unit unit = campaign.addNewUnit(en, false, 0);
Unit unit = campaign.addNewUnit(en, false, 0, 3);
if (unit == null) {
// No such unit matching the entity.
return;
Expand Down
Loading

0 comments on commit 2628f7f

Please sign in to comment.