MegaMek / mekhq

MekHQ is a java helper program for the MegaMek game that allows users to load a list of entities from an XML file, perform repairs and customizations, and then save the new entities to another XML file that can be loaded into MegaMek.
http://megamek.org
131 stars 168 forks source link

[0.50.0 Nightly CI #1600]: NPE when launching scenario after OpFor changed in a contract. #4755

Closed UlyssesSockdrawer closed 1 month ago

UlyssesSockdrawer commented 1 month ago

Environment

Version: 0.50.0 CI#1600 Nightly - StratCon MHQ campaign Java: 17 OS: Win11

Description

When trying to launch a base defence scenario on the new nightly, I am receiving an NPE. The scenario does not launch and Megamek does not load, essentially soft-locking the campaign from progressing without GM deleting the scenario.

I suspect something has broken in which factions to pull from, as the enemy changed on the contract due to the previous enemy going to a 'Rout' morale status in the previous month.

The scenario with the issue in the savefile is: "Industrial Facility - Allied - Evacuate".

Key extract from the log:

13:39:03,288 ERROR [mekhq.MekHQ] {AWT-EventQueue-0} mekhq.MekHQ.lambda$main$1(MekHQ.java:294) - Uncaught Exception Detected java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "rp.friendlyFaction" is null at megamek.client.generator.TeamLoadoutGenerator.generateMunitionTree(TeamLoadoutGenerator.java:929) at megamek.client.generator.TeamLoadoutGenerator.generateMunitionTree(TeamLoadoutGenerator.java:766) at mekhq.gui.BriefingTab.autoconfigureBotMunitions(BriefingTab.java:988) at mekhq.gui.BriefingTab.startScenario(BriefingTab.java:908) at mekhq.gui.BriefingTab.lambda$initTab$8(BriefingTab.java:234) at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972) at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313) at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405) at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279) at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:297) at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626) at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389) at java.desktop/java.awt.Component.processEvent(Component.java:6391) at java.desktop/java.awt.Container.processEvent(Container.java:2266) at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833) at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948) at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575) at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310) at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97) at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747) at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Files

Save file: The Nova Dragoons-PreNPEScenario.cpnx.gz

Log file: mekhq.log

Thom293 commented 1 month ago

Which faction did it change to in what year? If the new on is extinct can cause problems. Can try to change opfor to different faction, as a test.

Sleet01 commented 1 month ago

The root cause is that the enemy Mercenaries don't have a faction set. I'll try to resolve this alongside adding safety checks to the munitions code, but there may not be time to fix that part before release.