From 520e41de7090a4acf5ddc70c0b3aedd8b38d2eea Mon Sep 17 00:00:00 2001 From: algebro Date: Fri, 16 Aug 2024 12:55:31 -0400 Subject: [PATCH] refactor hiring halls to support different levels; add new hiring halls --- MekHQ/data/universe/atbconfig.xml | 20 ++++---- .../resources/AtBConfigDefaults.properties | 2 +- .../againstTheBot/AtBConfiguration.java | 47 +++++++++++++++---- .../mekhq/campaign/universe/HiringHall.java | 36 ++++++++++++++ .../universe/enums/HiringHallLevel.java | 9 ++++ 5 files changed, 96 insertions(+), 18 deletions(-) create mode 100644 MekHQ/src/mekhq/campaign/universe/HiringHall.java create mode 100644 MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java diff --git a/MekHQ/data/universe/atbconfig.xml b/MekHQ/data/universe/atbconfig.xml index 4d34d06134d..fbeda1ad6b9 100644 --- a/MekHQ/data/universe/atbconfig.xml +++ b/MekHQ/data/universe/atbconfig.xml @@ -155,14 +155,18 @@ of 4. An entry of the form option has a weight of 1. follow yyyy-MM-dd format. Planet names much match the name in planets.xml exactly.--> - Outreach - Solaris - Arc-Royal - Fletcher - Galatea - Westerhand - Northwind - Herotitus + Outreach + Solaris + Arc-Royal + Fletcher + Galatea + Westerhand + Northwind + Herotitus + Antallos (Port Krin) + Astrokaszy + Noisiel + Le Blanc diff --git a/MekHQ/resources/mekhq/resources/AtBConfigDefaults.properties b/MekHQ/resources/mekhq/resources/AtBConfigDefaults.properties index d952b4cdc32..2299b46c2e7 100644 --- a/MekHQ/resources/mekhq/resources/AtBConfigDefaults.properties +++ b/MekHQ/resources/mekhq/resources/AtBConfigDefaults.properties @@ -10,7 +10,7 @@ botLance.CLAN=1:LLLLL,1:LLLLM,1:LLLMM|1:LLMMM,1:LMMMM,2:MMMMM,1:MMMMH,1:MMMHH|1: botLance.CS=1:LLLLLL,2:LLLLLM,2:LLLLMM,1:LLLMMM|1:LLLMMM,1:LLMMMM,1:LMMMMM,1:MMMMMM,1:MMMMMH,1:MMMMHH|1:MMMHHH,1:MMHHHH,1:MHHHHH,1:HHHHHH,1:HHHHHA,1:HHHHAA|2:HHHAAA,1:HHAAAA,2:HAAAAA,1:AAAAAA #The following are not required for AtB to function and are only used if atbconfig.xml is missing or broken -hiringHalls=3031-01-01,3067-10-15,Outreach|2700-01-01,,Solaris|3057-01-01,,Arc-Royal|3058-01-01,3081-03-15,Fletcher|2650-01-01,,Galatea|3000-01-01,,Westerhand|3057-01-01,3081-03-15,Northwind|3020-01-01,,Herotitus +hiringHalls=3031-01-01,3067-10-15,great,Outreach|2700-01-01,,minor,Solaris|3057-01-01,,standard,Arc-Royal|3058-01-01,3081-03-15,minor,Fletcher|2650-01-01,,great,Galatea|3000-01-01,,great,Westerhand|3057-01-01,3081-03-15,great,Northwind|3020-01-01,,minor,Herotitus|2694-01-01,,questionable,Antallos (Port Krin)|2912-01-01,,questionable,Astrokaszy|3052-01-01,,minor,Noisiel|2811-01-01,3045-01-01,minor,Le Blanc shipSearchCost=100000 shipSearchLengthWeeks=4 diff --git a/MekHQ/src/mekhq/campaign/againstTheBot/AtBConfiguration.java b/MekHQ/src/mekhq/campaign/againstTheBot/AtBConfiguration.java index 18b22ae7ff3..17325b6d0ab 100644 --- a/MekHQ/src/mekhq/campaign/againstTheBot/AtBConfiguration.java +++ b/MekHQ/src/mekhq/campaign/againstTheBot/AtBConfiguration.java @@ -24,6 +24,9 @@ import megamek.common.*; import megamek.common.annotations.Nullable; import mekhq.MekHQ; +import mekhq.campaign.universe.HiringHall; +import mekhq.campaign.universe.Planet; +import mekhq.campaign.universe.enums.HiringHallLevel; import mekhq.utilities.MHQXMLUtility; import mekhq.campaign.Campaign; import mekhq.campaign.finances.Money; @@ -72,7 +75,7 @@ public class AtBConfiguration { private HashMap>> botLanceTables = new HashMap<>(); /* Contract generation */ - private ArrayList> hiringHalls; + private HashMap hiringHalls = new HashMap<>(); /* Personnel and unit markets */ private Money shipSearchCost; @@ -87,7 +90,6 @@ public class AtBConfiguration { MekHQ.getMHQOptions().getLocale()); private AtBConfiguration() { - hiringHalls = new ArrayList<>(); dsTable = new WeightedTable<>(); jsTable = new WeightedTable<>(); shipSearchCost = Money.of(100000); @@ -158,10 +160,16 @@ private void setAllValuesToDefaults() { case "hiringHalls": for (String entry : property.split("\\|")) { String[] fields = entry.split(","); - hiringHalls.add(new DatedRecord<>( - !fields[0].isBlank() ? MHQXMLUtility.parseDate(fields[0]) : null, - !fields[1].isBlank() ? MHQXMLUtility.parseDate(fields[1]) : null, - fields[2])); + LocalDate startDate = !fields[0].isBlank() ? MHQXMLUtility.parseDate(fields[0]) : null; + LocalDate endDate = !fields[1].isBlank() ? MHQXMLUtility.parseDate(fields[1]) : null; + HiringHallLevel level = null; + try { + level = HiringHallLevel.valueOf(fields[2].toUpperCase()); + } catch (IllegalArgumentException ex) { + level = HiringHallLevel.GREAT; + } + String name = fields[3]; + hiringHalls.put(name, new HiringHall(level, startDate, endDate, name)); } break; case "shipSearchCost": @@ -284,8 +292,16 @@ public static String getParentFactionType(final Faction faction) { } public boolean isHiringHall(String planet, LocalDate date) { - return hiringHalls.stream().anyMatch( rec -> rec.getValue().equals(planet) - && rec.fitsDate(date)); + HiringHall hall = hiringHalls.get(planet); + return hall != null && hall.isActive(date); + } + + public HiringHallLevel getHiringHallLevel(String planet, LocalDate date) { + HiringHall hall = hiringHalls.get(planet); + if (hall != null && hall.isActive(date)) { + return hall.getLevel(); + } + return HiringHallLevel.NONE; } public Money getShipSearchCost() { @@ -467,7 +483,20 @@ private void loadContractGenerationNodeFromXml(Node node) { if (wn2.getAttributes().getNamedItem("end") != null) { end = MHQXMLUtility.parseDate(wn2.getAttributes().getNamedItem("end").getTextContent()); } - hiringHalls.add(new DatedRecord<>(start, end, wn2.getTextContent())); + HiringHallLevel level = HiringHallLevel.NONE; + if (wn2.getAttributes().getNamedItem("level") != null) { + try { + String text = wn2.getAttributes().getNamedItem("level").getTextContent().toUpperCase(); + level = HiringHallLevel.valueOf(wn2.getAttributes().getNamedItem("level").getTextContent().toUpperCase()); + } catch (IllegalArgumentException e) { + LogManager.getLogger().warn("Invalid value for Hiring Hall level, falling back to NONE: " + e); + } + } else { + // Backwards compatibility--hiring halls in atbconfig.xml should default to GREAT + level = HiringHallLevel.GREAT; + } + String planetName = wn2.getTextContent(); + hiringHalls.put(planetName, new HiringHall(level, start, end, planetName)); } } } diff --git a/MekHQ/src/mekhq/campaign/universe/HiringHall.java b/MekHQ/src/mekhq/campaign/universe/HiringHall.java new file mode 100644 index 00000000000..85949f9c788 --- /dev/null +++ b/MekHQ/src/mekhq/campaign/universe/HiringHall.java @@ -0,0 +1,36 @@ +package mekhq.campaign.universe; + +import mekhq.campaign.universe.enums.HiringHallLevel; + +import java.time.LocalDate; + +public class HiringHall { + private HiringHallLevel level; + private LocalDate startDate; + private LocalDate endDate; + private String planetName; + + public HiringHall(HiringHallLevel level, LocalDate startDate, LocalDate endDate, String planetName) { + this.level = level; + this.startDate = startDate; + this.endDate = endDate; + this.planetName = planetName; + } + + public boolean isActive(LocalDate date) { + return ((startDate == null) || !startDate.isAfter(date)) + && ((endDate == null) || !endDate.isBefore(date)); + } + + public String getPlanetName() { + return planetName; + } + + public HiringHallLevel getLevel() { + return level; + } + + public void setLevel(HiringHallLevel level) { + this.level = level; + } +} diff --git a/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java b/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java new file mode 100644 index 00000000000..823121c2d5e --- /dev/null +++ b/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java @@ -0,0 +1,9 @@ +package mekhq.campaign.universe.enums; + +public enum HiringHallLevel { + NONE, + QUESTIONABLE, + MINOR, + STANDARD, + GREAT +}