Skip to content

Commit

Permalink
Merge pull request #2688 from NickAragua/objective_modifier_update
Browse files Browse the repository at this point in the history
contract objective update
  • Loading branch information
NickAragua authored Jun 10, 2021
2 parents cb29247 + a291dd3 commit c170d4a
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 48 deletions.
2 changes: 1 addition & 1 deletion MekHQ/data/scenariomodifiers/BadIntelAir.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<fixedUnitCount>-1</fixedUnitCount>
<forceAlignment>2</forceAlignment>
<forceMultiplier>1.0</forceMultiplier>
<forceName>Opfor Ground Reinforcements</forceName>
<forceName>Additional OpFor Aircraft</forceName>
<generationMethod>3</generationMethod>
<generationOrder>3</generationOrder>
<maxWeightClass>4</maxWeightClass>
Expand Down
2 changes: 1 addition & 1 deletion MekHQ/data/scenariomodifiers/BadIntelGround.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<fixedUnitCount>-1</fixedUnitCount>
<forceAlignment>2</forceAlignment>
<forceMultiplier>1.0</forceMultiplier>
<forceName>Opfor Ground Reinforcements</forceName>
<forceName>Additional Opfor Ground Units</forceName>
<generationMethod>3</generationMethod>
<generationOrder>3</generationOrder>
<maxWeightClass>4</maxWeightClass>
Expand Down
1 change: 1 addition & 0 deletions MekHQ/data/stratconcontractdefinitions/CadreDuty.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
</deploymentTimes>
<objectiveParameters>
<objectiveParameter>
<objectiveCount>-1</objectiveCount>
<objectiveType>AnyScenarioVictory</objectiveType>
<objectiveScenarioModifiers>
<objectiveScenarioModifier>AlliedTraineesGround.xml</objectiveScenarioModifier>
Expand Down
77 changes: 77 additions & 0 deletions MekHQ/data/stratconcontractdefinitions/FileFormat.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
The following is an example contract definition file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ScenarioTemplate>
<alliedFacilityCount>-0.3</alliedFacilityCount>
<briefing>Protect attached trainees.</briefing>
<contractTypeName>Cadre Duty</contractTypeName>
<hostileFacilityCount>0</hostileFacilityCount>
<scenarioOdds>
<scenarioOdds>10</scenarioOdds>
<scenarioOdds>10</scenarioOdds>
<scenarioOdds>10</scenarioOdds>
<scenarioOdds>10</scenarioOdds>
</scenarioOdds>
<deploymentTimes>
<deploymentTimes>0</deploymentTimes>
<deploymentTimes>1</deploymentTimes>
<deploymentTimes>2</deploymentTimes>
<deploymentTimes>3</deploymentTimes>
</deploymentTimes>
<objectiveParameters>
<objectiveParameter>
<objectiveType>AlliedFacilityControl</objectiveType>
<objectiveCount>-0.25</objectiveCount>
</objectiveParameter>
<objectiveParameter>
<objectiveCount>-0.25</objectiveCount>
<objectiveType>SpecificScenarioVictory</objectiveType>
<objectiveScenarios>
<objectiveScenario>Irregular Forces.xml</objectiveScenario>
</objectiveScenarios>
</objectiveParameter>
<objectiveParameter>
<objectiveType>FacilityDestruction</objectiveType>
<objectiveCount>-0.25</objectiveCount>
</objectiveParameter>
<objectiveParameter>
<objectiveCount>-0.25</objectiveCount>
<objectiveType>AnyScenarioVictory</objectiveType>
<objectiveScenarioModifiers>
<objectiveScenarioModifier>AlliedTraineesGround.xml</objectiveScenarioModifier>
<objectiveScenarioModifier>AlliedTraineesAir.xml</objectiveScenarioModifier>
</objectiveScenarioModifiers>
</objectiveParameter>
</objectiveParameters>
</ScenarioTemplate>

Let's break it down.

alliedFacilityCount - Decimal. The number of allied facilities to seed for the entire contract, split somewhat evenly among the tracks. Numbers less than zero indicate that the number of allied facilities should be scaled to the number of contract required lances. Avoid setting this too high, as the player will be swamped with allied reinforcements.

briefing - a (preferably brief) text description of the contract.

contractTypeName - the name of the contract

hostileFacilityCount - Decimal. Exactly like alliedFacilityCount, except for hostile facilities. Avoid setting this too high, as the player will be swamped with hostile reinforcements.

scenarioOdds - a list of base odds that a scenario will occur a) for a require lance on monday, b) when a lance is deployed to a hex on a track that does not have an allied facility. Picked randomly from the list for each track.

deploymentTimes - a list of deployment times, in days, for when a force gets assigned to a scenario. Once assigned, a force (and any reinforcements, and, theoretically, in the future, any salvage) will not return for the specified number of days. Picked randomly from the list for each track.

globalScenarioModifiers/globalScenarioModifier - a list of all scenario modifier file names to apply to any scenario in this contract. Use sparingly.

objectiveParameters - a list of objectives for the contract. Its child elements follow:

objectiveCount - Decimal. How much of this particular objective to generate. A number less than zero indicates that it's a scaling multiplier to the number of contract required lances. Avoid setting this too low or too high, as it will lead to boredom or craziness due to either nothing to do or way too much to do.

objectiveScenarios/objectiveScenario - a list of possible scenario file names pre-seeded for this particular objective, that need to be completed in order too meet this objective. Ignored AnyScenarioVictory objective type.

objectivescenarioModifiers/objectiveScenarioModifier - a list of scenario modifiers file names to be applied to objective scenarios. Note that for AnyScenarioVictory, these modifiers will be applied to *all* scenarios, and thus this should be used sparingly.


objectiveType - the class of objective. There are four types:
AnyScenarioVictory - victory in any scenario.
SpecificScenarioVictory - victory in specific pre-seeded scenarios, from the list in objectiveScenarios.
FacilityDestruction - drops some hostile facilities on the map, which the player must seize control over/destroy.
AlliedFacilityControl - drops some allied facilities on the map, which the player must retain control over (it is possible to retake if they were captured).
6 changes: 3 additions & 3 deletions MekHQ/data/stratconcontractdefinitions/PirateHunting.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
<objectiveParameters>
<objectiveParameter>
<objectiveType>FacilityDestruction</objectiveType>
<objectiveCount>-0.3</objectiveCount>
<objectiveCount>-0.33</objectiveCount>
</objectiveParameter>
<objectiveParameter>
<objectiveType>AlliedFacilityControl</objectiveType>
<objectiveCount>-0.3</objectiveCount>
<objectiveCount>-0.33</objectiveCount>
</objectiveParameter>
<objectiveParameter>
<objectiveCount>-0.3</objectiveCount>
<objectiveCount>-0.33</objectiveCount>
<objectiveType>AnyScenarioVictory</objectiveType>
<objectiveScenarios>
<objectiveScenario>Destroy Grounded Dropship.xml</objectiveScenario>
Expand Down
4 changes: 2 additions & 2 deletions MekHQ/data/stratconcontractdefinitions/RiotDuty.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<ScenarioTemplate>
<alliedFacilityCount>0</alliedFacilityCount>
<briefing>Defend designated facilities.</briefing>
<contractTypeName>Garrison Duty</contractTypeName>
<contractTypeName>Riot Duty</contractTypeName>
<hostileFacilityCount>0</hostileFacilityCount>
<scenarioOdds>
<scenarioOdds>10</scenarioOdds>
Expand All @@ -23,7 +23,7 @@
</objectiveParameter>
<objectiveParameter>
<objectiveCount>-0.5</objectiveCount>
<objectiveType>AnyScenarioVictory</objectiveType>
<objectiveType>SpecificScenarioVictory</objectiveType>
<objectiveScenarios>
<objectiveScenario>Irregular Forces.xml</objectiveScenario>
</objectiveScenarios>
Expand Down
11 changes: 1 addition & 10 deletions MekHQ/src/mekhq/campaign/stratcon/StratconCampaignState.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ public class StratconCampaignState {
private double globalOpforBVMultiplier;
private int supportPoints;
private int victoryPoints;
private String briefingText;
private boolean strategicObjectivesBehaveAsVPs;
private String briefingText;

// these are applied to any scenario generated in the campaign; use sparingly
private List<String> globalScenarioModifiers = new ArrayList<>();
Expand Down Expand Up @@ -133,14 +132,6 @@ public void setBriefingText(String briefingText) {
this.briefingText = briefingText;
}

public boolean strategicObjectivesBehaveAsVPs() {
return strategicObjectivesBehaveAsVPs;
}

public void setStrategicObjectivesBehaveAsVPs(boolean strategicObjectivesBehaveAsVPs) {
this.strategicObjectivesBehaveAsVPs = strategicObjectivesBehaveAsVPs;
}

public List<String> getGlobalScenarioModifiers() {
return globalScenarioModifiers;
}
Expand Down
26 changes: 14 additions & 12 deletions MekHQ/src/mekhq/campaign/stratcon/StratconContractDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.File;
import java.io.FileInputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -167,9 +168,10 @@ public enum StrategicObjectiveType {
private List<ObjectiveParameters> objectiveParameters;

/**
* If true, strategic objective scenarios contribute to the VP count
* This is a list of scenario modifier names that apply to
* *every* mission generated in this contract. Use very sparingly.
*/
private boolean objectivesBehaveAsVPs;
private List<String> globalScenarioModifiers = new ArrayList<>();

private List<Integer> scenarioOdds;

Expand Down Expand Up @@ -255,14 +257,6 @@ public void setObjectiveParameters(List<ObjectiveParameters> objectiveParameters
this.objectiveParameters = objectiveParameters;
}

public boolean objectivesBehaveAsVPs() {
return objectivesBehaveAsVPs;
}

public void setObjectivesBehaveAsVPs(boolean objectivesBehaveAsVPs) {
this.objectivesBehaveAsVPs = objectivesBehaveAsVPs;
}

@XmlElementWrapper(name = "scenarioOdds")
@XmlElement(name = "scenarioOdds")
public List<Integer> getScenarioOdds() {
Expand All @@ -283,6 +277,14 @@ public void setDeploymentTimes(List<Integer> deploymentTimes) {
this.deploymentTimes = deploymentTimes;
}

public List<String> getGlobalScenarioModifiers() {
return globalScenarioModifiers;
}

public void setGlobalScenarioModifiers(List<String> globalScenarioModifiers) {
this.globalScenarioModifiers = globalScenarioModifiers;
}

/**
* Data structure that deals with the characteristics that a StratCon scenario objective may have
*/
Expand All @@ -307,15 +309,15 @@ public static class ObjectiveParameters {
*/
@XmlElementWrapper(name = "objectiveScenarios")
@XmlElement(name = "objectiveScenario")
List<String> objectiveScenarios;
List<String> objectiveScenarios = new ArrayList<>();

/**
* If a particular scenario being generated is a strategic objective, it will have
* these modifiers applied to it
*/
@XmlElementWrapper(name = "objectiveScenarioModifiers")
@XmlElement(name = "objectiveScenarioModifier")
List<String> objectiveScenarioModifiers;
List<String> objectiveScenarioModifiers = new ArrayList<>();
}

/**
Expand Down
44 changes: 30 additions & 14 deletions MekHQ/src/mekhq/campaign/stratcon/StratconContractInitializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public class StratconContractInitializer {
public static void initializeCampaignState(AtBContract contract, Campaign campaign, StratconContractDefinition contractDefinition) {
StratconCampaignState campaignState = new StratconCampaignState(contract);
campaignState.setBriefingText(contractDefinition.getBriefing() + "<br/>" + contract.getCommandRights().getStratConText());
campaignState.setStrategicObjectivesBehaveAsVPs(contractDefinition.objectivesBehaveAsVPs());

// dependency: this is required here in order for scenario initialization to work properly
contract.setStratconCampaignState(campaignState);
Expand Down Expand Up @@ -103,29 +102,43 @@ public static void initializeCampaignState(AtBContract contract, Campaign campai
objectiveParams.objectiveScenarios, objectiveParams.objectiveScenarioModifiers);
break;
case AlliedFacilityControl:
initializeTrackFacilities(campaignState.getTrack(x), numObjects, ForceAlignment.Allied, true);
initializeTrackFacilities(campaignState.getTrack(x), numObjects, ForceAlignment.Allied,
true, objectiveParams.objectiveScenarioModifiers);
break;
case HostileFacilityControl:
case FacilityDestruction:
initializeTrackFacilities(campaignState.getTrack(x), numObjects, ForceAlignment.Opposing, true);
initializeTrackFacilities(campaignState.getTrack(x), numObjects, ForceAlignment.Opposing,
true, objectiveParams.objectiveScenarioModifiers);
break;
case AnyScenarioVictory:
// set up a "win X scenarios" objective
StratconStrategicObjective sso = new StratconStrategicObjective();
sso.setDesiredObjectiveCount(numObjects);
sso.setObjectiveType(StrategicObjectiveType.AnyScenarioVictory);
campaignState.getTrack(x).addStrategicObjective(sso);

// modifiers defined for "any scenario" by definition apply to any scenario
// so they get added to the global campaign modifiers. Use sparingly since
// this can snowball pretty quickly.
if (objectiveParams.objectiveScenarioModifiers != null) {
for (String modifier : objectiveParams.objectiveScenarioModifiers) {
if (!campaignState.getGlobalScenarioModifiers().contains(modifier)) {
campaignState.getGlobalScenarioModifiers().add(modifier);
}
}
}

break;
}
}

// if any modifiers are to be applied across all scenarios in the campaign
// do so here; do not add duplicates
if (objectiveParams.objectiveScenarioModifiers != null) {
for (String modifier : objectiveParams.objectiveScenarioModifiers) {
if (!campaignState.getGlobalScenarioModifiers().contains(modifier)) {
campaignState.getGlobalScenarioModifiers().add(modifier);
}
}

// if any modifiers are to be applied across all scenarios in the campaign
// do so here; do not add duplicates
if (contractDefinition.getGlobalScenarioModifiers() != null) {
for (String modifier : contractDefinition.getGlobalScenarioModifiers() ) {
if (!campaignState.getGlobalScenarioModifiers().contains(modifier)) {
campaignState.getGlobalScenarioModifiers().add(modifier);
}
}
}
Expand All @@ -140,7 +153,8 @@ public static void initializeCampaignState(AtBContract contract, Campaign campai
for (int x = 0; x < trackObjects.size(); x++) {
int numObjects = trackObjects.get(x);

initializeTrackFacilities(campaignState.getTrack(x), numObjects, ForceAlignment.Allied, false);
initializeTrackFacilities(campaignState.getTrack(x), numObjects, ForceAlignment.Allied,
false, Collections.emptyList());
}

// non-objective hostile facilities
Expand All @@ -153,7 +167,8 @@ public static void initializeCampaignState(AtBContract contract, Campaign campai
for (int x = 0; x < trackObjects.size(); x++) {
int numObjects = trackObjects.get(x);

initializeTrackFacilities(campaignState.getTrack(x), numObjects, ForceAlignment.Opposing, false);
initializeTrackFacilities(campaignState.getTrack(x), numObjects, ForceAlignment.Opposing,
false, Collections.emptyList());
}

// now we're done
Expand Down Expand Up @@ -216,7 +231,7 @@ private static List<Integer> trackObjectDistribution(int numObjects, int numTrac
* Avoids places with existing facilities and scenarios, capable of taking facility sub set and setting strategic objective flag.
*/
private static void initializeTrackFacilities(StratconTrackState trackState, int numFacilities,
ForceAlignment owner, boolean strategicObjective) {
ForceAlignment owner, boolean strategicObjective, List<String> modifiers) {

int trackSize = trackState.getWidth() * trackState.getHeight();

Expand All @@ -232,6 +247,7 @@ private static void initializeTrackFacilities(StratconTrackState trackState, int

sf.setOwner(owner);
sf.setStrategicObjective(strategicObjective);
sf.getLocalModifiers().addAll(modifiers);

StratconCoords coords = getUnoccupiedCoords(trackState);

Expand Down
5 changes: 5 additions & 0 deletions MekHQ/src/mekhq/campaign/stratcon/StratconCoords.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,9 @@ public boolean equals(Object object) {
StratconCoords other = (StratconCoords) object;
return (other.getX() == this.getX()) && (other.getY() == this.getY());
}

@Override
public String toString() {
return String.format("%s, %s", getX(), getY());
}
}
6 changes: 1 addition & 5 deletions MekHQ/src/mekhq/gui/StratconTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import mekhq.campaign.event.NewDayEvent;
import mekhq.campaign.event.StratconDeploymentEvent;
import mekhq.campaign.mission.AtBContract;
import mekhq.campaign.mission.Contract;
import mekhq.campaign.stratcon.StratconCampaignState;
import mekhq.campaign.stratcon.StratconStrategicObjective;
import mekhq.campaign.stratcon.StratconTrackState;
Expand Down Expand Up @@ -339,11 +338,8 @@ private String buildStrategicObjectiveText(StratconCampaignState campaignState)
break;
}

// need to add:
// global (campaign-state level) "keep VP count above 0" for liaison/house/integrated

if (coordsRevealed && displayCoordinateData) {
sb.append(" at ").append(objective.getObjectiveCoords().toFriendlyString())
sb.append(" at ").append(objective.getObjectiveCoords().toString())
.append(" on ").append(track.getDisplayableName());
}

Expand Down

0 comments on commit c170d4a

Please sign in to comment.