From a540a30f43698adeb4d7d0c47bb786c1def3a590 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 10 Feb 2025 11:31:50 -0800 Subject: [PATCH 01/10] Change xml recording of hiring halls --- .../planetary_systems/system_events.xml | 49 +++++++++++++++++ MekHQ/data/universe/systems.xml | 52 ------------------- 2 files changed, 49 insertions(+), 52 deletions(-) diff --git a/MekHQ/data/universe/planetary_systems/system_events.xml b/MekHQ/data/universe/planetary_systems/system_events.xml index f4a3505fe55..cac1984f278 100644 --- a/MekHQ/data/universe/planetary_systems/system_events.xml +++ b/MekHQ/data/universe/planetary_systems/system_events.xml @@ -49693,6 +49693,10 @@ 2690-01-01 527861 + + 2694-01-01 + QUESTIONABLE + 2700-01-01 950115 @@ -55967,6 +55971,10 @@ 3050-01-01 2049886673 + + 3057-01-01 + STANDARD + 3057-11-20 LA,CWIE @@ -67379,6 +67387,10 @@ 2910-01-01 203935 + + 2912-01-01 + QUESTIONABLE + 2914-01-01 D-D-C-C-D @@ -290655,6 +290667,10 @@ 3057-11-01 CM + + 3058-01-01 + MINOR + 3060-01-01 1068129202 @@ -290679,6 +290695,10 @@ 3080-01-01 1092871580 + + 3081-03-15 + NONE + 3081-10-16 ROS @@ -302936,6 +302956,7 @@ 2650-01-01 594885097 + GREAT 2660-01-01 @@ -362457,6 +362478,7 @@ 3020-01-01 252601 + MINOR 3025-01-01 @@ -484649,6 +484671,10 @@ 2810-01-01 117826489 + + 2811-01-01 + MINOR + 2820-01-01 110752446 @@ -484757,6 +484783,10 @@ 3042-01-01 D-D-B-F-D + + 3045-01-01 + NONE + 3050-01-01 56349558 @@ -623087,6 +623117,10 @@ 3050-01-01 167836896 + + 3052-01-01 + MINOR + 3057-09-18 LA @@ -625447,6 +625481,10 @@ 3050-01-01 1638867276 + + 3057-01-01 + STANDARD + 3057-11-01 MERC @@ -625471,6 +625509,10 @@ 3080-01-01 1673814775 + + 3081-03-15 + NONE + 3081-08-13 ROS @@ -648431,6 +648473,7 @@ MERC 1696188118 B-B-C-B-B + GREAT 3040-01-01 @@ -648448,6 +648491,10 @@ 3060-01-01 1747320462 + + 3067-10-15 + NONE + 3067-12-26 WOB @@ -786669,6 +786716,7 @@ 2700-01-01 1302174644 + MINOR 2710-01-01 @@ -916662,6 +916710,7 @@ 3000-01-01 987050454 + STANDARD 3010-01-01 diff --git a/MekHQ/data/universe/systems.xml b/MekHQ/data/universe/systems.xml index 79e10930062..3f10851deec 100644 --- a/MekHQ/data/universe/systems.xml +++ b/MekHQ/data/universe/systems.xml @@ -35472,10 +35472,6 @@ A few Stone Age tribes exist in the planet's deep deserts and jungles, far from 281.417 K4IV 3 - - 2694-01-01 - QUESTIONABLE - Riverhead Giant Terrestrial @@ -40717,10 +40713,6 @@ Arboris has a history of fierce independence. In 2308, Arboris seceded from the 226.576 G3V 4 - - 3057-01-01 - STANDARD - Plowden's Stand Dwarf Terrestrial @@ -48869,10 +48861,6 @@ Though a major exporter of heavy metals and radioactive elements, as well as sma -315.408 G4V 3 - - 2912-01-01 - QUESTIONABLE - Frey Dwarf Terrestrial @@ -221726,11 +221714,6 @@ Coalition Armory -23.569 G4V 7 - - 3058-01-01 - 3081-03-15 - MINOR - Csurgói Járás Terrestrial @@ -230648,10 +230631,6 @@ At the dawn the thirty-second century, a surgical strike from the Lyran Commonwe 34.077 F8II 6 - - 2650-01-01 - GREAT - Skouzas's Frontier Terrestrial @@ -280574,10 +280553,6 @@ Freeport Armorworks -430.11 G3IV 2 - - 3020-01-01 - MINOR - Mugoma Giant Terrestrial @@ -373852,11 +373827,6 @@ Aside from the large island continent of Galapagos in the northern hemisphere of 18.309 G0III 4 - - 2811-01-01 - 3045-01-01 - MINOR - Port de Nedelec Terrestrial @@ -480826,10 +480796,6 @@ Niops V and VI were settled primarily to expand the available resources to the N 148.073 K0V 3 - - 3052-01-01 - MINOR - Kaarst Terrestrial @@ -482497,11 +482463,6 @@ During the Fourth Succession War, the Federated Suns leaked false reports of ung -2.891 G2IV 2 - - 3057-01-01 - 3081-03-15 - GREAT - Bloomsburg Giant Terrestrial @@ -499005,11 +498966,6 @@ Rim Motors -34.688 K9V 2 - - 3031-01-01 - 3067-10-15 - GREAT - Chen Dwarf Terrestrial @@ -601733,10 +601689,6 @@ During the Jihad, the Word of Blake forces invaded after they neutralized the de -7.025 K1V 7 - - 2700-01-01 - MINOR - Sanopi Dwarf Terrestrial @@ -701619,10 +701571,6 @@ Wei is home to one of the many Duchy RTC training facilities in the Confederatio -276.084 G3V 2 - - 3000-01-01 - GREAT - High Kelling Giant Terrestrial From ba4fb6b566824c216f33f233eb956a941842f118 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 10 Feb 2025 12:35:44 -0800 Subject: [PATCH 02/10] Fix xml error on closing tag --- MekHQ/data/universe/planetary_systems/system_events.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MekHQ/data/universe/planetary_systems/system_events.xml b/MekHQ/data/universe/planetary_systems/system_events.xml index cac1984f278..b7f84b52f5c 100644 --- a/MekHQ/data/universe/planetary_systems/system_events.xml +++ b/MekHQ/data/universe/planetary_systems/system_events.xml @@ -290697,7 +290697,7 @@ 3081-03-15 - NONE + NONE 3081-10-16 From 1f481f31732b0691895e24a3ffbb36c58d1ed973 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 10 Feb 2025 12:55:37 -0800 Subject: [PATCH 03/10] Update xml planet loading for new location of hiring hall information --- .../src/mekhq/adapter/HiringHallAdapter.java | 35 +++++++ MekHQ/src/mekhq/campaign/universe/Planet.java | 94 +++++++++++++++++-- .../campaign/universe/PlanetarySystem.java | 94 ++++--------------- .../universe/enums/HiringHallLevel.java | 14 ++- 4 files changed, 149 insertions(+), 88 deletions(-) create mode 100644 MekHQ/src/mekhq/adapter/HiringHallAdapter.java diff --git a/MekHQ/src/mekhq/adapter/HiringHallAdapter.java b/MekHQ/src/mekhq/adapter/HiringHallAdapter.java new file mode 100644 index 00000000000..be83ca9361a --- /dev/null +++ b/MekHQ/src/mekhq/adapter/HiringHallAdapter.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019-2022 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MekHQ. + * + * MekHQ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * MekHQ 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. + * + * You should have received a copy of the GNU General Public License + * along with MekHQ. If not, see . + */ + +package mekhq.adapter; + +import jakarta.xml.bind.annotation.adapters.XmlAdapter; +import mekhq.campaign.universe.enums.HiringHallLevel; + +public class HiringHallAdapter extends XmlAdapter { + @Override + public HiringHallLevel unmarshal(String v) throws Exception { + return HiringHallLevel.parseHiringHallLevel(v); + } + + @Override + public String marshal(HiringHallLevel v) throws Exception { + return v.toString(); + } +} diff --git a/MekHQ/src/mekhq/campaign/universe/Planet.java b/MekHQ/src/mekhq/campaign/universe/Planet.java index bc701e358dd..48955e539e1 100644 --- a/MekHQ/src/mekhq/campaign/universe/Planet.java +++ b/MekHQ/src/mekhq/campaign/universe/Planet.java @@ -36,17 +36,10 @@ import megamek.common.TargetRoll; import megamek.logging.MMLogger; import mekhq.Utilities; -import mekhq.adapter.AtmosphereAdapter; -import mekhq.adapter.BooleanValueAdapter; -import mekhq.adapter.ClimateAdapter; -import mekhq.adapter.DateAdapter; -import mekhq.adapter.HPGRatingAdapter; -import mekhq.adapter.LifeFormAdapter; -import mekhq.adapter.PressureAdapter; -import mekhq.adapter.SocioIndustrialDataAdapter; -import mekhq.adapter.StringListAdapter; +import mekhq.adapter.*; import mekhq.campaign.CampaignOptions; import mekhq.campaign.universe.Faction.Tag; +import mekhq.campaign.universe.enums.HiringHallLevel; /** * This is the start of a planet object that will keep lots of information about @@ -133,6 +126,7 @@ public class Planet { @XmlElement(name = "faction") @XmlJavaTypeAdapter(StringListAdapter.class) private List factions; + private HiringHallLevel hiringHall = HiringHallLevel.NONE; // private List garrisonUnits; @@ -725,6 +719,80 @@ public String getFactionDesc(LocalDate when) { return toReturn; } + /** + * Checks whether a hiring hall exists on the planet on the specified date + * + * @param when Date to check for existence of hiring hall + * @return True if a hiring hall exists on the given date; otherwise false. + */ + public boolean isHiringHall(LocalDate when) { + return getHiringHallLevel(when) != HiringHallLevel.NONE; + } + + /** + * Retrieves the level of the Hiring Hall on the planet on the specified + * date. The level is dynamically determined on various planetary characteristics, + * including Technological Sophistication, HPG level, and planetary governments. + * + * @param when Date to check for the level of the hiring hall + * @return The hiring hall level on the given date + */ + public HiringHallLevel getHiringHallLevel(LocalDate when) { + return getEventData(when, hiringHall, e -> e.hiringHall); + /*if (staticHall != null && staticHall.isActive(date)) { + return staticHall.getLevel(); + } + if (getPopulation(date) == 0) { + return HiringHallLevel.NONE; + } + for (Faction faction : getFactionSet(date)) { + if (faction.isPirate() || faction.isChaos()) { + return HiringHallLevel.QUESTIONABLE; + } + if (faction.isClan()) { + return HiringHallLevel.NONE; + } + } + int score = calculateHiringHallScore(date); + return resolveHiringHallLevel(score);*/ + } + + private int calculateHiringHallScore(LocalDate date) { + int score = 0; + score += getHiringHallHpgBonus(date); + score += getHiringHallTechBonus(date); + return score; + } + + private HiringHallLevel resolveHiringHallLevel(int score) { + if (score > 9) { + return HiringHallLevel.GREAT; + } else if (score > 6) { + return HiringHallLevel.STANDARD; + } else if (score > 4) { + return HiringHallLevel.MINOR; + } + return HiringHallLevel.NONE; + } + + private int getHiringHallHpgBonus(LocalDate date) { + return switch (getHPG(date)) { + case EquipmentType.RATING_A -> 5; + case EquipmentType.RATING_B -> 3; + case EquipmentType.RATING_C, EquipmentType.RATING_D -> 1; + default -> 0; + }; + } + + private int getHiringHallTechBonus(LocalDate date) { + return switch (getSocioIndustrial(date).tech) { + case -1 -> 5; // Ultra-Advanced; not accounted for in the EquipmentType.RATING constants + case EquipmentType.RATING_A, EquipmentType.RATING_B -> 3; + case EquipmentType.RATING_C, EquipmentType.RATING_D -> 1; + default -> 0; + }; + } + /** * @return the distance to another planet in light years (0 if both are in the * same system) @@ -1124,6 +1192,9 @@ public static final class PlanetaryEvent { public SocioIndustrialData socioIndustrial; @XmlJavaTypeAdapter(HPGRatingAdapter.class) public Integer hpg; + @XmlElement(name = "hiringHall") + @XmlJavaTypeAdapter(HiringHallAdapter.class) + private HiringHallLevel hiringHall; @XmlJavaTypeAdapter(PressureAdapter.class) private Integer pressure; @XmlJavaTypeAdapter(AtmosphereAdapter.class) @@ -1145,6 +1216,7 @@ public void copyDataFrom(PlanetaryEvent other) { percentWater = ObjectUtility.nonNull(other.percentWater, percentWater); shortName = ObjectUtility.nonNull(other.shortName, shortName); socioIndustrial = ObjectUtility.nonNull(other.socioIndustrial, socioIndustrial); + hiringHall = ObjectUtility.nonNull(other.hiringHall, hiringHall); temperature = ObjectUtility.nonNull(other.temperature, temperature); pressure = ObjectUtility.nonNull(other.pressure, pressure); atmosphere = ObjectUtility.nonNull(other.atmosphere, atmosphere); @@ -1175,6 +1247,7 @@ public void replaceDataFrom(PlanetaryEvent other) { percentWater = other.percentWater; shortName = other.shortName; socioIndustrial = other.socioIndustrial; + hiringHall = other.hiringHall; temperature = other.temperature; pressure = other.pressure; atmosphere = other.atmosphere; @@ -1189,7 +1262,8 @@ public boolean isEmpty() { return (null == climate) && (null == faction) && (null == hpg) && (null == lifeForm) && (null == message) && (null == name) && (null == shortName) && (null == socioIndustrial) && (null == temperature) && (null == pressure) && (null == atmosphere) - && (null == composition) && (null == population) && (null == dayLength); + && (null == composition) && (null == population) && (null == dayLength) + && (null == hiringHall); } } diff --git a/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java b/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java index 0e9a36c338d..4fa772a4bbc 100644 --- a/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java +++ b/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java @@ -133,9 +133,6 @@ public class PlanetarySystem { // the location of the primary planet for this system private int primarySlot; - @XmlElement(name = "hiringHall") - private HiringHallOverride staticHall = null; - /** Marker for "please delete this system" */ @XmlJavaTypeAdapter(value = BooleanValueAdapter.class) public Boolean delete; @@ -265,6 +262,22 @@ public Integer getHPG(LocalDate when) { return rating; } + /** @return the highest Hiring Hall rating among planets **/ + public HiringHallLevel getHiringHallLevel(LocalDate when) { + HiringHallLevel level = HiringHallLevel.NONE; + for (Planet planet : planets.values()) { + if ((null != planet.getHiringHallLevel(when)) && (planet.getHiringHallLevel(when).compareTo(level) > 0)) { + level = planet.getHiringHallLevel(when); + } + } + return level; + } + + /** @return true if a hiring hall is present in the system **/ + public boolean isHiringHall(LocalDate when) { + return getHiringHallLevel(when) != HiringHallLevel.NONE; + } + /** * @return short name if set, else full name, else "unnamed" */ @@ -728,82 +741,9 @@ public String getAcademiesForSystem(List filteredAcademies) { for (Academy academy : filteredAcademies) { // there are not enough entries to justify a Stream academyString.append("").append(academy.getName()).append("
") - .append(academy.getDescription()).append("

"); + .append(academy.getDescription()).append("

"); } return academyString.toString(); } - - /** - * Checks whether a hiring hall exists in the planetary system on the specified date - * - * @param date Date to check for existence of hiring hall - * @return True if a hiring hall exists on the given date; otherwise false. - */ - public boolean isHiringHall(LocalDate date) { - return getHiringHallLevel(date) != HiringHallLevel.NONE; - } - - /** - * Retrieves the level of the Hiring Hall in the planetary system on the specified - * date. The level is dynamically determined on various planetary characteristics, - * including Technological Sophistication, HPG level, and planetary governments. - * - * @param date Date to check for the level of the hiring hall - * @return The hiring hall level on the given date - */ - public HiringHallLevel getHiringHallLevel(LocalDate date) { - if (staticHall != null && staticHall.isActive(date)) { - return staticHall.getLevel(); - } - if (getPopulation(date) == 0) { - return HiringHallLevel.NONE; - } - for (Faction faction : getFactionSet(date)) { - if (faction.isPirate() || faction.isChaos()) { - return HiringHallLevel.QUESTIONABLE; - } - if (faction.isClan()) { - return HiringHallLevel.NONE; - } - } - int score = calculateHiringHallScore(date); - return resolveHiringHallLevel(score); - } - - private int calculateHiringHallScore(LocalDate date) { - int score = 0; - score += getHiringHallHpgBonus(date); - score += getHiringHallTechBonus(date); - return score; - } - - private HiringHallLevel resolveHiringHallLevel(int score) { - if (score > 9) { - return HiringHallLevel.GREAT; - } else if (score > 6) { - return HiringHallLevel.STANDARD; - } else if (score > 4) { - return HiringHallLevel.MINOR; - } - return HiringHallLevel.NONE; - } - - private int getHiringHallHpgBonus(LocalDate date) { - return switch (getHPG(date)) { - case EquipmentType.RATING_A -> 5; - case EquipmentType.RATING_B -> 3; - case EquipmentType.RATING_C, EquipmentType.RATING_D -> 1; - default -> 0; - }; - } - - private int getHiringHallTechBonus(LocalDate date) { - return switch (getSocioIndustrial(date).tech) { - case -1 -> 5; // Ultra-Advanced; not accounted for in the EquipmentType.RATING constants - case EquipmentType.RATING_A, EquipmentType.RATING_B -> 3; - case EquipmentType.RATING_C, EquipmentType.RATING_D -> 1; - default -> 0; - }; - } } diff --git a/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java b/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java index b4de49dd279..0ed8d6fa0e7 100644 --- a/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java +++ b/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java @@ -27,5 +27,17 @@ public enum HiringHallLevel { QUESTIONABLE, MINOR, STANDARD, - GREAT + GREAT; + + public static HiringHallLevel parseHiringHallLevel(String val) { + return switch (val.toLowerCase()) { + case "questionable" -> QUESTIONABLE; + case "minor" -> MINOR; + case "standard" -> STANDARD; + case "great" -> GREAT; + default -> NONE; + }; + } } + + From 49998c2ad875c660fa718785413eb79bd9dd1aea Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 10 Feb 2025 13:05:43 -0800 Subject: [PATCH 04/10] Display hiring hall on actual planet, not for planetary system --- .../campaign/universe/HiringHallOverride.java | 83 ------------------- MekHQ/src/mekhq/gui/view/PlanetViewPanel.java | 3 +- 2 files changed, 1 insertion(+), 85 deletions(-) delete mode 100644 MekHQ/src/mekhq/campaign/universe/HiringHallOverride.java diff --git a/MekHQ/src/mekhq/campaign/universe/HiringHallOverride.java b/MekHQ/src/mekhq/campaign/universe/HiringHallOverride.java deleted file mode 100644 index 8c9dcef3b6d..00000000000 --- a/MekHQ/src/mekhq/campaign/universe/HiringHallOverride.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. - * - * This file is part of MekHQ. - * - * MekHQ is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * MekHQ 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. - * - * You should have received a copy of the GNU General Public License - * along with MekHQ. If not, see . - */ -package mekhq.campaign.universe; - -import jakarta.xml.bind.annotation.*; -import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import mekhq.adapter.LocalDateAdapter; -import mekhq.campaign.universe.enums.HiringHallLevel; - -import java.time.LocalDate; - -/** - * Class representing an "override" for the dynamic hiring hall system. Normally, hiring halls are - * generated dynamically based on planetary system factors like tech level and HPG quality, but some - * canonical systems should have hiring halls of certain qualities despite what the dynamic formula - * says. - * Overrides are stored as child elements of planetary systems in systems.xml, with a start date, - * optional end date, and quality. - */ -@XmlRootElement(name = "hiringHall") -@XmlAccessorType(value = XmlAccessType.FIELD) -public class HiringHallOverride { - @XmlJavaTypeAdapter(value = LocalDateAdapter.class) - private LocalDate start = null; - @XmlJavaTypeAdapter(value = LocalDateAdapter.class) - private LocalDate end = null; - @XmlElement - private HiringHallLevel level = HiringHallLevel.NONE; - - /** - * Gets the level of the hiring hall for this override - * - * @return The hiring hall level as an enum - */ - public HiringHallLevel getLevel() { - return level; - } - - /** - * Sets the hiring hall level for this override - * - * @param level The level of hiring hall - */ - public void setLevel(HiringHallLevel level) { - this.level = level; - } - - /** - * Checks whether the hiring hall is active on a certain date. Returns true if no end date is - * specified in the override. - * - * @param date The date to check whether the hiring hall is active - * @return boolean representing whether the hiring hall is active - */ - public boolean isActive(LocalDate date) { - // Hall has no start date, so it's always inactive - if (start == null) { - return false; - } - // Hall has a start date and no end date, so it's always active - if (end == null) { - return true; - } - // Hall has a start date and end date, so it's only active between those dates - return date.isAfter(start) && date.isBefore(end); - } -} diff --git a/MekHQ/src/mekhq/gui/view/PlanetViewPanel.java b/MekHQ/src/mekhq/gui/view/PlanetViewPanel.java index 2f7f4c0fe66..ea5f5363fe8 100644 --- a/MekHQ/src/mekhq/gui/view/PlanetViewPanel.java +++ b/MekHQ/src/mekhq/gui/view/PlanetViewPanel.java @@ -336,8 +336,7 @@ private JPanel getPlanetPanel(Planet planet) { gbcLabel.gridy = infoRow; panel.add(lblHiringHall, gbcLabel); JLabel textHiringHall = new JLabel(StringUtils.capitalize( - planet.getParentSystem() - .getHiringHallLevel(currentDate) + planet.getHiringHallLevel(currentDate) .name() .toLowerCase())); gbcText.gridy = infoRow; From 5041b6e653431bb5d2b7273a5c92c6e90751c09b Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 10 Feb 2025 13:16:20 -0800 Subject: [PATCH 05/10] Add convenience isNone method to HiringHallLevel class --- MekHQ/src/mekhq/campaign/universe/Planet.java | 2 +- MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java | 2 +- MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/universe/Planet.java b/MekHQ/src/mekhq/campaign/universe/Planet.java index 48955e539e1..a18b5d9eb93 100644 --- a/MekHQ/src/mekhq/campaign/universe/Planet.java +++ b/MekHQ/src/mekhq/campaign/universe/Planet.java @@ -726,7 +726,7 @@ public String getFactionDesc(LocalDate when) { * @return True if a hiring hall exists on the given date; otherwise false. */ public boolean isHiringHall(LocalDate when) { - return getHiringHallLevel(when) != HiringHallLevel.NONE; + return !getHiringHallLevel(when).isNone(); } /** diff --git a/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java b/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java index 4fa772a4bbc..f3286d52248 100644 --- a/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java +++ b/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java @@ -275,7 +275,7 @@ public HiringHallLevel getHiringHallLevel(LocalDate when) { /** @return true if a hiring hall is present in the system **/ public boolean isHiringHall(LocalDate when) { - return getHiringHallLevel(when) != HiringHallLevel.NONE; + return !getHiringHallLevel(when).isNone(); } /** diff --git a/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java b/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java index 0ed8d6fa0e7..701f141df09 100644 --- a/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java +++ b/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java @@ -38,6 +38,11 @@ public static HiringHallLevel parseHiringHallLevel(String val) { default -> NONE; }; } + + public boolean isNone() { + return this == NONE; + } + } From 45ea317fbc82f5a227af29ca2f6fda3f65707ccb Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 10 Feb 2025 13:37:08 -0800 Subject: [PATCH 06/10] Add back in code for dynamically generating hiring halls, with checks for NPE --- MekHQ/src/mekhq/campaign/universe/Planet.java | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/universe/Planet.java b/MekHQ/src/mekhq/campaign/universe/Planet.java index a18b5d9eb93..f1369c06640 100644 --- a/MekHQ/src/mekhq/campaign/universe/Planet.java +++ b/MekHQ/src/mekhq/campaign/universe/Planet.java @@ -738,29 +738,29 @@ public boolean isHiringHall(LocalDate when) { * @return The hiring hall level on the given date */ public HiringHallLevel getHiringHallLevel(LocalDate when) { - return getEventData(when, hiringHall, e -> e.hiringHall); - /*if (staticHall != null && staticHall.isActive(date)) { - return staticHall.getLevel(); + HiringHallLevel staticHall = getEventData(when, hiringHall, e -> e.hiringHall); + if (!staticHall.isNone()) { + return staticHall; } - if (getPopulation(date) == 0) { + if (getPopulation(when) == null || getPopulation(when) == 0) { return HiringHallLevel.NONE; } - for (Faction faction : getFactionSet(date)) { + for (Faction faction : getFactionSet(when)) { if (faction.isPirate() || faction.isChaos()) { return HiringHallLevel.QUESTIONABLE; } - if (faction.isClan()) { + if (faction.isClan() || faction.isInactive()) { return HiringHallLevel.NONE; } } - int score = calculateHiringHallScore(date); - return resolveHiringHallLevel(score);*/ + int score = calculateHiringHallScore(when); + return resolveHiringHallLevel(score); } - private int calculateHiringHallScore(LocalDate date) { + private int calculateHiringHallScore(LocalDate when) { int score = 0; - score += getHiringHallHpgBonus(date); - score += getHiringHallTechBonus(date); + score += getHiringHallHpgBonus(when); + score += getHiringHallTechBonus(when); return score; } @@ -775,8 +775,11 @@ private HiringHallLevel resolveHiringHallLevel(int score) { return HiringHallLevel.NONE; } - private int getHiringHallHpgBonus(LocalDate date) { - return switch (getHPG(date)) { + private int getHiringHallHpgBonus(LocalDate when) { + if(null == getHPG(when)) { + return 0; + } + return switch (getHPG(when)) { case EquipmentType.RATING_A -> 5; case EquipmentType.RATING_B -> 3; case EquipmentType.RATING_C, EquipmentType.RATING_D -> 1; @@ -784,8 +787,11 @@ private int getHiringHallHpgBonus(LocalDate date) { }; } - private int getHiringHallTechBonus(LocalDate date) { - return switch (getSocioIndustrial(date).tech) { + private int getHiringHallTechBonus(LocalDate when) { + if(null == getSocioIndustrial(when)) { + return 0; + } + return switch (getSocioIndustrial(when).tech) { case -1 -> 5; // Ultra-Advanced; not accounted for in the EquipmentType.RATING constants case EquipmentType.RATING_A, EquipmentType.RATING_B -> 3; case EquipmentType.RATING_C, EquipmentType.RATING_D -> 1; From 3a72e9bb3a0bdd73c3cbf1954c5b84cfe50c0d7d Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 10 Feb 2025 13:41:41 -0800 Subject: [PATCH 07/10] Remove AtB limitations on map adornments for Great hiring halls --- MekHQ/src/mekhq/gui/InterstellarMapPanel.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MekHQ/src/mekhq/gui/InterstellarMapPanel.java b/MekHQ/src/mekhq/gui/InterstellarMapPanel.java index ee2dacda9cc..e90514a6990 100644 --- a/MekHQ/src/mekhq/gui/InterstellarMapPanel.java +++ b/MekHQ/src/mekhq/gui/InterstellarMapPanel.java @@ -734,8 +734,7 @@ protected void paintComponent(Graphics g) { 360.0 * (1 - ((double) i) / factions.size()), Arc2D.OPEN); g2.fill(arc); } else { - if (campaign.getCampaignOptions().isUseAtB() - && (system.getHiringHallLevel(campaign.getLocalDate()) == HiringHallLevel.GREAT)) { + if (system.getHiringHallLevel(campaign.getLocalDate()) == HiringHallLevel.GREAT) { g2.setPaint(new Color(176, 196, 222)); arc.setArcByCenter(x, y, size + 5, 0, 360.0 * (1 - ((double) i) / factions.size()), Arc2D.OPEN); From dc3910a1a1229162fc6da332ba08a3dcceb15866 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Tue, 11 Feb 2025 14:15:05 -0800 Subject: [PATCH 08/10] Correct copyright error --- MekHQ/src/mekhq/adapter/HiringHallAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/adapter/HiringHallAdapter.java b/MekHQ/src/mekhq/adapter/HiringHallAdapter.java index be83ca9361a..6fac40923df 100644 --- a/MekHQ/src/mekhq/adapter/HiringHallAdapter.java +++ b/MekHQ/src/mekhq/adapter/HiringHallAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022 - The MegaMek Team. All Rights Reserved. + * Copyright (c) 2019-2025 - The MegaMek Team. All Rights Reserved. * * This file is part of MekHQ. * From 314b17c4686d30e45b4a6620637d5a6c7e3f93f2 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Tue, 11 Feb 2025 14:24:37 -0800 Subject: [PATCH 09/10] Change copyright on other touched files --- MekHQ/src/mekhq/campaign/universe/Planet.java | 2 +- MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java | 2 +- MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java | 2 +- MekHQ/src/mekhq/gui/InterstellarMapPanel.java | 2 +- MekHQ/src/mekhq/gui/view/PlanetViewPanel.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/universe/Planet.java b/MekHQ/src/mekhq/campaign/universe/Planet.java index f1369c06640..8421330296d 100644 --- a/MekHQ/src/mekhq/campaign/universe/Planet.java +++ b/MekHQ/src/mekhq/campaign/universe/Planet.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2011 - Jay Lawson (jaylawson39 at yahoo.com). All Rights Reserved. - * Copyright (c) 2011-2022 - The MegaMek Team. All Rights Reserved. + * Copyright (c) 2011-2025 - The MegaMek Team. All Rights Reserved. * * This file is part of MekHQ. * diff --git a/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java b/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java index f3286d52248..5c38ceba127 100644 --- a/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java +++ b/MekHQ/src/mekhq/campaign/universe/PlanetarySystem.java @@ -2,7 +2,7 @@ * PlanetarySystem.java * * Copyright (c) 2011 - Jay Lawson (jaylawson39 at yahoo.com). All Rights Reserved. - * Copyright (c) 2011-2024 - The MegaMek team. All Rights Reserved. + * Copyright (c) 2011-2025 - The MegaMek team. All Rights Reserved. * * This file is part of MekHQ. * diff --git a/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java b/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java index 701f141df09..2e61fd4efaa 100644 --- a/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java +++ b/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * Copyright (c) 2025 - The MegaMek Team. All Rights Reserved. * * This file is part of MekHQ. * diff --git a/MekHQ/src/mekhq/gui/InterstellarMapPanel.java b/MekHQ/src/mekhq/gui/InterstellarMapPanel.java index e90514a6990..630474702b8 100644 --- a/MekHQ/src/mekhq/gui/InterstellarMapPanel.java +++ b/MekHQ/src/mekhq/gui/InterstellarMapPanel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2024 - The MegaMek Team. All Rights Reserved. + * Copyright (c) 2011-2025 - The MegaMek Team. All Rights Reserved. * * This file is part of MekHQ. * diff --git a/MekHQ/src/mekhq/gui/view/PlanetViewPanel.java b/MekHQ/src/mekhq/gui/view/PlanetViewPanel.java index ea5f5363fe8..ab364eddbcf 100644 --- a/MekHQ/src/mekhq/gui/view/PlanetViewPanel.java +++ b/MekHQ/src/mekhq/gui/view/PlanetViewPanel.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2024 - The MegaMek Team. All Rights Reserved. + * Copyright (C) 2009-2025 - The MegaMek Team. All Rights Reserved. * * This file is part of MekHQ. * From 3f390219f1573ab3bbfe67739f4baff849238033 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Tue, 11 Feb 2025 14:37:44 -0800 Subject: [PATCH 10/10] Change parse method for HiringHallLevel for less maintenance --- .../universe/enums/HiringHallLevel.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java b/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java index 2e61fd4efaa..283c8575540 100644 --- a/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java +++ b/MekHQ/src/mekhq/campaign/universe/enums/HiringHallLevel.java @@ -18,6 +18,9 @@ */ package mekhq.campaign.universe.enums; +import io.sentry.Sentry; +import megamek.logging.MMLogger; + /** * The level of a Hiring Hall as defined in CamOps (4th printing). Used to determine various modifiers * related to contract generation. @@ -29,14 +32,16 @@ public enum HiringHallLevel { STANDARD, GREAT; + private static final MMLogger logger = MMLogger.create(HiringHallLevel.class); + public static HiringHallLevel parseHiringHallLevel(String val) { - return switch (val.toLowerCase()) { - case "questionable" -> QUESTIONABLE; - case "minor" -> MINOR; - case "standard" -> STANDARD; - case "great" -> GREAT; - default -> NONE; - }; + try { + return HiringHallLevel.valueOf(val.toUpperCase()); + } catch (Exception ex) { + Sentry.captureException(ex); + logger.error("Couldn't find a hiring hall level matching " + val.toUpperCase(), ex); + return NONE; + } } public boolean isNone() {