Skip to content

Commit

Permalink
Merge pull request MegaMek#5292 from IllianiCBT/stratCon_sectorDisplay
Browse files Browse the repository at this point in the history
Updated Sector Display & Expanded Scenario Information
  • Loading branch information
IllianiCBT authored Dec 4, 2024
2 parents 672241c + 514f419 commit 3d3fc7c
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 71 deletions.
2 changes: 1 addition & 1 deletion MekHQ/resources/mekhq/resources/Mission.properties
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ ContractCommandRights.INTEGRATED.toolTipText=<html><body style="width: 300px;">-
<br>- No map scouting (StratCon).\
<br>\
<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>
ContractCommandRights.INTEGRATED.stratConText=The employer will make Lance assignments. Complete required scenarios to fulfill contract conditions.
ContractCommandRights.INTEGRATED.stratConText=The employer will make Lance assignments.<br>Complete required scenarios to fulfill contract conditions.

ContractCommandRights.HOUSE.text=House
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.\
Expand Down
72 changes: 72 additions & 0 deletions MekHQ/src/mekhq/campaign/mission/AtBDynamicScenario.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@
import megamek.common.Entity;
import megamek.common.annotations.Nullable;
import megamek.common.enums.SkillLevel;
import megamek.logging.MMLogger;
import mekhq.campaign.Campaign;
import mekhq.campaign.force.Force;
import mekhq.campaign.force.StrategicFormation;
import mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment;
import mekhq.campaign.mission.ScenarioForceTemplate.ForceGenerationMethod;
import mekhq.campaign.mission.atb.AtBScenarioModifier;
import mekhq.campaign.personnel.Person;
import mekhq.campaign.personnel.SkillType;
import mekhq.campaign.rating.IUnitRating;
import mekhq.campaign.unit.Unit;
import mekhq.utilities.MHQXMLUtility;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Element;
Expand All @@ -39,6 +43,11 @@
import java.text.ParseException;
import java.util.*;

import static mekhq.campaign.mission.AtBDynamicScenarioFactory.getPlanetOwnerAlignment;
import static mekhq.campaign.mission.AtBDynamicScenarioFactory.getPlanetOwnerFaction;
import static mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment.Allied;
import static mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment.PlanetOwner;

/**
* Data structure intended to hold data relevant to AtB Dynamic Scenarios (AtB 3.0)
* @author NickAragua
Expand Down Expand Up @@ -86,6 +95,9 @@ public static class BenchedEntityData {
private transient Map<UUID, ScenarioForceTemplate> playerUnitTemplates;
private transient List<AtBScenarioModifier> scenarioModifiers;

private static final MMLogger logger = MMLogger.create(AtBDynamicScenario.class);


public AtBDynamicScenario() {
super();

Expand Down Expand Up @@ -594,4 +606,64 @@ public void clearAllForcesAndPersonnel(Campaign campaign) {
public String getBattlefieldControlDescription() {
return "";
}

/**
* Returns the total battle value (BV) either for allied forces or opposing forces in
* a given contract campaign, as per the parameter {@code isAllied}.
* <p>
* If {@code isAllied} is {@code true}, the method calculates the total BV for the allied
* forces inclusive of player forces. If {@code isAllied} is {@code false}, the total BV for
* opposing forces is calculated.
* <p>
* The calculation is done based on Bot forces attributed to each side. In the case of
* PlanetOwner, the alignment of the owner faction is considered to determine the ownership of
* Bot forces.
*
* @param campaign The campaign in which the forces are participating.
* @param isAllied A boolean value indicating whether to calculate the total BV for
* allied forces (if true) or opposing forces (if false).
* @return The total battle value (BV) either for the allied forces or
* opposing forces, as specified by the parameter isAllied.
*/
public int getTeamTotalBattleValue(Campaign campaign, boolean isAllied) {
AtBContract contract = getContract(campaign);
int totalBattleValue = 0;

for (BotForce botForce : getBotForces()) {
int battleValue = botForce.getTotalBV(campaign);

int team = botForce.getTeam();

if (team == PlanetOwner.ordinal()) {
String planetOwnerFaction = getPlanetOwnerFaction(contract, campaign.getLocalDate());
ForceAlignment forceAlignment = getPlanetOwnerAlignment(contract, planetOwnerFaction, campaign.getLocalDate());
team = forceAlignment.ordinal();
}

if (team <= Allied.ordinal()) {
if (isAllied) {
totalBattleValue += battleValue;
}
} else if (!isAllied) {
totalBattleValue += battleValue;
}
}

if (isAllied) {
Force playerForces = this.getForces(campaign);

for (UUID unitID : playerForces.getAllUnits(false)) {
try {
Unit unit = campaign.getUnit(unitID);
Entity entity = unit.getEntity();

totalBattleValue += entity.calculateBattleValue();
} catch (Exception ex) {
logger.warn(ex.getMessage(), ex);
}
}
}

return totalBattleValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3909,7 +3909,7 @@ private static void correctNonAeroFlyerBehavior(List<Entity> entityList, int boa
* @param currentDate Current date.
* @return Faction code.
*/
private static String getPlanetOwnerFaction(AtBContract contract, LocalDate currentDate) {
static String getPlanetOwnerFaction(AtBContract contract, LocalDate currentDate) {
String factionCode = "MERC";

// planet owner is the first of the factions that owns the current planet.
Expand All @@ -3935,8 +3935,7 @@ private static String getPlanetOwnerFaction(AtBContract contract, LocalDate curr
* @param currentDate Current date.
* @return ForceAlignment.
*/
private static ForceAlignment getPlanetOwnerAlignment(AtBContract contract, String factionCode,
LocalDate currentDate) {
static ForceAlignment getPlanetOwnerAlignment(AtBContract contract, String factionCode, LocalDate currentDate) {
// if the faction is one of the planet owners, see if it's either the employer
// or opfor. If it's not, third-party.
if (contract.getSystem().getFactions(currentDate).contains(factionCode)) {
Expand Down
16 changes: 14 additions & 2 deletions MekHQ/src/mekhq/campaign/stratcon/StratconScenario.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import jakarta.xml.bind.annotation.XmlTransient;
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import megamek.common.annotations.Nullable;
import mekhq.MekHQ;
import mekhq.adapter.DateAdapter;
import mekhq.campaign.Campaign;
Expand Down Expand Up @@ -166,10 +167,10 @@ public void setCurrentState(ScenarioState state) {

@Override
public String getInfo() {
return getInfo(true);
return getInfo(null, true);
}

public String getInfo(boolean html) {
public String getInfo(@Nullable Campaign campaign, boolean html) {
StringBuilder stateBuilder = new StringBuilder();

if (isStrategicObjective()) {
Expand Down Expand Up @@ -218,6 +219,17 @@ public String getInfo(boolean html) {
.append("<br/>");
}

if (campaign != null) {
AtBDynamicScenario backingScenario = getBackingScenario();

if (backingScenario != null) {
stateBuilder.append(String.format("Hostile BV: %d<br>",
backingScenario.getTeamTotalBattleValue(campaign, false)));
stateBuilder.append(String.format("Allied BV: %d",
backingScenario.getTeamTotalBattleValue(campaign, true)));
}
}

stateBuilder.append("</html>");
return stateBuilder.toString();
}
Expand Down
29 changes: 15 additions & 14 deletions MekHQ/src/mekhq/gui/StratconPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import mekhq.MekHQ;
import mekhq.campaign.Campaign;
import mekhq.campaign.force.Force;
import mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment;
import mekhq.campaign.stratcon.*;
import mekhq.campaign.stratcon.StratconBiomeManifest.ImageType;
import mekhq.gui.stratcon.StratconScenarioWizard;
Expand All @@ -40,6 +39,8 @@
import java.util.HashMap;
import java.util.Map;

import static mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment.Allied;

/**
* This panel handles AtB-Stratcon GUI interactions with a specific scenario
* track.
Expand Down Expand Up @@ -144,7 +145,7 @@ public void selectTrack(StratconCampaignState campaignState, StratconTrackState
// clear hex selection
boardState.selectedX = null;
boardState.selectedY = null;
infoArea.setText(buildSelectedHexInfo());
infoArea.setText(buildSelectedHexInfo(campaign));

repaint();
}
Expand Down Expand Up @@ -471,7 +472,7 @@ private boolean imageLoaded(String imageKey) {
}

private BufferedImage getFacilityImage(StratconFacility facility) {
String imageKeyPrefix = facility.getOwner() == ForceAlignment.Allied ? StratconBiomeManifest.FACILITY_ALLIED
String imageKeyPrefix = facility.getOwner() == Allied ? StratconBiomeManifest.FACILITY_ALLIED
: StratconBiomeManifest.FACILITY_HOSTILE;
String imageKey = imageKeyPrefix + facility.getFacilityType().name();

Expand Down Expand Up @@ -569,7 +570,7 @@ private void drawScenarios(Graphics2D g2D) {

if (currentTrack.getFacility(currentCoords) == null) {
drawTextEffect(g2D, scenarioMarker, "Hostile Force Detected", currentCoords);
} else if (currentTrack.getFacility(currentCoords).getOwner() == ForceAlignment.Allied) {
} else if (currentTrack.getFacility(currentCoords).getOwner() == Allied) {
drawTextEffect(g2D, scenarioMarker, "Under Attack!", currentCoords);
}
}
Expand Down Expand Up @@ -610,7 +611,7 @@ private void drawFacilities(Graphics2D g2D) {
StratconFacility facility = currentTrack.getFacility(currentCoords);

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

BufferedImage facilityImage = getFacilityImage(facility);

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

if (pointFoundOnBoard) {
infoArea.setText(buildSelectedHexInfo());
infoArea.setText(buildSelectedHexInfo(campaign));
}

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

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

if (currentTrack.getAssignedCoordForces().containsKey(boardState.getSelectedCoords())) {
for (int forceID : currentTrack.getAssignedCoordForces().get(boardState.getSelectedCoords())) {
Force force = campaign.getForce(forceID);
Force force = this.campaign.getForce(forceID);
infoBuilder.append(force.getName()).append(" assigned");

if (currentTrack.getStickyForces().contains(forceID)) {
Expand All @@ -890,12 +891,12 @@ private String buildSelectedHexInfo() {
if ((facility != null) && (facility.getFacilityType() != null)) {
if (facility.isStrategicObjective()) {
infoBuilder.append(String.format("<br/><span color='%s'>Contract objective located</span>",
facility.getOwner() == ForceAlignment.Allied
facility.getOwner() == Allied
? MekHQ.getMHQOptions().getFontColorPositiveHexColor()
: MekHQ.getMHQOptions().getFontColorNegativeHexColor()));
}
infoBuilder.append("<span color='")
.append(facility.getOwner() == ForceAlignment.Allied
.append(facility.getOwner() == Allied
? MekHQ.getMHQOptions().getFontColorPositiveHexColor()
: MekHQ.getMHQOptions().getFontColorNegativeHexColor())
.append("'>")
Expand All @@ -912,14 +913,14 @@ private String buildSelectedHexInfo() {

} else {
infoBuilder.append("<span color='").append(MekHQ.getMHQOptions().getFontColorNegative())
.append("'>Recon incomplete</span>");
.append("'>Recon Incomplete</span>");
}
infoBuilder.append("<br/>");

StratconScenario selectedScenario = getSelectedScenario();
if ((selectedScenario != null) &&
((selectedScenario.getDeploymentDate() != null) || currentTrack.isGmRevealed())) {
infoBuilder.append(selectedScenario.getInfo());
infoBuilder.append(selectedScenario.getInfo(campaign, true));
}

infoBuilder.append("</html>");
Expand Down
Loading

0 comments on commit 3d3fc7c

Please sign in to comment.