Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: Help with custom hullmods?  (Read 336 times)

Radon088

  • Ensign
  • *
  • Posts: 1
    • View Profile
Help with custom hullmods?
« on: July 30, 2020, 07:14:58 PM »

Hey guys, first post but long-time lurker.
I'm doing a bit of a custom mod for a friend of mine in conjunction with a writing project.
I jumped into modding to get some custom skins for a wolf and a mule that my friend had made into the game and it's kind of ballooned out till I need a custom hullmod to go with his ships.
I would do them myself (I already got the ships into the game thanks to the great "Intro to modding" tutorial in the wiki but sadly it doesn't have a section for hullmods. Also I have no experience working in java...

If anyone feels like donating your time the mod i need is thus;

Mod:
improved target leading
improved range
improved agility
improved durability
reduced minimum crew requirement by 10
acceleration
shield turn rate
reduced supply usage

Basically those things in small amounts, 5-10% improvement or so.

Alternatively if anyone knows of a really good tutorial I'll also gladly put in the time.
Logged

Histidine

  • Admiral
  • *****
  • Posts: 2822
    • View Profile
    • Bitbucket profile
    • Email
Re: Help with custom hullmods?
« Reply #1 on: August 03, 2020, 04:35:13 AM »

Unfortunately I don't have time to help, but: For a simple stat-modification hullmod, looking at the examples in [starsector-core]/data/hullmods and copying what you need should be sufficient.
Logged

Mondaymonkey

  • Admiral
  • *****
  • Posts: 777
    • View Profile
Re: Help with custom hullmods?
« Reply #2 on: August 03, 2020, 05:25:44 AM »

Explanation for improved range:

1. Find a hullmod that do the same (Integrated Targeting Unit). Find script it uses (starsector-core\data\hullmods\IntegratedTargetingUnit.java). Open it with something (even notepad is enough, but advanced things would be better)

2. Read it carefully.
Spoiler
Code
package data.hullmods;

import java.util.HashMap;
import java.util.Map;

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;

public class IntegratedTargetingUnit extends BaseHullMod {

private static Map mag = new HashMap();
static {
mag.put(HullSize.FIGHTER, 0f);
mag.put(HullSize.FRIGATE, 10f);
mag.put(HullSize.DESTROYER, 20f);
mag.put(HullSize.CRUISER, 40f);
mag.put(HullSize.CAPITAL_SHIP, 60f);
}

public String getDescriptionParam(int index, HullSize hullSize) {
if (index == 0) return "" + ((Float) mag.get(HullSize.FRIGATE)).intValue() + "%";
if (index == 1) return "" + ((Float) mag.get(HullSize.DESTROYER)).intValue() + "%";
if (index == 2) return "" + ((Float) mag.get(HullSize.CRUISER)).intValue() + "%";
if (index == 3) return "" + ((Float) mag.get(HullSize.CAPITAL_SHIP)).intValue() + "%";
return null;
}


public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
stats.getBallisticWeaponRangeBonus().modifyPercent(id, (Float) mag.get(hullSize));
stats.getEnergyWeaponRangeBonus().modifyPercent(id, (Float) mag.get(hullSize));
}


@Override
public boolean isApplicableToShip(ShipAPI ship) {
return !ship.getVariant().getHullMods().contains("dedicated_targeting_core") && !ship.getVariant().getHullMods().contains("advancedcore");
}

public String getUnapplicableReason(ShipAPI ship) {
if (ship.getVariant().getHullMods().contains("dedicated_targeting_core")) {
return "Incompatible with Dedicated Targeting Core";
}
if (ship.getVariant().getHullMods().contains("advancedcore")) {
return "Incompatible with Advanced Targeting Core";
}
return null;
}

}
[close]

3. Find part, that actually do this improvement. Here it is (Bluish are my comments. Here and after):

   public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
Determine when effect is applied. Here - "BeforeShipCreation", in other words, each time you make any loadout changes, like weapons or hullmods.
      stats.getBallisticWeaponRangeBonus().modifyPercent(id, (Float) mag.get(hullSize));
Adds bonus for ballistic weapons.
      stats.getEnergyWeaponRangeBonus().modifyPercent(id, (Float) mag.get(hullSize));
Adds bonus for energy weapons.
   }


4. Determine which variables are used there. Take a look at the last part: .modifyPercent(id, (Float) mag.get(hullSize));

id - is an id of a ship. It's already announced in applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id). Just do nothing.

(Float) mag.get(hullSize) - announced by:

   private static Map mag = new HashMap();
   static {
      mag.put(HullSize.FIGHTER, 0f);
      mag.put(HullSize.FRIGATE, 10f);
      mag.put(HullSize.DESTROYER, 20f);
      mag.put(HullSize.CRUISER, 40f);
      mag.put(HullSize.CAPITAL_SHIP, 60f);
   }

It means, that value determined by size. You can use this as it is if you need different values for different hullsizes or replace with a static float variable for all. Second option is easier to me, but it would be easier to you just make all values from static {} to be the same, like: (yeah, I know it's stupid. Still easier for newbie)

   private static Map mag = new HashMap();
   static {
      mag.put(HullSize.FIGHTER, 10f);
      mag.put(HullSize.FRIGATE, 10f);
      mag.put(HullSize.DESTROYER, 10f);
      mag.put(HullSize.CRUISER, 10f);
      mag.put(HullSize.CAPITAL_SHIP, 10f);
   }

That is for +10% for all.

5.See what import you need. Here - pretty much you need is all:

Spoiler
import java.util.HashMap;
import java.util.Map;

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;
[close]

6. Compile significant data into one piece:
Spoiler
//A) Head with imports:
package data.hullmods;

import java.util.HashMap;
import java.util.Map;

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;

//B) Your hullmod class name:

public class YourHullmodNameHere extends BaseHullMod {

//C) All the variables you need further:

   private static Map mag = new HashMap();
   static {
      mag.put(HullSize.FIGHTER, 10f);
      mag.put(HullSize.FRIGATE, 10f);
      mag.put(HullSize.DESTROYER, 10f);
      mag.put(HullSize.CRUISER, 10f);
      mag.put(HullSize.CAPITAL_SHIP, 10f);
   }
//D) Effect applying section:

   public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
      stats.getBallisticWeaponRangeBonus().modifyPercent(id, (Float) mag.get(hullSize));
      stats.getEnergyWeaponRangeBonus().modifyPercent(id, (Float) mag.get(hullSize));
   }
//E) I think we forget "}" from public class IntegratedTargetingUnit extends BaseHullMod {, lets add it:

}
[close]

Lets see what we have:
Spoiler
package data.hullmods;

import java.util.HashMap;
import java.util.Map;

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;

public class YourHullmodNameHere extends BaseHullMod {

   private static Map mag = new HashMap();
   static {
      mag.put(HullSize.FIGHTER, 10f);
      mag.put(HullSize.FRIGATE, 10f);
      mag.put(HullSize.DESTROYER, 10f);
      mag.put(HullSize.CRUISER, 10f);
      mag.put(HullSize.CAPITAL_SHIP, 10f);
   }

   public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
      stats.getBallisticWeaponRangeBonus().modifyPercent(id, (Float) mag.get(hullSize));
      stats.getEnergyWeaponRangeBonus().modifyPercent(id, (Float) mag.get(hullSize));
   }
}
[close]

This will not do description parameters. You always can add it later if you wish.

Should work. Also, you would need CSV. Next post, as this is too long.
« Last Edit: August 03, 2020, 06:03:01 AM by Mondaymonkey »
Logged
I dislike human beings... or I just do not know how to cook them well.

Mondaymonkey

  • Admiral
  • *****
  • Posts: 777
    • View Profile
Re: Help with custom hullmods?
« Reply #3 on: August 03, 2020, 05:55:24 AM »

1. You need a  hull_mods.csv. Find vanilla one in starsector-core\data\hullmods. Copy it somewhere not to damage. Open it. Excel can do this, but it *** me up several times by corrupting data so... use something else. I use Google Sheets and find it comfortable. And it never *** me. Yet.

2. Now you can see a table. Explore it. Then delete all except two rows, first one(head) and any "example" row you will going to modify.

3. Now lets move through your example row, reading column name from head one and editing them appropriately.

name - Obvious what it is. Change it to whatever you want.

id - id of your hullmod. That is what game use, be carefull here. Lets name it the same as your hullmod class: YourHullmodNameHere

tier - how advanced your hullmod is. Let it be 3?

rarity - empty

tech/manufacturer - empty

tags - let it be "special" (use no quotes). Empty is fine too

uiTags - special again. Empty is fine too.

base value - price on market. As non of a markets does not have it (yet) set any. Like 5000

unlocked - probably empty. Although can set to "true" if you wish it be available from a beginning.

hidden - usually empty. "true" used mostly for built-in.

hiddenEverywhere - empty

cost_frigate, cost_dest, cost_cruiser, cost_capital - OP cost for each hull size. Set as you wish. Empty for 0

script - important part. Change to data.YourHullmodNameHere     name from inside class YourHullmodNameHere extends BaseHullMod used here.

desc - Description. Write any.

short - shorter description. Mostly for modding comfort. User will not see it.

sprite - add a way to your hullmod sprite. You already prepared it, don't you? graphics/hullmods/YourHullmodNameHere_sprite.png

Save as .csv and put in appropriate folder of your mod.
Logged
I dislike human beings... or I just do not know how to cook them well.