Fractal Softworks Forum

Please login or register.

Login with username, password and session length

Author Topic: [0.8.1a RC8] TransmitterTrapSpecial NPE  (Read 1456 times)

Histidine

  • Admiral
  • *****
  • Posts: 4688
    • View Profile
    • GitHub profile
[0.8.1a RC8] TransmitterTrapSpecial NPE
« on: February 26, 2018, 03:50:18 AM »

In derelict ship salvage dialog, clicked Explore:

Code
1064325 [Thread-5] WARN  com.fs.starfarer.campaign.rules.A  - Problem with command of class com.fs.starfarer.api.impl.campaign.rulecmd.salvage.SalvageSpecialInteraction: null
java.lang.NullPointerException
at com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.TransmitterTrapSpecial.transmitterActivated(TransmitterTrapSpecial.java:127)
at com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.TransmitterTrapSpecial.initEntityLocation(TransmitterTrapSpecial.java:94)
at com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.TransmitterTrapSpecial.init(TransmitterTrapSpecial.java:67)
at com.fs.starfarer.api.impl.campaign.rulecmd.salvage.SalvageSpecialInteraction$SalvageSpecialDialogPlugin.init(SalvageSpecialInteraction.java:59)
at com.fs.starfarer.api.impl.campaign.rulecmd.salvage.SalvageSpecialInteraction.execute(SalvageSpecialInteraction.java:167)
at com.fs.starfarer.campaign.rules.A.execute(Unknown Source)
at com.fs.starfarer.campaign.rules.ooOO.runScript(Unknown Source)
at com.fs.starfarer.api.impl.campaign.rulecmd.FireBest.applyRule(FireBest.java:97)
at com.fs.starfarer.api.impl.campaign.rulecmd.FireBest.execute(FireBest.java:47)
at com.fs.starfarer.campaign.rules.A.execute(Unknown Source)
at com.fs.starfarer.campaign.rules.ooOO.runScript(Unknown Source)
at com.fs.starfarer.api.impl.campaign.rulecmd.FireBest.applyRule(FireBest.java:97)
at com.fs.starfarer.api.impl.campaign.rulecmd.FireBest.execute(FireBest.java:47)
at com.fs.starfarer.api.impl.campaign.rulecmd.FireBest.fire(FireBest.java:53)
at com.fs.starfarer.api.impl.campaign.RuleBasedInteractionDialogPluginImpl.fireBest(RuleBasedInteractionDialogPluginImpl.java:176)
at com.fs.starfarer.api.impl.campaign.RuleBasedInteractionDialogPluginImpl.optionSelected(RuleBasedInteractionDialogPluginImpl.java:208)
at com.fs.starfarer.ui.newui.OoOo$1.super(Unknown Source)
at com.fs.starfarer.ui.newui.oOOO.actionPerformed(Unknown Source)
at com.fs.starfarer.ui.j.o00000(Unknown Source)
at com.fs.starfarer.ui.I.processInput(Unknown Source)
at com.fs.starfarer.ui.V.o00000(Unknown Source)
at com.fs.starfarer.BaseGameState.traverse(Unknown Source)
at com.fs.state.AppDriver.begin(Unknown Source)
at com.fs.starfarer.combat.CombatMain.main(Unknown Source)
at com.fs.starfarer.StarfarerLauncher$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Afterwards, the Explore/Leave options were still present, but neither did anything.

My guess: I'd just killed a Remnant fleet at the time, but it hadn't been removed from the location yet. So the code tried to get the fleet's non-existent flagship -> error

(Additional suggestion: If rules-based dialog throws an exception, add an option to hard-exit the dialog like devmode Esc, so the player can't get stuck.)
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 24125
    • View Profile
Re: [0.8.1a RC8] TransmitterTrapSpecial NPE
« Reply #1 on: February 26, 2018, 08:58:57 AM »

Thanks for the report! Hmm, this is a bit weird - does your transmitterActivated method look like this?

Code: java
	public void transmitterActivated() {
if (data == null) return;
if (entity == null) return;

if (data.fleetId != null) {
SectorEntityToken found = Global.getSector().getEntityById(data.fleetId);
if (found instanceof CampaignFleetAPI) {
CampaignFleetAPI fleet = (CampaignFleetAPI) found;
FleetMemberAPI flagship = fleet.getFlagship();
boolean makeAggressive = false;
if (flagship != null) {
makeAggressive = flagship.getVariant().hasHullMod(HullMods.AUTOMATED);
}
makeFleetInterceptPlayer(fleet, makeAggressive, 30f);
}
return;
}

if (data.useAllFleetsInRange != null && data.useAllFleetsInRange) {
boolean foundSomeFleets = false;
for (CampaignFleetAPI fleet : entity.getContainingLocation().getFleets()) {
if (data.nearbyFleetFaction != null &&
!data.nearbyFleetFaction.equals(fleet.getFaction().getId())) {
continue;
} /*** <--- LINE 127 ***************************************************/

if (fleet.isStationMode()) continue;

if (fleet.getMemoryWithoutUpdate().is(MemFlags.MEMORY_KEY_TRADE_FLEET, true)) continue;

float dist = Misc.getDistance(fleet.getLocation(), entity.getLocation());
if (dist < data.maxRange) {
FleetMemberAPI flagship = fleet.getFlagship();
boolean makeAggressive = false;
if (flagship != null) {
makeAggressive = flagship.getVariant().hasHullMod(HullMods.AUTOMATED);
}
makeFleetInterceptPlayer(fleet, makeAggressive, 30f);
foundSomeFleets = true;
}
}
if (foundSomeFleets) return;
}

I'm not seeing any changes in the code since the .8.1 release, but the line number doesn't make sense. Maybe I'm just not seeing something obvious, but hard to see an NPE in that area, too. The only candidate near that line - getFaction().getId(), if getFaction() returned null - can't happen because getFaction() can't return null - it actually checks inside that method and returns a dummy faction if the entity's faction is null for whatever reason.

(Yep, made a note re: adding a leave option, good call.)
Logged

Histidine

  • Admiral
  • *****
  • Posts: 4688
    • View Profile
    • GitHub profile
Re: [0.8.1a RC8] TransmitterTrapSpecial NPE
« Reply #2 on: February 27, 2018, 02:33:35 AM »

0.8.1a source has this

Spoiler
Code: java
	public void transmitterActivated() {
if (data.fleetId != null) {
SectorEntityToken found = Global.getSector().getEntityById(data.fleetId);
if (found instanceof CampaignFleetAPI) {
CampaignFleetAPI fleet = (CampaignFleetAPI) found;
boolean makeAggressive = fleet.getFlagship().getVariant().hasHullMod(HullMods.AUTOMATED);
makeFleetInterceptPlayer(fleet, makeAggressive, 30f);
return;
}
}

if (data.useAllFleetsInRange != null && data.useAllFleetsInRange) {
boolean foundSomeFleets = false;
for (CampaignFleetAPI fleet : entity.getContainingLocation().getFleets()) {
if (data.nearbyFleetFaction != null &&
!data.nearbyFleetFaction.equals(fleet.getFaction().getId())) {
continue;
}

if (fleet.isStationMode()) continue;

if (fleet.getMemoryWithoutUpdate().is(MemFlags.MEMORY_KEY_TRADE_FLEET, true)) continue;

float dist = Misc.getDistance(fleet.getLocation(), entity.getLocation());
if (dist < data.maxRange) {
boolean makeAggressive = fleet.getFlagship().getVariant().hasHullMod(HullMods.AUTOMATED);  /*** <--- LINE 127 ***************************************************/  
makeFleetInterceptPlayer(fleet, makeAggressive, 30f);
foundSomeFleets = true;
}
}
if (foundSomeFleets) return;
}

if (data.useClosestFleetInRange != null && data.useClosestFleetInRange) {
CampaignFleetAPI closest = null;
float minDist = Float.MAX_VALUE;
for (CampaignFleetAPI fleet : entity.getContainingLocation().getFleets()) {
if (data.nearbyFleetFaction != null &&
!data.nearbyFleetFaction.equals(fleet.getFaction().getId())) {
continue;
}

if (fleet.isStationMode()) continue;

if (fleet.getMemoryWithoutUpdate().is(MemFlags.MEMORY_KEY_TRADE_FLEET, true)) continue;

float dist = Misc.getDistance(fleet.getLocation(), entity.getLocation());
if (dist < data.maxRange && dist < minDist) {
closest = fleet;
minDist = dist;
}
}
if (closest != null) {
boolean makeAggressive = closest.getFlagship().getVariant().hasHullMod(HullMods.AUTOMATED);
makeFleetInterceptPlayer(closest, makeAggressive, 30f);
return;
}
}

if (data.params != null) {
CampaignFleetAPI fleet = FleetFactoryV2.createFleet(data.params);
if (fleet == null) return;

if (Factions.REMNANTS.equals(fleet.getFaction().getId())) {
RemnantSeededFleetManager.initRemnantFleetProperties(null, fleet, false);
} else {
fleet.setTransponderOn(false);
fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PIRATE, true);
}

float range = data.minRange + random.nextFloat() * (data.maxRange - data.minRange);
Vector2f loc = Misc.getPointAtRadius(entity.getLocation(), range);

entity.getContainingLocation().addEntity(fleet);
fleet.setLocation(loc.x, loc.y);


boolean makeAggressive = fleet.getFlagship().getVariant().hasHullMod(HullMods.AUTOMATED);
makeFleetInterceptPlayer(fleet, makeAggressive, 30f);


SectorEntityToken despawnLoc = entity.getContainingLocation().createToken(20000, 0);
fleet.addAssignment(FleetAssignment.GO_TO_LOCATION_AND_DESPAWN, despawnLoc, 10000f);
return;
}
}
[close]

Your version of the code appears to add an if (flagship == null) check, so I guess it's already fixed for next release?
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 24125
    • View Profile
Re: [0.8.1a RC8] TransmitterTrapSpecial NPE
« Reply #3 on: February 27, 2018, 07:28:14 AM »

... aha, right. Sorry, it looks like I was being a bit dense - misread the date in the commit history. Looks like I did indeed fix this, but shortly after the 0.8.1a release, not before.
Logged