From 41f1699e6c99fdf007ec208f082a6530ea919d24 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 28 Apr 2025 23:59:24 -0500 Subject: [PATCH 1/6] Fixed Ammo Not Stacking in the Warehouse ### Dev Notes We had a couple of lines of code that were trying to specially handle ammo. However, we were already handling ammo later in the process. The two handlers were incompatible, which resulted in ammo refusing to stack. --- MekHQ/src/mekhq/campaign/Quartermaster.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/Quartermaster.java b/MekHQ/src/mekhq/campaign/Quartermaster.java index 175182f87a7..bece5c971a5 100644 --- a/MekHQ/src/mekhq/campaign/Quartermaster.java +++ b/MekHQ/src/mekhq/campaign/Quartermaster.java @@ -48,7 +48,6 @@ import mekhq.campaign.parts.Part; import mekhq.campaign.parts.Refit; import mekhq.campaign.parts.enums.PartQuality; -import mekhq.campaign.parts.equipment.AmmoBin; import mekhq.campaign.unit.TestUnit; import mekhq.campaign.unit.Unit; @@ -146,11 +145,6 @@ public void addPart(Part part, int transitDays, boolean isBrandNew) { return; } - // don't keep around spare ammo bins - if ((part instanceof AmmoBin) && (null == part.getUnit())) { - return; - } - part.setDaysToArrival(Math.max(transitDays, 0)); part.setBrandNew(isBrandNew); From db30a9d8b9e81c8b57beb584c9276a9e9d394691 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Tue, 29 Apr 2025 00:21:18 -0500 Subject: [PATCH 2/6] - Added additional checks --- MekHQ/src/mekhq/campaign/Warehouse.java | 46 +++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/Warehouse.java b/MekHQ/src/mekhq/campaign/Warehouse.java index 5009ed6bbbb..b6633a955f8 100644 --- a/MekHQ/src/mekhq/campaign/Warehouse.java +++ b/MekHQ/src/mekhq/campaign/Warehouse.java @@ -39,6 +39,7 @@ import java.util.stream.Stream; import megamek.common.annotations.Nullable; +import megamek.logging.MMLogger; import mekhq.MekHQ; import mekhq.campaign.event.PartChangedEvent; import mekhq.campaign.event.PartNewEvent; @@ -52,6 +53,8 @@ * Stores parts for a Campaign. */ public class Warehouse { + private static final MMLogger logger = MMLogger.create(Warehouse.class); + private final TreeMap parts = new TreeMap<>(); /** @@ -235,7 +238,7 @@ private Part mergePartWithExisting(Part part) { // Check if the part has no unit, no parent part, and is not reserved for replacement if ((null == part.getUnit()) && !part.hasParentPart() && !part.isReservedForReplacement()) { - Part spare = checkForExistingSparePart(part); + Part spare = checkForExistingSparePart(part, true); // Ensure a matching spare exists and both parts share the same isBrandNew state if (spare != null && part.isBrandNew() == spare.isBrandNew()) { @@ -263,13 +266,52 @@ private Part mergePartWithExisting(Part part) { * @return The matching spare part or null if none were found. */ public @Nullable Part checkForExistingSparePart(Part part) { - Objects.requireNonNull(part); + if (part == null) { + logger.error("checkForExistingSparePart(Part): Part is null"); + return null; + } return findSparePart(spare -> (spare.getId() != part.getId()) && part.isSamePartTypeAndStatus(spare)); } + /** + * Checks for an existing spare part in inventory that matches the given {@code part}. + * + *

In addition to comparing type and status, this method can optionally consider whether both parts are + * equally brand new based on the {@code includeNewnessCheck} parameter.

+ * + *
    + *
  • If {@code includeNewnessCheck} is {@code true}, this method defers to + * {@link #checkForExistingSparePart(Part)} for a match based on type and status.
  • + *
  • If {@code part} is {@code null}, an error is logged and {@code null} is returned.
  • + *
  • Otherwise, returns a matching spare part or {@code null} if none is found.
  • + *
+ * + * @param part the part to find a match for; may not be {@code null} + * @param includeNewnessCheck whether to require matching "brand new" status as part of the comparison + * + * @return an existing spare part matching the given part and criteria, or {@code null} if no match is found + * + * @author Illiani + * @since 0.50.06 + */ + public @Nullable Part checkForExistingSparePart(Part part, boolean includeNewnessCheck) { + if (!includeNewnessCheck) { + return checkForExistingSparePart(part); + } + + if (part == null) { + logger.error("checkForExistingSparePart(Part, boolean): Part is null"); + return null; + } + + return findSparePart(spare -> (spare.getId() != part.getId()) && + part.isSamePartTypeAndStatus(spare) && + (part.isBrandNew() == spare.isBrandNew())); + } + /** * Gets a list of spare parts in the warehouse. * @return A list of spare parts in the warehouse. From 74b64156a10e2674c939304ce2ace2b89f7a20cb Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Tue, 29 Apr 2025 00:22:16 -0500 Subject: [PATCH 3/6] - Updated legal statements --- MekHQ/src/mekhq/campaign/Quartermaster.java | 5 +++++ MekHQ/src/mekhq/campaign/Warehouse.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/MekHQ/src/mekhq/campaign/Quartermaster.java b/MekHQ/src/mekhq/campaign/Quartermaster.java index bece5c971a5..3c096d432d6 100644 --- a/MekHQ/src/mekhq/campaign/Quartermaster.java +++ b/MekHQ/src/mekhq/campaign/Quartermaster.java @@ -24,6 +24,11 @@ * * Catalyst Game Labs and the Catalyst Game Labs logo are trademarks of * InMediaRes Productions, LLC. + * + * MechWarrior Copyright Microsoft Corporation. MekHQ was created under + * Microsoft's "Game Content Usage Rules" + * and it is not endorsed by or + * affiliated with Microsoft. */ package mekhq.campaign; diff --git a/MekHQ/src/mekhq/campaign/Warehouse.java b/MekHQ/src/mekhq/campaign/Warehouse.java index b6633a955f8..107d7537212 100644 --- a/MekHQ/src/mekhq/campaign/Warehouse.java +++ b/MekHQ/src/mekhq/campaign/Warehouse.java @@ -24,6 +24,11 @@ * * Catalyst Game Labs and the Catalyst Game Labs logo are trademarks of * InMediaRes Productions, LLC. + * + * MechWarrior Copyright Microsoft Corporation. MekHQ was created under + * Microsoft's "Game Content Usage Rules" + * and it is not endorsed by or + * affiliated with Microsoft. */ package mekhq.campaign; From 0add7fd0033d94f37e1129984e0c86992ed5d52a Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Tue, 29 Apr 2025 00:25:27 -0500 Subject: [PATCH 4/6] - Fixed minor code quality note --- MekHQ/src/mekhq/campaign/Warehouse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/campaign/Warehouse.java b/MekHQ/src/mekhq/campaign/Warehouse.java index 107d7537212..68e2decf2e6 100644 --- a/MekHQ/src/mekhq/campaign/Warehouse.java +++ b/MekHQ/src/mekhq/campaign/Warehouse.java @@ -86,7 +86,7 @@ public Part addPart(Part part, boolean mergeWithExisting) { Part mergedPart = mergePartWithExisting(part); // CAW: intentional reference equality - if (mergedPart != part) { + if (!mergedPart.equals(part)) { // We've merged parts, so let interested parties know we've // updated the merged part. MekHQ.triggerEvent(new PartChangedEvent(mergedPart)); From e8dfc0d3053988836eb35f0e0afd15e4806cd9ee Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Wed, 30 Apr 2025 23:08:51 -0500 Subject: [PATCH 5/6] - Incorporated Luana's feedback --- MekHQ/src/mekhq/campaign/Quartermaster.java | 6 ++++++ MekHQ/src/mekhq/campaign/Warehouse.java | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/Quartermaster.java b/MekHQ/src/mekhq/campaign/Quartermaster.java index 3c096d432d6..429d7116e23 100644 --- a/MekHQ/src/mekhq/campaign/Quartermaster.java +++ b/MekHQ/src/mekhq/campaign/Quartermaster.java @@ -53,6 +53,7 @@ import mekhq.campaign.parts.Part; import mekhq.campaign.parts.Refit; import mekhq.campaign.parts.enums.PartQuality; +import mekhq.campaign.parts.equipment.AmmoBin; import mekhq.campaign.unit.TestUnit; import mekhq.campaign.unit.Unit; @@ -150,6 +151,11 @@ public void addPart(Part part, int transitDays, boolean isBrandNew) { return; } + // don't keep around spare ammo bins + if ((part instanceof AmmoBin) && (null == part.getUnit())) { + return; + } + part.setDaysToArrival(Math.max(transitDays, 0)); part.setBrandNew(isBrandNew); diff --git a/MekHQ/src/mekhq/campaign/Warehouse.java b/MekHQ/src/mekhq/campaign/Warehouse.java index 68e2decf2e6..7f59dd25b81 100644 --- a/MekHQ/src/mekhq/campaign/Warehouse.java +++ b/MekHQ/src/mekhq/campaign/Warehouse.java @@ -272,7 +272,7 @@ private Part mergePartWithExisting(Part part) { */ public @Nullable Part checkForExistingSparePart(Part part) { if (part == null) { - logger.error("checkForExistingSparePart(Part): Part is null"); + logger.error(new NullPointerException("Part is null"), "checkForExistingSparePart(Part): Part is null"); return null; } @@ -308,7 +308,8 @@ private Part mergePartWithExisting(Part part) { } if (part == null) { - logger.error("checkForExistingSparePart(Part, boolean): Part is null"); + logger.error(new NullPointerException("Part is null"), + "checkForExistingSparePart(Part, boolean): Part is null"); return null; } From f90c12ce19ad87a2ac186031292331702318cd41 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Wed, 30 Apr 2025 23:08:51 -0500 Subject: [PATCH 6/6] - Incorporated Luana's feedback --- MekHQ/src/mekhq/campaign/Quartermaster.java | 6 ++++++ MekHQ/src/mekhq/campaign/Warehouse.java | 13 +++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/Quartermaster.java b/MekHQ/src/mekhq/campaign/Quartermaster.java index 3c096d432d6..429d7116e23 100644 --- a/MekHQ/src/mekhq/campaign/Quartermaster.java +++ b/MekHQ/src/mekhq/campaign/Quartermaster.java @@ -53,6 +53,7 @@ import mekhq.campaign.parts.Part; import mekhq.campaign.parts.Refit; import mekhq.campaign.parts.enums.PartQuality; +import mekhq.campaign.parts.equipment.AmmoBin; import mekhq.campaign.unit.TestUnit; import mekhq.campaign.unit.Unit; @@ -150,6 +151,11 @@ public void addPart(Part part, int transitDays, boolean isBrandNew) { return; } + // don't keep around spare ammo bins + if ((part instanceof AmmoBin) && (null == part.getUnit())) { + return; + } + part.setDaysToArrival(Math.max(transitDays, 0)); part.setBrandNew(isBrandNew); diff --git a/MekHQ/src/mekhq/campaign/Warehouse.java b/MekHQ/src/mekhq/campaign/Warehouse.java index 68e2decf2e6..74336cc56e7 100644 --- a/MekHQ/src/mekhq/campaign/Warehouse.java +++ b/MekHQ/src/mekhq/campaign/Warehouse.java @@ -272,7 +272,7 @@ private Part mergePartWithExisting(Part part) { */ public @Nullable Part checkForExistingSparePart(Part part) { if (part == null) { - logger.error("checkForExistingSparePart(Part): Part is null"); + logger.error(new NullPointerException("Part is null"), "checkForExistingSparePart(Part): Part is null"); return null; } @@ -303,15 +303,16 @@ private Part mergePartWithExisting(Part part) { * @since 0.50.06 */ public @Nullable Part checkForExistingSparePart(Part part, boolean includeNewnessCheck) { - if (!includeNewnessCheck) { - return checkForExistingSparePart(part); - } - if (part == null) { - logger.error("checkForExistingSparePart(Part, boolean): Part is null"); + logger.error(new NullPointerException("Part is null"), + "checkForExistingSparePart(Part, boolean): Part is null"); return null; } + if (!includeNewnessCheck) { + return checkForExistingSparePart(part); + } + return findSparePart(spare -> (spare.getId() != part.getId()) && part.isSamePartTypeAndStatus(spare) && (part.isBrandNew() == spare.isBrandNew()));