8000 feat: add actual board for acar by Scoppio · Pull Request #6938 · MegaMek/mekhq · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: add actual board for acar #6938

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 3 additions & 61 deletions MekHQ/src/mekhq/AtBGameThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import megamek.common.UnitType;
import megamek.common.annotations.Nullable;
import megamek.common.planetaryconditions.PlanetaryConditions;
import megamek.common.util.BoardUtilities;
import megamek.logging.MMLogger;
import mekhq.campaign.enums.CampaignTransportType;
import mekhq.campaign.force.Force;
Expand All @@ -80,6 +81,7 @@
import mekhq.campaign.unit.Unit;
import mekhq.utilities.MHQInternationalization;
import mekhq.utilities.PotentialTransportsMap;
import mekhq.utilities.ScenarioUtils;

/**
* Enhanced version of GameThread which imports settings and non-player units into the MM game
Expand Down Expand Up @@ -174,47 +176,7 @@ public void run() {
Thread.sleep(MekHQ.getMHQOptions().getStartGameDelay());
}

MapSettings mapSettings = MapSettings.getInstance();
mapSettings.setBoardSize(scenario.getMapX(), scenario.getMapY());
mapSettings.setMapSize(1, 1);
mapSettings.getBoardsSelectedVector().clear();

// if the scenario is taking place in space, do space settings instead
if (scenario.getBoardType() == Scenario.T_SPACE || scenario.getTerrainType().equals("Space")) {
mapSettings.setMedium(MapSettings.MEDIUM_SPACE);
mapSettings.getBoardsSelectedVector().add(MapSettings.BOARD_GENERATED);
} else if (scenario.isUsingFixedMap()) {
// TODO : remove inline file type
String board = scenario.getMap().replace(".board", "");
board = board.replace("\\", "/");
mapSettings.getBoardsSelectedVector().add(board);

if (scenario.getBoardType() == Scenario.T_ATMOSPHERE) {
mapSettings.setMedium(MapSettings.MEDIUM_ATMOSPHERE);
}
} else {
// TODO : Remove inline file path
File mapgenFile = new File("data/mapgen/" + scenario.getMap() + ".xml");
try (InputStream is = new FileInputStream(mapgenFile)) {
mapSettings = MapSettings.getInstance(is);
} catch (FileNotFoundException ex) {
Sentry.captureException(ex);
// TODO: Remove inline file path
logger.error(String.format("Could not load map file data/mapgen/%s.xml", scenario.getMap()),
ex);
}

if (scenario.getBoardType() == Scenario.T_ATMOSPHERE) {
mapSettings.setMedium(MapSettings.MEDIUM_ATMOSPHERE);
}

// duplicate code, but getting a new instance of map settings resets the size
// parameters
mapSettings.setBoardSize(scenario.getMapX(), scenario.getMapY());
mapSettings.setMapSize(1, 1);
mapSettings.getBoardsSelectedVector().add(MapSettings.BOARD_GENERATED);
}

MapSettings mapSettings = ScenarioUtils.getMapSettings(scenario);
client.sendMapSettings(mapSettings);
Thread.sleep(MekHQ.getMHQOptions().getStartGameDelay());

Expand Down Expand Up @@ -707,26 +669,6 @@ private BotClient setupPlayerBotForAutoResolve(Player player) throws Interrupted
return botClient;
}

private PlanetaryConditions getPlanetaryConditions() {
PlanetaryConditions planetaryConditions = new PlanetaryConditions();
if (campaign.getCampaignOptions().isUseLightConditions()) {
planetaryConditions.setLight(scenario.getLight());
}
if (campaign.getCampaignOptions().isUseWeatherConditions()) {
planetaryConditions.setWeather(scenario.getWeather());
planetaryConditions.setWind(scenario.getWind());
planetaryConditions.setFog(scenario.getFog());
planetaryConditions.setEMI(scenario.getEMI());
planetaryConditions.setBlowingSand(scenario.getBlowingSand());
planetaryConditions.setTemperature(scenario.getModifiedTemperature());
}
if (campaign.getCampaignOptions().isUsePlanetaryConditions()) {
planetaryConditions.setAtmosphere(scenario.getAtmosphere());
planetaryConditions.setGravity(scenario.getGravity());
}
return planetaryConditions;
}

/**
* wait for the server to add the bot client, then send starting position, camo, and entities
*
Expand Down
55 changes: 8 additions & 47 deletions MekHQ/src/mekhq/GameThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@
import megamek.common.Entity;
import megamek.common.MapSettings;
import megamek.common.WeaponOrderHandler;
import megamek.common.planetaryconditions.PlanetaryConditions;
import megamek.common.preference.PreferenceManager;
import megamek.logging.MMLogger;
import mekhq.campaign.Campaign;
import mekhq.campaign.force.Force;
import mekhq.campaign.mission.BotForce;
import mekhq.campaign.mission.Scenario;
import mekhq.campaign.unit.Unit;
import mekhq.utilities.ScenarioUtils;

class GameThread extends Thread implements CloseClientListener {
private static final MMLogger logger = MMLogger.create(GameThread.class);
Expand Down Expand Up @@ -207,56 +209,11 @@ public void run() {
Thread.sleep(MekHQ.getMHQOptions().getStartGameDelay());
}

MapSettings mapSettings = MapSettings.getInstance();

// check that we have valid conditions for setting the mapSettings
if ((scenario.getMapSizeX() > 1) && (scenario.getMapSizeY() > 1) && (null != scenario.getMap())) {

mapSettings.setBoardSize(scenario.getMapSizeX(), scenario.getMapSizeY());
mapSettings.setMapSize(1, 1);
mapSettings.getBoardsSelectedVector().clear();

// if the scenario is taking place in space, do space settings instead
if (scenario.getBoardType() == Scenario.T_SPACE) {
mapSettings.setMedium(MapSettings.MEDIUM_SPACE);
mapSettings.getBoardsSelectedVector().add(MapSettings.BOARD_GENERATED);
} else if (scenario.isUsingFixedMap()) {
String board = scenario.getMap().replace(".board", ""); // TODO : remove inline file type
board = board.replace("\\", "/");
mapSettings.getBoardsSelectedVector().add(board);

if (scenario.getBoardType() == Scenario.T_ATMOSPHERE) {
mapSettings.setMedium(MapSettings.MEDIUM_ATMOSPHERE);
}
} else {
File mapgenFile = new File("data/mapgen/" + scenario.getMap() + ".xml"); // TODO : remove inline
// file path
try (InputStream is = new FileInputStream(mapgenFile)) {
mapSettings = MapSettings.getInstance(is);
} catch (FileNotFoundException ex) {
logger.error(String.format("Could not load map file data/mapgen/%s.xml", scenario.getMap()),
ex);
// TODO: remove inline file path
}

if (scenario.getBoardType() == Scenario.T_ATMOSPHERE) {
mapSettings.setMedium(MapSettings.MEDIUM_ATMOSPHERE);
}

// duplicate code, but getting a new instance of map settings resets the size
// parameters
mapSettings.setBoardSize(scenario.getMapSizeX(), scenario.getMapSizeY());
mapSettings.setMapSize(1, 1);
mapSettings.getBoardsSelectedVector().add(MapSettings.BOARD_GENERATED);
}
} else {
logger.error(String.format("invalid map settings provided for scenario %s", scenario.getName()));
}

MapSettings mapSettings = ScenarioUtils.getMapSettings(scenario);
client.sendMapSettings(mapSettings);
Thread.sleep(MekHQ.getMHQOptions().getStartGameDelay());

client.sendPlanetaryConditions(scenario.createPlanetaryConditions());
client.sendPlanetaryConditions(getPlanetaryConditions());
Thread.sleep(MekHQ.getMHQOptions().getStartGameDelay());

// set player deployment
Expand Down Expand Up @@ -403,6 +360,10 @@ protected List<Entity> setupBotEntities(BotClient botClient, BotForce botForce,
return entities;
}

protected PlanetaryConditions getPlanetaryConditions() {
return campaign.getCurrentPlanetaryConditions(scenario);
}

/*
* from megamek.client.CloseClientListener clientClosed() Thanks to MM for
* adding the listener. And to MMNet for the poorly documented code change.
Expand Down
1 change: 1 addition & 0 deletions MekHQ/src/mekhq/MHQConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ public final class MHQConstants extends SuiteConstants {
public static final String PLANETARY_SYSTEM_DIRECTORY_PATH = "data/universe/planetary_systems";
public static final String FORCE_ICON_PATH = "data/images/force";
public static final String PERSONNEL_MARKET_DIRECTORY_PATH = "data/universe/markets/personnelMarket/";
public static final String MAPGEN_PATH = "data/mapgen";

// region StratCon
public static final String STRATCON_REQUIRED_HOSTILE_FACILITY_MODS = "./data/scenariomodifiers/requiredHostileFacilityModifiers.xml";
Expand Down
38 changes: 27 additions & 11 deletions MekHQ/src/mekhq/MekHQ.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,22 @@
import megamek.common.Board;
import megamek.common.annotations.Nullable;
import megamek.common.autoresolve.acar.SimulatedClient;
import megamek.common.autoresolve.converter.SetupForces;
import megamek.common.autoresolve.converter.SingletonForces;
import megamek.common.autoresolve.event.AutoResolveConcludedEvent;
import megamek.common.event.*;
import megamek.common.internationalization.I18n;
import megamek.common.net.marshalling.SanityInputFilter;
import megamek.common.planetaryconditions.PlanetaryConditions;
import megamek.logging.MMLogger;
import megamek.server.Server;
import megamek.server.totalwarfare.TWGameManager;
import megameklab.MegaMekLab;
import mekhq.campaign.Campaign;
import mekhq.campaign.CampaignController;
import mekhq.campaign.ResolveScenarioTracker;
import mekhq.campaign.autoresolve.AtBSetupForces;
import mekhq.campaign.autoresolve.MekHQSetupForces;
import mekhq.campaign.autoresolve.StratconSetupForces;
import mekhq.campaign.handler.PostScenarioDialogHandler;
import mekhq.campaign.handler.XPHandler;
import mekhq.campaign.mission.AtBDynamicScenario;
Expand All @@ -108,6 +111,7 @@
import mekhq.service.AutosaveService;
import mekhq.service.IAutosaveService;
import mekhq.utilities.MHQInternationalization;
import mekhq.utilities.ScenarioUtils;

/**
* The main class of the application.
Expand Down Expand Up @@ -749,30 +753,42 @@ public IconPackage getIconPackage() {
return iconPackage;
}

private SetupForces getSetupForces(Scenario scenario, List<Unit> units) {
if (scenario instanceof AtBScenario atBScenario) {
return new StratconSetupForces(getCampaign(), units, atBScenario, new SingletonForces());
}
return new MekHQSetupForces(getCampaign(), units, scenario, new SingletonForces());
}

/**
* This method is called when the player wants to auto resolve the scenario using ACAR method
*
* @param units The list of player units involved in the scenario
*/
public void startAutoResolve(AtBScenario scenario, List<Unit> units) {

public void startAutoResolve(Scenario scenario, List<Unit> units) {
this.autosaveService.requestBeforeScenarioAutosave(getCampaign());

Board board = ScenarioUtils.getBoardFor(scenario);
SetupForces setupForces = getSetupForces(scenario, units);

PlanetaryConditions planetaryConditions = getCampaign().getCurrentPlanetaryConditions(scenario);
if (getCampaign().getCampaignOptions().isAutoResolveVictoryChanceEnabled()) {

var proceed = AutoResolveChanceDialog.showDialog(campaignGUI.getFrame(),
getCampaign().getCampaignOptions().getAutoResolveNumberOfScenarios(),
Runtime.getRuntime().availableProcessors(),
1,
new AtBSetupForces(getCampaign(), units, scenario, new SingletonForces()),
new Board(scenario.getBaseMapX(), scenario.getBaseMapY())) == JOptionPane.YES_OPTION;
setupForces,
board,
planetaryConditions) == JOptionPane.YES_OPTION;
if (!proceed) {
return;
}
}

var event = AutoResolveProgressDialog.showDialog(campaignGUI.getFrame(),
new AtBSetupForces(getCampaign(), units, scenario, new SingletonForces()),
new Board(scenario.getBaseMapX(), scenario.getBaseMapY()));
setupForces,
board, planetaryConditions);

var autoResolveBattleReport = new AutoResolveSimulationLogDialog(campaignGUI.getFrame(), event.getLogFile());
autoResolveBattleReport.setModal(true);
Expand All @@ -786,16 +802,16 @@ public void startAutoResolve(AtBScenario scenario, List<Unit> units) {
*
* @param autoResolveConcludedEvent The event that contains the results of the auto resolve game.
*/
public void autoResolveConcluded(AutoResolveConcludedEvent autoResolveConcludedEvent, AtBScenario scenario) {
public void autoResolveConcluded(AutoResolveConcludedEvent autoResolveConcludedEvent, Scenario scenario) {
try {
String victoryMessage = autoResolveConcludedEvent.controlledScenario() ?
MHQInternationalization.getText("AutoResolveDialog.message.victory") :
MHQInternationalization.getText("AutoResolveDialog.message.defeat");

String decisionMessage = MHQInternationalization.getText("ResolveDialog.control.message");

if (scenario instanceof AtBDynamicScenario) {
ScenarioTemplate template = ((AtBDynamicScenario) scenario).getTemplate();
if (scenario instanceof AtBDynamicScenario atBDynamicScenario) {
ScenarioTemplate template = atBDynamicScenario.getTemplate();

if (template != null) {
BattlefieldControlType battlefieldControl = template.getBattlefieldControl();
Expand Down Expand Up @@ -835,7 +851,7 @@ public void autoResolveConcluded(AutoResolveConcludedEvent autoResolveConcludedE
}
}

private void postAbortedAutoResolve(AutoResolveConcludedEvent autoResolveConcludedEvent, AtBScenario scenario,
private void postAbortedAutoResolve(AutoResolveConcludedEvent autoResolveConcludedEvent, Scenario scenario,
ResolveScenarioTracker tracker) {
try {
resetPersonsHits(tracker);
Expand Down
28 changes: 28 additions & 0 deletions MekHQ/src/mekhq/campaign/Campaign.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
import megamek.common.options.IOption;
import megamek.common.options.IOptionGroup;
import megamek.common.options.OptionsConstants;
import megamek.common.planetaryconditions.PlanetaryConditions;
import megamek.common.util.BuildingBlock;
import megamek.logging.MMLogger;
import mekhq.MHQConstants;
Expand Down Expand Up @@ -7736,6 +7737,33 @@ public TargetRoll getTargetForAcquisition(final IAcquisitionWork acquisition, fi
return getTargetForAcquisition(acquisition, person, false);
}

public PlanetaryConditions getCurrentPlanetaryConditions(Scenario scenario) {
PlanetaryConditions planetaryConditions = new PlanetaryConditions();
if (scenario instanceof AtBScenario atBScenario) {
if (getCampaignOptions().isUseLightConditions()) {
planetaryConditions.setLight(atBScenario.getLight());
}
if (getCampaignOptions().isUseWeatherConditions()) {
planetaryConditions.setWeather(atBScenario.getWeather());
planetaryConditions.setWind(atBScenario.getWind());
planetaryConditions.setFog(atBScenario.getFog());
planetaryConditions.setEMI(atBScenario.getEMI());
planetaryConditions.setBlowingSand(atBScenario.getBlowingSand());
planetaryConditions.setTemperature(atBScenario.getModifiedTemperature());

}
if (getCampaignOptions().isUsePlanetaryConditions()) {
planetaryConditions.setAtmosphere(atBScenario.getAtmosphere());
planetaryConditions.setGravity(atBScenario.getGravity());
}
} else {
planetaryConditions = scenario.createPlanetaryConditions();
}

return planetaryConditions;

}

/**
* Determines the target roll required for successfully acquiring a specific part or unit based on various campaign
* settings, the acquisition details, and the person attempting the acquisition.
Expand Down
60 changes: 60 additions & 0 deletions MekHQ/src/mekhq/campaign/autoresolve/MekHQSetupForces.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (C) 2025 The MegaMek Team. All Rights Reserved.
*
* This file is part of MegaMek.
*
* MegaMek is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License (GPL),
* version 3 or (at your option) any later version,
* as published by the Free Software Foundation.
*
* MegaMek is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* A copy of the GPL should have been included with this project;
* if not, see <https://www.gnu.org/licenses/>.
*
* NOTICE: The MegaMek organization is a non-profit group of volunteers
* creating free software for the BattleTech community.
*
* MechWarrior, BattleMech, `Mech and AeroTech are registered trademarks
* of The Topps Company, Inc. All Rights Reserved.
*
* Catalyst Game Labs and the Catalyst Game Labs logo are trademarks of
* InMediaRes Productions, LLC.
*
* MechWarrior Copyright Microsoft Corporation. MegaMek was created under
* Microsoft's "Game Content Usage Rules"
* <https://www.xbox.com/en-US/developers/rules> and it is not endorsed by or
* affiliated with Microsoft.
*/
package mekhq.campaign.autoresolve;

import java.util.List;

import megamek.common.autoresolve.converter.ForceConsolidation;
import megamek.logging.MMLogger;
import mekhq.campaign.Campaign;
import mekhq.campaign.mission.Scenario;
import mekhq.campaign.unit.Unit;

/**
* This class is responsible for setting up the forces for a scenario
* @author Luana Coppio
*/
public class MekHQSetupForces extends ScenarioSetupForces<Scenario> {
private static final MMLogger LOGGER = MMLogger.create(MekHQSetupForces.class);


public MekHQSetupForces(Campaign campaign, List<Unit> units, Scenario scenario,
ForceConsolidation forceConsolidationMethod) {
super(campaign, units, scenario, forceConsolidationMethod, new OrderFactory(campaign, scenario));
}

public MekHQSetupForces(Campaign campaign, List<Unit> units, Scenario scenario,
ForceConsolidation forceConsolidationMethod, OrderFactory orderFactory) {
super(campaign, units, scenario, forceConsolidationMethod, orderFactory);
}
}
Loading
Loading
0