Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Starsector 0.97a is out! (02/02/24); New blog post: Codex Overhaul (05/11/24)

Pages: 1 ... 542 543 [544] 545 546 ... 717

Author Topic: Misc modding questions that are too minor to warrant their own thread  (Read 1760297 times)

Jackundor

  • Commander
  • ***
  • Posts: 242
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8145 on: November 21, 2021, 11:25:50 PM »

this has probably already been asked several dozen times but well... In what state should a mod be for when you want it to be added to the index? In my weapon pack i currently have 4 weapons and 2 fighter wings finished and i'm working on some more weapons... would that be enough?
Logged

Morrokain

  • Admiral
  • *****
  • Posts: 2143
  • Megalith Dreadnought - Archean Order
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8146 on: November 22, 2021, 11:27:34 AM »

I applied this to my game, but it causes a NullPointerException when generating a new save. Is there a possible reason why? I believe I added the appropriate imports too.

I'd check if your HyperSpaceGeneratorPlugin or the SectorEntityToken you are passing into that method is null, and then you can narrow down which one it is as it has to be one of the two assuming it operates normally if this code block isn't run at all.

See this next section of my post for more helpful information relating to this.

I'm trying to build a mod that will play custom music in the menu for a planet based on the planet's name. Right now I'm just trying to verify that I'm going down the right path by having it print something when I interact with the planet. I'm not getting any print out. What would be the right way to do it?

I'm using the Asteroid Mining code as a base.

Code
Code: mod_info.json
{
    "id":"CustomMusic",
    "name":"Custom Music",
    "version":"0.0.1",
    "description":"Custom music",
    "gameVersion":"0.95a-RC15",
    "modPlugin":"scripts.CustomMusic_ModPlugin"
}
Code: CustomMusic_ModPlugin.java
package scripts;
import com.fs.starfarer.api.BaseModPlugin;
import com.fs.starfarer.api.Global;

public class CustomMusic_ModPlugin extends BaseModPlugin {
    @Override
    public void onGameLoad(boolean newGame) {
        super.onGameLoad(newGame);
        System.out.println("Registering mod");
        Global.getSector().registerPlugin(new CustomMusicCampaignPlugin());
    }
}
Code: CustomMusicCampaignPlugin.java
package scripts;

import com.fs.starfarer.api.PluginPick;
import com.fs.starfarer.api.campaign.BaseCampaignPlugin;
import com.fs.starfarer.api.campaign.OrbitalStationAPI;
import com.fs.starfarer.api.campaign.PlanetAPI;
import com.fs.starfarer.api.campaign.SectorEntityToken;

public class CustomMusicCampaignPlugin extends BaseCampaignPlugin {
    @Override
    public String getId() {
        System.out.println("ID");
        return "CustomMusic";
    }

    @Override
    public boolean isTransient() {
        System.out.println("Transient");
        return true;
    }

    @Override
    public PluginPick<com.fs.starfarer.api.campaign.InteractionDialogPlugin> pickInteractionPluginPick(SectorEntityToken interactionTarget) {
        System.out.println("Interaction");
        if ((interactionTarget instanceof OrbitalStationAPI) || (interactionTarget instanceof PlanetAPI)) {
            System.out.println(interactionTarget.getName());
        }

        return null;
    }

    @Override
    public  PluginPick<com.fs.starfarer.api.campaign.InteractionDialogPlugin> pickInteractionDialogPlugin(java.lang.Object param, com.fs.starfarer.api.campaign.SectorEntityToken interactionTarget) {
        System.out.println("Interaction w/ param");
        return null;
    }
}
[close]

Admittedly I haven't looked at your code snippets so it could simply be that System.out.println is never reached, but assuming that isn't the case it may be better to set up a logger instead:

Code
private static final Logger LOG = Global.getLogger(*YourClassNameHere*.class);

then in place of the println statement you'd call:

Code
LOG.info("Interacted with planet PlanetName");

 - or something like that. Then you can check the Starsector log file (A text file called Starsector in the core directory) and search for your class name to find the relevant logs (starting from the bottom to find the most recent) and see if your code is actually being ran at all. IIRC I don't think Janino can handle this so you'd need an IDE set up.
Logged

float

  • Captain
  • ****
  • Posts: 275
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8147 on: November 22, 2021, 06:22:03 PM »

Is there any way to use HullModEffect.isApplicableToShip outside of combat? The problem is that it takes in a ShipAPI as the argument, but in the campaign layer we seem to only have access to FleetMemberAPI instances. I couldn’t find any way to instantiate a ShipAPI from a FleetMember or ShipVariant outside of combat (the spawnFleetMember and spawnShipOrWing functions take in position vectors so I don’t think they’re usable outside of combat, and getShipFor seems to always return null in the campaign layer).

I could create a map between FleetMemberAPI and ShipAPI that gets filled in by an engagement listener, but the issue with that is that I need the data even if the ship in the player’s fleet has never seen combat.
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 24329
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8148 on: November 22, 2021, 06:29:25 PM »

this has probably already been asked several dozen times but well... In what state should a mod be for when you want it to be added to the index? In my weapon pack i currently have 4 weapons and 2 fighter wings finished and i'm working on some more weapons... would that be enough?

It's more about it getting some use and player feedback, but we don't really have an official set of criteria.


Is there any way to use HullModEffect.isApplicableToShip outside of combat? The problem is that it takes in a ShipAPI as the argument, but in the campaign layer we seem to only have access to FleetMemberAPI instances. I couldn’t find any way to instantiate a ShipAPI from a FleetMember or ShipVariant outside of combat (the spawnFleetMember and spawnShipOrWing functions take in position vectors so I don’t think they’re usable outside of combat, and getShipFor seems to always return null in the campaign layer).

I could create a map between FleetMemberAPI and ShipAPI that gets filled in by an engagement listener, but the issue with that is that I need the data even if the ship in the player’s fleet has never seen combat.

There isn't, no - sorry! And I don't think it'd be a good idea to either try to instantiate ShipAPIs in the campaign or hang on to ones from combat at some prior time; the latter in particular seems like it could result in memory leaks/savefile bloat/and so on, while the former wouldn't perform very well.

It does need a ship, though, rather than a FleetMemberAPI, so basically determining whether a hullmod is applicable to a ship is not possible in the campaign. Consider a case where one hullmod adds a shield to a shieldless ship, and another requires the ship to have shields. Since the first mod acts on a ShipAPI - and is in fact an arbitrary script - there's no way to get this information about what the hullmod does without actually applying it to a ShipAPI and seeing what the result is.
Logged

float

  • Captain
  • ****
  • Posts: 275
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8149 on: November 22, 2021, 06:47:10 PM »

Quote

There isn't, no - sorry! And I don't think it'd be a good idea to either try to instantiate ShipAPIs in the campaign or hang on to ones from combat at some prior time; the latter in particular seems like it could result in memory leaks/savefile bloat/and so on, while the former wouldn't perform very well.

It does need a ship, though, rather than a FleetMemberAPI, so basically determining whether a hullmod is applicable to a ship is not possible in the campaign. Consider a case where one hullmod adds a shield to a shieldless ship, and another requires the ship to have shields. Since the first mod acts on a ShipAPI - and is in fact an arbitrary script - there's no way to get this information about what the hullmod does without actually applying it to a ShipAPI and seeing what the result is.

Ah, I see, thanks! Out of curiosity, how does it work in the refit screen? I am able to select hull mods there and have other hull mods disable/enable themselves on the fly. Is the refit screen actually inside a combat instance?
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 24329
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8150 on: November 22, 2021, 06:49:58 PM »

Ah, I see, thanks! Out of curiosity, how does it work in the refit screen? I am able to select hull mods there and have other hull mods disable/enable themselves on the fly. Is the refit screen actually inside a combat instance?

Sort of! There's always a combat instance (which gets reset when you enter a battle, say) and the refit screen is using that one while still being in the campaign game state.
Logged

esm8m

  • Ensign
  • *
  • Posts: 3
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8151 on: November 22, 2021, 07:42:59 PM »

Admittedly I haven't looked at your code snippets so it could simply be that System.out.println is never reached, but assuming that isn't the case it may be better to set up a logger instead:

Code
private static final Logger LOG = Global.getLogger(*YourClassNameHere*.class);

then in place of the println statement you'd call:

Code
LOG.info("Interacted with planet PlanetName");

 - or something like that. Then you can check the Starsector log file (A text file called Starsector in the core directory) and search for your class name to find the relevant logs (starting from the bottom to find the most recent) and see if your code is actually being ran at all. IIRC I don't think Janino can handle this so you'd need an IDE set up.

I just tried doing that, and it didn't seem to get called. I had to switch from using scripts to using the jar for it, as you said. I have prints in getting the ID for the CampaignPlugin and in onGameLoad in the ModPlugin - those appear when using the script but not the jar. I wonder if I'm doing something wrong with the jar?
Logged

Morrokain

  • Admiral
  • *****
  • Posts: 2143
  • Megalith Dreadnought - Archean Order
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8152 on: November 23, 2021, 03:44:14 PM »

I just tried doing that, and it didn't seem to get called. I had to switch from using scripts to using the jar for it, as you said. I have prints in getting the ID for the CampaignPlugin and in onGameLoad in the ModPlugin - those appear when using the script but not the jar. I wonder if I'm doing something wrong with the jar?

Have you declared your jar in your mod_info file?

Example:

   "jars": ["Archean Order TC v0.9.5a.jar"],
Logged

Dazs

  • Admiral
  • *****
  • Posts: 1084
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8153 on: November 23, 2021, 06:41:30 PM »

One of the users of my mod Junk Yard Dogs is having a crash with the CHM hull mod in it. I've had the mod up for some time now and this is the first time anyone has had this issue with it. I have exhausted my knowledge trying to help him and thought maybe someone more adept with Java could help.

His error Log:
304193 [Thread-3] ERROR com.fs.starfarer.combat.CombatMain  - java.lang.NullPointerException
java.lang.NullPointerException
   at data.scripts.hullmods.CHM_JYD.applyEffectsBeforeShipCreation(CHM_JYD.java:24)
   at com.fs.starfarer.campaign.fleet.FleetMember.updateStats(Unknown Source)
   at com.fs.starfarer.campaign.fleet.FleetMember.init(Unknown Source)
   at com.fs.starfarer.campaign.fleet.FleetMember.<init>(Unknown Source)
   at com.fs.starfarer.title.Object.M.o00000(Unknown Source)
   at com.fs.starfarer.title.Object.M.render(Unknown Source)
   at com.fs.starfarer.coreui.OO0o.super(Unknown Source)
   at com.fs.starfarer.ui.newnew.renderImpl(Unknown Source)
   at com.fs.starfarer.ui.o00O.render(Unknown Source)
   at com.fs.starfarer.ui.v.renderImpl(Unknown Source)
   at com.fs.starfarer.ui.o00O.render(Unknown Source)
   at com.fs.starfarer.ui.v.renderImpl(Unknown Source)
   at com.fs.starfarer.ui.impl.StandardTooltipV2.renderImpl(Unknown Source)
   at com.fs.starfarer.ui.o00O.render(Unknown Source)
   at com.fs.starfarer.ui.v.renderImpl(Unknown Source)
   at com.fs.starfarer.ui.o00O.render(Unknown Source)
   at com.fs.starfarer.campaign.CampaignState.render(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.o00000(Unknown Source)
   at com.fs.starfarer.StarfarerLauncher$1.run(Unknown Source)
   at java.lang.Thread.run(Unknown Source)

CHM_JYD code:

Code
package data.scripts.hullmods;
import com.fs.starfarer.api.combat.BaseHullMod;
import com.fs.starfarer.api.combat.MutableShipStatsAPI;
import com.fs.starfarer.api.combat.ShipAPI;
import com.fs.starfarer.api.combat.ShipAPI.HullSize;
import java.awt.Color;
import java.util.HashMap;
import java.util.Map;

public class CHM_JYD extends BaseHullMod {
    private static final Map jydcom = new HashMap();
public static final float ARMOR_BONUS = 20f;
    public static final float MAINTENANCE_MULT = 0.90f;
    static {
        jydcom.put(HullSize.FRIGATE, 30f);
        jydcom.put(HullSize.DESTROYER, 25f);
        jydcom.put(HullSize.CRUISER, 20f);
        jydcom.put(HullSize.CAPITAL_SHIP, 15f);
        jydcom.put(HullSize.DEFAULT, 15f);
    }

    @Override
    public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
        float timeMult = 1f / ((100f + (Float) jydcom.get(hullSize)) / 100f);
        stats.getFighterRefitTimeMult().modifyMult(id, timeMult);
        stats.getMinCrewMod().modifyMult(id, MAINTENANCE_MULT);
stats.getArmorBonus().modifyFlat(id, ARMOR_BONUS);
    }


    @Override
    public String getDescriptionParam(int index, HullSize hullSize) {
        if (index == 0) return "" + ((Float) jydcom.get(HullSize.FRIGATE)).intValue()  + "%";
        if (index == 1) return "" + ((Float) jydcom.get(HullSize.DESTROYER)).intValue()  + "%";
        if (index == 2) return "" + ((Float) jydcom.get(HullSize.CRUISER)).intValue()  + "%";
        if (index == 3) return "" + ((Float) jydcom.get(HullSize.CAPITAL_SHIP)).intValue()  + "%";
        if (index == 4) return "" + (int) ((1f - MAINTENANCE_MULT) * 100f) + "%";
if (index == 5) return "" + (int) ARMOR_BONUS;
        return null;
    }


    @Override
    public Color getBorderColor() {
        return new Color(147, 102, 50, 0);
    }

    @Override
    public Color getNameColor() {
        return new Color(220,185,20);
    }
}

Any help would be appreciated, thank you.

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 24329
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8154 on: November 23, 2021, 06:47:35 PM »

   at data.scripts.hullmods.CHM_JYD.applyEffectsBeforeShipCreation(CHM_JYD.java:24)

Line 24 looks to be this (bolded the line number in the stack trace, btw, so you know where to look for it):
float timeMult = 1f / ((100f + (Float) jydcom.get(hullSize)) / 100f);

If that's indeed the line, the only way it can throw an NPE is when trying to cast the return of get() to a Float. Which means that the given hullSize is not present in that map. Given what you've got in there, I suspect it's "FIGHTER", but why a ship would be of that hull size and refittable, I'm not sure.
Logged

Timid

  • Admiral
  • *****
  • Posts: 640
  • Personal Text
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8155 on: November 23, 2021, 06:56:43 PM »

Any help would be appreciated, thank you.
In addition to what Alex said.

https://fractalsoftworks.com/forum/index.php?topic=22981.msg345402#msg345402

I see this case come up with Diable Avionics a lot :V

Dazs

  • Admiral
  • *****
  • Posts: 1084
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8156 on: November 23, 2021, 07:58:51 PM »

Thank you both for your help. TBH I would never have considered FIGHTER to be a HullSize. If I were to add it to the hash map would it be: jydcom.put(HullSize.FIGHTER, 35f); then add FIGHTER to the index list for getDescriptionParam?

float

  • Captain
  • ****
  • Posts: 275
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8157 on: November 23, 2021, 08:17:19 PM »

Sort of! There's always a combat instance (which gets reset when you enter a battle, say) and the refit screen is using that one while still being in the campaign game state.

Is there any way I could use this combat instance to create something similar to the hull mod selection interface on the refit screen? I thought maybe I could hijack any ShipAPI I could find and use setVariantForHullModCheckOnly, but it turns out that function doesn't modify a ship's stats, hull size, or shields, and probably other things as well. So I feel like there must be a way to get a ShipAPI for a ship that I can use, unless the refit screen is using methods that aren't exposed in the API.

I've also thought about it and holding onto ShipAPIs from the last engagement doesn't work either, since it's possible that the fleet member's stats get changed in the meantime. Theoretically there could be a hull mod that requires some ship stat to be a certain number. This means that the hull mod selection interface must be using a "fresh" copy of the ship in question... but how?
Logged

esm8m

  • Ensign
  • *
  • Posts: 3
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8158 on: November 23, 2021, 08:46:27 PM »

Have you declared your jar in your mod_info file?

Example:

   "jars": ["Archean Order TC v0.9.5a.jar"],

Yep:

Code
{
    "id":"CustomMusic",
    "name":"Custom Music",
    "version":"0.0.1",
    "description":"Custom music",
    "gameVersion":"0.95a-RC15",
    "jars": ["jars/CustomMusic.jar"]
}
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 24329
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #8159 on: November 23, 2021, 08:52:41 PM »

Thank you both for your help. TBH I would never have considered FIGHTER to be a HullSize. If I were to add it to the hash map would it be: jydcom.put(HullSize.FIGHTER, 35f); then add FIGHTER to the index list for getDescriptionParam?

Yeah, that sounds about right.


... unless the refit screen is using methods that aren't exposed in the API.

I'm afraid that's what it does, yeah.

And: creating ShipAPI objects in the background might not be a good idea anyway, at least... depending. For example if you were doing it for NPC fleets, too, it would certainly be a bad idea performance-wise. As would, say, doing it a bunch of times per frame, etc etc.

But that's really secondary to there just not being a way to do it that's exposed in the API. And I'm leery of adding one - I'd have to be really careful about it and do a lot of testing (which would likely not happen due to it not being used by vanilla), since this specific thing can (i.e. has in the past) produce some very, very nasty memory leaks.
Logged
Pages: 1 ... 542 543 [544] 545 546 ... 717