From dcfac9dddd668da9476595b39cf6bded860a41f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Jul 2021 20:47:05 -0400 Subject: [PATCH 1/4] fixes for multiple stratcon issues --- MekHQ/data/scenariotemplates/Pursuit.xml | 129 +++++++++--------- .../stratcon/StratconRulesManager.java | 16 ++- .../stratcon/StratconStrategicObjective.java | 24 ++++ .../campaign/stratcon/StratconTrackState.java | 28 ++++ MekHQ/src/mekhq/gui/StratconTab.java | 9 +- .../mekhq/gui/adapter/TOEMouseAdapter.java | 5 +- 6 files changed, 142 insertions(+), 69 deletions(-) diff --git a/MekHQ/data/scenariotemplates/Pursuit.xml b/MekHQ/data/scenariotemplates/Pursuit.xml index e1e7d5f840..c2aebec218 100644 --- a/MekHQ/data/scenariotemplates/Pursuit.xml +++ b/MekHQ/data/scenariotemplates/Pursuit.xml @@ -3,6 +3,8 @@ Pursuit Escape superior pursuing enemy force. Reach the far edge of the map or destroy 50% of the pursuing force. + false + false true @@ -13,6 +15,66 @@ false 1 + + + + Player + + + + + ScenarioVictory + Fixed + 2 + + + + + ScenarioDefeat + Fixed + 1 + + + + Crippled units do not count towards this objective. + + Reach the far edge of the map with at least 50% of the following force(s) and unit(s): + NONE + ReachMapEdge + 50 + 0 + true + None + + + + Primary Opfor + + + + + ScenarioVictory + Fixed + 2 + + + + + ScenarioDefeat + Fixed + 1 + + + + Destroy or rout 50% of the following force(s) and unit(s): + NONE + ForceWithdraw + 50 + 0 + true + None + + Player @@ -29,7 +91,7 @@ 11 - 5 + 6 0 0 1.0 @@ -38,6 +100,7 @@ 1 4 0 + 50 0 None @@ -59,7 +122,7 @@ 11 - 6 + 5 0 2 2.0 @@ -68,6 +131,7 @@ 5 4 1 + 50 0 None @@ -96,6 +160,7 @@ 1 4 1 + 50 0 OppositeEdge @@ -104,64 +169,4 @@ - - - - Player - - - - - ScenarioVictory - Fixed - 2 - - - - - ScenarioDefeat - Fixed - 1 - - - - Crippled units do not count towards this objective. - - Reach the far edge of the map with at least 50% of the following force(s) and unit(s): - NONE - ReachMapEdge - 50 - 0 - true - None - - - - Primary Opfor - - - - - ScenarioVictory - Fixed - 2 - - - - - ScenarioDefeat - Fixed - 1 - - - - Destroy or rout 50% of the following force(s) and unit(s): - NONE - ForceWithdraw - 50 - 0 - true - None - - diff --git a/MekHQ/src/mekhq/campaign/stratcon/StratconRulesManager.java b/MekHQ/src/mekhq/campaign/stratcon/StratconRulesManager.java index 9cde8bd093..29fce47190 100644 --- a/MekHQ/src/mekhq/campaign/stratcon/StratconRulesManager.java +++ b/MekHQ/src/mekhq/campaign/stratcon/StratconRulesManager.java @@ -1422,9 +1422,14 @@ private static void updateStrategicObjectives(boolean victory, StratconScenario // first, we check if this scenario is associated with any specific scenario objectives StratconStrategicObjective specificObjective = track.getObjectivesByCoords().get(scenario.getCoords()); - if (victory && (specificObjective != null) && + if ((specificObjective != null) && (specificObjective.getObjectiveType() == StrategicObjectiveType.SpecificScenarioVictory)) { - specificObjective.incrementCurrentObjectiveCount(); + + if (victory) { + specificObjective.incrementCurrentObjectiveCount(); + } else { + specificObjective.setCurrentObjectiveCount(StratconStrategicObjective.OBJECTIVE_FAILED); + } } // "any scenario victory" is not linked to any specific coordinates, so we have to @@ -1542,6 +1547,12 @@ public static boolean processIgnoredScenario(StratconScenario scenario, Stratcon if (closestAlliedFacilityCoords != null) { StratconCoords newCoords = scenario.getCoords() .translate(scenario.getCoords().direction(closestAlliedFacilityCoords)); + + boolean objectiveMoved = track.moveObjective(scenario.getCoords(), newCoords); + if (!objectiveMoved) { + track.failObjective(scenario.getCoords()); + } + scenario.setCoords(newCoords); int daysForward = Math.max(1, track.getDeploymentTime()); @@ -1563,6 +1574,7 @@ public static boolean processIgnoredScenario(StratconScenario scenario, Stratcon scenario.setCurrentState(ScenarioState.UNRESOLVED); return false; } else { + track.failObjective(scenario.getCoords()); // TODO: if there's no allied facilities here, add its forces to track // reinforcement pool return true; diff --git a/MekHQ/src/mekhq/campaign/stratcon/StratconStrategicObjective.java b/MekHQ/src/mekhq/campaign/stratcon/StratconStrategicObjective.java index 1c2938099a..f6ac662ffb 100644 --- a/MekHQ/src/mekhq/campaign/stratcon/StratconStrategicObjective.java +++ b/MekHQ/src/mekhq/campaign/stratcon/StratconStrategicObjective.java @@ -27,6 +27,7 @@ * and also handles some small amount of "business logic" */ public class StratconStrategicObjective { + public static final int OBJECTIVE_FAILED = -1; private StratconCoords objectiveCoords; private StrategicObjectiveType objectiveType; @@ -69,6 +70,29 @@ public void setDesiredObjectiveCount(int desiredObjectiveCount) { this.desiredObjectiveCount = desiredObjectiveCount; } + public boolean isObjectiveFailed(StratconTrackState trackState) { + switch (getObjectiveType()) { + case AnyScenarioVictory: + case SpecificScenarioVictory: + // you can fail this if the scenario goes away somehow + return getCurrentObjectiveCount() == OBJECTIVE_FAILED; + case AlliedFacilityControl: + // you can fail this by having the facility destroyed + StratconFacility alliedFacility = trackState.getFacility(getObjectiveCoords()); + return alliedFacility == null; + case HostileFacilityControl: + // you can fail this by having the facility destroyed + StratconFacility hostileFacility = trackState.getFacility(getObjectiveCoords()); + return hostileFacility == null; + case FacilityDestruction: + // you can't really permanently fail this + return false; + default: + // we shouldn't be here, but just in case + return false; + } + } + /** * Given the track that this objective is on, is it complete? */ diff --git a/MekHQ/src/mekhq/campaign/stratcon/StratconTrackState.java b/MekHQ/src/mekhq/campaign/stratcon/StratconTrackState.java index 2ff07518af..5ba71e850d 100644 --- a/MekHQ/src/mekhq/campaign/stratcon/StratconTrackState.java +++ b/MekHQ/src/mekhq/campaign/stratcon/StratconTrackState.java @@ -376,6 +376,34 @@ public Map getObjectivesByCoords() { return specificStrategicObjectives; } + /** + * Moves a strategic objectives from the source to the destination coordinates. + * @return True if the operation succeeded, false if it failed + */ + public boolean moveObjective(StratconCoords source, StratconCoords destination) { + // safety: don't move it if it's not there; logic prevents two objectives in the same coords + if (getObjectivesByCoords().containsKey(source) && + !getObjectivesByCoords().containsKey(destination)) { + StratconStrategicObjective objective = getObjectivesByCoords().get(source); + // gotta get the cache + getObjectivesByCoords().remove(source); + getObjectivesByCoords().put(destination, objective); + objective.setObjectiveCoords(destination); + return true; + } + + return false; + } + + /** + * Convenience method to fail an objective at the given coordinates. + */ + public void failObjective(StratconCoords coords) { + if (getObjectivesByCoords().containsKey(coords)) { + getObjectivesByCoords().get(coords).setCurrentObjectiveCount(StratconStrategicObjective.OBJECTIVE_FAILED); + } + } + /** * Convenience method - returns true if the force with the given ID is currently deployed to this track */ diff --git a/MekHQ/src/mekhq/gui/StratconTab.java b/MekHQ/src/mekhq/gui/StratconTab.java index e39f064b7a..31dedd6407 100644 --- a/MekHQ/src/mekhq/gui/StratconTab.java +++ b/MekHQ/src/mekhq/gui/StratconTab.java @@ -304,14 +304,17 @@ private String buildStrategicObjectiveText(StratconCampaignState campaignState) boolean coordsRevealed = track.getRevealedCoords().contains(objective.getObjectiveCoords()); boolean displayCoordinateData = objective.getObjectiveCoords() != null; boolean objectiveCompleted = objective.isObjectiveCompleted(track); + boolean objectiveFailed = objective.isObjectiveFailed(track); if ((objective.getObjectiveType() == StrategicObjectiveType.AlliedFacilityControl) && !campaignState.allowEarlyVictory()) { - sb.append(""); + sb.append("o"); } else if (objectiveCompleted) { - sb.append(""); + sb.append("✓ "); + } else if (objectiveFailed) { + sb.append("x "); } else { - sb.append(""); + sb.append("o "); } if (!coordsRevealed && displayCoordinateData) { diff --git a/MekHQ/src/mekhq/gui/adapter/TOEMouseAdapter.java b/MekHQ/src/mekhq/gui/adapter/TOEMouseAdapter.java index 962a7bd72e..7a35485656 100644 --- a/MekHQ/src/mekhq/gui/adapter/TOEMouseAdapter.java +++ b/MekHQ/src/mekhq/gui/adapter/TOEMouseAdapter.java @@ -917,9 +917,10 @@ protected Optional createPopupMenu() { for (final Mission mission : gui.getCampaign().getActiveMissions()) { missionMenu = new JMenu(mission.getName()); for (final Scenario scenario : mission.getCurrentScenarios()) { - if (gui.getCampaign().getCampaignOptions().getUseAtB() + if (scenario.isCloaked() + || (gui.getCampaign().getCampaignOptions().getUseAtB() && (scenario instanceof AtBScenario) - && !((AtBScenario) scenario).canDeployForces(forces, gui.getCampaign())) { + && !((AtBScenario) scenario).canDeployForces(forces, gui.getCampaign()))) { continue; } menuItem = new JMenuItem(scenario.getName()); From 74f27df57530f5f529847283c12c938c2fad8b5b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Jul 2021 21:10:36 -0400 Subject: [PATCH 2/4] VPs too --- MekHQ/src/mekhq/gui/StratconTab.java | 29 +++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/MekHQ/src/mekhq/gui/StratconTab.java b/MekHQ/src/mekhq/gui/StratconTab.java index 31dedd6407..1b063aba3c 100644 --- a/MekHQ/src/mekhq/gui/StratconTab.java +++ b/MekHQ/src/mekhq/gui/StratconTab.java @@ -48,6 +48,10 @@ public class StratconTab extends CampaignGuiTab { private static final long serialVersionUID = 8179754409939346465L; + private static final String OBJECTIVE_FAILED = "x"; + private static final String OBJECTIVE_COMPLETED = "✓"; + private static final String OBJECTIVE_IN_PROGRESS = "o"; + private StratconPanel stratconPanel; private JPanel infoPanel; private JComboBox cboCurrentTrack; @@ -291,6 +295,8 @@ private String buildShortStrategicObjectiveText(StratconCampaignState campaignSt private String buildStrategicObjectiveText(StratconCampaignState campaignState) { StringBuilder sb = new StringBuilder(); + boolean contractIsActive = campaignState.getContract().isActiveOn(getCampaignGui().getCampaign().getLocalDate()); + // loop through all tracks // for each track, loop through all objectives // for each objective, grab the coordinates @@ -306,16 +312,19 @@ private String buildStrategicObjectiveText(StratconCampaignState campaignState) boolean objectiveCompleted = objective.isObjectiveCompleted(track); boolean objectiveFailed = objective.isObjectiveFailed(track); + // special case: allied facilities can get lost at any point in time if ((objective.getObjectiveType() == StrategicObjectiveType.AlliedFacilityControl) && !campaignState.allowEarlyVictory()) { - sb.append("o"); + sb.append("").append(OBJECTIVE_IN_PROGRESS); } else if (objectiveCompleted) { - sb.append("✓ "); + sb.append("").append(OBJECTIVE_COMPLETED); } else if (objectiveFailed) { - sb.append("x "); + sb.append("").append(OBJECTIVE_FAILED); } else { - sb.append("o "); + sb.append("").append(OBJECTIVE_IN_PROGRESS); } + + sb.append(" "); if (!coordsRevealed && displayCoordinateData) { sb.append("Locate and "); @@ -357,14 +366,16 @@ private String buildStrategicObjectiveText(StratconCampaignState campaignState) } // special case text reminding player to complete required scenarios - if (!campaignState.getContract().getCommandRights().isIndependent()) { - if (campaignState.getVictoryPoints() > 0) { - sb.append(""); + if (!campaignState.getContract().getCommandRights().isIndependent()) { + if (contractIsActive) { + sb.append("").append(OBJECTIVE_IN_PROGRESS); + } else if (campaignState.getVictoryPoints() > 0) { + sb.append("").append(OBJECTIVE_COMPLETED); } else { - sb.append(""); + sb.append("").append(OBJECTIVE_FAILED); } - sb.append("Maintain victory point count above 0 by completing required scenarios") + sb.append(" Maintain victory point count above 0 by completing required scenarios") .append("
"); } From 1e51aed43f3b3ea03cb0b45d1d5d0ac25ab1ebd0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Jul 2021 20:54:10 -0400 Subject: [PATCH 3/4] code review changes --- .../stratcon/StratconStrategicObjective.java | 38 +++++++++---------- .../campaign/stratcon/StratconTrackState.java | 4 +- MekHQ/src/mekhq/gui/StratconTab.java | 6 +-- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/stratcon/StratconStrategicObjective.java b/MekHQ/src/mekhq/campaign/stratcon/StratconStrategicObjective.java index f6ac662ffb..4e6b28ff9e 100644 --- a/MekHQ/src/mekhq/campaign/stratcon/StratconStrategicObjective.java +++ b/MekHQ/src/mekhq/campaign/stratcon/StratconStrategicObjective.java @@ -72,25 +72,25 @@ public void setDesiredObjectiveCount(int desiredObjectiveCount) { public boolean isObjectiveFailed(StratconTrackState trackState) { switch (getObjectiveType()) { - case AnyScenarioVictory: - case SpecificScenarioVictory: - // you can fail this if the scenario goes away somehow - return getCurrentObjectiveCount() == OBJECTIVE_FAILED; - case AlliedFacilityControl: - // you can fail this by having the facility destroyed - StratconFacility alliedFacility = trackState.getFacility(getObjectiveCoords()); - return alliedFacility == null; - case HostileFacilityControl: - // you can fail this by having the facility destroyed - StratconFacility hostileFacility = trackState.getFacility(getObjectiveCoords()); - return hostileFacility == null; - case FacilityDestruction: - // you can't really permanently fail this - return false; - default: - // we shouldn't be here, but just in case - return false; - } + case AnyScenarioVictory: + case SpecificScenarioVictory: + // you can fail this if the scenario goes away somehow + return getCurrentObjectiveCount() == OBJECTIVE_FAILED; + case AlliedFacilityControl: + // you can fail this by having the facility destroyed + StratconFacility alliedFacility = trackState.getFacility(getObjectiveCoords()); + return alliedFacility == null; + case HostileFacilityControl: + // you can fail this by having the facility destroyed + StratconFacility hostileFacility = trackState.getFacility(getObjectiveCoords()); + return hostileFacility == null; + case FacilityDestruction: + // you can't really permanently fail this + return false; + default: + // we shouldn't be here, but just in case + return false; + } } /** diff --git a/MekHQ/src/mekhq/campaign/stratcon/StratconTrackState.java b/MekHQ/src/mekhq/campaign/stratcon/StratconTrackState.java index 5ba71e850d..06d131add3 100644 --- a/MekHQ/src/mekhq/campaign/stratcon/StratconTrackState.java +++ b/MekHQ/src/mekhq/campaign/stratcon/StratconTrackState.java @@ -390,9 +390,9 @@ public boolean moveObjective(StratconCoords source, StratconCoords destination) getObjectivesByCoords().put(destination, objective); objective.setObjectiveCoords(destination); return true; + } else { + return false; } - - return false; } /** diff --git a/MekHQ/src/mekhq/gui/StratconTab.java b/MekHQ/src/mekhq/gui/StratconTab.java index 1b063aba3c..e2dccee385 100644 --- a/MekHQ/src/mekhq/gui/StratconTab.java +++ b/MekHQ/src/mekhq/gui/StratconTab.java @@ -295,8 +295,6 @@ private String buildShortStrategicObjectiveText(StratconCampaignState campaignSt private String buildStrategicObjectiveText(StratconCampaignState campaignState) { StringBuilder sb = new StringBuilder(); - boolean contractIsActive = campaignState.getContract().isActiveOn(getCampaignGui().getCampaign().getLocalDate()); - // loop through all tracks // for each track, loop through all objectives // for each objective, grab the coordinates @@ -366,7 +364,9 @@ private String buildStrategicObjectiveText(StratconCampaignState campaignState) } // special case text reminding player to complete required scenarios - if (!campaignState.getContract().getCommandRights().isIndependent()) { + if (!campaignState.getContract().getCommandRights().isIndependent()) { + boolean contractIsActive = campaignState.getContract().isActiveOn(getCampaignGui().getCampaign().getLocalDate()); + if (contractIsActive) { sb.append("").append(OBJECTIVE_IN_PROGRESS); } else if (campaignState.getVictoryPoints() > 0) { From a7a969bb809ade93bf7ea58e75a6af2eea3f7b2e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Jul 2021 20:55:37 -0400 Subject: [PATCH 4/4] hostile off-board artillery shouldn't contribute to main objectives --- MekHQ/data/scenariomodifiers/EnemyArty.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/MekHQ/data/scenariomodifiers/EnemyArty.xml b/MekHQ/data/scenariomodifiers/EnemyArty.xml index c2d6302064..0ac4e12ff1 100644 --- a/MekHQ/data/scenariomodifiers/EnemyArty.xml +++ b/MekHQ/data/scenariomodifiers/EnemyArty.xml @@ -27,9 +27,6 @@ 3 3 4 - - Primary Opfor - 50 0 None