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: Planet Search Overhaul (07/13/24)

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - AtlanticAccent

Pages: [1] 2 3 ... 6
1
Modding / Re: ShipHullSpecAPI.getShipFilePath(); Unexpected return value.
« on: September 29, 2024, 01:55:54 PM »
Could it get fixed in the next update? I am spliting the path from data/ and add it back but that'll cause problems if the game is under a folder called data/.

If you're concerned about that, you can do a right split instead - though the Java standard library doesn't have a method for that. It's relatively simple to implement yourself though with a combination of String#lastIndexOf(String str) and String#substring(int beginIndex). Ex:

Code
String path = "D:/Game Files/Fractal Softworks/0.97a-RC11/starsector-core/data/hulls/shade.ship";

int splitAt = path.lastIndexOf("data/");
if splitAt > -1 {
    return path.substring(splitAt)
} else {
    return null
}


2
Modding / Re: [0.97a] ExtendedControls [0.1.0]
« on: September 07, 2024, 06:35:24 AM »
Congratulations on releasing this! Excited for this and whatever you come up with next!

3
Mods / Re: [0.97a] Star Lords- Mount & Blade Campaign in Space v0.1.0
« on: August 26, 2024, 09:28:54 AM »
Might be jumping the gun by commenting this before playing, but I'd love to see some slightly more "sci-fi" names for feasts. Things like "summit", "conference" or "gala", with maybe different terms used depending on what faction the initiating Lord is from.

This mod sounds amazing though!

4
Does anyone know what the Janino compiler's problem with pairs is?

Trying to use the .java into ...\data\scripts\ method for industry files that use Pair, for example this bit:

Code
		Pair<String, Integer> deficit = getUpkeepAffectingDeficit();

if (deficit.two > 0) {
float loss = getUpkeepPenalty(deficit);
getUpkeep().modifyMult("deficit", 1f + loss, getDeficitText(deficit.one));
} else {
getUpkeep().unmodifyMult("deficit");
}

Results in a crash on startup with:

      Cannot compare types "java.lang.Object" and "int" (pointing to the "if (deficit.two > 0)" part)

It correctly imports

      import com.fs.starfarer.api.util.Pair;
      import com.fs.starfarer.api.impl.campaign.econ.impl.BaseIndustry;

Where these things are defined, because I get errors about not matching what's defined in them when I try to mess around with "deficit.two" to try to get it to work. So I have no idea what the problem is.

Unfortunately Janino doesn't fully support generics: http://janino-compiler.github.io/janino/#limitations

5
Hi, I'm trying to add a skill that gives the captain's ship a hullmod, but I'm having trouble actually getting the hullmod to appear and disappear from the ship as the captain is moved from ship to ship. I'm testing this via a clean campaign with just the bare essential mods and a starter fleet with the captain with the custom skill a part of my starting fleet.

I implemented a simple 1-level skill with implements AfterShipCreationSkillEffect. There were only two real statements in the whole file. The first being applying the hullmod when (I assume) the skill is active, in apply():

Spoiler
Code
        @Override
        public void apply(final MutableShipStatsAPI stats, final HullSize hullSize, final String id, final float level) {
        log.info("CALL APPLY BEFORE");
              stats.getVariant().addPermaMod("yrxp_TestSkill");
        }

And the second would be to remove it. Originally, I had it in unapply(), but then I was already having a problem - the hullmod was never being removed. So I tried placing it in unapplyEffectsAfterShipCreation():

Code

@Override
public void unapplyEffectsAfterShipCreation(ShipAPI ship, String id) {
    log.info("CALL UNAPPLY AFTER");
            ship.getVariant().removePermaMod("yrxp_TestSkill");

}

The problem with this now, is that the hullmod is always removed... And worse still, when I reassign the captain to a different ship, that's actually when the hullmod appears - left on the ship where the captain was just removed from. Very strange! So I figured there must something going on with the order in which these functions are being called, and sure enough, the logs showed that weirdness:

Code
294895 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294895 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY AFTER
294896 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294896 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294896 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294896 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294897 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294897 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY AFTER
294897 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294897 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY AFTER
294897 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY BEFORE
294897 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294898 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294898 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294898 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY AFTER
294899 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294899 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294899 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294900 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294900 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294901 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294901 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294901 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY AFTER
294901 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294902 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY AFTER
294902 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY BEFORE
294902 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294902 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294902 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294902 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY AFTER
294903 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294903 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294904 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294904 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY AFTER
294905 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294905 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY AFTER
294905 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY BEFORE
294905 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294905 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294905 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL UNAPPLY AFTER
294906 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY AFTER
294907 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
294907 [Thread-3] INFO  data.scripts.campaign.skills.yrxp_TestSkill  - CALL APPLY BEFORE
[close]

Whenever I get the code to refresh - that is, switching the view from a different ship and back to the ship with the captain in question - the above logs appear. It was simply a result of adding a single log line to apply(), unapply(), applyEffectsAfterShipCreation() and unapplyEffectsAfterShipCreation(). Firstly, and what I expected, apply() was being called (though it was being called a heck of a lot which was a bit strange). This means that the call for adding the hullmod was certainly being called. however, what I find then is that, for some reason, the unapply() and unapplyEffectsAfterShipCreation() functions also get called? Did I misundestand that the unapply calls would only when the captain is removed? In any case, they, too are being called in rapid succession, and with seemingly no pattern to it. And that's probably what's causing the weird behavior.

tl;dr: How can I make it so a hullmod is applied to a captain's ship, and is then removed when they are dismissed or sent to a different ship?

I've got a skill doing this exact thing and seemingly working, though I'm honestly not sure if it's really working in every case but I don't know of any issues.

The only difference however is that my skill implements ShipSkillEffect, with the relevant section of the .skill file being:
Code
"effects":[
    {"type":"SHIP", "script":"com.price_of_command.conditions.scars.personality_change.Cautious"},
]

6
Modding / Re: reportPlayerOpened/ClosedMarket seems bugged.
« on: June 30, 2024, 05:25:04 AM »
Turns out you're right about that not getting called when a colony is open from the colony list. However, when I open a market by interacting with a planet it seems like reportPlayerOpenedMarket gets called about 20 times or at least I get 20 or so log messages from one log statement in reportPlayerOpenedMarket. Same when closing the market. I'm not sure if that's expecting or not but this is the call in reportPlayerOpenedMarket:                Global.getLogger(this.getClass()).info(market.getName() + "opened");

Hi, this sounds like you might have more than one copy of your listener attached to the sector. Are you sure the listener isn't being serialised into the save, and/or is only being added once when the save loads?

7
Could someone please explain to me what I am doing wrong with my Script?

I get this error in the log file:
Spoiler
java.lang.RuntimeException: Error loading [data.shipsystems.scripts.SensorJammerStats]
   at com.fs.starfarer.loading.scripts.ScriptStore$3.run(Unknown Source)
   at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: Parsing compilation unit 'data.shipsystems.scripts.SensorJammerStats'
   at org.codehaus.janino.JavaSourceIClassLoader.findIClass(JavaSourceIClassLoader.java:172)
   at org.codehaus.janino.IClassLoader.loadIClass(IClassLoader.java:254)
   at org.codehaus.janino.JavaSourceClassLoader.generateBytecodes(JavaSourceClassLoader.java:214)
   at org.codehaus.janino.JavaSourceClassLoader.findClass(JavaSourceClassLoader.java:178)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   ... 2 more
Caused by: org.codehaus.commons.compiler.CompileException: Compilation unit 'data.shipsystems.scripts.SensorJammerStats' does not declare a class with the same name
   at org.codehaus.janino.JavaSourceIClassLoader.findIClass(JavaSourceIClassLoader.java:160)
   ... 7 more
[close]

I am pretty sure that with "public class SensorJammerStats extends BaseShipSystemScript {" I do declare a class of the same name so I really do not understand the error.

Script:
Spoiler
package com.fs.starfarer.api.impl.combat;

import java.awt.Color;
import java.util.List;

import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.combat.BaseEveryFrameCombatPlugin;
import com.fs.starfarer.api.combat.EveryFrameCombatPlugin;
import com.fs.starfarer.api.combat.MutableShipStatsAPI;
import com.fs.starfarer.api.combat.ShipAPI;
import com.fs.starfarer.api.combat.ShipAPI.HullSize;
import com.fs.starfarer.api.combat.ShipSystemAPI;
import com.fs.starfarer.api.combat.ShipSystemAPI.SystemState;
import com.fs.starfarer.api.combat.ShipwideAIFlags.AIFlags;
import com.fs.starfarer.api.input.InputEventAPI;
import com.fs.starfarer.api.util.Misc;

public class SensorJammerStats extends BaseShipSystemScript {
   public static Object KEY_SHIP = new Object();
   public static Object KEY_TARGET = new Object();
   
   public static float RANGE_MULT = 0.8f;
   public static float SENSOR_MULT = 0.6f;   
   protected static float RANGE = 1500f;
   
   public static Color TEXT_COLOR = new Color(255,55,55,255);
   
   public static Color JITTER_COLOR = new Color(255,50,50,75);
   public static Color JITTER_UNDER_COLOR = new Color(255,100,100,155);

   
   public static class TargetData {
      public ShipAPI ship;
      public ShipAPI target;
      public EveryFrameCombatPlugin targetEffectPlugin;
      public float currRange_Mult;
      public float currSensor_Mult;      
      public float elaspedAfterInState;
      public TargetData(ShipAPI ship, ShipAPI target) {
         this.ship = ship;
         this.target = target;
      }
   }
   
   
   public void apply(MutableShipStatsAPI stats, final String id, State state, float effectLevel) {
      ShipAPI ship = null;
      if (stats.getEntity() instanceof ShipAPI) {
         ship = (ShipAPI) stats.getEntity();
      } else {
         return;
      }
      
      final String targetDataKey = ship.getId() + "_Jammer_target_data";
      
      Object targetDataObj = Global.getCombatEngine().getCustomData().get(targetDataKey);
      if (state == State.IN && targetDataObj == null) {
         ShipAPI target = findTarget(ship);
         Global.getCombatEngine().getCustomData().put(targetDataKey, new TargetData(ship, target));
         if (target != null) {
            if (target.getFluxTracker().showFloaty() ||
                  ship == Global.getCombatEngine().getPlayerShip() ||
                  target == Global.getCombatEngine().getPlayerShip()) {
               target.getFluxTracker().showOverloadFloatyIfNeeded("Sensors Jammed!", TEXT_COLOR, 4f, true);
            }
         }
      } else if (state == State.IDLE && targetDataObj != null) {
         Global.getCombatEngine().getCustomData().remove(targetDataKey);
         ((TargetData)targetDataObj).currRange_Mult = 1f;
         ((TargetData)targetDataObj).currSensor_Mult = 1f;         
         targetDataObj = null;
      }
      if (targetDataObj == null || ((TargetData) targetDataObj).target == null) return;
      
      final TargetData targetData = (TargetData) targetDataObj;
      targetData.currRange_Mult = RANGE_MULT * (1f - effectLevel);
      targetData.currSensor_Mult = SENSOR_MULT * (1f - effectLevel);      
      if (targetData.targetEffectPlugin == null) {
         targetData.targetEffectPlugin = new BaseEveryFrameCombatPlugin() {
            @Override
            public void advance(float amount, List<InputEventAPI> events) {
               if (Global.getCombatEngine().isPaused()) return;
               if (targetData.target == Global.getCombatEngine().getPlayerShip()) {
                  Global.getCombatEngine().maintainStatusForPlayerShip(KEY_TARGET,
                        targetData.ship.getSystem().getSpecAPI().getIconSpriteName(),
                        targetData.ship.getSystem().getDisplayName(),
                        "" + (int)((targetData.currRange_Mult - 1f) * 100f) + "% Weapon Range and " + (int)((targetData.currSensor_Mult - 1f) * 100f) + "% Sensor Range", true);
               }
               
               if (targetData.currRange_Mult <= 1f || !targetData.ship.isAlive()) {
                  targetData.target.getMutableStats().getBallisticWeaponRangeBonus().unmodify(id);
                  targetData.target.getMutableStats().getEnergyWeaponRangeBonus().unmodify(id);
                  targetData.target.getMutableStats().getSightRadiusMod().unmodify(id);
                  Global.getCombatEngine().removePlugin(targetData.targetEffectPlugin);
               } else {
                  targetData.target.getMutableStats().getBallisticWeaponRangeBonus().modifyMult(id, currRange_Mult);
                  targetData.target.getMutableStats().getEnergyWeaponRangeBonus().modifyMult(id, currRange_Mult);
                  targetData.target.getMutableStats().getSightRadiusMod().modifyMult(id, currSensor_Mult);
               }
            }
         };
         Global.getCombatEngine().addPlugin(targetData.targetEffectPlugin);
      }
      
      
      if (effectLevel > 0) {
         if (state != State.IN) {
            targetData.elaspedAfterInState += Global.getCombatEngine().getElapsedInLastFrame();
         }
         float shipJitterLevel = 0;
         if (state == State.IN) {
            shipJitterLevel = effectLevel;
         } else {
            float durOut = 0.5f;
            shipJitterLevel = Math.max(0, durOut - targetData.elaspedAfterInState) / durOut;
         }
         float targetJitterLevel = effectLevel;
         
         float maxRangeBonus = 50f;
         float jitterRangeBonus = shipJitterLevel * maxRangeBonus;
         
         Color color = JITTER_COLOR;
         if (shipJitterLevel > 0) {
            //ship.setJitterUnder(KEY_SHIP, JITTER_UNDER_COLOR, shipJitterLevel, 21, 0f, 3f + jitterRangeBonus);
            ship.setJitter(KEY_SHIP, color, shipJitterLevel, 4, 0f, 0 + jitterRangeBonus * 1f);
         }
         
         if (targetJitterLevel > 0) {
            //target.setJitterUnder(KEY_TARGET, JITTER_UNDER_COLOR, targetJitterLevel, 5, 0f, 15f);
            targetData.target.setJitter(KEY_TARGET, color, targetJitterLevel, 3, 0f, 5f);
         }
      }
   }
   
   
   public void unapply(MutableShipStatsAPI stats, String id) {
      
   }
   
   protected ShipAPI findTarget(ShipAPI ship) {
      float range = getMaxRange(ship);
      boolean player = ship == Global.getCombatEngine().getPlayerShip();
      ShipAPI target = ship.getShipTarget();
      
      if (ship.getShipAI() != null && ship.getAIFlags().hasFlag(AIFlags.TARGET_FOR_SHIP_SYSTEM)){
         target = (ShipAPI) ship.getAIFlags().getCustom(AIFlags.TARGET_FOR_SHIP_SYSTEM);
      }
      
      if (target != null) {
         float dist = Misc.getDistance(ship.getLocation(), target.getLocation());
         float radSum = ship.getCollisionRadius() + target.getCollisionRadius();
         if (dist > range + radSum) target = null;
      } else {
         if (target == null || target.getOwner() == ship.getOwner()) {
            if (player) {
               target = Misc.findClosestShipEnemyOf(ship, ship.getMouseTarget(), HullSize.FIGHTER, range, true);
            } else {
               Object test = ship.getAIFlags().getCustom(AIFlags.MANEUVER_TARGET);
               if (test instanceof ShipAPI) {
                  target = (ShipAPI) test;
                  float dist = Misc.getDistance(ship.getLocation(), target.getLocation());
                  float radSum = ship.getCollisionRadius() + target.getCollisionRadius();
                  if (dist > range + radSum) target = null;
               }
            }
         }
         if (target == null) {
            target = Misc.findClosestShipEnemyOf(ship, ship.getLocation(), HullSize.FIGHTER, range, true);
         }
      }
      
      return target;
   }
   
   
   public static float getMaxRange(ShipAPI ship) {
      return ship.getMutableStats().getSystemRangeBonus().computeEffective(RANGE);
   }

   
   public StatusData getStatusData(int index, State state, float effectLevel) {
      if (effectLevel > 0) {
         if (index == 0) {
            float damMult = 1f + (DAM_MULT - 1f) * effectLevel;
            return new StatusData("" + (int)((targetData.currRange_Mult - 1f) * 100f) + "% Weapon Range and " + (int)((targetData.currSensor_Mult - 1f) * 100f) + "% Sensor Range", false);
         }
      }
      return null;
   }


   @Override
   public String getInfoText(ShipSystemAPI system, ShipAPI ship) {
      if (system.isOutOfAmmo()) return null;
      if (system.getState() != SystemState.IDLE) return null;
      
      ShipAPI target = findTarget(ship);
      if (target != null && target != ship) {
         return "READY";
      }
      if ((target == null) && ship.getShipTarget() != null) {
         return "OUT OF RANGE";
      }
      return "NO TARGET";
   }

   
   @Override
   public boolean isUsable(ShipSystemAPI system, ShipAPI ship) {
      //if (true) return true;
      ShipAPI target = findTarget(ship);
      return target != null && target != ship;
   }

}
[close]

In your apply method, where you create a new BaseEveryFrameCombatPlugin, you reference the type "List<InputEventAPI>". Unfortunately Janino, the runtime compiler bundled with the game does not understand this type as it uses generics, and Janino does not support generics.
In order for the above to work, you will need to compile your code prior to it being loaded by the game and include the compilation output in a .jar file. Whilst this sounds complicated, there is a tutorial on how to do so here: https://starsector.fandom.com/wiki/IntelliJ_IDEA_Setup

8
Mods / [0.97a] Auto-Continue-Inator 0.0.4
« on: February 15, 2024, 02:01:03 PM »
Behold! The Auto-Continue-Inator!
With this mod, I can automatically continue any game in the Tri-State area!

Immediately loads your last save, bypassing the main menu, as soon as you start the game (and it finishes starting up).

Note: Includes a terrible, terrible hack involving setting the CombatEngine manually avoid a NPE I occasionally experienced. If this concerns you, don't use the mod lol

DOWNLOAD HERE

9
Hi,

I'm glad you're enjoying MOSS!

I'm currently in the middle of rewriting MOSS pretty heavily. However, I've just checked and mods like Seeker seem to be handled fine - nested folder handling has been part of MOSS from the very first version, seeing as handling them was one of the reasons I wrote it in the first place.

As for mass rewriting the supported game version in mods' mod_info.json files, it's something I've considered (it was also suggested to SMOL) and the conclusion I and others came to was that it would create more issues than it solves. It would encourage fairly reckless usage of mods between game versions, and whilst it is often the case that mods are fully compatible between versions they should be checked individually and carefully. If someone else were to write the code and contribute it, I would certainly consider integrating it, but it's not something I will spend my own time writing right now.

10
Suggestions / Re: API request thread (please read OP before posting!)
« on: January 22, 2024, 09:46:33 AM »
Hi Alex.

Two linked requests.

Could you please add methods like `public bool hasConfirmationDialog` and `public void onSelected` to StoryPointActionDelegate. The former would, on returning false, prevent the confirmation dialog triggered by story point action delegates currently from appearing, and the latter would allow arbitrary code to be executed when the dialog option the delegate is attached to is selected. As discussed in https://fractalsoftworks.com/forum/index.php?topic=28698.0 there are workarounds for these currently, but they are fragile and require multiple (two) frames to execute.

Hybrid bug report/API request - currently `OptionPanelAPI.restoreSavedOptions(List<Object>)` does not restore delegates, confirmation dialogs or hotkeys as expected. Current users likely expect this to fully restore all option selection functionality (ie: [Esc] triggering the common "Leave" option). Again, we discuss workarounds to this in https://fractalsoftworks.com/forum/index.php?topic=28698.0

11
I think I've expressed this elsewhere, but a minimal subset of this I'd like to see is renaming StoryPointActionDelegate and adding methods to it like
Code
public bool hasConfirmationDialog
and
Code
public void onSelected
.

Code
hasConfirmationDialog
would stop the game from displaying the confirmation popup that story point options currently always display.
Code
onSelected
would allow running some arbitrary code when the option the delegate is attached to is chosen/clicked.

These two would allow us to a) stop using the
Code
createDescription
method of the delegate to run code, and b) remove the need for our multi-frame workaround to dismissing the stock story-point-spending confirmation dialog.

Though, to be honest, it would be nice if the existing exposed API method
Code
restoreSavedOptions
were to be more "complete" and also restore delegates and hotkeys - this is an issue even when not trying to change the order of the options list.

12
Code
public static final float COST_REDUCTION  = 3;
This needs to be 3.0 not 3, as 3 is an int type not float

13
Announcements / Re: Starsector 0.96.1a (In Development) Patch Notes
« on: January 01, 2024, 12:04:10 PM »
Quote
Safety Overrides: can no longer be installed on ships with Flux Shunt (i.e. the Monitor)

It would be lovely if this hullmod incompatibility mechanism were available to modders  ;D

14
Modding / Re: Is it possible to 'debug' a save file?
« on: November 17, 2023, 06:24:49 AM »
Debugging save files is generally quite difficult. I think the easier thing to do here would be to have a look at your mod source to try and understand why it might be bricking the save file. The complexity of the code is generally lower than the complexity of the save file.

15
While looking at how certain text is set in the game, I saw that most (all?) instances of "story points" have the "story" word set by Misc.STORY, leading to the following in Misc.java:

Code
/**
* Name of "story points".
*/
public static String STORY = "story";
This seems to allow their name to be easily changed across the game. I tried my hand at changing them with a small mod and the following:
Spoiler
Code
package data.scripts;

import com.fs.starfarer.api.BaseModPlugin;
import com.fs.starfarer.api.Global.*;
import com.fs.starfarer.api.impl.campaign.ids.Strings.*;

public class StorypointMod extends BaseModPlugin {

    @Override
public void onApplicationLoad() {   

String STORY = "placeholder";


    }


}
[close]

-but I am not seeing a change (although it's not crashing). My java knowledge is next to zero so I am most certainly messing up - or I'm not understanding when this is being loaded. Thank you if you can help.

You're just setting a local variable (essentially a holder for data that you can operate on or reference later) here. This doesn't change anything about the values in the game itself. To do so, you must reference the value and alter it, like so:

Code
package data.scripts;

import com.fs.starfarer.api.BaseModPlugin;
import com.fs.starfarer.api.util.Misc;

public class StorypointMod extends BaseModPlugin {
    @Override
    public void onApplicationLoad() {   
Misc.STORY = "placeholder";
    }
}

Pages: [1] 2 3 ... 6