Skip to content

Commit 3d3fc7c

Browse files
authored
Merge pull request #5292 from IllianiCBT/stratCon_sectorDisplay
Updated Sector Display & Expanded Scenario Information
2 parents 672241c + 514f419 commit 3d3fc7c

File tree

7 files changed

+162
-71
lines changed

7 files changed

+162
-71
lines changed

MekHQ/resources/mekhq/resources/Mission.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ ContractCommandRights.INTEGRATED.toolTipText=<html><body style="width: 300px;">-
6464
<br>- No map scouting (StratCon).\
6565
<br>\
6666
<br><i>Integrated command rights, standard for government forces, streamline command and control, particularly in large-scale operations involving multiple forces, ensuring effective collaboration without inter-service rivalry or confusion over command authority.</i></body></html>
67-
ContractCommandRights.INTEGRATED.stratConText=The employer will make Lance assignments. Complete required scenarios to fulfill contract conditions.
67+
ContractCommandRights.INTEGRATED.stratConText=The employer will make Lance assignments.<br>Complete required scenarios to fulfill contract conditions.
6868

6969
ContractCommandRights.HOUSE.text=House
7070
ContractCommandRights.HOUSE.toolTipText=<html><body style="width: 300px;">- Keep your Campaign Victory Points (CVP) positive. Winning a non-initiated scenario: +1 CVP. Losing a non-initiated scenario: -1 CVP.\

MekHQ/src/mekhq/campaign/mission/AtBDynamicScenario.java

+72
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@
2222
import megamek.common.Entity;
2323
import megamek.common.annotations.Nullable;
2424
import megamek.common.enums.SkillLevel;
25+
import megamek.logging.MMLogger;
2526
import mekhq.campaign.Campaign;
27+
import mekhq.campaign.force.Force;
2628
import mekhq.campaign.force.StrategicFormation;
29+
import mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment;
2730
import mekhq.campaign.mission.ScenarioForceTemplate.ForceGenerationMethod;
2831
import mekhq.campaign.mission.atb.AtBScenarioModifier;
2932
import mekhq.campaign.personnel.Person;
3033
import mekhq.campaign.personnel.SkillType;
3134
import mekhq.campaign.rating.IUnitRating;
35+
import mekhq.campaign.unit.Unit;
3236
import mekhq.utilities.MHQXMLUtility;
3337
import org.apache.commons.lang3.StringUtils;
3438
import org.w3c.dom.Element;
@@ -39,6 +43,11 @@
3943
import java.text.ParseException;
4044
import java.util.*;
4145

46+
import static mekhq.campaign.mission.AtBDynamicScenarioFactory.getPlanetOwnerAlignment;
47+
import static mekhq.campaign.mission.AtBDynamicScenarioFactory.getPlanetOwnerFaction;
48+
import static mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment.Allied;
49+
import static mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment.PlanetOwner;
50+
4251
/**
4352
* Data structure intended to hold data relevant to AtB Dynamic Scenarios (AtB 3.0)
4453
* @author NickAragua
@@ -86,6 +95,9 @@ public static class BenchedEntityData {
8695
private transient Map<UUID, ScenarioForceTemplate> playerUnitTemplates;
8796
private transient List<AtBScenarioModifier> scenarioModifiers;
8897

98+
private static final MMLogger logger = MMLogger.create(AtBDynamicScenario.class);
99+
100+
89101
public AtBDynamicScenario() {
90102
super();
91103

@@ -594,4 +606,64 @@ public void clearAllForcesAndPersonnel(Campaign campaign) {
594606
public String getBattlefieldControlDescription() {
595607
return "";
596608
}
609+
610+
/**
611+
* Returns the total battle value (BV) either for allied forces or opposing forces in
612+
* a given contract campaign, as per the parameter {@code isAllied}.
613+
* <p>
614+
* If {@code isAllied} is {@code true}, the method calculates the total BV for the allied
615+
* forces inclusive of player forces. If {@code isAllied} is {@code false}, the total BV for
616+
* opposing forces is calculated.
617+
* <p>
618+
* The calculation is done based on Bot forces attributed to each side. In the case of
619+
* PlanetOwner, the alignment of the owner faction is considered to determine the ownership of
620+
* Bot forces.
621+
*
622+
* @param campaign The campaign in which the forces are participating.
623+
* @param isAllied A boolean value indicating whether to calculate the total BV for
624+
* allied forces (if true) or opposing forces (if false).
625+
* @return The total battle value (BV) either for the allied forces or
626+
* opposing forces, as specified by the parameter isAllied.
627+
*/
628+
public int getTeamTotalBattleValue(Campaign campaign, boolean isAllied) {
629+
AtBContract contract = getContract(campaign);
630+
int totalBattleValue = 0;
631+
632+
for (BotForce botForce : getBotForces()) {
633+
int battleValue = botForce.getTotalBV(campaign);
634+
635+
int team = botForce.getTeam();
636+
637+
if (team == PlanetOwner.ordinal()) {
638+
String planetOwnerFaction = getPlanetOwnerFaction(contract, campaign.getLocalDate());
639+
ForceAlignment forceAlignment = getPlanetOwnerAlignment(contract, planetOwnerFaction, campaign.getLocalDate());
640+
team = forceAlignment.ordinal();
641+
}
642+
643+
if (team <= Allied.ordinal()) {
644+
if (isAllied) {
645+
totalBattleValue += battleValue;
646+
}
647+
} else if (!isAllied) {
648+
totalBattleValue += battleValue;
649+
}
650+
}
651+
652+
if (isAllied) {
653+
Force playerForces = this.getForces(campaign);
654+
655+
for (UUID unitID : playerForces.getAllUnits(false)) {
656+
try {
657+
Unit unit = campaign.getUnit(unitID);
658+
Entity entity = unit.getEntity();
659+
660+
totalBattleValue += entity.calculateBattleValue();
661+
} catch (Exception ex) {
662+
logger.warn(ex.getMessage(), ex);
663+
}
664+
}
665+
}
666+
667+
return totalBattleValue;
668+
}
597669
}

MekHQ/src/mekhq/campaign/mission/AtBDynamicScenarioFactory.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -3909,7 +3909,7 @@ private static void correctNonAeroFlyerBehavior(List<Entity> entityList, int boa
39093909
* @param currentDate Current date.
39103910
* @return Faction code.
39113911
*/
3912-
private static String getPlanetOwnerFaction(AtBContract contract, LocalDate currentDate) {
3912+
static String getPlanetOwnerFaction(AtBContract contract, LocalDate currentDate) {
39133913
String factionCode = "MERC";
39143914

39153915
// planet owner is the first of the factions that owns the current planet.
@@ -3935,8 +3935,7 @@ private static String getPlanetOwnerFaction(AtBContract contract, LocalDate curr
39353935
* @param currentDate Current date.
39363936
* @return ForceAlignment.
39373937
*/
3938-
private static ForceAlignment getPlanetOwnerAlignment(AtBContract contract, String factionCode,
3939-
LocalDate currentDate) {
3938+
static ForceAlignment getPlanetOwnerAlignment(AtBContract contract, String factionCode, LocalDate currentDate) {
39403939
// if the faction is one of the planet owners, see if it's either the employer
39413940
// or opfor. If it's not, third-party.
39423941
if (contract.getSystem().getFactions(currentDate).contains(factionCode)) {

MekHQ/src/mekhq/campaign/stratcon/StratconScenario.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import jakarta.xml.bind.annotation.XmlTransient;
1717
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
18+
import megamek.common.annotations.Nullable;
1819
import mekhq.MekHQ;
1920
import mekhq.adapter.DateAdapter;
2021
import mekhq.campaign.Campaign;
@@ -166,10 +167,10 @@ public void setCurrentState(ScenarioState state) {
166167

167168
@Override
168169
public String getInfo() {
169-
return getInfo(true);
170+
return getInfo(null, true);
170171
}
171172

172-
public String getInfo(boolean html) {
173+
public String getInfo(@Nullable Campaign campaign, boolean html) {
173174
StringBuilder stateBuilder = new StringBuilder();
174175

175176
if (isStrategicObjective()) {
@@ -218,6 +219,17 @@ public String getInfo(boolean html) {
218219
.append("<br/>");
219220
}
220221

222+
if (campaign != null) {
223+
AtBDynamicScenario backingScenario = getBackingScenario();
224+
225+
if (backingScenario != null) {
226+
stateBuilder.append(String.format("Hostile BV: %d<br>",
227+
backingScenario.getTeamTotalBattleValue(campaign, false)));
228+
stateBuilder.append(String.format("Allied BV: %d",
229+
backingScenario.getTeamTotalBattleValue(campaign, true)));
230+
}
231+
}
232+
221233
stateBuilder.append("</html>");
222234
return stateBuilder.toString();
223235
}

MekHQ/src/mekhq/gui/StratconPanel.java

+15-14
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import mekhq.MekHQ;
1919
import mekhq.campaign.Campaign;
2020
import mekhq.campaign.force.Force;
21-
import mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment;
2221
import mekhq.campaign.stratcon.*;
2322
import mekhq.campaign.stratcon.StratconBiomeManifest.ImageType;
2423
import mekhq.gui.stratcon.StratconScenarioWizard;
@@ -40,6 +39,8 @@
4039
import java.util.HashMap;
4140
import java.util.Map;
4241

42+
import static mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment.Allied;
43+
4344
/**
4445
* This panel handles AtB-Stratcon GUI interactions with a specific scenario
4546
* track.
@@ -144,7 +145,7 @@ public void selectTrack(StratconCampaignState campaignState, StratconTrackState
144145
// clear hex selection
145146
boardState.selectedX = null;
146147
boardState.selectedY = null;
147-
infoArea.setText(buildSelectedHexInfo());
148+
infoArea.setText(buildSelectedHexInfo(campaign));
148149

149150
repaint();
150151
}
@@ -471,7 +472,7 @@ private boolean imageLoaded(String imageKey) {
471472
}
472473

473474
private BufferedImage getFacilityImage(StratconFacility facility) {
474-
String imageKeyPrefix = facility.getOwner() == ForceAlignment.Allied ? StratconBiomeManifest.FACILITY_ALLIED
475+
String imageKeyPrefix = facility.getOwner() == Allied ? StratconBiomeManifest.FACILITY_ALLIED
475476
: StratconBiomeManifest.FACILITY_HOSTILE;
476477
String imageKey = imageKeyPrefix + facility.getFacilityType().name();
477478

@@ -569,7 +570,7 @@ private void drawScenarios(Graphics2D g2D) {
569570

570571
if (currentTrack.getFacility(currentCoords) == null) {
571572
drawTextEffect(g2D, scenarioMarker, "Hostile Force Detected", currentCoords);
572-
} else if (currentTrack.getFacility(currentCoords).getOwner() == ForceAlignment.Allied) {
573+
} else if (currentTrack.getFacility(currentCoords).getOwner() == Allied) {
573574
drawTextEffect(g2D, scenarioMarker, "Under Attack!", currentCoords);
574575
}
575576
}
@@ -610,7 +611,7 @@ private void drawFacilities(Graphics2D g2D) {
610611
StratconFacility facility = currentTrack.getFacility(currentCoords);
611612

612613
if ((facility != null) && (facility.isVisible() || trackRevealed || currentTrack.isGmRevealed())) {
613-
g2D.setColor(facility.getOwner() == ForceAlignment.Allied ? Color.CYAN : Color.RED);
614+
g2D.setColor(facility.getOwner() == Allied ? Color.CYAN : Color.RED);
614615

615616
BufferedImage facilityImage = getFacilityImage(facility);
616617

@@ -813,7 +814,7 @@ public void mouseReleasedHandler(MouseEvent e) {
813814
boolean pointFoundOnBoard = detectClickedHex();
814815

815816
if (pointFoundOnBoard) {
816-
infoArea.setText(buildSelectedHexInfo());
817+
infoArea.setText(buildSelectedHexInfo(campaign));
817818
}
818819

819820
repaint();
@@ -850,7 +851,7 @@ public StratconCoords getSelectedCoords() {
850851
* containing info such as whether it's been revealed, assigned forces,
851852
* scenarios, facilities, etc.
852853
*/
853-
private String buildSelectedHexInfo() {
854+
private String buildSelectedHexInfo(Campaign campaign) {
854855
StringBuilder infoBuilder = new StringBuilder();
855856
infoBuilder.append("<html><br/>");
856857

@@ -864,13 +865,13 @@ private String buildSelectedHexInfo() {
864865
boolean coordsRevealed = currentTrack.hasActiveTrackReveal()
865866
|| currentTrack.getRevealedCoords().contains(boardState.getSelectedCoords());
866867
if (coordsRevealed) {
867-
infoBuilder.append("<span color='" + MekHQ.getMHQOptions().getFontColorPositiveHexColor()
868-
+ "'>Recon complete</span><br/>");
868+
infoBuilder.append("<span color='").append(MekHQ.getMHQOptions().getFontColorPositiveHexColor())
869+
.append("'>Recon Complete</span><br/>");
869870
}
870871

871872
if (currentTrack.getAssignedCoordForces().containsKey(boardState.getSelectedCoords())) {
872873
for (int forceID : currentTrack.getAssignedCoordForces().get(boardState.getSelectedCoords())) {
873-
Force force = campaign.getForce(forceID);
874+
Force force = this.campaign.getForce(forceID);
874875
infoBuilder.append(force.getName()).append(" assigned");
875876

876877
if (currentTrack.getStickyForces().contains(forceID)) {
@@ -890,12 +891,12 @@ private String buildSelectedHexInfo() {
890891
if ((facility != null) && (facility.getFacilityType() != null)) {
891892
if (facility.isStrategicObjective()) {
892893
infoBuilder.append(String.format("<br/><span color='%s'>Contract objective located</span>",
893-
facility.getOwner() == ForceAlignment.Allied
894+
facility.getOwner() == Allied
894895
? MekHQ.getMHQOptions().getFontColorPositiveHexColor()
895896
: MekHQ.getMHQOptions().getFontColorNegativeHexColor()));
896897
}
897898
infoBuilder.append("<span color='")
898-
.append(facility.getOwner() == ForceAlignment.Allied
899+
.append(facility.getOwner() == Allied
899900
? MekHQ.getMHQOptions().getFontColorPositiveHexColor()
900901
: MekHQ.getMHQOptions().getFontColorNegativeHexColor())
901902
.append("'>")
@@ -912,14 +913,14 @@ private String buildSelectedHexInfo() {
912913

913914
} else {
914915
infoBuilder.append("<span color='").append(MekHQ.getMHQOptions().getFontColorNegative())
915-
.append("'>Recon incomplete</span>");
916+
.append("'>Recon Incomplete</span>");
916917
}
917918
infoBuilder.append("<br/>");
918919

919920
StratconScenario selectedScenario = getSelectedScenario();
920921
if ((selectedScenario != null) &&
921922
((selectedScenario.getDeploymentDate() != null) || currentTrack.isGmRevealed())) {
922-
infoBuilder.append(selectedScenario.getInfo());
923+
infoBuilder.append(selectedScenario.getInfo(campaign, true));
923924
}
924925

925926
infoBuilder.append("</html>");

0 commit comments

Comments
 (0)